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