// // 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 #include #include "absl/base/attributes.h" #include "absl/base/config.h" #ifdef __cpp_lib_span #include // NOLINT(build/c++20) #endif #ifdef ABSL_HAVE_STD_STRING_VIEW #include #endif // Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17 // feature. #if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) #define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__ #else // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) #define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT alignof(std::max_align_t) #endif // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) namespace absl { ABSL_NAMESPACE_BEGIN namespace type_traits_internal { template struct VoidTImpl { using type = void; }; //////////////////////////////// // 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