15#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_OPTIONS_H
16#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_OPTIONS_H
18#include "google/cloud/internal/type_list.h"
19#include "google/cloud/version.h"
20#include "absl/base/attributes.h"
25#include <unordered_map>
34void CheckExpectedOptionsImpl(std::set<std::type_index>
const&,
Options const&,
39inline T
const& DefaultValue() {
40 static auto const*
const kDefaultValue =
new T{};
41 return *kDefaultValue;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
94 using ValueTypeT =
typename T::Type;
101 for (
auto const& kv : rhs.m_) m_.emplace(kv.first, kv.second->clone());
105 std::swap(m_, tmp.m_);
112
113
114
115
116
117
118
119
120
121
122
123
124 template <
typename T>
126 m_[
typeid(T)] = std::make_unique<Data<T>>(std::move(v));
131
132
133
134
135 template <
typename T>
137 return m_.find(
typeid(T)) != m_.end();
141
142
143
144
145 template <
typename T>
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 template <
typename T>
174 ValueTypeT<T>
const&
get()
const {
175 auto const it = m_.find(
typeid(T));
176 if (it == m_.end())
return internal::DefaultValue<ValueTypeT<T>>();
177 auto const* value = it->second->data_address();
178 return *
reinterpret_cast<ValueTypeT<T>
const*>(value);
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 template <
typename T>
202 ValueTypeT<T>&
lookup(ValueTypeT<T> value = {}) {
203 auto p = m_.find(
typeid(T));
205 p = m_.emplace(
typeid(T), std::make_unique<Data<T>>(std::move(value)))
208 auto* v = p->second->data_address();
209 return *
reinterpret_cast<ValueTypeT<T>*>(v);
214 friend void internal::CheckExpectedOptionsImpl(
215 std::set<std::type_index>
const&,
Options const&,
char const*);
216 friend bool internal::IsEmpty(
Options const&);
221 virtual ~DataHolder() =
default;
222 virtual void const* data_address()
const = 0;
223 virtual void* data_address() = 0;
224 virtual std::unique_ptr<DataHolder> clone()
const = 0;
228 template <
typename T>
229 class Data :
public DataHolder {
231 explicit Data(ValueTypeT<T> v) : value_(std::move(v)) {}
232 ~Data()
override =
default;
234 void const* data_address()
const override {
return &value_; }
235 void* data_address()
override {
return &value_; }
236 std::unique_ptr<DataHolder> clone()
const override {
237 return std::make_unique<Data<T>>(*
this);
241 ValueTypeT<T> value_;
247 std::unordered_map<std::type_index, std::unique_ptr<DataHolder>> m_;
251
252
253
254
255
256
257
258template <
typename... T>
259using OptionList = internal::TypeList<T...>;
266 using Type = OptionList<T>;
268template <
typename... T>
269struct WrapTypeList<OptionList<T...>> {
270 using Type = OptionList<T...>;
273using WrapTypeListT =
typename WrapTypeList<T>::Type;
275template <
typename... T>
276void CheckExpectedOptionsImpl(OptionList<T...>
const&,
Options const& opts,
277 char const* caller) {
278 CheckExpectedOptionsImpl({
typeid(T)...}, opts, caller);
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310template <
typename... T>
311void CheckExpectedOptions(
Options const& opts,
char const* caller) {
312 using ExpectedTypes = TypeListCatT<WrapTypeListT<T>...>;
313 CheckExpectedOptionsImpl(ExpectedTypes{}, opts, caller);
317
318
319
320
324
325
326Options const& CurrentOptions();
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348class ABSL_MUST_USE_RESULT OptionsSpan {
350 explicit OptionsSpan(
Options opts);
353 OptionsSpan(OptionsSpan
const&) =
delete;
354 OptionsSpan(OptionsSpan&&) =
delete;
355 OptionsSpan& operator=(OptionsSpan
const&) =
delete;
356 OptionsSpan& operator=(OptionsSpan&&) =
delete;
359 static void* operator
new(std::size_t) =
delete;
360 static void* operator
new[](std::size_t) =
delete;
A class that holds option structs indexed by their type.
Definition: options.h:91
bool has() const
Returns true IFF an option with type T exists.
Definition: options.h:136
ValueTypeT< T > const & get() const
Returns a reference to the value for T, or a value-initialized default if T was not set.
Definition: options.h:174
ValueTypeT< T > & lookup(ValueTypeT< T > value={})
Returns a reference to the value for option T, setting the value to init_value if necessary.
Definition: options.h:202
Options & set(ValueTypeT< T > v)
Sets option T to the value v and returns a reference to *this.
Definition: options.h:125
Options & operator=(Options const &rhs)
Definition: options.h:103
Options(Options const &rhs)
Definition: options.h:100
Options & operator=(Options &&)=default
void unset()
Erases the option specified by the type T.
Definition: options.h:146
Options()=default
Constructs an empty instance.
Options(Options &&)=default
Contains all the Google Cloud C++ Library APIs.
Definition: async_operation.h:23
Definition: async_operation.h:22
#define GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Definition: version.h:45
#define GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
Definition: version.h:43