]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/nostd/internal/absl/utility/utility.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / api / include / opentelemetry / nostd / internal / absl / utility / utility.h
CommitLineData
1e59de90
TL
1// Copyright 2017 The Abseil Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// This header file contains C++11 versions of standard <utility> header
16// abstractions available within C++14 and C++17, and are designed to be drop-in
17// replacement for code compliant with C++14 and C++17.
18//
19// The following abstractions are defined:
20//
21// * integer_sequence<T, Ints...> == std::integer_sequence<T, Ints...>
22// * index_sequence<Ints...> == std::index_sequence<Ints...>
23// * make_integer_sequence<T, N> == std::make_integer_sequence<T, N>
24// * make_index_sequence<N> == std::make_index_sequence<N>
25// * index_sequence_for<Ts...> == std::index_sequence_for<Ts...>
26// * apply<Functor, Tuple> == std::apply<Functor, Tuple>
27// * exchange<T> == std::exchange<T>
28// * make_from_tuple<T> == std::make_from_tuple<T>
29//
30// This header file also provides the tag types `in_place_t`, `in_place_type_t`,
31// and `in_place_index_t`, as well as the constant `in_place`, and
32// `constexpr` `std::move()` and `std::forward()` implementations in C++11.
33//
34// References:
35//
36// https://en.cppreference.com/w/cpp/utility/integer_sequence
37// https://en.cppreference.com/w/cpp/utility/apply
38// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
39
40#ifndef OTABSL_UTILITY_UTILITY_H_
41#define OTABSL_UTILITY_UTILITY_H_
42
43#include <cstddef>
44#include <cstdlib>
45#include <tuple>
46#include <utility>
47
48#include "../base/config.h"
49#include "../base/internal/inline_variable.h"
50#include "../base/internal/invoke.h"
51#include "../meta/type_traits.h"
52
53namespace absl {
54OTABSL_NAMESPACE_BEGIN
55
56// integer_sequence
57//
58// Class template representing a compile-time integer sequence. An instantiation
59// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
60// type through its template arguments (which is a common need when
61// working with C++11 variadic templates). `absl::integer_sequence` is designed
62// to be a drop-in replacement for C++14's `std::integer_sequence`.
63//
64// Example:
65//
66// template< class T, T... Ints >
67// void user_function(integer_sequence<T, Ints...>);
68//
69// int main()
70// {
71// // user_function's `T` will be deduced to `int` and `Ints...`
72// // will be deduced to `0, 1, 2, 3, 4`.
73// user_function(make_integer_sequence<int, 5>());
74// }
75template <typename T, T... Ints>
76struct integer_sequence {
77 using value_type = T;
78 static constexpr size_t size() noexcept { return sizeof...(Ints); }
79};
80
81// index_sequence
82//
83// A helper template for an `integer_sequence` of `size_t`,
84// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
85// `std::index_sequence`.
86template <size_t... Ints>
87using index_sequence = integer_sequence<size_t, Ints...>;
88
89namespace utility_internal {
90
91template <typename Seq, size_t SeqSize, size_t Rem>
92struct Extend;
93
94// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
95template <typename T, T... Ints, size_t SeqSize>
96struct Extend<integer_sequence<T, Ints...>, SeqSize, 0> {
97 using type = integer_sequence<T, Ints..., (Ints + SeqSize)...>;
98};
99
100template <typename T, T... Ints, size_t SeqSize>
101struct Extend<integer_sequence<T, Ints...>, SeqSize, 1> {
102 using type = integer_sequence<T, Ints..., (Ints + SeqSize)..., 2 * SeqSize>;
103};
104
105// Recursion helper for 'make_integer_sequence<T, N>'.
106// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
107template <typename T, size_t N>
108struct Gen {
109 using type =
110 typename Extend<typename Gen<T, N / 2>::type, N / 2, N % 2>::type;
111};
112
113template <typename T>
114struct Gen<T, 0> {
115 using type = integer_sequence<T>;
116};
117
118template <typename T>
119struct InPlaceTypeTag {
120 explicit InPlaceTypeTag() = delete;
121 InPlaceTypeTag(const InPlaceTypeTag&) = delete;
122 InPlaceTypeTag& operator=(const InPlaceTypeTag&) = delete;
123};
124
125template <size_t I>
126struct InPlaceIndexTag {
127 explicit InPlaceIndexTag() = delete;
128 InPlaceIndexTag(const InPlaceIndexTag&) = delete;
129 InPlaceIndexTag& operator=(const InPlaceIndexTag&) = delete;
130};
131
132} // namespace utility_internal
133
134// Compile-time sequences of integers
135
136// make_integer_sequence
137//
138// This template alias is equivalent to
139// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
140// replacement for C++14's `std::make_integer_sequence`.
141template <typename T, T N>
142using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
143
144// make_index_sequence
145//
146// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
147// and is designed to be a drop-in replacement for C++14's
148// `std::make_index_sequence`.
149template <size_t N>
150using make_index_sequence = make_integer_sequence<size_t, N>;
151
152// index_sequence_for
153//
154// Converts a typename pack into an index sequence of the same length, and
155// is designed to be a drop-in replacement for C++14's
156// `std::index_sequence_for()`
157template <typename... Ts>
158using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
159
160// Tag types
161
162#ifdef OTABSL_USES_STD_OPTIONAL
163
164using std::in_place_t;
165using std::in_place;
166
167#else // OTABSL_USES_STD_OPTIONAL
168
169// in_place_t
170//
171// Tag type used to specify in-place construction, such as with
172// `absl::optional`, designed to be a drop-in replacement for C++17's
173// `std::in_place_t`.
174struct in_place_t {};
175
176OTABSL_INTERNAL_INLINE_CONSTEXPR(in_place_t, in_place, {});
177
178#endif // OTABSL_USES_STD_OPTIONAL
179
180#if defined(OTABSL_USES_STD_ANY) || defined(OTABSL_USES_STD_VARIANT)
181using std::in_place_type;
182using std::in_place_type_t;
183#else
184
185// in_place_type_t
186//
187// Tag type used for in-place construction when the type to construct needs to
188// be specified, such as with `absl::any`, designed to be a drop-in replacement
189// for C++17's `std::in_place_type_t`.
190template <typename T>
191using in_place_type_t = void (*)(utility_internal::InPlaceTypeTag<T>);
192
193template <typename T>
194void in_place_type(utility_internal::InPlaceTypeTag<T>) {}
195#endif // OTABSL_USES_STD_ANY || OTABSL_USES_STD_VARIANT
196
197#ifdef OTABSL_USES_STD_VARIANT
198using std::in_place_index;
199using std::in_place_index_t;
200#else
201
202// in_place_index_t
203//
204// Tag type used for in-place construction when the type to construct needs to
205// be specified, such as with `absl::any`, designed to be a drop-in replacement
206// for C++17's `std::in_place_index_t`.
207template <size_t I>
208using in_place_index_t = void (*)(utility_internal::InPlaceIndexTag<I>);
209
210template <size_t I>
211void in_place_index(utility_internal::InPlaceIndexTag<I>) {}
212#endif // OTABSL_USES_STD_VARIANT
213
214// Constexpr move and forward
215
216// move()
217//
218// A constexpr version of `std::move()`, designed to be a drop-in replacement
219// for C++14's `std::move()`.
220template <typename T>
221constexpr absl::remove_reference_t<T>&& move(T&& t) noexcept {
222 return static_cast<absl::remove_reference_t<T>&&>(t);
223}
224
225// forward()
226//
227// A constexpr version of `std::forward()`, designed to be a drop-in replacement
228// for C++14's `std::forward()`.
229template <typename T>
230constexpr T&& forward(
231 absl::remove_reference_t<T>& t) noexcept { // NOLINT(runtime/references)
232 return static_cast<T&&>(t);
233}
234
235namespace utility_internal {
236// Helper method for expanding tuple into a called method.
237template <typename Functor, typename Tuple, std::size_t... Indexes>
238auto apply_helper(Functor&& functor, Tuple&& t, index_sequence<Indexes...>)
239 -> decltype(absl::OTABSL_OPTION_INLINE_NAMESPACE_NAME::base_internal::Invoke(
240 absl::forward<Functor>(functor),
241 std::get<Indexes>(absl::forward<Tuple>(t))...)) {
242 return absl::OTABSL_OPTION_INLINE_NAMESPACE_NAME::base_internal::Invoke(
243 absl::forward<Functor>(functor),
244 std::get<Indexes>(absl::forward<Tuple>(t))...);
245}
246
247} // namespace utility_internal
248
249// apply
250//
251// Invokes a Callable using elements of a tuple as its arguments.
252// Each element of the tuple corresponds to an argument of the call (in order).
253// Both the Callable argument and the tuple argument are perfect-forwarded.
254// For member-function Callables, the first tuple element acts as the `this`
255// pointer. `absl::apply` is designed to be a drop-in replacement for C++17's
256// `std::apply`. Unlike C++17's `std::apply`, this is not currently `constexpr`.
257//
258// Example:
259//
260// class Foo {
261// public:
262// void Bar(int);
263// };
264// void user_function1(int, std::string);
265// void user_function2(std::unique_ptr<Foo>);
266// auto user_lambda = [](int, int) {};
267//
268// int main()
269// {
270// std::tuple<int, std::string> tuple1(42, "bar");
271// // Invokes the first user function on int, std::string.
272// absl::apply(&user_function1, tuple1);
273//
274// std::tuple<std::unique_ptr<Foo>> tuple2(absl::make_unique<Foo>());
275// // Invokes the user function that takes ownership of the unique
276// // pointer.
277// absl::apply(&user_function2, std::move(tuple2));
278//
279// auto foo = absl::make_unique<Foo>();
280// std::tuple<Foo*, int> tuple3(foo.get(), 42);
281// // Invokes the method Bar on foo with one argument, 42.
282// absl::apply(&Foo::Bar, tuple3);
283//
284// std::tuple<int, int> tuple4(8, 9);
285// // Invokes a lambda.
286// absl::apply(user_lambda, tuple4);
287// }
288template <typename Functor, typename Tuple>
289auto apply(Functor&& functor, Tuple&& t)
290 -> decltype(utility_internal::apply_helper(
291 absl::forward<Functor>(functor), absl::forward<Tuple>(t),
292 absl::make_index_sequence<std::tuple_size<
293 typename std::remove_reference<Tuple>::type>::value>{})) {
294 return utility_internal::apply_helper(
295 absl::forward<Functor>(functor), absl::forward<Tuple>(t),
296 absl::make_index_sequence<std::tuple_size<
297 typename std::remove_reference<Tuple>::type>::value>{});
298}
299
300// exchange
301//
302// Replaces the value of `obj` with `new_value` and returns the old value of
303// `obj`. `absl::exchange` is designed to be a drop-in replacement for C++14's
304// `std::exchange`.
305//
306// Example:
307//
308// Foo& operator=(Foo&& other) {
309// ptr1_ = absl::exchange(other.ptr1_, nullptr);
310// int1_ = absl::exchange(other.int1_, -1);
311// return *this;
312// }
313template <typename T, typename U = T>
314T exchange(T& obj, U&& new_value) {
315 T old_value = absl::move(obj);
316 obj = absl::forward<U>(new_value);
317 return old_value;
318}
319
320namespace utility_internal {
321template <typename T, typename Tuple, size_t... I>
322T make_from_tuple_impl(Tuple&& tup, absl::index_sequence<I...>) {
323 return T(std::get<I>(std::forward<Tuple>(tup))...);
324}
325} // namespace utility_internal
326
327// make_from_tuple
328//
329// Given the template parameter type `T` and a tuple of arguments
330// `std::tuple(arg0, arg1, ..., argN)` constructs an object of type `T` as if by
331// calling `T(arg0, arg1, ..., argN)`.
332//
333// Example:
334//
335// std::tuple<const char*, size_t> args("hello world", 5);
336// auto s = absl::make_from_tuple<std::string>(args);
337// assert(s == "hello");
338//
339template <typename T, typename Tuple>
340constexpr T make_from_tuple(Tuple&& tup) {
341 return utility_internal::make_from_tuple_impl<T>(
342 std::forward<Tuple>(tup),
343 absl::make_index_sequence<
344 std::tuple_size<absl::decay_t<Tuple>>::value>{});
345}
346
347OTABSL_NAMESPACE_END
348} // namespace absl
349
350#endif // OTABSL_UTILITY_UTILITY_H_