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