Coverage Report

Created: 2023-06-07 07:13

/src/LPM/external.protobuf/include/absl/utility/utility.h
Line
Count
Source (jump to first uncovered line)
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 ABSL_UTILITY_UTILITY_H_
41
#define ABSL_UTILITY_UTILITY_H_
42
43
#include <cstddef>
44
#include <cstdlib>
45
#include <tuple>
46
#include <utility>
47
48
#include "absl/base/config.h"
49
#include "absl/base/internal/inline_variable.h"
50
#include "absl/base/internal/invoke.h"
51
#include "absl/meta/type_traits.h"
52
53
namespace absl {
54
ABSL_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
//   }
75
template <typename T, T... Ints>
76
struct 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`.
86
template <size_t... Ints>
87
using index_sequence = integer_sequence<size_t, Ints...>;
88
89
namespace utility_internal {
90
91
template <typename Seq, size_t SeqSize, size_t Rem>
92
struct Extend;
93
94
// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
95
template <typename T, T... Ints, size_t SeqSize>
96
struct Extend<integer_sequence<T, Ints...>, SeqSize, 0> {
97
  using type = integer_sequence<T, Ints..., (Ints + SeqSize)...>;
98
};
99
100
template <typename T, T... Ints, size_t SeqSize>
101
struct 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>'.
107
template <typename T, size_t N>
108
struct Gen {
109
  using type =
110
      typename Extend<typename Gen<T, N / 2>::type, N / 2, N % 2>::type;
111
};
112
113
template <typename T>
114
struct Gen<T, 0> {
115
  using type = integer_sequence<T>;
116
};
117
118
template <typename T>
119
struct InPlaceTypeTag {
120
  explicit InPlaceTypeTag() = delete;
121
  InPlaceTypeTag(const InPlaceTypeTag&) = delete;
122
  InPlaceTypeTag& operator=(const InPlaceTypeTag&) = delete;
123
};
124
125
template <size_t I>
126
struct 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`.
141
template <typename T, T N>
142
using 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`.
149
template <size_t N>
150
using 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()`
157
template <typename... Ts>
158
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
159
160
// Tag types
161
162
#ifdef ABSL_USES_STD_OPTIONAL
163
164
using std::in_place_t;
165
using std::in_place;
166
167
#else  // ABSL_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`.
174
struct in_place_t {};
175
176
ABSL_INTERNAL_INLINE_CONSTEXPR(in_place_t, in_place, {});
177
178
#endif  // ABSL_USES_STD_OPTIONAL
179
180
#if defined(ABSL_USES_STD_ANY) || defined(ABSL_USES_STD_VARIANT)
181
using std::in_place_type;
182
using 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`.
190
template <typename T>
191
using in_place_type_t = void (*)(utility_internal::InPlaceTypeTag<T>);
192
193
template <typename T>
194
void in_place_type(utility_internal::InPlaceTypeTag<T>) {}
195
#endif  // ABSL_USES_STD_ANY || ABSL_USES_STD_VARIANT
196
197
#ifdef ABSL_USES_STD_VARIANT
198
using std::in_place_index;
199
using 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`.
207
template <size_t I>
208
using in_place_index_t = void (*)(utility_internal::InPlaceIndexTag<I>);
209
210
template <size_t I>
211
void in_place_index(utility_internal::InPlaceIndexTag<I>) {}
212
#endif  // ABSL_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()`.
220
template <typename T>
221
constexpr 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()`.
229
template <typename T>
230
constexpr T&& forward(
231
0
    absl::remove_reference_t<T>& t) noexcept {  // NOLINT(runtime/references)
232
0
  return static_cast<T&&>(t);
233
0
}
Unexecuted instantiation: unsigned int&& absl::lts_20230125::forward<unsigned int>(std::__1::remove_reference<unsigned int>::type&)
Unexecuted instantiation: absl::lts_20230125::string_view&& absl::lts_20230125::forward<absl::lts_20230125::string_view>(std::__1::remove_reference<absl::lts_20230125::string_view>::type&)
Unexecuted instantiation: char const*&& absl::lts_20230125::forward<char const*>(std::__1::remove_reference<char const*>::type&)
Unexecuted instantiation: absl::lts_20230125::container_internal::HashtablezInfoHandle&& absl::lts_20230125::forward<absl::lts_20230125::container_internal::HashtablezInfoHandle>(std::__1::remove_reference<absl::lts_20230125::container_internal::HashtablezInfoHandle>::type&)
Unexecuted instantiation: unsigned long& absl::lts_20230125::forward<unsigned long&>(std::__1::remove_reference<unsigned long&>::type&)
Unexecuted instantiation: void (*&&absl::lts_20230125::forward<void (*)(absl::lts_20230125::string_view)>(std::__1::remove_reference<void (*)(absl::lts_20230125::string_view)>::type&))(absl::lts_20230125::string_view)
234
235
namespace utility_internal {
236
// Helper method for expanding tuple into a called method.
237
template <typename Functor, typename Tuple, std::size_t... Indexes>
238
auto apply_helper(Functor&& functor, Tuple&& t, index_sequence<Indexes...>)
239
    -> decltype(absl::base_internal::invoke(
240
        absl::forward<Functor>(functor),
241
        std::get<Indexes>(absl::forward<Tuple>(t))...)) {
242
  return absl::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
//   }
288
template <typename Functor, typename Tuple>
289
auto 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
//   }
313
template <typename T, typename U = T>
314
T 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
320
namespace utility_internal {
321
template <typename T, typename Tuple, size_t... I>
322
T 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
//
339
template <typename T, typename Tuple>
340
constexpr 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
347
ABSL_NAMESPACE_END
348
}  // namespace absl
349
350
#endif  // ABSL_UTILITY_UTILITY_H_