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 <experimental/__config> 16#include <experimental/utility> // for erased_type 17#include <__functional_base> 18#include <type_traits> 19 20_LIBCPP_BEGIN_NAMESPACE_LFTS 21 22template < 23 class _Tp, class _Alloc 24 , bool = uses_allocator<_Tp, _Alloc>::value 25 , bool = __has_allocator_type<_Tp>::value 26 > 27struct __lfts_uses_allocator : public false_type {}; 28 29template <class _Tp, class _Alloc> 30struct __lfts_uses_allocator<_Tp, _Alloc, false, false> : public false_type {}; 31 32template <class _Tp, class _Alloc, bool HasAlloc> 33struct __lfts_uses_allocator<_Tp, _Alloc, true, HasAlloc> : public true_type {}; 34 35template <class _Tp, class _Alloc> 36struct __lfts_uses_allocator<_Tp, _Alloc, false, true> 37 : public integral_constant<bool 38 , is_convertible<_Alloc, typename _Tp::allocator_type>::value 39 || is_same<erased_type, typename _Tp::allocator_type>::value 40 > 41{}; 42 43template <bool _UsesAlloc, class _Tp, class _Alloc, class ..._Args> 44struct __lfts_uses_alloc_ctor_imp 45{ 46 static const int value = 0; 47}; 48 49template <class _Tp, class _Alloc, class ..._Args> 50struct __lfts_uses_alloc_ctor_imp<true, _Tp, _Alloc, _Args...> 51{ 52 static const bool __ic_first 53 = is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; 54 55 static const bool __ic_second = 56 conditional< 57 __ic_first, 58 false_type, 59 is_constructible<_Tp, _Args..., _Alloc> 60 >::type::value; 61 62 static_assert(__ic_first || __ic_second, 63 "Request for uses allocator construction is ill-formed"); 64 65 static const int value = __ic_first ? 1 : 2; 66}; 67 68template <class _Tp, class _Alloc, class ..._Args> 69struct __lfts_uses_alloc_ctor 70 : integral_constant<int, 71 __lfts_uses_alloc_ctor_imp< 72 __lfts_uses_allocator<_Tp, _Alloc>::value 73 , _Tp, _Alloc, _Args... 74 >::value 75 > 76{}; 77 78template <class _Tp, class _Allocator, class... _Args> 79inline _LIBCPP_INLINE_VISIBILITY 80void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args ) 81{ 82 new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); 83} 84 85// FIXME: This should have a version which takes a non-const alloc. 86template <class _Tp, class _Allocator, class... _Args> 87inline _LIBCPP_INLINE_VISIBILITY 88void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) 89{ 90 new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); 91} 92 93// FIXME: This should have a version which takes a non-const alloc. 94template <class _Tp, class _Allocator, class... _Args> 95inline _LIBCPP_INLINE_VISIBILITY 96void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) 97{ 98 new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); 99} 100 101template <class _Tp, class _Alloc, class ..._Args> 102inline _LIBCPP_INLINE_VISIBILITY 103void __lfts_user_alloc_construct( 104 _Tp * __store, const _Alloc & __a, _Args &&... __args) 105{ 106 ::std::experimental::fundamentals_v1::__user_alloc_construct_impl( 107 typename __lfts_uses_alloc_ctor<_Tp, _Alloc, _Args...>::type() 108 , __store, __a, _VSTD::forward<_Args>(__args)... 109 ); 110} 111 112_LIBCPP_END_NAMESPACE_LFTS 113 114#endif /* _LIBCPP_EXPERIMENTAL___MEMORY */ 115