Lumiera  0.pre.03
»edit your freedom«
tree-mutator-gen-node-binding.hpp
Go to the documentation of this file.
1 /*
2  TREE-MUTATOR-GEN-NODE-BINDING.hpp - diff::TreeMutator implementation building block
3 
4  Copyright (C) Lumiera.org
5  2016, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
59 #ifndef LIB_DIFF_TREE_MUTATOR_GEN_NODE_BINDING_H
60 #define LIB_DIFF_TREE_MUTATOR_GEN_NODE_BINDING_H
61 
62 
63 #include "lib/diff/gen-node.hpp"
66 
67 #include <tuple>
68 
69 
70 namespace lib {
71 namespace diff{
72 
73  namespace { // Mutator-Builder decorator components...
74 
90  template<class PAR>
92  : public PAR
93  {
94  Rec::Mutator& targetObj_;
95 
96  public:
97  ObjectTypeHandler(Rec::Mutator& targetObj, PAR&& chain)
98  : PAR(std::forward<PAR>(chain))
99  , targetObj_(targetObj)
100  { }
101 
102  virtual bool
103  injectNew (GenNode const& spec) override
104  {
105  if (spec.isNamed() and spec.isTypeID())
106  {
107  targetObj_.setType(spec.data.get<string>());
108  return true;
109  }
110  else
111  return PAR::injectNew (spec);
112  }
113 
114  virtual bool
115  assignElm (GenNode const& spec) override
116  {
117  if (spec.isNamed() and spec.isTypeID())
118  {
119  targetObj_.setType(spec.data.get<string>());
120  return true;
121  }
122  else
123  return PAR::assignElm (spec);
124  }
125  };
126 
127  template<class MUT>
128  inline Builder<ObjectTypeHandler<MUT>>
129  filterObjectTypeAttribute (Rec::Mutator& targetTree, Builder<MUT>&& chain)
130  {
131  using ObTyHa = ObjectTypeHandler<MUT>;
132  return Builder<ObTyHa>{ObTyHa {targetTree, move(chain)}};
133  }
134 
135 
136 
137  using Storage = RecordSetup<GenNode>::Storage;
138 
139  inline Storage&
140  accessAttribs (Rec::Mutator& targetTree)
141  {
142  return std::get<0> (targetTree.exposeToDiff());
143  }
144 
145  inline Storage&
146  accessChildren (Rec::Mutator& targetTree)
147  {
148  return std::get<1> (targetTree.exposeToDiff());
149  }
150 
151 
153  template<class PAR>
154  inline auto
155  Builder<PAR>::attach (Rec::Mutator& targetTree)
156  {
157  auto rawBinding = this->attach (collection (accessChildren(targetTree)))
158  .attach (collection (accessAttribs(targetTree))
159  .isApplicableIf ([](GenNode const& spec) -> bool
160  { // »Selector« : treat key-value elements here
161  return spec.isNamed();
162  }));
163 
164  return filterObjectTypeAttribute(targetTree, move(rawBinding));
165  }
166 
167  }//(END)Mutator-Builder decorator components...
168 
169 
170 }} // namespace lib::diff
171 #endif /*LIB_DIFF_TREE_MUTATOR_GEN_NODE_BINDING_H*/
Implementation namespace for support and library code.
Generic building block for tree shaped (meta)data structures.
Customisable intermediary to abstract generic tree mutation operations.
Special binding implementation for lib::diff::TreeMutator, allowing to map tree diff operations onto ...
auto collection(COLL &coll)
Entry point to a nested DSL for setup and configuration of a collection binding.
generic data element node within a tree
Definition: gen-node.hpp:231