convert.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004,2006 Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 
30 #ifndef TNT_CONVERT_H
31 #define TNT_CONVERT_H
32 
33 #include <sstream>
34 #include <stdexcept>
35 #include <locale>
36 #include <cxxtools/convert.h>
37 
38 namespace tnt
39 {
40  class ConversionError : public std::runtime_error
41  {
42  explicit ConversionError(const std::string& msg);
43 
44  public:
45  static void doThrow(const char* argname, const char* typeto, const std::string& value);
46  };
47 
48  template <typename T>
49  inline std::string toString(const T& value)
50  {
51  std::ostringstream s;
52  s << value;
53  return s.str();
54  }
55 
56  template <typename T>
57  inline std::string toString(const T& value, const std::locale& loc)
58  {
59  std::ostringstream s;
60  s.imbue(loc);
61  s << value;
62  return s.str();
63  }
64 
65  template <>
66  inline std::string toString(const std::string& value)
67  { return value; }
68 
69  template <>
70  inline std::string toString(const std::string& value, const std::locale&)
71  { return value; }
72 
73  inline std::string toString(const char* value)
74  { return std::string(value); }
75 
76  inline std::string toString(const char* value, const std::locale&)
77  { return std::string(value); }
78 
79  inline std::string toString(char value)
80  { return std::string(1, value); }
81 
82  inline std::string toString(char value, const std::locale&)
83  { return std::string(1, value); }
84 
85  inline std::string toString(bool value)
86  {
87  static const std::string trueValue = "1";
88  return value ? trueValue : std::string();
89  }
90 
91  inline std::string toString(bool value, const std::locale&)
92  { return toString(value); }
93 
94  // convert std::string to some type
95 
96  template <typename T>
97  inline T stringTo(const char* argname, const char* typeto, const std::string& value)
98  {
99  T ret;
100  std::istringstream s(value);
101  s >> ret;
102  if (!s)
103  ConversionError::doThrow(argname, typeto, value);
104  return ret;
105  }
106 
107  template <typename T>
108  inline T stringTo(const char* argname, const char* typeto, const std::string& value, const std::locale& loc)
109  {
110  T ret;
111  std::istringstream s(value);
112  s.imbue(loc);
113  s >> ret;
114  if (!s)
115  ConversionError::doThrow(argname, typeto, value);
116  return ret;
117  }
118 
119  template <typename T>
120  inline T stringToWithDefault(const std::string& value, const T& def)
121  {
122  try
123  {
124  return cxxtools::convert<T>(value);
125  }
126  catch (const cxxtools::ConversionError&)
127  {
128  return def;
129  }
130  }
131 
132  template <typename T>
133  inline T stringToWithDefault(const std::string& value, const T& def, const std::locale& loc)
134  {
135  T ret;
136  std::istringstream s(value);
137  s.imbue(loc);
138  s >> ret;
139  if (!s)
140  return def;
141  return ret;
142  }
143 
144  // specializations
145 
146  template <>
147  inline std::string stringTo<std::string>(const char* /*argname*/, const char* /*typeto*/, const std::string& value)
148  { return value; }
149 
150  template <>
151  inline std::string stringTo<std::string>(const char* /*argname*/, const char* /*typeto*/, const std::string& value, const std::locale&)
152  { return value; }
153 
154  template <>
155  inline char stringTo<char>(const char* argname, const char* typeto, const std::string& value)
156  {
157  if (value.empty())
158  ConversionError::doThrow(argname, typeto, value);
159  return value[0];
160  }
161 
162  template <>
163  inline char stringTo<char>(const char* argname, const char* typeto, const std::string& value, const std::locale&)
164  { return stringTo<char>(argname, typeto, value); }
165 
166  template <>
167  inline bool stringTo<bool>(const char* /*argname*/, const char* /*typeto*/, const std::string& value)
168  {
169  // consider empty value as false
170  return !value.empty();
171  }
172 
173  template <>
174  inline bool stringTo<bool>(const char* /*argname*/, const char* /*typeto*/, const std::string& value, const std::locale&)
175  { return stringTo<bool>(0, 0, value); }
176 
177  template <>
178  inline std::string stringToWithDefault<std::string>(const std::string& value, const std::string&)
179  { return value; }
180 
181  template <>
182  inline std::string stringToWithDefault<std::string>(const std::string& value, const std::string&, const std::locale&)
183  { return value; }
184 
185  template <>
186  inline char stringToWithDefault<char>(const std::string& value, const char& def)
187  { return value.empty() ? def : value[0]; }
188 
189  template <>
190  inline char stringToWithDefault<char>(const std::string& value, const char& def, const std::locale&)
191  { return value.empty() ? def : value[0]; }
192 
193  template <>
194  inline bool stringToWithDefault<bool>(const std::string& value, const bool& def)
195  {
196  return value.empty() ? def
197  : stringTo<bool>(0, 0, value);
198  }
199 
200  template <>
201  inline bool stringToWithDefault<bool>(const std::string& value, const bool& def, const std::locale&)
202  { return stringToWithDefault<bool>(value, def); }
203 
204  template <typename iteratorType, typename vectorType>
205  void convertRange(const char* argname, const char* typeto, iteratorType b, iteratorType e, vectorType& v, const std::locale& l)
206  {
207  for (iteratorType it = b; it != e; ++it)
208  v.push_back(stringTo<typename vectorType::value_type>(argname, typeto, *it, l));
209  }
210 
211 }
212 
213 #endif // TNT_CONVERT_H
214