ObjectTrie.hpp
Go to the documentation of this file.
1 // @formatter:off
2 //
3 // Balau core C++ library
4 //
5 // Copyright (C) 2008 Bora Software (contact@borasoftware.com)
6 //
7 // Licensed under the Boost Software License - Version 1.0 - August 17th, 2003.
8 // See the LICENSE file for the full license text.
9 //
10 
16 
17 #ifndef COM_BORA_SOFTWARE__BALAU_CONTAINER__BALAU_TRIE
18 #define COM_BORA_SOFTWARE__BALAU_CONTAINER__BALAU_TRIE
19 
20 #include <Balau/Util/Vectors.hpp>
21 
22 // Avoid false positives.
23 #pragma clang diagnostic push
24 #pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
25 
26 namespace Balau::Container {
27 
28 template <typename T> class ObjectTrie;
29 
40 template <typename T> class ObjectTrieNode {
41  // Used in the fluent API.
42  private: class ObjectAdder {
43  friend class ObjectTrieNode<T>;
44  T value;
45  std::vector<ObjectAdder> childAdders;
46 
47  ObjectAdder(T && value_, std::vector<ObjectAdder> && childAdders_)
48  : value(std::move(value_))
49  , childAdders(std::move(childAdders_)) {}
50 
51  public: ObjectAdder(ObjectAdder && ) noexcept = default;
52  };
53 
57  public: static ObjectAdder child(T && value) {
58  return ObjectAdder(std::move(value), {});
59  }
60 
64  public: template <typename ... ObjectAdderT>
65  static ObjectAdder child(T && value, ObjectAdderT && ... childAdder) {
66  return ObjectAdder(std::move(value), Util::Vectors::pushBack(std::move(childAdder) ... ));
67  }
68 
74  public: template <typename ... ObjectAdderT>
75  ObjectTrieNode<T> & add(T && value, ObjectAdderT && ... childAdder) {
76  auto & child = addAndReturnChild(std::move(value));
77  child.add(Util::Vectors::pushBack(std::move(childAdder) ... ));
78  return *this;
79  }
80 
86  public: ObjectTrieNode<T> & add(std::vector<ObjectAdder> && childAdders) {
87  for (auto & childAdder : childAdders) {
88  children.emplace_back(ObjectTrieNode<T>(std::move(childAdder.value)));
89  children.back().add(std::move(childAdder.childAdders));
90  }
91 
92  return *this;
93  }
94 
98  public: T value;
99 
108  public: ObjectTrieNode<T> & add(T && value) {
109  addAndReturnChild(std::move(value));
110  return *this;
111  }
112 
121  public: ObjectTrieNode<T> & add(const T & value) {
122  addAndReturnChild(value);
123  return *this;
124  }
125 
139  public: ObjectTrieNode<T> & addOrReplace(T && value) {
140  ObjectTrieNode<T> * match = find(value);
141 
142  if (match) {
143  match->value = std::move(value);
144  } else {
145  addAndReturnChild(std::move(value));
146  }
147 
148  return *this;
149  }
150 
164  public: ObjectTrieNode<T> & addOrReplace(const T & value) {
165  ObjectTrieNode<T> * match = find(value);
166 
167  if (match) {
168  match->value = value;
169  } else {
170  addAndReturnChild(value);
171  }
172 
173  return *this;
174  }
175 
191  public: template <typename CompareT>
192  ObjectTrieNode<T> & addOrReplace(T && value, CompareT compare) {
193  ObjectTrieNode<T> * match = find(value, compare);
194 
195  if (match) {
196  match->value = std::move(value);
197  } else {
198  addAndReturnChild(std::move(value));
199  }
200 
201  return *this;
202  }
203 
219  public: template <typename CompareT>
220  ObjectTrieNode<T> & addOrReplace(const T & value, CompareT compare) {
221  ObjectTrieNode<T> * match = find(value, compare);
222 
223  if (match) {
224  match->value = value;
225  } else {
226  addAndReturnChild(value);
227  }
228 
229  return *this;
230  }
231 
251  public: template <typename CompareT, typename ReplaceT, ReplaceT replace>
252  ObjectTrieNode<T> & addOrReplace(T && value, CompareT compare) {
253  ObjectTrieNode<T> * match = find(value, compare);
254 
255  if (match) {
256  replace(match->value, std::move(value));
257  } else {
258  addAndReturnChild(std::move(value));
259  }
260 
261  return *this;
262  }
263 
283  public: template <typename CompareT, typename ReplaceT>
284  ObjectTrieNode<T> & addOrReplace(const T & value, CompareT compare, ReplaceT replace) {
285  ObjectTrieNode<T> * match = find(value, compare);
286 
287  if (match) {
288  replace(match->value, value);
289  } else {
290  addAndReturnChild(value);
291  }
292 
293  return *this;
294  }
295 
307  public: ObjectTrieNode<T> & addAndReturnChild(const T & value) {
308  children.emplace_back(ObjectTrieNode<T>(value));
309  return children.back();
310  }
311 
323  public: ObjectTrieNode<T> & addAndReturnChild(T && value) {
324  children.emplace_back(ObjectTrieNode<T>(std::move(value)));
325  return children.back();
326  }
327 
344  public: ObjectTrieNode<T> & addOrReplaceAndReturnChild(const T & value) {
345  ObjectTrieNode<T> * match = find(value);
346 
347  if (match) {
348  match->value = value;
349  return *match;
350  } else {
351  return addAndReturnChild(value);
352  }
353  }
354 
372  ObjectTrieNode<T> * match = find(value);
373 
374  if (match) {
375  match->value = std::move(value);
376  return *match;
377  } else {
378  return addAndReturnChild(std::move(value));
379  }
380  }
381 
400  public: template <typename CompareT>
401  ObjectTrieNode<T> & addOrReplaceAndReturnChild(const T & value, CompareT compare) {
402  ObjectTrieNode<T> * match = find(value, compare);
403 
404  if (match) {
405  match->value = value;
406  return *match;
407  } else {
408  return addAndReturnChild(value);
409  }
410  }
411 
430  public: template <typename CompareT>
431  ObjectTrieNode<T> & addOrReplaceAndReturnChild(T && value, CompareT compare) {
432  ObjectTrieNode<T> * match = find(value, compare);
433 
434  if (match) {
435  match->value = std::move(value);
436  return *match;
437  } else {
438  return addAndReturnChild(std::move(value));
439  }
440  }
441 
464  public: template <typename CompareT, typename ReplaceT>
465  ObjectTrieNode<T> & addOrReplaceAndReturnChild(const T & value, CompareT compare, ReplaceT replace) {
466  ObjectTrieNode<T> * match = find(value, compare);
467 
468  if (match) {
469  replace(match->value, value);
470  return *match;
471  } else {
472  return addAndReturnChild(value);
473  }
474  }
475 
498  public: template <typename CompareT, typename ReplaceT>
499  ObjectTrieNode<T> & addOrReplaceAndReturnChild(T && value, CompareT compare, ReplaceT replace) {
500  ObjectTrieNode<T> * match = find(value, compare);
501 
502  if (match) {
503  replace(match->value, std::move(value));
504  return *match;
505  } else {
506  return addAndReturnChild(std::move(value));
507  }
508  }
509 
516  public: ObjectTrieNode<T> * find(const T & value) {
517  for (size_t m = 0; m < children.size(); m++) {
518  if (children[m].value == value) {
519  return &children[m];
520  }
521  }
522 
523  return nullptr;
524  }
525 
532  public: const ObjectTrieNode<T> * find(const T & value) const {
533  for (size_t m = 0; m < children.size(); m++) {
534  if (children[m].value == value) {
535  return &children[m];
536  }
537  }
538 
539  return nullptr;
540  }
541 
552  public: template <typename CompareT>
553  ObjectTrieNode<T> * find(const T & value, CompareT compare) {
554  for (size_t m = 0; m < children.size(); m++) {
555  if (compare(children[m].value, value)) {
556  return &children[m];
557  }
558  }
559 
560  return nullptr;
561  }
562 
573  public: template <typename CompareT>
574  const ObjectTrieNode<T> * find(const T & value, CompareT compare) const {
575  for (size_t m = 0; m < children.size(); m++) {
576  if (compare(children[m].value, value)) {
577  return &children[m];
578  }
579  }
580 
581  return nullptr;
582  }
583 
595  public: template <typename U, typename CompareT>
596  ObjectTrieNode<T> * find(const U & value, CompareT compare) {
597  for (size_t m = 0; m < children.size(); m++) {
598  if (compare(children[m].value, value)) {
599  return &children[m];
600  }
601  }
602 
603  return nullptr;
604  }
605 
617  public: template <typename U, typename CompareT>
618  const ObjectTrieNode<T> * find(const U & value, CompareT compare) const {
619  for (size_t m = 0; m < children.size(); m++) {
620  if (compare(children[m].value, value)) {
621  return &children[m];
622  }
623  }
624 
625  return nullptr;
626  }
627 
636  public: ObjectTrieNode<T> & findOrAddChild(const T & value) {
637  for (size_t m = 0; m < children.size(); m++) {
638  if (children[m].value == value) {
639  return children[m];
640  }
641  }
642 
643  children.emplace_back(ObjectTrieNode<T>(value));
644  return children.back();
645  }
646 
655  public: ObjectTrieNode<T> & findOrAddChild(T && value) {
656  for (size_t m = 0; m < children.size(); m++) {
657  if (children[m].value == value) {
658  return children[m];
659  }
660  }
661 
662  children.emplace_back(ObjectTrieNode<T>(std::move(value)));
663  return children.back();
664  }
665 
678  public: template <typename U, typename CompareT>
679  ObjectTrieNode<T> & findOrAddChild(const U & value, CompareT compare) {
680  for (size_t m = 0; m < children.size(); m++) {
681  if (compare(children[m].value, value)) {
682  return children[m];
683  }
684  }
685 
686  children.emplace_back(ObjectTrieNode<T>(T(value)));
687  return children.back();
688  }
689 
703  public: template <typename U, typename CompareT, typename Create>
704  ObjectTrieNode<T> & findOrAddChild(const U & value, CompareT compare, Create create) {
705  for (size_t m = 0; m < children.size(); m++) {
706  if (compare(children[m].value, value)) {
707  return children[m];
708  }
709  }
710 
711  children.emplace_back(ObjectTrieNode<T>(create(value)));
712  return children.back();
713  }
714 
718  public: ObjectTrieNode<T> & operator [] (size_t index) {
719  return children[index];
720  }
721 
725  public: const ObjectTrieNode<T> & operator [] (size_t index) const {
726  return children[index];
727  }
728 
732  public: size_t count() const {
733  return children.size();
734  }
735 
739  public: bool empty() const {
740  return children.empty();
741  }
742 
746  public: ObjectTrieNode<T> * begin() {
747  return &children[0];
748  }
749 
753  public: const ObjectTrieNode<T> * begin() const {
754  return &children[0];
755  }
756 
760  public: ObjectTrieNode<T> * end() {
761  return &children.back();
762  }
763 
767  public: const ObjectTrieNode<T> * end() const {
768  return &children.back();
769  }
770 
772 
773  // Used to support the child array allocation.
774  private: explicit ObjectTrieNode()
775  : value() {}
776 
777  // Required public for std::vector
778  public: ObjectTrieNode(ObjectTrieNode<T> && rhs) noexcept
779  : value(std::move(rhs.value))
780  , children(std::move(rhs.children)) {}
781 
782  // Required public for std::vector
783  public: ObjectTrieNode(const ObjectTrieNode<T> & copy)
784  : value(copy.value)
785  , children(copy.children) {}
786 
787  private: explicit ObjectTrieNode(const T & value_)
788  : value(value_) {}
789 
790  private: explicit ObjectTrieNode(T && value_)
791  : value(std::move(value_)) {}
792 
793  private: ObjectTrieNode<T> & operator = (const ObjectTrieNode<T> & copy) {
794  value = copy.value;
795  children = copy.children;
796  return *this;
797  }
798 
799  // Required for std::move.
800  public: ObjectTrieNode<T> & operator = (ObjectTrieNode<T> && rhs) noexcept {
801  value = std::move(rhs.value);
802  children = std::move(rhs.children);
803  return *this;
804  }
805 
806  // Used in the public cascade copy method.
807  private: void cascadeChildren(const ObjectTrieNode<T> & toCascade) {
808  for (size_t m = 0; m < toCascade.children.size(); m++) {
809  const ObjectTrieNode<T> & childToCascade = toCascade.children[m];
810  ObjectTrieNode<T> * selfChild = find(childToCascade.value);
811 
812  if (selfChild) {
813  selfChild->value = childToCascade.value;
814  selfChild->cascadeChildren(childToCascade);
815  } else {
816  addAndReturnChild(childToCascade.value).cascadeChildren(childToCascade);
817  }
818  }
819  }
820 
821  // Used in the public cascade move method.
822  private: template <typename U> void cascadeChildren(ObjectTrieNode<T> & toCascade, U moveFunction) {
823  for (size_t m = 0; m < toCascade.children.size(); m++) {
824  ObjectTrieNode<T> & childToCascade = toCascade.children[m];
825  ObjectTrieNode<T> * selfChild = find(childToCascade.value);
826 
827  if (selfChild) {
828  selfChild->value = moveFunction(childToCascade.value);
829  selfChild->cascadeChildren(childToCascade);
830  } else {
831  addAndReturnChild(moveFunction(childToCascade.value)).cascadeChildren(childToCascade);
832  }
833  }
834  }
835 
836  template <typename U> friend class ObjectTrie;
837 
838  private: std::vector<ObjectTrieNode<T>> children;
839 };
840 
842 
876 template <typename T> class ObjectTrie {
880  public: class DepthIterator {
881  private: class IteratorNode {
882  public: ObjectTrieNode<T> * node;
883  // The index is offset by +1 in order to assign 0 to the current node.
884  public: size_t index;
885 
886  public: IteratorNode(ObjectTrieNode<T> * node_, size_t index_) : node(node_), index(index_) {}
887  };
888 
892  public: DepthIterator(const DepthIterator & copy)
893  : nodeStack(copy.nodeStack) {}
894 
898  public: DepthIterator & operator = (const DepthIterator & copy) {
899  nodeStack = copy.nodeStack;
900  return *this;
901  }
902 
906  public: DepthIterator & operator ++ () {
907  if (!nodeStack.size()) {
908  return endMarker;
909  }
910 
911  while (nodeStack.size() > 0) {
912  if (nodeStack.back().index < nodeStack.back().node->children.size()) {
913  ++nodeStack.back().index;
914  nodeStack.push_back({ &nodeStack.back().node->children[nodeStack.back().index - 1], 0 });
915  return *this;
916  } else {
917  nodeStack.pop_back();
918  }
919  }
920 
921  return endMarker;
922  }
923 
927  public: ObjectTrieNode<T> & operator * () {
928  return *nodeStack.back().node;
929  }
930 
934  public: const ObjectTrieNode<T> & operator * () const {
935  return *nodeStack.back().node;
936  }
937 
941  public: ObjectTrieNode<T> * operator -> () {
942  return nodeStack.back().node;
943  }
944 
948  public: const ObjectTrieNode<T> * operator -> () const {
949  return nodeStack.back().node;
950  }
951 
960  public: ObjectTrieNode<T> * getAncestor(size_t level) {
961  if (nodeStack.size() <= level) {
962  return nullptr;
963  }
964 
965  return nodeStack[nodeStack.size() - 1 - level].node;
966  }
967 
976  public: const ObjectTrieNode<T> * getAncestor(size_t level) const {
977  if (nodeStack.size() <= level) {
978  return nullptr;
979  }
980 
981  return nodeStack[nodeStack.size() - 1 - level].node;
982  }
983 
989  public: void getAncestors(std::vector<const ObjectTrieNode<T> *> & output) const {
990  output.clear();
991 
992  for (const auto & iteratorNode : nodeStack) {
993  output.emplace_back(iteratorNode.node);
994  }
995  }
996 
1000  public: bool operator == (const DepthIterator & rhs) const {
1001  return nodeStack.size() == rhs.nodeStack.size()
1002  && (!nodeStack.size() || nodeStack.back().node == rhs.nodeStack.back().node);
1003  }
1004 
1008  public: bool operator != (const DepthIterator & rhs) const {
1009  return ! operator == (rhs);
1010  }
1011 
1012  friend class ObjectTrie<T>;
1013 
1014  private: DepthIterator() = default;
1015 
1016  private: explicit DepthIterator(ObjectTrie<T> * parent)
1017  : nodeStack({ IteratorNode(&parent->trieRoot, 0) }) {}
1018 
1019  private: static DepthIterator endMarker;
1020  private: std::vector<IteratorNode> nodeStack;
1021  };
1022 
1026  public: class ConstDepthIterator {
1027  private: class IteratorNode {
1028  public: const ObjectTrieNode<T> * node;
1029  // The index is offset by +1 in order to assign 0 to the current node.
1030  public: size_t index;
1031 
1032  public: IteratorNode(const ObjectTrieNode<T> * node_, size_t index_) : node(node_), index(index_) {}
1033  };
1034 
1039  : nodeStack(copy.nodeStack) {}
1040 
1044  public: ConstDepthIterator & operator = (const ConstDepthIterator & copy) {
1045  nodeStack = copy.nodeStack;
1046  return *this;
1047  }
1048 
1052  public: ConstDepthIterator & operator ++ () {
1053  if (!nodeStack.size()) {
1054  return endMarker;
1055  }
1056 
1057  while (nodeStack.size() > 0) {
1058  if (nodeStack.back().index < nodeStack.back().node->children.size()) {
1059  ++nodeStack.back().index;
1060  nodeStack.push_back({ &nodeStack.back().node->children[nodeStack.back().index - 1], 0 });
1061  return *this;
1062  } else {
1063  nodeStack.pop_back();
1064  }
1065  }
1066 
1067  return endMarker;
1068  }
1069 
1073  public: const ObjectTrieNode<T> & operator * () const {
1074  return *nodeStack.back().node;
1075  }
1076 
1080  public: const ObjectTrieNode<T> * operator -> () const {
1081  return nodeStack.back().node;
1082  }
1083 
1092  public: const ObjectTrieNode<T> * getAncestor(size_t level) const {
1093  if (nodeStack.size() <= level) {
1094  return nullptr;
1095  }
1096 
1097  return nodeStack[nodeStack.size() - 1 - level].node;
1098  }
1099 
1105  public: void getAncestors(std::vector<ObjectTrieNode<T> * const> & output) const {
1106  output.clear();
1107 
1108  for (const auto & iteratorNode : nodeStack) {
1109  output.emplace_back(iteratorNode.node);
1110  }
1111  }
1112 
1116  public: bool operator == (const ConstDepthIterator & rhs) const {
1117  return nodeStack.size() == rhs.nodeStack.size()
1118  && (!nodeStack.size() || nodeStack.back().node == rhs.nodeStack.back().node);
1119  }
1120 
1124  public: bool operator != (const ConstDepthIterator & rhs) const {
1125  return ! operator == (rhs);
1126  }
1127 
1128  friend class ObjectTrie<T>;
1129 
1130  private: ConstDepthIterator() = default;
1131 
1132  private: explicit ConstDepthIterator(const ObjectTrie<T> * parent)
1133  : nodeStack({ IteratorNode(&parent->trieRoot, 0) }) {}
1134 
1135  private: static ConstDepthIterator endMarker;
1136  private: std::vector<IteratorNode> nodeStack;
1137  };
1138 
1144  using iterator = DepthIterator;
1145 
1151  using const_iterator = ConstDepthIterator;
1152 
1156  public: class BreadthIterator {
1160  public: BreadthIterator(const BreadthIterator & copy)
1161  : nodeQueue(copy.nodeQueue) {}
1162 
1166  public: BreadthIterator & operator = (const BreadthIterator & copy) {
1167  nodeQueue = copy.nodeQueue;
1168  return *this;
1169  }
1170 
1174  public: BreadthIterator & operator ++ () {
1175  if (!nodeQueue.size()) {
1176  return endMarker;
1177  }
1178 
1179  ObjectTrieNode<T> * previous = nodeQueue.front();
1180  nodeQueue.pop();
1181 
1182  for (size_t m = 0; m < previous->children.size(); m++) {
1183  nodeQueue.push(&previous->children[m]);
1184  }
1185 
1186  if (!nodeQueue.size()) {
1187  return endMarker;
1188  }
1189 
1190  return *this;
1191  }
1192 
1196  public: ObjectTrieNode<T> & operator * () {
1197  return *nodeQueue.front();
1198  }
1199 
1203  public: const ObjectTrieNode<T> & operator * () const {
1204  return *nodeQueue.front();
1205  }
1206 
1210  public: ObjectTrieNode<T> * operator -> () {
1211  return nodeQueue.front();
1212  }
1213 
1217  public: const ObjectTrieNode<T> * operator -> () const {
1218  return nodeQueue.front();
1219  }
1220 
1224  public: bool operator == (const BreadthIterator & rhs) const {
1225  return nodeQueue.size() == rhs.nodeQueue.size()
1226  && (!nodeQueue.size() || nodeQueue.front() == rhs.nodeQueue.front());
1227  }
1228 
1232  public: bool operator != (const BreadthIterator & rhs) const {
1233  return ! operator == (rhs);
1234  }
1235 
1236  friend class ObjectTrie<T>;
1237 
1238  private: BreadthIterator() = default;
1239 
1240  private: explicit BreadthIterator(ObjectTrie<T> * parent)
1241  : nodeQueue({ &parent->trieRoot }) {}
1242 
1243  private: static BreadthIterator endMarker;
1244  private: std::queue<ObjectTrieNode<T> *> nodeQueue;
1245  };
1246 
1250  public: class ConstBreadthIterator {
1255  : nodeQueue(copy.nodeQueue) {}
1256 
1260  public: ConstBreadthIterator & operator = (const ConstBreadthIterator & copy) {
1261  nodeQueue = copy.nodeQueue;
1262  return *this;
1263  }
1264 
1268  public: ConstBreadthIterator & operator ++ () {
1269  if (!nodeQueue.size()) {
1270  return endMarker;
1271  }
1272 
1273  const ObjectTrieNode<T> * previous = nodeQueue.front();
1274  nodeQueue.pop();
1275 
1276  for (size_t m = 0; m < previous->children.size(); m++) {
1277  nodeQueue.push(&previous->children[m]);
1278  }
1279 
1280  if (!nodeQueue.size()) {
1281  return endMarker;
1282  }
1283 
1284  return *this;
1285  }
1286 
1290  public: const ObjectTrieNode<T> & operator * () const {
1291  return *nodeQueue.front();
1292  }
1293 
1297  public: const ObjectTrieNode<T> * operator -> () const {
1298  return nodeQueue.front();
1299  }
1300 
1304  public: bool operator == (const ConstBreadthIterator & rhs) const {
1305  return nodeQueue.size() == rhs.nodeQueue.size()
1306  && (!nodeQueue.size() || nodeQueue.front() == rhs.nodeQueue.front());
1307  }
1308 
1312  public: bool operator != (const ConstBreadthIterator & rhs) const {
1313  return ! operator == (rhs);
1314  }
1315 
1316  friend class ObjectTrie<T>;
1317 
1318  private: ConstBreadthIterator() = default;
1319 
1320  private: explicit ConstBreadthIterator(const ObjectTrie<T> * parent)
1321  : nodeQueue({ &parent->trieRoot }) {}
1322 
1323  private: static ConstBreadthIterator endMarker;
1324  private: std::queue<const ObjectTrieNode<T> *> nodeQueue;
1325  };
1326 
1330  public: ObjectTrie() = default;
1331 
1338  public: explicit ObjectTrie(const T & trieRoot_) : trieRoot(trieRoot_) {}
1339 
1346  public: explicit ObjectTrie(T && trieRoot_) : trieRoot(std::move(trieRoot_)) {}
1347 
1351  public: ObjectTrie(const ObjectTrie<T> & copy) : trieRoot(copy.trieRoot) {}
1352 
1356  public: ObjectTrie(ObjectTrie<T> && rhs) noexcept : trieRoot(std::move(rhs.trieRoot)) {}
1357 
1361  public: ObjectTrie<T> & operator = (ObjectTrie<T> && rhs) noexcept {
1362  trieRoot = std::move(rhs.trieRoot);
1363  return *this;
1364  }
1365 
1369  public: ObjectTrie<T> & operator = (const ObjectTrie<T> & rhs) {
1370  trieRoot = rhs.trieRoot;
1371  return *this;
1372  }
1373 
1377  public: ObjectTrieNode<T> & root() {
1378  return trieRoot;
1379  }
1380 
1384  public: const ObjectTrieNode<T> & root() const {
1385  return trieRoot;
1386  }
1387 
1393  public: template <typename ... ObjectAdderT>
1394  ObjectTrieNode<T> & add(T && value, ObjectAdderT && ... childNode) {
1395  auto & child = trieRoot.addAndReturnChild(std::move(value));
1396  child.add(Util::Vectors::pushBack(std::move(childNode) ... ));
1397  return trieRoot;
1398  }
1399 
1406  public: ObjectTrieNode<T> & add(const T & value) {
1407  return trieRoot.add(value);
1408  }
1409 
1416  public: ObjectTrieNode<T> & add(T && value) {
1417  return trieRoot.add(std::move(value));
1418  }
1419 
1432  public: ObjectTrieNode<T> & addOrReplace(const T & value) {
1433  return trieRoot.addOrReplace(value);
1434  }
1435 
1449  return trieRoot.addOrReplace(std::move(value));
1450  }
1451 
1464  public: template <typename CompareT>
1465  ObjectTrieNode<T> & addOrReplace(const T & value, CompareT compare) {
1466  return trieRoot.addOrReplace(value, compare);
1467  }
1468 
1481  public: template <typename CompareT>
1482  ObjectTrieNode<T> & addOrReplace(T && value, CompareT compare) {
1483  return trieRoot.addOrReplace(std::move(value), compare);
1484  }
1485 
1497  public: template <typename CompareT, typename ReplaceT>
1498  ObjectTrieNode<T> & addOrReplace(const T & value, CompareT compare, ReplaceT replace) {
1499  return trieRoot.addOrReplace(value, compare, replace);
1500  }
1501 
1513  public: template <typename CompareT, typename ReplaceT>
1514  ObjectTrieNode<T> & addOrReplace(T && value, CompareT compare, ReplaceT replace) {
1515  return trieRoot.addOrReplace(std::move(value), compare, replace);
1516  }
1517 
1529  return trieRoot.addAndReturnChild(value);
1530  }
1531 
1543  return trieRoot.addAndReturnChild(std::move(value));
1544  }
1545 
1562  return trieRoot.addOrReplaceAndReturnChild(value);
1563  }
1564 
1581  return trieRoot.addOrReplaceAndReturnChild(std::move(value));
1582  }
1583 
1599  public: template <typename CompareT>
1600  ObjectTrieNode<T> & addOrReplaceAndReturnChild(const T & value, CompareT compare) {
1601  return trieRoot.addOrReplaceAndReturnChild(value, compare);
1602  }
1603 
1619  public: template <typename CompareT>
1621  return trieRoot.addOrReplaceAndReturnChild(std::move(value), compare);
1622  }
1623 
1639  public: template <typename CompareT, typename ReplaceT>
1640  ObjectTrieNode<T> & addOrReplaceAndReturnChild(const T & value, CompareT compare, ReplaceT replace) {
1641  return trieRoot.addOrReplaceAndReturnChild(value, compare, replace);
1642  }
1643 
1659  public: template <typename CompareT, typename ReplaceT>
1660  ObjectTrieNode<T> & addOrReplaceAndReturnChild(T && value, CompareT compare, ReplaceT replace) {
1661  return trieRoot.addOrReplaceAndReturnChild(std::move(value), compare, replace);
1662  }
1663 
1667  public: ObjectTrieNode<T> & operator [] (size_t index) {
1668  return trieRoot.children[index];
1669  }
1670 
1674  public: const ObjectTrieNode<T> & operator [] (size_t index) const {
1675  return trieRoot.children[index];
1676  }
1677 
1681  public: size_t count() const {
1682  return trieRoot.children.size();
1683  }
1684 
1688  public: bool empty() const {
1689  return trieRoot.children.empty();
1690  }
1691 
1695  public: DepthIterator begin() {
1696  return depthBegin();
1697  }
1698 
1702  public: ConstDepthIterator begin() const {
1703  return depthBegin();
1704  }
1705 
1709  public: DepthIterator end() {
1710  return depthEnd();
1711  }
1712 
1716  public: ConstDepthIterator end() const {
1717  return depthEnd();
1718  }
1719 
1723  public: DepthIterator depthBegin() {
1724  return DepthIterator(this);
1725  }
1726 
1730  public: ConstDepthIterator depthBegin() const {
1731  return ConstDepthIterator(this);
1732  }
1733 
1737  public: DepthIterator depthEnd() {
1738  return DepthIterator::endMarker;
1739  }
1740 
1744  public: ConstDepthIterator depthEnd() const {
1745  return ConstDepthIterator::endMarker;
1746  }
1747 
1751  public: BreadthIterator breadthBegin() {
1752  return BreadthIterator(this);
1753  }
1754 
1758  public: ConstBreadthIterator breadthBegin() const {
1759  return ConstBreadthIterator(this);
1760  }
1761 
1765  public: BreadthIterator breadthEnd() {
1766  return BreadthIterator::endMarker;
1767  }
1768 
1772  public: ConstBreadthIterator breadthEnd() const {
1773  return ConstBreadthIterator::endMarker;
1774  }
1775 
1789  public: template <typename U, template <typename ...> class ContainerT, typename ... UC>
1790  ObjectTrieNode<T> * find(const ContainerT<U, UC ...> & values, bool skipRoot = true) {
1791  return find(values, [] (auto & lhs, auto & rhs) { return lhs == rhs; }, skipRoot);
1792  }
1793 
1807  public: template <typename U, template <typename ...> class ContainerT, typename ... UC>
1808  const ObjectTrieNode<T> * find(const ContainerT<U, UC ...> & values, bool skipRoot = true) const {
1809  return find(values, [] (auto & lhs, auto & rhs) { return lhs == rhs; }, skipRoot);
1810  }
1811 
1828  public: template <typename U, template <typename ...> class ContainerT, typename ... UC, typename CompareT>
1829  ObjectTrieNode<T> * find(const ContainerT<U, UC ...> & values, CompareT compare, bool skipRoot = true) {
1830  if (values.empty()) {
1831  return nullptr;
1832  }
1833 
1834  auto iter = values.begin();
1835 
1836  if (!skipRoot) {
1837  if (!(compare(trieRoot.value, *iter))) {
1838  return nullptr;
1839  }
1840 
1841  ++iter;
1842  }
1843 
1844  ObjectTrieNode<T> * node = &trieRoot;
1845 
1846  while (iter != values.end()) {
1847  node = node->template find<U, CompareT>(*iter, compare);
1848 
1849  if (node == nullptr) {
1850  return nullptr;
1851  }
1852 
1853  ++iter;
1854  }
1855 
1856  return node;
1857  }
1858 
1875  public: template <typename U, template <typename ...> class ContainerT, typename ... UC, typename CompareT>
1876  const ObjectTrieNode<T> * find(const ContainerT<U, UC ...> & values, CompareT compare, bool skipRoot = true) const {
1877  if (values.empty()) {
1878  return nullptr;
1879  }
1880 
1881  auto iter = values.begin();
1882 
1883  if (!skipRoot) {
1884  if (!(compare(trieRoot.value, *iter))) {
1885  return nullptr;
1886  }
1887 
1888  ++iter;
1889  }
1890 
1891  const ObjectTrieNode<T> * node = &trieRoot;;
1892 
1893  while (iter != values.end()) {
1894  node = node->template find<U, CompareT>(*iter, compare);
1895 
1896  if (node == nullptr) {
1897  return nullptr;
1898  }
1899 
1900  ++iter;
1901  }
1902 
1903  return node;
1904  }
1905 
1906 
1925  public: template <typename U, template <typename ...> class ContainerT, typename ... UC>
1926  ObjectTrieNode<T> & findOrAdd(const ContainerT<U, UC ...> & values) {
1927  return findOrAdd(values, [] (auto & lhs, auto & rhs) { return lhs == rhs; });
1928  }
1929 
1951  public: template <typename U, template <typename ...> class ContainerT, typename ... UC, typename CompareT>
1952  ObjectTrieNode<T> & findOrAdd(const ContainerT<U, UC ...> & values, CompareT compare) {
1953  ObjectTrieNode<T> * node = &trieRoot;
1954 
1955  if (values.empty()) {
1956  return *node;
1957  }
1958 
1959  auto iter = values.begin();
1960 
1961  while (iter != values.end()) {
1962  node = &node->template findOrAddChild<U, CompareT>(*iter, compare);
1963  ++iter;
1964  }
1965 
1966  return *node;
1967  }
1968 
1994  public: template <typename U, template <typename ...> class ContainerT, typename ... UC, typename CompareT, typename Create>
1995  ObjectTrieNode<T> & findOrAdd(const ContainerT<U, UC ...> & values, CompareT compare, Create create) {
1996  ObjectTrieNode<T> * node = &trieRoot;
1997 
1998  if (values.empty()) {
1999  return *node;
2000  }
2001 
2002  auto iter = values.begin();
2003 
2004  while (iter != values.end()) {
2005  node = &node->template findOrAddChild<U, CompareT>(*iter, compare, create);
2006  ++iter;
2007  }
2008 
2009  return *node;
2010  }
2011 
2027  public: template <typename U, template <typename ...> class ContainerT, typename ... UC>
2028  ObjectTrieNode<T> * findNearest(const ContainerT<U, UC ...> & values, bool skipRoot = true) {
2029  return findNearest(values, [] (auto & lhs, auto & rhs) { return lhs == rhs; }, skipRoot);
2030  }
2031 
2047  public: template <typename U, template <typename ...> class ContainerT, typename ... UC>
2048  const ObjectTrieNode<T> * findNearest(const ContainerT<U, UC ...> & values, bool skipRoot = true) const {
2049  return findNearest(values, [] (auto & lhs, auto & rhs) { return lhs == rhs; }, skipRoot);
2050  }
2051 
2070  public: template <typename U, template <typename ...> class ContainerT, typename ... UC, typename CompareT>
2071  ObjectTrieNode<T> * findNearest(const ContainerT<U, UC ...> & values, CompareT compare, bool skipRoot = true) {
2072  if (values.empty()) {
2073  return nullptr;
2074  }
2075 
2076  auto iter = values.begin();
2077  ObjectTrieNode<T> * nodeToSearch = &trieRoot;
2078  ObjectTrieNode<T> * currentNode = nullptr;
2079 
2080  if (!skipRoot) {
2081  if (!compare(trieRoot.value, *iter)) {
2082  return nullptr;
2083  }
2084 
2085  ++iter;
2086  currentNode = &trieRoot;
2087  }
2088 
2089  ObjectTrieNode<T> * nextNode;
2090 
2091  while (iter != values.end()) {
2092  nextNode = nodeToSearch->find(*iter, compare);
2093 
2094  if (nextNode == nullptr) {
2095  return currentNode;
2096  }
2097 
2098  ++iter;
2099  currentNode = nextNode;
2100  nodeToSearch = nextNode;
2101  }
2102 
2103  return currentNode;
2104  }
2105 
2124  public: template <typename U, template <typename ...> class ContainerT, typename ... UC, typename CompareT>
2125  const ObjectTrieNode<T> * findNearest(const ContainerT<U, UC ...> & values, CompareT compare, bool skipRoot = true) const {
2126  if (values.empty()) {
2127  return nullptr;
2128  }
2129 
2130  auto iter = values.begin();
2131  const ObjectTrieNode<T> * nodeToSearch = &trieRoot;
2132  const ObjectTrieNode<T> * currentNode = nullptr;
2133 
2134  if (!skipRoot) {
2135  if (!compare(trieRoot.value, *iter)) {
2136  return nullptr;
2137  }
2138 
2139  ++iter;
2140  currentNode = &trieRoot;
2141  }
2142 
2143  const ObjectTrieNode<T> * nextNode;
2144 
2145  while (iter != values.end()) {
2146  nextNode = nodeToSearch->find(*iter, compare);
2147 
2148  if (nextNode == nullptr) {
2149  return currentNode;
2150  }
2151 
2152  ++iter;
2153  currentNode = nextNode;
2154  nodeToSearch = nextNode;
2155  }
2156 
2157  return currentNode;
2158  }
2159 
2175  public: template <typename U, template <typename ...> class ContainerT, typename ... UC>
2176  ObjectTrieNode<T> * findNearestLeaf(const ContainerT<U, UC ...> & values, bool skipRoot = true) {
2177  return findNearestLeaf(values, [] (auto & lhs, auto & rhs) { return lhs == rhs; }, skipRoot);
2178  }
2179 
2195  public: template <typename U, template <typename ...> class ContainerT, typename ... UC>
2196  const ObjectTrieNode<T> * findNearestLeaf(const ContainerT<U, UC ...> & values, bool skipRoot = true) const {
2197  return findNearestLeaf(values, [] (auto & lhs, auto & rhs) { return lhs == rhs; }, skipRoot);
2198  }
2199 
2218  public: template <typename U, template <typename ...> class ContainerT, typename ... UC, typename CompareT>
2219  ObjectTrieNode<T> * findNearestLeaf(const ContainerT<U, UC ...> & values, CompareT compare, bool skipRoot = true) {
2220  auto node = findNearest(values, compare, skipRoot);
2221  return node != nullptr && node->children.empty() ? node : nullptr;
2222  }
2223 
2242  public: template <typename U, template <typename ...> class ContainerT, typename ... UC, typename CompareT>
2243  const ObjectTrieNode<T> * findNearestLeaf(const ContainerT<U, UC ...> & values, CompareT compare, bool skipRoot = true) const {
2244  auto node = findNearest(values, compare, skipRoot);
2245  return node != nullptr && node->children.empty() ? node : nullptr;
2246  }
2247 
2257  public: void cascade(const ObjectTrie<T> & toCascade) {
2258  cascade(toCascade, stdCopyFunction);
2259  }
2260 
2272  public: void cascade(ObjectTrie<T> && toCascade) {
2273  cascade(std::move(toCascade), stdMoveFunction);
2274  }
2275 
2286  public: template <typename U> void cascade(const ObjectTrie<T> & toCascade, U copyFunction) {
2287  if (!(trieRoot.value == toCascade.trieRoot.value)) {
2288  return; // NOP
2289  }
2290 
2291  trieRoot.value = copyFunction(toCascade.trieRoot.value);
2292  trieRoot.cascadeChildren(toCascade.trieRoot);
2293  }
2294 
2306  public: template <typename U> void cascade(ObjectTrie<T> && toCascade, U moveFunction) {
2307  if (!(trieRoot.value == toCascade.trieRoot.value)) {
2308  return; // NOP
2309  }
2310 
2311  trieRoot.value = moveFunction(toCascade.trieRoot.value);
2312  trieRoot.cascadeChildren(toCascade.trieRoot, moveFunction);
2313  }
2314 
2316 
2317  private: static const T & stdCopyFunction(const T & in) {
2318  return in;
2319  }
2320 
2321  private: static T && stdMoveFunction(T & in) {
2322  return std::move(in);
2323  }
2324 
2325  private: ObjectTrieNode<T> trieRoot;
2326 };
2327 
2328 template <typename T>
2330 
2331 template <typename T>
2333 
2334 template <typename T>
2336 
2337 template <typename T>
2339 
2343 template <typename T>
2344 std::ostream & operator << (std::ostream & stream, const ObjectTrie<T> & trie) {
2345  typename ObjectTrie<T>::ConstBreadthIterator iter = trie.breadthBegin();
2346  typename ObjectTrie<T>::ConstBreadthIterator end = trie.breadthEnd();
2347 
2348  while (iter != end) {
2349  stream << iter->value << "\n";
2350  ++iter;
2351  }
2352 
2353  return stream;
2354 }
2355 
2356 } // namespace Balau::Container
2357 
2358 #pragma clang diagnostic pop
2359 
2360 #endif // COM_BORA_SOFTWARE__BALAU_CONTAINER__BALAU_TRIE
void cascade(ObjectTrie< T > &&toCascade)
Cascades the supplied trie onto this trie, moving the source values.
Definition: ObjectTrie.hpp:2272
const ObjectTrieNode< T > * end() const
Get a const iterator positioned at the end of the vector of children.
Definition: ObjectTrie.hpp:767
DepthIterator(const DepthIterator &copy)
Make a copy of the supplied iterator.
Definition: ObjectTrie.hpp:892
bool operator==(const BalauException &lhs, const BalauException &rhs)
Base class comparison function for Balau exceptions.
Definition: BalauException.hpp:112
A depth first iterator for the trie.
Definition: ObjectTrie.hpp:880
ObjectTrieNode< T > & addOrReplaceAndReturnChild(T &&value, CompareT compare, ReplaceT replace)
Append a root node child containing a copy of the supplied data if a child equal to the supplied valu...
Definition: ObjectTrie.hpp:1660
ObjectTrieNode< T > * findNearestLeaf(const ContainerT< U, UC ... > &values, CompareT compare, bool skipRoot=true)
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:2219
DepthIterator begin()
Get a depth iterator positioned at the beginning of the trie.
Definition: ObjectTrie.hpp:1695
T value
The publicly accessible data contained in the node.
Definition: ObjectTrie.hpp:98
ObjectTrieNode< T > * findNearest(const ContainerT< U, UC ... > &values, bool skipRoot=true)
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:2028
const ObjectTrieNode< T > * find(const T &value, CompareT compare) const
Locates the first child matching the supplied value or return nullptr if not found.
Definition: ObjectTrie.hpp:574
ObjectTrie(ObjectTrie< T > &&rhs) noexcept
Move a trie.
Definition: ObjectTrie.hpp:1356
static std::vector< T > pushBack()
Create and populate a vector via emplace back of multiple elements (empty case).
Definition: Vectors.hpp:71
ObjectTrieNode< T > & addOrReplace(const T &value, CompareT compare, ReplaceT replace)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:284
DepthIterator end()
Get a depth iterator positioned at the end of the trie.
Definition: ObjectTrie.hpp:1709
ObjectTrieNode< T > & findOrAdd(const ContainerT< U, UC ... > &values)
Descend into the trie, locating matches of the supplied values, or creating them if they do not exist...
Definition: ObjectTrie.hpp:1926
ObjectTrieNode< T > & findOrAddChild(const T &value)
Locates the first child matching the supplied value or creates a one.
Definition: ObjectTrie.hpp:636
ObjectTrieNode< T > & operator[](size_t index)
Get a reference to the specified child.
Definition: ObjectTrie.hpp:718
Various container classes, apart from interprocess containers.
Definition: ArrayBlockingQueue.hpp:25
ObjectTrieNode< T > & addOrReplaceAndReturnChild(T &&value)
Append a root node child containing a copy of the supplied data if a child equal to the supplied valu...
Definition: ObjectTrie.hpp:1580
bool empty() const
Returns true if the trie is empty.
Definition: ObjectTrie.hpp:1688
A breadth first const iterator for the trie.
Definition: ObjectTrie.hpp:1250
ObjectTrieNode< T > & addAndReturnChild(T &&value)
Append a root node child containing a the supplied data.
Definition: ObjectTrie.hpp:1542
ObjectTrieNode< T > & addOrReplaceAndReturnChild(const T &value, CompareT compare)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:401
size_t count() const
Get the number of children in the root node.
Definition: ObjectTrie.hpp:1681
ObjectTrieNode< T > & addAndReturnChild(const T &value)
Append a child containing a copy of the supplied data.
Definition: ObjectTrie.hpp:307
The node type contained in the object trie.
Definition: ObjectTrie.hpp:40
ObjectTrieNode< T > & addOrReplace(const T &value, CompareT compare)
Append a child containing the supplied data to the root node if a child equal to the supplied value i...
Definition: ObjectTrie.hpp:1465
ConstDepthIterator(const ConstDepthIterator &copy)
Make a copy of the supplied iterator.
Definition: ObjectTrie.hpp:1038
Utilities for vectors.
STL namespace.
ConstDepthIterator depthEnd() const
Get a const depth iterator positioned at the end of the trie.
Definition: ObjectTrie.hpp:1744
ObjectTrieNode< T > & addAndReturnChild(T &&value)
Append a child containing the supplied data.
Definition: ObjectTrie.hpp:323
size_t count() const
Get the number of children in the node.
Definition: ObjectTrie.hpp:732
A breadth first iterator for the trie.
Definition: ObjectTrie.hpp:1156
ObjectTrieNode< T > & findOrAdd(const ContainerT< U, UC ... > &values, CompareT compare)
Descend into the trie, locating matches of the supplied values, or creating them if they do not exist...
Definition: ObjectTrie.hpp:1952
DepthIterator depthEnd()
Get a depth iterator positioned at the end of the trie.
Definition: ObjectTrie.hpp:1737
ObjectTrieNode< T > & add(T &&value, ObjectAdderT &&... childAdder)
Append a list of children to the node.
Definition: ObjectTrie.hpp:75
ObjectTrieNode< T > & addOrReplace(const T &value, CompareT compare, ReplaceT replace)
Append a child containing the supplied data to the root node if a child equal to the supplied value i...
Definition: ObjectTrie.hpp:1498
ObjectTrieNode< T > & addOrReplaceAndReturnChild(const T &value)
Append a root node child containing a copy of the supplied data if a child equal to the supplied valu...
Definition: ObjectTrie.hpp:1561
ConstBreadthIterator breadthEnd() const
Get a const breadth iterator positioned at the end of the trie.
Definition: ObjectTrie.hpp:1772
ObjectTrieNode< T > * find(const ContainerT< U, UC ... > &values, CompareT compare, bool skipRoot=true)
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:1829
A depth first const iterator for the trie.
Definition: ObjectTrie.hpp:1026
ObjectTrieNode< T > & findOrAddChild(T &&value)
Locates the first child matching the supplied value or creates a one.
Definition: ObjectTrie.hpp:655
ObjectTrieNode< T > & addOrReplaceAndReturnChild(const T &value, CompareT compare)
Append a root node child containing a copy of the supplied data if a child equal to the supplied valu...
Definition: ObjectTrie.hpp:1600
ObjectTrieNode< T > & addOrReplace(const T &value)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:164
ObjectTrieNode< T > * find(const T &value, CompareT compare)
Locates the first child matching the supplied value or return nullptr if not found.
Definition: ObjectTrie.hpp:553
static ObjectAdder child(T &&value)
Add a child of the child being added.
Definition: ObjectTrie.hpp:57
const ObjectTrieNode< T > * find(const U &value, CompareT compare) const
Locates the first child matching the supplied value or return nullptr if not found.
Definition: ObjectTrie.hpp:618
static ObjectAdder child(T &&value, ObjectAdderT &&... childAdder)
Add a child of the child being added, plus descendants of the child.
Definition: ObjectTrie.hpp:65
ConstDepthIterator depthBegin() const
Get a const depth iterator positioned at the beginning of the trie.
Definition: ObjectTrie.hpp:1730
ObjectTrieNode< T > & addOrReplace(T &&value)
Append a child containing the supplied data to the root node if a child equal to the supplied value i...
Definition: ObjectTrie.hpp:1448
ObjectTrieNode< T > & findOrAddChild(const U &value, CompareT compare)
Locates the first child matching the supplied value or creates one.
Definition: ObjectTrie.hpp:679
ObjectTrieNode< T > & add(std::vector< ObjectAdder > &&childAdders)
Append a vector of children to the node.
Definition: ObjectTrie.hpp:86
bool empty() const
Returns true if the trie node is empty.
Definition: ObjectTrie.hpp:739
ObjectTrieNode< T > & findOrAdd(const ContainerT< U, UC ... > &values, CompareT compare, Create create)
Descend into the trie, locating matches of the supplied values, or creating them if they do not exist...
Definition: ObjectTrie.hpp:1995
ObjectTrieNode< T > & add(T &&value, ObjectAdderT &&... childNode)
Append a child containing the supplied data to the root node, plus children of the new child...
Definition: ObjectTrie.hpp:1394
ObjectTrieNode< T > * findNearestLeaf(const ContainerT< U, UC ... > &values, bool skipRoot=true)
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:2176
const ObjectTrieNode< T > * findNearest(const ContainerT< U, UC ... > &values, CompareT compare, bool skipRoot=true) const
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:2125
ObjectTrieNode< T > & addOrReplace(T &&value, CompareT compare)
Append a child containing the supplied data to the root node if a child equal to the supplied value i...
Definition: ObjectTrie.hpp:1482
ObjectTrie(const T &trieRoot_)
Construct the trie by making a copy of the supplied root value.
Definition: ObjectTrie.hpp:1338
ObjectTrieNode< T > & addOrReplace(const T &value, CompareT compare)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:220
BreadthIterator(const BreadthIterator &copy)
Make a copy of the supplied iterator.
Definition: ObjectTrie.hpp:1160
const ObjectTrieNode< T > * find(const ContainerT< U, UC ... > &values, bool skipRoot=true) const
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:1808
ConstBreadthIterator(const ConstBreadthIterator &copy)
Make a copy of the supplied iterator.
Definition: ObjectTrie.hpp:1254
const ObjectTrieNode< T > * findNearestLeaf(const ContainerT< U, UC ... > &values, bool skipRoot=true) const
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:2196
void getAncestors(std::vector< ObjectTrieNode< T > *const > &output) const
Populate the supplied const pointer vector with the node&#39;s ancestors and the current node...
Definition: ObjectTrie.hpp:1105
ObjectTrieNode< T > & root()
Get the root node of the trie.
Definition: ObjectTrie.hpp:1377
ObjectTrieNode< T > * begin()
Get a depth iterator positioned at the beginning of the trie.
Definition: ObjectTrie.hpp:746
const ObjectTrieNode< T > * begin() const
Get a const depth iterator positioned at the beginning of the trie.
Definition: ObjectTrie.hpp:753
ObjectTrie(const ObjectTrie< T > &copy)
Create a trie by copying an existing trie.
Definition: ObjectTrie.hpp:1351
const ObjectTrieNode< T > * find(const T &value) const
Locates the first child matching the supplied value or return nullptr if not found.
Definition: ObjectTrie.hpp:532
ObjectTrieNode< T > & addAndReturnChild(const T &value)
Append a root node child containing a copy of the supplied data.
Definition: ObjectTrie.hpp:1528
void cascade(const ObjectTrie< T > &toCascade)
Cascades the supplied trie onto this trie, copying the values.
Definition: ObjectTrie.hpp:2257
ObjectTrieNode< T > & addOrReplaceAndReturnChild(T &&value, CompareT compare)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:431
ObjectTrieNode< T > & addOrReplaceAndReturnChild(const T &value, CompareT compare, ReplaceT replace)
Append a root node child containing a copy of the supplied data if a child equal to the supplied valu...
Definition: ObjectTrie.hpp:1640
const ObjectTrieNode< T > * getAncestor(size_t level) const
Get a const pointer to the nth ancestor of the current node.
Definition: ObjectTrie.hpp:976
ObjectTrieNode< T > * find(const ContainerT< U, UC ... > &values, bool skipRoot=true)
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:1790
ObjectTrieNode< T > & addOrReplaceAndReturnChild(T &&value, CompareT compare, ReplaceT replace)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:499
ObjectTrieNode< T > & addOrReplace(T &&value, CompareT compare)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:192
ObjectTrieNode< T > * find(const U &value, CompareT compare)
Locates the first child matching the supplied value or return nullptr if not found.
Definition: ObjectTrie.hpp:596
const ObjectTrieNode< T > * getAncestor(size_t level) const
Get a const pointer to the nth ancestor of the current node.
Definition: ObjectTrie.hpp:1092
ObjectTrieNode< T > & addOrReplaceAndReturnChild(T &&value, CompareT compare)
Append a root node child containing a copy of the supplied data if a child equal to the supplied valu...
Definition: ObjectTrie.hpp:1620
ObjectTrieNode< T > & addOrReplaceAndReturnChild(const T &value, CompareT compare, ReplaceT replace)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:465
ObjectTrieNode< T > & addOrReplaceAndReturnChild(const T &value)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:344
DepthIterator depthBegin()
Get a depth iterator positioned at the beginning of the trie.
Definition: ObjectTrie.hpp:1723
void getAncestors(std::vector< const ObjectTrieNode< T > *> &output) const
Populate the supplied const pointer vector with the node&#39;s ancestors and the current node...
Definition: ObjectTrie.hpp:989
ObjectTrieNode< T > & addOrReplace(T &&value, CompareT compare)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:252
ObjectTrieNode< T > * find(const T &value)
Locates the first child matching the supplied value or return nullptr if not found.
Definition: ObjectTrie.hpp:516
ConstDepthIterator const_iterator
Default (depth first) const iterator.
Definition: ObjectTrie.hpp:1151
ObjectTrieNode< T > & addOrReplace(const T &value)
Append a child containing the supplied data to the root node if a child equal to the supplied value i...
Definition: ObjectTrie.hpp:1432
ObjectTrieNode< T > & add(T &&value)
Append a child containing the supplied data.
Definition: ObjectTrie.hpp:108
const ObjectTrieNode< T > & root() const
Get the root node of the trie.
Definition: ObjectTrie.hpp:1384
DepthIterator iterator
Default (depth first) iterator.
Definition: ObjectTrie.hpp:1144
ObjectTrieNode< T > & addOrReplaceAndReturnChild(T &&value)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:371
const ObjectTrieNode< T > * find(const ContainerT< U, UC ... > &values, CompareT compare, bool skipRoot=true) const
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:1876
void cascade(ObjectTrie< T > &&toCascade, U moveFunction)
Cascades the supplied trie onto this trie.
Definition: ObjectTrie.hpp:2306
void cascade(const ObjectTrie< T > &toCascade, U copyFunction)
Cascades the supplied trie onto this trie.
Definition: ObjectTrie.hpp:2286
ObjectTrieNode< T > * findNearest(const ContainerT< U, UC ... > &values, CompareT compare, bool skipRoot=true)
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:2071
ConstDepthIterator end() const
Get a const depth iterator positioned at the end of the trie.
Definition: ObjectTrie.hpp:1716
ObjectTrieNode< T > & add(const T &value)
Append a child containing a copy of the supplied data to the root node.
Definition: ObjectTrie.hpp:1406
ConstDepthIterator begin() const
Get a const depth iterator positioned at the beginning of the trie.
Definition: ObjectTrie.hpp:1702
ObjectTrieNode< T > & add(const T &value)
Append a child containing the supplied data.
Definition: ObjectTrie.hpp:121
ObjectTrie(T &&trieRoot_)
Construct the trie by moving the supplied root value.
Definition: ObjectTrie.hpp:1346
const ObjectTrieNode< T > * findNearest(const ContainerT< U, UC ... > &values, bool skipRoot=true) const
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:2048
ObjectTrieNode< T > & addOrReplace(T &&value)
Append a child containing the supplied data if a child equal to the supplied value is not present...
Definition: ObjectTrie.hpp:139
ObjectTrieNode< T > & add(T &&value)
Append a child containing the supplied data to the root node.
Definition: ObjectTrie.hpp:1416
const ObjectTrieNode< T > * findNearestLeaf(const ContainerT< U, UC ... > &values, CompareT compare, bool skipRoot=true) const
Descend into the trie, locating matches of the supplied values.
Definition: ObjectTrie.hpp:2243
ObjectTrieNode< T > & findOrAddChild(const U &value, CompareT compare, Create create)
Locates the first child matching the supplied value or creates one.
Definition: ObjectTrie.hpp:704
BreadthIterator breadthBegin()
Get a breadth iterator positioned at the beginning of the trie.
Definition: ObjectTrie.hpp:1751
ConstBreadthIterator breadthBegin() const
Get a const breadth iterator positioned at the beginning of the trie.
Definition: ObjectTrie.hpp:1758
BreadthIterator breadthEnd()
Get a breadth iterator positioned at the end of the trie.
Definition: ObjectTrie.hpp:1765
ObjectTrieNode< T > & addOrReplace(T &&value, CompareT compare, ReplaceT replace)
Append a child containing the supplied data to the root node if a child equal to the supplied value i...
Definition: ObjectTrie.hpp:1514
ObjectTrieNode< T > * getAncestor(size_t level)
Get a pointer to the nth ancestor of the current node.
Definition: ObjectTrie.hpp:960
An object based trie used for parent-child hierarchies.
Definition: ObjectTrie.hpp:28
ObjectTrieNode< T > * end()
Get an iterator positioned at the end of the vector of children.
Definition: ObjectTrie.hpp:760