Lumiera  0.pre.03
»edit your freedom«
tree-mutator-listener-binding.hpp
Go to the documentation of this file.
1 /*
2  TREE-MUTATOR-LISTENER-BINDING.hpp - decorator for TreeMutator to attach change listeners
3 
4  Copyright (C) Lumiera.org
5  2019, 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 
47 #ifndef LIB_DIFF_TREE_MUTATOR_LISTENER_BINDING_H
48 #define LIB_DIFF_TREE_MUTATOR_LISTENER_BINDING_H
49 
50 
51 #include "lib/error.hpp"
52 #include "lib/diff/gen-node.hpp"
54 
55 namespace lib {
56 namespace diff{
57 
58  namespace { // Mutator-Builder decorator components...
59 
60 
83  template<class PAR, typename LIS, bool assign =false>
85  : public PAR
86  {
87  LIS changeListener_;
88  bool triggered_ = false;
89 
90  void
91  trigger(bool relevant =true)
92  {
93  if (relevant)
94  triggered_ = true;
95  }
96 
97  public:
98  Detector4StructuralChanges (LIS functor, PAR&& chain)
99  : PAR(std::forward<PAR>(chain))
100  , changeListener_{functor}
101  { }
102 
103  // move construction allowed and expected to happen
105 
110  {
111  if (triggered_)
112  changeListener_();
113  }
114 
115  /* ==== TreeMutator API ==== */
116 
117  using Elm = GenNode const&;
118 
119  bool injectNew (Elm elm) override { trigger(); return PAR::injectNew (elm); }
120  bool findSrc (Elm elm) override { trigger(); return PAR::findSrc (elm); }
121  void skipSrc (Elm elm) override { trigger(); PAR::skipSrc (elm); }
122  bool assignElm (Elm elm) override { trigger(assign); return PAR::assignElm (elm); }
123  };
124 
125 
126 
129  template<class PAR>
130  template<typename LIS>
131  inline auto
132  Builder<PAR>::onSeqChange (LIS changeListener)
133  {
134  ASSERT_VALID_SIGNATURE (LIS, void(void))
135 
136  return chainedBuilder<Detector4StructuralChanges<PAR,LIS>> (changeListener);
137  }
138 
142  template<class PAR>
143  template<typename LIS>
144  inline auto
145  Builder<PAR>::onLocalChange (LIS changeListener)
146  {
147  ASSERT_VALID_SIGNATURE (LIS, void(void))
148  // vvvv---note: including assignments
149  return chainedBuilder<Detector4StructuralChanges<PAR,LIS, true>> (changeListener);
150  }
151 
152  }//(END)Mutator-Builder decorator components...
153 
154 }} // namespace lib::diff
155 #endif /*LIB_DIFF_TREE_MUTATOR_LISTENER_BINDING_H*/
#define ASSERT_VALID_SIGNATURE(_FUN_, _SIG_)
Macro for a compile-time check to verify the given generic functors or lambdas expose some expected s...
Definition: function.hpp:256
Decorator for TreeMutator bindings, to fire a listener function when the applied diff describes a rel...
Implementation namespace for support and library code.
~Detector4StructuralChanges()
once the diff for this level is completely applied, the TreeMutator will be discarded, and we can fire our change listener at that point.
Generic building block for tree shaped (meta)data structures.
Lumiera error handling (C++ interface).
Customisable intermediary to abstract generic tree mutation operations.
generic data element node within a tree
Definition: gen-node.hpp:231