Lumiera  0.pre.03
»edit your freedom«
gen-node.hpp File Reference

Go to the source code of this file.

Description

Generic building block for tree shaped (meta)data structures.

A representation built from GenNode elements is intended to support (limited) introspection of data structures and exchange of mutations in the form of diff messages.

Despite of the name, GenNode is not meant to be an universal data representation; rather it is limited to embody a fixed hard wired set of data types, able to stand-in for attributes and sub scope contents of the lumiera high-level data model.

Anatomy of a GenNode

GenNode is a polymorphic value with well defined identity and type. Each element is conceived to be »unique within context« – as defined by the immediately visible scope within a tree like structure. Beyond this identity metadata, each GenNode carries a DataCap, which is an inline container and attachment point for payload data. Simple attribute values can be carried alongside, while more complex types or entities bound to a reference and registration system (e.g. Placement) will be referred by a suitable reference representation (PlacementID). The DataCap is what creates the polymorphic nature, where the common interface is mostly limited to managemental tasks (copying of values, external representation).

To represent object-like structures and for building trees, a special kind of data type is placed into the DataCap. This type, Record<GenNode> is recursive and has the ability to hold both a a set of attributes addressable by-name and an (ordered) collection of elements treated as children within the scope of the given record.

The GenNode ID

Each GenNode holds an ID tag, allowing to establish identical and distinct elements within a scope. This ID is based on lib::idi::BareEntryID, thereby providing a human readable symbolic part, and a hash value. By default, these GenNode IDs are fabricated such as to hold a non-reproducible, random hash value – however, there are construction flavours allowing to pass in an pre-existing distinct Entry-ID.

Requirements

GenNode elements are to be used in the diff detection and implementation. This implies some requirements for the (opaque) elements used in diff:

  • they need to support the notion of equality
  • we need to derive a key type for usage in index tables
    • this implies the necessity to support std::less comparisons for tree-maps
    • and the necessity to support hash code generation for unordered (hash)maps
  • moreover, the elements need to be values, able to be copied and handled at will
  • it will be beneficial for these values to support move semantics explicitly
  • in addition, the tree diffing suggests a mechanism to re-gain the fully typed context, either based on some kind of embedded type tag, or alternatively by visitation and matching
  • finally, the handling of changes prompts us to support installation of a specifically typed change handling closure.

monadic nature?

As suggested by the usage for representation of tree shaped data, we acknowledge that GenNode could be a Monad. We support the basic operation construction, and the operation flatMap would be trivial to add. To fit in with this generic processing pattern, the one element flavours of GenNode are considered the special case, while the collective flavours form the base case – every GenNode can be iterated. The construction requirement suggests that GenNode may be created readily, just by wrapping any given and suitable element, thereby picking up the element's type.

But the purpose and goal of the monadic approach is not clear yet (5/2015). To begin with, for the task of diff detection and application, it is sufficient to get the children as traversable collection and to offer a depth-first expansion.

See also
GenNode_test
diff-list-generation-test.cpp
DiffDetector

Definition in file gen-node.hpp.

#include "lib/error.hpp"
#include "lib/idi/entry-id.hpp"
#include "lib/time/timevalue.hpp"
#include "lib/diff/record.hpp"
#include "lib/variant.hpp"
#include "lib/util.hpp"
#include <optional>
#include <utility>
#include <string>
#include <deque>

Classes

struct  can_wrap_in_GenNode< ELM >
 metafunction to detect types able to be wrapped into a GenNode. More...
 
struct  CanBuildFrom< diff::MakeRec, Node< Rec, TYPES > >
 specialisation allowing to build a GenNode with a nested record from a Record::Mutator (aka MakeRec) More...
 
class  DataCap
 
struct  GenNode
 generic data element node within a tree More...
 
class  GenNode::ID
 
struct  GenNode::IDComparator
 allow for storage in ordered containers, ordering based on the human-readable ID within the GenNode. More...
 
struct  DataCap::Locator
 
struct  RecordSetup< GenNode >
 Define actual data storage and access types used. More...
 
struct  Ref
 Constructor for a specially crafted 'ref GenNode'. More...
 
class  GenNode::ScopeExplorer
 Building block for monad-like depth-first expansion of a GenNode. More...
 
struct  GenNode::ScopeExplorerIterator
 

Typedefs

using DataValues = meta::Types< int,int64_t,short,char,bool,double,string,time::Time,time::Offset,time::Duration,time::TimeSpan,hash::LuidH,RecRef,Rec >
 
using MakeRec = Rec::Mutator
 
using Rec = Record< GenNode >
 
using RecRef = RecordRef< GenNode >
 

Namespaces

 lib
 Implementation namespace for support and library code.