/* Copyright 2020-2021 Glen Joseph Fernandes (glenjofe@gmail.com) Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_CORE_ALLOCATOR_ACCESS_HPP #define BOOST_CORE_ALLOCATOR_ACCESS_HPP #include #include #include #include #if !defined(BOOST_NO_CXX11_ALLOCATOR) #include #endif #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #include #endif #if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40300) #define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) #elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500) #define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) #elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) #define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) #elif defined(BOOST_CLANG) && !defined(__CUDACC__) #if __has_feature(is_empty) #define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) #endif #elif defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) #define BOOST_DETAIL_ALLOC_EMPTY(T) __oracle_is_empty(T) #elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) #define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) #elif defined(BOOST_CODEGEARC) #define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) #endif #if defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) _LIBCPP_SUPPRESS_DEPRECATED_PUSH #endif #if defined(_STL_DISABLE_DEPRECATED_WARNING) _STL_DISABLE_DEPRECATED_WARNING #endif #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4996) #endif namespace boost { template struct allocator_value_type { typedef typename A::value_type type; }; namespace detail { template struct alloc_ptr { typedef typename boost::allocator_value_type::type* type; }; template struct alloc_void { typedef void type; }; template struct alloc_ptr::type> { typedef typename A::pointer type; }; } /* detail */ template struct allocator_pointer { typedef typename detail::alloc_ptr::type type; }; namespace detail { template struct alloc_const_ptr { typedef typename boost::pointer_traits::type>::template rebind_to::type>::type type; }; template struct alloc_const_ptr::type> { typedef typename A::const_pointer type; }; } /* detail */ template struct allocator_const_pointer { typedef typename detail::alloc_const_ptr::type type; }; namespace detail { template struct alloc_to { }; #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template class A, class T, class U> struct alloc_to, T> { typedef A type; }; template class A, class T, class U, class V> struct alloc_to, T> { typedef A type; }; template class A, class T, class U, class V1, class V2> struct alloc_to, T> { typedef A type; }; #else template class A, class T, class U, class... V> struct alloc_to, T> { typedef A type; }; #endif template struct alloc_rebind { typedef typename alloc_to::type type; }; template struct alloc_rebind::other>::type> { typedef typename A::template rebind::other type; }; } /* detail */ template struct allocator_rebind { typedef typename detail::alloc_rebind::type type; }; namespace detail { template struct alloc_void_ptr { typedef typename boost::pointer_traits::type>::template rebind_to::type type; }; template struct alloc_void_ptr::type> { typedef typename A::void_pointer type; }; } /* detail */ template struct allocator_void_pointer { typedef typename detail::alloc_void_ptr::type type; }; namespace detail { template struct alloc_const_void_ptr { typedef typename boost::pointer_traits::type>::template rebind_to::type type; }; template struct alloc_const_void_ptr::type> { typedef typename A::const_void_pointer type; }; } /* detail */ template struct allocator_const_void_pointer { typedef typename detail::alloc_const_void_ptr::type type; }; namespace detail { template struct alloc_diff_type { typedef typename boost::pointer_traits::type>::difference_type type; }; template struct alloc_diff_type::type> { typedef typename A::difference_type type; }; } /* detail */ template struct allocator_difference_type { typedef typename detail::alloc_diff_type::type type; }; namespace detail { #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct alloc_size_type { typedef std::size_t type; }; #else template struct alloc_size_type { typedef typename std::make_unsigned::type>::type type; }; #endif template struct alloc_size_type::type> { typedef typename A::size_type type; }; } /* detail */ template struct allocator_size_type { typedef typename detail::alloc_size_type::type type; }; namespace detail { #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct alloc_bool { typedef bool value_type; typedef alloc_bool type; static const bool value = V; operator bool() const BOOST_NOEXCEPT { return V; } bool operator()() const BOOST_NOEXCEPT { return V; } }; template const bool alloc_bool::value; typedef alloc_bool alloc_false; #else typedef std::false_type alloc_false; #endif template struct alloc_pocca { typedef alloc_false type; }; template struct alloc_pocca::type> { typedef typename A::propagate_on_container_copy_assignment type; }; } /* detail */ template struct allocator_propagate_on_container_copy_assignment { typedef typename detail::alloc_pocca::type type; }; namespace detail { template struct alloc_pocma { typedef alloc_false type; }; template struct alloc_pocma::type> { typedef typename A::propagate_on_container_move_assignment type; }; } /* detail */ template struct allocator_propagate_on_container_move_assignment { typedef typename detail::alloc_pocma::type type; }; namespace detail { template struct alloc_pocs { typedef alloc_false type; }; template struct alloc_pocs::type> { typedef typename A::propagate_on_container_swap type; }; } /* detail */ template struct allocator_propagate_on_container_swap { typedef typename detail::alloc_pocs::type type; }; namespace detail { #if !defined(BOOST_NO_CXX11_ALLOCATOR) template struct alloc_equal { typedef typename std::is_empty::type type; }; #elif defined(BOOST_DETAIL_ALLOC_EMPTY) template struct alloc_equal { typedef alloc_bool type; }; #else template struct alloc_equal { typedef alloc_false type; }; #endif template struct alloc_equal::type> { typedef typename A::is_always_equal type; }; } /* detail */ template struct allocator_is_always_equal { typedef typename detail::alloc_equal::type type; }; template inline typename allocator_pointer::type allocator_allocate(A& a, typename allocator_size_type::type n) { return a.allocate(n); } template inline void allocator_deallocate(A& a, typename allocator_pointer::type p, typename allocator_size_type::type n) { a.deallocate(p, n); } #if defined(BOOST_NO_CXX11_ALLOCATOR) template inline typename allocator_pointer::type allocator_allocate(A& a, typename allocator_size_type::type n, typename allocator_const_void_pointer::type h) { return a.allocate(n, h); } #else namespace detail { template struct alloc_no { char x, y; }; template class alloc_has_allocate { template static auto check(int) -> alloc_no().allocate(std::declval::type>(), std::declval::type>()))>; template static char check(long); public: BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; }; } /* detail */ template inline typename std::enable_if::value, typename allocator_pointer::type>::type allocator_allocate(A& a, typename allocator_size_type::type n, typename allocator_const_void_pointer::type h) { return a.allocate(n, h); } template inline typename std::enable_if::value, typename allocator_pointer::type>::type allocator_allocate(A& a, typename allocator_size_type::type n, typename allocator_const_void_pointer::type) { return a.allocate(n); } #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template inline void allocator_construct(A&, T* p) { ::new((void*)p) T(); } #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template inline void allocator_construct(A&, T* p, V&& v, Args&&... args) { ::new((void*)p) T(std::forward(v), std::forward(args)...); } #else template inline void allocator_construct(A&, T* p, V&& v) { ::new((void*)p) T(std::forward(v)); } #endif #else template inline void allocator_construct(A&, T* p, const V& v) { ::new((void*)p) T(v); } template inline void allocator_construct(A&, T* p, V& v) { ::new((void*)p) T(v); } #endif #else namespace detail { template class alloc_has_construct { template static auto check(int) -> alloc_no().construct(std::declval(), std::declval()...))>; template static char check(long); public: BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; }; } /* detail */ template inline typename std::enable_if::value>::type allocator_construct(A& a, T* p, Args&&... args) { a.construct(p, std::forward(args)...); } template inline typename std::enable_if::value>::type allocator_construct(A&, T* p, Args&&... args) { ::new((void*)p) T(std::forward(args)...); } #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template inline void allocator_destroy(A&, T* p) { p->~T(); (void)p; } #else namespace detail { template class alloc_has_destroy { template static auto check(int) -> alloc_no().destroy(std::declval()))>; template static char check(long); public: BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; }; } /* detail */ template inline typename std::enable_if::value>::type allocator_destroy(A& a, T* p) { a.destroy(p); } template inline typename std::enable_if::value>::type allocator_destroy(A&, T* p) { p->~T(); (void)p; } #endif namespace detail { #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct alloc_no { char x, y; }; template class alloc_has_max_size { template static alloc_no::type(O::*)(), &O::max_size> check(int); template static alloc_no::type(O::*)() const, &O::max_size> check(int); template static alloc_no::type(*)(), &O::max_size> check(int); template static char check(long); public: BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; }; #else template class alloc_has_max_size { template static auto check(int) -> alloc_no().max_size())>; template static char check(long); public: BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; }; #endif template struct alloc_if { }; template struct alloc_if { typedef T type; }; } /* detail */ template inline typename detail::alloc_if::value, typename allocator_size_type::type>::type allocator_max_size(const A& a) BOOST_NOEXCEPT { return a.max_size(); } template inline typename detail::alloc_if::value, typename allocator_size_type::type>::type allocator_max_size(const A&) BOOST_NOEXCEPT { return (std::numeric_limits::type>::max)() / sizeof(typename allocator_value_type::type); } namespace detail { #if defined(BOOST_NO_CXX11_ALLOCATOR) template class alloc_has_soccc { template static alloc_no check(int); template static alloc_no check(int); template static alloc_no check(int); template static char check(long); public: BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; }; #else template class alloc_has_soccc { template static auto check(int) -> alloc_no().select_on_container_copy_construction())>; template static char check(long); public: BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; }; #endif } /* detail */ template inline typename detail::alloc_if::value, A>::type allocator_select_on_container_copy_construction(const A& a) { return a.select_on_container_copy_construction(); } template inline typename detail::alloc_if::value, A>::type allocator_select_on_container_copy_construction(const A& a) { return a; } #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template using allocator_value_type_t = typename allocator_value_type::type; template using allocator_pointer_t = typename allocator_pointer::type; template using allocator_const_pointer_t = typename allocator_const_pointer::type; template using allocator_void_pointer_t = typename allocator_void_pointer::type; template using allocator_const_void_pointer_t = typename allocator_const_void_pointer::type; template using allocator_difference_type_t = typename allocator_difference_type::type; template using allocator_size_type_t = typename allocator_size_type::type; template using allocator_propagate_on_container_copy_assignment_t = typename allocator_propagate_on_container_copy_assignment::type; template using allocator_propagate_on_container_move_assignment_t = typename allocator_propagate_on_container_move_assignment::type; template using allocator_propagate_on_container_swap_t = typename allocator_propagate_on_container_swap::type; template using allocator_is_always_equal_t = typename allocator_is_always_equal::type; template using allocator_rebind_t = typename allocator_rebind::type; #endif } /* boost */ #if defined(_LIBCPP_SUPPRESS_DEPRECATED_POP) _LIBCPP_SUPPRESS_DEPRECATED_POP #endif #if defined(_STL_RESTORE_DEPRECATED_WARNING) _STL_RESTORE_DEPRECATED_WARNING #endif #if defined(_MSC_VER) #pragma warning(pop) #endif #endif