6#include <bond/core/config.h>
8#include "detail/once.h"
9#include "detail/tags.h"
10#include "reflection.h"
11#include "runtime_schema.h"
13#include <boost/bind/bind.hpp>
14#include <boost/make_shared.hpp>
25 : schema(schema.schema),
27 instance(schema.instance)
30inline RuntimeSchema::RuntimeSchema(
const SchemaDef& schema)
36 : schema(schema.get()),
42 : schema(schema.schema),
44 instance(schema.instance)
48 : schema(schema.schema),
50 instance(schema.instance)
53inline bool RuntimeSchema::HasBase()
const
55 return !GetStruct().base_def.empty();
58inline RuntimeSchema RuntimeSchema::GetBaseSchema()
const
63inline const StructDef& RuntimeSchema::GetStruct()
const
65 BOOST_ASSERT(type->id == BT_STRUCT);
66 return schema->structs[type->struct_def];
69inline BondDataType RuntimeSchema::GetTypeId()
const
75template <
typename Protocols = BuiltInProtocols,
typename Writer>
76inline void Serialize(
const RuntimeSchema& schema, Writer& output)
78 Apply<Protocols>(SerializeTo<Protocols>(output), schema.GetSchema());
82template <
typename Protocols = BuiltInProtocols,
typename Writer>
83inline void Marshal(
const RuntimeSchema& schema, Writer& output)
85 Apply<Protocols>(MarshalTo<Protocols>(output), schema.GetSchema());
92 inline uint16_t schema_depth(
const RuntimeSchema& schema)
97 depth += schema_depth(schema.GetBaseSchema());
102 template <
typename T,
typename Unused =
void>
106 static const SchemaDef& Get()
116 call_once(flag, boost::bind(&AppendStructDef, &schema));
120 static void AppendStructDef(SchemaDef* s);
123 static SchemaDef schema;
124 static once_flag flag;
131 template <
typename Unused>
132 class SchemaCache<Unknown, Unused>
135 static const SchemaDef& Get()
140 static SchemaDef NewSchemaDef()
144 s.root.id = BT_STRUCT;
150 static const SchemaDef schema;
153 template <
typename T,
typename Unused>
154 SchemaDef SchemaCache<T, Unused>::schema;
156 template <
typename Unused>
157 const SchemaDef SchemaCache<Unknown, Unused>::schema
158 = SchemaCache<Unknown>::NewSchemaDef();
160 template <
typename T,
typename Unused>
161 once_flag SchemaCache<T, Unused>::flag;
167 using Parser = StaticParser<SchemaReader&>;
171template <
typename Unused>
struct
172uses_marshaled_bonded<SchemaReader&, Unused> : std::false_type
180 :
public SerializingTransform
183 InitSchemaDef(SchemaDef& schema)
185 _struct_def(schema.structs.size())
187 _schema.structs.push_back(StructDef());
191 void Begin(
const Metadata& metadata)
const
193 This().metadata = metadata;
200 template <
typename T>
201 bool Base(
const T& )
const
203 TypeDef type = GetTypeDef<typename remove_bonded<T>::type>();
204 This().base_def.set(type);
209 template <
typename T>
210 bool Field(uint16_t
id,
const Metadata& metadata,
const T&)
const
215 field.metadata = metadata;
216 field.type = GetTypeDef<typename remove_bonded_value<T>::type>();
218 This().fields.push_back(field);
223 template <
typename T>
224 typename boost::enable_if<is_basic_type<T>, TypeDef>::type
229 type.id = get_type_id<T>::value;
235 template <
typename T>
236 typename boost::enable_if_c<is_container<T>::value && !is_map_container<T>::value, TypeDef>::type
241 type.id = get_type_id<T>::value;
242 type.element.set() = GetTypeDef<typename element_type<T>::type>();
248 template <
typename T>
249 typename boost::enable_if<is_map_container<T>, TypeDef>::type
254 type.id = get_type_id<T>::value;
255 type.key.set() = GetTypeDef<typename element_type<T>::type::first_type>();
256 type.element.set() = GetTypeDef<typename element_type<T>::type::second_type>();
262 template <
typename T>
263 typename boost::enable_if<is_bond_type<T>, TypeDef>::type
268 type.id = get_type_id<T>::value;
269 type.struct_def = GetStructDef<typename remove_bonded<T>::type>();
270 type.bonded_type = is_bonded<T>::value;
276 template <
typename T>
277 uint16_t GetStructDef()
const
279 const auto& structs = _schema.structs;
281 BOOST_ASSERT(structs.size() <= (std::numeric_limits<uint16_t>::max)());
283 auto it = std::find_if(
286 [](
const StructDef& def)
288 return def.metadata.qualified_name == schema<T>::type::metadata.qualified_name;
291 const auto index =
static_cast<uint16_t
>(std::distance(std::begin(structs), it));
293 if (it == std::end(structs))
295 detail::SchemaCache<T>::AppendStructDef(&_schema);
306 StructDef& This()
const
308 BOOST_ASSERT(_schema.structs.size() > _struct_def);
309 return _schema.structs[_struct_def];
314 const size_t _struct_def;
320template <
typename T,
typename Unused>
321void SchemaCache<T, Unused>::AppendStructDef(SchemaDef* s)
323 Apply<T>(InitSchemaDef{ *s });
338 return RuntimeSchema(detail::SchemaCache<T>::Get());
342inline RuntimeSchema element_schema(
const RuntimeSchema& schema)
344 if (!schema.GetType().element.empty())
345 return RuntimeSchema(schema, schema.GetType().element.value());
347 return GetRuntimeSchema<Unknown>();
351inline RuntimeSchema key_schema(
const RuntimeSchema& schema)
353 if (!schema.GetType().key.empty())
354 return RuntimeSchema(schema, schema.GetType().key.value());
356 return GetRuntimeSchema<Unknown>();
361template <
typename T,
typename Map = std::map<T, std::
string> >
364 return GetValueToNameMap(T{}, detail::mpl::identity<Map>{});
369template <
typename T,
typename Map = std::map<std::
string, T> >
372 return GetNameToValueMap(T{}, detail::mpl::identity<Map>{});
Represents runtime schema See User's Manual
Definition: runtime_schema.h:26
RuntimeSchema()
Default constructor.
Definition: runtime_schema.h:29
namespace bond
Definition: apply.h:17
const Map & GetEnumNames()
Returns a const reference to a map of names for a user defined enum.
Definition: schema.h:370
RuntimeSchema GetRuntimeSchema()
Returns an instance of RuntimeSchema for a user defined struct.
Definition: schema.h:330
void Serialize(const T &obj, Writer &output)
Serialize an object using a protocol writer.
Definition: bond.h:19
void Marshal(const T &obj, Writer &output)
Marshal an object using a protocol writer.
Definition: bond.h:63
const Map & GetEnumValues()
Returns a const reference to a map of values for a user defined enum.
Definition: schema.h:362