| 
									
										
										
										
											2012-11-06 14:17:32 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | Copyright 2012-2017 Glen Joseph Fernandes | 
					
						
							|  |  |  | (glenjofe@gmail.com) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Distributed under the Boost Software License, Version 1.0. | 
					
						
							|  |  |  | (http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2012-11-06 14:17:32 +00:00
										 |  |  | #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
 | 
					
						
							|  |  |  | #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | #include <boost/smart_ptr/shared_ptr.hpp>
 | 
					
						
							| 
									
										
										
										
											2017-04-22 22:39:57 -04:00
										 |  |  | #include <boost/type_traits/alignment_of.hpp>
 | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | #include <boost/type_traits/has_trivial_assign.hpp>
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | #include <boost/type_traits/has_trivial_constructor.hpp>
 | 
					
						
							|  |  |  | #include <boost/type_traits/has_trivial_destructor.hpp>
 | 
					
						
							|  |  |  | #include <boost/type_traits/type_with_alignment.hpp>
 | 
					
						
							| 
									
										
										
										
											2012-11-06 14:17:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace boost { | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | namespace detail { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class> | 
					
						
							|  |  |  | struct sp_if_array { }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_if_array<T[]> { | 
					
						
							|  |  |  |     typedef boost::shared_ptr<T[]> type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class> | 
					
						
							|  |  |  | struct sp_if_size_array { }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, std::size_t N> | 
					
						
							|  |  |  | struct sp_if_size_array<T[N]> { | 
					
						
							|  |  |  |     typedef boost::shared_ptr<T[N]> type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class> | 
					
						
							|  |  |  | struct sp_array_element { }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_array_element<T[]> { | 
					
						
							|  |  |  |     typedef T type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, std::size_t N> | 
					
						
							|  |  |  | struct sp_array_element<T[N]> { | 
					
						
							|  |  |  |     typedef T type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_array_scalar { | 
					
						
							|  |  |  |     typedef T type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, std::size_t N> | 
					
						
							|  |  |  | struct sp_array_scalar<T[N]> { | 
					
						
							|  |  |  |     typedef typename sp_array_scalar<T>::type type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, std::size_t N> | 
					
						
							|  |  |  | struct sp_array_scalar<const T[N]> { | 
					
						
							|  |  |  |     typedef typename sp_array_scalar<T>::type type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, std::size_t N> | 
					
						
							|  |  |  | struct sp_array_scalar<volatile T[N]> { | 
					
						
							|  |  |  |     typedef typename sp_array_scalar<T>::type type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, std::size_t N> | 
					
						
							|  |  |  | struct sp_array_scalar<const volatile T[N]> { | 
					
						
							|  |  |  |     typedef typename sp_array_scalar<T>::type type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_array_scalar<T[]> { | 
					
						
							|  |  |  |     typedef typename sp_array_scalar<T>::type type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_array_scalar<const T[]> { | 
					
						
							|  |  |  |     typedef typename sp_array_scalar<T>::type type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_array_scalar<volatile T[]> { | 
					
						
							|  |  |  |     typedef typename sp_array_scalar<T>::type type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_array_scalar<const volatile T[]> { | 
					
						
							|  |  |  |     typedef typename sp_array_scalar<T>::type type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_array_count { | 
					
						
							| 
									
										
										
										
											2017-02-28 19:01:27 -05:00
										 |  |  |     enum { | 
					
						
							|  |  |  |         value = 1 | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, std::size_t N> | 
					
						
							|  |  |  | struct sp_array_count<T[N]> { | 
					
						
							| 
									
										
										
										
											2017-02-28 19:01:27 -05:00
										 |  |  |     enum { | 
					
						
							|  |  |  |         value = N * sp_array_count<T>::value | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<std::size_t N, std::size_t M> | 
					
						
							|  |  |  | struct sp_max_size { | 
					
						
							|  |  |  |     enum { | 
					
						
							|  |  |  |         value = N < M ? M : N | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<std::size_t N, std::size_t M> | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | struct sp_align_up { | 
					
						
							| 
									
										
										
										
											2017-02-28 19:01:27 -05:00
										 |  |  |     enum { | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |         value = (N + M - 1) & ~(M - 1) | 
					
						
							| 
									
										
										
										
											2017-02-28 19:01:27 -05:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | template<class A, class T> | 
					
						
							|  |  |  | struct sp_bind_allocator { | 
					
						
							| 
									
										
										
										
											2017-05-02 08:06:55 -04:00
										 |  |  |     typedef typename std::allocator_traits<A>::template rebind_alloc<T> type; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | template<class A, class T> | 
					
						
							|  |  |  | struct sp_bind_allocator { | 
					
						
							|  |  |  |     typedef typename A::template rebind<T>::other type; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class T> | 
					
						
							|  |  |  | BOOST_CONSTEXPR inline std::size_t | 
					
						
							|  |  |  | sp_objects(std::size_t size) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return (size + sizeof(T) - 1) / sizeof(T); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-28 19:01:27 -05:00
										 |  |  | template<bool, class = void> | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | struct sp_enable { }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-28 19:01:27 -05:00
										 |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_enable<true, T> { | 
					
						
							|  |  |  |     typedef T type; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<!E && boost::has_trivial_destructor<T>::value>::type | 
					
						
							|  |  |  | sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { } | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<!E && | 
					
						
							|  |  |  |     !boost::has_trivial_destructor<T>::value>::type | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | sp_array_destroy(A&, T* start, std::size_t size) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     while (size > 0) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         start[--size].~T(); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<E>::type | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | sp_array_destroy(A& allocator, T* start, std::size_t size) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     while (size > 0) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         std::allocator_traits<A>::destroy(allocator, start + --size); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<!E && | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |     boost::has_trivial_constructor<T>::value && | 
					
						
							|  |  |  |     boost::has_trivial_assign<T>::value>::type | 
					
						
							|  |  |  | sp_array_construct(A&, T* start, std::size_t size) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     for (std::size_t i = 0; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         start[i] = T(); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<!E && | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |     boost::has_trivial_constructor<T>::value && | 
					
						
							|  |  |  |     boost::has_trivial_assign<T>::value>::type | 
					
						
							|  |  |  | sp_array_construct(A&, T* start, std::size_t size, const T* list, | 
					
						
							|  |  |  |     std::size_t count) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |     for (std::size_t i = 0; i < size; ++i) { | 
					
						
							|  |  |  |         start[i] = list[i % count]; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | #if !defined(BOOST_NO_EXCEPTIONS)
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<!E && | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |     !(boost::has_trivial_constructor<T>::value && | 
					
						
							|  |  |  |       boost::has_trivial_assign<T>::value)>::type | 
					
						
							|  |  |  | sp_array_construct(A& none, T* start, std::size_t size) | 
					
						
							| 
									
										
										
										
											2017-04-22 22:39:57 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |     std::size_t i = 0; | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |         for (; i < size; ++i) { | 
					
						
							|  |  |  |             ::new(static_cast<void*>(start + i)) T(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } catch (...) { | 
					
						
							|  |  |  |         sp_array_destroy<E>(none, start, i); | 
					
						
							|  |  |  |         throw; | 
					
						
							| 
									
										
										
										
											2017-04-22 22:39:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<!E && | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |     !(boost::has_trivial_constructor<T>::value && | 
					
						
							|  |  |  |       boost::has_trivial_assign<T>::value)>::type | 
					
						
							|  |  |  | sp_array_construct(A& none, T* start, std::size_t size, const T* list, | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     std::size_t count) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     std::size_t i = 0; | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |         for (; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |             ::new(static_cast<void*>(start + i)) T(list[i % count]); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |     } catch (...) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         sp_array_destroy<E>(none, start, i); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         throw; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | inline typename sp_enable<!E && | 
					
						
							|  |  |  |     !(boost::has_trivial_constructor<T>::value && | 
					
						
							|  |  |  |       boost::has_trivial_assign<T>::value)>::type | 
					
						
							|  |  |  | sp_array_construct(A&, T* start, std::size_t size) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     for (std::size_t i = 0; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         ::new(static_cast<void*>(start + i)) T(); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | inline typename sp_enable<!E && | 
					
						
							|  |  |  |     !(boost::has_trivial_constructor<T>::value && | 
					
						
							|  |  |  |       boost::has_trivial_assign<T>::value)>::type | 
					
						
							|  |  |  | sp_array_construct(A&, T* start, std::size_t size, const T* list, | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     std::size_t count) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (std::size_t i = 0; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         ::new(static_cast<void*>(start + i)) T(list[i % count]); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | #if !defined(BOOST_NO_EXCEPTIONS)
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<E>::type | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | sp_array_construct(A& allocator, T* start, std::size_t size) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     std::size_t i = 0; | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |         for (i = 0; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |             std::allocator_traits<A>::construct(allocator, start + i); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |     } catch (...) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         sp_array_destroy<E>(allocator, start, i); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         throw; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<E>::type | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | sp_array_construct(A& allocator, T* start, std::size_t size, const T* list, | 
					
						
							|  |  |  |     std::size_t count) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     std::size_t i = 0; | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |         for (i = 0; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |             std::allocator_traits<A>::construct(allocator, start + i, | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |                 list[i % count]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } catch (...) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         sp_array_destroy<E>(allocator, start, i); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         throw; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<E>::type | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | sp_array_construct(A& allocator, T* start, std::size_t size) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     for (std::size_t i = 0; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         std::allocator_traits<A>::construct(allocator, start + i); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							|  |  |  | inline typename sp_enable<E>::type | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | sp_array_construct(A& allocator, T* start, std::size_t size, const T* list, | 
					
						
							|  |  |  |     std::size_t count) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     for (std::size_t i = 0; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         std::allocator_traits<A>::construct(allocator, start + i, | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |             list[i % count]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class A, class T> | 
					
						
							| 
									
										
										
										
											2017-05-02 08:06:55 -04:00
										 |  |  | inline typename sp_enable<boost::has_trivial_constructor<T>::value>::type | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { } | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if !defined(BOOST_NO_EXCEPTIONS)
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class A, class T> | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type | 
					
						
							|  |  |  | sp_array_default(A& none, T* start, std::size_t size) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     std::size_t i = 0; | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |         for (; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |             ::new(static_cast<void*>(start + i)) T; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |     } catch (...) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         sp_array_destroy<false>(none, start, i); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         throw; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<bool E, class A, class T> | 
					
						
							| 
									
										
										
										
											2017-05-02 08:06:55 -04:00
										 |  |  | inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  | sp_array_default(A&, T* start, std::size_t size) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     for (std::size_t i = 0; i < size; ++i) { | 
					
						
							| 
									
										
										
										
											2017-07-04 13:45:56 -04:00
										 |  |  |         ::new(static_cast<void*>(start + i)) T; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class A> | 
					
						
							|  |  |  | class sp_array_state { | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typedef A type; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     template<class U> | 
					
						
							|  |  |  |     sp_array_state(const U& allocator, std::size_t size) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         : allocator_(allocator), | 
					
						
							|  |  |  |           size_(size) { } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     A& allocator() BOOST_SP_NOEXCEPT { | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         return allocator_; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-12 18:06:54 +03:00
										 |  |  |     std::size_t size() const BOOST_SP_NOEXCEPT { | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         return size_; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     A allocator_; | 
					
						
							|  |  |  |     std::size_t size_; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class A, std::size_t N> | 
					
						
							|  |  |  | class sp_size_array_state { | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typedef A type; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     template<class U> | 
					
						
							|  |  |  |     sp_size_array_state(const U& allocator, std::size_t) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |         : allocator_(allocator) { } | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     A& allocator() BOOST_SP_NOEXCEPT { | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         return allocator_; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     BOOST_CONSTEXPR std::size_t size() const BOOST_SP_NOEXCEPT { | 
					
						
							|  |  |  |         return N; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     A allocator_; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class A> | 
					
						
							|  |  |  | struct sp_use_construct { | 
					
						
							|  |  |  |     enum { | 
					
						
							|  |  |  |         value = true | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class T> | 
					
						
							|  |  |  | struct sp_use_construct<std::allocator<T> > { | 
					
						
							|  |  |  |     enum { | 
					
						
							|  |  |  |         value = false | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class> | 
					
						
							|  |  |  | struct sp_use_construct { | 
					
						
							|  |  |  |     enum { | 
					
						
							|  |  |  |         value = false | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-02-10 20:54:48 -08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class T, class U> | 
					
						
							|  |  |  | struct sp_array_alignment { | 
					
						
							|  |  |  |     enum { | 
					
						
							|  |  |  |         value = sp_max_size<boost::alignment_of<T>::value, | 
					
						
							|  |  |  |             boost::alignment_of<U>::value>::value | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class T, class U> | 
					
						
							|  |  |  | struct sp_array_offset { | 
					
						
							|  |  |  |     enum { | 
					
						
							|  |  |  |         value = sp_align_up<sizeof(T), sp_array_alignment<T, U>::value>::value | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class T, class U> | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  | struct sp_array_storage { | 
					
						
							|  |  |  |     enum { | 
					
						
							|  |  |  |         value = sp_array_alignment<T, U>::value | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     typedef typename boost::type_with_alignment<value>::type type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, class U> | 
					
						
							|  |  |  | inline U* | 
					
						
							|  |  |  | sp_array_start(void* base) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | { | 
					
						
							|  |  |  |     enum { | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         size = sp_array_offset<T, U>::value | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     return reinterpret_cast<U*>(static_cast<char*>(base) + size); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class A, class T> | 
					
						
							|  |  |  | class sp_array_creator { | 
					
						
							|  |  |  |     typedef typename A::value_type scalar; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     enum { | 
					
						
							|  |  |  |         offset = sp_array_offset<T, scalar>::value | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     typedef typename sp_array_storage<T, scalar>::type type; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | public: | 
					
						
							|  |  |  |     template<class U> | 
					
						
							|  |  |  |     sp_array_creator(const U& other, std::size_t size) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |         : other_(other), | 
					
						
							|  |  |  |           size_(sp_objects<type>(offset + sizeof(scalar) * size)) { } | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     T* create() { | 
					
						
							|  |  |  |         return reinterpret_cast<T*>(other_.allocate(size_)); | 
					
						
							| 
									
										
										
										
											2017-06-20 20:38:26 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     void destroy(T* base) { | 
					
						
							|  |  |  |         other_.deallocate(reinterpret_cast<type*>(base), size_); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typename sp_bind_allocator<A, type>::type other_; | 
					
						
							|  |  |  |     std::size_t size_; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | struct sp_default { }; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class T, bool E = sp_use_construct<T>::value> | 
					
						
							|  |  |  | class sp_array_base | 
					
						
							|  |  |  |     : public sp_counted_base { | 
					
						
							|  |  |  |     typedef typename T::type allocator; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typedef typename allocator::value_type type; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     template<class A> | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     sp_array_base(const A& other, std::size_t size, type* start) | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |         : state_(other, size) { | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         sp_array_construct<E>(state_.allocator(), start, state_.size()); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     template<class A> | 
					
						
							|  |  |  |     sp_array_base(const A& other, std::size_t size, const type* list, | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         std::size_t count, type* start) | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |         : state_(other, size) { | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         sp_array_construct<E>(state_.allocator(), start, state_.size(), list, | 
					
						
							|  |  |  |             count); | 
					
						
							| 
									
										
										
										
											2017-06-20 20:38:26 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     template<class A> | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     sp_array_base(sp_default, const A& other, std::size_t size, type* start) | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |         : state_(other, size) { | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         sp_array_default(state_.allocator(), start, state_.size()); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 12:46:39 -04:00
										 |  |  |     T& state() BOOST_SP_NOEXCEPT { | 
					
						
							|  |  |  |         return state_; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     virtual void dispose() { | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         sp_array_destroy<E>(state_.allocator(), | 
					
						
							|  |  |  |             sp_array_start<sp_array_base, type>(this), state_.size()); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     virtual void destroy() { | 
					
						
							|  |  |  |         sp_array_creator<allocator, sp_array_base> other(state_.allocator(), | 
					
						
							|  |  |  |             state_.size()); | 
					
						
							|  |  |  |         this->~sp_array_base(); | 
					
						
							|  |  |  |         other.destroy(this); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     virtual void* get_deleter(const sp_typeinfo&) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     virtual void* get_local_deleter(const sp_typeinfo&) { | 
					
						
							| 
									
										
										
										
											2017-06-20 20:38:26 +03:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     virtual void* get_untyped_deleter() { | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     T state_; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | template<class A, class T> | 
					
						
							|  |  |  | struct sp_array_result { | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     template<class U> | 
					
						
							|  |  |  |     sp_array_result(const U& other, std::size_t size) | 
					
						
							|  |  |  |         : creator_(other, size), | 
					
						
							|  |  |  |           result_(creator_.create()) { } | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     ~sp_array_result() { | 
					
						
							|  |  |  |         if (result_) { | 
					
						
							|  |  |  |             creator_.destroy(result_); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     T* get() const { | 
					
						
							|  |  |  |         return result_; | 
					
						
							| 
									
										
										
										
											2017-06-20 20:38:26 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     void release() { | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |         result_ = 0; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     sp_array_result(const sp_array_result&); | 
					
						
							|  |  |  |     sp_array_result& operator=(const sp_array_result&); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sp_array_creator<A, T> creator_; | 
					
						
							|  |  |  |     T* result_; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } /* detail */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, class A> | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | inline typename detail::sp_if_array<T>::type | 
					
						
							|  |  |  | allocate_shared(const A& allocator, std::size_t count) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     typedef typename detail::sp_array_element<T>::type type; | 
					
						
							|  |  |  |     typedef typename detail::sp_array_scalar<T>::type scalar; | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | 
					
						
							|  |  |  |     typedef detail::sp_array_state<other> state; | 
					
						
							|  |  |  |     typedef detail::sp_array_base<state> base; | 
					
						
							|  |  |  |     std::size_t size = count * detail::sp_array_count<type>::value; | 
					
						
							|  |  |  |     detail::sp_array_result<other, base> result(allocator, size); | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     detail::sp_counted_base* node = result.get(); | 
					
						
							|  |  |  |     scalar* start = detail::sp_array_start<base, scalar>(node); | 
					
						
							|  |  |  |     ::new(static_cast<void*>(node)) base(allocator, size, start); | 
					
						
							|  |  |  |     result.release(); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         reinterpret_cast<type*>(start), detail::shared_count(node)); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, class A> | 
					
						
							|  |  |  | inline typename detail::sp_if_size_array<T>::type | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | allocate_shared(const A& allocator) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     enum { | 
					
						
							|  |  |  |         size = detail::sp_array_count<T>::value | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     typedef typename detail::sp_array_element<T>::type type; | 
					
						
							|  |  |  |     typedef typename detail::sp_array_scalar<T>::type scalar; | 
					
						
							|  |  |  |     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typedef detail::sp_size_array_state<other, size> state; | 
					
						
							|  |  |  |     typedef detail::sp_array_base<state> base; | 
					
						
							|  |  |  |     detail::sp_array_result<other, base> result(allocator, size); | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     detail::sp_counted_base* node = result.get(); | 
					
						
							|  |  |  |     scalar* start = detail::sp_array_start<base, scalar>(node); | 
					
						
							|  |  |  |     ::new(static_cast<void*>(node)) base(allocator, size, start); | 
					
						
							|  |  |  |     result.release(); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         reinterpret_cast<type*>(start), detail::shared_count(node)); | 
					
						
							| 
									
										
										
										
											2012-11-06 14:17:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | template<class T, class A> | 
					
						
							|  |  |  | inline typename detail::sp_if_array<T>::type | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | allocate_shared(const A& allocator, std::size_t count, | 
					
						
							|  |  |  |     const typename detail::sp_array_element<T>::type& value) | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     typedef typename detail::sp_array_element<T>::type type; | 
					
						
							|  |  |  |     typedef typename detail::sp_array_scalar<T>::type scalar; | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | 
					
						
							|  |  |  |     typedef detail::sp_array_state<other> state; | 
					
						
							|  |  |  |     typedef detail::sp_array_base<state> base; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     std::size_t size = count * detail::sp_array_count<type>::value; | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     detail::sp_array_result<other, base> result(allocator, size); | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     detail::sp_counted_base* node = result.get(); | 
					
						
							|  |  |  |     scalar* start = detail::sp_array_start<base, scalar>(node); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     ::new(static_cast<void*>(node)) base(allocator, size, | 
					
						
							|  |  |  |         reinterpret_cast<const scalar*>(&value), | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         detail::sp_array_count<type>::value, start); | 
					
						
							|  |  |  |     result.release(); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         reinterpret_cast<type*>(start), detail::shared_count(node)); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, class A> | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | inline typename detail::sp_if_size_array<T>::type | 
					
						
							|  |  |  | allocate_shared(const A& allocator, | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     const typename detail::sp_array_element<T>::type& value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     enum { | 
					
						
							|  |  |  |         size = detail::sp_array_count<T>::value | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     typedef typename detail::sp_array_element<T>::type type; | 
					
						
							|  |  |  |     typedef typename detail::sp_array_scalar<T>::type scalar; | 
					
						
							|  |  |  |     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typedef detail::sp_size_array_state<other, size> state; | 
					
						
							|  |  |  |     typedef detail::sp_array_base<state> base; | 
					
						
							|  |  |  |     detail::sp_array_result<other, base> result(allocator, size); | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     detail::sp_counted_base* node = result.get(); | 
					
						
							|  |  |  |     scalar* start = detail::sp_array_start<base, scalar>(node); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     ::new(static_cast<void*>(node)) base(allocator, size, | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |         reinterpret_cast<const scalar*>(&value), | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         detail::sp_array_count<type>::value, start); | 
					
						
							|  |  |  |     result.release(); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         reinterpret_cast<type*>(start), detail::shared_count(node)); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, class A> | 
					
						
							|  |  |  | inline typename detail::sp_if_array<T>::type | 
					
						
							|  |  |  | allocate_shared_noinit(const A& allocator, std::size_t count) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     typedef typename detail::sp_array_element<T>::type type; | 
					
						
							|  |  |  |     typedef typename detail::sp_array_scalar<T>::type scalar; | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | 
					
						
							|  |  |  |     typedef detail::sp_array_state<other> state; | 
					
						
							|  |  |  |     typedef detail::sp_array_base<state, false> base; | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  |     std::size_t size = count * detail::sp_array_count<type>::value; | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     detail::sp_array_result<other, base> result(allocator, size); | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     detail::sp_counted_base* node = result.get(); | 
					
						
							|  |  |  |     scalar* start = detail::sp_array_start<base, scalar>(node); | 
					
						
							|  |  |  |     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | 
					
						
							|  |  |  |         size, start); | 
					
						
							|  |  |  |     result.release(); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         reinterpret_cast<type*>(start), detail::shared_count(node)); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T, class A> | 
					
						
							|  |  |  | inline typename detail::sp_if_size_array<T>::type | 
					
						
							|  |  |  | allocate_shared_noinit(const A& allocator) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enum { | 
					
						
							|  |  |  |         size = detail::sp_array_count<T>::value | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     typedef typename detail::sp_array_element<T>::type type; | 
					
						
							|  |  |  |     typedef typename detail::sp_array_scalar<T>::type scalar; | 
					
						
							|  |  |  |     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     typedef detail::sp_size_array_state<other, size> state; | 
					
						
							|  |  |  |     typedef detail::sp_array_base<state, false> base; | 
					
						
							|  |  |  |     detail::sp_array_result<other, base> result(allocator, size); | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |     detail::sp_counted_base* node = result.get(); | 
					
						
							|  |  |  |     scalar* start = detail::sp_array_start<base, scalar>(node); | 
					
						
							|  |  |  |     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | 
					
						
							|  |  |  |         size, start); | 
					
						
							|  |  |  |     result.release(); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:06:10 -04:00
										 |  |  |     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | 
					
						
							| 
									
										
										
										
											2017-06-29 22:07:42 -04:00
										 |  |  |         reinterpret_cast<type*>(start), detail::shared_count(node)); | 
					
						
							| 
									
										
										
										
											2017-02-28 01:41:34 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } /* boost */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-06 14:17:32 +00:00
										 |  |  | #endif
 |