]> git.tdb.fi Git - libs/core.git/blob - source/strings/lexicalcast.h
b41654d1537a822f8a13af2d1a0616a4761d0e2f
[libs/core.git] / source / strings / lexicalcast.h
1 /* $Id$
2
3 This file is part of libmspstrings
4 Copyright © 2006-2008 Mikko Rasa
5 Distributed under the LGPL
6 */
7
8 #ifndef MSP_STRINGS_LEXICALCAST_H_
9 #define MSP_STRINGS_LEXICALCAST_H_
10
11 #include <sstream>
12 #include <string>
13 #include <stdexcept>
14 #include "fmt.h"
15
16 namespace Msp {
17
18 /**
19 Thrown for errors in lexical conversions
20 */
21 class lexical_error: public std::runtime_error
22 {
23 public:
24         lexical_error(const std::string &w): runtime_error(w) { }
25         virtual ~lexical_error() throw() { }
26 };
27
28
29 class format_mismatch: public lexical_error
30 {
31 public:
32         format_mismatch(const std::string &w): lexical_error(w) { }
33         virtual ~format_mismatch() throw() { }
34 };
35
36
37 /**
38 Helper class for lexical_cast to facilitate operator overloading.
39 */
40 class LexicalConverter
41 {
42 private:
43         Fmt fmt;
44         std::string buf;
45
46 public:
47         LexicalConverter(const Fmt &f): fmt(f) { }
48         LexicalConverter(const std::string &s, const Fmt &f): fmt(f), buf(s) { }
49
50         const Fmt &get_fmt() const { return fmt; }
51         const std::string &get() const { return buf; }
52         void result(const std::string &);
53 };
54
55
56 void operator<<(LexicalConverter &, char);
57 void operator<<(LexicalConverter &, signed char);
58 void operator<<(LexicalConverter &, short);
59 void operator<<(LexicalConverter &, int);
60 void operator<<(LexicalConverter &, long);
61 void operator<<(LexicalConverter &, unsigned char);
62 void operator<<(LexicalConverter &, unsigned short);
63 void operator<<(LexicalConverter &, unsigned);
64 void operator<<(LexicalConverter &, unsigned long);
65 #ifdef __GNUC__
66 void operator<<(LexicalConverter &, long long);
67 void operator<<(LexicalConverter &, unsigned long long);
68 #endif
69 void operator<<(LexicalConverter &, bool);
70 void operator<<(LexicalConverter &, float);
71 void operator<<(LexicalConverter &, double);
72 void operator<<(LexicalConverter &, long double);
73 void operator<<(LexicalConverter &, const std::string &);
74 void operator<<(LexicalConverter &, const char *);
75 void operator<<(LexicalConverter &, const void *);
76
77 void operator>>(const LexicalConverter &, char &);
78 void operator>>(const LexicalConverter &, signed char &);
79 void operator>>(const LexicalConverter &, short &);
80 void operator>>(const LexicalConverter &, int &);
81 void operator>>(const LexicalConverter &, long &);
82 void operator>>(const LexicalConverter &, unsigned char &);
83 void operator>>(const LexicalConverter &, unsigned short &);
84 void operator>>(const LexicalConverter &, unsigned int &);
85 void operator>>(const LexicalConverter &, unsigned long &);
86 #ifdef __GNUC__
87 void operator>>(const LexicalConverter &, long long &);
88 void operator>>(const LexicalConverter &, unsigned long long &);
89 #endif
90 void operator>>(const LexicalConverter &, bool &);
91 void operator>>(const LexicalConverter &, float &);
92 void operator>>(const LexicalConverter &, double &);
93 void operator>>(const LexicalConverter &, long double &);
94 void operator>>(const LexicalConverter &, std::string &);
95
96 // Generic operators using stringstream
97
98 template<typename T>
99 void operator<<(LexicalConverter &c, const T &v)
100 {
101         std::ostringstream ss;
102         ss<<c.get_fmt()<<v;
103         c.result(ss.str());
104 }
105
106 template<typename T>
107 void operator>>(const LexicalConverter &c, T &v)
108 {
109         std::istringstream ss(c.get());
110         ss.setf(std::ios_base::fmtflags(0), std::ios_base::skipws);
111         ss>>v;
112         if(ss.fail() || !ss.eof())
113                 throw lexical_error("conversion failure");
114 }
115
116 // The main interface to the lexical conversion machinery
117
118 template<typename T>
119 inline T lexical_cast(const std::string &s, const Fmt &f = Fmt())
120 {
121         LexicalConverter conv(s, f);
122         T result;
123         conv>>result;
124         return result;
125 }
126
127 template<typename T>
128 inline std::string lexical_cast(const T &v, const Fmt &f = Fmt())
129 {
130         LexicalConverter conv(f);
131         conv<<v;
132         return conv.get();
133 }
134
135 } // namespace Msp
136
137 #endif