Coverage Report

Created: 2025-04-27 06:20

/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++14 versions of standard <utility> header
16
// abstractions available within 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
//   * apply<Functor, Tuple>         == std::apply<Functor, Tuple>
22
//   * exchange<T>                   == std::exchange<T>
23
//   * make_from_tuple<T>            == std::make_from_tuple<T>
24
//
25
// This header file also provides the tag types `in_place_t`, `in_place_type_t`,
26
// and `in_place_index_t`, as well as the constant `in_place`, and
27
// `constexpr` `std::move()` and `std::forward()` implementations in C++11.
28
//
29
// References:
30
//
31
//  https://en.cppreference.com/w/cpp/utility/apply
32
//  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
33
34
#ifndef ABSL_UTILITY_UTILITY_H_
35
#define ABSL_UTILITY_UTILITY_H_
36
37
#include <cstddef>
38
#include <cstdlib>
39
#include <tuple>
40
#include <utility>
41
42
#include "absl/base/config.h"
43
#include "absl/base/internal/inline_variable.h"
44
#include "absl/base/internal/invoke.h"
45
#include "absl/meta/type_traits.h"
46
47
namespace absl {
48
ABSL_NAMESPACE_BEGIN
49
50
// Historical note: Abseil once provided implementations of these
51
// abstractions for platforms that had not yet provided them. Those
52
// platforms are no longer supported. New code should simply use the
53
// the ones from std directly.
54
using std::index_sequence;
55
using std::index_sequence_for;
56
using std::integer_sequence;
57
using std::make_index_sequence;
58
using std::make_integer_sequence;
59
60
namespace utility_internal {
61
62
template <typename T>
63
struct InPlaceTypeTag {
64
  explicit InPlaceTypeTag() = delete;
65
  InPlaceTypeTag(const InPlaceTypeTag&) = delete;
66
  InPlaceTypeTag& operator=(const InPlaceTypeTag&) = delete;
67
};
68
69
template <size_t I>
70
struct InPlaceIndexTag {
71
  explicit InPlaceIndexTag() = delete;
72
  InPlaceIndexTag(const InPlaceIndexTag&) = delete;
73
  InPlaceIndexTag& operator=(const InPlaceIndexTag&) = delete;
74
};
75
76
}  // namespace utility_internal
77
78
// Tag types
79
80
#ifdef ABSL_USES_STD_OPTIONAL
81
82
using std::in_place_t;
83
using std::in_place;
84
85
#else  // ABSL_USES_STD_OPTIONAL
86
87
// in_place_t
88
//
89
// Tag type used to specify in-place construction, such as with
90
// `absl::optional`, designed to be a drop-in replacement for C++17's
91
// `std::in_place_t`.
92
struct in_place_t {};
93
94
ABSL_INTERNAL_INLINE_CONSTEXPR(in_place_t, in_place, {});
95
96
#endif  // ABSL_USES_STD_OPTIONAL
97
98
#if defined(ABSL_USES_STD_ANY) || defined(ABSL_USES_STD_VARIANT)
99
using std::in_place_type;
100
using std::in_place_type_t;
101
#else
102
103
// in_place_type_t
104
//
105
// Tag type used for in-place construction when the type to construct needs to
106
// be specified, such as with `absl::any`, designed to be a drop-in replacement
107
// for C++17's `std::in_place_type_t`.
108
template <typename T>
109
using in_place_type_t = void (*)(utility_internal::InPlaceTypeTag<T>);
110
111
template <typename T>
112
void in_place_type(utility_internal::InPlaceTypeTag<T>) {}
113
#endif  // ABSL_USES_STD_ANY || ABSL_USES_STD_VARIANT
114
115
#ifdef ABSL_USES_STD_VARIANT
116
using std::in_place_index;
117
using std::in_place_index_t;
118
#else
119
120
// in_place_index_t
121
//
122
// Tag type used for in-place construction when the type to construct needs to
123
// be specified, such as with `absl::any`, designed to be a drop-in replacement
124
// for C++17's `std::in_place_index_t`.
125
template <size_t I>
126
using in_place_index_t = void (*)(utility_internal::InPlaceIndexTag<I>);
127
128
template <size_t I>
129
void in_place_index(utility_internal::InPlaceIndexTag<I>) {}
130
#endif  // ABSL_USES_STD_VARIANT
131
132
// Constexpr move and forward
133
134
// move()
135
//
136
// A constexpr version of `std::move()`, designed to be a drop-in replacement
137
// for C++14's `std::move()`.
138
template <typename T>
139
constexpr absl::remove_reference_t<T>&& move(T&& t) noexcept {
140
  return static_cast<absl::remove_reference_t<T>&&>(t);
141
}
142
143
// forward()
144
//
145
// A constexpr version of `std::forward()`, designed to be a drop-in replacement
146
// for C++14's `std::forward()`.
147
template <typename T>
148
constexpr T&& forward(
149
0
    absl::remove_reference_t<T>& t) noexcept {  // NOLINT(runtime/references)
150
0
  return static_cast<T&&>(t);
151
0
}
Unexecuted instantiation: absl::lts_20240116::string_view&& absl::lts_20240116::forward<absl::lts_20240116::string_view>(std::__1::remove_reference<absl::lts_20240116::string_view>::type&)
Unexecuted instantiation: char const*&& absl::lts_20240116::forward<char const*>(std::__1::remove_reference<char const*>::type&)
Unexecuted instantiation: unsigned long&& absl::lts_20240116::forward<unsigned long>(std::__1::remove_reference<unsigned long>::type&)
Unexecuted instantiation: std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> const& absl::lts_20240116::forward<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> const&>(std::__1::remove_reference<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> const&>::type&)
Unexecuted instantiation: unsigned int&& absl::lts_20240116::forward<unsigned int>(std::__1::remove_reference<unsigned int>::type&)
Unexecuted instantiation: void (*&&absl::lts_20240116::forward<void (*)(absl::lts_20240116::string_view)>(std::__1::remove_reference<void (*)(absl::lts_20240116::string_view)>::type&))(absl::lts_20240116::string_view)
Unexecuted instantiation: absl::lts_20240116::container_internal::CommonFields&& absl::lts_20240116::forward<absl::lts_20240116::container_internal::CommonFields>(std::__1::remove_reference<absl::lts_20240116::container_internal::CommonFields>::type&)
Unexecuted instantiation: absl::lts_20240116::hash_internal::Hash<std::__1::pair<google::protobuf::Message const*, google::protobuf::FieldDescriptor const*> > const& absl::lts_20240116::forward<absl::lts_20240116::hash_internal::Hash<std::__1::pair<google::protobuf::Message const*, google::protobuf::FieldDescriptor const*> > const&>(std::__1::remove_reference<absl::lts_20240116::hash_internal::Hash<std::__1::pair<google::protobuf::Message const*, google::protobuf::FieldDescriptor const*> > const&>::type&)
Unexecuted instantiation: std::__1::equal_to<std::__1::pair<google::protobuf::Message const*, google::protobuf::FieldDescriptor const*> > const& absl::lts_20240116::forward<std::__1::equal_to<std::__1::pair<google::protobuf::Message const*, google::protobuf::FieldDescriptor const*> > const&>(std::__1::remove_reference<std::__1::equal_to<std::__1::pair<google::protobuf::Message const*, google::protobuf::FieldDescriptor const*> > const&>::type&)
Unexecuted instantiation: std::__1::allocator<std::__1::pair<google::protobuf::Message const*, google::protobuf::FieldDescriptor const*> > const& absl::lts_20240116::forward<std::__1::allocator<std::__1::pair<google::protobuf::Message const*, google::protobuf::FieldDescriptor const*> > const&>(std::__1::remove_reference<std::__1::allocator<std::__1::pair<google::protobuf::Message const*, google::protobuf::FieldDescriptor const*> > const&>::type&)
152
153
namespace utility_internal {
154
// Helper method for expanding tuple into a called method.
155
template <typename Functor, typename Tuple, std::size_t... Indexes>
156
auto apply_helper(Functor&& functor, Tuple&& t, index_sequence<Indexes...>)
157
    -> decltype(absl::base_internal::invoke(
158
        absl::forward<Functor>(functor),
159
        std::get<Indexes>(absl::forward<Tuple>(t))...)) {
160
  return absl::base_internal::invoke(
161
      absl::forward<Functor>(functor),
162
      std::get<Indexes>(absl::forward<Tuple>(t))...);
163
}
164
165
}  // namespace utility_internal
166
167
// apply
168
//
169
// Invokes a Callable using elements of a tuple as its arguments.
170
// Each element of the tuple corresponds to an argument of the call (in order).
171
// Both the Callable argument and the tuple argument are perfect-forwarded.
172
// For member-function Callables, the first tuple element acts as the `this`
173
// pointer. `absl::apply` is designed to be a drop-in replacement for C++17's
174
// `std::apply`. Unlike C++17's `std::apply`, this is not currently `constexpr`.
175
//
176
// Example:
177
//
178
//   class Foo {
179
//    public:
180
//     void Bar(int);
181
//   };
182
//   void user_function1(int, std::string);
183
//   void user_function2(std::unique_ptr<Foo>);
184
//   auto user_lambda = [](int, int) {};
185
//
186
//   int main()
187
//   {
188
//       std::tuple<int, std::string> tuple1(42, "bar");
189
//       // Invokes the first user function on int, std::string.
190
//       absl::apply(&user_function1, tuple1);
191
//
192
//       std::tuple<std::unique_ptr<Foo>> tuple2(absl::make_unique<Foo>());
193
//       // Invokes the user function that takes ownership of the unique
194
//       // pointer.
195
//       absl::apply(&user_function2, std::move(tuple2));
196
//
197
//       auto foo = absl::make_unique<Foo>();
198
//       std::tuple<Foo*, int> tuple3(foo.get(), 42);
199
//       // Invokes the method Bar on foo with one argument, 42.
200
//       absl::apply(&Foo::Bar, tuple3);
201
//
202
//       std::tuple<int, int> tuple4(8, 9);
203
//       // Invokes a lambda.
204
//       absl::apply(user_lambda, tuple4);
205
//   }
206
template <typename Functor, typename Tuple>
207
auto apply(Functor&& functor, Tuple&& t)
208
    -> decltype(utility_internal::apply_helper(
209
        absl::forward<Functor>(functor), absl::forward<Tuple>(t),
210
        absl::make_index_sequence<std::tuple_size<
211
            typename std::remove_reference<Tuple>::type>::value>{})) {
212
  return utility_internal::apply_helper(
213
      absl::forward<Functor>(functor), absl::forward<Tuple>(t),
214
      absl::make_index_sequence<std::tuple_size<
215
          typename std::remove_reference<Tuple>::type>::value>{});
216
}
217
218
// exchange
219
//
220
// Replaces the value of `obj` with `new_value` and returns the old value of
221
// `obj`.  `absl::exchange` is designed to be a drop-in replacement for C++14's
222
// `std::exchange`.
223
//
224
// Example:
225
//
226
//   Foo& operator=(Foo&& other) {
227
//     ptr1_ = absl::exchange(other.ptr1_, nullptr);
228
//     int1_ = absl::exchange(other.int1_, -1);
229
//     return *this;
230
//   }
231
template <typename T, typename U = T>
232
T exchange(T& obj, U&& new_value) {
233
  T old_value = absl::move(obj);
234
  obj = absl::forward<U>(new_value);
235
  return old_value;
236
}
237
238
namespace utility_internal {
239
template <typename T, typename Tuple, size_t... I>
240
T make_from_tuple_impl(Tuple&& tup, absl::index_sequence<I...>) {
241
  return T(std::get<I>(std::forward<Tuple>(tup))...);
242
}
243
}  // namespace utility_internal
244
245
// make_from_tuple
246
//
247
// Given the template parameter type `T` and a tuple of arguments
248
// `std::tuple(arg0, arg1, ..., argN)` constructs an object of type `T` as if by
249
// calling `T(arg0, arg1, ..., argN)`.
250
//
251
// Example:
252
//
253
//   std::tuple<const char*, size_t> args("hello world", 5);
254
//   auto s = absl::make_from_tuple<std::string>(args);
255
//   assert(s == "hello");
256
//
257
template <typename T, typename Tuple>
258
constexpr T make_from_tuple(Tuple&& tup) {
259
  return utility_internal::make_from_tuple_impl<T>(
260
      std::forward<Tuple>(tup),
261
      absl::make_index_sequence<
262
          std::tuple_size<absl::decay_t<Tuple>>::value>{});
263
}
264
265
ABSL_NAMESPACE_END
266
}  // namespace absl
267
268
#endif  // ABSL_UTILITY_UTILITY_H_