• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //      https://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 https://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 ABSL_META_TYPE_TRAITS_H_
36 #define ABSL_META_TYPE_TRAITS_H_
37 
38 #include <stddef.h>
39 #include <functional>
40 #include <type_traits>
41 
42 #include "absl/base/config.h"
43 
44 // MSVC constructibility traits do not detect destructor properties and so our
45 // implementations should not use them as a source-of-truth.
46 #if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__)
47 #define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1
48 #endif
49 
50 namespace absl {
51 ABSL_NAMESPACE_BEGIN
52 
53 // Defined and documented later on in this file.
54 template <typename T>
55 struct is_trivially_destructible;
56 
57 // Defined and documented later on in this file.
58 template <typename T>
59 struct is_trivially_move_assignable;
60 
61 namespace type_traits_internal {
62 
63 // Silence MSVC warnings about the destructor being defined as deleted.
64 #if defined(_MSC_VER) && !defined(__GNUC__)
65 #pragma warning(push)
66 #pragma warning(disable : 4624)
67 #endif  // defined(_MSC_VER) && !defined(__GNUC__)
68 
69 template <class T>
70 union SingleMemberUnion {
71   T t;
72 };
73 
74 // Restore the state of the destructor warning that was silenced above.
75 #if defined(_MSC_VER) && !defined(__GNUC__)
76 #pragma warning(pop)
77 #endif  // defined(_MSC_VER) && !defined(__GNUC__)
78 
79 template <class T>
80 struct IsTriviallyMoveConstructibleObject
81     : std::integral_constant<
82           bool, std::is_move_constructible<
83                     type_traits_internal::SingleMemberUnion<T>>::value &&
84                     absl::is_trivially_destructible<T>::value> {};
85 
86 template <class T>
87 struct IsTriviallyCopyConstructibleObject
88     : std::integral_constant<
89           bool, std::is_copy_constructible<
90                     type_traits_internal::SingleMemberUnion<T>>::value &&
91                     absl::is_trivially_destructible<T>::value> {};
92 
93 template <class T>
94 struct IsTriviallyMoveAssignableReference : std::false_type {};
95 
96 template <class T>
97 struct IsTriviallyMoveAssignableReference<T&>
98     : absl::is_trivially_move_assignable<T>::type {};
99 
100 template <class T>
101 struct IsTriviallyMoveAssignableReference<T&&>
102     : absl::is_trivially_move_assignable<T>::type {};
103 
104 template <typename... Ts>
105 struct VoidTImpl {
106   using type = void;
107 };
108 
109 // This trick to retrieve a default alignment is necessary for our
110 // implementation of aligned_storage_t to be consistent with any implementation
111 // of std::aligned_storage.
112 template <size_t Len, typename T = std::aligned_storage<Len>>
113 struct default_alignment_of_aligned_storage;
114 
115 template <size_t Len, size_t Align>
116 struct default_alignment_of_aligned_storage<Len,
117                                             std::aligned_storage<Len, Align>> {
118   static constexpr size_t value = Align;
119 };
120 
121 ////////////////////////////////
122 // Library Fundamentals V2 TS //
123 ////////////////////////////////
124 
125 // NOTE: The `is_detected` family of templates here differ from the library
126 // fundamentals specification in that for library fundamentals, `Op<Args...>` is
127 // evaluated as soon as the type `is_detected<Op, Args...>` undergoes
128 // substitution, regardless of whether or not the `::value` is accessed. That
129 // is inconsistent with all other standard traits and prevents lazy evaluation
130 // in larger contexts (such as if the `is_detected` check is a trailing argument
131 // of a `conjunction`. This implementation opts to instead be lazy in the same
132 // way that the standard traits are (this "defect" of the detection idiom
133 // specifications has been reported).
134 
135 template <class Enabler, template <class...> class Op, class... Args>
136 struct is_detected_impl {
137   using type = std::false_type;
138 };
139 
140 template <template <class...> class Op, class... Args>
141 struct is_detected_impl<typename VoidTImpl<Op<Args...>>::type, Op, Args...> {
142   using type = std::true_type;
143 };
144 
145 template <template <class...> class Op, class... Args>
146 struct is_detected : is_detected_impl<void, Op, Args...>::type {};
147 
148 template <class Enabler, class To, template <class...> class Op, class... Args>
149 struct is_detected_convertible_impl {
150   using type = std::false_type;
151 };
152 
153 template <class To, template <class...> class Op, class... Args>
154 struct is_detected_convertible_impl<
155     typename std::enable_if<std::is_convertible<Op<Args...>, To>::value>::type,
156     To, Op, Args...> {
157   using type = std::true_type;
158 };
159 
160 template <class To, template <class...> class Op, class... Args>
161 struct is_detected_convertible
162     : is_detected_convertible_impl<void, To, Op, Args...>::type {};
163 
164 template <typename T>
165 using IsCopyAssignableImpl =
166     decltype(std::declval<T&>() = std::declval<const T&>());
167 
168 template <typename T>
169 using IsMoveAssignableImpl = decltype(std::declval<T&>() = std::declval<T&&>());
170 
171 }  // namespace type_traits_internal
172 
173 // MSVC 19.20 has a regression that causes our workarounds to fail, but their
174 // std forms now appear to be compliant.
175 #if defined(_MSC_VER) && !defined(__clang__) && (_MSC_VER >= 1920)
176 
177 template <typename T>
178 using is_copy_assignable = std::is_copy_assignable<T>;
179 
180 template <typename T>
181 using is_move_assignable = std::is_move_assignable<T>;
182 
183 #else
184 
185 template <typename T>
186 struct is_copy_assignable : type_traits_internal::is_detected<
187                                 type_traits_internal::IsCopyAssignableImpl, T> {
188 };
189 
190 template <typename T>
191 struct is_move_assignable : type_traits_internal::is_detected<
192                                 type_traits_internal::IsMoveAssignableImpl, T> {
193 };
194 
195 #endif
196 
197 // void_t()
198 //
199 // Ignores the type of any its arguments and returns `void`. In general, this
200 // metafunction allows you to create a general case that maps to `void` while
201 // allowing specializations that map to specific types.
202 //
203 // This metafunction is designed to be a drop-in replacement for the C++17
204 // `std::void_t` metafunction.
205 //
206 // NOTE: `absl::void_t` does not use the standard-specified implementation so
207 // that it can remain compatible with gcc < 5.1. This can introduce slightly
208 // different behavior, such as when ordering partial specializations.
209 template <typename... Ts>
210 using void_t = typename type_traits_internal::VoidTImpl<Ts...>::type;
211 
212 // conjunction
213 //
214 // Performs a compile-time logical AND operation on the passed types (which
215 // must have  `::value` members convertible to `bool`. Short-circuits if it
216 // encounters any `false` members (and does not compare the `::value` members
217 // of any remaining arguments).
218 //
219 // This metafunction is designed to be a drop-in replacement for the C++17
220 // `std::conjunction` metafunction.
221 template <typename... Ts>
222 struct conjunction : std::true_type {};
223 
224 template <typename T, typename... Ts>
225 struct conjunction<T, Ts...>
226     : std::conditional<T::value, conjunction<Ts...>, T>::type {};
227 
228 template <typename T>
229 struct conjunction<T> : T {};
230 
231 // disjunction
232 //
233 // Performs a compile-time logical OR operation on the passed types (which
234 // must have  `::value` members convertible to `bool`. Short-circuits if it
235 // encounters any `true` members (and does not compare the `::value` members
236 // of any remaining arguments).
237 //
238 // This metafunction is designed to be a drop-in replacement for the C++17
239 // `std::disjunction` metafunction.
240 template <typename... Ts>
241 struct disjunction : std::false_type {};
242 
243 template <typename T, typename... Ts>
244 struct disjunction<T, Ts...> :
245       std::conditional<T::value, T, disjunction<Ts...>>::type {};
246 
247 template <typename T>
248 struct disjunction<T> : T {};
249 
250 // negation
251 //
252 // Performs a compile-time logical NOT operation on the passed type (which
253 // must have  `::value` members convertible to `bool`.
254 //
255 // This metafunction is designed to be a drop-in replacement for the C++17
256 // `std::negation` metafunction.
257 template <typename T>
258 struct negation : std::integral_constant<bool, !T::value> {};
259 
260 // is_function()
261 //
262 // Determines whether the passed type `T` is a function type.
263 //
264 // This metafunction is designed to be a drop-in replacement for the C++11
265 // `std::is_function()` metafunction for platforms that have incomplete C++11
266 // support (such as libstdc++ 4.x).
267 //
268 // This metafunction works because appending `const` to a type does nothing to
269 // function types and reference types (and forms a const-qualified type
270 // otherwise).
271 template <typename T>
272 struct is_function
273     : std::integral_constant<
274           bool, !(std::is_reference<T>::value ||
275                   std::is_const<typename std::add_const<T>::type>::value)> {};
276 
277 // is_trivially_destructible()
278 //
279 // Determines whether the passed type `T` is trivially destructible.
280 //
281 // This metafunction is designed to be a drop-in replacement for the C++11
282 // `std::is_trivially_destructible()` metafunction for platforms that have
283 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
284 // fully support C++11, we check whether this yields the same result as the std
285 // implementation.
286 //
287 // NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >=
288 // 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always
289 // be present. These  extensions are documented at
290 // https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits.
291 template <typename T>
292 struct is_trivially_destructible
293     : std::integral_constant<bool, __has_trivial_destructor(T) &&
294                                    std::is_destructible<T>::value> {
295 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
296  private:
297   static constexpr bool compliant = std::is_trivially_destructible<T>::value ==
298                                     is_trivially_destructible::value;
299   static_assert(compliant || std::is_trivially_destructible<T>::value,
300                 "Not compliant with std::is_trivially_destructible; "
301                 "Standard: false, Implementation: true");
302   static_assert(compliant || !std::is_trivially_destructible<T>::value,
303                 "Not compliant with std::is_trivially_destructible; "
304                 "Standard: true, Implementation: false");
305 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
306 };
307 
308 // is_trivially_default_constructible()
309 //
310 // Determines whether the passed type `T` is trivially default constructible.
311 //
312 // This metafunction is designed to be a drop-in replacement for the C++11
313 // `std::is_trivially_default_constructible()` metafunction for platforms that
314 // have incomplete C++11 support (such as libstdc++ 4.x). On any platforms that
315 // do fully support C++11, we check whether this yields the same result as the
316 // std implementation.
317 //
318 // NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop]
319 // "The predicate condition for a template specialization is_constructible<T,
320 // Args...> shall be satisfied if and only if the following variable
321 // definition would be well-formed for some invented variable t:
322 //
323 // T t(declval<Args>()...);
324 //
325 // is_trivially_constructible<T, Args...> additionally requires that the
326 // variable definition does not call any operation that is not trivial.
327 // For the purposes of this check, the call to std::declval is considered
328 // trivial."
329 //
330 // Notes from https://en.cppreference.com/w/cpp/types/is_constructible:
331 // In many implementations, is_nothrow_constructible also checks if the
332 // destructor throws because it is effectively noexcept(T(arg)). Same
333 // applies to is_trivially_constructible, which, in these implementations, also
334 // requires that the destructor is trivial.
335 // GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452
336 // LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116.
337 //
338 // "T obj();" need to be well-formed and not call any nontrivial operation.
339 // Nontrivially destructible types will cause the expression to be nontrivial.
340 template <typename T>
341 struct is_trivially_default_constructible
342     : std::integral_constant<bool, __has_trivial_constructor(T) &&
343                                    std::is_default_constructible<T>::value &&
344                                    is_trivially_destructible<T>::value> {
345 #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
346     !defined(                                            \
347         ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
348  private:
349   static constexpr bool compliant =
350       std::is_trivially_default_constructible<T>::value ==
351       is_trivially_default_constructible::value;
352   static_assert(compliant || std::is_trivially_default_constructible<T>::value,
353                 "Not compliant with std::is_trivially_default_constructible; "
354                 "Standard: false, Implementation: true");
355   static_assert(compliant || !std::is_trivially_default_constructible<T>::value,
356                 "Not compliant with std::is_trivially_default_constructible; "
357                 "Standard: true, Implementation: false");
358 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
359 };
360 
361 // is_trivially_move_constructible()
362 //
363 // Determines whether the passed type `T` is trivially move constructible.
364 //
365 // This metafunction is designed to be a drop-in replacement for the C++11
366 // `std::is_trivially_move_constructible()` metafunction for platforms that have
367 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
368 // fully support C++11, we check whether this yields the same result as the std
369 // implementation.
370 //
371 // NOTE: `T obj(declval<T>());` needs to be well-formed and not call any
372 // nontrivial operation.  Nontrivially destructible types will cause the
373 // expression to be nontrivial.
374 template <typename T>
375 struct is_trivially_move_constructible
376     : std::conditional<
377           std::is_object<T>::value && !std::is_array<T>::value,
378           type_traits_internal::IsTriviallyMoveConstructibleObject<T>,
379           std::is_reference<T>>::type::type {
380 #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
381     !defined(                                            \
382         ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
383  private:
384   static constexpr bool compliant =
385       std::is_trivially_move_constructible<T>::value ==
386       is_trivially_move_constructible::value;
387   static_assert(compliant || std::is_trivially_move_constructible<T>::value,
388                 "Not compliant with std::is_trivially_move_constructible; "
389                 "Standard: false, Implementation: true");
390   static_assert(compliant || !std::is_trivially_move_constructible<T>::value,
391                 "Not compliant with std::is_trivially_move_constructible; "
392                 "Standard: true, Implementation: false");
393 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
394 };
395 
396 // is_trivially_copy_constructible()
397 //
398 // Determines whether the passed type `T` is trivially copy constructible.
399 //
400 // This metafunction is designed to be a drop-in replacement for the C++11
401 // `std::is_trivially_copy_constructible()` metafunction for platforms that have
402 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
403 // fully support C++11, we check whether this yields the same result as the std
404 // implementation.
405 //
406 // NOTE: `T obj(declval<const T&>());` needs to be well-formed and not call any
407 // nontrivial operation.  Nontrivially destructible types will cause the
408 // expression to be nontrivial.
409 template <typename T>
410 struct is_trivially_copy_constructible
411     : std::conditional<
412           std::is_object<T>::value && !std::is_array<T>::value,
413           type_traits_internal::IsTriviallyCopyConstructibleObject<T>,
414           std::is_lvalue_reference<T>>::type::type {
415 #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
416     !defined(                                            \
417         ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
418  private:
419   static constexpr bool compliant =
420       std::is_trivially_copy_constructible<T>::value ==
421       is_trivially_copy_constructible::value;
422   static_assert(compliant || std::is_trivially_copy_constructible<T>::value,
423                 "Not compliant with std::is_trivially_copy_constructible; "
424                 "Standard: false, Implementation: true");
425   static_assert(compliant || !std::is_trivially_copy_constructible<T>::value,
426                 "Not compliant with std::is_trivially_copy_constructible; "
427                 "Standard: true, Implementation: false");
428 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
429 };
430 
431 // is_trivially_move_assignable()
432 //
433 // Determines whether the passed type `T` is trivially move assignable.
434 //
435 // This metafunction is designed to be a drop-in replacement for the C++11
436 // `std::is_trivially_move_assignable()` metafunction for platforms that have
437 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
438 // fully support C++11, we check whether this yields the same result as the std
439 // implementation.
440 //
441 // NOTE: `is_assignable<T, U>::value` is `true` if the expression
442 // `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated
443 // operand. `is_trivially_assignable<T, U>` requires the assignment to call no
444 // operation that is not trivial. `is_trivially_copy_assignable<T>` is simply
445 // `is_trivially_assignable<T&, T>`.
446 template <typename T>
447 struct is_trivially_move_assignable
448     : std::conditional<
449           std::is_object<T>::value && !std::is_array<T>::value &&
450               std::is_move_assignable<T>::value,
451           std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>,
452           type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type::
453           type {
454 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
455  private:
456   static constexpr bool compliant =
457       std::is_trivially_move_assignable<T>::value ==
458       is_trivially_move_assignable::value;
459   static_assert(compliant || std::is_trivially_move_assignable<T>::value,
460                 "Not compliant with std::is_trivially_move_assignable; "
461                 "Standard: false, Implementation: true");
462   static_assert(compliant || !std::is_trivially_move_assignable<T>::value,
463                 "Not compliant with std::is_trivially_move_assignable; "
464                 "Standard: true, Implementation: false");
465 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
466 };
467 
468 // is_trivially_copy_assignable()
469 //
470 // Determines whether the passed type `T` is trivially copy assignable.
471 //
472 // This metafunction is designed to be a drop-in replacement for the C++11
473 // `std::is_trivially_copy_assignable()` metafunction for platforms that have
474 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
475 // fully support C++11, we check whether this yields the same result as the std
476 // implementation.
477 //
478 // NOTE: `is_assignable<T, U>::value` is `true` if the expression
479 // `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated
480 // operand. `is_trivially_assignable<T, U>` requires the assignment to call no
481 // operation that is not trivial. `is_trivially_copy_assignable<T>` is simply
482 // `is_trivially_assignable<T&, const T&>`.
483 template <typename T>
484 struct is_trivially_copy_assignable
485     : std::integral_constant<
486           bool, __has_trivial_assign(typename std::remove_reference<T>::type) &&
487                     absl::is_copy_assignable<T>::value> {
488 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
489  private:
490   static constexpr bool compliant =
491       std::is_trivially_copy_assignable<T>::value ==
492       is_trivially_copy_assignable::value;
493   static_assert(compliant || std::is_trivially_copy_assignable<T>::value,
494                 "Not compliant with std::is_trivially_copy_assignable; "
495                 "Standard: false, Implementation: true");
496   static_assert(compliant || !std::is_trivially_copy_assignable<T>::value,
497                 "Not compliant with std::is_trivially_copy_assignable; "
498                 "Standard: true, Implementation: false");
499 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
500 };
501 
502 #if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L
503 template <typename T>
504 using remove_cvref = std::remove_cvref<T>;
505 
506 template <typename T>
507 using remove_cvref_t = typename std::remove_cvref<T>::type;
508 #else
509 // remove_cvref()
510 //
511 // C++11 compatible implementation of std::remove_cvref which was added in
512 // C++20.
513 template <typename T>
514 struct remove_cvref {
515   using type =
516       typename std::remove_cv<typename std::remove_reference<T>::type>::type;
517 };
518 
519 template <typename T>
520 using remove_cvref_t = typename remove_cvref<T>::type;
521 #endif
522 
523 namespace type_traits_internal {
524 // is_trivially_copyable()
525 //
526 // Determines whether the passed type `T` is trivially copyable.
527 //
528 // This metafunction is designed to be a drop-in replacement for the C++11
529 // `std::is_trivially_copyable()` metafunction for platforms that have
530 // incomplete C++11 support (such as libstdc++ 4.x). We use the C++17 definition
531 // of TriviallyCopyable.
532 //
533 // NOTE: `is_trivially_copyable<T>::value` is `true` if all of T's copy/move
534 // constructors/assignment operators are trivial or deleted, T has at least
535 // one non-deleted copy/move constructor/assignment operator, and T is trivially
536 // destructible. Arrays of trivially copyable types are trivially copyable.
537 //
538 // We expose this metafunction only for internal use within absl.
539 template <typename T>
540 class is_trivially_copyable_impl {
541   using ExtentsRemoved = typename std::remove_all_extents<T>::type;
542   static constexpr bool kIsCopyOrMoveConstructible =
543       std::is_copy_constructible<ExtentsRemoved>::value ||
544       std::is_move_constructible<ExtentsRemoved>::value;
545   static constexpr bool kIsCopyOrMoveAssignable =
546       absl::is_copy_assignable<ExtentsRemoved>::value ||
547       absl::is_move_assignable<ExtentsRemoved>::value;
548 
549  public:
550   static constexpr bool kValue =
551       (__has_trivial_copy(ExtentsRemoved) || !kIsCopyOrMoveConstructible) &&
552       (__has_trivial_assign(ExtentsRemoved) || !kIsCopyOrMoveAssignable) &&
553       (kIsCopyOrMoveConstructible || kIsCopyOrMoveAssignable) &&
554       is_trivially_destructible<ExtentsRemoved>::value &&
555       // We need to check for this explicitly because otherwise we'll say
556       // references are trivial copyable when compiled by MSVC.
557       !std::is_reference<ExtentsRemoved>::value;
558 };
559 
560 template <typename T>
561 struct is_trivially_copyable
562     : std::integral_constant<
563           bool, type_traits_internal::is_trivially_copyable_impl<T>::kValue> {};
564 }  // namespace type_traits_internal
565 
566 // -----------------------------------------------------------------------------
567 // C++14 "_t" trait aliases
568 // -----------------------------------------------------------------------------
569 
570 template <typename T>
571 using remove_cv_t = typename std::remove_cv<T>::type;
572 
573 template <typename T>
574 using remove_const_t = typename std::remove_const<T>::type;
575 
576 template <typename T>
577 using remove_volatile_t = typename std::remove_volatile<T>::type;
578 
579 template <typename T>
580 using add_cv_t = typename std::add_cv<T>::type;
581 
582 template <typename T>
583 using add_const_t = typename std::add_const<T>::type;
584 
585 template <typename T>
586 using add_volatile_t = typename std::add_volatile<T>::type;
587 
588 template <typename T>
589 using remove_reference_t = typename std::remove_reference<T>::type;
590 
591 template <typename T>
592 using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
593 
594 template <typename T>
595 using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type;
596 
597 template <typename T>
598 using remove_pointer_t = typename std::remove_pointer<T>::type;
599 
600 template <typename T>
601 using add_pointer_t = typename std::add_pointer<T>::type;
602 
603 template <typename T>
604 using make_signed_t = typename std::make_signed<T>::type;
605 
606 template <typename T>
607 using make_unsigned_t = typename std::make_unsigned<T>::type;
608 
609 template <typename T>
610 using remove_extent_t = typename std::remove_extent<T>::type;
611 
612 template <typename T>
613 using remove_all_extents_t = typename std::remove_all_extents<T>::type;
614 
615 template <size_t Len, size_t Align = type_traits_internal::
616                           default_alignment_of_aligned_storage<Len>::value>
617 using aligned_storage_t = typename std::aligned_storage<Len, Align>::type;
618 
619 template <typename T>
620 using decay_t = typename std::decay<T>::type;
621 
622 template <bool B, typename T = void>
623 using enable_if_t = typename std::enable_if<B, T>::type;
624 
625 template <bool B, typename T, typename F>
626 using conditional_t = typename std::conditional<B, T, F>::type;
627 
628 template <typename... T>
629 using common_type_t = typename std::common_type<T...>::type;
630 
631 template <typename T>
632 using underlying_type_t = typename std::underlying_type<T>::type;
633 
634 
635 namespace type_traits_internal {
636 
637 #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
638 // std::result_of is deprecated (C++17) or removed (C++20)
639 template<typename> struct result_of;
640 template<typename F, typename... Args>
641 struct result_of<F(Args...)> : std::invoke_result<F, Args...> {};
642 #else
643 template<typename F> using result_of = std::result_of<F>;
644 #endif
645 
646 }  // namespace type_traits_internal
647 
648 template<typename F>
649 using result_of_t = typename type_traits_internal::result_of<F>::type;
650 
651 namespace type_traits_internal {
652 // In MSVC we can't probe std::hash or stdext::hash because it triggers a
653 // static_assert instead of failing substitution. Libc++ prior to 4.0
654 // also used a static_assert.
655 //
656 #if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \
657                           _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11)
658 #define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 0
659 #else
660 #define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 1
661 #endif
662 
663 #if !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
664 template <typename Key, typename = size_t>
665 struct IsHashable : std::true_type {};
666 #else   // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
667 template <typename Key, typename = void>
668 struct IsHashable : std::false_type {};
669 
670 template <typename Key>
671 struct IsHashable<
672     Key,
673     absl::enable_if_t<std::is_convertible<
674         decltype(std::declval<std::hash<Key>&>()(std::declval<Key const&>())),
675         std::size_t>::value>> : std::true_type {};
676 #endif  // !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
677 
678 struct AssertHashEnabledHelper {
679  private:
680   static void Sink(...) {}
681   struct NAT {};
682 
683   template <class Key>
684   static auto GetReturnType(int)
685       -> decltype(std::declval<std::hash<Key>>()(std::declval<Key const&>()));
686   template <class Key>
687   static NAT GetReturnType(...);
688 
689   template <class Key>
690   static std::nullptr_t DoIt() {
691     static_assert(IsHashable<Key>::value,
692                   "std::hash<Key> does not provide a call operator");
693     static_assert(
694         std::is_default_constructible<std::hash<Key>>::value,
695         "std::hash<Key> must be default constructible when it is enabled");
696     static_assert(
697         std::is_copy_constructible<std::hash<Key>>::value,
698         "std::hash<Key> must be copy constructible when it is enabled");
699     static_assert(absl::is_copy_assignable<std::hash<Key>>::value,
700                   "std::hash<Key> must be copy assignable when it is enabled");
701     // is_destructible is unchecked as it's implied by each of the
702     // is_constructible checks.
703     using ReturnType = decltype(GetReturnType<Key>(0));
704     static_assert(std::is_same<ReturnType, NAT>::value ||
705                       std::is_same<ReturnType, size_t>::value,
706                   "std::hash<Key> must return size_t");
707     return nullptr;
708   }
709 
710   template <class... Ts>
711   friend void AssertHashEnabled();
712 };
713 
714 template <class... Ts>
715 inline void AssertHashEnabled() {
716   using Helper = AssertHashEnabledHelper;
717   Helper::Sink(Helper::DoIt<Ts>()...);
718 }
719 
720 }  // namespace type_traits_internal
721 
722 // An internal namespace that is required to implement the C++17 swap traits.
723 // It is not further nested in type_traits_internal to avoid long symbol names.
724 namespace swap_internal {
725 
726 // Necessary for the traits.
727 using std::swap;
728 
729 // This declaration prevents global `swap` and `absl::swap` overloads from being
730 // considered unless ADL picks them up.
731 void swap();
732 
733 template <class T>
734 using IsSwappableImpl = decltype(swap(std::declval<T&>(), std::declval<T&>()));
735 
736 // NOTE: This dance with the default template parameter is for MSVC.
737 template <class T,
738           class IsNoexcept = std::integral_constant<
739               bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))>>
740 using IsNothrowSwappableImpl = typename std::enable_if<IsNoexcept::value>::type;
741 
742 // IsSwappable
743 //
744 // Determines whether the standard swap idiom is a valid expression for
745 // arguments of type `T`.
746 template <class T>
747 struct IsSwappable
748     : absl::type_traits_internal::is_detected<IsSwappableImpl, T> {};
749 
750 // IsNothrowSwappable
751 //
752 // Determines whether the standard swap idiom is a valid expression for
753 // arguments of type `T` and is noexcept.
754 template <class T>
755 struct IsNothrowSwappable
756     : absl::type_traits_internal::is_detected<IsNothrowSwappableImpl, T> {};
757 
758 // Swap()
759 //
760 // Performs the swap idiom from a namespace where valid candidates may only be
761 // found in `std` or via ADL.
762 template <class T, absl::enable_if_t<IsSwappable<T>::value, int> = 0>
763 void Swap(T& lhs, T& rhs) noexcept(IsNothrowSwappable<T>::value) {
764   swap(lhs, rhs);
765 }
766 
767 // StdSwapIsUnconstrained
768 //
769 // Some standard library implementations are broken in that they do not
770 // constrain `std::swap`. This will effectively tell us if we are dealing with
771 // one of those implementations.
772 using StdSwapIsUnconstrained = IsSwappable<void()>;
773 
774 }  // namespace swap_internal
775 
776 namespace type_traits_internal {
777 
778 // Make the swap-related traits/function accessible from this namespace.
779 using swap_internal::IsNothrowSwappable;
780 using swap_internal::IsSwappable;
781 using swap_internal::Swap;
782 using swap_internal::StdSwapIsUnconstrained;
783 
784 }  // namespace type_traits_internal
785 ABSL_NAMESPACE_END
786 }  // namespace absl
787 
788 #endif  // ABSL_META_TYPE_TRAITS_H_
789