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>>{}> {};
57 ProtoValue(T t) noexcept(std::is_nothrow_move_constructible<T>{});
87 template <
typename Value = google::protobuf::Value>
90 friend void to_proto(
const ProtoValue& t, google::protobuf::Value* v);
106 template <
typename T>
110 template <
typename T>
125 void (*copy)(
void const*,
void*);
126 void (*move)(
void*,
void*);
127 void (*to_proto)(
void const*, google::protobuf::Value*);
129 bool (*equal_to)(
void const*,
void const*,
const vtable&);
134 template <
typename T>
136 static_assert(std::is_nothrow_destructible<T>{},
"T has a throwing destructor");
138 model(T t)
noexcept(std::is_nothrow_move_constructible<T>{});
140 static void dtor(
void* self)
noexcept;
142 static void copy(
void const* self,
void* dest);
146 static void move(
void* self,
void* dest);
148 static void to_proto(
void const* self, google::protobuf::Value* v);
150 static int kind() noexcept;
152 static
bool equal_to(
void const* self,
void const* other, const vtable& other_vtable);
154 static constexpr vtable vtable_{dtor, copy, move, to_proto, kind, equal_to};
166 using BufType = std::aligned_union_t<0,
173 std::unordered_map<std::string, void*>>;
175 static constexpr std::size_t local_storage_size =
sizeof(BufType);
176 static constexpr std::size_t local_storage_alignment =
alignof(BufType);
179 template <
typename T>
180 storage(T t)
noexcept(std::is_nothrow_move_constructible<T>{});
186 storage(
const storage&) =
delete;
187 storage(storage&&) =
delete;
188 storage& operator=(
const storage&) =
delete;
189 storage& operator=(storage&&) =
delete;
192 storage(
const storage& other,
const vtable& vtable);
195 storage(storage&& other,
196 const vtable& vtable)
noexcept(proto_value_details::all_moves_noexcept{});
200 void swap(
const vtable& this_vtable,
202 const vtable& other_vtable)
noexcept(proto_value_details::all_moves_noexcept{});
205 void destruct(
const vtable& vtable)
noexcept;
207 template <
typename T =
void>
209 return static_cast<T*
>(
static_cast<void*
>(&buf_));
212 template <
typename T =
void>
213 T
const* get()
const {
214 return static_cast<T const*
>(
static_cast<void const*
>(&buf_));
220 ProtoValue(
const google::protobuf::Value* value);
228constexpr ProtoValue::vtable ProtoValue::model<T>::vtable_;
233using ProtoStruct = std::unordered_map<std::string, ProtoValue>;
235void to_proto(std::nullptr_t, google::protobuf::Value* v);
236void to_proto(
bool b, google::protobuf::Value* v);
237void to_proto(
int i, google::protobuf::Value* v);
238void to_proto(
double d, google::protobuf::Value* v);
239void to_proto(std::string s, google::protobuf::Value* v);
240void to_proto(
const std::vector<ProtoValue>& vec, google::protobuf::Value* v);
241void to_proto(
const ProtoStruct& m, google::protobuf::Value* v);
242void to_proto(
const ProtoValue& t, google::protobuf::Value* v);
244ProtoStruct struct_to_map(google::protobuf::Struct
const* s);
245void map_to_struct(
const ProtoStruct& m, google::protobuf::Struct* s);
251template <
typename T,
typename Value = google::protobuf::Value>
252Value to_proto(T&& t) {
254 to_proto(std::forward<T>(t), &v);
263template <
typename Struct = google::protobuf::Struct>
264ProtoStruct struct_to_map(
const Struct& s) {
265 return struct_to_map(&s);
272template <
typename Struct = google::protobuf::Struct>
273Struct map_to_struct(
const ProtoStruct& m) {
275 map_to_struct(m, &s);
288struct kind_t<std::nullptr_t> : std::integral_constant<int, 0> {};
291struct kind_t<bool> : std::integral_constant<int, 1> {};
294struct kind_t<int> : std::integral_constant<int, 2> {};
297struct kind_t<double> : std::integral_constant<int, 3> {};
300struct kind_t<std::string> : std::integral_constant<int, 4> {};
303struct kind_t<std::vector<ProtoValue>> : std::integral_constant<int, 5> {};
306struct kind_t<ProtoStruct> : std::integral_constant<int, 6> {};
315 if (this->is_a<T>()) {
316 return this->self_.template get<T>();
324 if (this->is_a<T>()) {
325 return this->self_.template get<T>();
Type-erased value for storing google::protobuf::Value types. A ProtoValue can be nullptr,...
Definition proto_value.hpp:50
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.
ProtoValue(const char *str)
Deduction helper constructor for string from string literal.
T * get()
Return a T pointer if this is_a<T>(), else return nullptr.
Definition proto_value.hpp:314
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:309
friend bool operator==(const ProtoValue &lhs, const ProtoValue &rhs)
Test equality of two types.
int kind() const
Obtain integer constant representing the stored data type.
T const * get() const
Return a T pointer if this is_a<T>(), else return nullptr.
ProtoValue RTTI type trait. This type trait is used to implement the ProtoValue::kind method which pr...
Definition proto_value.hpp:285
Definition proto_value.hpp:42
Definition proto_value.hpp:27