diff --git a/include/array.h b/include/array.h index ddc07b7..054fac6 100644 --- a/include/array.h +++ b/include/array.h @@ -62,9 +62,9 @@ public: * Create a new instance of this object * @return Field* */ - virtual Field *clone() const override + virtual std::shared_ptr clone() const override { - return new Array(*this); + return std::make_shared(*this); } /** @@ -84,7 +84,7 @@ public: Array set(uint8_t index, const Field &value) { // construct a shared pointer - auto ptr = std::shared_ptr(value.clone()); + auto ptr = value.clone(); // should we overwrite an existing record? if (index >= _fields.size()) @@ -181,7 +181,7 @@ public: bool first = true; // loop through all members - for (auto iter : _fields) + for (auto &iter : _fields) { // split with comma if (!first) stream << ","; @@ -196,6 +196,16 @@ public: // postfix stream << ")"; } + + /** + * Cast to array + * @return Array + */ + virtual operator const Array& () const override + { + // this already is an array, so no cast is necessary + return *this; + } }; /** diff --git a/include/booleanset.h b/include/booleanset.h index f165643..b527048 100644 --- a/include/booleanset.h +++ b/include/booleanset.h @@ -78,9 +78,9 @@ public: * Extending from field forces us to implement a clone function. * @return shared_ptr */ - virtual Field *clone() const override + virtual std::shared_ptr clone() const override { - return new BooleanSet(*this); + return std::make_shared(*this); } /** diff --git a/include/decimalfield.h b/include/decimalfield.h index 3164286..75a8ab0 100644 --- a/include/decimalfield.h +++ b/include/decimalfield.h @@ -83,9 +83,9 @@ public: * Create a new identical instance of this object * @return Field* */ - virtual Field *clone() const override + virtual std::shared_ptr clone() const override { - return new DecimalField(_places, _number); + return std::make_shared(_places, _number); } /** diff --git a/include/field.h b/include/field.h index 76f89ba..d6a7a88 100644 --- a/include/field.h +++ b/include/field.h @@ -37,7 +37,7 @@ public: * Create a new instance on the heap of this object, identical to the object passed * @return Field* */ - virtual Field *clone() const = 0; + virtual std::shared_ptr clone() const = 0; /** * Get the size this field will take when @@ -64,6 +64,25 @@ public: * @param std::ostream */ virtual void output(std::ostream &stream) const = 0; + + /** + * Casting operators + * @return mixed + */ + virtual operator const std::string& () const; + virtual operator const char * () const { return nullptr; } + virtual operator uint8_t () const { return 0; } + virtual operator uint16_t () const { return 0; } + virtual operator uint32_t () const { return 0; } + virtual operator uint64_t () const { return 0; } + virtual operator int8_t () const { return 0; } + virtual operator int16_t () const { return 0; } + virtual operator int32_t () const { return 0; } + virtual operator int64_t () const { return 0; } + virtual operator float () const { return 0; } + virtual operator double () const { return 0; } + virtual operator const Array& () const; + virtual operator const Table& () const; }; /** diff --git a/include/fieldproxy.h b/include/fieldproxy.h index 5cafcdc..2666850 100644 --- a/include/fieldproxy.h +++ b/include/fieldproxy.h @@ -197,6 +197,30 @@ public: return operator=(std::string(value)); } + /** + * Assign an array value + * @param value + * @return FieldProxy + */ + FieldProxy &operator=(const Array &value) + { + // assign value and allow chaining + _source->set(_index, value); + return *this; + } + + /** + * Assign a table value + * @param value + * @return FieldProxy + */ + FieldProxy &operator=(const Table &value) + { + // assign value and allow chaining + _source->set(_index, value); + return *this; + } + /** * Get the underlying field * @return Field @@ -210,97 +234,8 @@ public: * Get a boolean * @return bool */ - operator bool () - { - // retrieve the value - return _source->get(_index); - } - - /** - * Get numeric value - * @return int8_t - */ - operator int8_t () - { - // retrieve the value - return _source->get(_index); - } - - /** - * Get numeric value - * @return uint8_t - */ - operator uint8_t () - { - // retrieve the value - return _source->get(_index); - } - - /** - * Get numeric value - * @return int16_t - */ - operator int16_t () - { - // retrieve the value - return _source->get(_index); - } - - /** - * Get numeric value - * @return uint16_t - */ - operator uint16_t () - { - // retrieve the value - return _source->get(_index); - } - - /** - * Get numeric value - * @return int32_t - */ - operator int32_t () - { - // retrieve the value - return _source->get(_index); - } - - /** - * Get numeric value - * @return uint32_t - */ - operator uint32_t () - { - // retrieve the value - return _source->get(_index); - } - - /** - * Get numeric value - * @return int64_t - */ - operator int64_t () - { - // retrieve the value - return _source->get(_index); - } - - /** - * Get numeric value - * @return uint64_t - */ - operator uint64_t () - { - // retrieve the value - return _source->get(_index); - } - - /** - * Get string value - * @return string - */ - operator std::string () + template + operator TARGET () const { // retrieve the value return _source->get(_index); diff --git a/include/numericfield.h b/include/numericfield.h index 9a60e4d..3cd4c93 100644 --- a/include/numericfield.h +++ b/include/numericfield.h @@ -78,10 +78,10 @@ public: * Create a new instance of this object * @return Field* */ - virtual Field *clone() const override + virtual std::shared_ptr clone() const override { // create a new copy of ourselves and return it - return new NumericField(_value); + return std::make_shared(_value); } /** @@ -100,7 +100,7 @@ public: * Get the value * @return mixed */ - operator T () const + virtual operator T () const override { return _value; } diff --git a/include/stringfield.h b/include/stringfield.h index 3def910..0408de7 100644 --- a/include/stringfield.h +++ b/include/stringfield.h @@ -58,10 +58,10 @@ public: * Create a new instance of this object * @return Field* */ - virtual Field *clone() const override + virtual std::shared_ptr clone() const override { // create a new copy of ourselves and return it - return new StringField(_data); + return std::make_shared(_data); } /** @@ -96,7 +96,7 @@ public: * Get the value * @return string */ - operator const std::string& () const + virtual operator const std::string& () const override { return _data; } diff --git a/include/table.h b/include/table.h index 997c210..2faec2b 100644 --- a/include/table.h +++ b/include/table.h @@ -76,9 +76,9 @@ public: * Create a new instance on the heap of this object, identical to the object passed * @return Field* */ - virtual Field *clone() const override + virtual std::shared_ptr clone() const override { - return new Table(*this); + return std::make_shared(*this); } /** @@ -96,7 +96,7 @@ public: Table set(const std::string& name, const Field &value) { // copy to a new pointer and store it - _fields[name] = std::shared_ptr(value.clone()); + _fields[name] = value.clone(); // allow chaining return *this; @@ -122,6 +122,16 @@ public: return AssociativeFieldProxy(this, name); } + /** + * Get a field + * + * @param name field name + */ + AssociativeFieldProxy operator[](const char *name) + { + return AssociativeFieldProxy(this, name); + } + /** * Get a const field * @@ -132,6 +142,16 @@ public: return get(name); } + /** + * Get a const field + * + * @param name field name + */ + const Field &operator[](const char *name) const + { + return get(name); + } + /** * Write encoded payload to the given buffer. * @param buffer @@ -160,7 +180,7 @@ public: bool first = true; // loop through all members - for (auto iter : _fields) + for (auto &iter : _fields) { // split with comma if (!first) stream << ","; @@ -175,6 +195,17 @@ public: // postfix stream << ")"; } + + /** + * Cast to table + * @return Table + */ + virtual operator const Table& () const override + { + // this already is an array, so no cast is necessary + return *this; + } + }; /** diff --git a/src/field.cpp b/src/field.cpp index e49dc17..2655bb2 100644 --- a/src/field.cpp +++ b/src/field.cpp @@ -45,6 +45,45 @@ Field *Field::decode(ReceivedFrame &frame) } } +/** + * Cast to string + * @return std::string + */ +Field::operator const std::string& () const +{ + // static empty string + static std::string empty; + + // return it + return empty; +} + +/** + * Cast to array + * @return Array + */ +Field::operator const Array& () const +{ + // static empty array + static Array empty; + + // return it + return empty; +} + +/** + * Cast to object + * @return Array + */ +Field::operator const Table& () const +{ + // static empty table + static Table empty; + + // return it + return empty; +} + /** * End of namespace */