72#ifndef LIB_DIFF_TREE_MUTATOR_COLLECTION_BINDING_H
73#define LIB_DIFF_TREE_MUTATOR_COLLECTION_BINDING_H
105 using _AsMap = std::map<typename C::key_type, typename C::mapped_type>;
114 template<
class C,
typename SEL =
void>
117 static_assert (not
sizeof(C),
"unable to determine any supported container type for C");
124 using Elm = Vec::value_type;
125 using Itr = Vec::iterator;
130 return Itr{&vec.back()};
136 vec.emplace_back (forward<Elm> (elm));
144 using Key = Map::key_type;
145 using Val = Map::mapped_type;
146 using Elm = std::pair<const Key, Val>;
156 auto& recentPos = ++map.rend();
157 return map.find (recentPos->first);
163 map.emplace (forward<Elm> (elm));
187 template<
class COLL,
class MAT,
class CTR,
class SEL,
class ASS,
class MUT>
192 using Elm = Coll::value_type;
195 using iterator = lib::iter_stl::_SeqT<Coll>::Range;
235 contentBuffer.clear();
237 return eachElm (contentBuffer);
243 Trait::append (
collection, forward<Elm>(elm));
249 while (pos and not matches(targetSpec, *pos))
260 and matches (targetSpec, recentElm()))
261 return recentElmIter();
263 return search (targetSpec, eachElm(
collection));
305 template<
class PAR,
class BIN>
317 : PAR(
std::forward<PAR>(chain))
318 , binding_(forward<BIN>(wiringClosures))
330 pos_ = binding_.initMutation();
342 if (binding_.isApplicable(n))
344 binding_.inject (std::move (binding_.construct(n)));
348 return PAR::injectNew (n);
354 return bool(pos_) or PAR::hasSrc();
362 if (binding_.isApplicable(spec))
363 return pos_ and binding_.matches (spec, *pos_);
365 return PAR::matchSrc (spec);
375 if (binding_.isApplicable(n))
388 if (binding_.isApplicable(n))
390 bool isSrcMatch = pos_ and binding_.matches (n, *pos_);
393 binding_.inject (move(*pos_));
399 return PAR::acceptSrc (n);
406 if (binding_.isApplicable(refSpec))
408 Iter found = binding_.search (refSpec, pos_);
411 binding_.inject (move(*found));
416 return PAR::findSrc (refSpec);
426 and binding_.isApplicable (Ref::ATTRIBS)))
428 for ( ; pos_; ++pos_)
429 binding_.inject (move(*pos_));
430 return PAR::accept_until (spec);
433 if (binding_.isApplicable(spec))
435 bool foundTarget =
false;
436 while (pos_ and not binding_.matches (spec, *pos_))
438 binding_.inject (move(*pos_));
441 if (pos_ and binding_.matches (spec, *pos_))
443 binding_.inject (move(*pos_));
450 return PAR::accept_until (spec);
458 if (binding_.isApplicable(spec))
460 Iter target_found = binding_.locate (spec);
461 return target_found and binding_.assign (*target_found, spec);
464 return PAR::assignElm (spec);
482 if (binding_.isApplicable(spec))
484 Iter target_found = binding_.locate (spec);
485 return target_found and binding_.openSub (*target_found, spec.
idi, targetBuff);
488 return PAR::mutateChild (spec, targetBuff);
496 return PAR::completeScope()
497 and isnil(this->pos_);
507 template<
class COLL,
class MAT,
class CTR,
class SEL,
class ASS,
class MUT>
574 , childMutationBuilder
581 template<
class COLL,
class MAT,
class CTR,
class SEL,
class ASS,
class MUT>
587 return CollectionBindingBuilder<Coll, MAT,CTR,SEL,ASS,MUT> {coll, m,c,s,a,u};
598 throw error::Logic (
"unable to build a sensible default matching predicate");
604 throw error::Logic (
"unable to build a sensible default for creating new elements");
610 return spec != Ref::ATTRIBS;
633 ,__ERROR_missing_matcher
634 ,__ERROR_missing_constructor
637 ,disable_childMutation
660 template<
class ELM,
typename SEL =
void>
673 .matchElement([](
GenNode const& spec, ELM
const& elm)
677 .constructFrom([](
GenNode const& spec) -> ELM
710 if (target.
idi == subID
713 mutateInPlace (target.data.get<Rec>())
741 using Elm = COLL::value_type;
754 return chainedBuilder<ChildCollectionMutator<PAR,BIN>> (forward<BIN>(collectionBindingSetup));
A handle to allow for safe »remote implantation« of an unknown subclass into a given opaque InPlaceBu...
bool isNested() const
determine if payload constitutes a nested scope ("object")
Attach to collection: Building block for a concrete TreeMutator.
virtual bool acceptSrc(GenNode const &n) override
accept existing element, when matching the given spec
virtual bool accept_until(GenNode const &spec) override
repeatedly accept, until after the designated location
virtual bool matchSrc(GenNode const &spec) override
ensure the next recorded source element matches on a formal level with given spec
virtual bool findSrc(GenNode const &refSpec) override
locate designated element and accept it at current position
virtual bool mutateChild(GenNode const &spec, TreeMutator::Handle targetBuff) override
locate the designated target element and build a suitable sub-mutator for this element into the provi...
virtual bool hasSrc() override
virtual void init() override
virtual bool assignElm(GenNode const &spec) override
locate element already accepted into the target sequence and assign the designated payload value to i...
virtual bool completeScope() override
verify all our pending (old) source elements where mentioned.
virtual void skipSrc(GenNode const &n) override
skip next pending src element, causing this element to be discarded
virtual bool injectNew(GenNode const &n) override
fabricate a new element, based on the given specification (GenNode), and insert it at current positio...
ChildCollectionMutator(BIN &&wiringClosures, PAR &&chain)
Types marked with this mix-in may be moved but not copied.
Lumiera error handling (C++ interface).
#define ASSERT_VALID_SIGNATURE(_FUN_, _SIG_)
Macro for a compile-time check to verify the given generic functors or lambdas expose some expected s...
Generic building block for tree shaped (meta)data structures.
Preconfigured adapters for some STL container standard usage situations.
auto collection(COLL &coll)
Entry point to a nested DSL for setup and configuration of a collection binding.
lib::meta::enable_if< std::is_base_of< _AsVector< C >, C > > IF_is_vector
std::map< typename C::key_type, typename C::mapped_type > _AsMap
lib::meta::enable_if< std::is_base_of< _AsMap< C >, C > > IF_is_map
auto createCollectionBindingBuilder(COLL &coll, MAT m, CTR c, SEL s, ASS a, MUT u)
builder function to synthesise builder type from given functors
std::vector< typename C::value_type > _AsVector
Helper for uniform treatment of various STL containers.
_SeqT< CON >::Range eachElm(CON &coll)
Implementation namespace for support and library code.
LumieraError< LERR_(LOGIC)> Logic
Mix-Ins to allow or prohibit various degrees of copying and cloning.
generic data element node within a tree
bool matches(GenNode const &o) const
Nested DSL to define the specifics of a collection binding.
CollectionBindingBuilder< COLL, FUN, CTR, SEL, ASS, MUT > matchElement(FUN matcher)
CollectionBindingBuilder< COLL, MAT, CTR, FUN, ASS, MUT > isApplicableIf(FUN selector)
CollectionBindingBuilder< COLL, MAT, CTR, SEL, ASS, FUN > buildChildMutator(FUN childMutationBuilder)
CollectionBindingBuilder< COLL, MAT, FUN, SEL, ASS, MUT > constructFrom(FUN constructor)
CollectionBindingBuilder< COLL, MAT, CTR, SEL, FUN, MUT > assignElement(FUN setter)
Attach to collection: Concrete binding setup.
lib::iter_stl::_SeqT< Coll >::Range iterator
Strip< COLL >::TypeReferred Coll
lib::iter_stl::_SeqT< const Coll >::Range const_iterator
iterator search(GenNode const &targetSpec, iterator pos)
iterator locate(GenNode const &targetSpec)
locate element for assignment or mutation, with special shortcut to the recently inserted element
ContainerTraits< Coll > Trait
std::pair< const Key, Val > Elm
static void append(Map &map, Elm &&elm)
static auto recentElmRawIter(Map &map)
heuristic for std::map: lookup via reverse iterator.
static Itr recentElmRawIter(Vec &vec)
static void append(Vec &vec, Elm &&elm)
static auto attachTo(COLL &coll)
static auto attachTo(COLL &coll)
starting point for configuration of a binding to STL container.
static ELM __ERROR_missing_constructor(GenNode const &)
static bool disable_childMutation(ELM &, GenNode::ID const &, TreeMutator::Handle)
static bool ignore_selector(GenNode const &spec)
static bool disable_assignment(ELM &, GenNode const &)
static auto attachTo(COLL &coll)
static bool __ERROR_missing_matcher(GenNode const &, ELM const &)
Builder-DSL to create and configure a concrete TreeMutator.
metafunction to detect types able to be wrapped into a GenNode.
Helpers for type detection, type rewriting and metaprogramming.
Customisable intermediary to abstract generic tree mutation operations.