Loading...
Searching...
No Matches
TreeUtils.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31
32// TODO: check
33#ifndef DRAIN_TREE_UTILS
34#define DRAIN_TREE_UTILS "2.1"
35
36#include <cstddef> // nullptr
37#include <iterator>
38#include <string>
39#include <map>
40
41#include <drain/Log.h>
42#include <drain/String.h>
43#include "Path.h"
44
45namespace drain {
46
47
48
50
57class TreeUtils {
58
59public:
60
62
66 template <class TR, class S>
67 static
68 void getPaths(const TR & tree, S & container){
69 for (const auto & entry: tree){
70 typename TR::path_t p;
71 p << entry.first;
72 getPaths(entry.second, container, p); // recursion
73 };
74 }
75
77
81 template <class TR, class S>
82 static
83 void getPaths(const TR & tree, S & container, const typename TR::path_t & path){ // consider empty() and checking empty
84 container.push_back(path);
85 for (const auto & entry: tree){
86 //for (typename container_t::const_iterator it = begin(); it != end(); ++it){
87 typename TR::path_t p = path;
88 p << entry.first;
89 getPaths(entry.second, container, p); // recursion
90 };
91 }
92
93 template <class T1, class T2>
94 static
95 void deepCopy(const T1 & srcTree, T2 & dstTree){
96
97 for (const auto & entry: srcTree){
98 deepCopy(entry.second, dstTree.addChild(entry.first));
99 };
100
101 if (dstTree.empty() || !dstTree.isExclusive())
102 dstTree.data = srcTree.data;
103
104 }
105
106
107
109
117 template <class T, class H>
118 static void traverse(H & visitor, T & tree, const typename T::path_t & path = typename T::path_t()){
119
121 if (visitor.visitPrefix(tree, path)){
122 return;
123 }
124
125
126 // Recursion
127 for (auto & entry: tree(path).getChildren()){
128 // NOTICE: tree stays intact, path expands...
129 traverse(visitor, tree, typename T::path_t(path, entry.first));
130 }
131
132 if (visitor.visitPostfix(tree, path)){
133 // What to do? Not much commands below ...
134 }
135
136
137 };
138
139
141 template <class T>
142 static
143 bool dataDumper(const T & data, std::ostream &ostr){
144 ostr << data << ' ';
145 return true;
146 }
147
149
157 template <class TR, bool SKIP_EMPTY=false>
158 static
159 //void dump(const TR & tree, std::ostream &ostr = std::cout, bool nodes=false, const std::string & indent="") { // int depth = 0) const {
160 bool dump(const TR & tree, std::ostream &ostr = std::cout,
161 bool (* callBack)(const typename TR::node_data_t &, std::ostream &) = TreeUtils::dataDumper, const std::string & indent="") { // int depth = 0) const {
162
163 // https://www.w3.org/TR/xml-entity-names/025.html
164 /*
165 static const std::string EMPTY(" ");
166 static const std::string VERT("│");
167 static const std::string VERT_RIGHT("├");
168 static const std::string UP_RIGHT("└");
169 static const std::string HORZ("─");
170 static const std::string HORZ_DOWN("┬");
171 */
172
173 bool empty = true;
174
175 //if (nodes){
176 if (callBack != nullptr){ // nodes){
177 // std::stringstream sstr;
178 // if ((!tree.hasChildren()) || !tree.isExclusive()){
179 if (! (tree.isExclusive() && tree.hasChildren())){
180 // if (tree.empty()){
181 // if (empty || !tree.isExclusive()){
182 empty = (*callBack)(tree.data, ostr);
183 //if (sstr.LENGTH)
184 // ostr << sstr.str(); // See Logger for direct copy? Risk: pending
185 // ostr << tree.data;
186 }
187 }
188 ostr << '\n';
189
190 // for (const auto & entry: *this){
191 // for (const auto & entry: tree.begin()){
192 for (typename TR::container_t::const_iterator it = tree.begin(); it != tree.end(); it++){
193
194 std::ostream & ostrChild = ostr; // for now...
195
196 std::string indent2;
197 if (it == --tree.end()){
198 ostrChild << indent << "└──"; // UP_RIGHT << HORZ << HORZ; // "'––";
199 indent2 = indent + " "; // EMPTY + EMPTY + EMPTY; // " ";
200 }
201 else {
202 ostrChild << indent << "├──"; // VERT_RIGHT << HORZ << HORZ; // "¦––";
203 indent2 = indent + "│ "; // VERT + EMPTY + EMPTY; // "| ";
204 }
205 ostrChild << it->first; // << '\n'; //' ' << depth << '\n';
206
207 if (callBack != nullptr){ // nodes){
208 //ostr << ':';
209 ostrChild << ' ';
210 }
211
212 // dump(entry.second, ostr, nodes, indent2);
213 bool empty2 = dump(it->second, ostrChild, callBack, indent2);
214
215 if (!empty2)
216 empty = false;
217
218 //if (!(empty2 && SKIP_EMPTY))
219 // if ((empty2 && SKIP_EMPTY)) ostr << "{\n";
220 // ostr << sstr.str();
221 //if ((empty2 && SKIP_EMPTY)) ostr << "}\n";
222 };
223
224 return empty;
225
226 };
227
229 template <class TR>
230 static
231 void dumpContents(const TR & tree, std::ostream &ostr = std::cout, const typename TR::path_t & path = "") {
232 ostr << path << '=';
233 ostr << tree.data << '\n';
234 for (const auto & entry: tree){
235 ostr << entry.first << '\t'; // UNIMPLEMENTED: recursion?
236 dumpContents(entry.second, ostr); //, path+"/"+it->first);
237 };
238 };
239
241 // TODO: move to TreeUtils, Sprinter-like?
242 template <class TR>
243 static inline
244 void writeINI(const TR & t, std::ostream & ostr = std::cout, const typename TR::path_t & prefix = typename TR::path_t()){
245 drain::Logger mout(__FILE__, __FUNCTION__);
246 mout.unimplemented("future extension");
247 }
248
249
250
251 template <class TR>
252 static inline
253 void readINI(TR & tree, std::istream & istr){
254 drain::Logger mout(__FILE__, __FUNCTION__);
255 mout.unimplemented("future extension");
256 }
257
258
259};
260
261
263
269template <class T>
271
272public:
273
274 inline
275 TreeVisitor(){};
276
277 virtual inline
278 ~TreeVisitor(){};
279
281 virtual inline
282 int visitPrefix(T & tree, const typename T::path_t & path){
283 return 0;
284 }
285
287 virtual inline
288 int visitPostfix(T & tree, const typename T::path_t & path){
289 return 0;
290 }
291
292};
293
294
295
296
297#ifdef DRAIN_TYPE_UTILS
298/*
299template <>
300struct TypeName<TreeUtils> {
301 static const char* get(){
302 return "SuperTree";
303 }
304};
305*/
306#endif
307
308
309} // drain::
310
311#endif
312
313
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition Log.h:511
Collection of functions for investigating and processing trees.
Definition TreeUtils.h:57
static void getPaths(const TR &tree, S &container)
Retrieve all the paths.
Definition TreeUtils.h:68
static void writeINI(const TR &t, std::ostream &ostr=std::cout, const typename TR::path_t &prefix=typename TR::path_t())
Write a Windows INI file.
Definition TreeUtils.h:244
static void getPaths(const TR &tree, S &container, const typename TR::path_t &path)
Retrieve all the paths.
Definition TreeUtils.h:83
static void traverse(H &visitor, T &tree, const typename T::path_t &path=typename T::path_t())
Traverse tree, visiting each node as a prefix operation.
Definition TreeUtils.h:118
static bool dataDumper(const T &data, std::ostream &ostr)
Default implementation for recursive dump()
Definition TreeUtils.h:143
static void dumpContents(const TR &tree, std::ostream &ostr=std::cout, const typename TR::path_t &path="")
Debugging utility - dumps the tree, also the contents.
Definition TreeUtils.h:231
static bool dump(const TR &tree, std::ostream &ostr=std::cout, bool(*callBack)(const typename TR::node_data_t &, std::ostream &)=TreeUtils::dataDumper, const std::string &indent="")
Render a tree using character graphics.
Definition TreeUtils.h:160
Default implementation of a tree visitor (concept) compatible TreeUtils::traverser()
Definition TreeUtils.h:270
virtual int visitPrefix(T &tree, const typename T::path_t &path)
Tasks to be executed before traversing child nodes.
Definition TreeUtils.h:282
virtual int visitPostfix(T &tree, const typename T::path_t &path)
Tasks to be executed after traversing child nodes.
Definition TreeUtils.h:288
Definition DataSelector.cpp:1277