1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_EXPERIMENTAL___MEMORY 11#define _LIBCPP_EXPERIMENTAL___MEMORY 12 13#include <__memory/allocator_arg_t.h> 14#include <__memory/uses_allocator.h> 15#include <__type_traits/conditional.h> 16#include <__type_traits/is_constructible.h> 17#include <__type_traits/is_convertible.h> 18#include <__type_traits/is_same.h> 19#include <experimental/__config> 20#include <experimental/utility> // for erased_type 21 22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 23# pragma GCC system_header 24#endif 25 26_LIBCPP_BEGIN_NAMESPACE_LFTS 27 28template < 29 class _Tp, class _Alloc 30 , bool = uses_allocator<_Tp, _Alloc>::value 31 , bool = __has_allocator_type<_Tp>::value 32 > 33struct __lfts_uses_allocator : public false_type {}; 34 35template <class _Tp, class _Alloc> 36struct __lfts_uses_allocator<_Tp, _Alloc, false, false> : public false_type {}; 37 38template <class _Tp, class _Alloc, bool HasAlloc> 39struct __lfts_uses_allocator<_Tp, _Alloc, true, HasAlloc> : public true_type {}; 40 41template <class _Tp, class _Alloc> 42struct __lfts_uses_allocator<_Tp, _Alloc, false, true> 43 : public integral_constant<bool 44 , is_convertible<_Alloc, typename _Tp::allocator_type>::value 45 || is_same<erased_type, typename _Tp::allocator_type>::value 46 > 47{}; 48 49template <bool _UsesAlloc, class _Tp, class _Alloc, class ..._Args> 50struct __lfts_uses_alloc_ctor_imp 51{ 52 static const int value = 0; 53}; 54 55template <class _Tp, class _Alloc, class ..._Args> 56struct __lfts_uses_alloc_ctor_imp<true, _Tp, _Alloc, _Args...> 57{ 58 static const bool __ic_first 59 = is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; 60 61 static const bool __ic_second = 62 __conditional_t< 63 __ic_first, 64 false_type, 65 is_constructible<_Tp, _Args..., _Alloc> 66 >::value; 67 68 static_assert(__ic_first || __ic_second, 69 "Request for uses allocator construction is ill-formed"); 70 71 static const int value = __ic_first ? 1 : 2; 72}; 73 74template <class _Tp, class _Alloc, class ..._Args> 75struct __lfts_uses_alloc_ctor 76 : integral_constant<int, 77 __lfts_uses_alloc_ctor_imp< 78 __lfts_uses_allocator<_Tp, _Alloc>::value 79 , _Tp, _Alloc, _Args... 80 >::value 81 > 82{}; 83 84template <class _Tp, class _Allocator, class... _Args> 85inline _LIBCPP_INLINE_VISIBILITY 86void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args ) 87{ 88 new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); 89} 90 91// FIXME: This should have a version which takes a non-const alloc. 92template <class _Tp, class _Allocator, class... _Args> 93inline _LIBCPP_INLINE_VISIBILITY 94void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) 95{ 96 new (__storage) _Tp (allocator_arg_t(), __a, _VSTD::forward<_Args>(__args)...); 97} 98 99// FIXME: This should have a version which takes a non-const alloc. 100template <class _Tp, class _Allocator, class... _Args> 101inline _LIBCPP_INLINE_VISIBILITY 102void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) 103{ 104 new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); 105} 106 107template <class _Tp, class _Alloc, class ..._Args> 108inline _LIBCPP_INLINE_VISIBILITY 109void __lfts_user_alloc_construct( 110 _Tp * __store, const _Alloc & __a, _Args &&... __args) 111{ 112 ::std::experimental::fundamentals_v1::__user_alloc_construct_impl( 113 typename __lfts_uses_alloc_ctor<_Tp, _Alloc, _Args...>::type() 114 , __store, __a, _VSTD::forward<_Args>(__args)... 115 ); 116} 117 118_LIBCPP_END_NAMESPACE_LFTS 119 120#endif /* _LIBCPP_EXPERIMENTAL___MEMORY */ 121