__memory 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. #ifndef _LIBCPP_EXPERIMENTAL___MEMORY
  10. #define _LIBCPP_EXPERIMENTAL___MEMORY
  11. #include <__memory/allocator_arg_t.h>
  12. #include <__memory/uses_allocator.h>
  13. #include <experimental/__config>
  14. #include <experimental/utility> // for erased_type
  15. #include <type_traits>
  16. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  17. # pragma GCC system_header
  18. #endif
  19. _LIBCPP_BEGIN_NAMESPACE_LFTS
  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. template <class _Tp, class _Alloc>
  27. struct __lfts_uses_allocator<_Tp, _Alloc, false, false> : public false_type {};
  28. template <class _Tp, class _Alloc, bool HasAlloc>
  29. struct __lfts_uses_allocator<_Tp, _Alloc, true, HasAlloc> : public true_type {};
  30. template <class _Tp, class _Alloc>
  31. struct __lfts_uses_allocator<_Tp, _Alloc, false, true>
  32. : public integral_constant<bool
  33. , is_convertible<_Alloc, typename _Tp::allocator_type>::value
  34. || is_same<erased_type, typename _Tp::allocator_type>::value
  35. >
  36. {};
  37. template <bool _UsesAlloc, class _Tp, class _Alloc, class ..._Args>
  38. struct __lfts_uses_alloc_ctor_imp
  39. {
  40. static const int value = 0;
  41. };
  42. template <class _Tp, class _Alloc, class ..._Args>
  43. struct __lfts_uses_alloc_ctor_imp<true, _Tp, _Alloc, _Args...>
  44. {
  45. static const bool __ic_first
  46. = is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
  47. static const bool __ic_second =
  48. conditional<
  49. __ic_first,
  50. false_type,
  51. is_constructible<_Tp, _Args..., _Alloc>
  52. >::type::value;
  53. static_assert(__ic_first || __ic_second,
  54. "Request for uses allocator construction is ill-formed");
  55. static const int value = __ic_first ? 1 : 2;
  56. };
  57. template <class _Tp, class _Alloc, class ..._Args>
  58. struct __lfts_uses_alloc_ctor
  59. : integral_constant<int,
  60. __lfts_uses_alloc_ctor_imp<
  61. __lfts_uses_allocator<_Tp, _Alloc>::value
  62. , _Tp, _Alloc, _Args...
  63. >::value
  64. >
  65. {};
  66. template <class _Tp, class _Allocator, class... _Args>
  67. inline _LIBCPP_INLINE_VISIBILITY
  68. void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
  69. {
  70. new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
  71. }
  72. // FIXME: This should have a version which takes a non-const alloc.
  73. template <class _Tp, class _Allocator, class... _Args>
  74. inline _LIBCPP_INLINE_VISIBILITY
  75. void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
  76. {
  77. new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
  78. }
  79. // FIXME: This should have a version which takes a non-const alloc.
  80. template <class _Tp, class _Allocator, class... _Args>
  81. inline _LIBCPP_INLINE_VISIBILITY
  82. void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
  83. {
  84. new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
  85. }
  86. template <class _Tp, class _Alloc, class ..._Args>
  87. inline _LIBCPP_INLINE_VISIBILITY
  88. void __lfts_user_alloc_construct(
  89. _Tp * __store, const _Alloc & __a, _Args &&... __args)
  90. {
  91. ::std::experimental::fundamentals_v1::__user_alloc_construct_impl(
  92. typename __lfts_uses_alloc_ctor<_Tp, _Alloc, _Args...>::type()
  93. , __store, __a, _VSTD::forward<_Args>(__args)...
  94. );
  95. }
  96. _LIBCPP_END_NAMESPACE_LFTS
  97. #endif /* _LIBCPP_EXPERIMENTAL___MEMORY */