From c2e754829628d1e9b7a16b3389cfdace76950fdf Mon Sep 17 00:00:00 2001 From: misterg Date: Tue, 19 Sep 2017 16:54:40 -0400 Subject: Initial Commit --- absl/meta/type_traits.h | 314 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 absl/meta/type_traits.h (limited to 'absl/meta/type_traits.h') diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h new file mode 100644 index 0000000..779afd2 --- /dev/null +++ b/absl/meta/type_traits.h @@ -0,0 +1,314 @@ +// +// 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 +// +// http://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 http://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 "absl/base/config.h" + +namespace absl { + +namespace type_traits_internal { +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; +}; + +} // namespace type_traits_internal + +// void_t() +// +// Ignores the type of any its arguments and returns `void`. In general, this +// metafunction allows you to create a general case that maps to `void` while +// allowing specializations that map to specific types. +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::void_t` metafunction. +// +// NOTE: `absl::void_t` does not use the standard-specified implementation so +// that it can remain compatibile with gcc < 5.1. This can introduce slightly +// different behavior, such as when ordering partial specializations. +template +using void_t = typename type_traits_internal::VoidTImpl::type; + +// conjunction +// +// Performs a compile-time logical AND operation on the passed types (which +// must have `::value` members convertible to `bool`. Short-circuits if it +// encounters any `false` members (and does not compare the `::value` members +// of any remaining arguments). +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::conjunction` metafunction. +template +struct conjunction; + +template +struct conjunction + : std::conditional, T>::type {}; + +template +struct conjunction : T {}; + +template <> +struct conjunction<> : std::true_type {}; + +// disjunction +// +// Performs a compile-time logical OR operation on the passed types (which +// must have `::value` members convertible to `bool`. Short-circuits if it +// encounters any `true` members (and does not compare the `::value` members +// of any remaining arguments). +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::disjunction` metafunction. +template +struct disjunction; + +template +struct disjunction : + std::conditional>::type {}; + +template +struct disjunction : T {}; + +template <> +struct disjunction<> : std::false_type {}; + +// negation +// +// Performs a compile-time logical NOT operation on the passed type (which +// must have `::value` members convertible to `bool`. +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::negation` metafunction. +template +struct negation : std::integral_constant {}; + +// is_trivially_destructible() +// +// Determines whether the passed type `T` is trivially destructable. +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::is_trivially_destructible()` metafunction. +// +// NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >= +// 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always +// be present. These extensions are documented at +// https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits. +template +struct is_trivially_destructible + : std::integral_constant::value> { +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE + static_assert(std::is_trivially_destructible::value == + is_trivially_destructible::value, + "Not compliant with std::is_trivially_destructible"); +#endif // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE +}; + +// is_trivially_default_constructible() +// +// Determines whether the passed type `T` is trivially default constructible. +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::is_trivially_default_constructible()` metafunction. +// +// NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop] +// "The predicate condition for a template specialization is_constructible shall be satisfied if and only if the following variable +// definition would be well-formed for some invented variable t: +// +// T t(declval()...); +// +// is_trivially_constructible additionally requires that the +// variable definition does not call any operation that is not trivial. +// For the purposes of this check, the call to std::declval is considered +// trivial." +// +// Notes from http://en.cppreference.com/w/cpp/types/is_constructible: +// In many implementations, is_nothrow_constructible also checks if the +// destructor throws because it is effectively noexcept(T(arg)). Same +// applies to is_trivially_constructible, which, in these implementations, also +// requires that the destructor is trivial. +// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 +// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116. +// +// "T obj();" need to be well-formed and not call any non-trivial operation. +// Nontrivally destructible types will cause the expression to be nontrivial. +template +struct is_trivially_default_constructible + : std::integral_constant::value && + is_trivially_destructible::value> { +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE + static_assert(std::is_trivially_default_constructible::value == + is_trivially_default_constructible::value, + "Not compliant with std::is_trivially_default_constructible"); +#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +}; + +// is_trivially_copy_constructible() +// +// Determines whether the passed type `T` is trivially copy constructible. +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::is_trivially_copy_constructible()` metafunction. +// +// NOTE: `T obj(declval());` needs to be well-formed and not call any +// nontrivial operation. Nontrivally destructible types will cause the +// expression to be nontrivial. +template +struct is_trivially_copy_constructible + : std::integral_constant::value && + is_trivially_destructible::value> { +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE + static_assert(std::is_trivially_copy_constructible::value == + is_trivially_copy_constructible::value, + "Not compliant with std::is_trivially_copy_constructible"); +#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +}; + +// is_trivially_copy_assignable() +// +// Determines whether the passed type `T` is trivially copy assignable. +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::is_trivially_copy_assignable()` metafunction. +// +// NOTE: `is_assignable::value` is `true` if the expression +// `declval() = declval()` is well-formed when treated as an unevaluated +// operand. `is_trivially_assignable` requires the assignment to call no +// operation that is not trivial. `is_trivially_copy_assignable` is simply +// `is_trivially_assignable`. +template +struct is_trivially_copy_assignable + : std::integral_constant::value> { +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE + static_assert(std::is_trivially_copy_assignable::value == + is_trivially_copy_assignable::value, + "Not compliant with std::is_trivially_copy_assignable"); +#endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE +}; + +// ----------------------------------------------------------------------------- +// C++14 "_t" trait aliases +// ----------------------------------------------------------------------------- + +template +using remove_cv_t = typename std::remove_cv::type; + +template +using remove_const_t = typename std::remove_const::type; + +template +using remove_volatile_t = typename std::remove_volatile::type; + +template +using add_cv_t = typename std::add_cv::type; + +template +using add_const_t = typename std::add_const::type; + +template +using add_volatile_t = typename std::add_volatile::type; + +template +using remove_reference_t = typename std::remove_reference::type; + +template +using add_lvalue_reference_t = typename std::add_lvalue_reference::type; + +template +using add_rvalue_reference_t = typename std::add_rvalue_reference::type; + +template +using remove_pointer_t = typename std::remove_pointer::type; + +template +using add_pointer_t = typename std::add_pointer::type; + +template +using make_signed_t = typename std::make_signed::type; + +template +using make_unsigned_t = typename std::make_unsigned::type; + +template +using remove_extent_t = typename std::remove_extent::type; + +template +using remove_all_extents_t = typename std::remove_all_extents::type; + +template ::value> +using aligned_storage_t = typename std::aligned_storage::type; + +template +using decay_t = typename std::decay::type; + +template +using enable_if_t = typename std::enable_if::type; + +template +using conditional_t = typename std::conditional::type; + +template +using common_type_t = typename std::common_type::type; + +template +using underlying_type_t = typename std::underlying_type::type; + +template +using result_of_t = typename std::result_of::type; + +} // namespace absl +#endif // ABSL_META_TYPE_TRAITS_H_ -- cgit v1.2.3