// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H #define _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H #include <__config> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_constructible.h> #include <__type_traits/is_empty.h> #include <__type_traits/is_same.h> #include <__type_traits/make_unsigned.h> #include <__type_traits/remove_reference.h> #include <__type_traits/void_t.h> #include <__utility/declval.h> #include <__utility/forward.h> #include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif _LIBCPP_PUSH_MACROS #include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD #define _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(NAME, PROPERTY) \ template \ struct NAME : false_type {}; \ template \ struct NAME<_Tp, __void_t > : true_type {} // __pointer template , bool = __has_pointer<_RawAlloc>::value> struct __pointer { using type _LIBCPP_NODEBUG = typename _RawAlloc::pointer; }; template struct __pointer<_Tp, _Alloc, _RawAlloc, false> { using type _LIBCPP_NODEBUG = _Tp*; }; // __const_pointer _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_const_pointer, const_pointer); template ::value> struct __const_pointer { using type _LIBCPP_NODEBUG = typename _Alloc::const_pointer; }; template struct __const_pointer<_Tp, _Ptr, _Alloc, false> { #ifdef _LIBCPP_CXX03_LANG using type = typename pointer_traits<_Ptr>::template rebind::other; #else using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind; #endif }; // __void_pointer _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_void_pointer, void_pointer); template ::value> struct __void_pointer { using type _LIBCPP_NODEBUG = typename _Alloc::void_pointer; }; template struct __void_pointer<_Ptr, _Alloc, false> { #ifdef _LIBCPP_CXX03_LANG using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind::other; #else using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind; #endif }; // __const_void_pointer _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_const_void_pointer, const_void_pointer); template ::value> struct __const_void_pointer { using type _LIBCPP_NODEBUG = typename _Alloc::const_void_pointer; }; template struct __const_void_pointer<_Ptr, _Alloc, false> { #ifdef _LIBCPP_CXX03_LANG using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind::other; #else using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind; #endif }; // __size_type _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_size_type, size_type); template ::value> struct __size_type : make_unsigned<_DiffType> {}; template struct __size_type<_Alloc, _DiffType, true> { using type _LIBCPP_NODEBUG = typename _Alloc::size_type; }; // __alloc_traits_difference_type _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_alloc_traits_difference_type, difference_type); template ::value> struct __alloc_traits_difference_type { using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::difference_type; }; template struct __alloc_traits_difference_type<_Alloc, _Ptr, true> { using type _LIBCPP_NODEBUG = typename _Alloc::difference_type; }; // __propagate_on_container_copy_assignment _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_copy_assignment, propagate_on_container_copy_assignment); template ::value> struct __propagate_on_container_copy_assignment : false_type {}; template struct __propagate_on_container_copy_assignment<_Alloc, true> { using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_copy_assignment; }; // __propagate_on_container_move_assignment _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_move_assignment, propagate_on_container_move_assignment); template ::value> struct __propagate_on_container_move_assignment : false_type {}; template struct __propagate_on_container_move_assignment<_Alloc, true> { using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_move_assignment; }; // __propagate_on_container_swap _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_swap, propagate_on_container_swap); template ::value> struct __propagate_on_container_swap : false_type {}; template struct __propagate_on_container_swap<_Alloc, true> { using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_swap; }; // __is_always_equal _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_is_always_equal, is_always_equal); template ::value> struct __is_always_equal : is_empty<_Alloc> {}; template struct __is_always_equal<_Alloc, true> { using type _LIBCPP_NODEBUG = typename _Alloc::is_always_equal; }; // __allocator_traits_rebind _LIBCPP_SUPPRESS_DEPRECATED_PUSH template struct __has_rebind_other : false_type {}; template struct __has_rebind_other<_Tp, _Up, __void_t::other> > : true_type {}; template ::value> struct __allocator_traits_rebind { static_assert(__has_rebind_other<_Tp, _Up>::value, "This allocator has to implement rebind"); using type _LIBCPP_NODEBUG = typename _Tp::template rebind<_Up>::other; }; template