// // Copyright 2017 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // ----------------------------------------------------------------------------- // type_traits.h // ----------------------------------------------------------------------------- // // This file contains C++11-compatible versions of standard API // functions for determining the characteristics of types. Such traits can // support type inference, classification, and transformation, as well as // make it easier to write templates based on generic type behavior. // // See https://en.cppreference.com/w/cpp/header/type_traits // // WARNING: use of many of the constructs in this header will count as "complex // template metaprogramming", so before proceeding, please carefully consider // https://google.github.io/styleguide/cppguide.html#Template_metaprogramming // // WARNING: using template metaprogramming to detect or depend on API // features is brittle and not guaranteed. Neither the standard library nor // Abseil provides any guarantee that APIs are stable in the face of template // metaprogramming. Use with caution. #ifndef ABSL_META_TYPE_TRAITS_H_ #define ABSL_META_TYPE_TRAITS_H_ #include #include #include #include "absl/base/config.h" // MSVC constructibility traits do not detect destructor properties and so our // implementations should not use them as a source-of-truth. #if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) #define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 #endif namespace absl { ABSL_NAMESPACE_BEGIN // Defined and documented later on in this file. template struct is_trivially_destructible; // Defined and documented later on in this file. template struct is_trivially_move_assignable; namespace type_traits_internal { // Silence MSVC warnings about the destructor being defined as deleted. #if defined(_MSC_VER) && !defined(__GNUC__) #pragma warning(push) #pragma warning(disable : 4624) #endif // defined(_MSC_VER) && !defined(__GNUC__) template union SingleMemberUnion { T t; }; // Restore the state of the destructor warning that was silenced above. #if defined(_MSC_VER) && !defined(__GNUC__) #pragma warning(pop) #endif // defined(_MSC_VER) && !defined(__GNUC__) template struct IsTriviallyMoveConstructibleObject : std::integral_constant< bool, std::is_move_constructible< type_traits_internal::SingleMemberUnion>::value && absl::is_trivially_destructible::value> {}; template struct IsTriviallyCopyConstructibleObject : std::integral_constant< bool, std::is_copy_constructible< type_traits_internal::SingleMemberUnion>::value && absl::is_trivially_destructible::value> {}; template struct IsTriviallyMoveAssignableReference : std::false_type {}; template struct IsTriviallyMoveAssignableReference : absl::is_trivially_move_assignable::type {}; template struct IsTriviallyMoveAssignableReference : absl::is_trivially_move_assignable::type {}; template struct VoidTImpl { using type = void; }; // This trick to retrieve a default alignment is necessary for our // implementation of aligned_storage_t to be consistent with any implementation // of std::aligned_storage. template > struct default_alignment_of_aligned_storage; template struct default_alignment_of_aligned_storage> { static constexpr size_t value = Align; }; //////////////////////////////// // Library Fundamentals V2 TS // //////////////////////////////// // NOTE: The `is_detected` family of templates here differ from the library // fundamentals specification in that for library fundamentals, `Op` is // evaluated as soon as the type `is_detected` undergoes // substitution, regardless of whether or not the `::value` is accessed. That // is inconsistent with all other standard traits and prevents lazy evaluation // in larger contexts (such as if the `is_detected` check is a trailing argument // of a `conjunction`. This implementation opts to instead be lazy in the same // way that the standard traits are (this "defect" of the detection idiom // specifications has been reported). template class Op, class... Args> struct is_detected_impl { using type = std::false_type; }; template