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 <string>
37
38#include <drain/Log.h>
39
40namespace drain {
41
42
43
45
52class TreeUtils {
53
54public:
55
57
60 template <class TR, class S>
61 static
62 void getPaths(const TR & tree, S & container){
63 for (const auto & entry: tree){
64 typename TR::path_t p;
65 p << entry.first;
66 getPaths(entry.second, container, p); // recursion
67 };
68 }
69
71
75 template <class TR, class S>
76 static
77 void getPaths(const TR & tree, S & container, const typename TR::path_t & path){ // consider empty() and checking empty
78 container.push_back(path);
79 for (const auto & entry: tree){
80 //for (typename container_t::const_iterator it = begin(); it != end(); ++it){
81 typename TR::path_t p = path;
82 p << entry.first;
83 getPaths(entry.second, container, p); // recursion
84 };
85 }
86
87 template <class T1, class T2>
88 static
89 void deepCopy(const T1 & srcTree, T2 & dstTree){
90
91 for (const auto & entry: srcTree){
92 deepCopy(entry.second, dstTree.addChild(entry.first));
93 };
94
95 if (dstTree.empty() || !dstTree.isExclusive())
96 dstTree.data = srcTree.data;
97
98 }
99
100
101
103
111 template <class T, class H>
112 static void traverse(H & visitor, T & tree, const typename T::path_t & path = typename T::path_t()){
113
115 if (visitor.visitPrefix(tree, path)){
116 return;
117 }
118
119
120 // Recursion
121 for (auto & entry: tree(path).getChildren()){
122 // NOTICE: tree stays intact, path expands...
123 traverse(visitor, tree, typename T::path_t(path, entry.first));
124 }
125
126 if (visitor.visitPostfix(tree, path)){
127 // What to do? Not much commands below ...
128 }
129
130
131 }
132
133
135 template <class T>
136 static
137 bool dataDumper(const T & data, std::ostream &ostr){
138 ostr << data << ' ';
139 return true;
140 }
141
143
151 template <class TR, bool SKIP_EMPTY=false>
152 static
153 bool dump(const TR & tree, std::ostream &ostr = std::cout,
154 bool (* callBack)(const typename TR::node_data_t &, std::ostream &) = TreeUtils::dataDumper, const std::string & indent="") { // int depth = 0) const {
155
156 // https://www.w3.org/TR/xml-entity-names/025.html
157 /*
158 static const std::string EMPTY(" ");
159 static const std::string VERT("│");
160 static const std::string VERT_RIGHT("├");
161 static const std::string UP_RIGHT("└");
162 static const std::string HORZ("─");
163 static const std::string HORZ_DOWN("┬");
164 */
165
166 bool empty = true;
167
168 if (callBack != nullptr){
169 if (! (tree.isExclusive() && tree.hasChildren())){
170 // if (tree.empty()){
171 empty = (*callBack)(tree.data, ostr);
172 }
173 }
174 ostr << '\n';
175
176 for (typename TR::container_t::const_iterator it = tree.begin(); it != tree.end(); it++){
177
178 if (it->second.empty()){
179 continue;
180 }
181
182 std::ostream & ostrChild = ostr; // for now...
183
184 std::string indent2;
185 if (it == --tree.end()){
186 ostrChild << indent << "└──"; // UP_RIGHT << HORZ << HORZ; // "'––";
187 indent2 = indent + " "; // EMPTY + EMPTY + EMPTY; // " ";
188 }
189 else {
190 ostrChild << indent << "├──"; // VERT_RIGHT << HORZ << HORZ; // "¦––";
191 indent2 = indent + "│ "; // VERT + EMPTY + EMPTY; // "| ";
192 }
193 ostrChild << it->first; // << '\n'; //' ' << depth << '\n';
194
195 if (callBack != nullptr){
196 ostrChild << ' ';
197 }
198
199 // dump(entry.second, ostr, nodes, indent2);
200 bool empty2 = dump(it->second, ostrChild, callBack, indent2);
201
202 if (!empty2)
203 empty = false;
204
205 };
206
207 return empty;
208
209 }
210
212 template <class TR>
213 static
214 void dumpContents(const TR & tree, std::ostream &ostr = std::cout, const typename TR::path_t & path = "") {
215 ostr << path << '=';
216 ostr << tree.data << '\n';
217 for (const auto & entry: tree){
218 ostr << entry.first << '\t'; // UNIMPLEMENTED: recursion?
219 dumpContents(entry.second, ostr); //, path+"/"+it->first);
220 };
221 }
222
224 // TODO: move to TreeUtils, Sprinter-like?
225 template <class TR>
226 static inline
227 void writeINI(const TR & t, std::ostream & ostr = std::cout, const typename TR::path_t & prefix = typename TR::path_t()){
228 drain::Logger mout(__FILE__, __FUNCTION__);
229 mout.unimplemented("future extension");
230 }
231
232
233
234 template <class TR>
235 static inline
236 void readINI(TR & tree, std::istream & istr){
237 drain::Logger mout(__FILE__, __FUNCTION__);
238 mout.unimplemented("future extension");
239 }
240
241
242};
243
244
246
252template <class T>
254
255public:
256
257 inline
258 TreeVisitor(){};
259
260 virtual inline
261 ~TreeVisitor(){};
262
264 virtual inline
265 int visitPrefix(T & tree, const typename T::path_t & path){
266 return 0;
267 }
268
270 virtual inline
271 int visitPostfix(T & tree, const typename T::path_t & path){
272 return 0;
273 }
274
275};
276
277
278
279
280#ifdef DRAIN_TYPENAME
281DRAIN_TYPENAME(TreeUtils);
282#endif
283
284
285} // drain::
286
287#endif
288
289
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:326
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition Log.h:521
Collection of functions for investigating and processing trees.
Definition TreeUtils.h:52
static void getPaths(const TR &tree, S &container)
Retrieve all the paths.
Definition TreeUtils.h:62
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:227
static void getPaths(const TR &tree, S &container, const typename TR::path_t &path)
Retrieve all the paths.
Definition TreeUtils.h:77
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:112
static bool dataDumper(const T &data, std::ostream &ostr)
Default implementation for recursive dump()
Definition TreeUtils.h:137
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:214
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:153
Default implementation of a tree visitor (concept) compatible TreeUtils::traverser()
Definition TreeUtils.h:253
virtual int visitPrefix(T &tree, const typename T::path_t &path)
Tasks to be executed before traversing child nodes.
Definition TreeUtils.h:265
virtual int visitPostfix(T &tree, const typename T::path_t &path)
Tasks to be executed after traversing child nodes.
Definition TreeUtils.h:271
Definition Data.h:1473