// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). #pragma once #include #include namespace folly { #if !defined(_MSC_VER) template struct is_trivially_copyable : std::integral_constant {}; #else template using is_trivially_copyable = std::is_trivially_copyable; #endif /*** * _t * * Instead of: * * using decayed = typename std::decay::type; * * With the C++14 standard trait aliases, we could use: * * using decayed = std::decay_t; * * Without them, we could use: * * using decayed = _t>; * * Also useful for any other library with template types having dependent * member types named `type`, like the standard trait types. */ template using _t = typename T::type; /** * type_t * * A type alias for the first template type argument. `type_t` is useful for * controlling class-template and function-template partial specialization. * * Example: * * template * class Container { * public: * template * Container( * type_t()...))>, * Args&&...); * }; * * void_t * * A type alias for `void`. `void_t` is useful for controling class-template * and function-template partial specialization. * * Example: * * // has_value_type::value is true if T has a nested type `value_type` * template * struct has_value_type * : std::false_type {}; * * template * struct has_value_type> * : std::true_type {}; */ /** * There is a bug in libstdc++, libc++, and MSVC's STL that causes it to * ignore unused template parameter arguments in template aliases and does not * cause substitution failures. This defect has been recorded here: * http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558. * * This causes the implementation of std::void_t to be buggy, as it is likely * defined as something like the following: * * template * using void_t = void; * * This causes the compiler to ignore all the template arguments and does not * help when one wants to cause substitution failures. Rather declarations * which have void_t in orthogonal specializations are treated as the same. * For example, assuming the possible `T` types are only allowed to have * either the alias `one` or `two` and never both or none: * * template ::one>* = nullptr> * void foo(T&&) {} * template ::two>* = nullptr> * void foo(T&&) {} * * The second foo() will be a redefinition because it conflicts with the first * one; void_t does not cause substitution failures - the template types are * just ignored. */ namespace traits_detail { template struct type_t_ { using type = T; }; } // namespace traits_detail template using type_t = typename traits_detail::type_t_::type; template using void_t = type_t; /** * A type trait to remove all const volatile and reference qualifiers on a * type T */ template struct remove_cvref { using type = typename std::remove_cv::type>::type; }; template using remove_cvref_t = typename remove_cvref::type; template struct IsNothrowSwappable : std::integral_constant< bool, std::is_nothrow_move_constructible::value&& noexcept( std::swap(std::declval(), std::declval()))> {}; template struct Conjunction : std::true_type {}; template struct Conjunction : T {}; template struct Conjunction : std::conditional, T>::type {}; template struct Negation : std::integral_constant {}; template using index_constant = std::integral_constant; } // namespace folly