dml: Simple implementation

Still missing specializations for each DML type
This commit is contained in:
Joshua Scott 2018-03-29 16:06:20 +01:00
parent 18b6aeb407
commit be07d23ecf
5 changed files with 147 additions and 24 deletions

View File

@ -7,18 +7,25 @@ namespace ki
namespace dml namespace dml
{ {
template <typename ValueT> template <typename ValueT>
class Field : public FieldBase class Field final : public FieldBase
{ {
friend Record; friend Record;
public: public:
ValueT get_value() const; virtual ~Field() = default;
void set_value(ValueT value);
Field<ValueT> *clone(const Record &record) const; ValueT get_value() const
{
return m_value;
}
void write_to(std::ostream &ostream) const; void set_value(ValueT value)
void read_from(std::istream &istream); {
size_t get_size() const; m_value = value;
}
void write_to(std::ostream &ostream) const final;
void read_from(std::istream &istream) final;
size_t get_size() const final;
protected: protected:
Field(std::string name, const Record &record) Field(std::string name, const Record &record)
: FieldBase(name, record) : FieldBase(name, record)
@ -28,6 +35,14 @@ namespace dml
} }
private: private:
ValueT m_value; ValueT m_value;
Field<ValueT> *clone(const Record &record) const final
{
auto *clone = new Field<ValueT>(m_name, record);
clone->m_transferable = true;
clone->m_value = m_value;
return clone;
}
}; };
typedef Field<BYT> BytField; typedef Field<BYT> BytField;

View File

@ -2,6 +2,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include <typeinfo>
#include "../util/Serializable.h" #include "../util/Serializable.h"
namespace ki namespace ki
@ -14,6 +15,8 @@ namespace dml
{ {
friend Record; friend Record;
public: public:
virtual ~FieldBase() = default;
const Record &get_record() const; const Record &get_record() const;
std::string get_name() const; std::string get_name() const;
bool is_transferable() const; bool is_transferable() const;
@ -24,18 +27,15 @@ namespace dml
return (typeid(ValueT).hash_code() == m_type_hash); return (typeid(ValueT).hash_code() == m_type_hash);
} }
protected: protected:
std::string m_name;
bool m_transferable;
size_t m_type_hash; size_t m_type_hash;
FieldBase(std::string name, const Record& record); FieldBase(std::string name, const Record& record);
void set_name(std::string name);
void set_transferable(bool transferable);
virtual FieldBase *clone(const Record &record) const = 0; virtual FieldBase *clone(const Record &record) const = 0;
private: private:
const Record &m_record; const Record &m_record;
std::string m_name;
bool m_transferable;
}; };
typedef std::vector<FieldBase *> FieldList; typedef std::vector<FieldBase *> FieldList;

View File

@ -6,11 +6,12 @@ namespace ki
{ {
namespace dml namespace dml
{ {
class Record : public util::Serializable class Record final : public util::Serializable
{ {
public: public:
Record(); Record();
Record(const Record &record); Record(const Record &record);
virtual ~Record();
bool has_field(std::string name) const; bool has_field(std::string name) const;
@ -19,33 +20,35 @@ namespace dml
{ {
if (!has_field(name)) if (!has_field(name))
return false; return false;
return m_field_map[name]->is_type<ValueT>(); return m_field_map.at(name)->is_type<ValueT>();
} }
template <typename ValueT> template <typename ValueT>
Field<ValueT> &get_field(std::string name) const Field<ValueT> *get_field(std::string name) const
{ {
if (has_field<ValueT>(name)) if (has_field<ValueT>(name))
return dynamic_cast<Field<ValueT> *>(m_fields[name]); return dynamic_cast<Field<ValueT> *>(m_field_map.at(name));
return nullptr; return nullptr;
} }
template <typename ValueT> template <typename ValueT>
Field<ValueT> &add_field(std::string name, bool transferable = true) Field<ValueT> *add_field(std::string name, bool transferable = true)
{ {
// Does this field already exist?
if (has_field<ValueT>(name)) if (has_field<ValueT>(name))
return nullptr; return get_field<ValueT>(name);
Field<ValueT> *field = new Field<ValueT>(name, *this);
auto *base = static_cast<FieldBase *>(field); // Create the field
m_fields.push_back(base); auto *field = new Field<ValueT>(name, *this);
m_field_map.insert({ base->get_name(), base }); field->m_transferable = transferable;
add_field(field);
return field; return field;
} }
size_t get_field_count() const; size_t get_field_count() const;
FieldList::iterator fields_begin() const; FieldList::const_iterator fields_begin() const;
FieldList::iterator fields_end() const; FieldList::const_iterator fields_end() const;
void write_to(std::ostream &ostream) const; void write_to(std::ostream &ostream) const;
void read_from(std::istream &istream); void read_from(std::istream &istream);
@ -53,6 +56,8 @@ namespace dml
private: private:
FieldList m_fields; FieldList m_fields;
FieldNameMap m_field_map; FieldNameMap m_field_map;
void add_field(FieldBase *field);
}; };
} }
} }

View File

@ -0,0 +1,30 @@
#include "ki/dml/FieldBase.h"
namespace ki
{
namespace dml
{
FieldBase::FieldBase(std::string name, const Record& record)
: m_record(record)
{
m_name = name;
m_transferable = true;
m_type_hash = 0;
}
const Record &FieldBase::get_record() const
{
return m_record;
}
std::string FieldBase::get_name() const
{
return m_name;
}
bool FieldBase::is_transferable() const
{
return m_transferable;
}
}
}

View File

@ -0,0 +1,73 @@
#include "ki/dml/Record.h"
namespace ki
{
namespace dml
{
Record::Record()
{
m_fields = FieldList();
m_field_map = FieldNameMap();
}
Record::~Record()
{
m_fields.clear();
m_field_map.clear();
for (auto it = m_fields.begin(); it != m_fields.end(); ++it)
delete *it;
}
Record::Record(const Record& record)
{
for (auto it = record.fields_begin(); it != record.fields_end(); ++it)
add_field((*it)->clone(*this));
}
bool Record::has_field(std::string name) const
{
return m_field_map.count(name);
}
size_t Record::get_field_count() const
{
return m_fields.size();
}
FieldList::const_iterator Record::fields_begin() const
{
return m_fields.begin();
}
FieldList::const_iterator Record::fields_end() const
{
return m_fields.end();
}
void Record::write_to(std::ostream &ostream) const
{
for (auto it = m_fields.begin(); it != m_fields.end(); ++it)
(*it)->write_to(ostream);
}
void Record::read_from(std::istream &istream)
{
for (auto it = m_fields.begin(); it != m_fields.end(); ++it)
(*it)->read_from(istream);
}
size_t Record::get_size() const
{
size_t size = 0;
for (auto it = m_fields.begin(); it != m_fields.end(); ++it)
size += (*it)->get_size();
return size;
}
void Record::add_field(FieldBase* field)
{
m_fields.push_back(field);
m_field_map.insert({ field->get_name(), field });
}
}
}