1 //
2 // Copyright 2017 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // -----------------------------------------------------------------------------
17 // type_traits.h
18 // -----------------------------------------------------------------------------
19 //
20 // This file contains C++11-compatible versions of standard <type_traits> API
21 // functions for determining the characteristics of types. Such traits can
22 // support type inference, classification, and transformation, as well as
23 // make it easier to write templates based on generic type behavior.
24 //
25 // See http://en.cppreference.com/w/cpp/header/type_traits
26 //
27 // WARNING: use of many of the constructs in this header will count as "complex
28 // template metaprogramming", so before proceeding, please carefully consider
29 // https://google.github.io/styleguide/cppguide.html#Template_metaprogramming
30 //
31 // WARNING: using template metaprogramming to detect or depend on API
32 // features is brittle and not guaranteed. Neither the standard library nor
33 // Abseil provides any guarantee that APIs are stable in the face of template
34 // metaprogramming. Use with caution.
35 #ifndef S2_THIRD_PARTY_ABSL_META_TYPE_TRAITS_H_
36 #define S2_THIRD_PARTY_ABSL_META_TYPE_TRAITS_H_
37 
38 #include <cstddef>
39 #include <functional>
40 #include <type_traits>
41 
42 #include "s2/third_party/absl/base/config.h"
43 
44 namespace absl {
45 
46 namespace type_traits_internal {
47 
48 template <typename... Ts>
49 struct VoidTImpl {
50   using type = void;
51 };
52 
53 // This trick to retrieve a default alignment is necessary for our
54 // implementation of aligned_storage_t to be consistent with any implementation
55 // of std::aligned_storage.
56 template <size_t Len, typename T = std::aligned_storage<Len>>
57 struct default_alignment_of_aligned_storage;
58 
59 template <size_t Len, size_t Align>
60 struct default_alignment_of_aligned_storage<Len,
61                                             std::aligned_storage<Len, Align>> {
62   static constexpr size_t value = Align;
63 };
64 
65 ////////////////////////////////
66 // Library Fundamentals V2 TS //
67 ////////////////////////////////
68 
69 // NOTE: The `is_detected` family of templates here differ from the library
70 // fundamentals specification in that for library fundamentals, `Op<Args...>` is
71 // evaluated as soon as the type `is_detected<Op, Args...>` undergoes
72 // substitution, regardless of whether or not the `::value` is accessed. That
73 // is inconsistent with all other standard traits and prevents lazy evaluation
74 // in larger contexts (such as if the `is_detected` check is a trailing argument
75 // of a `conjunction`. This implementation opts to instead be lazy in the same
76 // way that the standard traits are (this "defect" of the detection idiom
77 // specifications has been reported).
78 
79 template <class Enabler, template <class...> class Op, class... Args>
80 struct is_detected_impl {
81   using type = std::false_type;
82 };
83 
84 template <template <class...> class Op, class... Args>
85 struct is_detected_impl<typename VoidTImpl<Op<Args...>>::type, Op, Args...> {
86   using type = std::true_type;
87 };
88 
89 template <template <class...> class Op, class... Args>
90 struct is_detected : is_detected_impl<void, Op, Args...>::type {};
91 
92 template <class Enabler, class To, template <class...> class Op, class... Args>
93 struct is_detected_convertible_impl {
94   using type = std::false_type;
95 };
96 
97 template <class To, template <class...> class Op, class... Args>
98 struct is_detected_convertible_impl<
99     typename std::enable_if<std::is_convertible<Op<Args...>, To>::value>::type,
100     To, Op, Args...> {
101   using type = std::true_type;
102 };
103 
104 template <class To, template <class...> class Op, class... Args>
105 struct is_detected_convertible
106     : is_detected_convertible_impl<void, To, Op, Args...>::type {};
107 
108 template <typename T>
109 using IsCopyAssignableImpl =
110     decltype(std::declval<T&>() = std::declval<const T&>());
111 
112 template <typename T>
113 using IsMoveAssignableImpl = decltype(std::declval<T&>() = std::declval<T&&>());
114 
115 }  // namespace type_traits_internal
116 
117 template <typename T>
118 struct is_copy_assignable : type_traits_internal::is_detected<
119                                 type_traits_internal::IsCopyAssignableImpl, T> {
120 };
121 
122 template <typename T>
123 struct is_move_assignable : type_traits_internal::is_detected<
124                                 type_traits_internal::IsMoveAssignableImpl, T> {
125 };
126 
127 // void_t()
128 //
129 // Ignores the type of any its arguments and returns `void`. In general, this
130 // metafunction allows you to create a general case that maps to `void` while
131 // allowing specializations that map to specific types.
132 //
133 // This metafunction is designed to be a drop-in replacement for the C++17
134 // `std::void_t` metafunction.
135 //
136 // NOTE: `absl::void_t` does not use the standard-specified implementation so
137 // that it can remain compatible with gcc < 5.1. This can introduce slightly
138 // different behavior, such as when ordering partial specializations.
139 template <typename... Ts>
140 using void_t = typename type_traits_internal::VoidTImpl<Ts...>::type;
141 
142 // conjunction
143 //
144 // Performs a compile-time logical AND operation on the passed types (which
145 // must have  `::value` members convertible to `bool`. Short-circuits if it
146 // encounters any `false` members (and does not compare the `::value` members
147 // of any remaining arguments).
148 //
149 // This metafunction is designed to be a drop-in replacement for the C++17
150 // `std::conjunction` metafunction.
151 template <typename... Ts>
152 struct conjunction;
153 
154 template <typename T, typename... Ts>
155 struct conjunction<T, Ts...>
156     : std::conditional<T::value, conjunction<Ts...>, T>::type {};
157 
158 template <typename T>
159 struct conjunction<T> : T {};
160 
161 template <>
162 struct conjunction<> : std::true_type {};
163 
164 // disjunction
165 //
166 // Performs a compile-time logical OR operation on the passed types (which
167 // must have  `::value` members convertible to `bool`. Short-circuits if it
168 // encounters any `true` members (and does not compare the `::value` members
169 // of any remaining arguments).
170 //
171 // This metafunction is designed to be a drop-in replacement for the C++17
172 // `std::disjunction` metafunction.
173 template <typename... Ts>
174 struct disjunction;
175 
176 template <typename T, typename... Ts>
177 struct disjunction<T, Ts...> :
178       std::conditional<T::value, T, disjunction<Ts...>>::type {};
179 
180 template <typename T>
181 struct disjunction<T> : T {};
182 
183 template <>
184 struct disjunction<> : std::false_type {};
185 
186 // negation
187 //
188 // Performs a compile-time logical NOT operation on the passed type (which
189 // must have  `::value` members convertible to `bool`.
190 //
191 // This metafunction is designed to be a drop-in replacement for the C++17
192 // `std::negation` metafunction.
193 template <typename T>
194 struct negation : std::integral_constant<bool, !T::value> {};
195 
196 // is_trivially_destructible()
197 //
198 // Determines whether the passed type `T` is trivially destructable.
199 //
200 // This metafunction is designed to be a drop-in replacement for the C++11
201 // `std::is_trivially_destructible()` metafunction for platforms that have
202 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
203 // fully support C++11, we check whether this yields the same result as the std
204 // implementation.
205 //
206 // NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >=
207 // 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always
208 // be present. These  extensions are documented at
209 // https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits.
210 template <typename T>
211 struct is_trivially_destructible
212     : std::integral_constant<bool, __has_trivial_destructor(T) &&
213                                    std::is_destructible<T>::value> {
214 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
215  private:
216   static constexpr bool compliant = std::is_trivially_destructible<T>::value ==
217                                     is_trivially_destructible::value;
218   static_assert(compliant || std::is_trivially_destructible<T>::value,
219                 "Not compliant with std::is_trivially_destructible; "
220                 "Standard: false, Implementation: true");
221   static_assert(compliant || !std::is_trivially_destructible<T>::value,
222                 "Not compliant with std::is_trivially_destructible; "
223                 "Standard: true, Implementation: false");
224 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
225 };
226 
227 // is_trivially_default_constructible()
228 //
229 // Determines whether the passed type `T` is trivially default constructible.
230 //
231 // This metafunction is designed to be a drop-in replacement for the C++11
232 // `std::is_trivially_default_constructible()` metafunction for platforms that
233 // have incomplete C++11 support (such as libstdc++ 4.x). On any platforms that
234 // do fully support C++11, we check whether this yields the same result as the
235 // std implementation.
236 //
237 // NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop]
238 // "The predicate condition for a template specialization is_constructible<T,
239 // Args...> shall be satisfied if and only if the following variable
240 // definition would be well-formed for some invented variable t:
241 //
242 // T t(declval<Args>()...);
243 //
244 // is_trivially_constructible<T, Args...> additionally requires that the
245 // variable definition does not call any operation that is not trivial.
246 // For the purposes of this check, the call to std::declval is considered
247 // trivial."
248 //
249 // Notes from http://en.cppreference.com/w/cpp/types/is_constructible:
250 // In many implementations, is_nothrow_constructible also checks if the
251 // destructor throws because it is effectively noexcept(T(arg)). Same
252 // applies to is_trivially_constructible, which, in these implementations, also
253 // requires that the destructor is trivial.
254 // GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452
255 // LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116.
256 //
257 // "T obj();" need to be well-formed and not call any nontrivial operation.
258 // Nontrivially destructible types will cause the expression to be nontrivial.
259 template <typename T>
260 struct is_trivially_default_constructible
261     : std::integral_constant<bool, __has_trivial_constructor(T) &&
262                                    std::is_default_constructible<T>::value &&
263                                    is_trivially_destructible<T>::value> {
264 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
265  private:
266   static constexpr bool compliant =
267       std::is_trivially_default_constructible<T>::value ==
268       is_trivially_default_constructible::value;
269   static_assert(compliant || std::is_trivially_default_constructible<T>::value,
270                 "Not compliant with std::is_trivially_default_constructible; "
271                 "Standard: false, Implementation: true");
272   static_assert(compliant || !std::is_trivially_default_constructible<T>::value,
273                 "Not compliant with std::is_trivially_default_constructible; "
274                 "Standard: true, Implementation: false");
275 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
276 };
277 
278 // is_trivially_copy_constructible()
279 //
280 // Determines whether the passed type `T` is trivially copy constructible.
281 //
282 // This metafunction is designed to be a drop-in replacement for the C++11
283 // `std::is_trivially_copy_constructible()` metafunction for platforms that have
284 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
285 // fully support C++11, we check whether this yields the same result as the std
286 // implementation.
287 //
288 // NOTE: `T obj(declval<const T&>());` needs to be well-formed and not call any
289 // nontrivial operation.  Nontrivially destructible types will cause the
290 // expression to be nontrivial.
291 template <typename T>
292 struct is_trivially_copy_constructible
293     : std::integral_constant<bool, __has_trivial_copy(T) &&
294                                    std::is_copy_constructible<T>::value &&
295                                    is_trivially_destructible<T>::value> {
296 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
297  private:
298   static constexpr bool compliant =
299       std::is_trivially_copy_constructible<T>::value ==
300       is_trivially_copy_constructible::value;
301   static_assert(compliant || std::is_trivially_copy_constructible<T>::value,
302                 "Not compliant with std::is_trivially_copy_constructible; "
303                 "Standard: false, Implementation: true");
304   static_assert(compliant || !std::is_trivially_copy_constructible<T>::value,
305                 "Not compliant with std::is_trivially_copy_constructible; "
306                 "Standard: true, Implementation: false");
307 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
308 };
309 
310 // is_trivially_copy_assignable()
311 //
312 // Determines whether the passed type `T` is trivially copy assignable.
313 //
314 // This metafunction is designed to be a drop-in replacement for the C++11
315 // `std::is_trivially_copy_assignable()` metafunction for platforms that have
316 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
317 // fully support C++11, we check whether this yields the same result as the std
318 // implementation.
319 //
320 // NOTE: `is_assignable<T, U>::value` is `true` if the expression
321 // `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated
322 // operand. `is_trivially_assignable<T, U>` requires the assignment to call no
323 // operation that is not trivial. `is_trivially_copy_assignable<T>` is simply
324 // `is_trivially_assignable<T&, const T&>`.
325 template <typename T>
326 struct is_trivially_copy_assignable
327     : std::integral_constant<
328           bool, __has_trivial_assign(typename std::remove_reference<T>::type) &&
329                     absl::is_copy_assignable<T>::value> {
330 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
331  private:
332   static constexpr bool compliant =
333       std::is_trivially_copy_assignable<T>::value ==
334       is_trivially_copy_assignable::value;
335   static_assert(compliant || std::is_trivially_copy_assignable<T>::value,
336                 "Not compliant with std::is_trivially_copy_assignable; "
337                 "Standard: false, Implementation: true");
338   static_assert(compliant || !std::is_trivially_copy_assignable<T>::value,
339                 "Not compliant with std::is_trivially_copy_assignable; "
340                 "Standard: true, Implementation: false");
341 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
342 };
343 
344 // -----------------------------------------------------------------------------
345 // C++14 "_t" trait aliases
346 // -----------------------------------------------------------------------------
347 
348 template <typename T>
349 using remove_cv_t = typename std::remove_cv<T>::type;
350 
351 template <typename T>
352 using remove_const_t = typename std::remove_const<T>::type;
353 
354 template <typename T>
355 using remove_volatile_t = typename std::remove_volatile<T>::type;
356 
357 template <typename T>
358 using add_cv_t = typename std::add_cv<T>::type;
359 
360 template <typename T>
361 using add_const_t = typename std::add_const<T>::type;
362 
363 template <typename T>
364 using add_volatile_t = typename std::add_volatile<T>::type;
365 
366 template <typename T>
367 using remove_reference_t = typename std::remove_reference<T>::type;
368 
369 template <typename T>
370 using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
371 
372 template <typename T>
373 using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type;
374 
375 template <typename T>
376 using remove_pointer_t = typename std::remove_pointer<T>::type;
377 
378 template <typename T>
379 using add_pointer_t = typename std::add_pointer<T>::type;
380 
381 template <typename T>
382 using make_signed_t = typename std::make_signed<T>::type;
383 
384 template <typename T>
385 using make_unsigned_t = typename std::make_unsigned<T>::type;
386 
387 template <typename T>
388 using remove_extent_t = typename std::remove_extent<T>::type;
389 
390 template <typename T>
391 using remove_all_extents_t = typename std::remove_all_extents<T>::type;
392 
393 template <size_t Len, size_t Align = type_traits_internal::
394                           default_alignment_of_aligned_storage<Len>::value>
395 using aligned_storage_t = typename std::aligned_storage<Len, Align>::type;
396 
397 template <typename T>
398 using decay_t = typename std::decay<T>::type;
399 
400 template <bool B, typename T = void>
401 using enable_if_t = typename std::enable_if<B, T>::type;
402 
403 template <bool B, typename T, typename F>
404 using conditional_t = typename std::conditional<B, T, F>::type;
405 
406 template <typename... T>
407 using common_type_t = typename std::common_type<T...>::type;
408 
409 template <typename T>
410 using underlying_type_t = typename std::underlying_type<T>::type;
411 
412 template <typename T>
413 using result_of_t = typename std::result_of<T>::type;
414 
415 namespace type_traits_internal {
416 template <typename Key, typename = size_t>
417 struct IsHashable : std::false_type {};
418 
419 template <typename Key>
420 struct IsHashable<Key,
421                   decltype(std::declval<std::hash<Key>>()(std::declval<Key>()))>
422     : std::true_type {};
423 
424 template <typename Key>
425 struct IsHashEnabled
426     : absl::conjunction<std::is_default_constructible<std::hash<Key>>,
427                         std::is_copy_constructible<std::hash<Key>>,
428                         std::is_destructible<std::hash<Key>>,
429                         absl::is_copy_assignable<std::hash<Key>>,
430                         IsHashable<Key>> {};
431 
432 }  // namespace type_traits_internal
433 
434 }  // namespace absl
435 
436 #endif  // S2_THIRD_PARTY_ABSL_META_TYPE_TRAITS_H_
437