Lumiera  0.pre.03
»edit your freedom«
tree-mutator-collection-binding.hpp File Reference

Go to the source code of this file.

Description

Special binding implementation for lib::diff::TreeMutator, allowing to map tree diff operations onto a STL collection of native implementation objects.

TreeMutator is a customisable intermediary, which enables otherwise opaque implementation data structures to receive and respond to generic structural change messages ("tree diff").

Each concrete TreeMutator instance will be configured differently, and this adaptation is done by implementing binding templates, in the way of building blocks, attached and customised through lambdas. It is possible to layer several bindings on top of a single TreeMutator – and indeed this header defines a building block for one such layer, specifically for binding to a representation of "child objects" managed within a typical STL container.

As a special case, binding to a STL map is supported, while this usage is rather discouraged, since it contradicts the diff semantics due to intrinsic ordering.

Internal structure

The task to set up a binding to a generic STL collection has to face some technical intricacies, leading to a rather involved implementation, which can be hard to understand and maintain. We attempt to address this challenge through a decomposition into several sub-tasks, organised into four levels of abstraction

  • at the bottom we use an adaptation layer in the form of a traits template, with two concrete specialisations of the ContainerTraits for vector-like and map-like collections
  • on top of this the CollectionBinding is established to establish a kind of generic access protocol for consuming a collection guided by diff instructions
  • the third level then holds the actual TreeMutator implementation, embodied into the ChildCollectionMutator template, which in fact translates and delegates any actual access to the underlying collection to its embedded CollectionBinding instance...
  • which in turn is assembled on the top level, the DSL level, from building blocks provided by the client of this collection binding. The entrance point to this DSL layer is the _DefaultBinding, which is established by wrapping the actual collection into the concrete CollectionBinding at the point where the builder is created. The further DSL verbs on the CollectionBindingBuilder just server to provide or overlay some lambdas to fill in the flexible parts of the binding.

And these flexible parts are mostly concerned with the actual contents of the STL collection to be bound. Because, at this point, we can not assume much without loosing genericity. Thus, the user of this binding has to fill in the missing link

  • to decide if a given diff specification is addressed at this collection binding (»Selector«)
  • when to consider a concrete content element as a match for the diff specification (»Matcher«)
  • the way actually to construct a new content element in accordance to the given diff spec (»Constructor«)
  • the actual implementation of value assignment (optional)
  • and the recursive entrance into mutation of a specific element within that collection (optional)
Note
the header tree-mutator-collection-binding.hpp was split off for sake of readability and is included automatically from bottom of tree-mutator.hpp
See also
tree-mutator-test.cpp
TreeMutator::build()

Definition in file tree-mutator-collection-binding.hpp.

#include "lib/error.hpp"
#include "lib/nocopy.hpp"
#include "lib/meta/trait.hpp"
#include "lib/diff/gen-node.hpp"
#include "lib/diff/tree-mutator.hpp"
#include "lib/iter-adapter-stl.hpp"
#include <utility>
#include <vector>
#include <map>

Classes

struct  _DefaultBinding< ELM, SEL >
 starting point for configuration of a binding to STL container. More...
 
struct  _DefaultBinding< ELM, enable_if< can_wrap_in_GenNode< ELM > > >
 
struct  _DefaultBinding< GenNode >
 standard configuration to deal with GenNode collections. More...
 
struct  _EmptyBinding< ELM >
 
class  ChildCollectionMutator< PAR, BIN >
 Attach to collection: Building block for a concrete TreeMutator. More...
 
struct  CollectionBinding< COLL, MAT, CTR, SEL, ASS, MUT >
 Attach to collection: Concrete binding setup. More...
 
struct  CollectionBindingBuilder< COLL, MAT, CTR, SEL, ASS, MUT >
 Nested DSL to define the specifics of a collection binding. More...
 
struct  ContainerTraits< C, SEL >
 Helper for uniform treatment of various STL containers. More...
 
struct  ContainerTraits< M, IF_is_map< M > >
 
struct  ContainerTraits< V, IF_is_vector< V > >
 

Typedefs

template<class C >
using _AsMap = std::map< typename C::key_type, typename C::mapped_type >
 
template<class C >
using _AsVector = std::vector< typename C::value_type >
 
template<class C >
using IF_is_map = lib::meta::enable_if< std::is_base_of< _AsMap< C >, C > >
 
template<class C >
using IF_is_vector = lib::meta::enable_if< std::is_base_of< _AsVector< C >, C > >
 

Functions

template<class COLL >
auto collection (COLL &coll)
 Entry point to a nested DSL for setup and configuration of a collection binding. More...
 
template<class COLL , class MAT , class CTR , class SEL , class ASS , class MUT >
auto createCollectionBindingBuilder (COLL &coll, MAT m, CTR c, SEL s, ASS a, MUT u)
 builder function to synthesise builder type from given functors
 

Namespaces

 lib
 Implementation namespace for support and library code.
 

Class Documentation

◆ lib::diff::anonymous_namespace{tree-mutator-collection-binding.hpp}::ContainerTraits

struct lib::diff::anonymous_namespace{tree-mutator-collection-binding.hpp}::ContainerTraits
+ Collaboration diagram for ContainerTraits< C, SEL >: