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"
21 #include "absl/memory/memory.h"
25 #include <unordered_map>
34 void CheckExpectedOptionsImpl(std::set<std::type_index>
const&,
Options const&,
39 inline T
const& DefaultValue() {
40 static auto const*
const kDefaultValue =
new T{};
41 return *kDefaultValue;
92 using ValueTypeT =
typename T::Type;
99 for (
auto const& kv : rhs.m_) m_.emplace(kv.first, kv.second->clone());
103 std::swap(m_, tmp.m_);
122 template <
typename T>
124 m_[
typeid(T)] = absl::make_unique<Data<T>>(std::move(v));
133 template <
typename T>
135 return m_.find(
typeid(T)) != m_.end();
143 template <
typename T>
171 template <
typename T>
172 ValueTypeT<T>
const&
get()
const {
173 auto const it = m_.find(
typeid(T));
174 if (it == m_.end())
return internal::DefaultValue<ValueTypeT<T>>();
175 auto const* value = it->second->data_address();
176 return *
reinterpret_cast<ValueTypeT<T>
const*>(value);
199 template <
typename T>
200 ValueTypeT<T>&
lookup(ValueTypeT<T> value = {}) {
201 auto p = m_.find(
typeid(T));
203 p = m_.emplace(
typeid(T), absl::make_unique<Data<T>>(std::move(value)))
206 auto* v = p->second->data_address();
207 return *
reinterpret_cast<ValueTypeT<T>*>(v);
212 friend void internal::CheckExpectedOptionsImpl(
213 std::set<std::type_index>
const&,
Options const&,
char const*);
214 friend bool internal::IsEmpty(
Options const&);
219 virtual ~DataHolder() =
default;
220 virtual void const* data_address()
const = 0;
221 virtual void* data_address() = 0;
222 virtual std::unique_ptr<DataHolder> clone()
const = 0;
226 template <
typename T>
227 class Data :
public DataHolder {
229 explicit Data(ValueTypeT<T> v) : value_(std::move(v)) {}
230 ~Data()
override =
default;
232 void const* data_address()
const override {
return &value_; }
233 void* data_address()
override {
return &value_; }
234 std::unique_ptr<DataHolder> clone()
const override {
235 return absl::make_unique<Data<T>>(*
this);
239 ValueTypeT<T> value_;
245 std::unordered_map<std::type_index, std::unique_ptr<DataHolder>> m_;
256 template <
typename... T>
257 using OptionList = internal::TypeList<T...>;
262 template <
typename T>
263 struct WrapTypeList {
264 using Type = OptionList<T>;
266 template <
typename... T>
267 struct WrapTypeList<OptionList<T...>> {
268 using Type = OptionList<T...>;
270 template <
typename T>
271 using WrapTypeListT =
typename WrapTypeList<T>::Type;
273 template <
typename... T>
274 void CheckExpectedOptionsImpl(OptionList<T...>
const&,
Options const& opts,
275 char const* caller) {
276 CheckExpectedOptionsImpl({
typeid(T)...}, opts, caller);
308 template <
typename... T>
309 void CheckExpectedOptions(
Options const& opts,
char const* caller) {
310 using ExpectedTypes = TypeListCatT<WrapTypeListT<T>...>;
311 CheckExpectedOptionsImpl(ExpectedTypes{}, opts, caller);
324 Options const& CurrentOptions();
346 class ABSL_MUST_USE_RESULT OptionsSpan {
348 explicit OptionsSpan(
Options opts);
351 OptionsSpan(OptionsSpan
const&) =
delete;
352 OptionsSpan(OptionsSpan&&) =
delete;
353 OptionsSpan& operator=(OptionsSpan
const&) =
delete;
354 OptionsSpan& operator=(OptionsSpan&&) =
delete;
357 static void* operator
new(std::size_t) =
delete;
358 static void* operator
new[](std::size_t) =
delete;