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)
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
29 #ifndef LIB_FORMAT_UTIL_H
30 #define LIB_FORMAT_UTIL_H
31 
32 #include "lib/meta/trait.hpp"
33 #include "lib/format-obj.hpp"
34 #include "lib/itertools.hpp"
35 #include "lib/symbol.hpp"
36 #include "lib/util.hpp"
37 
38 #include <string>
39 #include <vector>
40 #include <sstream>
41 #include <utility>
42 #include <typeinfo>
43 
44 
45 
46 namespace util {
47 
49  using std::string;
50  using std::forward;
51  using std::move;
52 
53 
54 
55  namespace { // helper to convert arbitrary elements toString
56 
57  template<class CON>
58  inline void
59  do_stringify(CON&)
60  { /* do nothing */ }
61 
62  template<class CON, typename X, typename...ELMS>
63  inline void
64  do_stringify(CON& container, X const& elm, ELMS const& ...args)
65  {
66  container += util::toString (elm);
67  do_stringify (container, args...);
68  }
69 
70 
71  template<class CON, typename...ELMS>
72  struct SeqContainer
73  : CON
74  {
75  void
76  operator+= (string&& s)
77  {
78  CON::push_back (move(s));
79  }
80  };
81 
82  // most common case: use a vector container...
83  using std::vector;
84 
85  template<typename X, typename...ELMS>
86  struct SeqContainer<vector<X>, ELMS...>
87  :vector<X>
88  {
89  SeqContainer()
90  {
91  this->reserve(sizeof...(ELMS));
92  }
93 
94  void
95  operator+= (string&& s)
96  {
97  this->emplace_back (move(s));
98  }
99  };
100  }//(end) stringify helper
101 
102 
109  template<class CON, typename...ELMS>
110  inline CON
111  collectStr(ELMS const& ...elms)
112  {
113  SeqContainer<CON,ELMS...> storage;
114  do_stringify (storage, elms...);
115  return CON {move(storage)};
116  }
117 
119  template<typename...ELMS>
120  inline vector<string>
121  stringify (ELMS const& ...elms)
122  {
123  return collectStr<vector<string>> (elms...);
124  }
125 
131  template<class IT>
132  inline auto
133  stringify (IT&& src)
134  {
135  using Val = typename lib::meta::ValueTypeBinding<IT>::value_type;
136 
137  return lib::transformIterator(forward<IT>(src), util::toString<Val>);
138  }
139 
140 
141 
142  namespace { // helper to build range iterator on demand
143  template<class CON, typename TOGGLE = void>
144  struct _RangeIter
145  {
146  using StlIter = typename CON::const_iterator;
147 
149 
150  _RangeIter(CON const& collection)
151  : iter(begin(collection), end(collection))
152  { }
153  };
154 
155  template<class IT>
156  struct _RangeIter<IT, lib::meta::enable_if< can_IterForEach<IT>> >
157  {
158  IT iter;
159 
160  _RangeIter(IT&& srcIter)
161  : iter(std::forward<IT>(srcIter))
162  { }
163  _RangeIter(IT const& srcIter) // note: copy here
164  : iter(srcIter)
165  { }
166 
167  };
168  }//(end) join helper
169 
170 
191  template<class CON>
192  inline string
193  join (CON&& coll, string const& delim =", ")
194  {
195  using Coll = typename lib::meta::Strip<CON>::TypePlain;
196  _RangeIter<Coll> range(std::forward<CON>(coll)); // copies when CON is reference
197 
198  auto strings = stringify (std::move (range.iter));
199  if (!strings) return "";
200 
201  std::ostringstream buffer;
202  for ( ; strings; ++strings)
203  buffer << *strings << delim;
204 
205  // chop off last delimiter
206  size_t len = buffer.str().length();
207  ASSERT (len >= delim.length());
208  return buffer.str().substr(0, len - delim.length());
209  }
210 
211  template<class X>
212  inline string
213  join (std::initializer_list<X> const&& ili, string const& delim =", ")
214  {
215  return join (ili, delim);
216  }
217 
218  // Note: offering a variant of join with var-args would create lots of ambiguities
219 
221  template<typename...ARGS>
222  inline string
223  joinArgList (ARGS const& ...args)
224  {
225  return "("+join (stringify (args...))+")";
226  }
227 
229  template<typename...ARGS>
230  inline string
231  joinDash (ARGS const& ...args)
232  {
233  return join (stringify (args...), "-");
234  }
235 
237  template<typename...ARGS>
238  inline string
239  joinDot (ARGS const& ...args)
240  {
241  return join (stringify (args...), ".");
242  }
243 
244 
245 } // namespace util
246 #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 dots
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:510
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Definition: format-obj.hpp:191
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:788