00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef ABSL_STRINGS_INTERNAL_STL_TYPE_TRAITS_H_
00026 #define ABSL_STRINGS_INTERNAL_STL_TYPE_TRAITS_H_
00027
00028 #include <array>
00029 #include <bitset>
00030 #include <deque>
00031 #include <forward_list>
00032 #include <list>
00033 #include <map>
00034 #include <set>
00035 #include <type_traits>
00036 #include <unordered_map>
00037 #include <unordered_set>
00038 #include <vector>
00039
00040 #include "absl/meta/type_traits.h"
00041
00042 namespace absl {
00043 namespace strings_internal {
00044
00045 template <typename C, template <typename...> class T>
00046 struct IsSpecializationImpl : std::false_type {};
00047 template <template <typename...> class T, typename... Args>
00048 struct IsSpecializationImpl<T<Args...>, T> : std::true_type {};
00049 template <typename C, template <typename...> class T>
00050 using IsSpecialization = IsSpecializationImpl<absl::decay_t<C>, T>;
00051
00052 template <typename C>
00053 struct IsArrayImpl : std::false_type {};
00054 template <template <typename, size_t> class A, typename T, size_t N>
00055 struct IsArrayImpl<A<T, N>> : std::is_same<A<T, N>, std::array<T, N>> {};
00056 template <typename C>
00057 using IsArray = IsArrayImpl<absl::decay_t<C>>;
00058
00059 template <typename C>
00060 struct IsBitsetImpl : std::false_type {};
00061 template <template <size_t> class B, size_t N>
00062 struct IsBitsetImpl<B<N>> : std::is_same<B<N>, std::bitset<N>> {};
00063 template <typename C>
00064 using IsBitset = IsBitsetImpl<absl::decay_t<C>>;
00065
00066 template <typename C>
00067 struct IsSTLContainer
00068 : absl::disjunction<
00069 IsArray<C>, IsBitset<C>, IsSpecialization<C, std::deque>,
00070 IsSpecialization<C, std::forward_list>,
00071 IsSpecialization<C, std::list>, IsSpecialization<C, std::map>,
00072 IsSpecialization<C, std::multimap>, IsSpecialization<C, std::set>,
00073 IsSpecialization<C, std::multiset>,
00074 IsSpecialization<C, std::unordered_map>,
00075 IsSpecialization<C, std::unordered_multimap>,
00076 IsSpecialization<C, std::unordered_set>,
00077 IsSpecialization<C, std::unordered_multiset>,
00078 IsSpecialization<C, std::vector>> {};
00079
00080 template <typename C, template <typename...> class T, typename = void>
00081 struct IsBaseOfSpecializationImpl : std::false_type {};
00082
00083
00084
00085 template <typename C, template <typename, typename> class T>
00086 struct IsBaseOfSpecializationImpl<
00087 C, T, absl::void_t<typename C::value_type, typename C::allocator_type>>
00088 : std::is_base_of<C,
00089 T<typename C::value_type, typename C::allocator_type>> {};
00090 template <typename C, template <typename, typename, typename> class T>
00091 struct IsBaseOfSpecializationImpl<
00092 C, T,
00093 absl::void_t<typename C::key_type, typename C::key_compare,
00094 typename C::allocator_type>>
00095 : std::is_base_of<C, T<typename C::key_type, typename C::key_compare,
00096 typename C::allocator_type>> {};
00097 template <typename C, template <typename, typename, typename, typename> class T>
00098 struct IsBaseOfSpecializationImpl<
00099 C, T,
00100 absl::void_t<typename C::key_type, typename C::mapped_type,
00101 typename C::key_compare, typename C::allocator_type>>
00102 : std::is_base_of<C,
00103 T<typename C::key_type, typename C::mapped_type,
00104 typename C::key_compare, typename C::allocator_type>> {
00105 };
00106 template <typename C, template <typename, typename, typename, typename> class T>
00107 struct IsBaseOfSpecializationImpl<
00108 C, T,
00109 absl::void_t<typename C::key_type, typename C::hasher,
00110 typename C::key_equal, typename C::allocator_type>>
00111 : std::is_base_of<C, T<typename C::key_type, typename C::hasher,
00112 typename C::key_equal, typename C::allocator_type>> {
00113 };
00114 template <typename C,
00115 template <typename, typename, typename, typename, typename> class T>
00116 struct IsBaseOfSpecializationImpl<
00117 C, T,
00118 absl::void_t<typename C::key_type, typename C::mapped_type,
00119 typename C::hasher, typename C::key_equal,
00120 typename C::allocator_type>>
00121 : std::is_base_of<C, T<typename C::key_type, typename C::mapped_type,
00122 typename C::hasher, typename C::key_equal,
00123 typename C::allocator_type>> {};
00124 template <typename C, template <typename...> class T>
00125 using IsBaseOfSpecialization = IsBaseOfSpecializationImpl<absl::decay_t<C>, T>;
00126
00127 template <typename C>
00128 struct IsBaseOfArrayImpl : std::false_type {};
00129 template <template <typename, size_t> class A, typename T, size_t N>
00130 struct IsBaseOfArrayImpl<A<T, N>> : std::is_base_of<A<T, N>, std::array<T, N>> {
00131 };
00132 template <typename C>
00133 using IsBaseOfArray = IsBaseOfArrayImpl<absl::decay_t<C>>;
00134
00135 template <typename C>
00136 struct IsBaseOfBitsetImpl : std::false_type {};
00137 template <template <size_t> class B, size_t N>
00138 struct IsBaseOfBitsetImpl<B<N>> : std::is_base_of<B<N>, std::bitset<N>> {};
00139 template <typename C>
00140 using IsBaseOfBitset = IsBaseOfBitsetImpl<absl::decay_t<C>>;
00141
00142 template <typename C>
00143 struct IsBaseOfSTLContainer
00144 : absl::disjunction<IsBaseOfArray<C>, IsBaseOfBitset<C>,
00145 IsBaseOfSpecialization<C, std::deque>,
00146 IsBaseOfSpecialization<C, std::forward_list>,
00147 IsBaseOfSpecialization<C, std::list>,
00148 IsBaseOfSpecialization<C, std::map>,
00149 IsBaseOfSpecialization<C, std::multimap>,
00150 IsBaseOfSpecialization<C, std::set>,
00151 IsBaseOfSpecialization<C, std::multiset>,
00152 IsBaseOfSpecialization<C, std::unordered_map>,
00153 IsBaseOfSpecialization<C, std::unordered_multimap>,
00154 IsBaseOfSpecialization<C, std::unordered_set>,
00155 IsBaseOfSpecialization<C, std::unordered_multiset>,
00156 IsBaseOfSpecialization<C, std::vector>> {};
00157
00158 template <typename C, template <typename...> class T, typename = void>
00159 struct IsConvertibleToSpecializationImpl : std::false_type {};
00160
00161
00162
00163 template <typename C, template <typename, typename> class T>
00164 struct IsConvertibleToSpecializationImpl<
00165 C, T, absl::void_t<typename C::value_type, typename C::allocator_type>>
00166 : std::is_convertible<
00167 C, T<typename C::value_type, typename C::allocator_type>> {};
00168 template <typename C, template <typename, typename, typename> class T>
00169 struct IsConvertibleToSpecializationImpl<
00170 C, T,
00171 absl::void_t<typename C::key_type, typename C::key_compare,
00172 typename C::allocator_type>>
00173 : std::is_convertible<C, T<typename C::key_type, typename C::key_compare,
00174 typename C::allocator_type>> {};
00175 template <typename C, template <typename, typename, typename, typename> class T>
00176 struct IsConvertibleToSpecializationImpl<
00177 C, T,
00178 absl::void_t<typename C::key_type, typename C::mapped_type,
00179 typename C::key_compare, typename C::allocator_type>>
00180 : std::is_convertible<
00181 C, T<typename C::key_type, typename C::mapped_type,
00182 typename C::key_compare, typename C::allocator_type>> {};
00183 template <typename C, template <typename, typename, typename, typename> class T>
00184 struct IsConvertibleToSpecializationImpl<
00185 C, T,
00186 absl::void_t<typename C::key_type, typename C::hasher,
00187 typename C::key_equal, typename C::allocator_type>>
00188 : std::is_convertible<
00189 C, T<typename C::key_type, typename C::hasher, typename C::key_equal,
00190 typename C::allocator_type>> {};
00191 template <typename C,
00192 template <typename, typename, typename, typename, typename> class T>
00193 struct IsConvertibleToSpecializationImpl<
00194 C, T,
00195 absl::void_t<typename C::key_type, typename C::mapped_type,
00196 typename C::hasher, typename C::key_equal,
00197 typename C::allocator_type>>
00198 : std::is_convertible<C, T<typename C::key_type, typename C::mapped_type,
00199 typename C::hasher, typename C::key_equal,
00200 typename C::allocator_type>> {};
00201 template <typename C, template <typename...> class T>
00202 using IsConvertibleToSpecialization =
00203 IsConvertibleToSpecializationImpl<absl::decay_t<C>, T>;
00204
00205 template <typename C>
00206 struct IsConvertibleToArrayImpl : std::false_type {};
00207 template <template <typename, size_t> class A, typename T, size_t N>
00208 struct IsConvertibleToArrayImpl<A<T, N>>
00209 : std::is_convertible<A<T, N>, std::array<T, N>> {};
00210 template <typename C>
00211 using IsConvertibleToArray = IsConvertibleToArrayImpl<absl::decay_t<C>>;
00212
00213 template <typename C>
00214 struct IsConvertibleToBitsetImpl : std::false_type {};
00215 template <template <size_t> class B, size_t N>
00216 struct IsConvertibleToBitsetImpl<B<N>>
00217 : std::is_convertible<B<N>, std::bitset<N>> {};
00218 template <typename C>
00219 using IsConvertibleToBitset = IsConvertibleToBitsetImpl<absl::decay_t<C>>;
00220
00221 template <typename C>
00222 struct IsConvertibleToSTLContainer
00223 : absl::disjunction<
00224 IsConvertibleToArray<C>, IsConvertibleToBitset<C>,
00225 IsConvertibleToSpecialization<C, std::deque>,
00226 IsConvertibleToSpecialization<C, std::forward_list>,
00227 IsConvertibleToSpecialization<C, std::list>,
00228 IsConvertibleToSpecialization<C, std::map>,
00229 IsConvertibleToSpecialization<C, std::multimap>,
00230 IsConvertibleToSpecialization<C, std::set>,
00231 IsConvertibleToSpecialization<C, std::multiset>,
00232 IsConvertibleToSpecialization<C, std::unordered_map>,
00233 IsConvertibleToSpecialization<C, std::unordered_multimap>,
00234 IsConvertibleToSpecialization<C, std::unordered_set>,
00235 IsConvertibleToSpecialization<C, std::unordered_multiset>,
00236 IsConvertibleToSpecialization<C, std::vector>> {};
00237
00238 template <typename C>
00239 struct IsStrictlyBaseOfAndConvertibleToSTLContainer
00240 : absl::conjunction<absl::negation<IsSTLContainer<C>>,
00241 IsBaseOfSTLContainer<C>,
00242 IsConvertibleToSTLContainer<C>> {};
00243
00244 }
00245 }
00246 #endif // ABSL_STRINGS_INTERNAL_STL_TYPE_TRAITS_H_