diff --git a/include/ki/pclass/Enum.h b/include/ki/pclass/Enum.h index 50adc36..3494384 100644 --- a/include/ki/pclass/Enum.h +++ b/include/ki/pclass/Enum.h @@ -1,7 +1,6 @@ #pragma once #include "ki/pclass/types/EnumType.h" #include "ki/pclass/types/PrimitiveType.h" -#include "ki/util/BitTypes.h" namespace ki { @@ -10,125 +9,36 @@ namespace pclass /** * TODO: Documentation */ - class IEnum + class Enum { public: - explicit IEnum(const Type &type); - virtual ~IEnum() {} + explicit Enum(const Type &type, enum_value_t value = 0); + explicit Enum(const Type &type, const std::string &element_name); + Enum &operator=(const Enum &that); const EnumType &get_type() const; - virtual void write_to(BitStream &stream) const = 0; - virtual void read_from(BitStream &stream) = 0; + enum_value_t get_value() const; + void set_value(enum_value_t value); + void set_value(const std::string &element_name); + + void write_to(BitStream& stream) const; + void read_from(BitStream& stream); + + operator enum_value_t() const; + void operator=(enum_value_t value); + bool operator==(const enum_value_t &rhs) const; + + operator std::string() const; + void operator=(const std::string &element_name); + bool operator==(const std::string &rhs) const; + + bool operator==(const Enum &rhs) const; + bool operator!=(const Enum &rhs) const; private: - EnumType *m_type; - }; - - /** - * TODO: Documentation - */ - template - class Enum : public IEnum - { - // Make sure UnderlyingT is integral - static_assert( - is_integral::value, - "The underlying type of an enum must be integral." - ); - - public: - explicit Enum(const Type &type, UnderlyingT value = 0) - : IEnum(type) - { - set_value(value); - } - - explicit Enum(const Type &type, const std::string &element_name) - : IEnum(type) - { - set_value(element_name); - } - - UnderlyingT get_value() const - { - return m_value; - } - - virtual void set_value(UnderlyingT value) - { - if (value != 0 && !get_type().has_element(value)) - { - std::ostringstream oss; - oss << "Enum '" << get_type().get_name() - << "' has no element with value: " << value << "."; - throw runtime_error(oss.str()); - } - m_value = value; - } - - void set_value(const std::string &element_name) - { - m_value = get_type().get_element(element_name).get_value(); - } - - void write_to(BitStream& stream) const override - { - PrimitiveTypeWriter::write_to(stream, m_value); - } - - void read_from(BitStream& stream) override - { - UnderlyingT value; - PrimitiveTypeReader::read_from(stream, value); - set_value(value); - } - - operator UnderlyingT() const - { - return get_value(); - } - - void operator=(UnderlyingT value) - { - set_value(value); - } - - bool operator==(const UnderlyingT &rhs) const - { - return m_value == rhs; - } - - operator std::string() const - { - return get_type().get_element(m_value); - } - - void operator=(const std::string &element_name) - { - set_value(element_name); - } - - bool operator==(const std::string &rhs) const - { - if (!get_type().has_element(rhs)) - return false; - return m_value == get_type().get_element(rhs).get_value(); - } - - bool operator==(const Enum &rhs) const - { - return get_type() == &rhs.get_type() && - m_value == rhs.m_value; - } - - bool operator!=(const Enum &rhs) const - { - return !(*this == rhs); - } - - protected: - UnderlyingT m_value; + enum_value_t m_value; + const EnumType *m_type; }; } } \ No newline at end of file diff --git a/include/ki/pclass/StaticProperty.h b/include/ki/pclass/StaticProperty.h index 7963a85..112ef44 100644 --- a/include/ki/pclass/StaticProperty.h +++ b/include/ki/pclass/StaticProperty.h @@ -248,12 +248,16 @@ namespace pclass { static void write(const StaticProperty &prop, BitStream &stream) { - prop.get_type().write_to(stream, Value::make_reference(prop.m_value)); + prop.get_type().write_to( + stream, + Value::make_reference(prop.m_value) + ); } static void read(StaticProperty &prop, BitStream &stream) { - prop.get_type().read_from(stream, Value::make_reference(prop.m_value)); + Value value = prop.get_type().read_from(stream); + prop.m_value = value.get(); } }; @@ -272,14 +276,20 @@ namespace pclass >::type > { + using type = typename std::remove_pointer::type; + static void write(const StaticProperty &prop, BitStream &stream) { - prop.get_type().write_to(stream, Value::make_reference(*prop.m_value)); + prop.get_type().write_to( + stream, + Value::make_reference(*prop.m_value) + ); } static void read(StaticProperty &prop, BitStream &stream) { - prop.get_type().read_from(stream, Value::make_reference(*prop.m_value)); + Value value = prop.get_type().read_from(stream); + prop.m_value = value.take(); } }; diff --git a/include/ki/pclass/Value.h b/include/ki/pclass/Value.h index a88da21..ced2c8a 100644 --- a/include/ki/pclass/Value.h +++ b/include/ki/pclass/Value.h @@ -200,7 +200,17 @@ namespace pclass ~Value(); /** - * @return Whether or not the value being held is of type T. + * @returns Whether or the not the value is holding a reference or a value. + */ + bool is_reference() const + { + // If the pointer isn't owned, then it isn't this Value's responsibility + // to clean it up, so we say it's referencing something. + return !m_ptr_is_owned; + } + + /** + * @returns Whether or not the value being held is of type T. */ template bool is() const @@ -208,31 +218,74 @@ namespace pclass // Do the type hashes match? return m_type_hash == typeid(T).hash_code(); } + + /** + * @tparam T + * @returns A new Value instance that owns it's value. + */ + template + Value dereference() const + { + // Do we need to attempt casting? + if (!is()) + return m_caster->cast_value(*this); + return Value::make_value(*static_cast(m_value_ptr)); + } /** - * @return A reference to the value being held as the specified type. + * @tparam T The expected type. + * @returns A reference to the value being held. + * @throws ki::runtime_error The expected type and the type of the value being held are not the same. */ template const T &get() const { - // Do we need to attempt casting? + // Make sure they requested the correct type if (!is()) - return m_caster->cast_value(*this).get(); + throw runtime_error("Invalid call to Value::get."); + + // Return a reference to the value being held return *static_cast(m_value_ptr); } /** - * @return A reference to the value being held as the specified type. + * @tparam T The expected type. + * @returns A reference to the value being held. + * @throws ki::runtime_error If the expected type and the type of the value being held are not the same. */ template T &get() { - // Do we need to attempt casting? + // Make sure they requested the correct type if (!is()) - return m_caster->cast_value(*this).get(); + throw runtime_error("Invalid call to Value::get."); + + // Return a reference to the value being held return *static_cast(m_value_ptr); } + /** + * @tparam T The expected type. + * @returns A pointer to the value being held (that the caller takes ownership of). + * @throws ki::runtime_error If the Value is a reference. + * @throws ki::runtime_error If the expected type and the type of the value being held are not the same. + */ + template + T *take() + { + // Make sure this Value is not a reference + if (is_reference()) + throw runtime_error("Cannot take ownership from a reference Value."); + + // Make sure they requested the correct type + if (!is()) + throw runtime_error("Invalid call to Value::get."); + + // Give up the pointer (this Value becomes a reference) + m_ptr_is_owned = false; + return static_cast(m_value_ptr); + } + /** * @tparam T The type of value to hold. * @param[in] value The initial value. @@ -278,11 +331,7 @@ namespace pclass private: void *m_value_ptr; bool m_ptr_is_owned; - std::size_t m_type_hash; - bool m_value_is_object; - bool m_value_is_enum; - ValueCaster *m_caster; detail::ValueDeallocator m_deallocator; @@ -295,15 +344,6 @@ namespace pclass template void construct() { - m_value_is_object = std::is_base_of< - PropertyClass, - typename std::decay::type - >::value; - m_value_is_enum = std::is_base_of< - IEnum, - typename std::decay::type - >::value; - m_type_hash = typeid(T).hash_code(); m_caster = &ValueCaster::get(); m_deallocator = detail::ValueDeallocator::make(); diff --git a/include/ki/pclass/VectorProperty.h b/include/ki/pclass/VectorProperty.h index 94dae5b..588d9a3 100644 --- a/include/ki/pclass/VectorProperty.h +++ b/include/ki/pclass/VectorProperty.h @@ -227,7 +227,11 @@ namespace pclass // Ensure index is within bounds if (index < 0 || index >= prop.size()) throw runtime_error("Index out of bounds."); - prop.get_type().write_to(stream, prop.at(index)); + + prop.get_type().write_to( + stream, + Value::make_reference(prop.at(index)) + ); } static void read_value_from(VectorProperty &prop, BitStream &stream, const int index) @@ -235,7 +239,9 @@ namespace pclass // Ensure index is within bounds if (index < 0 || index >= prop.size()) throw runtime_error("Index out of bounds."); - prop.get_type().read_from(stream, Value(prop.at(index))); + + Value value = prop.get_type().read_from(stream); + prop.at(index) = value.get(); } }; @@ -248,13 +254,18 @@ namespace pclass typename std::enable_if::value>::type > { + using type = typename std::remove_pointer::type; + static void write_value_to(const VectorProperty &prop, BitStream &stream, const int index) { // Ensure index is within bounds if (index < 0 || index >= prop.size()) throw runtime_error("Index out of bounds."); - - prop.get_type().write_to(stream, Value::make_reference(*prop.at(index))); + + prop.get_type().write_to( + stream, + Value::make_reference(*prop.at(index)) + ); } static void read_value_from(VectorProperty &prop, BitStream &stream, const int index) @@ -263,7 +274,9 @@ namespace pclass if (index < 0 || index >= prop.size()) throw runtime_error("Index out of bounds."); - prop.get_type().read_from(stream, Value::make_reference(*prop.at(index))); + Value value = prop.get_type().read_from(stream); + ValueT &value_ref = prop.at(index); + value_ref = value.take(); } }; diff --git a/include/ki/pclass/types/ClassType.h b/include/ki/pclass/types/ClassType.h index 98829cb..c99b056 100644 --- a/include/ki/pclass/types/ClassType.h +++ b/include/ki/pclass/types/ClassType.h @@ -1,9 +1,9 @@ #pragma once #include #include -#include "ki/pclass/Property.h" #include "ki/pclass/types/Type.h" #include "ki/pclass/PropertyClass.h" +#include "ki/pclass/Property.h" namespace ki { @@ -19,14 +19,10 @@ namespace pclass const Type *base_class, const TypeSystem &type_system); virtual ~IClassType() {} - void write_to(BitStream &stream, const Value &value) const override; - void read_from(BitStream &stream, Value &value) const override; - bool inherits(const Type &type) const; - protected: - virtual const PropertyClass &get_object_from_value(const Value &value) const = 0; - virtual PropertyClass &get_object_from_value(Value &value) const = 0; + void write_to(BitStream &stream, Value value) const override = 0; + Value read_from(BitStream &stream) const override = 0; private: const IClassType *m_base_class; @@ -44,21 +40,29 @@ namespace pclass public: ClassType(const std::string &name, const Type *base_class, const TypeSystem &type_system) - : IClassType(name, base_class, type_system) {} + : IClassType(name, base_class, type_system) + {} PropertyClass *instantiate() const override { return new ClassT(*this, get_type_system()); } - const PropertyClass& get_object_from_value(const Value& value) const override + void write_to(BitStream &stream, Value value) const override { - return dynamic_cast(value.get()); + const auto &object = value.get(); + const auto &properties = object.get_properties(); + for (auto it = properties.begin(); it != properties.end(); ++it) + it->write_value_to(stream); } - PropertyClass& get_object_from_value(Value& value) const override + Value read_from(BitStream &stream) const override { - return dynamic_cast(value.get()); + auto object = ClassT(*this, get_type_system()); + auto &properties = object.get_properties(); + for (auto it = properties.begin(); it != properties.end(); ++it) + it->read_value_from(stream); + return Value::make_value(object); } }; } diff --git a/include/ki/pclass/types/EnumType.h b/include/ki/pclass/types/EnumType.h index 884041e..1c06c1b 100644 --- a/include/ki/pclass/types/EnumType.h +++ b/include/ki/pclass/types/EnumType.h @@ -7,7 +7,7 @@ namespace ki { namespace pclass { - typedef uint64_t enum_value_t; + typedef uint32_t enum_value_t; /** * TODO: Documentation @@ -42,8 +42,8 @@ namespace pclass EnumType &add_element(const std::string &name, enum_value_t value); - void write_to(BitStream& stream, const Value& value) const override; - void read_from(BitStream& stream, Value& value) const override; + void write_to(BitStream &stream, Value value) const override; + Value read_from(BitStream &stream) const override; private: std::vector m_elements; @@ -68,17 +68,20 @@ namespace pclass m_kind = kind::ENUM; } - void write_to(BitStream& stream, const Value &value) const override + void write_to(BitStream &stream, const Value value) const override { - PrimitiveTypeWriter::write_to( - stream, reinterpret_cast(value.get()) - ); + auto &enum_reference = value.get(); + auto &underlying_reference = reinterpret_cast(enum_reference); + detail::primitive_type_helper::write_to(stream, underlying_reference); } - void read_from(BitStream& stream, Value &value) const override + Value read_from(BitStream &stream) const override { - PrimitiveTypeReader::read_from( - stream, reinterpret_cast(value.get()) + Value read_result = + detail::primitive_type_helper::read_from(stream); + auto underlying_value = read_result.get(); + return Value::make_value( + static_cast(underlying_value) ); } }; diff --git a/include/ki/pclass/types/FloatingPointPrimitiveType.h b/include/ki/pclass/types/FloatingPointPrimitiveType.h index 41fa848..018d938 100644 --- a/include/ki/pclass/types/FloatingPointPrimitiveType.h +++ b/include/ki/pclass/types/FloatingPointPrimitiveType.h @@ -5,9 +5,11 @@ namespace ki { namespace pclass +{ +namespace detail { template - struct PrimitiveTypeWriter< + struct primitive_type_helper< ValueT, typename std::enable_if::value>::type > @@ -21,6 +23,12 @@ namespace pclass stream.write(v, bitsizeof::value); } + static Value read_from(BitStream &stream) + { + uint_type uint_value = stream.read(bitsizeof::value); + return Value::make_value(*reinterpret_cast(&uint_value)); + } + private: /** * An unsigned integer type with the same size as the floating point type @@ -28,28 +36,6 @@ namespace pclass */ using uint_type = typename bits::value>::uint_type; }; - - template - struct PrimitiveTypeReader< - ValueT, - typename std::enable_if::value>::type - > - { - static void read_from(BitStream &stream, ValueT &value) - { - // Reinterpret the reference as a reference to an integer - uint_type &v = *( - reinterpret_cast(&value) - ); - v = stream.read(bitsizeof::value); - } - - private: - /** - * An unsigned integer type with the same size as the floating point type - * ValueT. - */ - using uint_type = typename bits::value>::uint_type; - }; +} } } diff --git a/include/ki/pclass/types/IntegralPrimitiveType.h b/include/ki/pclass/types/IntegralPrimitiveType.h index 7fb7302..496670c 100644 --- a/include/ki/pclass/types/IntegralPrimitiveType.h +++ b/include/ki/pclass/types/IntegralPrimitiveType.h @@ -5,9 +5,11 @@ namespace ki { namespace pclass +{ +namespace detail { template - struct PrimitiveTypeWriter< + struct primitive_type_helper< ValueT, typename std::enable_if::value>::type > @@ -16,18 +18,14 @@ namespace pclass { stream.write(value); } - }; - template - struct PrimitiveTypeReader< - ValueT, - typename std::enable_if::value>::type - > - { - static void read_from(BitStream &stream, ValueT &value) + static Value read_from(BitStream &stream) { - value = stream.read(); + return Value::make_value( + stream.read() + ); } }; } } +} diff --git a/include/ki/pclass/types/PrimitiveType.h b/include/ki/pclass/types/PrimitiveType.h index a27280e..03c6883 100644 --- a/include/ki/pclass/types/PrimitiveType.h +++ b/include/ki/pclass/types/PrimitiveType.h @@ -5,37 +5,42 @@ namespace ki { namespace pclass { - /** - * TODO: Documentation - */ - template - struct PrimitiveTypeWriter + namespace detail { - static void write_to(BitStream &stream, const ValueT &value) + /** + * TODO: Documentation + */ + template + struct primitive_type_helper { - // Provide a compiler error if this is not specialized - static_assert( - sizeof(ValueT) == 0, - "Missing specialization of PrimitiveTypeWriter::write_to" - ); - } - }; + /** + * TODO: Documentation + */ + static void write_to(BitStream &stream, const ValueT &value) + { + // Provide a compiler error if this is not specialized + static_assert( + sizeof(ValueT) == 0, + "Missing specialization of primitive_type_writer::write_to" + ); + } - /** - * TODO: Documentation - */ - template - struct PrimitiveTypeReader - { - static void read_from(BitStream &stream, ValueT &value) - { - // Provide a compiler error if this is not specialized - static_assert( - sizeof(ValueT) == 0, - "Missing specialization of PrimitiveTypeReader::read_from" - ); - } - }; + /** + * TODO: Documentation + */ + static Value read_from(BitStream &stream) + { + // Provide a compiler error if this is not specialized + static_assert( + sizeof(ValueT) == 0, + "Missing specialization of PrimitiveTypeReader::read_from" + ); + + // This should be impossible to reach. + throw runtime_error("Missing specialization of PrimitiveTypeReader::read_from"); + } + }; + } /** * TODO: Documentation @@ -50,11 +55,16 @@ namespace pclass m_kind = kind::PRIMITIVE; } - void write_to(BitStream &stream, const Value &value) const override + void write_to(BitStream &stream, const Value value) const override { try { - PrimitiveTypeWriter::write_to(stream, value.get()); + // Dereference the value to the correct type + Value deref_value = value.dereference(); + detail::primitive_type_helper::write_to( + stream, + deref_value.get() + ); } catch (runtime_error &e) { @@ -64,11 +74,11 @@ namespace pclass } } - void read_from(BitStream &stream, Value &value) const override + Value read_from(BitStream &stream) const override { try { - PrimitiveTypeReader::read_from(stream, value.get()); + return detail::primitive_type_helper::read_from(stream); } catch (runtime_error &e) { diff --git a/include/ki/pclass/types/StringPrimitiveType.h b/include/ki/pclass/types/StringPrimitiveType.h index 4af6870..a220009 100644 --- a/include/ki/pclass/types/StringPrimitiveType.h +++ b/include/ki/pclass/types/StringPrimitiveType.h @@ -4,13 +4,15 @@ namespace ki { namespace pclass +{ +namespace detail { template < typename _Elem, typename _Traits, typename _Alloc > - struct PrimitiveTypeWriter> + struct primitive_type_helper> { private: using type = std::basic_string<_Elem, _Traits, _Alloc>; @@ -25,29 +27,21 @@ namespace pclass for (auto it = value.begin(); it != value.end(); ++it) stream.write<_Elem>(*it); } - }; - template < - typename _Elem, - typename _Traits, - typename _Alloc - > - struct PrimitiveTypeReader> - { - private: - using type = std::basic_string<_Elem, _Traits, _Alloc>; - - public: - static void read_from(BitStream &stream, type &value) + static Value read_from(BitStream &stream) { // Read the length and create a new string with the correct capacity auto length = stream.read(); - value = type(length, ' '); + auto value = type(length, ' ');; // Read each character into the string for (auto it = value.begin(); it != value.end(); ++it) *it = stream.read<_Elem>(); + + // Copy string value into the return value + return Value::make_value(value); } }; } } +} diff --git a/include/ki/pclass/types/Type.h b/include/ki/pclass/types/Type.h index a6e8c81..be9a232 100644 --- a/include/ki/pclass/types/Type.h +++ b/include/ki/pclass/types/Type.h @@ -48,8 +48,8 @@ namespace pclass const TypeSystem &get_type_system() const; virtual PropertyClass *instantiate() const; - virtual void write_to(BitStream &stream, const Value &value) const; - virtual void read_from(BitStream &stream, Value &value) const; + virtual void write_to(BitStream &stream, Value value) const; + virtual Value read_from(BitStream &stream) const; protected: kind m_kind; diff --git a/src/pclass/ClassType.cpp b/src/pclass/ClassType.cpp index 0224101..c857ffb 100644 --- a/src/pclass/ClassType.cpp +++ b/src/pclass/ClassType.cpp @@ -28,22 +28,6 @@ namespace pclass m_base_class = nullptr; } - void IClassType::write_to(BitStream &stream, const Value &value) const - { - const auto &object = get_object_from_value(value); - const auto &properties = object.get_properties(); - for (auto it = properties.begin(); it != properties.end(); ++it) - it->write_value_to(stream); - } - - void IClassType::read_from(BitStream &stream, Value &value) const - { - auto &object = get_object_from_value(value); - auto &properties = object.get_properties(); - for (auto it = properties.begin(); it != properties.end(); ++it) - it->read_value_from(stream); - } - bool IClassType::inherits(const Type &type) const { // Types do not technically inherit from themselves, but it is more useful diff --git a/src/pclass/Enum.cpp b/src/pclass/Enum.cpp index acc8e6e..ca20a8b 100644 --- a/src/pclass/Enum.cpp +++ b/src/pclass/Enum.cpp @@ -4,6 +4,116 @@ namespace ki { namespace pclass { - // TODO: Runtime Enum implementation + Enum::Enum(const Type &type, const enum_value_t value) + { + // Make sure the type we've been given is an enum type + if (type.get_kind() != Type::kind::ENUM) + throw runtime_error("Enum constructor was supplied with a non-enum type."); + + m_type = &dynamic_cast(type); + set_value(value); + } + + Enum::Enum(const Type &type, const std::string &element_name) + { + // Make sure the type we've been given is an enum type + if (type.get_kind() != Type::kind::ENUM) + throw runtime_error("Enum constructor was supplied with a non-enum type."); + + m_type = &dynamic_cast(type); + set_value(element_name); + } + + Enum& Enum::operator=(const Enum& that) + { + // Are the types the same? + if (&get_type() != &that.get_type()) + throw runtime_error("Cannot change Enum type after it's constructed."); + set_value(that.m_value); + return *this; + } + + const EnumType &Enum::get_type() const + { + return *m_type; + } + + enum_value_t Enum::get_value() const + { + return m_value; + } + + void Enum::set_value(const enum_value_t value) + { + // Make sure the given value is valid for this enum type + if (value != 0 && !get_type().has_element(value)) + { + std::ostringstream oss; + oss << "Enum '" << get_type().get_name() + << "' has no element with value: " << value << "."; + throw runtime_error(oss.str()); + } + m_value = value; + } + + void Enum::set_value(const std::string& element_name) + { + m_value = get_type().get_element(element_name).get_value(); + } + + void Enum::write_to(BitStream& stream) const + { + detail::primitive_type_helper::write_to(stream, m_value); + } + + void Enum::read_from(BitStream& stream) + { + const auto value = detail::primitive_type_helper + ::read_from(stream).get(); + set_value(value); + } + + Enum::operator enum_value_t() const + { + return get_value(); + } + + void Enum::operator=(const enum_value_t value) + { + set_value(value); + } + + bool Enum::operator==(const enum_value_t &rhs) const + { + return m_value == rhs; + } + + Enum::operator std::basic_string() const + { + return get_type().get_element(m_value).get_name(); + } + + void Enum::operator=(const std::string& element_name) + { + set_value(element_name); + } + + bool Enum::operator==(const std::string& rhs) const + { + if (!get_type().has_element(rhs)) + return false; + return m_value == get_type().get_element(rhs).get_value(); + } + + bool Enum::operator==(const Enum &rhs) const + { + return &get_type() == &rhs.get_type() && + m_value == rhs.m_value; + } + + bool Enum::operator!=(const Enum& rhs) const + { + return !(*this == rhs); + } } } diff --git a/src/pclass/EnumType.cpp b/src/pclass/EnumType.cpp index ce92a15..c65ca16 100644 --- a/src/pclass/EnumType.cpp +++ b/src/pclass/EnumType.cpp @@ -1,6 +1,7 @@ #include "ki/pclass/types/EnumType.h" #include "ki/util/exception.h" #include +#include "ki/pclass/Enum.h" namespace ki { @@ -109,14 +110,17 @@ namespace pclass return *this; } - void EnumType::write_to(BitStream& stream, const Value &value) const + void EnumType::write_to(BitStream &stream, const Value value) const { - // TODO: Extend Value to get IEnum values + // Get an Enum reference and use it to write to the stream + value.get().write_to(stream); } - void EnumType::read_from(BitStream& stream, Value &value) const + Value EnumType::read_from(BitStream &stream) const { - // TODO: Extend Value to get IEnum values + auto value = Enum(*this); + value.read_from(stream); + return Value::make_value(value); } } } diff --git a/src/pclass/Type.cpp b/src/pclass/Type.cpp index b60344f..4f210b0 100644 --- a/src/pclass/Type.cpp +++ b/src/pclass/Type.cpp @@ -39,14 +39,14 @@ namespace pclass return m_type_system; } - void Type::write_to(BitStream &stream, const Value& value) const + void Type::write_to(BitStream &stream, Value value) const { std::ostringstream oss; oss << "Type '" << m_name << "' does not implement Type::write_to."; throw runtime_error(oss.str()); } - void Type::read_from(BitStream &stream, Value& value) const + Value Type::read_from(BitStream &stream) const { std::ostringstream oss; oss << "Type '" << m_name << "' does not implement Type::read_from."; diff --git a/src/pclass/Value.cpp b/src/pclass/Value.cpp index 9ce5b4c..ca770d9 100644 --- a/src/pclass/Value.cpp +++ b/src/pclass/Value.cpp @@ -69,8 +69,6 @@ namespace pclass m_value_ptr = value_ptr; m_ptr_is_owned = owned; m_type_hash = 0; - m_value_is_object = false; - m_value_is_enum = false; m_caster = nullptr; m_deallocator = detail::ValueDeallocator(); } @@ -82,9 +80,6 @@ namespace pclass m_value_ptr = that.m_value_ptr; m_ptr_is_owned = that.m_ptr_is_owned; that.m_ptr_is_owned = false; - - m_value_is_object = that.m_value_is_object; - m_value_is_enum = that.m_value_is_enum; m_type_hash = that.m_type_hash; m_caster = that.m_caster; m_deallocator = std::move(that.m_deallocator); @@ -101,9 +96,6 @@ namespace pclass m_value_ptr = that.m_value_ptr; m_ptr_is_owned = that.m_ptr_is_owned; that.m_ptr_is_owned = false; - - m_value_is_object = that.m_value_is_object; - m_value_is_enum = that.m_value_is_enum; m_type_hash = that.m_type_hash; m_caster = that.m_caster; m_deallocator = std::move(that.m_deallocator); diff --git a/test/src/unit-serialization.cpp b/test/src/unit-serialization.cpp index c32134d..2f1bd78 100644 --- a/test/src/unit-serialization.cpp +++ b/test/src/unit-serialization.cpp @@ -45,16 +45,22 @@ struct Vector3D void write_to(BitStream &stream) const { - pclass::PrimitiveTypeWriter::write_to(stream, m_x); - pclass::PrimitiveTypeWriter::write_to(stream, m_y); - pclass::PrimitiveTypeWriter::write_to(stream, m_z); + pclass::detail::primitive_type_helper + ::write_to(stream, m_x); + pclass::detail::primitive_type_helper + ::write_to(stream, m_y); + pclass::detail::primitive_type_helper + ::write_to(stream, m_z); } void read_from(BitStream &stream) { - pclass::PrimitiveTypeReader::read_from(stream, m_x); - pclass::PrimitiveTypeReader::read_from(stream, m_y); - pclass::PrimitiveTypeReader::read_from(stream, m_z); + m_x = pclass::detail::primitive_type_helper + ::read_from(stream).get(); + m_y = pclass::detail::primitive_type_helper + ::read_from(stream).get(); + m_z = pclass::detail::primitive_type_helper + ::read_from(stream).get(); } private: @@ -63,29 +69,34 @@ private: float m_z; }; -/** - * Type Writer for custom primitive type (Vector3D). - */ -template <> -struct pclass::PrimitiveTypeWriter +namespace ki { - static void write_to(BitStream &stream, const Vector3D &value) +namespace pclass +{ +namespace detail +{ + /** + * Helper for custom primitive type (Vector3D). + * Provides write_to and read_from implementations for PrimitiveType. + */ + template <> + struct primitive_type_helper { - value.write_to(stream); - } -}; + static void write_to(BitStream &stream, const Vector3D &value) + { + value.write_to(stream); + } -/** - * Type Reader for custom primitive type (Vector3D). - */ -template <> -struct pclass::PrimitiveTypeReader -{ - static void read_from(BitStream &stream, Vector3D &value) - { - value.read_from(stream); - } -}; + static Value read_from(BitStream &stream) + { + Vector3D value; + value.read_from(stream); + return Value::make_value(value); + } + }; +} +} +} /** * Enumeration used to test enum serialization.