Lumiera  0.pre.03
»edit your freedom«
format-util.hpp
Go to the documentation of this file.
1 /*
2  FORMAT-UTIL.hpp - helpers for formatting and diagnostics
3 
4  Copyright (C) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
38 #ifndef LIB_FORMAT_UTIL_H
39 #define LIB_FORMAT_UTIL_H
40 
41 #include "lib/meta/trait.hpp"
42 #include "lib/format-obj.hpp"
43 #include "lib/itertools.hpp"
44 #include "lib/symbol.hpp"
45 #include "lib/util.hpp"
46 
47 #include <string>
48 #include <vector>
49 #include <sstream>
50 #include <utility>
51 #include <typeinfo>
52 
53 
54 
55 namespace util {
56 
58  using std::string;
59  using std::forward;
60  using std::move;
61 
62 
63 
64  namespace { // helper to convert arbitrary elements toString
65 
66  template<class CON>
67  inline void
68  do_stringify(CON&)
69  { /* do nothing */ }
70 
71  template<class CON, typename X, typename...ELMS>
72  inline void
73  do_stringify(CON& container, X const& elm, ELMS const& ...args)
74  {
75  container += util::toString (elm);
76  do_stringify (container, args...);
77  }
78 
79 
80  template<class CON, typename...ELMS>
81  struct SeqContainer
82  : CON
83  {
84  void
85  operator+= (string&& s)
86  {
87  CON::push_back (move(s));
88  }
89  };
90 
91  // most common case: use a vector container...
92  using std::vector;
93 
94  template<typename X, typename...ELMS>
95  struct SeqContainer<vector<X>, ELMS...>
96  :vector<X>
97  {
98  SeqContainer()
99  {
100  this->reserve(sizeof...(ELMS));
101  }
102 
103  void
104  operator+= (string&& s)
105  {
106  this->emplace_back (move(s));
107  }
108  };
109  }//(end) stringify helper
110 
111 
118  template<class CON, typename...ELMS>
119  inline CON
120  collectStr(ELMS const& ...elms)
121  {
122  SeqContainer<CON,ELMS...> storage;
123  do_stringify (storage, elms...);
124  return CON {move(storage)};
125  }
126 
128  template<typename...ELMS>
129  inline vector<string>
130  stringify (ELMS const& ...elms)
131  {
132  return collectStr<vector<string>> (elms...);
133  }
134 
140  template<class IT>
141  inline auto
142  stringify (IT&& src)
143  {
144  using Val = typename lib::meta::ValueTypeBinding<IT>::value_type;
145 
146  return lib::transformIterator(forward<IT>(src), util::toString<Val>);
147  }
148 
149 
150 
151  namespace { // helper to build range iterator on demand
152  template<class CON, typename TOGGLE = void>
153  struct _RangeIter
154  {
155  using StlIter = typename CON::const_iterator;
156 
158 
159  _RangeIter(CON const& collection)
160  : iter(begin(collection), end(collection))
161  { }
162  };
163 
164  template<class IT>
165  struct _RangeIter<IT, lib::meta::enable_if< can_IterForEach<IT>> >
166  {
167  IT iter;
168 
169  _RangeIter(IT&& srcIter)
170  : iter(std::forward<IT>(srcIter))
171  { }
172  _RangeIter(IT const& srcIter)
173  : iter(srcIter)
174  { }
175 
176  };
177  }//(end) join helper
178 
179 
198  template<class CON>
199  inline string
200  join (CON&& coll, string const& delim =", ")
201  {
202  using Coll = typename lib::meta::Strip<CON>::TypePlain;
203  _RangeIter<Coll> range(std::forward<CON>(coll));
204 
205  auto strings = stringify (std::move (range.iter));
206  if (!strings) return "";
207 
208  std::ostringstream buffer;
209  for ( ; strings; ++strings)
210  buffer << *strings << delim;
211 
212  // chop off last delimiter
213  size_t len = buffer.str().length();
214  ASSERT (len >= delim.length());
215  return buffer.str().substr(0, len - delim.length());
216  }
217 
218  template<class X>
219  inline string
220  join (std::initializer_list<X> const&& ili, string const& delim =", ")
221  {
222  return join (ili, delim);
223  }
224 
225  // Note: offering a variant of join with var-args would create lots of ambiguities
226 
228  template<typename...ARGS>
229  inline string
230  joinArgList (ARGS const& ...args)
231  {
232  return "("+join (stringify (args...))+")";
233  }
234 
236  template<typename...ARGS>
237  inline string
238  joinDash (ARGS const& ...args)
239  {
240  return join (stringify (args...), "-");
241  }
242 
244  template<typename...ARGS>
245  inline string
246  joinDot (ARGS const& ...args)
247  {
248  return join (stringify (args...), ".");
249  }
250 
251 
252 } // namespace util
253 #endif /*LIB_FORMAT_UTIL_H*/
vector< string > stringify(ELMS const &...elms)
standard setup: convert to string into a vector
CON collectStr(ELMS const &...elms)
convert a sequence of elements to string
Implementation namespace for support and library code.
string joinDot(ARGS const &...args)
shortcut: join directly with dashes
string joinArgList(ARGS const &...args)
shortcut: List in parentheses, separated by comma, using temporary vector
string joinDash(ARGS const &...args)
shortcut: join directly with dashes
Marker types to indicate a literal string and a Symbol.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Trait template to detect a type usable immediately as "Lumiera Forward Iterator" in a specialised for...
Definition: trait.hpp:505
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Definition: format-obj.hpp:200
Helpers for type detection, type rewriting and metaprogramming.
string join(CON &&coll, string const &delim=", ")
enumerate a collection&#39;s contents, separated by delimiter.
Simple functions to represent objects, for debugging and diagnostics.
Helpers for working with iterators based on the pipeline model.
auto collection(COLL &coll)
Entry point to a nested DSL for setup and configuration of a collection binding.
auto transformIterator(IT const &src, FUN processingFunc)
Build a TransformIter: convenience free function shortcut, picking up the involved types automaticall...
Definition: itertools.hpp:797