00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef LEXICAL_CAST_DEBUG
00026 #undef LEXICAL_CAST_HPP_INCLUDED
00027 #endif
00028
00029 #ifndef LEXICAL_CAST_HPP_INCLUDED
00030 #define LEXICAL_CAST_HPP_INCLUDED
00031
00032 #ifdef LEXICAL_CAST_DEBUG
00033
00034 #undef DEBUG_THROW
00035
00036
00037
00038
00039
00040
00041
00042 #define DEBUG_THROW(id) throw id;
00043 #else
00044
00045 #ifdef __FreeBSD__
00046 #define __LONG_LONG_SUPPORTED
00047 #endif
00048
00049 #ifdef _MSC_VER
00050 #define strtoll _strtoi64
00051 #define strtoull _strtoui64
00052 #endif
00053
00054 #include "global.hpp"
00055
00056 #include <string>
00057 #include <sstream>
00058 #include <boost/mpl/set.hpp>
00059 #include <boost/type_traits.hpp>
00060 #include <boost/utility/enable_if.hpp>
00061
00062 #define DEBUG_THROW(id)
00063 #endif
00064
00065
00066
00067
00068
00069
00070 namespace implementation {
00071
00072 template<
00073 typename To
00074 , typename From
00075 , typename ToEnable = void
00076 , typename FromEnable = void
00077 >
00078 struct tlexical_cast;
00079
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 template<typename To, typename From>
00093 inline To lexical_cast(From value)
00094 {
00095 return implementation::tlexical_cast<To, From>().operator()(value);
00096 }
00097
00098
00099 struct bad_lexical_cast {};
00100
00101 namespace implementation {
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 template<
00115 typename To
00116 , typename From
00117 , typename ToEnable
00118 , typename FromEnable
00119 >
00120 struct tlexical_cast
00121 {
00122 To operator()(From value)
00123 {
00124 DEBUG_THROW("generic");
00125
00126 To result;
00127 std::stringstream sstr;
00128
00129 if(!(sstr << value && sstr >> result)) {
00130 throw bad_lexical_cast();
00131 } else {
00132 return result;
00133 }
00134 }
00135 };
00136
00137
00138
00139
00140
00141
00142
00143 template <typename From>
00144 struct tlexical_cast<
00145 std::string
00146 , From
00147 , void
00148 , typename boost::enable_if<boost::is_integral<
00149 typename boost::remove_pointer<From>::type> >::type
00150 >
00151 {
00152 std::string operator()(From value)
00153 {
00154 DEBUG_THROW("specialized - To std::string - From integral (pointer)");
00155
00156 std::stringstream sstr;
00157 sstr << value;
00158 return sstr.str();
00159 }
00160 };
00161
00162
00163
00164
00165
00166
00167
00168
00169 template <class From>
00170 struct tlexical_cast<
00171 long long
00172 , From
00173 , void
00174 , typename boost::enable_if<boost::mpl::has_key<boost::mpl::set<
00175 char*, const char*> , From> >::type
00176 >
00177 {
00178 long long operator()(From value)
00179 {
00180 DEBUG_THROW("specialized - To long long - From (const) char*");
00181
00182 char* endptr;
00183 int res = strtoll(value, &endptr, 10);
00184
00185 if (*value == '\0' || *endptr != '\0') {
00186 throw bad_lexical_cast();
00187 } else {
00188 return res;
00189 }
00190 }
00191 };
00192
00193
00194
00195
00196
00197
00198
00199
00200 template <>
00201 struct tlexical_cast<
00202 long long
00203 , std::string
00204 >
00205 {
00206 long long operator()(const std::string& value)
00207 {
00208 DEBUG_THROW("specialized - To long long - From std::string");
00209
00210 return lexical_cast<long long>(value.c_str());
00211 }
00212 };
00213
00214
00215
00216
00217
00218
00219 template <class To, class From>
00220 struct tlexical_cast<
00221 To
00222 , From
00223 , typename boost::enable_if<boost::is_signed<To> >::type
00224 , typename boost::enable_if<boost::mpl::has_key<boost::mpl::set<
00225 char*, const char*> , From> >::type
00226 >
00227 {
00228 To operator()(From value)
00229 {
00230 DEBUG_THROW("specialized - To signed - From (const) char*");
00231
00232 char* endptr;
00233 int res = strtol(value, &endptr, 10);
00234
00235 if (*value == '\0' || *endptr != '\0') {
00236 throw bad_lexical_cast();
00237 } else {
00238 return res;
00239 }
00240 }
00241 };
00242
00243
00244
00245
00246
00247
00248 template <class To>
00249 struct tlexical_cast<
00250 To
00251 , std::string
00252 , typename boost::enable_if<boost::is_signed<To> >::type
00253 >
00254 {
00255 To operator()(const std::string& value)
00256 {
00257 DEBUG_THROW("specialized - To signed - From std::string");
00258
00259 return lexical_cast<To>(value.c_str());
00260 }
00261 };
00262
00263
00264
00265
00266
00267
00268
00269
00270 template <class From>
00271 struct tlexical_cast<
00272 unsigned long long
00273 , From
00274 , void
00275 , typename boost::enable_if<boost::mpl::has_key<boost::mpl::set<
00276 char*, const char*> , From> >::type
00277 >
00278 {
00279 long long operator()(From value)
00280 {
00281 DEBUG_THROW(
00282 "specialized - To unsigned long long - From (const) char*");
00283
00284 char* endptr;
00285 int res = strtoull(value, &endptr, 10);
00286
00287 if (*value == '\0' || *endptr != '\0') {
00288 throw bad_lexical_cast();
00289 } else {
00290 return res;
00291 }
00292 }
00293 };
00294
00295
00296
00297
00298
00299
00300
00301
00302 template <>
00303 struct tlexical_cast<
00304 unsigned long long
00305 , std::string
00306 >
00307 {
00308 long long operator()(const std::string& value)
00309 {
00310 DEBUG_THROW("specialized - To unsigned long long - From std::string");
00311
00312 return lexical_cast<unsigned long long>(value.c_str());
00313 }
00314 };
00315
00316
00317
00318
00319
00320
00321 template <class To, class From>
00322 struct tlexical_cast<
00323 To
00324 , From
00325 , typename boost::enable_if<boost::is_unsigned<To> >::type
00326 , typename boost::enable_if<boost::mpl::has_key<boost::mpl::set<
00327 char*, const char*> , From> >::type
00328 >
00329 {
00330 To operator()(From value)
00331 {
00332 DEBUG_THROW("specialized - To unsigned - From (const) char*");
00333
00334 char* endptr;
00335 int res = strtoul(value, &endptr, 10);
00336
00337 if (*value == '\0' || *endptr != '\0') {
00338 throw bad_lexical_cast();
00339 } else {
00340 return res;
00341 }
00342 }
00343 };
00344
00345
00346
00347
00348
00349
00350 template <class To>
00351 struct tlexical_cast<
00352 To
00353 , std::string
00354 , typename boost::enable_if<boost::is_unsigned<To> >::type
00355 >
00356 {
00357 To operator()(const std::string& value)
00358 {
00359 DEBUG_THROW("specialized - To unsigned - From std::string");
00360
00361 return lexical_cast<To>(value.c_str());
00362 }
00363 };
00364
00365 }
00366
00367 #endif
00368