summaryrefslogtreecommitdiffstats
path: root/libcxx/include/__functional_base
diff options
context:
space:
mode:
authorMarshall Clow <mclow.lists@gmail.com>2013-09-12 02:11:16 +0000
committerMarshall Clow <mclow.lists@gmail.com>2013-09-12 02:11:16 +0000
commit50c003b5774247b12655f439be959d23ee356614 (patch)
treefc0e399e576d8ec6860e83a5a397bb7d5d6286c5 /libcxx/include/__functional_base
parent475e872489dd9a5474e4a5f395ccd64953711b11 (diff)
downloadbcm5719-llvm-50c003b5774247b12655f439be959d23ee356614.tar.gz
bcm5719-llvm-50c003b5774247b12655f439be959d23ee356614.zip
Implement uses-allocator construction
llvm-svn: 190571
Diffstat (limited to 'libcxx/include/__functional_base')
-rw-r--r--libcxx/include/__functional_base92
1 files changed, 92 insertions, 0 deletions
diff --git a/libcxx/include/__functional_base b/libcxx/include/__functional_base
index 72da75971b9..8927f9d7f37 100644
--- a/libcxx/include/__functional_base
+++ b/libcxx/include/__functional_base
@@ -15,6 +15,7 @@
#include <type_traits>
#include <typeinfo>
#include <exception>
+#include <new>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -515,6 +516,97 @@ public:
};
#endif
+// allocator_arg_t
+
+struct _LIBCPP_TYPE_VIS_ONLY allocator_arg_t { };
+
+#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
+extern const allocator_arg_t allocator_arg;
+#else
+constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+#endif
+
+// uses_allocator
+
+template <class _Tp>
+struct __has_allocator_type
+{
+private:
+ struct __two {char __lx; char __lxx;};
+ template <class _Up> static __two __test(...);
+ template <class _Up> static char __test(typename _Up::allocator_type* = 0);
+public:
+ static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
+struct __uses_allocator
+ : public integral_constant<bool,
+ is_convertible<_Alloc, typename _Tp::allocator_type>::value>
+{
+};
+
+template <class _Tp, class _Alloc>
+struct __uses_allocator<_Tp, _Alloc, false>
+ : public false_type
+{
+};
+
+template <class _Tp, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator
+ : public __uses_allocator<_Tp, _Alloc>
+{
+};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+// allocator construction
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __uses_alloc_ctor_imp
+{
+ static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
+ static const bool __ic =
+ is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
+ static const int value = __ua ? 2 - __ic : 0;
+};
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __uses_alloc_ctor
+ : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
+ {};
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
+{
+ new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
+{
+ new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
+{
+ new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
+}
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args)
+{
+ __user_alloc_construct_impl(
+ __uses_alloc_ctor<_Tp, _Allocator>(),
+ __storage, __a, _VSTD::forward<_Args>(__args)...
+ );
+}
+#endif // _LIBCPP_HAS_NO_VARIADICS
_LIBCPP_END_NAMESPACE_STD
OpenPOWER on IntegriCloud