From cecb5db97270efc8567aefce1c33966d6554829f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 6 Jun 2015 02:40:18 +0200 Subject: [PATCH] settle on an approach for handling attributes Initially, I considered to build an index table like collection of ordered attributes. But since our actual use case is Record, this was ruled out in favour of just a vector, where the keys are embedded right within the nameID-Field of GenNode. A decisive factor was the observation, that this design is basically forced to encode the attribute keys somehow into the attribute values, because otherwise the whole collection like initialisation and iteration would break down. Thus, a fully generic implementation is not possible, and a pseudo generic implementation just for the purpose of writing unit tests would be overkill. Basically this decision means that Record requires an explicit specialisation to implement the attribute-key binding for each value type to use. --- src/lib/diff/gen-node.hpp | 44 +++++++++++++ src/lib/diff/record.hpp | 129 +++++++++++++++++++++++++++----------- 2 files changed, 135 insertions(+), 38 deletions(-) diff --git a/src/lib/diff/gen-node.hpp b/src/lib/diff/gen-node.hpp index 41245df2f..cfce16e56 100644 --- a/src/lib/diff/gen-node.hpp +++ b/src/lib/diff/gen-node.hpp @@ -157,6 +157,50 @@ namespace diff{ + /* === Specialisation for handling of attributes in Record === */ + + template<> + inline bool + Record::isAttribute (GenNode const& v) + { + return false; ////TODO + } + + template<> + inline bool + Record::isTypeID (GenNode const& v) + { + return false; ////TODO + } + + template<> + inline string + Record::extractTypeID (GenNode const& v) + { + return "todo"; ////TODO + } + + template<> + inline GenNode + Record::buildTypeAttribute (string const& typeID) + { + return GenNode(); ///TODO + } + + template<> + inline string + Record::extractKey (GenNode const& v) + { + return "todo"; ////TODO + } + + template<> + inline GenNode + Record::extractVal (GenNode const& v) + { + return GenNode(); ///TODO + } + }} // namespace lib::diff #endif /*LIB_DIFF_GEN_NODE_H*/ diff --git a/src/lib/diff/record.hpp b/src/lib/diff/record.hpp index 5f87da6ad..3b6f2bb9c 100644 --- a/src/lib/diff/record.hpp +++ b/src/lib/diff/record.hpp @@ -55,7 +55,25 @@ ** ** \par rationale ** The underlying theme of this design is negative, dialectical: we do not want to - ** build yet another object system. The object model of C++ is deemed adequate. + ** build yet another object system. The object model of C++ is deemed adequate. + ** + ** @remarks + ** - the implementation is focused on the intended primary use case, + ** which is to exchange diff messages drawn against a symbolic representation + ** of a typed object tree. Especially, we assume that there is only a small + ** number of attributes (so linear search for access by key is adequate). + ** - moreover, we assume that the value type allows to somehow to embed + ** the key of each attribute; the implementation needs an explicit + ** specialisation of the binding functions for each value type. + ** - this header defines a specialisation for VAL = std::string -- + ** while the most relevant specialisation for GenNode is provided + ** alongside with this special, monadic value type. + ** - an alternative implementation approach would have been to use a + ** dedicated helper type to represent the collection of attributes. + ** This type might then be specialised, e.g. to utilise an index table + ** for key-value lookup. However, in the light of the intended usage + ** of Record entities as tree nodes within a GenNode monad, such a + ** more elaborate approach was deemed unnecessary for the time being. ** ** @see GenericRecordRepresentation_test ** @@ -78,7 +96,7 @@ #include #include #include -//#include + namespace lib { @@ -91,7 +109,24 @@ namespace diff{ - /** object-like record of data */ + /** + * object-like record of data. + * For symbolic representation of "objects". + * A Record holds both \em attributes (key-value data) + * plus a list of \em enclosed children, which are conceived + * to be within the "scope" of this Record. Optionally, a \em typeID + * (metadata) may be defined. Otherwise, this typeID defaults to \c "NIL". + * The representation of attributes depends on the actual value type, which + * somehow need the ability to encode the keys within the value data. + * By default, a specialisation is given for string, using the \c "key = val" + * syntax. Yet the most relevant use case is \c Record -- using the + * embedded name-ID of the GenNode elements as key for attributes. + * + * Recode elements meant to be immutable; they can be created from a + * defining collection. However, we provide a #Mutator mechanism to allow + * for rebuilding and mutating symbolic data structures based on Records + * and GenNode. Especially, Lumiera's diff framework relies on this. + */ template class Record { @@ -265,41 +300,13 @@ namespace diff{ } } private: - static bool - isAttribute (VAL const& v) - { - return false; ////TODO - } - - static bool - isTypeID (VAL const& v) - { - return false; ////TODO - } - - static string - extractTypeID (VAL const& v) - { - return "todo"; ////TODO - } - - static VAL - buildTypeAttribute (string const& typeID) - { - return VAL(); ///TODO - } - - static string - extractKey (VAL const& v) - { - return "todo"; ////TODO - } - - static VAL - extractVal (VAL const& v) - { - return VAL(); ///TODO - } + /* === abstract attribute handling : needs specialisation === */ + static bool isAttribute (VAL const& v); + static bool isTypeID (VAL const& v); + static string extractTypeID (VAL const& v); + static VAL buildTypeAttribute (string const& typeID); + static string extractKey (VAL const& v); + static VAL extractVal (VAL const& v); friend bool @@ -384,5 +391,51 @@ namespace diff{ + /* === Specialisations to define the handling of attributes === */ + + template<> + inline bool + Record::isAttribute (string const& v) + { + return false; ////TODO + } + + template<> + inline bool + Record::isTypeID (string const& v) + { + return false; ////TODO + } + + template<> + inline string + Record::extractTypeID (string const& v) + { + return "todo"; ////TODO + } + + template<> + inline string + Record::buildTypeAttribute (string const& typeID) + { + return string(); ///TODO + } + + template<> + inline string + Record::extractKey (string const& v) + { + return "todo"; ////TODO + } + + template<> + inline string + Record::extractVal (string const& v) + { + return string(); ///TODO + } + + + }} // namespace lib::diff #endif /*LIB_DIFF_GEN_NODE_H*/