comparison DEPENDENCIES/generic/include/boost/dynamic_bitset/dynamic_bitset.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
1 // ----------------------------------------------------------- 1 // -----------------------------------------------------------
2 // 2 //
3 // Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek 3 // Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
4 // Copyright (c) 2003-2006, 2008 Gennaro Prota 4 // Copyright (c) 2003-2006, 2008 Gennaro Prota
5 // Copyright (c) 2014 Ahmed Charles
6 //
7 // Copyright (c) 2014 Glen Joseph Fernandes
8 // glenfe at live dot com
9 // Copyright (c) 2014 Riccardo Marcangelo
5 // 10 //
6 // Distributed under the Boost Software License, Version 1.0. 11 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at 12 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt) 13 // http://www.boost.org/LICENSE_1_0.txt)
9 // 14 //
34 #endif 39 #endif
35 40
36 #include "boost/dynamic_bitset_fwd.hpp" 41 #include "boost/dynamic_bitset_fwd.hpp"
37 #include "boost/detail/dynamic_bitset.hpp" 42 #include "boost/detail/dynamic_bitset.hpp"
38 #include "boost/detail/iterator.hpp" // used to implement append(Iter, Iter) 43 #include "boost/detail/iterator.hpp" // used to implement append(Iter, Iter)
39 #include "boost/static_assert.hpp" 44 #include "boost/move/move.hpp"
40 #include "boost/limits.hpp" 45 #include "boost/limits.hpp"
41 #include "boost/pending/lowest_bit.hpp" 46 #include "boost/pending/lowest_bit.hpp"
47 #include "boost/static_assert.hpp"
48 #include "boost/utility/addressof.hpp"
49 #include "boost/detail/no_exceptions_support.hpp"
50 #include "boost/throw_exception.hpp"
42 51
43 52
44 namespace boost { 53 namespace boost {
45 54
46 template <typename Block, typename Allocator> 55 template <typename Block, typename Allocator>
47 class dynamic_bitset 56 class dynamic_bitset
48 { 57 {
49 // Portability note: member function templates are defined inside 58 // Portability note: member function templates are defined inside
50 // this class definition to avoid problems with VC++. Similarly, 59 // this class definition to avoid problems with VC++. Similarly,
51 // with the member functions of nested classes. 60 // with the member functions of nested classes.
52 // 61 //
53 // [October 2008: the note above is mostly historical; new versions 62 // [October 2008: the note above is mostly historical; new versions
54 // of VC++ are likely able to digest a more drinking form of the 63 // of VC++ are likely able to digest a more drinking form of the
55 // code; but changing it now is probably not worth the risks...] 64 // code; but changing it now is probably not worth the risks...]
56 65
57 BOOST_STATIC_ASSERT((bool)detail::dynamic_bitset_impl::allowed_block_type<Block>::value); 66 BOOST_STATIC_ASSERT((bool)detail::dynamic_bitset_impl::allowed_block_type<Block>::value);
67 typedef std::vector<Block, Allocator> buffer_type;
58 68
59 public: 69 public:
60 typedef Block block_type; 70 typedef Block block_type;
61 typedef Allocator allocator_type; 71 typedef Allocator allocator_type;
62 typedef std::size_t size_type; 72 typedef std::size_t size_type;
63 typedef block_type block_width_type; 73 typedef typename buffer_type::size_type block_width_type;
64 74
65 BOOST_STATIC_CONSTANT(block_width_type, bits_per_block = (std::numeric_limits<Block>::digits)); 75 BOOST_STATIC_CONSTANT(block_width_type, bits_per_block = (std::numeric_limits<Block>::digits));
66 BOOST_STATIC_CONSTANT(size_type, npos = static_cast<size_type>(-1)); 76 BOOST_STATIC_CONSTANT(size_type, npos = static_cast<size_type>(-1));
67 77
68 78
205 ~dynamic_bitset(); 215 ~dynamic_bitset();
206 216
207 void swap(dynamic_bitset& b); 217 void swap(dynamic_bitset& b);
208 dynamic_bitset& operator=(const dynamic_bitset& b); 218 dynamic_bitset& operator=(const dynamic_bitset& b);
209 219
220 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
221 dynamic_bitset(dynamic_bitset&& src);
222 dynamic_bitset& operator=(dynamic_bitset&& src);
223 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
224
210 allocator_type get_allocator() const; 225 allocator_type get_allocator() const;
211 226
212 // size changing operations 227 // size changing operations
213 void resize(size_type num_bits, bool value = false); 228 void resize(size_type num_bits, bool value = false);
214 void clear(); 229 void clear();
215 void push_back(bool bit); 230 void push_back(bool bit);
231 void pop_back();
216 void append(Block block); 232 void append(Block block);
217 233
218 template <typename BlockInputIterator> 234 template <typename BlockInputIterator>
219 void m_append(BlockInputIterator first, BlockInputIterator last, std::input_iterator_tag) 235 void m_append(BlockInputIterator first, BlockInputIterator last, std::input_iterator_tag)
220 { 236 {
268 dynamic_bitset& reset(size_type n); 284 dynamic_bitset& reset(size_type n);
269 dynamic_bitset& reset(); 285 dynamic_bitset& reset();
270 dynamic_bitset& flip(size_type n); 286 dynamic_bitset& flip(size_type n);
271 dynamic_bitset& flip(); 287 dynamic_bitset& flip();
272 bool test(size_type n) const; 288 bool test(size_type n) const;
289 bool test_set(size_type n, bool val = true);
290 bool all() const;
273 bool any() const; 291 bool any() const;
274 bool none() const; 292 bool none() const;
275 dynamic_bitset operator~() const; 293 dynamic_bitset operator~() const;
276 size_type count() const; 294 size_type count() const BOOST_NOEXCEPT;
277 295
278 // subscript 296 // subscript
279 reference operator[](size_type pos) { 297 reference operator[](size_type pos) {
280 return reference(m_bits[block_index(pos)], bit_index(pos)); 298 return reference(m_bits[block_index(pos)], bit_index(pos));
281 } 299 }
282 bool operator[](size_type pos) const { return test(pos); } 300 bool operator[](size_type pos) const { return test(pos); }
283 301
284 unsigned long to_ulong() const; 302 unsigned long to_ulong() const;
285 303
286 size_type size() const; 304 size_type size() const BOOST_NOEXCEPT;
287 size_type num_blocks() const; 305 size_type num_blocks() const BOOST_NOEXCEPT;
288 size_type max_size() const; 306 size_type max_size() const BOOST_NOEXCEPT;
289 bool empty() const; 307 bool empty() const BOOST_NOEXCEPT;
290 308
291 bool is_subset_of(const dynamic_bitset& a) const; 309 bool is_subset_of(const dynamic_bitset& a) const;
292 bool is_proper_subset_of(const dynamic_bitset& a) const; 310 bool is_proper_subset_of(const dynamic_bitset& a) const;
293 bool intersects(const dynamic_bitset & a) const; 311 bool intersects(const dynamic_bitset & a) const;
294 312
328 #endif 346 #endif
329 347
330 348
331 private: 349 private:
332 BOOST_STATIC_CONSTANT(block_width_type, ulong_width = std::numeric_limits<unsigned long>::digits); 350 BOOST_STATIC_CONSTANT(block_width_type, ulong_width = std::numeric_limits<unsigned long>::digits);
333 typedef std::vector<block_type, allocator_type> buffer_type;
334 351
335 void m_zero_unused_bits(); 352 void m_zero_unused_bits();
336 bool m_check_invariants() const; 353 bool m_check_invariants() const;
337 354
338 size_type m_do_find_from(size_type first_block) const; 355 size_type m_do_find_from(size_type first_block) const;
339 356
340 block_width_type count_extra_bits() const { return bit_index(size()); } 357 block_width_type count_extra_bits() const BOOST_NOEXCEPT { return bit_index(size()); }
341 static size_type block_index(size_type pos) { return pos / bits_per_block; } 358 static size_type block_index(size_type pos) BOOST_NOEXCEPT { return pos / bits_per_block; }
342 static block_width_type bit_index(size_type pos) { return static_cast<block_width_type>(pos % bits_per_block); } 359 static block_width_type bit_index(size_type pos) BOOST_NOEXCEPT { return static_cast<block_width_type>(pos % bits_per_block); }
343 static Block bit_mask(size_type pos) { return Block(1) << bit_index(pos); } 360 static Block bit_mask(size_type pos) BOOST_NOEXCEPT { return Block(1) << bit_index(pos); }
344 361
345 template <typename CharT, typename Traits, typename Alloc> 362 template <typename CharT, typename Traits, typename Alloc>
346 void init_from_string(const std::basic_string<CharT, Traits, Alloc>& s, 363 void init_from_string(const std::basic_string<CharT, Traits, Alloc>& s,
347 typename std::basic_string<CharT, Traits, Alloc>::size_type pos, 364 typename std::basic_string<CharT, Traits, Alloc>::size_type pos,
348 typename std::basic_string<CharT, Traits, Alloc>::size_type n, 365 typename std::basic_string<CharT, Traits, Alloc>::size_type n,
631 m_bits = b.m_bits; 648 m_bits = b.m_bits;
632 m_num_bits = b.m_num_bits; 649 m_num_bits = b.m_num_bits;
633 return *this; 650 return *this;
634 } 651 }
635 652
653 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
654
655 template <typename Block, typename Allocator>
656 inline dynamic_bitset<Block, Allocator>::
657 dynamic_bitset(dynamic_bitset<Block, Allocator>&& b)
658 : m_bits(boost::move(b.m_bits)), m_num_bits(boost::move(b.m_num_bits))
659 {
660 // Required so that assert(m_check_invariants()); works.
661 assert((b.m_bits = buffer_type()).empty());
662 b.m_num_bits = 0;
663 }
664
665 template <typename Block, typename Allocator>
666 inline dynamic_bitset<Block, Allocator>& dynamic_bitset<Block, Allocator>::
667 operator=(dynamic_bitset<Block, Allocator>&& b)
668 {
669 if (boost::addressof(b) == this) { return *this; }
670
671 m_bits = boost::move(b.m_bits);
672 m_num_bits = boost::move(b.m_num_bits);
673 // Required so that assert(m_check_invariants()); works.
674 assert((b.m_bits = buffer_type()).empty());
675 b.m_num_bits = 0;
676 return *this;
677 }
678
679 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
680
636 template <typename Block, typename Allocator> 681 template <typename Block, typename Allocator>
637 inline typename dynamic_bitset<Block, Allocator>::allocator_type 682 inline typename dynamic_bitset<Block, Allocator>::allocator_type
638 dynamic_bitset<Block, Allocator>::get_allocator() const 683 dynamic_bitset<Block, Allocator>::get_allocator() const
639 { 684 {
640 return m_bits.get_allocator(); 685 return m_bits.get_allocator();
703 set(sz, bit); 748 set(sz, bit);
704 } 749 }
705 750
706 template <typename Block, typename Allocator> 751 template <typename Block, typename Allocator>
707 void dynamic_bitset<Block, Allocator>:: 752 void dynamic_bitset<Block, Allocator>::
753 pop_back()
754 {
755 const size_type old_num_blocks = num_blocks();
756 const size_type required_blocks = calc_num_blocks(m_num_bits - 1);
757
758 if (required_blocks != old_num_blocks) {
759 m_bits.pop_back();
760 }
761
762 --m_num_bits;
763 m_zero_unused_bits();
764 }
765
766
767 template <typename Block, typename Allocator>
768 void dynamic_bitset<Block, Allocator>::
708 append(Block value) // strong guarantee 769 append(Block value) // strong guarantee
709 { 770 {
710 const block_width_type r = count_extra_bits(); 771 const block_width_type r = count_extra_bits();
711 772
712 if (r == 0) { 773 if (r == 0) {
805 } 866 }
806 b[div] = b[0]; 867 b[div] = b[0];
807 } 868 }
808 869
809 // zero out div blocks at the less significant end 870 // zero out div blocks at the less significant end
810 std::fill_n(b, div, static_cast<block_type>(0)); 871 std::fill_n(m_bits.begin(), div, static_cast<block_type>(0));
811 872
812 // zero out any 1 bit that flowed into the unused part 873 // zero out any 1 bit that flowed into the unused part
813 m_zero_unused_bits(); // thanks to Lester Gong 874 m_zero_unused_bits(); // thanks to Lester Gong
814 875
815 } 876 }
858 } 919 }
859 920
860 921
861 922
862 // div blocks are zero filled at the most significant end 923 // div blocks are zero filled at the most significant end
863 std::fill_n(b + (num_blocks()-div), div, static_cast<block_type>(0)); 924 std::fill_n(m_bits.begin() + (num_blocks()-div), div, static_cast<block_type>(0));
864 } 925 }
865 926
866 return *this; 927 return *this;
867 } 928 }
868 929
965 assert(pos < m_num_bits); 1026 assert(pos < m_num_bits);
966 return m_unchecked_test(pos); 1027 return m_unchecked_test(pos);
967 } 1028 }
968 1029
969 template <typename Block, typename Allocator> 1030 template <typename Block, typename Allocator>
1031 bool dynamic_bitset<Block, Allocator>::test_set(size_type pos, bool val)
1032 {
1033 bool const b = test(pos);
1034 if (b != val) {
1035 set(pos, val);
1036 }
1037 return b;
1038 }
1039
1040 template <typename Block, typename Allocator>
1041 bool dynamic_bitset<Block, Allocator>::all() const
1042 {
1043 if (empty()) {
1044 return true;
1045 }
1046
1047 const block_width_type extra_bits = count_extra_bits();
1048 block_type const all_ones = ~static_cast<Block>(0);
1049
1050 if (extra_bits == 0) {
1051 for (size_type i = 0, e = num_blocks(); i < e; ++i) {
1052 if (m_bits[i] != all_ones) {
1053 return false;
1054 }
1055 }
1056 } else {
1057 for (size_type i = 0, e = num_blocks() - 1; i < e; ++i) {
1058 if (m_bits[i] != all_ones) {
1059 return false;
1060 }
1061 }
1062 block_type const mask = ~(~static_cast<Block>(0) << extra_bits);
1063 if (m_highest_block() != mask) {
1064 return false;
1065 }
1066 }
1067 return true;
1068 }
1069
1070 template <typename Block, typename Allocator>
970 bool dynamic_bitset<Block, Allocator>::any() const 1071 bool dynamic_bitset<Block, Allocator>::any() const
971 { 1072 {
972 for (size_type i = 0; i < num_blocks(); ++i) 1073 for (size_type i = 0; i < num_blocks(); ++i)
973 if (m_bits[i]) 1074 if (m_bits[i])
974 return true; 1075 return true;
990 return b; 1091 return b;
991 } 1092 }
992 1093
993 template <typename Block, typename Allocator> 1094 template <typename Block, typename Allocator>
994 typename dynamic_bitset<Block, Allocator>::size_type 1095 typename dynamic_bitset<Block, Allocator>::size_type
995 dynamic_bitset<Block, Allocator>::count() const 1096 dynamic_bitset<Block, Allocator>::count() const BOOST_NOEXCEPT
996 { 1097 {
997 using detail::dynamic_bitset_impl::table_width; 1098 using detail::dynamic_bitset_impl::table_width;
998 using detail::dynamic_bitset_impl::access_by_bytes; 1099 using detail::dynamic_bitset_impl::access_by_bytes;
999 using detail::dynamic_bitset_impl::access_by_blocks; 1100 using detail::dynamic_bitset_impl::access_by_blocks;
1000 using detail::dynamic_bitset_impl::value_to_type; 1101 using detail::dynamic_bitset_impl::value_to_type;
1099 return 0; // convention 1200 return 0; // convention
1100 1201
1101 // Check for overflows. This may be a performance burden on very 1202 // Check for overflows. This may be a performance burden on very
1102 // large bitsets but is required by the specification, sorry 1203 // large bitsets but is required by the specification, sorry
1103 if (find_next(ulong_width - 1) != npos) 1204 if (find_next(ulong_width - 1) != npos)
1104 throw std::overflow_error("boost::dynamic_bitset::to_ulong overflow"); 1205 BOOST_THROW_EXCEPTION(std::overflow_error("boost::dynamic_bitset::to_ulong overflow"));
1105 1206
1106 1207
1107 // Ok, from now on we can be sure there's no "on" bit 1208 // Ok, from now on we can be sure there's no "on" bit
1108 // beyond the "allowed" positions 1209 // beyond the "allowed" positions
1109 typedef unsigned long result_type; 1210 typedef unsigned long result_type;
1124 return result; 1225 return result;
1125 } 1226 }
1126 1227
1127 template <typename Block, typename Allocator> 1228 template <typename Block, typename Allocator>
1128 inline typename dynamic_bitset<Block, Allocator>::size_type 1229 inline typename dynamic_bitset<Block, Allocator>::size_type
1129 dynamic_bitset<Block, Allocator>::size() const 1230 dynamic_bitset<Block, Allocator>::size() const BOOST_NOEXCEPT
1130 { 1231 {
1131 return m_num_bits; 1232 return m_num_bits;
1132 } 1233 }
1133 1234
1134 template <typename Block, typename Allocator> 1235 template <typename Block, typename Allocator>
1135 inline typename dynamic_bitset<Block, Allocator>::size_type 1236 inline typename dynamic_bitset<Block, Allocator>::size_type
1136 dynamic_bitset<Block, Allocator>::num_blocks() const 1237 dynamic_bitset<Block, Allocator>::num_blocks() const BOOST_NOEXCEPT
1137 { 1238 {
1138 return m_bits.size(); 1239 return m_bits.size();
1139 } 1240 }
1140 1241
1141 template <typename Block, typename Allocator> 1242 template <typename Block, typename Allocator>
1142 inline typename dynamic_bitset<Block, Allocator>::size_type 1243 inline typename dynamic_bitset<Block, Allocator>::size_type
1143 dynamic_bitset<Block, Allocator>::max_size() const 1244 dynamic_bitset<Block, Allocator>::max_size() const BOOST_NOEXCEPT
1144 { 1245 {
1145 // Semantics of vector<>::max_size() aren't very clear 1246 // Semantics of vector<>::max_size() aren't very clear
1146 // (see lib issue 197) and many library implementations 1247 // (see lib issue 197) and many library implementations
1147 // simply return dummy values, _unrelated_ to the underlying 1248 // simply return dummy values, _unrelated_ to the underlying
1148 // allocator. 1249 // allocator.
1159 m * bits_per_block : 1260 m * bits_per_block :
1160 size_type(-1); 1261 size_type(-1);
1161 } 1262 }
1162 1263
1163 template <typename Block, typename Allocator> 1264 template <typename Block, typename Allocator>
1164 inline bool dynamic_bitset<Block, Allocator>::empty() const 1265 inline bool dynamic_bitset<Block, Allocator>::empty() const BOOST_NOEXCEPT
1165 { 1266 {
1166 return size() == 0; 1267 return size() == 0;
1167 } 1268 }
1168 1269
1169 template <typename Block, typename Allocator> 1270 template <typename Block, typename Allocator>
1228 ++i; 1329 ++i;
1229 1330
1230 if (i >= num_blocks()) 1331 if (i >= num_blocks())
1231 return npos; // not found 1332 return npos; // not found
1232 1333
1233 return i * bits_per_block + boost::lowest_bit(m_bits[i]); 1334 return i * bits_per_block + static_cast<size_type>(boost::lowest_bit(m_bits[i]));
1234 1335
1235 } 1336 }
1236 1337
1237 1338
1238 template <typename Block, typename Allocator> 1339 template <typename Block, typename Allocator>
1255 ++pos; 1356 ++pos;
1256 1357
1257 const size_type blk = block_index(pos); 1358 const size_type blk = block_index(pos);
1258 const block_width_type ind = bit_index(pos); 1359 const block_width_type ind = bit_index(pos);
1259 1360
1260 // mask out bits before pos 1361 // shift bits upto one immediately after current
1261 const Block fore = m_bits[blk] & ( ~Block(0) << ind ); 1362 const Block fore = m_bits[blk] >> ind;
1262 1363
1263 return fore? 1364 return fore?
1264 blk * bits_per_block + lowest_bit(fore) 1365 pos + static_cast<size_type>(lowest_bit(fore))
1265 : 1366 :
1266 m_do_find_from(blk + 1); 1367 m_do_find_from(blk + 1);
1267 1368
1268 } 1369 }
1269 1370
1420 1521
1421 BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, os.getloc()); 1522 BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, os.getloc());
1422 const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0'); 1523 const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0');
1423 const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1'); 1524 const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1');
1424 1525
1425 try { 1526 BOOST_TRY {
1426 1527
1427 typedef typename dynamic_bitset<Block, Alloc>::size_type bitsetsize_type; 1528 typedef typename dynamic_bitset<Block, Alloc>::size_type bitset_size_type;
1428 typedef basic_streambuf<Ch, Tr> buffer_type; 1529 typedef basic_streambuf<Ch, Tr> buffer_type;
1429 1530
1430 buffer_type * buf = os.rdbuf(); 1531 buffer_type * buf = os.rdbuf();
1431 size_t npad = os.width() <= 0 // careful: os.width() is signed (and can be < 0) 1532 // careful: os.width() is signed (and can be < 0)
1432 || (bitsetsize_type) os.width() <= b.size()? 0 : os.width() - b.size(); 1533 const bitset_size_type width = (os.width() <= 0) ? 0 : static_cast<bitset_size_type>(os.width());
1534 streamsize npad = (width <= b.size()) ? 0 : width - b.size();
1433 1535
1434 const Ch fill_char = os.fill(); 1536 const Ch fill_char = os.fill();
1435 const ios_base::fmtflags adjustfield = os.flags() & ios_base::adjustfield; 1537 const ios_base::fmtflags adjustfield = os.flags() & ios_base::adjustfield;
1436 1538
1437 // if needed fill at left; pad is decresed along the way 1539 // if needed fill at left; pad is decreased along the way
1438 if (adjustfield != ios_base::left) { 1540 if (adjustfield != ios_base::left) {
1439 for (; 0 < npad; --npad) 1541 for (; 0 < npad; --npad)
1440 if (Tr::eq_int_type(Tr::eof(), buf->sputc(fill_char))) { 1542 if (Tr::eq_int_type(Tr::eof(), buf->sputc(fill_char))) {
1441 err |= ios_base::failbit; 1543 err |= ios_base::failbit;
1442 break; 1544 break;
1443 } 1545 }
1444 } 1546 }
1445 1547
1446 if (err == ok) { 1548 if (err == ok) {
1447 // output the bitset 1549 // output the bitset
1448 for (bitsetsize_type i = b.size(); 0 < i; --i) { 1550 for (bitset_size_type i = b.size(); 0 < i; --i) {
1449 typename buffer_type::int_type 1551 typename buffer_type::int_type
1450 ret = buf->sputc(b.test(i-1)? one : zero); 1552 ret = buf->sputc(b.test(i-1)? one : zero);
1451 if (Tr::eq_int_type(Tr::eof(), ret)) { 1553 if (Tr::eq_int_type(Tr::eof(), ret)) {
1452 err |= ios_base::failbit; 1554 err |= ios_base::failbit;
1453 break; 1555 break;
1466 } 1568 }
1467 1569
1468 1570
1469 os.width(0); 1571 os.width(0);
1470 1572
1471 } catch (...) { // see std 27.6.1.1/4 1573 } BOOST_CATCH (...) { // see std 27.6.1.1/4
1472 bool rethrow = false; 1574 bool rethrow = false;
1473 try { os.setstate(ios_base::failbit); } catch (...) { rethrow = true; } 1575 BOOST_TRY { os.setstate(ios_base::failbit); } BOOST_CATCH (...) { rethrow = true; } BOOST_CATCH_END
1474 1576
1475 if (rethrow) 1577 if (rethrow)
1476 throw; 1578 BOOST_RETHROW;
1477 } 1579 }
1580 BOOST_CATCH_END
1478 } 1581 }
1479 1582
1480 if(err != ok) 1583 if(err != ok)
1481 os.setstate(err); // may throw exception 1584 os.setstate(err); // may throw exception
1482 return os; 1585 return os;
1518 1621
1519 b.clear(); 1622 b.clear();
1520 1623
1521 const std::streamsize w = is.width(); 1624 const std::streamsize w = is.width();
1522 const size_type limit = w > 0 && static_cast<size_type>(w) < b.max_size() 1625 const size_type limit = w > 0 && static_cast<size_type>(w) < b.max_size()
1523 ? w : b.max_size(); 1626 ? static_cast<size_type>(w) : b.max_size();
1524 typename bitset_type::bit_appender appender(b); 1627 typename bitset_type::bit_appender appender(b);
1525 std::streambuf * buf = is.rdbuf(); 1628 std::streambuf * buf = is.rdbuf();
1526 for(int c = buf->sgetc(); appender.get_count() < limit; c = buf->snextc() ) { 1629 for(int c = buf->sgetc(); appender.get_count() < limit; c = buf->snextc() ) {
1527 1630
1528 if (c == EOF) { 1631 if (c == EOF) {
1531 } 1634 }
1532 else if (char(c) != '0' && char(c) != '1') 1635 else if (char(c) != '0' && char(c) != '1')
1533 break; // non digit character 1636 break; // non digit character
1534 1637
1535 else { 1638 else {
1536 try { 1639 BOOST_TRY {
1537 appender.do_append(char(c) == '1'); 1640 appender.do_append(char(c) == '1');
1538 } 1641 }
1539 catch(...) { 1642 BOOST_CATCH(...) {
1540 is.setstate(std::ios::failbit); // assume this can't throw 1643 is.setstate(std::ios::failbit); // assume this can't throw
1541 throw; 1644 BOOST_RETHROW;
1542 } 1645 }
1646 BOOST_CATCH_END
1543 } 1647 }
1544 1648
1545 } // for 1649 } // for
1546 } 1650 }
1547 1651
1566 typedef dynamic_bitset<Block, Alloc> bitset_type; 1670 typedef dynamic_bitset<Block, Alloc> bitset_type;
1567 typedef typename bitset_type::size_type size_type; 1671 typedef typename bitset_type::size_type size_type;
1568 1672
1569 const streamsize w = is.width(); 1673 const streamsize w = is.width();
1570 const size_type limit = 0 < w && static_cast<size_type>(w) < b.max_size()? 1674 const size_type limit = 0 < w && static_cast<size_type>(w) < b.max_size()?
1571 w : b.max_size(); 1675 static_cast<size_type>(w) : b.max_size();
1572 1676
1573 ios_base::iostate err = ios_base::goodbit; 1677 ios_base::iostate err = ios_base::goodbit;
1574 typename basic_istream<Ch, Tr>::sentry cerberos(is); // skips whitespaces 1678 typename basic_istream<Ch, Tr>::sentry cerberos(is); // skips whitespaces
1575 if(cerberos) { 1679 if(cerberos) {
1576 1680
1578 BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, is.getloc()); 1682 BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, is.getloc());
1579 const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0'); 1683 const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0');
1580 const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1'); 1684 const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1');
1581 1685
1582 b.clear(); 1686 b.clear();
1583 try { 1687 BOOST_TRY {
1584 typename bitset_type::bit_appender appender(b); 1688 typename bitset_type::bit_appender appender(b);
1585 basic_streambuf <Ch, Tr> * buf = is.rdbuf(); 1689 basic_streambuf <Ch, Tr> * buf = is.rdbuf();
1586 typename Tr::int_type c = buf->sgetc(); 1690 typename Tr::int_type c = buf->sgetc();
1587 for( ; appender.get_count() < limit; c = buf->snextc() ) { 1691 for( ; appender.get_count() < limit; c = buf->snextc() ) {
1588 1692
1601 1705
1602 } 1706 }
1603 1707
1604 } // for 1708 } // for
1605 } 1709 }
1606 catch (...) { 1710 BOOST_CATCH (...) {
1607 // catches from stream buf, or from vector: 1711 // catches from stream buf, or from vector:
1608 // 1712 //
1609 // bits_stored bits have been extracted and stored, and 1713 // bits_stored bits have been extracted and stored, and
1610 // either no further character is extractable or we can't 1714 // either no further character is extractable or we can't
1611 // append to the underlying vector (out of memory) 1715 // append to the underlying vector (out of memory)
1612 1716
1613 bool rethrow = false; // see std 27.6.1.1/4 1717 bool rethrow = false; // see std 27.6.1.1/4
1614 try { is.setstate(ios_base::badbit); } 1718 BOOST_TRY { is.setstate(ios_base::badbit); }
1615 catch(...) { rethrow = true; } 1719 BOOST_CATCH(...) { rethrow = true; }
1720 BOOST_CATCH_END
1616 1721
1617 if (rethrow) 1722 if (rethrow)
1618 throw; 1723 BOOST_RETHROW;
1619 1724
1620 } 1725 }
1726 BOOST_CATCH_END
1621 } 1727 }
1622 1728
1623 is.width(0); 1729 is.width(0);
1624 if (b.size() == 0 /*|| !cerberos*/) 1730 if (b.size() == 0 /*|| !cerberos*/)
1625 err |= ios_base::failbit; 1731 err |= ios_base::failbit;
1692 template <typename Block, typename Allocator> 1798 template <typename Block, typename Allocator>
1693 inline typename dynamic_bitset<Block, Allocator>::size_type 1799 inline typename dynamic_bitset<Block, Allocator>::size_type
1694 dynamic_bitset<Block, Allocator>::calc_num_blocks(size_type num_bits) 1800 dynamic_bitset<Block, Allocator>::calc_num_blocks(size_type num_bits)
1695 { 1801 {
1696 return num_bits / bits_per_block 1802 return num_bits / bits_per_block
1697 + static_cast<int>( num_bits % bits_per_block != 0 ); 1803 + static_cast<size_type>( num_bits % bits_per_block != 0 );
1698 } 1804 }
1699 1805
1700 // gives a reference to the highest block 1806 // gives a reference to the highest block
1701 // 1807 //
1702 template <typename Block, typename Allocator> 1808 template <typename Block, typename Allocator>