Lumiera  0.pre.03
»edit your freedom«
record.hpp File Reference

Go to the source code of this file.

Description

Special collection to represent object-like data.

To be used in a context where introspection, open, extensible definitions and loose coupling of data representation matters. Typically, structures defined in terms of Record elements are linked to the actual core representation of the same entities relying on diff messages. Record is one of the supported flavours within the DataCap of GenNode elements, which in turn serve as the standard handle to refer to other elements, entities, attributes or references within the "backbone" of the Lumiera GUI.

A Record holds

  • (optionally) a type-ID string
  • a collection of named attributes (key-value data)
  • a list of enclosed children (contents within the "scope" of this Record)

design decisions

The Record type is shaped from its intended use: It serves to symbolically represent objects in the "external tree description". Here, "objects" means objects for real, i.e. with types, fields and an enclosed scope. Yet the term external means that we do not work on these objects right here, we only represent them, for later referral, symbolically.

rationale
The underlying theme and motivation of this design is negative: we do not want to build yet another object system. The object model of C++ is deemed adequate.

This leads to the following decisions

  • the Record entity is itself an object and thus has an inner side, privately. The entrails of the Record can be reworked and tuned for performance
  • yet the Record has an external appearance, which makes it look flat and passive. This is to say, a Record has no visible functionality.
  • the parts or realms within this symbolic representation are distinguished by convention solely
    • metadata is very limited and boils down to a type attribute known by name
    • children (scope contents) can be recognised by not bearing a name

Record entities are meant to be immutable. The proper way to alter a Record is to apply a diff. Yet for the implementation of this diff handling, a Record::Mutator is provided, to allow controlled partial re-building of a given data element. Moreover, especially for Record<GenNode>, this mutator can be used for a DSL-style compact notation of a complete "object tree" – a feature intended for writing unit tests.

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 for somehow embedding 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 also
GenericRecord_test

Definition in file record.hpp.

#include "lib/error.hpp"
#include "lib/nocopy.hpp"
#include "lib/iter-adapter.hpp"
#include "lib/iter-adapter-stl.hpp"
#include "lib/itertools.hpp"
#include "lib/format-util.hpp"
#include "lib/util.hpp"
#include <algorithm>
#include <utility>
#include <vector>
#include <string>

Classes

class  Record< VAL >::Mutator
 
class  PlantingHandle< BA, DEFAULT >
 A handle to allow for safe »remote implantation« of an unknown subclass into a given opaque InPlaceBuffer, without having to disclose the concrete buffer type or size. More...
 
class  Record< VAL >
 object-like record of data. More...
 
class  RecordRef< VAL >
 wrapped record reference. More...
 
struct  RecordSetup< VAL >
 
struct  RecordSetup< string >
 Type configuration (extension point). More...
 

Functions

template<typename VAL >
Record< VAL >::Mutator & mutateInPlace (Record< VAL > &record_to_mutate)
 open an existing record for modification in-place. More...
 

Namespaces

 lib
 Implementation namespace for support and library code.
 
 lib::idi
 Identification Schemes.
 

Function Documentation

◆ mutateInPlace()

Record<VAL>::Mutator& lib::diff::mutateInPlace ( Record< VAL > &  record_to_mutate)
inline

open an existing record for modification in-place.

Warning
this function undermines the immutability of Record
Remarks
exploits the specific and known memory layout of Rec::Mutator. This trickery is necessary to avoid copying a large and possibly nested object tree; this happens when applying a diff, when recursively descending into nested child objects.
Todo:
do we have a design mismatch here?? /////////////////////////////////////////TICKET #970
See also
tree-diff-application.hpp

Definition at line 594 of file record.hpp.

References lib::diff::mutateInPlace().

Referenced by lib::diff::mutateInPlace().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: