Chris@16: /* Chris@101: * Copyright (c) 2012-2014 Glen Joseph Fernandes Chris@16: * glenfe at live dot com Chris@16: * Chris@101: * Distributed under the Boost Software License, Chris@101: * Version 1.0. (See accompanying file LICENSE_1_0.txt Chris@16: * or copy at http://boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP Chris@16: #define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #if !defined(BOOST_NO_CXX11_ALLOCATOR) Chris@101: #include Chris@101: #endif Chris@16: Chris@16: namespace boost { Chris@16: namespace detail { Chris@101: typedef boost::true_type ms_is_trivial; Chris@101: typedef boost::false_type ms_no_trivial; Chris@101: Chris@101: template Chris@101: inline void ms_destroy(T*, std::size_t, ms_is_trivial) { Chris@16: } Chris@101: Chris@101: template Chris@101: inline void ms_destroy(T* memory, std::size_t size, ms_no_trivial) { Chris@101: for (std::size_t i = size; i > 0;) { Chris@16: memory[--i].~T(); Chris@16: } Chris@16: } Chris@101: Chris@101: template Chris@101: inline void ms_destroy(T* memory, std::size_t size) { Chris@101: boost::has_trivial_destructor trivial; Chris@101: ms_destroy(memory, size, trivial); Chris@16: } Chris@101: Chris@101: template Chris@101: inline void ms_init(T* memory, std::size_t size, ms_is_trivial) { Chris@16: for (std::size_t i = 0; i < size; i++) { Chris@101: void* p1 = memory + i; Chris@101: ::new(p1) T(); Chris@16: } Chris@16: } Chris@101: Chris@101: template Chris@101: inline void ms_init(T* memory, std::size_t size, ms_no_trivial) { Chris@16: #if !defined(BOOST_NO_EXCEPTIONS) Chris@16: std::size_t i = 0; Chris@16: try { Chris@16: for (; i < size; i++) { Chris@16: void* p1 = memory + i; Chris@16: ::new(p1) T(); Chris@16: } Chris@16: } catch (...) { Chris@101: ms_destroy(memory, i); Chris@16: throw; Chris@16: } Chris@16: #else Chris@16: for (std::size_t i = 0; i < size; i++) { Chris@16: void* p1 = memory + i; Chris@16: ::new(p1) T(); Chris@16: } Chris@16: #endif Chris@16: } Chris@101: Chris@101: template Chris@101: inline void ms_init(T* memory, std::size_t size) { Chris@101: boost::has_trivial_default_constructor trivial; Chris@101: ms_init(memory, size, trivial); Chris@16: } Chris@101: Chris@101: template Chris@101: inline void ms_init(T* memory, std::size_t size, const T* list) { Chris@16: #if !defined(BOOST_NO_EXCEPTIONS) Chris@16: std::size_t i = 0; Chris@16: try { Chris@16: for (; i < size; i++) { Chris@16: void* p1 = memory + i; Chris@16: ::new(p1) T(list[i % N]); Chris@16: } Chris@16: } catch (...) { Chris@101: ms_destroy(memory, i); Chris@16: throw; Chris@16: } Chris@16: #else Chris@16: for (std::size_t i = 0; i < size; i++) { Chris@16: void* p1 = memory + i; Chris@16: ::new(p1) T(list[i % N]); Chris@16: } Chris@16: #endif Chris@16: } Chris@101: Chris@101: #if !defined(BOOST_NO_CXX11_ALLOCATOR) Chris@101: template Chris@101: inline void as_destroy(const A& allocator, T* memory, Chris@101: std::size_t size) { Chris@101: typedef typename std::allocator_traits:: Chris@101: template rebind_alloc TA; Chris@101: typedef typename std::allocator_traits:: Chris@101: template rebind_traits TT; Chris@101: TA a2(allocator); Chris@101: for (std::size_t i = size; i > 0;) { Chris@101: TT::destroy(a2, &memory[--i]); Chris@101: } Chris@16: } Chris@101: Chris@101: template Chris@101: inline void as_init(const A& allocator, T* memory, std::size_t size, Chris@101: ms_is_trivial) { Chris@101: typedef typename std::allocator_traits:: Chris@101: template rebind_alloc TA; Chris@101: typedef typename std::allocator_traits:: Chris@101: template rebind_traits TT; Chris@101: TA a2(allocator); Chris@101: for (std::size_t i = 0; i < size; i++) { Chris@101: TT::construct(a2, memory + i); Chris@101: } Chris@101: } Chris@101: Chris@101: template Chris@101: inline void as_init(const A& allocator, T* memory, std::size_t size, Chris@101: ms_no_trivial) { Chris@101: typedef typename std::allocator_traits:: Chris@101: template rebind_alloc TA; Chris@101: typedef typename std::allocator_traits:: Chris@101: template rebind_traits TT; Chris@101: TA a2(allocator); Chris@101: #if !defined(BOOST_NO_EXCEPTIONS) Chris@101: std::size_t i = 0; Chris@101: try { Chris@101: for (; i < size; i++) { Chris@101: TT::construct(a2, memory + i); Chris@101: } Chris@101: } catch (...) { Chris@101: as_destroy(a2, memory, i); Chris@101: throw; Chris@101: } Chris@101: #else Chris@101: for (std::size_t i = 0; i < size; i++) { Chris@101: TT::construct(a2, memory + i); Chris@101: } Chris@101: #endif Chris@101: } Chris@101: Chris@101: template Chris@101: inline void as_init(const A& allocator, T* memory, std::size_t size) { Chris@101: boost::has_trivial_default_constructor trivial; Chris@101: as_init(allocator, memory, size, trivial); Chris@101: } Chris@101: Chris@101: template Chris@101: inline void as_init(const A& allocator, T* memory, std::size_t size, Chris@101: const T* list) { Chris@101: typedef typename std::allocator_traits:: Chris@101: template rebind_alloc TA; Chris@101: typedef typename std::allocator_traits:: Chris@101: template rebind_traits TT; Chris@101: TA a2(allocator); Chris@101: #if !defined(BOOST_NO_EXCEPTIONS) Chris@101: std::size_t i = 0; Chris@101: try { Chris@101: for (; i < size; i++) { Chris@101: TT::construct(a2, memory + i, list[i % N]); Chris@101: } Chris@101: } catch (...) { Chris@101: as_destroy(a2, memory, i); Chris@101: throw; Chris@101: } Chris@101: #else Chris@101: for (std::size_t i = 0; i < size; i++) { Chris@101: TT::construct(a2, memory + i, list[i % N]); Chris@101: } Chris@101: #endif Chris@101: } Chris@101: #endif Chris@101: Chris@101: template Chris@101: inline void ms_noinit(T*, std::size_t, ms_is_trivial) { Chris@101: } Chris@101: Chris@101: template Chris@101: inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) { Chris@16: #if !defined(BOOST_NO_EXCEPTIONS) Chris@16: std::size_t i = 0; Chris@16: try { Chris@16: for (; i < size; i++) { Chris@16: void* p1 = memory + i; Chris@16: ::new(p1) T; Chris@16: } Chris@16: } catch (...) { Chris@101: ms_destroy(memory, i); Chris@16: throw; Chris@16: } Chris@16: #else Chris@16: for (std::size_t i = 0; i < size; i++) { Chris@16: void* p1 = memory + i; Chris@16: ::new(p1) T; Chris@16: } Chris@16: #endif Chris@16: } Chris@101: Chris@101: template Chris@101: inline void ms_noinit(T* memory, std::size_t size) { Chris@101: boost::has_trivial_default_constructor trivial; Chris@101: ms_noinit(memory, size, trivial); Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: #endif