1 // -----------------------------------------------------------
2 // Copyright (c) 2001 Jeremy Siek
3 // Copyright (c) 2003-2006 Gennaro Prota
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
9 // -----------------------------------------------------------
13 #include <cstddef> // for std::size_t
14 #include <stdexcept> // for std::logic_error
17 #include "boost/config.hpp"
18 #if !defined (BOOST_NO_STRINGSTREAM)
22 #include "bitset_test.hpp"
23 #include "boost/dynamic_bitset/dynamic_bitset.hpp"
24 #include "boost/detail/workaround.hpp"
27 // Codewarrior 8.3 for Win fails without this.
28 // Thanks Howard Hinnant ;)
29 #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x
30 # pragma parse_func_templ off
34 #if defined BOOST_NO_STD_WSTRING || defined BOOST_NO_STD_LOCALE
35 # define BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
38 #if !defined BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
39 std::wstring
widen_string( const std::string
& str
,
40 const std::locale
& loc
= std::locale() )
43 const std::string::size_type len
= str
.length();
46 typedef std::ctype
<wchar_t> ct_type
;
47 typedef std::wstring::traits_type tr_type
;
48 const ct_type
& ct
= BOOST_USE_FACET(ct_type
, loc
);
51 for (std::size_t i
= 0; i
< len
; ++i
)
52 tr_type::assign(result
[i
], ct
.widen(str
[i
]));
59 template <typename Block
>
60 void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block
) )
63 typedef boost::dynamic_bitset
<Block
> bitset_type
;
64 typedef bitset_test
<bitset_type
> Tests
;
66 //=====================================================================
67 // Test stream operator<<
70 // The test "variables" are: the stream type and its state, the
71 // exception mask, the width, the fill char and the padding side (left/right)
73 std::ios::iostate masks
[] = {
77 std::ios::eofbit
| std::ios::failbit
80 static std::string strings
[] = {
88 char fill_chars
[] = { '*', 'x', ' ' };
90 std::size_t num_masks
= sizeof(masks
) / sizeof(masks
[0]);
91 std::size_t num_strings
= sizeof(strings
) / sizeof(strings
[0]);
92 std::size_t num_chars
= sizeof(fill_chars
) / sizeof(fill_chars
[0]);
94 std::fstream
not_good_stream("dynamic_bitset_tests - this file shouldn't exist",
98 for (std::size_t mi
= 0; mi
< num_masks
; ++mi
) {
99 for (std::size_t si
= 0; si
< num_strings
; ++si
) {
101 std::streamsize slen
= (std::streamsize
)(strings
[si
].length());
103 assert( (std::numeric_limits
<std::streamsize
>::max
)()
104 >=(std::streamsize
)(1+slen
*2) );
106 for (std::size_t ci
= 0; ci
< num_chars
; ++ci
) {
108 // note how "negative widths" are tested too
109 const std::streamsize widths
[] = { -1 - slen
/2, 0, slen
/2, 1 + slen
*2 };
110 std::size_t num_widths
= sizeof(widths
) / sizeof(widths
[0]);
112 for (std::size_t wi
= 0; wi
< num_widths
; ++wi
) {
113 std::streamsize w
= widths
[wi
];
115 // test 0 - stream !good()
116 if(not_good_stream
.good())
117 throw std::logic_error("Error in operator << tests"
118 " - please, double check");
119 bitset_type
b(strings
[si
]);
120 not_good_stream
.width(w
);
121 not_good_stream
.fill(fill_chars
[ci
]);
122 try { not_good_stream
.exceptions(masks
[mi
]); } catch(...) {}
124 Tests::stream_inserter(b
, not_good_stream
, "<unused_string>");
127 // test 1a - file stream
128 bitset_type
b(strings
[si
]);
129 std::ofstream
file(test_file_name(), std::ios::trunc
);
131 file
.fill(fill_chars
[ci
]);
132 file
.exceptions(masks
[mi
]);
133 Tests::stream_inserter(b
, file
, test_file_name());
137 //NOTE: there are NO string stream tests
139 #if !defined (BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
141 // test 1b - wide file stream
142 bitset_type
b(strings
[si
]);
143 std::wofstream
file(test_file_name());
145 file
.fill(fill_chars
[ci
]);
146 file
.exceptions(masks
[mi
]);
147 Tests::stream_inserter(b
, file
, test_file_name());
157 //=====================================================================
158 // Test stream operator>>
161 // The test "variables" are: the stream type, the exception mask,
162 // the actual contents (and/or state) of the stream, and width.
164 // With few exceptions, each test case consists of writing a different
165 // assortment of digits and "whitespaces" to a text stream and then checking
166 // that what was written gets read back unchanged. That's NOT guaranteed by
167 // the standard, unless the assortment always ends with a '\n' and satisfies
168 // other conditions (see C99, 7.19.2/2), however it works in practice and is
169 // a good "real life" test. Some characters, such as '\v' and '\f', are not
170 // used exactly because they are the ones which will most likely give problems
171 // on some systems (for instance '\f' could actually be written as a sequence
172 // of new-lines, and we could never be able to read it back)
174 // Note how the bitset object is not initially empty. That helps checking
175 // that it isn't erroneously clear()ed by operator>>.
178 std::ios::iostate masks
[] = {
182 std::ios::eofbit
| std::ios::failbit
185 const std::string spaces
= "\t\n "; //"\t\n\v\f ";
187 const std::string long_string
= get_long_string();
188 /*const*/ static std::string strings
[] = {
189 // NOTE: "const" gives the usual problems with Borland
190 // (in Tests::stream_extractor instantiation)
193 #if !(defined __BORLANDC__ \
194 && BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)))
195 // Borland 5.5.1 with RW library crashes
203 std::string("\t xyz"),
213 spaces
+ "1" + spaces
,
214 std::string(" x1x "),
219 " " + long_string
+ " xyz",
220 spaces
+ long_string
,
221 spaces
+ long_string
+ spaces
225 //-----------------------------------------------------
227 std::stringstream not_good_stream
;
228 not_good_stream
<< "test";
230 not_good_stream
>> sink
; // now the stream should be in eof state
232 const std::size_t num_masks
= sizeof(masks
) / sizeof(masks
[0]);
233 const std::size_t num_strings
= sizeof(strings
) / sizeof(strings
[0]);
235 for (std::size_t mi
= 0; mi
< num_masks
; ++mi
) {
236 for (std::size_t si
= 0; si
< num_strings
; ++si
) {
238 const std::streamsize slen
= (std::streamsize
)(strings
[si
].length());
239 assert((std::numeric_limits
<std::streamsize
>::max
)() >= (std::streamsize
)(1+slen
*2));
241 std::streamsize widths
[] = { -1, 0, slen
/2, slen
, 1 + slen
*2 };
242 std::size_t num_widths
= sizeof(widths
) / sizeof(widths
[0]);
244 for(std::size_t wi
= 0; wi
< num_widths
; ++wi
) {
245 const std::streamsize w
= widths
[wi
];
247 // test 0 - !good() stream
249 if(not_good_stream
.good())
250 throw std::logic_error("Error in operator >> tests"
251 " - please, double check");
252 bitset_type
b(1, 15ul); // note: b is not empty
253 not_good_stream
.width(w
);
254 try { not_good_stream
.exceptions(masks
[mi
]); } catch(...) {}
255 std::string irrelevant
;
256 Tests::stream_extractor(b
, not_good_stream
, irrelevant
);
258 // test 1a - (narrow) file stream
260 bitset_type
b(1, 255ul);
262 std::ofstream
f(test_file_name());
266 std::ifstream
f(test_file_name());
268 f
.exceptions(masks
[mi
]);
269 Tests::stream_extractor(b
, f
, strings
[si
]);
271 #if !defined(BOOST_NO_STRINGSTREAM)
272 // test 2a - stringstream
274 bitset_type
b(1, 255ul);
275 std::istringstream
stream(strings
[si
]);
277 stream
.exceptions(masks
[mi
]);
278 Tests::stream_extractor(b
, stream
, strings
[si
]);
282 #if !defined(BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
283 // test 1b - wchar_t file stream
285 std::wstring wstr
= widen_string(strings
[si
]);
286 bitset_type
b(1, 255ul);
288 std::basic_ofstream
<wchar_t> of(test_file_name());
292 std::basic_ifstream
<wchar_t> f(test_file_name());
294 f
.exceptions(masks
[mi
]);
295 Tests::stream_extractor(b
, f
, wstr
);
297 // test 2b - wstringstream
299 bitset_type
b(1, 255ul);
300 std::wstring wstr
= widen_string(strings
[si
]);
302 std::wistringstream
wstream(wstr
);
304 wstream
.exceptions(masks
[mi
]);
305 Tests::stream_extractor(b
, wstream
, wstr
);
307 #endif // BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
312 } // for ( mi = 0; ...)
316 //=====================================================================
317 // << Any other tests go here >>
324 test_main(int, char*[])
326 run_test_cases
<unsigned char>();
327 run_test_cases
<unsigned short>();
328 run_test_cases
<unsigned int>();
329 run_test_cases
<unsigned long>();
330 # ifdef BOOST_HAS_LONG_LONG
331 run_test_cases
< ::boost::ulong_long_type
>();