22#include "palimpsest/internal/Allocator.h"
23#include "palimpsest/internal/is_valid_hash.h"
24#include "palimpsest/internal/type_name.h"
25#include "palimpsest/json/write.h"
26#include "palimpsest/mpack/Writer.h"
27#include "palimpsest/mpack/read.h"
28#include "palimpsest/mpack/write.h"
32using exceptions::TypeError;
46 other.copy_(*
this, other);
61 other.copy_(*
this, other);
84 reinterpret_cast<uint8_t *
>(internal::Allocator<T>().
allocate(1)));
92 void deserialize(mpack_node_t node) { deserialize_(*
this, node); }
98 void print(std::ostream &stream)
const { print_(*
this, stream); }
105 serialize_(*
this, writer.mpack_writer());
112 template <
typename T,
typename... ArgsT>
114 this->
type_name = &internal::type_name<T>;
115 this->
same = &internal::is_valid_hash<T, ArgsT...>;
119 dest.
same = src.same;
120 dest.deserialize_ = src.deserialize_;
121 dest.destroy_ = src.destroy_;
122 dest.print_ = src.print_;
123 dest.serialize_ = src.serialize_;
124 dest.copy_ = src.copy_;
125 const T *src_obj =
reinterpret_cast<const T *
>(src.buffer.get());
126 new (dest.
buffer.get()) T(*src_obj);
128 deserialize_ = [](
Value &self, mpack_node_t node) {
129 T *cast_buffer =
reinterpret_cast<T *
>(self.
buffer.get());
130 mpack::read<T>(node, *cast_buffer);
132 destroy_ = [](
Value &self) {
133 T *p =
reinterpret_cast<T *
>(self.
buffer.release());
135 internal::Allocator<T>().deallocate(p, 1);
137 print_ = [](
const Value &self, std::ostream &stream) {
138 const T *cast_buffer =
reinterpret_cast<const T *
>(self.
buffer.get());
139 json::write<T>(stream, *cast_buffer);
141 serialize_ = [](
const Value &self, mpack_writer_t *writer) {
142 const T *cast_buffer =
reinterpret_cast<const T *
>(self.
buffer.get());
143 mpack::write<T>(writer, *cast_buffer);
145 return *(
reinterpret_cast<T *
>(this->
buffer.get()));
154 template <
typename T>
156 if (!this->
same(
typeid(T).hash_code())) {
157 std::string cast_type = this->
type_name();
159 "Object has type \"" + cast_type +
160 "\" but is being cast to type \"" +
typeid(T).name() +
163 return *(
reinterpret_cast<T *
>(this->
buffer.get()));
168 std::unique_ptr<uint8_t[]>
buffer =
nullptr;
171 const char *(*type_name)();
181 void (*deserialize_)(
Value &, mpack_node_t);
184 void (*destroy_)(
Value &);
187 void (*print_)(
const Value &, std::ostream &);
190 void (*serialize_)(
const Value &, mpack_writer_t *);
Internal wrapper around an object and its type information.
T & setup()
Allocate object and register internal functions.
Value & operator=(Value &&)=default
Default move assignment operator.
~Value()
Destruct the object and free the internal buffer.
bool(* same)(std::size_t)
Function that checks if a given type matches the object's type.
void deserialize(mpack_node_t node)
Update value from an MPack node.
void print(std::ostream &stream) const
Print value to an output stream;.
Value()=default
Default constructor.
void allocate()
Allocate the internal buffer.
void serialize(mpack::Writer &writer) const
Serialize value to a MessagePack writer.
T & get_reference() const
Cast value to its object's type after checking that it matches T.
Value(Value &&)=default
Default move constructor.
Value & operator=(const Value &other)
Copy assignment operator.
std::unique_ptr< uint8_t[]> buffer
Internal buffer that holds the actual object.
Value(const Value &other)
Copy constructor.
const char *(* type_name)()
Function returning the name of the object's type.
Requested type doesn't match the one already in the dictionary.