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___FUNCTIONAL_ALLOCATOR_ARG_T_H 11#define _LIBCPP___FUNCTIONAL_ALLOCATOR_ARG_T_H 12 13#include <__config> 14#include <__memory/uses_allocator.h> 15#include <__type_traits/integral_constant.h> 16#include <__type_traits/is_constructible.h> 17#include <__type_traits/remove_cvref.h> 18#include <__utility/forward.h> 19 20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21# pragma GCC system_header 22#endif 23 24_LIBCPP_BEGIN_NAMESPACE_STD 25 26struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; }; 27 28#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) 29extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg; 30#else 31/* inline */ constexpr allocator_arg_t allocator_arg = allocator_arg_t(); 32#endif 33 34#ifndef _LIBCPP_CXX03_LANG 35 36// allocator construction 37 38template <class _Tp, class _Alloc, class ..._Args> 39struct __uses_alloc_ctor_imp 40{ 41 typedef _LIBCPP_NODEBUG __remove_cvref_t<_Alloc> _RawAlloc; 42 static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value; 43 static const bool __ic = 44 is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; 45 static const int value = __ua ? 2 - __ic : 0; 46}; 47 48template <class _Tp, class _Alloc, class ..._Args> 49struct __uses_alloc_ctor 50 : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value> 51 {}; 52 53template <class _Tp, class _Allocator, class... _Args> 54inline _LIBCPP_INLINE_VISIBILITY 55void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args ) 56{ 57 new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); 58} 59 60// FIXME: This should have a version which takes a non-const alloc. 61template <class _Tp, class _Allocator, class... _Args> 62inline _LIBCPP_INLINE_VISIBILITY 63void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) 64{ 65 new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); 66} 67 68// FIXME: This should have a version which takes a non-const alloc. 69template <class _Tp, class _Allocator, class... _Args> 70inline _LIBCPP_INLINE_VISIBILITY 71void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) 72{ 73 new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); 74} 75 76#endif // _LIBCPP_CXX03_LANG 77 78_LIBCPP_END_NAMESPACE_STD 79 80#endif // _LIBCPP___FUNCTIONAL_ALLOCATOR_ARG_T_H 81