Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/logic/tribool_io.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Three-state boolean logic library | |
2 | |
3 // Copyright Douglas Gregor 2002-2004. Use, modification and | |
4 // distribution is subject to the Boost Software License, Version | |
5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
6 // http://www.boost.org/LICENSE_1_0.txt) | |
7 #ifndef BOOST_LOGIC_TRIBOOL_IO_HPP | |
8 #define BOOST_LOGIC_TRIBOOL_IO_HPP | |
9 | |
10 #include <boost/logic/tribool.hpp> | |
11 #include <boost/detail/workaround.hpp> | |
12 #include <boost/noncopyable.hpp> | |
13 | |
14 #if BOOST_WORKAROUND(_MSC_VER, >= 1200) | |
15 # pragma once | |
16 #endif | |
17 | |
18 #ifndef BOOST_NO_STD_LOCALE | |
19 # include <locale> | |
20 #endif | |
21 | |
22 #include <string> | |
23 #include <iostream> | |
24 | |
25 namespace boost { namespace logic { | |
26 | |
27 #ifdef BOOST_NO_STD_LOCALE | |
28 | |
29 /** | |
30 * \brief Returns a string containing the default name for the \c | |
31 * false value of a tribool with the given character type T. | |
32 * | |
33 * This function only exists when the C++ standard library | |
34 * implementation does not support locales. | |
35 */ | |
36 template<typename T> std::basic_string<T> default_false_name(); | |
37 | |
38 /** | |
39 * \brief Returns the character string "false". | |
40 * | |
41 * This function only exists when the C++ standard library | |
42 * implementation does not support locales. | |
43 */ | |
44 template<> | |
45 inline std::basic_string<char> default_false_name<char>() | |
46 { return "false"; } | |
47 | |
48 # ifndef BOOST_NO_WCHAR_T | |
49 /** | |
50 * \brief Returns the wide character string L"false". | |
51 * | |
52 * This function only exists when the C++ standard library | |
53 * implementation does not support locales. | |
54 */ | |
55 template<> | |
56 inline std::basic_string<wchar_t> default_false_name<wchar_t>() | |
57 { return L"false"; } | |
58 # endif | |
59 | |
60 /** | |
61 * \brief Returns a string containing the default name for the \c true | |
62 * value of a tribool with the given character type T. | |
63 * | |
64 * This function only exists when the C++ standard library | |
65 * implementation does not support locales. | |
66 */ | |
67 template<typename T> std::basic_string<T> default_true_name(); | |
68 | |
69 /** | |
70 * \brief Returns the character string "true". | |
71 * | |
72 * This function only exists when the C++ standard library | |
73 * implementation does not support locales. | |
74 */ | |
75 template<> | |
76 inline std::basic_string<char> default_true_name<char>() | |
77 { return "true"; } | |
78 | |
79 # ifndef BOOST_NO_WCHAR_T | |
80 /** | |
81 * \brief Returns the wide character string L"true". | |
82 * | |
83 * This function only exists * when the C++ standard library | |
84 * implementation does not support * locales. | |
85 */ | |
86 template<> | |
87 inline std::basic_string<wchar_t> default_true_name<wchar_t>() | |
88 { return L"true"; } | |
89 # endif | |
90 #endif | |
91 | |
92 /** | |
93 * \brief Returns a string containing the default name for the indeterminate | |
94 * value of a tribool with the given character type T. | |
95 * | |
96 * This routine is used by the input and output streaming operators | |
97 * for tribool when there is no locale support or the stream's locale | |
98 * does not contain the indeterminate_name facet. | |
99 */ | |
100 template<typename T> std::basic_string<T> get_default_indeterminate_name(); | |
101 | |
102 /// Returns the character string "indeterminate". | |
103 template<> | |
104 inline std::basic_string<char> get_default_indeterminate_name<char>() | |
105 { return "indeterminate"; } | |
106 | |
107 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) | |
108 // VC++ 6.0 chokes on the specialization below, so we're stuck without | |
109 // wchar_t support. What a pain. TODO: it might just need a the template | |
110 // parameter as function parameter... | |
111 #else | |
112 # ifndef BOOST_NO_WCHAR_T | |
113 /// Returns the wide character string L"indeterminate". | |
114 template<> | |
115 inline std::basic_string<wchar_t> get_default_indeterminate_name<wchar_t>() | |
116 { return L"indeterminate"; } | |
117 # endif | |
118 #endif | |
119 | |
120 // http://www.cantrip.org/locale.html | |
121 | |
122 #ifndef BOOST_NO_STD_LOCALE | |
123 /** | |
124 * \brief A locale facet specifying the name of the indeterminate | |
125 * value of a tribool. | |
126 * | |
127 * The facet is used to perform I/O on tribool values when \c | |
128 * std::boolalpha has been specified. This class template is only | |
129 * available if the C++ standard library implementation supports | |
130 * locales. | |
131 */ | |
132 template<typename CharT> | |
133 class indeterminate_name : public std::locale::facet, private boost::noncopyable | |
134 { | |
135 public: | |
136 typedef CharT char_type; | |
137 typedef std::basic_string<CharT> string_type; | |
138 | |
139 /// Construct the facet with the default name | |
140 indeterminate_name() : name_(get_default_indeterminate_name<CharT>()) {} | |
141 | |
142 /// Construct the facet with the given name for the indeterminate value | |
143 explicit indeterminate_name(const string_type& initial_name) | |
144 : name_(initial_name) {} | |
145 | |
146 /// Returns the name for the indeterminate value | |
147 string_type name() const { return name_; } | |
148 | |
149 /// Uniquily identifies this facet with the locale. | |
150 static std::locale::id id; | |
151 | |
152 private: | |
153 string_type name_; | |
154 }; | |
155 | |
156 template<typename CharT> std::locale::id indeterminate_name<CharT>::id; | |
157 #endif | |
158 | |
159 /** | |
160 * \brief Writes the value of a tribool to a stream. | |
161 * | |
162 * When the value of @p x is either \c true or \c false, this routine | |
163 * is semantically equivalent to: | |
164 * \code out << static_cast<bool>(x); \endcode | |
165 * | |
166 * When @p x has an indeterminate value, it outputs either the integer | |
167 * value 2 (if <tt>(out.flags() & std::ios_base::boolalpha) == 0</tt>) | |
168 * or the name of the indeterminate value. The name of the | |
169 * indeterminate value comes from the indeterminate_name facet (if it | |
170 * is defined in the output stream's locale), or from the | |
171 * get_default_indeterminate_name function (if it is not defined in the | |
172 * locale or if the C++ standard library implementation does not | |
173 * support locales). | |
174 * | |
175 * \returns @p out | |
176 */ | |
177 template<typename CharT, typename Traits> | |
178 inline std::basic_ostream<CharT, Traits>& | |
179 operator<<(std::basic_ostream<CharT, Traits>& out, tribool x) | |
180 { | |
181 if (!indeterminate(x)) { | |
182 out << static_cast<bool>(x); | |
183 } else { | |
184 typename std::basic_ostream<CharT, Traits>::sentry cerberus(out); | |
185 if (cerberus) { | |
186 if (out.flags() & std::ios_base::boolalpha) { | |
187 #ifndef BOOST_NO_STD_LOCALE | |
188 if (BOOST_HAS_FACET(indeterminate_name<CharT>, out.getloc())) { | |
189 const indeterminate_name<CharT>& facet = | |
190 BOOST_USE_FACET(indeterminate_name<CharT>, out.getloc()); | |
191 out << facet.name(); | |
192 } else { | |
193 out << get_default_indeterminate_name<CharT>(); | |
194 } | |
195 #else | |
196 out << get_default_indeterminate_name<CharT>(); | |
197 #endif | |
198 } | |
199 else | |
200 out << 2; | |
201 } | |
202 } | |
203 return out; | |
204 } | |
205 | |
206 /** | |
207 * \brief Writes the indeterminate tribool value to a stream. | |
208 * | |
209 * This routine outputs either the integer | |
210 * value 2 (if <tt>(out.flags() & std::ios_base::boolalpha) == 0</tt>) | |
211 * or the name of the indeterminate value. The name of the | |
212 * indeterminate value comes from the indeterminate_name facet (if it | |
213 * is defined in the output stream's locale), or from the | |
214 * get_default_indeterminate_name function (if it is not defined in the | |
215 * locale or if the C++ standard library implementation does not | |
216 * support locales). | |
217 * | |
218 * \returns @p out | |
219 */ | |
220 template<typename CharT, typename Traits> | |
221 inline std::basic_ostream<CharT, Traits>& | |
222 operator<<(std::basic_ostream<CharT, Traits>& out, | |
223 bool (*)(tribool, detail::indeterminate_t)) | |
224 { return out << tribool(indeterminate); } | |
225 | |
226 /** | |
227 * \brief Reads a tribool value from a stream. | |
228 * | |
229 * When <tt>(out.flags() & std::ios_base::boolalpha) == 0</tt>, this | |
230 * function reads a \c long value from the input stream @p in and | |
231 * converts that value to a tribool. If that value is 0, @p x becomes | |
232 * \c false; if it is 1, @p x becomes \c true; if it is 2, @p becomes | |
233 * \c indetermine; otherwise, the operation fails (and the fail bit is | |
234 * set on the input stream @p in). | |
235 * | |
236 * When <tt>(out.flags() & std::ios_base::boolalpha) != 0</tt>, this | |
237 * function first determines the names of the false, true, and | |
238 * indeterminate values. The false and true names are extracted from | |
239 * the \c std::numpunct facet of the input stream's locale (if the C++ | |
240 * standard library implementation supports locales), or from the \c | |
241 * default_false_name and \c default_true_name functions (if there is | |
242 * no locale support). The indeterminate name is extracted from the | |
243 * appropriate \c indeterminate_name facet (if it is available in the | |
244 * input stream's locale), or from the \c get_default_indeterminate_name | |
245 * function (if the C++ standard library implementation does not | |
246 * support locales, or the \c indeterminate_name facet is not | |
247 * specified for this locale object). The input is then matched to | |
248 * each of these names, and the tribool @p x is assigned the value | |
249 * corresponding to the longest name that matched. If no name is | |
250 * matched or all names are empty, the operation fails (and the fail | |
251 * bit is set on the input stream @p in). | |
252 * | |
253 * \returns @p in | |
254 */ | |
255 template<typename CharT, typename Traits> | |
256 inline std::basic_istream<CharT, Traits>& | |
257 operator>>(std::basic_istream<CharT, Traits>& in, tribool& x) | |
258 { | |
259 if (in.flags() & std::ios_base::boolalpha) { | |
260 typename std::basic_istream<CharT, Traits>::sentry cerberus(in); | |
261 if (cerberus) { | |
262 typedef std::basic_string<CharT> string_type; | |
263 | |
264 #ifndef BOOST_NO_STD_LOCALE | |
265 const std::numpunct<CharT>& numpunct_facet = | |
266 BOOST_USE_FACET(std::numpunct<CharT>, in.getloc()); | |
267 | |
268 string_type falsename = numpunct_facet.falsename(); | |
269 string_type truename = numpunct_facet.truename(); | |
270 | |
271 string_type othername; | |
272 if (BOOST_HAS_FACET(indeterminate_name<CharT>, in.getloc())) { | |
273 othername = | |
274 BOOST_USE_FACET(indeterminate_name<CharT>, in.getloc()).name(); | |
275 } else { | |
276 othername = get_default_indeterminate_name<CharT>(); | |
277 } | |
278 #else | |
279 string_type falsename = default_false_name<CharT>(); | |
280 string_type truename = default_true_name<CharT>(); | |
281 string_type othername = get_default_indeterminate_name<CharT>(); | |
282 #endif | |
283 | |
284 typename string_type::size_type pos = 0; | |
285 bool falsename_ok = true, truename_ok = true, othername_ok = true; | |
286 | |
287 // Modeled after the code from Library DR 17 | |
288 while (falsename_ok && pos < falsename.size() | |
289 || truename_ok && pos < truename.size() | |
290 || othername_ok && pos < othername.size()) { | |
291 typename Traits::int_type c = in.get(); | |
292 if (c == Traits::eof()) | |
293 return in; | |
294 | |
295 bool matched = false; | |
296 if (falsename_ok && pos < falsename.size()) { | |
297 if (Traits::eq(Traits::to_char_type(c), falsename[pos])) | |
298 matched = true; | |
299 else | |
300 falsename_ok = false; | |
301 } | |
302 | |
303 if (truename_ok && pos < truename.size()) { | |
304 if (Traits::eq(Traits::to_char_type(c), truename[pos])) | |
305 matched = true; | |
306 else | |
307 truename_ok = false; | |
308 } | |
309 | |
310 if (othername_ok && pos < othername.size()) { | |
311 if (Traits::eq(Traits::to_char_type(c), othername[pos])) | |
312 matched = true; | |
313 else | |
314 othername_ok = false; | |
315 } | |
316 | |
317 if (matched) { ++pos; } | |
318 if (pos > falsename.size()) falsename_ok = false; | |
319 if (pos > truename.size()) truename_ok = false; | |
320 if (pos > othername.size()) othername_ok = false; | |
321 } | |
322 | |
323 if (pos == 0) | |
324 in.setstate(std::ios_base::failbit); | |
325 else { | |
326 if (falsename_ok) x = false; | |
327 else if (truename_ok) x = true; | |
328 else if (othername_ok) x = indeterminate; | |
329 else in.setstate(std::ios_base::failbit); | |
330 } | |
331 } | |
332 } else { | |
333 long value; | |
334 if (in >> value) { | |
335 switch (value) { | |
336 case 0: x = false; break; | |
337 case 1: x = true; break; | |
338 case 2: x = indeterminate; break; | |
339 default: in.setstate(std::ios_base::failbit); break; | |
340 } | |
341 } | |
342 } | |
343 | |
344 return in; | |
345 } | |
346 | |
347 } } // end namespace boost::logic | |
348 | |
349 #endif // BOOST_LOGIC_TRIBOOL_IO_HPP |