Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 <sstream>
49 #include <utility>
50 #include <typeinfo>
51 
52 
53 
54 namespace util {
55 
57  using std::string;
58  using std::forward;
59  using std::move;
60 
61 
62 
63  namespace { // helper to convert arbitrary elements toString
64 
65  template<class CON>
66  inline void
67  do_stringify(CON&)
68  { /* do nothing */ }
69 
70  template<class CON, typename X, typename...ELMS>
71  inline void
72  do_stringify(CON& container, X const& elm, ELMS const& ...args)
73  {
74  container += util::toString (elm);
75  do_stringify (container, args...);
76  }
77 
78 
79  template<class CON, typename...ELMS>
80  struct SeqContainer
81  : CON
82  {
83  void
84  operator+= (string&& s)
85  {
86  CON::push_back (move(s));
87  }
88  };
89 
90  // most common case: use a vector container...
91  using std::vector;
92 
93  template<typename X, typename...ELMS>
94  struct SeqContainer<vector<X>, ELMS...>
95  :vector<X>
96  {
97  SeqContainer()
98  {
99  this->reserve(sizeof...(ELMS));
100  }
101 
102  void
103  operator+= (string&& s)
104  {
105  this->emplace_back (move(s));
106  }
107  };
108  }//(end) stringify helper
109 
110 
117  template<class CON, typename...ELMS>
118  inline CON
119  stringify(ELMS const& ...elms)
120  {
121  SeqContainer<CON,ELMS...> storage;
122  do_stringify (storage, elms...);
123  return CON {move(storage)};
124  }
125 
131  template<class IT>
132  inline auto
133  stringify (IT&& src)
134  {
135  using Val = typename std::remove_reference<IT>::type::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)
164  : iter(srcIter)
165  { }
166 
167  };
168  }//(end) join helper
169 
170 
189  template<class CON>
190  inline string
191  join (CON&& coll, string const& delim =", ")
192  {
193  using Coll = typename lib::meta::Strip<CON>::TypePlain;
194  _RangeIter<Coll> range(std::forward<CON>(coll));
195 
196  auto strings = stringify (std::move (range.iter));
197  if (!strings) return "";
198 
199  std::ostringstream buffer;
200  for ( ; strings; ++strings)
201  buffer << *strings << delim;
202 
203  // chop off last delimiter
204  size_t len = buffer.str().length();
205  ASSERT (len >= delim.length());
206  return buffer.str().substr(0, len - delim.length());
207  }
208 
209  template<class X>
210  inline string
211  join (std::initializer_list<X> const&& ili, string const& delim =", ")
212  {
213  return join (ili, delim);
214  }
215 
216 
217 } // namespace util
218 #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
STL namespace.
string join(CON &&coll, string const &delim=", ")
enumerate a collection's contents, separated by delimiter.
Implementation namespace for support and library code.
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