// -*- 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 <__cstddef/size_t.h> #include <__fwd/memory.h> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> #include <__type_traits/detected_or.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 #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 using __pointer_member _LIBCPP_NODEBUG = typename _Tp::pointer; template using __pointer _LIBCPP_NODEBUG = __detected_or_t<_Tp*, __pointer_member, __libcpp_remove_reference_t<_Alloc> >; // __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 _LIBCPP_NODEBUG = 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 template using __size_type_member _LIBCPP_NODEBUG = typename _Tp::size_type; template using __size_type _LIBCPP_NODEBUG = __detected_or_t<__make_unsigned_t<_DiffType>, __size_type_member, _Alloc>; // __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 template using __propagate_on_container_copy_assignment_member _LIBCPP_NODEBUG = typename _Tp::propagate_on_container_copy_assignment; template using __propagate_on_container_copy_assignment _LIBCPP_NODEBUG = __detected_or_t; // __propagate_on_container_move_assignment template using __propagate_on_container_move_assignment_member _LIBCPP_NODEBUG = typename _Tp::propagate_on_container_move_assignment; template using __propagate_on_container_move_assignment _LIBCPP_NODEBUG = __detected_or_t; // __propagate_on_container_swap template using __propagate_on_container_swap_member _LIBCPP_NODEBUG = typename _Tp::propagate_on_container_swap; template using __propagate_on_container_swap _LIBCPP_NODEBUG = __detected_or_t; // __is_always_equal template using __is_always_equal_member _LIBCPP_NODEBUG = typename _Tp::is_always_equal; template using __is_always_equal _LIBCPP_NODEBUG = __detected_or_t::type, __is_always_equal_member, _Alloc>; // __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