2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <type_traits>
28 * Usable when you have a function with two overloads:
31 * void something(MyData&&);
32 * void something(const MyData&);
34 * Where the purpose is to make copies and moves explicit without having to
35 * spell out the full type names - in this case, for copies, to invoke copy
38 * When the caller wants to pass a copy of an lvalue, the caller may:
42 * something(folly::copy(data)); // explicit copy
43 * something(std::move(data)); // explicit move
44 * something(data); // const& - neither move nor copy
47 * Note: If passed an rvalue, invokes the move-ctor, not the copy-ctor. This
48 * can be used to to force a move, where just using std::move would not:
50 * std::copy(std::move(data)); // force-move, not just a cast to &&
52 * Note: The following text appears in the standard:
54 * > In several places in this Clause the operation //DECAY_COPY(x)// is used.
55 * > All such uses mean call the function `decay_copy(x)` and use the result,
56 * > where `decay_copy` is defined as follows:
58 * > template <class T> decay_t<T> decay_copy(T&& v)
59 * > { return std::forward<T>(v); }
61 * > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf
62 * > 30.2.6 `decay_copy` [thread.decaycopy].
64 * We mimic it, with a `noexcept` specifier for good measure.
68 constexpr typename std::decay<T>::type copy(T&& value) noexcept(
69 noexcept(typename std::decay<T>::type(std::forward<T>(value)))) {
70 return std::forward<T>(value);
74 * A simple helper for getting a constant reference to an object.
78 * std::vector<int> v{1,2,3};
79 * // The following two lines are equivalent:
80 * auto a = const_cast<const std::vector<int>&>(v).begin();
81 * auto b = folly::as_const(v).begin();
83 * Like C++17's std::as_const. See http://wg21.link/p0007
85 #if __cpp_lib_as_const || _MSC_VER
87 /* using override */ using std::as_const;
92 constexpr T const& as_const(T& t) noexcept {
97 void as_const(T const&&) = delete;
101 #if __cpp_lib_integer_sequence || _MSC_VER
103 /* using override */ using std::integer_sequence;
104 /* using override */ using std::index_sequence;
105 /* using override */ using std::make_index_sequence;
109 template <class T, T... Ints>
110 struct integer_sequence {
111 using value_type = T;
113 static constexpr std::size_t size() noexcept {
114 return sizeof...(Ints);
118 template <std::size_t... Ints>
119 using index_sequence = folly::integer_sequence<std::size_t, Ints...>;
122 template <std::size_t N, std::size_t... Ints>
123 struct make_index_sequence
124 : detail::make_index_sequence<N - 1, N - 1, Ints...> {};
126 template <std::size_t... Ints>
127 struct make_index_sequence<0, Ints...> : folly::index_sequence<Ints...> {};
130 template <std::size_t N>
131 using make_index_sequence = detail::make_index_sequence<N>;
136 * A simple function object that passes its argument through unchanged.
141 * int &j = Identity()(i);
144 * Warning: passing a prvalue through Identity turns it into an xvalue,
145 * which can effect whether lifetime extension occurs or not. For instance:
147 * auto&& x = std::make_unique<int>(42);
148 * cout << *x ; // OK, x refers to a valid unique_ptr.
150 * auto&& y = Identity()(std::make_unique<int>(42));
151 * cout << *y ; // ERROR: y did not lifetime-extend the unique_ptr. It
152 * // is no longer valid
155 using is_transparent = void;
157 constexpr T&& operator()(T&& x) const noexcept {
158 return static_cast<T&&>(x);