Lumiera  0.pre.03
»edityourfreedom«
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  stringify(ELMS const& ...elms)
121  {
122  SeqContainer<CON,ELMS...> storage;
123  do_stringify (storage, elms...);
124  return CON {move(storage)};
125  }
126 
132  template<class IT>
133  inline auto
134  stringify (IT&& src)
135  {
136  using Val = typename std::remove_reference<IT>::type::value_type;
137 
138  return lib::transformIterator(forward<IT>(src), util::toString<Val>);
139  }
140 
141 
142 
143  namespace { // helper to build range iterator on demand
144  template<class CON, typename TOGGLE = void>
145  struct _RangeIter
146  {
147  using StlIter = typename CON::const_iterator;
148 
150 
151  _RangeIter(CON const& collection)
152  : iter(begin(collection), end(collection))
153  { }
154  };
155 
156  template<class IT>
157  struct _RangeIter<IT, lib::meta::enable_if< can_IterForEach<IT>> >
158  {
159  IT iter;
160 
161  _RangeIter(IT&& srcIter)
162  : iter(std::forward<IT>(srcIter))
163  { }
164  _RangeIter(IT const& srcIter)
165  : iter(srcIter)
166  { }
167 
168  };
169  }//(end) join helper
170 
171 
190  template<class CON>
191  inline string
192  join (CON&& coll, string const& delim =", ")
193  {
194  using Coll = typename lib::meta::Strip<CON>::TypePlain;
195  _RangeIter<Coll> range(std::forward<CON>(coll));
196 
197  auto strings = stringify (std::move (range.iter));
198  if (!strings) return "";
199 
200  std::ostringstream buffer;
201  for ( ; strings; ++strings)
202  buffer << *strings << delim;
203 
204  // chop off last delimiter
205  size_t len = buffer.str().length();
206  ASSERT (len >= delim.length());
207  return buffer.str().substr(0, len - delim.length());
208  }
209 
210  template<class X>
211  inline string
212  join (std::initializer_list<X> const&& ili, string const& delim =", ")
213  {
214  return join (ili, delim);
215  }
216 
217 
218 } // namespace util
219 #endif /*LIB_FORMAT_UTIL_H*/
typename enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition: meta/util.hpp:91
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Definition: format-obj.hpp:174
std::remove_cv< TypePointee >::type TypePlain
Definition: trait.hpp:225
string join(CON &&coll, string const &delim=", ")
enumerate a collection&#39;s contents, separated by delimiter.
typename meta::Strip< CON >::TypeReferred::const_iterator const_iterator
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:443
Helpers for type detection, type rewriting and metaprogramming.
CON stringify(ELMS const &...elms)
convert a sequence of elements to string
Simple functions to represent objects, for debugging and diagnostics.
Helpers for working with iterators based on the pipeline model.
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
auto transformIterator(IT const &src, FUN processingFunc)
Build a TransformIter: convenience free function shortcut, picking up the involved types automaticall...
Definition: itertools.hpp:790