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