23 #ifndef COM_DAFER45_TBTK_INDEXED_DATA_TREE 24 #define COM_DAFER45_TBTK_INDEXED_DATA_TREE 26 #include "TBTK/ElementNotFoundException.h" 38 #ifndef TBTK_DISABLE_NLOHMANN_JSON 39 # include "TBTK/json.hpp" 44 template<
typename Data>
67 void add(
const Data &data,
const Index &index);
77 bool get(Data &data,
const Index &index)
const;
87 Data&
get(
const Index &index);
97 const Data&
get(
const Index &index)
const;
119 template<
bool isConstIterator>
124 typedef typename std::conditional<
128 >::type DataReferenceType;
137 bool operator==(
const _Iterator &rhs)
const;
143 const Index& getCurrentIndex()
const;
147 typedef typename std::conditional<
151 >::type IndexedDataTreePointerType;
154 IndexedDataTreePointerType indexedDataTree;
161 _Iterator(IndexedDataTreePointerType indexedDataTree,
bool end =
false);
175 ) : _Iterator<false>(indexedDataTree,
end){};
188 ) : _Iterator<true>(indexedDataTree,
end){};
228 std::map<Subindex, IndexedDataTree> children;
244 void add(
const Data &data,
const Index& index,
unsigned int subindex);
248 bool get(Data &data,
const Index& index,
unsigned int subindex)
const;
252 const Data&
get(
const Index& index,
unsigned int subindex)
const;
255 Index getFirstIndex()
const;
259 bool getFirstIndex(
Index &index)
const;
269 const Index ¤tIndex,
276 #ifndef TBTK_DISABLE_NLOHMANN_JSON 278 template<
typename Data>
280 indexIncluded =
false;
281 indexSeparator =
false;
284 template<
typename Data>
286 const std::string &serialization,
290 validate(serialization,
"IndexedDataTree", mode),
291 "IndexedDataTree<bool>::IndexedDataTree()",
292 "Unable to parse string as IndexedDataTree<bool> '" 293 << serialization <<
"'.",
301 nlohmann::json j = nlohmann::json::parse(
304 indexIncluded = j.at(
"indexIncluded").get<
bool>();
305 indexSeparator = j.at(
"indexSeparator").get<
bool>();
306 data = Serializable::deserialize<Data>(
307 j.at(
"data").get<std::string>(),
310 nlohmann::json jsonChildren = j.at(
"children");
312 nlohmann::json::const_iterator iterator
313 = jsonChildren.cbegin();
314 iterator != jsonChildren.cend();
320 Serializable::Mode::JSON
323 iterator.value().dump(),
324 Serializable::Mode::JSON
329 catch(nlohmann::json::exception &e){
331 "IndexedDataTree<bool>::IndexedDataTree()",
332 "Unable to parse string as" 333 <<
" IndexedDataTree<bool> '" 334 << serialization <<
"'.",
343 "IndexedDataTree<Data>::IndexedDataTree()",
344 "Only Serializable::Mode::JSON is supported yet.",
350 template<
typename Data>
354 template<
typename Data>
359 template<
typename Data>
363 unsigned int subindex
365 if(subindex < index.
getSize()){
373 if(children.size() == 0){
374 indexSeparator =
true;
379 "IndexedDataTree:add()",
380 "Invalid index '" << index.
toString()
381 <<
"'. Another Index has already been" 382 <<
" added to the tree that has a" 383 <<
" conflicting index at the index" 384 <<
" separator at subindex '" 386 "Note that a separation point between" 387 <<
" two indices counts as a subindex." 391 indexSeparator =
false;
392 add(data, index, subindex+1);
393 indexSeparator =
true;
399 "IndexedDataTree:add()",
400 "Invalid index '" << index.
toString() <<
"'." 401 <<
" Another Index has already been added to" 402 <<
" the tree that has a conflicting index" 403 <<
" separator at subindex '" 405 "Note that a separation point between two" 406 <<
" indices counts as a subindex." 412 "IndexedDataTree::add()",
413 "Invalid Index. Negative indices not allowed, but the" 414 <<
"index " << index.
toString() <<
" have a negative" 415 <<
" index" <<
" in position " << subindex <<
".",
416 "Compound indices such as {{1, 2, 3}, {4, 5, 6}} are" 417 <<
" separated by IDX_SEPARATOR with the value '" 418 << IDX_SEPARATOR <<
"' and are" <<
" represented as {1" 419 <<
", 2, 3, " << IDX_SEPARATOR <<
", 4, 5, 6}. This is" 420 <<
" the only allowed instance of negative numbers." 431 "IndexedDataTree::add()",
432 "Incompatible indices. The Index " << index.
toString()
433 <<
" cannot be added because an Index of length " 434 << subindex + 1 <<
" which exactly agrees with the " 435 << subindex + 1 <<
" first indices of the current" 436 <<
" Index has already been added.",
440 children[currentIndex].add(data, index, subindex+1);
452 children.size() == 0,
453 "IndexedDataTree::add()",
454 "Incompatible indices. The Index " << index.
toString()
455 <<
" cannot be added because a longer Index which" 456 <<
" exactly agrees with the current Index in the" 457 <<
" common indices has already been added.",
461 indexIncluded =
true;
466 template<
typename Data>
468 return get(data, index, 0);
471 template<
typename Data>
475 unsigned int subindex
477 if(subindex < index.
getSize()){
485 if(children.size() == 0 && !indexIncluded)
493 return get(data, index, subindex+1);
497 "IndexedDataTree::get()",
498 "Invalid Index. Found IDX_SEPARATOR at" 499 <<
" subindex '" << subindex <<
"'," 500 <<
" but the node is not an index" 509 "IndexedDataTree::add()",
510 "Invalid Index. Negative indices not allowed, but the" 511 <<
" index " << index.
toString() <<
" have a negative" 512 <<
" index in position " << subindex <<
".",
517 return children.at(currentIndex).get(data, index, subindex+1);
519 catch(std::out_of_range &e){
538 template<
typename Data>
545 return const_cast<Data&
>(
550 template<
typename Data>
552 return get(index, 0);
555 template<
typename Data>
558 unsigned int subindex
560 if(subindex < index.
getSize()){
569 if(children.size() == 0 && !indexIncluded){
573 "Tried to get element with Index '" 574 + index.
toString() +
"', but no such element" 583 if(currentIndex.isIndexSeparator()){
585 return get(index, subindex+1);
589 "IndexedDataTree::get()",
590 "Invalid Index. Found IDX_SEPARATOR at" 591 <<
" subindex '" << subindex <<
"'," 592 <<
" but the node is not an index" 601 "IndexedDataTree::get()",
602 "Invalid Index. Negative indices not allowed, but the" 603 <<
"index " << index.
toString() <<
" have a negative" 604 <<
" index" <<
" in position " << subindex <<
".",
605 "Compound indices such as {{1, 2, 3}, {4, 5, 6}} are" 606 <<
" separated by IDX_SEPARATOR with the value '" 607 << IDX_SEPARATOR <<
"' and are" <<
" represented as {1" 608 <<
", 2, 3, " << IDX_SEPARATOR <<
", 4, 5, 6}. This is" 609 <<
" the only allowed instance of negative numbers." 613 return children.at(currentIndex).get(index, subindex+1);
615 catch(std::out_of_range &e){
619 "Tried to get element with Index '" 620 + index.
toString() +
"', but no such element" 637 "Tried to get element with Index '" 638 + index.
toString() +
"', but no such element" 646 template<
typename Data>
649 getFirstIndex(index);
654 template<
typename Data>
666 >::const_iterator iterator = children.
cbegin();
667 iterator != children.cend();
670 Subindex subindex = iterator->first;
672 if(iterator->second.getFirstIndex(index))
684 template<
typename Data>
690 getNextIndex(index, nextIndex);
695 template<
typename Data>
697 const Index ¤tIndex,
701 if(currentIndex.
equals(nextIndex))
710 bool hasSameIndexStructure =
true;
712 for(
unsigned int n = 0; n < nextIndex.
getSize(); n++){
713 if(currentIndex[n] != nextIndex[n]){
714 hasSameIndexStructure =
false;
720 hasSameIndexStructure =
false;
723 typename std::map<Subindex, IndexedDataTree>::const_iterator iterator;
724 if(hasSameIndexStructure)
725 iterator = children.find(currentIndex[nextIndex.
getSize()]);
727 iterator = children.cbegin();
728 while(iterator != children.cend()){
729 nextIndex.
pushBack(iterator->first);
730 if(iterator->second.getNextIndex(currentIndex, nextIndex))
743 template<
typename Data>
745 indexIncluded =
false;
749 template<
typename Data>
756 >::const_iterator iterator = children.
cbegin();
757 iterator != children.cend();
760 size += iterator->second.getSizeInBytes();
766 template<
typename Data>
772 j[
"id"] =
"IndexedDataTree";
773 j[
"indexIncluded"] = indexIncluded;
774 j[
"indexSeparator"] = indexSeparator;
776 j[
"children"] = nlohmann::json();
781 >::const_iterator iterator = children.
cbegin();
782 iterator != children.cend();
786 iterator->first.serialize(
787 Serializable::Mode::JSON
789 ] = nlohmann::json::parse(
790 iterator->second.serialize(
791 Serializable::Mode::JSON
800 "IndexedDataTree<Data>::serialize()",
801 "Only Serializable::Mode::JSON is supported yet.",
807 template<
typename Data>
809 return Iterator(
this);
812 template<
typename Data>
816 return ConstIterator(
this);
819 template<
typename Data>
823 return ConstIterator(
this);
826 template<
typename Data>
828 return Iterator(
this,
true);
831 template<
typename Data>
833 return ConstIterator(
this,
true);
836 template<
typename Data>
838 return ConstIterator(
this,
true);
841 template<
typename Data>
template<
bool isConstIterator>
843 currentIndex = indexedDataTree->getNextIndex(currentIndex);
846 template<
typename Data>
template<
bool isConstIterator>
852 return indexedDataTree->
get(currentIndex);
855 template<
typename Data>
template<
bool isConstIterator>
860 indexedDataTree == rhs.indexedDataTree
861 && currentIndex.
equals(rhs.currentIndex)
870 template<
typename Data>
template<
bool isConstIterator>
875 indexedDataTree != rhs.indexedDataTree
876 || !currentIndex.
equals(rhs.currentIndex)
885 template<
typename Data>
template<
bool isConstIterator>
893 template<
typename Data>
template<
bool isConstIterator>
895 IndexedDataTreePointerType indexedDataTree,
898 this->indexedDataTree = indexedDataTree;
900 currentIndex =
Index();
902 currentIndex = indexedDataTree->getFirstIndex();
unsigned int getSizeInBytes() const
Definition: IndexedDataTree.h:750
Subindex popBack()
Definition: Index.h:501
Iterator end()
Definition: IndexedDataTree.h:827
void pushBack(Subindex subindex)
Definition: Index.h:490
ConstIterator cbegin() const
Definition: IndexedDataTree.h:822
ConstIterator cend() const
Definition: IndexedDataTree.h:837
void add(const Data &data, const Index &index)
Definition: IndexedDataTree.h:355
Definition: Serializable.h:43
An entry in an Index.
Definition: Subindex.h:91
Subindex & at(unsigned int n)
Definition: Index.h:474
std::string toString() const
Definition: Index.h:349
Definition: IndexedDataTree.h:183
bool get(Data &data, const Index &index) const
Definition: IndexedDataTree.h:467
friend class Index
Definition: Serializable.h:200
Base class for psudo-serializable objects.
bool isIndexSeparator() const
Definition: Subindex.h:449
Definition: ElementNotFoundException.h:10
Definition: IndexedDataTree.h:45
void clear()
Definition: IndexedDataTree.h:744
unsigned int getSize() const
Definition: Index.h:482
Physical index.
Definition: Index.h:44
Definition: IndexedDataTree.h:170
bool equals(const Index &index, bool allowWildcard=false) const
Definition: Index.h:411
IndexedDataTree()
Definition: IndexedDataTree.h:279
const Vector2d operator*(double lhs, const Vector2d &rhs)
Definition: Vector2d.h:129
Mode
Definition: Serializable.h:47
static bool validate(const std::string &serialization, const std::string &id, Mode mode)
virtual std::string serialize(Mode mode) const =0
virtual ~IndexedDataTree()
Definition: IndexedDataTree.h:351
Abstract base class for serializable objects.
bool operator!=(const IndexTree &lhs, const IndexTree &rhs)
Definition: IndexTree.h:391
virtual std::string serialize(Mode mode) const
Definition: IndexedDataTree.h:767
Iterator begin()
Definition: IndexedDataTree.h:808