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;
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_);
124 template <
typename T>
126 m_[
typeid(T)] = absl::make_unique<Data<T>>(std::move(v));
135 template <
typename T>
137 return m_.find(
typeid(T)) != m_.end();
145 template <
typename T>
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);
201 template <
typename T>
202 ValueTypeT<T>&
lookup(ValueTypeT<T> value = {}) {
203 auto p = m_.find(
typeid(T));
205 p = m_.emplace(
typeid(T), absl::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 absl::make_unique<Data<T>>(*
this);
241 ValueTypeT<T> value_;
247 std::unordered_map<std::type_index, std::unique_ptr<DataHolder>> m_;
258 template <
typename... T>
259 using OptionList = internal::TypeList<T...>;
264 template <
typename T>
265 struct WrapTypeList {
266 using Type = OptionList<T>;
268 template <
typename... T>
269 struct WrapTypeList<OptionList<T...>> {
270 using Type = OptionList<T...>;
272 template <
typename T>
273 using WrapTypeListT =
typename WrapTypeList<T>::Type;
275 template <
typename... T>
276 void CheckExpectedOptionsImpl(OptionList<T...>
const&,
Options const& opts,
277 char const* caller) {
278 CheckExpectedOptionsImpl({
typeid(T)...}, opts, caller);
310 template <
typename... T>
311 void CheckExpectedOptions(
Options const& opts,
char const* caller) {
312 using ExpectedTypes = TypeListCatT<WrapTypeListT<T>...>;
313 CheckExpectedOptionsImpl(ExpectedTypes{}, opts, caller);
326 Options const& CurrentOptions();
348 class 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;