libstdc++
|
00001 // Uses-allocator Construction -*- C++ -*- 00002 00003 // Copyright (C) 2010-2016 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 #ifndef _USES_ALLOCATOR_H 00026 #define _USES_ALLOCATOR_H 1 00027 00028 #if __cplusplus < 201103L 00029 # include <bits/c++0x_warning.h> 00030 #else 00031 00032 #include <type_traits> 00033 #include <bits/move.h> 00034 00035 namespace std _GLIBCXX_VISIBILITY(default) 00036 { 00037 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00038 00039 struct __erased_type { }; 00040 00041 template<typename _Alloc, typename _Tp> 00042 using __is_erased_or_convertible 00043 = __or_<is_same<_Tp, __erased_type>, is_convertible<_Alloc, _Tp>>; 00044 00045 /// [allocator.tag] 00046 struct allocator_arg_t { explicit allocator_arg_t() = default; }; 00047 00048 constexpr allocator_arg_t allocator_arg = allocator_arg_t(); 00049 00050 template<typename _Tp, typename _Alloc, typename = __void_t<>> 00051 struct __uses_allocator_helper 00052 : false_type { }; 00053 00054 template<typename _Tp, typename _Alloc> 00055 struct __uses_allocator_helper<_Tp, _Alloc, 00056 __void_t<typename _Tp::allocator_type>> 00057 : __is_erased_or_convertible<_Alloc, typename _Tp::allocator_type>::type 00058 { }; 00059 00060 /// [allocator.uses.trait] 00061 template<typename _Tp, typename _Alloc> 00062 struct uses_allocator 00063 : __uses_allocator_helper<_Tp, _Alloc>::type 00064 { }; 00065 00066 struct __uses_alloc_base { }; 00067 00068 struct __uses_alloc0 : __uses_alloc_base 00069 { 00070 struct _Sink { void operator=(const void*) { } } _M_a; 00071 }; 00072 00073 template<typename _Alloc> 00074 struct __uses_alloc1 : __uses_alloc_base { const _Alloc* _M_a; }; 00075 00076 template<typename _Alloc> 00077 struct __uses_alloc2 : __uses_alloc_base { const _Alloc* _M_a; }; 00078 00079 template<bool, typename _Tp, typename _Alloc, typename... _Args> 00080 struct __uses_alloc; 00081 00082 template<typename _Tp, typename _Alloc, typename... _Args> 00083 struct __uses_alloc<true, _Tp, _Alloc, _Args...> 00084 : conditional< 00085 is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value, 00086 __uses_alloc1<_Alloc>, 00087 __uses_alloc2<_Alloc>>::type 00088 { 00089 static_assert(__or_< 00090 is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>, 00091 is_constructible<_Tp, _Args..., _Alloc>>::value, "construction with" 00092 " an allocator must be possible if uses_allocator is true"); 00093 }; 00094 00095 template<typename _Tp, typename _Alloc, typename... _Args> 00096 struct __uses_alloc<false, _Tp, _Alloc, _Args...> 00097 : __uses_alloc0 { }; 00098 00099 template<typename _Tp, typename _Alloc, typename... _Args> 00100 using __uses_alloc_t = 00101 __uses_alloc<uses_allocator<_Tp, _Alloc>::value, _Tp, _Alloc, _Args...>; 00102 00103 template<typename _Tp, typename _Alloc, typename... _Args> 00104 inline __uses_alloc_t<_Tp, _Alloc, _Args...> 00105 __use_alloc(const _Alloc& __a) 00106 { 00107 __uses_alloc_t<_Tp, _Alloc, _Args...> __ret; 00108 __ret._M_a = std::__addressof(__a); 00109 return __ret; 00110 } 00111 00112 _GLIBCXX_END_NAMESPACE_VERSION 00113 } // namespace std 00114 00115 #endif 00116 #endif