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