6#include <unordered_map>
25namespace proto_value_details {
39 : std::integral_constant<bool,
40 std::is_nothrow_move_constructible<std::vector<move_may_throw>>{} &&
41 std::is_nothrow_move_constructible<
42 std::unordered_map<std::string, move_may_throw>>{}> {};
56 enum Kind { k_null = 0, k_bool = 1, k_double = 2, k_string = 3, k_list = 4, k_struct = 5 };
81 typename = std::enable_if_t<std::is_same<Val,
ProtoValue>{}>>
82 ProtoValue(std::vector<Val>)
noexcept(std::is_nothrow_move_constructible<std::vector<Val>>{});
86 typename = std::enable_if_t<std::is_same<Val, ProtoValue>{}>>
87 ProtoValue(std::unordered_map<std::string, Val>)
noexcept(
88 std::is_nothrow_move_constructible<std::unordered_map<std::string, Val>>{});
117 template <
typename Value = google::protobuf::Value>
120 friend void to_proto(
const ProtoValue& t, google::protobuf::Value* v);
129 template <
typename T>
136 template <
typename T>
140 template <
typename T>
145 template <
typename T>
150 template <
typename T>
155 template <
typename T>
160 template <
typename T>
165 template <typename T>
179 void (*copy)(
void const*,
void*);
180 void (*move)(
void*,
void*);
181 void (*to_proto)(
void const*, google::protobuf::Value*);
183 bool (*equal_to)(
void const*,
void const*,
const vtable&);
188 template <
typename T>
190 static_assert(std::is_nothrow_destructible<T>{},
"T has a throwing destructor");
192 model(T t)
noexcept(std::is_nothrow_move_constructible<T>{});
194 static void dtor(
void* self)
noexcept;
196 static void copy(
void const* self,
void* dest);
200 static void move(
void* self,
void* dest);
202 static void to_proto(
void const* self, google::protobuf::Value* v);
204 static Kind kind() noexcept;
206 static
bool equal_to(
void const* self,
void const* other, const vtable& other_vtable);
208 static constexpr vtable vtable_{dtor, copy, move, to_proto, kind, equal_to};
220 using BufType = std::aligned_union_t<0,
226 std::unordered_map<std::string, void*>>;
228 static constexpr std::size_t local_storage_size =
sizeof(BufType);
229 static constexpr std::size_t local_storage_alignment =
alignof(BufType);
232 template <
typename T>
233 storage(T t)
noexcept(std::is_nothrow_move_constructible<T>{});
239 storage(
const storage&) =
delete;
240 storage(storage&&) =
delete;
241 storage& operator=(
const storage&) =
delete;
242 storage& operator=(storage&&) =
delete;
245 storage(
const storage& other,
const vtable& vtable);
248 storage(storage&& other,
249 const vtable& vtable)
noexcept(proto_value_details::all_moves_noexcept{});
253 void swap(
const vtable& this_vtable,
255 const vtable& other_vtable)
noexcept(proto_value_details::all_moves_noexcept{});
258 void destruct(
const vtable& vtable)
noexcept;
260 template <
typename T =
void>
262 return static_cast<T*
>(
static_cast<void*
>(&buf_));
265 template <
typename T =
void>
266 T
const* get()
const {
267 return static_cast<T const*
>(
static_cast<void const*
>(&buf_));
273 ProtoValue(
const google::protobuf::Value* value);
277 template <
typename T>
278 ProtoValue(T t, std::nullptr_t)
noexcept(std::is_nothrow_move_constructible<T>{});
286constexpr ProtoValue::vtable ProtoValue::model<T>::vtable_;
290using ProtoList = std::vector<ProtoValue>;
295using ProtoStruct = std::unordered_map<std::string, ProtoValue>;
299 std::is_nothrow_move_constructible<ProtoList>{});
301 std::is_nothrow_move_constructible<ProtoStruct>{});
304extern template bool& ProtoValue::get_unchecked<bool>();
305extern template double& ProtoValue::get_unchecked<double>();
307extern template bool ProtoValue::get_unchecked<bool>()
const;
308extern template double ProtoValue::get_unchecked<double>()
const;
311extern template std::string& ProtoValue::get_unchecked<std::string>() &;
312extern template ProtoList& ProtoValue::get_unchecked<ProtoList>() &;
313extern template ProtoStruct& ProtoValue::get_unchecked<ProtoStruct>() &;
315extern template std::string
const& ProtoValue::get_unchecked<std::string>() const&;
316extern template ProtoList const& ProtoValue::get_unchecked<ProtoList>() const&;
317extern template ProtoStruct const& ProtoValue::get_unchecked<ProtoStruct>() const&;
319extern template std::
string&& ProtoValue::get_unchecked<std::
string>() &&;
320extern template ProtoList&& ProtoValue::get_unchecked<ProtoList>() &&;
321extern template ProtoStruct&& ProtoValue::get_unchecked<ProtoStruct>() &&;
323void to_proto(std::nullptr_t, google::protobuf::Value* v);
324void to_proto(
bool b, google::protobuf::Value* v);
325void to_proto(
double d, google::protobuf::Value* v);
326void to_proto(std::
string s, google::protobuf::Value* v);
327void to_proto(const ProtoList& vec, google::protobuf::Value* v);
328void to_proto(const ProtoStruct& m, google::protobuf::Value* v);
329void to_proto(const ProtoValue& t, google::protobuf::Value* v);
331void struct_to_map(google::protobuf::Struct const* s, ProtoStruct& m);
332void map_to_struct(const ProtoStruct& m, google::protobuf::Struct* s);
338template <typename Value = google::protobuf::Value>
339Value to_proto(const ProtoValue& proto_value) {
341 to_proto(proto_value, &v);
350template <
typename Struct = google::protobuf::Struct>
351ProtoStruct struct_to_map(
const Struct& s) {
353 struct_to_map(&s, result);
362template <
typename Struct = google::protobuf::Struct>
363Struct map_to_struct(
const ProtoStruct& m) {
365 map_to_struct(m, &s);
370namespace proto_value_details {
375template <ProtoValue::Kind k>
376using KindConstant = std::integral_constant<ProtoValue::Kind, k>;
379struct kind<std::nullptr_t> {
380 using type = KindConstant<ProtoValue::Kind::k_null>;
385 using type = KindConstant<ProtoValue::Kind::k_bool>;
390 using type = KindConstant<ProtoValue::Kind::k_double>;
394struct kind<std::string> {
395 using type = KindConstant<ProtoValue::Kind::k_string>;
399struct kind<ProtoList> {
400 using type = KindConstant<ProtoValue::Kind::k_list>;
404struct kind<ProtoStruct> {
405 using type = KindConstant<ProtoValue::Kind::k_struct>;
417 if (this->is_a<T>()) {
418 return this->self_.template get<T>();
426 if (this->is_a<T>()) {
427 return this->self_.template get<T>();
Type-erased value for storing google::protobuf::Value types. A ProtoValue can be nullptr,...
Definition proto_value.hpp:53
static ProtoValue from_proto(const Value &v)
Construct from proto value.
bool is_null() const
Convenience version of is_a<T> to check if the value is nullptr.
ProtoValue(ProtoValue &&other) noexcept(proto_value_details::all_moves_noexcept{})
Move construct this from other, leaving other in its unspecified-but-valid moved from state.
T * get()
Return a T pointer if this is_a<T>(), else return nullptr.
Definition proto_value.hpp:416
std::enable_if_t< std::is_scalar< T >{}, T & > get_unchecked()
Return a reference to the underlying T, without checking.
ProtoValue & operator=(ProtoValue &&other) noexcept(proto_value_details::all_moves_noexcept{})
Move assignment from other, leaving other in its unspecified-but-valid moved from state.
ProtoValue() noexcept
Construct a null object.
bool is_a() const
Checks whether this ProtoT is an instance of type T.
Definition proto_value.hpp:411
friend bool operator==(const ProtoValue &lhs, const ProtoValue &rhs)
Test equality of two types.
Kind kind() const
Obtain enumerator constant representing the stored data type.
ProtoValue(std::unordered_map< std::string, Val >) noexcept(std::is_nothrow_move_constructible< std::unordered_map< std::string, Val > >{})
Construct from a ProtoStruct.
ProtoValue(std::vector< Val >) noexcept(std::is_nothrow_move_constructible< std::vector< Val > >{})
Construct from a ProtoList.
T const * get() const
Return a T pointer if this is_a<T>(), else return nullptr.
Kind
Type discriminator constants for possible values stored in a ProtoValue.
Definition proto_value.hpp:56
Definition proto_value.hpp:42
Definition proto_value.hpp:373
Definition proto_value.hpp:27