]> git.lyx.org Git - lyx.git/blob - boost/boost/lexical_cast.hpp
135ef0789585b5b1663815c8211641001a3df260
[lyx.git] / boost / boost / lexical_cast.hpp
1 #ifndef BOOST_LEXICAL_CAST_INCLUDED
2 #define BOOST_LEXICAL_CAST_INCLUDED
3
4 // Boost lexical_cast.hpp header  -------------------------------------------//
5 //
6 // See http://www.boost.org for most recent version including documentation.
7 // See end of this header for rights and permissions.
8 //
9 // what:  lexical_cast custom keyword cast
10 // who:   contributed by Kevlin Henney,
11 //        enhanced with contributions from Terje Slettebø,
12 //        with additional fixes and suggestions from Gennaro Prota,
13 //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
14 //        and other Boosters
15 // when:  November 2000, March 2003
16
17 #include <string>
18 #include <typeinfo>
19 #include <boost/config.hpp>
20 #include <boost/limits.hpp>
21 #include <boost/throw_exception.hpp>
22 #include <boost/type_traits/is_pointer.hpp>
23
24 #ifdef BOOST_NO_STRINGSTREAM
25 #include <strstream>
26 #else
27 #include <sstream>
28 #endif
29
30 #if defined(BOOST_NO_STRINGSTREAM) || \
31     defined(BOOST_NO_STD_WSTRING) || \
32     defined(BOOST_NO_STD_LOCALE) || \
33     defined(BOOST_NO_INTRINSIC_WCHAR_T)
34 #define DISABLE_WIDE_CHAR_SUPPORT
35 #endif
36
37 namespace boost
38 {
39     // exception used to indicate runtime lexical_cast failure
40     class bad_lexical_cast : public std::bad_cast
41     {
42     public:
43         bad_lexical_cast() :
44         source(&typeid(void)), target(&typeid(void))
45         {
46         }
47         bad_lexical_cast(
48             const std::type_info &s,
49             const std::type_info &t) :
50             source(&s), target(&t)
51         {
52         }
53         const std::type_info &source_type() const
54         {
55             return *source;
56         }
57         const std::type_info &target_type() const
58         {
59             return *target;
60         }
61         virtual const char *what() const throw()
62         {
63             return "bad lexical cast: "
64                    "source type value could not be interpreted as target";
65         }
66         virtual ~bad_lexical_cast() throw()
67         {
68         }
69     private:
70         const std::type_info *source;
71         const std::type_info *target;
72     };
73
74     namespace detail // selectors for choosing stream character type
75     {
76         template<typename Type>
77         struct stream_char
78         {
79             typedef char type;
80         };
81
82         #ifndef DISABLE_WIDE_CHAR_SUPPORT
83         template<>
84         struct stream_char<wchar_t>
85         {
86             typedef wchar_t type;
87         };
88
89         template<>
90         struct stream_char<wchar_t *>
91         {
92             typedef wchar_t type;
93         };
94
95         template<>
96         struct stream_char<const wchar_t *>
97         {
98             typedef wchar_t type;
99         };
100
101         template<>
102         struct stream_char<std::wstring>
103         {
104             typedef wchar_t type;
105         };
106         #endif
107
108         template<typename TargetChar, typename SourceChar>
109         struct widest_char
110         {
111             typedef TargetChar type;
112         };
113
114         template<>
115         struct widest_char<char, wchar_t>
116         {
117             typedef wchar_t type;
118         };
119     }
120     
121     namespace detail // stream wrapper for handling lexical conversions
122     {
123         template<typename Target, typename Source>
124         class lexical_stream
125         {
126         public:
127             lexical_stream()
128             {
129                 stream.unsetf(std::ios::skipws);
130
131                 if(std::numeric_limits<Target>::is_specialized)
132                     stream.precision(std::numeric_limits<Target>::digits10 + 1);
133                 else if(std::numeric_limits<Source>::is_specialized)
134                     stream.precision(std::numeric_limits<Source>::digits10 + 1);
135             }
136             ~lexical_stream()
137             {
138                 #if defined(BOOST_NO_STRINGSTREAM)
139                 stream.freeze(false);
140                 #endif
141             }
142             bool operator<<(const Source &input)
143             {
144                 return !(stream << input).fail();
145             }
146             template<typename InputStreamable>
147             bool operator>>(InputStreamable &output)
148             {
149                 return !is_pointer<InputStreamable>::value &&
150                        stream >> output &&
151                        (stream >> std::ws).eof();
152             }
153             bool operator>>(std::string &output)
154             {
155                 #if defined(BOOST_NO_STRINGSTREAM)
156                 stream << '\0';
157                 #endif
158                 output = stream.str();
159                 return true;
160             }
161             #ifndef DISABLE_WIDE_CHAR_SUPPORT
162             bool operator>>(std::wstring &output)
163             {
164                 output = stream.str();
165                 return true;
166             }
167             #endif
168         private:
169             typedef typename widest_char<
170                 typename stream_char<Target>::type,
171                 typename stream_char<Source>::type>::type char_type;
172
173             #if defined(BOOST_NO_STRINGSTREAM)
174             std::strstream stream;
175             #elif defined(BOOST_NO_STD_LOCALE)
176             std::stringstream stream;
177             #else
178             std::basic_stringstream<char_type> stream;
179             #endif
180         };
181     }
182
183     template<typename Target, typename Source>
184     Target lexical_cast(Source arg)
185     {
186         detail::lexical_stream<Target, Source> interpreter;
187         Target result;
188
189         if(!(interpreter << arg && interpreter >> result))
190             throw_exception(bad_lexical_cast(typeid(Target), typeid(Source)));
191         return result;
192     }
193 }
194
195 // Copyright Kevlin Henney, 2000-2003. All rights reserved.
196 //
197 // Permission to use, copy, modify, and distribute this software for any
198 // purpose is hereby granted without fee, provided that this copyright and
199 // permissions notice appear in all copies and derivatives.
200 //
201 // This software is provided "as is" without express or implied warranty.
202
203 #undef DISABLE_WIDE_CHAR_SUPPORT
204 #endif
205