]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/third-party/folly/folly/Traits.h
buildsys: change download over to reef release
[ceph.git] / ceph / src / rocksdb / third-party / folly / folly / Traits.h
CommitLineData
f67539c2
TL
1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
5
6#pragma once
7
8#include <type_traits>
9#include <utility>
10
11namespace folly {
12
13#if !defined(_MSC_VER)
14template <class T>
15struct is_trivially_copyable
16 : std::integral_constant<bool, __has_trivial_copy(T)> {};
17#else
18template <class T>
19using is_trivially_copyable = std::is_trivially_copyable<T>;
20#endif
21
22/***
23 * _t
24 *
25 * Instead of:
26 *
27 * using decayed = typename std::decay<T>::type;
28 *
29 * With the C++14 standard trait aliases, we could use:
30 *
31 * using decayed = std::decay_t<T>;
32 *
33 * Without them, we could use:
34 *
35 * using decayed = _t<std::decay<T>>;
36 *
37 * Also useful for any other library with template types having dependent
38 * member types named `type`, like the standard trait types.
39 */
40template <typename T>
41using _t = typename T::type;
42
43/**
44 * type_t
45 *
46 * A type alias for the first template type argument. `type_t` is useful for
47 * controlling class-template and function-template partial specialization.
48 *
49 * Example:
50 *
51 * template <typename Value>
52 * class Container {
53 * public:
54 * template <typename... Args>
55 * Container(
56 * type_t<in_place_t, decltype(Value(std::declval<Args>()...))>,
57 * Args&&...);
58 * };
59 *
60 * void_t
61 *
62 * A type alias for `void`. `void_t` is useful for controling class-template
63 * and function-template partial specialization.
64 *
65 * Example:
66 *
67 * // has_value_type<T>::value is true if T has a nested type `value_type`
68 * template <class T, class = void>
69 * struct has_value_type
70 * : std::false_type {};
71 *
72 * template <class T>
73 * struct has_value_type<T, folly::void_t<typename T::value_type>>
74 * : std::true_type {};
75 */
76
77/**
78 * There is a bug in libstdc++, libc++, and MSVC's STL that causes it to
79 * ignore unused template parameter arguments in template aliases and does not
80 * cause substitution failures. This defect has been recorded here:
81 * http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558.
82 *
83 * This causes the implementation of std::void_t to be buggy, as it is likely
84 * defined as something like the following:
85 *
86 * template <typename...>
87 * using void_t = void;
88 *
89 * This causes the compiler to ignore all the template arguments and does not
90 * help when one wants to cause substitution failures. Rather declarations
91 * which have void_t in orthogonal specializations are treated as the same.
92 * For example, assuming the possible `T` types are only allowed to have
93 * either the alias `one` or `two` and never both or none:
94 *
95 * template <typename T,
96 * typename std::void_t<std::decay_t<T>::one>* = nullptr>
97 * void foo(T&&) {}
98 * template <typename T,
99 * typename std::void_t<std::decay_t<T>::two>* = nullptr>
100 * void foo(T&&) {}
101 *
102 * The second foo() will be a redefinition because it conflicts with the first
103 * one; void_t does not cause substitution failures - the template types are
104 * just ignored.
105 */
106
107namespace traits_detail {
108template <class T, class...>
109struct type_t_ {
110 using type = T;
111};
112} // namespace traits_detail
113
114template <class T, class... Ts>
115using type_t = typename traits_detail::type_t_<T, Ts...>::type;
116template <class... Ts>
117using void_t = type_t<void, Ts...>;
118
119/**
120 * A type trait to remove all const volatile and reference qualifiers on a
121 * type T
122 */
123template <typename T>
124struct remove_cvref {
125 using type =
126 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
127};
128template <typename T>
129using remove_cvref_t = typename remove_cvref<T>::type;
130
131template <class T>
132struct IsNothrowSwappable
133 : std::integral_constant<
134 bool,
135 std::is_nothrow_move_constructible<T>::value&& noexcept(
136 std::swap(std::declval<T&>(), std::declval<T&>()))> {};
137
138template <typename...>
139struct Conjunction : std::true_type {};
140template <typename T>
141struct Conjunction<T> : T {};
142template <typename T, typename... TList>
143struct Conjunction<T, TList...>
144 : std::conditional<T::value, Conjunction<TList...>, T>::type {};
145
146template <typename T>
147struct Negation : std::integral_constant<bool, !T::value> {};
148
149template <std::size_t I>
150using index_constant = std::integral_constant<std::size_t, I>;
151
152} // namespace folly