blob: 229fea605bfd33ad6f7c4491fab72f0b82356181 [file] [log] [blame]
Eric Fiselier257fd692016-05-07 01:04:55 +00001// -*- 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
21template <
22 class _Tp, class _Alloc
23 , bool = uses_allocator<_Tp, _Alloc>::value
24 , bool = __has_allocator_type<_Tp>::value
25 >
26struct __lfts_uses_allocator : public false_type {};
27
28template <class _Tp, class _Alloc>
29struct __lfts_uses_allocator<_Tp, _Alloc, false, false> : public false_type {};
30
31template <class _Tp, class _Alloc, bool HasAlloc>
32struct __lfts_uses_allocator<_Tp, _Alloc, true, HasAlloc> : public true_type {};
33
34template <class _Tp, class _Alloc>
35struct __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
42template <bool _UsesAlloc, class _Tp, class _Alloc, class ..._Args>
43struct __lfts_uses_alloc_ctor_imp
44{
45 static const int value = 0;
46};
47
48template <class _Tp, class _Alloc, class ..._Args>
49struct __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
67template <class _Tp, class _Alloc, class ..._Args>
68struct __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
77template <class _Tp, class _Alloc, class ..._Args>
78inline _LIBCPP_INLINE_VISIBILITY
79void __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 */