1 // Copyright Douglas Gregor 2002-2004. Use, modification and
2 // distribution is subject to the Boost Software License, Version
3 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #include <boost/logic/tribool.hpp>
6 #include <boost/logic/tribool_io.hpp>
7 #include <boost/test/minimal.hpp>
8 #include <sstream>
9 #include <string>
10 #include <iostream>
11 #include <ios>     // for std::boolalpha
12 
13 #ifndef BOOST_NO_STD_LOCALE
14 #  include <locale>
15 #endif
16 
test_main(int,char * [])17 int test_main(int, char*[])
18 {
19   using namespace boost::logic;
20 
21   tribool x;
22 
23   #if !defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_STD_WSTRING)
24   std::wostringstream wout;
25   wout << std::boolalpha << tribool(false);
26   BOOST_CHECK(wout.str() == L"false");
27   wout.str(std::wstring());
28   wout << std::boolalpha << tribool(true);
29   BOOST_CHECK(wout.str() == L"true");
30   wout.str(std::wstring());
31   wout << std::boolalpha << tribool(indeterminate);
32   BOOST_CHECK(wout.str() == L"indeterminate");
33   #endif
34 
35   // Check tribool output
36   std::ostringstream out;
37 
38   // Output false (noboolalpha)
39   out.str(std::string());
40   x = false;
41   out << x;
42   std::cout << "Output false (noboolalpha): " << out.str() << std::endl;
43   BOOST_CHECK(out.str() == "0");
44 
45   // Output true (noboolalpha)
46   out.str(std::string());
47   x = true;
48   out << x;
49   std::cout << "Output true (noboolalpha): " << out.str() << std::endl;
50   BOOST_CHECK(out.str() == "1");
51 
52   // Output indeterminate (noboolalpha)
53   out.str(std::string());
54   x = indeterminate;
55   out << x;
56   std::cout << "Output indeterminate (noboolalpha): " << out.str()
57             << std::endl;
58   BOOST_CHECK(out.str() == "2");
59 
60   // Output indeterminate (noboolalpha)
61   out.str(std::string());
62   out << indeterminate;
63   std::cout << "Output indeterminate (noboolalpha): " << out.str()
64             << std::endl;
65   BOOST_CHECK(out.str() == "2");
66 
67 #ifndef BOOST_NO_STD_LOCALE
68   const std::numpunct<char>& punct =
69     BOOST_USE_FACET(std::numpunct<char>, out.getloc());
70 
71   // Output false (boolalpha)
72   out.str(std::string());
73   x = false;
74   out << std::boolalpha << x;
75   std::cout << "Output false (boolalpha): " << out.str() << std::endl;
76   BOOST_CHECK(out.str() == punct.falsename());
77 
78   // Output true (boolalpha)
79   out.str(std::string());
80   x = true;
81   out << std::boolalpha << x;
82   std::cout << "Output true (boolalpha): " << out.str() << std::endl;
83 
84   BOOST_CHECK(out.str() == punct.truename());
85 
86   // Output indeterminate (boolalpha - default name)
87   out.str(std::string());
88   x = indeterminate;
89   out << std::boolalpha << x;
90   std::cout << "Output indeterminate (boolalpha - default name): " << out.str()
91             << std::endl;
92   BOOST_CHECK(out.str() == "indeterminate");
93 
94   // Output indeterminate (boolalpha - default name)
95   out.str(std::string());
96   out << std::boolalpha << indeterminate;
97   std::cout << "Output indeterminate (boolalpha - default name): " << out.str()
98             << std::endl;
99   BOOST_CHECK(out.str() == "indeterminate");
100 
101 #  if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
102   // No template constructors, so we can't build the test locale
103 #  else
104   // Give indeterminate a new name, and output it via boolalpha
105   std::locale global;
106   std::locale test_locale(global, new indeterminate_name<char>("maybe"));
107   out.imbue(test_locale);
108   out.str(std::string());
109   out << std::boolalpha << x;
110   std::cout << "Output indeterminate (boolalpha - \"maybe\"): " << out.str()
111             << std::endl;
112   BOOST_CHECK(out.str() == "maybe");
113 #  endif
114 #endif // ! BOOST_NO_STD_LOCALE
115 
116   // Checking tribool input
117 
118   // Input false (noboolalpha)
119   {
120     std::istringstream in("0");
121     std::cout << "Input \"0\" (checks for false)" << std::endl;
122     in >> x;
123     BOOST_CHECK(x == false);
124   }
125 
126   // Input true (noboolalpha)
127   {
128     std::istringstream in("1");
129     std::cout << "Input \"1\" (checks for true)" << std::endl;
130     in >> x;
131     BOOST_CHECK(x == true);
132   }
133 
134   // Input false (noboolalpha)
135   {
136     std::istringstream in("2");
137     std::cout << "Input \"2\" (checks for indeterminate)" << std::endl;
138     in >> x;
139     BOOST_CHECK(indeterminate(x));
140   }
141 
142   // Input bad number (noboolalpha)
143   {
144     std::istringstream in("3");
145     std::cout << "Input \"3\" (checks for failure)" << std::endl;
146     BOOST_CHECK(!(in >> x));
147   }
148 
149   // Input false (boolalpha)
150   {
151     std::istringstream in("false");
152     std::cout << "Input \"false\" (checks for false)" << std::endl;
153     in >> std::boolalpha >> x;
154     BOOST_CHECK(x == false);
155   }
156 
157   // Input true (boolalpha)
158   {
159     std::istringstream in("true");
160     std::cout << "Input \"true\" (checks for true)" << std::endl;
161     in >> std::boolalpha >> x;
162     BOOST_CHECK(x == true);
163   }
164 
165   // Input indeterminate (boolalpha)
166   {
167     std::istringstream in("indeterminate");
168     std::cout << "Input \"indeterminate\" (checks for indeterminate)"
169               << std::endl;
170     in >> std::boolalpha >> x;
171     BOOST_CHECK(indeterminate(x));
172   }
173 
174   // Input bad string (boolalpha)
175   {
176     std::istringstream in("bad");
177     std::cout << "Input \"bad\" (checks for failure)"
178               << std::endl;
179     BOOST_CHECK(!(in >> std::boolalpha >> x));
180   }
181 
182 #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
183   // No template constructors, so we can't build the test locale
184 #elif !defined(BOOST_NO_STD_LOCALE)
185 
186   // Input indeterminate named "maybe" (boolalpha)
187   {
188     std::istringstream in("maybe");
189     in.imbue(test_locale);
190     std::cout << "Input \"maybe\" (checks for indeterminate, uses locales)"
191               << std::endl;
192     in >> std::boolalpha >> x;
193     BOOST_CHECK(indeterminate(x));
194   }
195 
196   // Input indeterminate named "true_or_false" (boolalpha)
197   {
198     std::locale my_locale(global,
199                           new indeterminate_name<char>("true_or_false"));
200     std::istringstream in("true_or_false");
201     in.imbue(my_locale);
202     std::cout << "Input \"true_or_false\" (checks for indeterminate)"
203               << std::endl;
204     in >> std::boolalpha >> x;
205     BOOST_CHECK(indeterminate(x));
206   }
207 #endif
208 
209   return 0;
210 }
211