/* 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 #if !defined(BOOST_NO_CXX11_ALLOCATOR) #include #include #include #endif #include #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #include #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; }; #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_pointer { typedef typename A::pointer type; }; #else template struct allocator_pointer { typedef typename A::value_type* type; }; namespace detail { template struct alloc_void { typedef void type; }; } /* detail */ template struct allocator_pointer::type> { typedef typename A::pointer type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_const_pointer { typedef typename A::const_pointer type; }; #else template struct allocator_const_pointer { typedef typename pointer_traits::type>::template rebind_to::type type; }; template struct allocator_const_pointer::type> { typedef typename A::const_pointer type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_void_pointer { typedef typename A::template rebind::other::pointer type; }; #else template struct allocator_void_pointer { typedef typename pointer_traits::type>::template rebind_to::type type; }; template struct allocator_void_pointer::type> { typedef typename A::void_pointer type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_const_void_pointer { typedef typename A::template rebind::other::const_pointer type; }; #else template struct allocator_const_void_pointer { typedef typename pointer_traits::type>::template rebind_to::type type; }; template struct allocator_const_void_pointer::type> { typedef typename A::const_void_pointer type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_difference_type { typedef typename A::difference_type type; }; #else template struct allocator_difference_type { typedef typename pointer_traits::type>::difference_type type; }; template struct allocator_difference_type::type> { typedef typename A::difference_type type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_size_type { typedef typename A::size_type type; }; #else template struct allocator_size_type { typedef typename std::make_unsigned::type>::type type; }; template struct allocator_size_type::type> { typedef typename A::size_type type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) namespace detail { struct alloc_false { BOOST_STATIC_CONSTEXPR bool value = false; }; } /* detail */ template struct allocator_propagate_on_container_copy_assignment { typedef detail::alloc_false type; }; #else template struct allocator_propagate_on_container_copy_assignment { typedef std::false_type type; }; template struct allocator_propagate_on_container_copy_assignment::type> { typedef typename A::propagate_on_container_copy_assignment type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_propagate_on_container_move_assignment { typedef detail::alloc_false type; }; #else template struct allocator_propagate_on_container_move_assignment { typedef std::false_type type; }; template struct allocator_propagate_on_container_move_assignment::type> { typedef typename A::propagate_on_container_move_assignment type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_propagate_on_container_swap { typedef detail::alloc_false type; }; #else template struct allocator_propagate_on_container_swap { typedef std::false_type type; }; template struct allocator_propagate_on_container_swap::type> { typedef typename A::propagate_on_container_swap type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_is_always_equal { typedef detail::alloc_false type; }; #else template struct allocator_is_always_equal { typedef typename std::is_empty::type type; }; template struct allocator_is_always_equal::type> { typedef typename A::is_always_equal type; }; #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template struct allocator_rebind { typedef typename A::template rebind::other type; }; #else namespace detail { template struct alloc_to { }; template class A, class T, class U, class... V> struct alloc_to, T> { typedef A type; }; } /* detail */ template struct allocator_rebind { typedef typename detail::alloc_to::type type; }; template struct allocator_rebind::other>::type> { typedef typename A::template rebind::other type; }; #endif 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 { struct alloc_none { }; template class alloc_has_allocate { template static auto check(int) -> decltype(std::declval().allocate( std::declval::type>(), std::declval::type>())); template static alloc_none check(long); public: BOOST_STATIC_CONSTEXPR bool value = !std::is_same(0)), alloc_none>::value; }; } /* 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) -> decltype(std::declval().construct(std::declval(), std::declval()...)); template static alloc_none check(long); public: BOOST_STATIC_CONSTEXPR bool value = !std::is_same(0)), alloc_none>::value; }; } /* 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) -> decltype(std::declval().destroy(std::declval())); template static alloc_none check(long); public: BOOST_STATIC_CONSTEXPR bool value = !std::is_same(0)), alloc_none>::value; }; } /* 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 #if defined(BOOST_NO_CXX11_ALLOCATOR) template inline typename allocator_size_type::type allocator_max_size(const A& a) { return a.max_size(); } #else namespace detail { template class alloc_has_max_size { template static auto check(int) -> decltype(std::declval().max_size()); template static alloc_none check(long); public: BOOST_STATIC_CONSTEXPR bool value = !std::is_same(0)), alloc_none>::value; }; } /* detail */ template inline typename std::enable_if::value, typename allocator_size_type::type>::type allocator_max_size(const A& a) { return a.max_size(); } template inline typename std::enable_if::value, typename allocator_size_type::type>::type allocator_max_size(const A&) { return (std::numeric_limits::type>::max)() / sizeof(typename A::value_type); } #endif #if defined(BOOST_NO_CXX11_ALLOCATOR) template inline A allocator_select_on_container_copy_construction(const A& a) { return a; } #else namespace detail { template class alloc_has_soccc { template static auto check(int) -> decltype(std::declval().select_on_container_copy_construction()); template static alloc_none check(long); public: BOOST_STATIC_CONSTEXPR bool value = !std::is_same(0)), alloc_none>::value; }; } /* detail */ template inline typename std::enable_if::value, A>::type allocator_select_on_container_copy_construction(const A& a) { return a.select_on_container_copy_construction(); } template inline typename std::enable_if::value, A>::type allocator_select_on_container_copy_construction(const A& a) { return a; } #endif #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