1*7c82a1ecSDimitry Andric// -*- C++ -*- 2*7c82a1ecSDimitry Andric//===----------------------------------------------------------------------===// 3*7c82a1ecSDimitry Andric// 4*7c82a1ecSDimitry Andric// The LLVM Compiler Infrastructure 5*7c82a1ecSDimitry Andric// 6*7c82a1ecSDimitry Andric// This file is dual licensed under the MIT and the University of Illinois Open 7*7c82a1ecSDimitry Andric// Source Licenses. See LICENSE.TXT for details. 8*7c82a1ecSDimitry Andric// 9*7c82a1ecSDimitry Andric//===----------------------------------------------------------------------===// 10*7c82a1ecSDimitry Andric 11*7c82a1ecSDimitry Andric#ifndef _LIBCPP_EXPERIMENTAL___MEMORY 12*7c82a1ecSDimitry Andric#define _LIBCPP_EXPERIMENTAL___MEMORY 13*7c82a1ecSDimitry Andric 14*7c82a1ecSDimitry Andric#include <experimental/__config> 15*7c82a1ecSDimitry Andric#include <experimental/utility> // for erased_type 16*7c82a1ecSDimitry Andric#include <__functional_base> 17*7c82a1ecSDimitry Andric#include <type_traits> 18*7c82a1ecSDimitry Andric 19*7c82a1ecSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS 20*7c82a1ecSDimitry Andric 21*7c82a1ecSDimitry Andrictemplate < 22*7c82a1ecSDimitry Andric class _Tp, class _Alloc 23*7c82a1ecSDimitry Andric , bool = uses_allocator<_Tp, _Alloc>::value 24*7c82a1ecSDimitry Andric , bool = __has_allocator_type<_Tp>::value 25*7c82a1ecSDimitry Andric > 26*7c82a1ecSDimitry Andricstruct __lfts_uses_allocator : public false_type {}; 27*7c82a1ecSDimitry Andric 28*7c82a1ecSDimitry Andrictemplate <class _Tp, class _Alloc> 29*7c82a1ecSDimitry Andricstruct __lfts_uses_allocator<_Tp, _Alloc, false, false> : public false_type {}; 30*7c82a1ecSDimitry Andric 31*7c82a1ecSDimitry Andrictemplate <class _Tp, class _Alloc, bool HasAlloc> 32*7c82a1ecSDimitry Andricstruct __lfts_uses_allocator<_Tp, _Alloc, true, HasAlloc> : public true_type {}; 33*7c82a1ecSDimitry Andric 34*7c82a1ecSDimitry Andrictemplate <class _Tp, class _Alloc> 35*7c82a1ecSDimitry Andricstruct __lfts_uses_allocator<_Tp, _Alloc, false, true> 36*7c82a1ecSDimitry Andric : public integral_constant<bool 37*7c82a1ecSDimitry Andric , is_convertible<_Alloc, typename _Tp::allocator_type>::value 38*7c82a1ecSDimitry Andric || is_same<erased_type, typename _Tp::allocator_type>::value 39*7c82a1ecSDimitry Andric > 40*7c82a1ecSDimitry Andric{}; 41*7c82a1ecSDimitry Andric 42*7c82a1ecSDimitry Andrictemplate <bool _UsesAlloc, class _Tp, class _Alloc, class ..._Args> 43*7c82a1ecSDimitry Andricstruct __lfts_uses_alloc_ctor_imp 44*7c82a1ecSDimitry Andric{ 45*7c82a1ecSDimitry Andric static const int value = 0; 46*7c82a1ecSDimitry Andric}; 47*7c82a1ecSDimitry Andric 48*7c82a1ecSDimitry Andrictemplate <class _Tp, class _Alloc, class ..._Args> 49*7c82a1ecSDimitry Andricstruct __lfts_uses_alloc_ctor_imp<true, _Tp, _Alloc, _Args...> 50*7c82a1ecSDimitry Andric{ 51*7c82a1ecSDimitry Andric static const bool __ic_first 52*7c82a1ecSDimitry Andric = is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; 53*7c82a1ecSDimitry Andric 54*7c82a1ecSDimitry Andric static const bool __ic_second = 55*7c82a1ecSDimitry Andric conditional< 56*7c82a1ecSDimitry Andric __ic_first, 57*7c82a1ecSDimitry Andric false_type, 58*7c82a1ecSDimitry Andric is_constructible<_Tp, _Args..., _Alloc> 59*7c82a1ecSDimitry Andric >::type::value; 60*7c82a1ecSDimitry Andric 61*7c82a1ecSDimitry Andric static_assert(__ic_first || __ic_second, 62*7c82a1ecSDimitry Andric "Request for uses allocator construction is ill-formed"); 63*7c82a1ecSDimitry Andric 64*7c82a1ecSDimitry Andric static const int value = __ic_first ? 1 : 2; 65*7c82a1ecSDimitry Andric}; 66*7c82a1ecSDimitry Andric 67*7c82a1ecSDimitry Andrictemplate <class _Tp, class _Alloc, class ..._Args> 68*7c82a1ecSDimitry Andricstruct __lfts_uses_alloc_ctor 69*7c82a1ecSDimitry Andric : integral_constant<int, 70*7c82a1ecSDimitry Andric __lfts_uses_alloc_ctor_imp< 71*7c82a1ecSDimitry Andric __lfts_uses_allocator<_Tp, _Alloc>::value 72*7c82a1ecSDimitry Andric , _Tp, _Alloc, _Args... 73*7c82a1ecSDimitry Andric >::value 74*7c82a1ecSDimitry Andric > 75*7c82a1ecSDimitry Andric{}; 76*7c82a1ecSDimitry Andric 77*7c82a1ecSDimitry Andrictemplate <class _Tp, class _Alloc, class ..._Args> 78*7c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 79*7c82a1ecSDimitry Andricvoid __lfts_user_alloc_construct( 80*7c82a1ecSDimitry Andric _Tp * __store, const _Alloc & __a, _Args &&... __args) 81*7c82a1ecSDimitry Andric{ 82*7c82a1ecSDimitry Andric _VSTD::__user_alloc_construct_impl( 83*7c82a1ecSDimitry Andric typename __lfts_uses_alloc_ctor<_Tp, _Alloc, _Args...>::type() 84*7c82a1ecSDimitry Andric , __store, __a, _VSTD::forward<_Args>(__args)... 85*7c82a1ecSDimitry Andric ); 86*7c82a1ecSDimitry Andric} 87*7c82a1ecSDimitry Andric 88*7c82a1ecSDimitry Andric_LIBCPP_END_NAMESPACE_LFTS 89*7c82a1ecSDimitry Andric 90*7c82a1ecSDimitry Andric#endif /* _LIBCPP_EXPERIMENTAL___MEMORY */ 91