81#ifndef LIB_DIFF_RECORD_H
82#define LIB_DIFF_RECORD_H
103 template<
class BA,
class DEFAULT>
104 class PlantingHandle;
118 template<
typename VAL>
140 template<
typename VAL>
160 template<
typename A,
typename C>
167 template<
typename A,
typename C>
169 , std::initializer_list<C>
const&& chi)
175 template<
typename SEQ>
180 auto p = std::begin(con);
181 auto e = std::end(con);
191 Record (std::initializer_list<VAL>
const&& ili)
203 operator std::string()
const;
261 ,error::LUMIERA_ERROR_INDEX_BOUNDS);
310 using scopeIter = iter_stl::_SeqT<const Storage>::Range;
349 if (pos != END and (pos != src->
children_.end()))
372 return std::find_if (
attribs_.begin()
376 return key == extractKey(elm);
392 return not (r1 == r2);
396 template<
typename VAL>
399 template<
typename VAL>
404 template<
typename VAL>
419 : record_(startingPoint)
424 : record_(
std::move (startingPoint))
428 operator Rec & () {
return record_; }
429 operator Rec const&()
const {
return record_; }
435 swap (existingInstance, record_);
441 return record_.empty();
450 record_.type_ = newTypeID;
462 set (
string const& key, X&& content)
465 return set (std::move (attribute));
473 throw error::Invalid (
"Attempt to set an attribute with empty key");
476 auto found = std::find_if (as.begin(),as.end()
479 return key == extractKey(elm);
481 if (as.end() == found)
482 as.push_back (std::forward<VAL> (attribute));
484 (*found) = (std::forward<VAL> (attribute));
492 record_.attribs_.push_back (newAttrib);
499 record_.children_.push_back (newChild);
506 record_.children_.insert (record_.children_.begin(), newChild);
533 return std::tie (record_.attribs_, record_.children_);
547 throw error::State(
"Record is empty, unable to access (last) element.");
549 if (record_.children_.empty())
550 return record_.attribs_.back();
552 return record_.children_.back();
566 VAL genNode(
string const& symbolicID);
568 template<
typename X,
typename...ARGS>
571 set (key, std::forward<X>(initialiser));
572 return attrib (std::forward<ARGS>(args)...);
577 template<
typename X,
typename...ARGS>
580 appendChild (VAL(initialiser));
581 return scope (std::forward<ARGS>(args)...);
597 template<
typename VAL>
616 template<
typename VAL>
650 std::swap (
record_, o.record_);
656 operator bool()
const
673 throw error::Logic(
"attempt to dereference an unbound record reference"
674 ,error::LUMIERA_ERROR_BOTTOM_VALUE);
684 operator string()
const
686 return "Ref->" + (
empty()? util::BOTTOM_INDICATOR
729 size_t pos = v.find(
'=');
730 if (string::npos == pos)
740 size_t pos = v.find(
'=');
741 if (string::npos == pos)
744 return util::trim (v.substr (pos+1, v.length() - pos));
751 return string::npos != v.find(
'=');
758 return isAttribute(v)
759 and
"type" == extractKey(v);
766 return extractVal(v);
773 return extractKey(attrib) +
" = " + extractVal(attrib);
781 return string(key +
" = " + extractVal(payload));
791 template<
typename VAL>
798 + (TYPE_NIL==type_?
"" : type_)
799 + (isnil(this->attribs())?
"" :
"| "+join (
transformIterator (this->attribs(), renderAttribute))+
" ")
800 + (isnil(this->scope())?
"" :
"|{"+join (this->scope())+
"}")
Adapter for building an implementation of the »Lumiera Forward Iterator« concept.
A handle to allow for safe »remote implantation« of an unknown subclass into a given opaque InPlaceBu...
Token or Atom with distinct identity.
wrapped record reference.
friend bool operator!=(RecordRef const &r1, RecordRef const &r2)
RecordRef(RecordRef &&)=default
RecordRef() noexcept
by default create an invalid ("bottom") reference
RecordRef(Target &o) noexcept
create a reference bound to the given target; can not be rebound
RecordRef & operator=(RecordRef const &)=delete
references can not be reassigned
RecordRef(RecordRef const &)=default
RecordRef(Target &&)=delete
prevent moving into black hole
Target * get() const noexcept
friend bool operator==(RecordRef const &r1, RecordRef const &r2)
Mutator && set(string const &key, X &&content)
Mutator && set(VAL &&attribute)
Mutator && scope(X const &initialiser, ARGS &&...args)
Mutator && prependChild(VAL const &newChild)
void swap(Rec &existingInstance) noexcept
Mutator(Rec const &startingPoint)
VAL const & accessLast()
get the tail element.
Mutator && appendAttrib(VAL const &newAttrib)
void buildMutator(BufferHandle)
attachment point to receive and apply tree-diff changes.
Mutator && appendChild(VAL const &newChild)
Mutator && attrib(string const &key, X &&initialiser, ARGS &&...args)
Mutator(Rec &&startingPoint)
Mutator && type(string const &typeID)
void setType(string const &newTypeID)
object-like record of data.
static const string TYPE_NIL
iterator begin() const
default iteration exposes all data within this "object", starting with the attributes
static const Symbol TYPE_NIL_SYM
operator std::string() const
for diagnostic purpose
ElmIter findKey(string key) const
Record(std::initializer_list< VAL > const &&ili)
static bool isAttribute(VAL const &v)
Access get(string key) const
static string extractTypeID(VAL const &v)
scopeIter attribs() const
bool hasAttribute(string key) const
size_t attribSize() const
TransformIter< scopeIter, Access > valIter
static VAL buildAttribute(string const &key, X &&payload)
Record(Symbol typeID, A &&att, C &&chi)
IterAdapter< ElmIter, const Record * > iterator
RecordSetup< VAL >::ElmIter ElmIter
friend void iterNext(const Record *, ElmIter &pos)
Implementation of Iteration-logic: pull next element.
RecordSetup< VAL >::Access Access
friend bool checkPoint(const Record *src, ElmIter &pos)
Implementation of Iteration-logic: detect iteration end.
bool contains(VAL const &val) const
Record(Record &&)=default
RecordSetup< VAL >::Storage Storage
static string renderAttribute(VAL const &a)
Record(Record const &)=default
static Access extractVal(VAL const &v)
Access child(size_t idx) const
friend bool operator==(Record const &r1, Record const &r2)
Record & operator=(Record &&)=default
Record(Symbol typeID, std::initializer_list< A > const &&att, std::initializer_list< C > const &&chi)
iter_stl::_SeqT< const Storage >::Range scopeIter
static bool isTypeID(VAL const &v)
Record(Mutator const &mut)
copy-initialise (or convert) from the given Mutator instance.
friend bool operator!=(Record const &r1, Record const &r2)
static string extractKey(VAL const &v)
TransformIter< scopeIter, string > keyIter
type erased baseclass for building a combined hash and symbolic ID.
Types marked with this mix-in may be moved but not copied.
Lumiera error handling (C++ interface).
Preconfigured adapters for some STL container standard usage situations.
Helper template(s) for creating Lumiera Forward Iterators.
Storage::const_iterator ElmIter
std::vector< string > Storage
Record< VAL >::Mutator & mutateInPlace(Record< VAL > &record_to_mutate)
open an existing record for modification in-place.
string Access
data access by value copy
_SeqT< CON >::Range eachElm(CON &coll)
Implementation namespace for support and library code.
auto transformIterator(IT const &src, FUN processingFunc)
Build a TransformIter: convenience free function shortcut, picking up the involved types automaticall...
LumieraError< LERR_(STATE)> State
LumieraError< LERR_(LOGIC)> Logic
LumieraError< LERR_(INVALID)> Invalid
bool contains(MAP &map, typename MAP::key_type const &key)
shortcut for containment test on a map
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
string join(COLL &&coll, string const &delim=", ")
enumerate a collection's contents, separated by delimiter.
string trim(string const &org)
remove leading and trailing whitespace
bool isnil(lib::time::Duration const &dur)
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...