OpenWalnut  1.5.0dev
WStringUtils.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WSTRINGUTILS_H
26 #define WSTRINGUTILS_H
27 
28 #include <algorithm>
29 #include <iostream>
30 #include <iomanip>
31 #include <iterator>
32 #include <list>
33 #include <set>
34 #include <sstream>
35 #include <string>
36 #include <vector>
37 
38 #include "exceptions/WTypeMismatch.h"
39 
40 /**
41  * Some utilities for string manipulation and output operations. Please note
42  * that the overloaded ostream output operators aren't in a separate namespace
43  * but the string manipulation functions. This is because of short use of e.g.
44  * the <tt><<</tt> operator instead of <tt>string_utils::operator( cout,
45  * myVector)</tt>.
46  *
47  * The reason for not using the Boost trimming functions is, that Boost
48  * providing just Whitespace trimming depending on the current locale, but we
49  * might want to trim other character sets too.
50  *
51  * The reason for not using the Boost case switching functions is that we want
52  * those functions to return a <tt>std::string</tt> copy which is modified to
53  * make some call chains ala: <tt>foo( rTrim( toLower( str ), "bar" ) );</tt>.
54  *
55  * The reason for not using Boosts Tokenizer is, that this tokenizer, is much
56  * most simplest to use :).
57  */
58 namespace string_utils
59 {
60  /**
61  * Conversion class to convert a string to a given target type. We place this in separate classes as we are not allowed to specialize
62  * function templates. But we need specializations for certain cases.
63  *
64  * \tparam Target target type
65  */
66  template< typename Target >
68  {
69  /**
70  * Convert a given string to the target type. If this fails, a exception is thrown.
71  *
72  * \throw WTypeMismatch if source string cannot be converted to target type value.
73  *
74  * \param from source string
75  *
76  * \return target value
77  */
78  static Target fromString( const std::string& from )
79  {
80  std::stringstream ss( from );
81  Target value;
82  ss >> value;
83  if( ss.fail() )
84  {
85  throw WTypeMismatch( "Specified string could not be converted to target type." );
86  }
87 
88  return value;
89  }
90  };
91 
92  /**
93  * Conversion class to convert a string to a given target type. This is a specialization whenever a string is given as input type
94  */
95  template<>
96  struct fromStringImpl< std::string >
97  {
98  /**
99  * Convert a given string to the target type. Never fails.
100  *
101  * \param from source string
102  *
103  * \return copy of the source string
104  */
105  static std::string fromString( const std::string& from )
106  {
107  return from;
108  }
109  };
110 
111  /**
112  * Convert a given value to a string. The input value must provide a operator<< or be a standard scalar type.
113  *
114  * \tparam T the source type. You do not need to specify this directly as it can be deducted from the given parameter
115  * \param value the value to cast to string
116  *
117  * \return the string.
118  */
119  template< typename T >
120  inline std::string toString( const T& value )
121  {
122  std::stringstream ss;
123  ss << value;
124  return ss.str();
125  }
126 
127  /**
128  * Convert a given value to a string. The input value must provide a operator<< or be a standard scalar type.
129  *
130  * \param value the value to cast to string
131  *
132  * \return the string.
133  */
134  inline std::string toString( const unsigned char& value ) // NOLINT: stylechecker complains about non const ref!?
135  {
136  std::stringstream ss;
137  // NOTE: unsigned chars are interpreted as ASCII chars. We want it to be used as number.
138  ss << static_cast< int >( value );
139  return ss.str();
140  }
141 
142  /**
143  * Convert a given value to a string. The input value must provide a operator<< or be a standard scalar type. This method additionally allows
144  * setting width and precision flags of the used std::stringstream.
145  *
146  * \tparam T the source type. You do not need to specify this directly as it can be deducted from the given parameter
147  * \param value the value to cast to string
148  * \param precision the precision
149  * \param width the width
150  *
151  * \return the string.
152  */
153  template< typename T >
154  inline std::string toString( const T& value, const size_t width, const size_t precision )
155  {
156  std::stringstream ss;
157  ss.width( width );
158  ss.precision( precision );
159  ss << value;
160  return ss.str();
161  }
162 
163  /**
164  * Convert a given string to a value of a certain type. The target type must provide a operator>> to work or be a standard scalar type.
165  *
166  * \tparam T the source type.
167  * \param str the value to cast to string
168  *
169  * \throw WTypeMismatch if the string cannot be converted properly.
170  * \return the string.
171  */
172  template< typename T >
173  inline T fromString( const std::string& str )
174  {
175  return fromStringImpl< T >::fromString( str );
176  }
177 
178  /** We consider the following characters as whitespace:
179  * - <tt>\\r</tt> carriage return
180  * - <tt>\\n</tt> newline
181  * - <tt>\\t</tt> tab
182  * - <tt>' '</tt> space
183  */
184  extern const std::string WHITESPACE;
185 
186  /**
187  * Trims any occurence of each character given in parameter t from the end
188  * (or right side) of the given string.
189  *
190  * \param source String to trim
191  * \param t String representing a set containg all trimmable characters
192  * \return A copy of the trimmed string
193  */
194 
195  std::string rTrim( const std::string& source, const std::string& t = WHITESPACE );
196 
197  /**
198  * Trims any occurence of each character given in parameter t from the
199  * start (or left side) of the given string.
200  *
201  * \param source String to trim
202  * \param t String representing a set containg all trimmable characters
203  * \return A copy of the trimmed string
204  */
205  std::string lTrim( const std::string& source, const std::string& t =
206  WHITESPACE );
207 
208  /**
209  * Trims any occurence of each character given in parameter t from both
210  * ends (right and left side) of the given string.
211  *
212  * \param source String to trim
213  * \param t String representing a set containg all trimmable characters
214  * \return A copy of the trimmed string
215  */
216  std::string trim( const std::string& source, const std::string& t = WHITESPACE );
217 
218  /**
219  * Transforms all characters in the given string into upper case
220  * characters.
221  *
222  * \param source String to transpose.
223  * \return A copy of the upper case only string
224  */
225  std::string toUpper( const std::string& source );
226 
227  /**
228  * Transforms all characters in the given string into lower case
229  * characters.
230  *
231  * \param source String to transpose.
232  * \return A copy of the lower case only string
233  */
234  std::string toLower( const std::string& source );
235 
236  /**
237  * Splits the given string into a vector of strings (so called tokens).
238  *
239  * \param source String to tokenize
240  * \param compress If true, characters matching between two tokens are
241  * collapsed and handled as just one character.
242  * \param delim String representing a set containing all characters considered
243  * as whitespace.
244  * \return A vector of strings containing the tokens.
245  */
246  std::vector< std::string > tokenize( const std::string& source,
247  const std::string& delim = WHITESPACE,
248  bool compress = true );
249 
250  /**
251  * Writes every vector to an output stream such as cout, if its elements
252  * have an output operator defined.
253  *
254  * \param os The output stream where the elements are written to
255  * \param v Vector containing the elements
256  * \return The output stream again.
257  */
258  template< class T > std::ostream& operator<<( std::ostream& os, const std::vector< T >& v )
259  {
260  std::stringstream result;
261  result << "[" << std::scientific << std::setprecision( 16 );
262  std::copy( v.begin(), v.end(), std::ostream_iterator< T >( result, ", " ) );
263  os << rTrim( result.str(), ", " ) << "]";
264  return os;
265  }
266 
267  /**
268  * Write an input stream into the given vector. The delimiter is implicitly set to ", ".
269  * Also wrapping brackets '[' ']' are expected. In general this is the opposite of the
270  * output operator above.
271  * \warning The inputstream is first written into a string then the convertion into T
272  * via fromString takes place.
273  * \warning The delimiter should not be in an elements string representation since then
274  * the tokenizer may gets confused
275  *
276  * \param in Input stream
277  * \param v Vector where to store the elements.
278  *
279  * \return The input stream again
280  */
281  template< class T > std::istream& operator>>( std::istream& in, std::vector< T >& v )
282  {
283  std::string str;
284  in >> str;
285  trim( str, "[]" ); // remove preceeding and trailing brackets '[', ']' if any
286  std::vector< std::string > tokens = tokenize( str, ", " );
287  v.resize( 0 ); // clear would deallocate
288  v.reserve( tokens.size() );
289  for( size_t i = 0; i < tokens.size(); ++i )
290  {
291  v.push_back( fromString< T >( tokens[i] ) );
292  }
293  return in;
294  }
295 
296  /**
297  * Writes every list to an output stream such as cout, if its elements have
298  * an output operator defined.
299  *
300  * \param os The output stream where the elements are written to
301  * \param l List containing the elements
302  * \return The output stream again.
303  */
304  template< class T > std::ostream& operator<<( std::ostream& os, const std::list< T >& l )
305  {
306  std::stringstream result;
307  result << "<" << std::scientific;
308  std::copy( l.begin(), l.end(), std::ostream_iterator< T >( result, ", " ) );
309  os << rTrim( result.str(), ", " ) << ">";
310  return os;
311  }
312 
313  /**
314  * Writes every set to an output stream such as cout, if its elements have
315  * an output operator defined.
316  *
317  * \param os The output stream where the elements are written to
318  * \param s set containing the elements
319  * \return The output stream again.
320  */
321  template< class T > std::ostream& operator<<( std::ostream& os, const std::set< T >& s )
322  {
323  std::stringstream result;
324  result << "{" << std::scientific;
325  std::copy( s.begin(), s.end(), std::ostream_iterator< T >( result, ", " ) );
326  os << rTrim( result.str(), ", " ) << "}";
327  return os;
328  }
329 } // end of namespace
330 
331 #endif // WSTRINGUTILS_H
Indicates invalid type of something.
Definition: WTypeMismatch.h:37
Some utilities for string manipulation and output operations.
Definition: WStringUtils.h:59
std::string toLower(const std::string &source)
Transforms all characters in the given string into lower case characters.
std::ostream & operator<<(std::ostream &os, const std::vector< T > &v)
Writes every vector to an output stream such as cout, if its elements have an output operator defined...
Definition: WStringUtils.h:258
std::string toUpper(const std::string &source)
Transforms all characters in the given string into upper case characters.
std::vector< std::string > tokenize(const std::string &source, const std::string &delim=WHITESPACE, bool compress=true)
Splits the given string into a vector of strings (so called tokens).
std::istream & operator>>(std::istream &in, std::vector< T > &v)
Write an input stream into the given vector.
Definition: WStringUtils.h:281
std::string trim(const std::string &source, const std::string &t=WHITESPACE)
Trims any occurence of each character given in parameter t from both ends (right and left side) of th...
T fromString(const std::string &str)
Convert a given string to a value of a certain type.
Definition: WStringUtils.h:173
const std::string WHITESPACE
We consider the following characters as whitespace:
std::string rTrim(const std::string &source, const std::string &t=WHITESPACE)
Trims any occurence of each character given in parameter t from the end (or right side) of the given ...
std::string toString(const T &value)
Convert a given value to a string.
Definition: WStringUtils.h:120
std::string lTrim(const std::string &source, const std::string &t=WHITESPACE)
Trims any occurence of each character given in parameter t from the start (or left side) of the given...
static std::string fromString(const std::string &from)
Convert a given string to the target type.
Definition: WStringUtils.h:105
Conversion class to convert a string to a given target type.
Definition: WStringUtils.h:68
static Target fromString(const std::string &from)
Convert a given string to the target type.
Definition: WStringUtils.h:78