DriveHQ Start Menu
Cloud Drive Mapping
Folder Sync
Cloud Backup
True Drop Box
FTP/SFTP Hosting
Group Account
DriveHQ Start Menu
Online File Server
My Storage
|
Manage Shares
|
Publishes
|
Drop Boxes
|
Group Account
WebDAV Drive Mapping
Cloud Drive Home
|
WebDAV Guide
|
Drive Mapping Tool
|
Drive Mapping URL
Complete Data Backup
Backup Guide
|
Online Backup Tool
|
Cloud-to-Cloud Backup
FTP, Email & Web Service
FTP Home
|
FTP Hosting FAQ
|
Email Hosting
|
EmailManager
|
Web Hosting
Help & Resources
About
|
Enterprise Service
|
Partnership
|
Comparisons
|
Support
Quick Links
Security and Privacy
Download Software
Service Manual
Use Cases
Group Account
Online Help
Blog
Contact
Cloud Surveillance
Sign Up
Login
Features
Business Features
Online File Server
FTP Hosting
Cloud Drive Mapping
Cloud File Backup
Email Backup & Hosting
Cloud File Sharing
Folder Synchronization
Group Management
True Drop Box
Full-text Search
AD Integration/SSO
Mobile Access
IP Camera & DVR Solution
More...
Personal Features
Personal Cloud Drive
Backup All Devices
Mobile APPs
Personal Web Hosting
Sub-Account (for Kids)
Home/PC/Kids Monitoring
More...
Software
DriveHQ Drive Mapping Tool
DriveHQ FileManager
DriveHQ Online Backup
DriveHQ Mobile Apps
Pricing
Business Plans & Pricing
Personal Plans & Pricing
Price Comparison with Others
Feature Comparison with Others
Install Mobile App
Sign up
Creating account...
Invalid character in username! Only 0-9, a-z, A-Z, _, -, . allowed.
Username is required!
Invalid email address!
E-mail is required!
Password is required!
Password is invalid!
Password and confirmation do not match.
Confirm password is required!
I accept
Membership Agreement
Please read the Membership Agreement and check "I accept"!
Free Quick Sign-up
Sign-up Page
Log in
Signing in...
Username or e-mail address is required!
Password is required!
Keep me logged in
Quick Login
Forgot Password
Up
Upload
Download
Share
Publish
New Folder
New File
Copy
Cut
Delete
Paste
Rate
Upgrade
Rotate
Effect
Edit
Slide
History
// -------------------------------------------------- // // (C) Copyright Chuck Allison and Jeremy Siek 2001 - 2002. // (C) Copyright Gennaro Prota 2003 - 2006. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // ----------------------------------------------------------- // See http://www.boost.org/libs/dynamic_bitset/ for documentation. // // $Revision: 41959 $ $Date: 2007-12-10 13:51:19 -0500 (Mon, 10 Dec 2007) $ - $Name$ #ifndef BOOST_DYNAMIC_BITSET_DYNAMIC_BITSET_HPP #define BOOST_DYNAMIC_BITSET_DYNAMIC_BITSET_HPP #include
#include
#include
// for std::overflow_error #include
// for std::swap, min, copy, fill #include
#include
// for CHAR_BIT #include "boost/dynamic_bitset/config.hpp" #ifndef BOOST_NO_STD_LOCALE # include
#endif #if defined(BOOST_OLD_IOSTREAMS) # include
# include
// for isspace #else # include
# include
#endif #include "boost/dynamic_bitset_fwd.hpp" #include "boost/detail/dynamic_bitset.hpp" #include "boost/detail/iterator.hpp" // used to implement append(Iter, Iter) #include "boost/static_assert.hpp" #include "boost/limits.hpp" #include "boost/pending/lowest_bit.hpp" // used by find_first/next namespace boost { template #if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // 1300 == VC++ 7.0 // VC++ (up to 7.0) wants the default arguments again
> # else
# endif class dynamic_bitset { // Portability note: member function templates are defined inside // this class definition to avoid problems with VC++. Similarly, // with the member functions of nested classes. BOOST_STATIC_ASSERT(detail::dynamic_bitset_allowed_block_type
::value); public: typedef Block block_type; typedef Allocator allocator_type; typedef std::size_t size_type; typedef int block_width_type; BOOST_STATIC_CONSTANT(block_width_type, bits_per_block = (std::numeric_limits
::digits)); BOOST_STATIC_CONSTANT(size_type, npos = static_cast
(-1)); public: // A proxy class to simulate lvalues of bit type. // class reference { friend class dynamic_bitset
; // the one and only non-copy ctor reference(block_type & b, int pos) :m_block(b), m_mask(block_type(1) << pos) { assert(pos >= 0 && pos < bits_per_block); } void operator&(); // left undefined public: // copy constructor: compiler generated operator bool() const { return (m_block & m_mask) != 0; } bool operator~() const { return (m_block & m_mask) == 0; } reference& flip() { do_flip(); return *this; } reference& operator=(bool x) { do_assign(x); return *this; } // for b[i] = x reference& operator=(const reference& rhs) { do_assign(rhs); return *this; } // for b[i] = b[j] reference& operator|=(bool x) { if (x) do_set(); return *this; } reference& operator&=(bool x) { if (!x) do_reset(); return *this; } reference& operator^=(bool x) { if (x) do_flip(); return *this; } reference& operator-=(bool x) { if (x) do_reset(); return *this; } private: block_type & m_block; const block_type m_mask; void do_set() { m_block |= m_mask; } void do_reset() { m_block &= ~m_mask; } void do_flip() { m_block ^= m_mask; } void do_assign(bool x) { x? do_set() : do_reset(); } }; typedef bool const_reference; // constructors, etc. explicit dynamic_bitset(const Allocator& alloc = Allocator()); explicit dynamic_bitset(size_type num_bits, unsigned long value = 0, const Allocator& alloc = Allocator()); // WARNING: you should avoid using this constructor. // // A conversion from string is, in most cases, formatting, // and should be performed by using operator>>. // // NOTE: // Leave the parentheses around std::basic_string
::npos. // g++ 3.2 requires them and probably the standard will - see core issue 325 // NOTE 2: // split into two constructors because of bugs in MSVC 6.0sp5 with STLport template
dynamic_bitset(const std::basic_string
& s, typename std::basic_string
::size_type pos, typename std::basic_string
::size_type n, size_type num_bits = npos, const Allocator& alloc = Allocator()) :m_bits(alloc), m_num_bits(0) { init_from_string(s, pos, n, num_bits); } template
explicit dynamic_bitset(const std::basic_string
& s, typename std::basic_string
::size_type pos = 0) :m_bits(Allocator()), m_num_bits(0) { init_from_string(s, pos, (std::basic_string
::npos), npos); } // The first bit in *first is the least significant bit, and the // last bit in the block just before *last is the most significant bit. template
dynamic_bitset(BlockInputIterator first, BlockInputIterator last, const Allocator& alloc = Allocator()) :m_bits(first, last, alloc), m_num_bits(m_bits.size() * bits_per_block) {} // copy constructor dynamic_bitset(const dynamic_bitset& b); ~dynamic_bitset(); void swap(dynamic_bitset& b); dynamic_bitset& operator=(const dynamic_bitset& b); allocator_type get_allocator() const; // size changing operations void resize(size_type num_bits, bool value = false); void clear(); void push_back(bool bit); void append(Block block); template
void m_append(BlockInputIterator first, BlockInputIterator last, std::input_iterator_tag) { std::vector
v(first, last); m_append(v.begin(), v.end(), std::random_access_iterator_tag()); } template
void m_append(BlockInputIterator first, BlockInputIterator last, std::forward_iterator_tag) { assert(first != last); block_width_type r = count_extra_bits(); std::size_t d = boost::detail::distance(first, last); m_bits.reserve(num_blocks() + d); if (r == 0) { for( ; first != last; ++first) m_bits.push_back(*first); // could use vector<>::insert() } else { m_highest_block() |= (*first << r); do { Block b = *first >> (bits_per_block - r); ++first; m_bits.push_back(b | (first==last? 0 : *first << r)); } while (first != last); } m_num_bits += bits_per_block * d; } template
void append(BlockInputIterator first, BlockInputIterator last) // strong guarantee { if (first != last) { typename detail::iterator_traits
::iterator_category cat; m_append(first, last, cat); } } // bitset operations dynamic_bitset& operator&=(const dynamic_bitset& b); dynamic_bitset& operator|=(const dynamic_bitset& b); dynamic_bitset& operator^=(const dynamic_bitset& b); dynamic_bitset& operator-=(const dynamic_bitset& b); dynamic_bitset& operator<<=(size_type n); dynamic_bitset& operator>>=(size_type n); dynamic_bitset operator<<(size_type n) const; dynamic_bitset operator>>(size_type n) const; // basic bit operations dynamic_bitset& set(size_type n, bool val = true); dynamic_bitset& set(); dynamic_bitset& reset(size_type n); dynamic_bitset& reset(); dynamic_bitset& flip(size_type n); dynamic_bitset& flip(); bool test(size_type n) const; bool any() const; bool none() const; dynamic_bitset operator~() const; size_type count() const; // subscript reference operator[](size_type pos) { return reference(m_bits[block_index(pos)], bit_index(pos)); } bool operator[](size_type pos) const { return test(pos); } unsigned long to_ulong() const; size_type size() const; size_type num_blocks() const; size_type max_size() const; bool empty() const; bool is_subset_of(const dynamic_bitset& a) const; bool is_proper_subset_of(const dynamic_bitset& a) const; bool intersects(const dynamic_bitset & a) const; // lookup size_type find_first() const; size_type find_next(size_type pos) const; #if !defined BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS // lexicographical comparison template
friend bool operator==(const dynamic_bitset
& a, const dynamic_bitset
& b); template
friend bool operator<(const dynamic_bitset
& a, const dynamic_bitset
& b); template
friend void to_block_range(const dynamic_bitset
& b, BlockOutputIterator result); template
friend void from_block_range(BlockIterator first, BlockIterator last, dynamic_bitset
& result); template
friend std::basic_istream
& operator>>(std::basic_istream
& is, dynamic_bitset
& b); template
friend void to_string_helper(const dynamic_bitset
& b, stringT & s, bool dump_all); #endif private: BOOST_STATIC_CONSTANT(block_width_type, ulong_width = std::numeric_limits
::digits); typedef std::vector
buffer_type; void m_zero_unused_bits(); bool m_check_invariants() const; size_type m_do_find_from(size_type first_block) const; block_width_type count_extra_bits() const { return bit_index(size()); } static size_type block_index(size_type pos) { return pos / bits_per_block; } static block_width_type bit_index(size_type pos) { return static_cast
(pos % bits_per_block); } static Block bit_mask(size_type pos) { return Block(1) << bit_index(pos); } template
void init_from_string(const std::basic_string
& s, typename std::basic_string
::size_type pos, typename std::basic_string
::size_type n, size_type num_bits) { assert(pos <= s.size()); typedef typename std::basic_string
StrT; typedef typename StrT::traits_type Tr; const typename StrT::size_type rlen = (std::min)(n, s.size() - pos); const size_type sz = ( num_bits != npos? num_bits : rlen); m_bits.resize(calc_num_blocks(sz)); m_num_bits = sz; BOOST_DYNAMIC_BITSET_CTYPE_FACET(CharT, fac, std::locale()); const CharT one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1'); const size_type m = num_bits < rlen ? num_bits : rlen; typename StrT::size_type i = 0; for( ; i < m; ++i) { const CharT c = s[(pos + m - 1) - i]; assert( Tr::eq(c, one) || Tr::eq(c, BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0')) ); if (Tr::eq(c, one)) set(i); } } BOOST_DYNAMIC_BITSET_PRIVATE: bool m_unchecked_test(size_type pos) const; static size_type calc_num_blocks(size_type num_bits); Block& m_highest_block(); const Block& m_highest_block() const; buffer_type m_bits; size_type m_num_bits; class bit_appender; friend class bit_appender; class bit_appender { // helper for stream >> // Supplies to the lack of an efficient append at the less // significant end: bits are actually appended "at left" but // rearranged in the destructor. From the perspective of // client code everything works *as if* dynamic_bitset<> had // an append_at_right() function (eventually throwing the same // exceptions as push_back) except that the function is in fact // called bit_appender::do_append(). // dynamic_bitset & bs; size_type n; Block mask; Block * current; public: bit_appender(dynamic_bitset & r) : bs(r), n(0), mask(0), current(0) {} ~bit_appender() { // reverse the order of blocks, shift // if needed, and then resize // std::reverse(bs.m_bits.begin(), bs.m_bits.end()); const block_width_type offs = bit_index(n); if (offs) bs >>= (bits_per_block - offs); bs.resize(n); // doesn't enlarge, so can't throw assert(bs.m_check_invariants()); } inline void do_append(bool value) { if (mask == 0) { bs.append(Block(0)); current = &bs.m_highest_block(); mask = Block(1) << (bits_per_block - 1); } if(value) *current |= mask; mask /= 2; ++n; } size_type get_count() const { return n; } }; }; #if defined(__IBMCPP__) && BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) // Workaround for IBM's AIX platform. // See http://comments.gmane.org/gmane.comp.lib.boost.user/15331 // // NOTE: // The compiler is actually right, until core issue 454 will be settled: // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#454 // // It's arguable whether we want to mark this with BOOST_WORKAROUND or not. template
dynamic_bitset
::block_width_type const dynamic_bitset
::bits_per_block; template
dynamic_bitset
::block_width_type const dynamic_bitset
::ulong_width; #endif // Global Functions: // comparison template
bool operator!=(const dynamic_bitset
& a, const dynamic_bitset
& b); template
bool operator<=(const dynamic_bitset
& a, const dynamic_bitset
& b); template
bool operator>(const dynamic_bitset
& a, const dynamic_bitset
& b); template
bool operator>=(const dynamic_bitset
& a, const dynamic_bitset
& b); // stream operators #ifdef BOOST_OLD_IOSTREAMS template
std::ostream& operator<<(std::ostream& os, const dynamic_bitset
& b); template
std::istream& operator>>(std::istream& is, dynamic_bitset
& b); #else template
std::basic_ostream
& operator<<(std::basic_ostream
& os, const dynamic_bitset
& b); template
std::basic_istream
& operator>>(std::basic_istream
& is, dynamic_bitset
& b); #endif // bitset operations template
dynamic_bitset
operator&(const dynamic_bitset
& b1, const dynamic_bitset
& b2); template
dynamic_bitset
operator|(const dynamic_bitset
& b1, const dynamic_bitset
& b2); template
dynamic_bitset
operator^(const dynamic_bitset
& b1, const dynamic_bitset
& b2); template
dynamic_bitset
operator-(const dynamic_bitset
& b1, const dynamic_bitset
& b2); // namespace scope swap template
void swap(dynamic_bitset
& b1, dynamic_bitset
& b2); template
void to_string(const dynamic_bitset
& b, stringT & s); template
void to_block_range(const dynamic_bitset
& b, BlockOutputIterator result); template
inline void from_block_range(BlockIterator first, BlockIterator last, dynamic_bitset
& result) { // PRE: distance(first, last) <= numblocks() std::copy (first, last, result.m_bits.begin()); } //============================================================================= // dynamic_bitset implementation //----------------------------------------------------------------------------- // constructors, etc. template
dynamic_bitset
::dynamic_bitset(const Allocator& alloc) : m_bits(alloc), m_num_bits(0) { } template
dynamic_bitset
:: dynamic_bitset(size_type num_bits, unsigned long value, const Allocator& alloc) : m_bits(calc_num_blocks(num_bits), Block(0), alloc), m_num_bits(num_bits) { typedef unsigned long num_type; typedef boost::detail::shifter
shifter; //if (num_bits == 0) // return; // zero out all bits at pos >= num_bits, if any; // note that: num_bits == 0 implies value == 0 if (num_bits < static_cast
(ulong_width)) { const num_type mask = (num_type(1) << num_bits) - 1; value &= mask; } typename buffer_type::iterator it = m_bits.begin(); for( ; value; shifter::left_shift(value), ++it) { *it = static_cast
(value); } } // copy constructor template
inline dynamic_bitset
:: dynamic_bitset(const dynamic_bitset& b) : m_bits(b.m_bits), m_num_bits(b.m_num_bits) { } template
inline dynamic_bitset
:: ~dynamic_bitset() { assert(m_check_invariants()); } template
inline void dynamic_bitset
:: swap(dynamic_bitset
& b) // no throw { std::swap(m_bits, b.m_bits); std::swap(m_num_bits, b.m_num_bits); } template
dynamic_bitset
& dynamic_bitset
:: operator=(const dynamic_bitset
& b) { m_bits = b.m_bits; m_num_bits = b.m_num_bits; return *this; } template
inline typename dynamic_bitset
::allocator_type dynamic_bitset
::get_allocator() const { return m_bits.get_allocator(); } //----------------------------------------------------------------------------- // size changing operations template
void dynamic_bitset
:: resize(size_type num_bits, bool value) // strong guarantee { const size_type old_num_blocks = num_blocks(); const size_type required_blocks = calc_num_blocks(num_bits); const block_type v = value? ~Block(0) : Block(0); if (required_blocks != old_num_blocks) { m_bits.resize(required_blocks, v); // s.g. (copy) } // At this point: // // - if the buffer was shrunk, we have nothing more to do, // except a call to m_zero_unused_bits() // // - if it was enlarged, all the (used) bits in the new blocks have // the correct value, but we have not yet touched those bits, if // any, that were 'unused bits' before enlarging: if value == true, // they must be set. if (value && (num_bits > m_num_bits)) { const size_type extra_bits = count_extra_bits(); if (extra_bits) { assert(old_num_blocks >= 1 && old_num_blocks <= m_bits.size()); // Set them. m_bits[old_num_blocks - 1] |= (v << extra_bits); } } m_num_bits = num_bits; m_zero_unused_bits(); } template
void dynamic_bitset
:: clear() // no throw { m_bits.clear(); m_num_bits = 0; } template
void dynamic_bitset
:: push_back(bool bit) { const size_type sz = size(); resize(sz + 1); set(sz, bit); } template
void dynamic_bitset
:: append(Block value) // strong guarantee { const block_width_type r = count_extra_bits(); if (r == 0) { // the buffer is empty, or all blocks are filled m_bits.push_back(value); } else { m_bits.push_back(value >> (bits_per_block - r)); m_bits[m_bits.size() - 2] |= (value << r); // m_bits.size() >= 2 } m_num_bits += bits_per_block; assert(m_check_invariants()); } //----------------------------------------------------------------------------- // bitset operations template
dynamic_bitset
& dynamic_bitset
::operator&=(const dynamic_bitset& rhs) { assert(size() == rhs.size()); for (size_type i = 0; i < num_blocks(); ++i) m_bits[i] &= rhs.m_bits[i]; return *this; } template
dynamic_bitset
& dynamic_bitset
::operator|=(const dynamic_bitset& rhs) { assert(size() == rhs.size()); for (size_type i = 0; i < num_blocks(); ++i) m_bits[i] |= rhs.m_bits[i]; //m_zero_unused_bits(); return *this; } template
dynamic_bitset
& dynamic_bitset
::operator^=(const dynamic_bitset& rhs) { assert(size() == rhs.size()); for (size_type i = 0; i < this->num_blocks(); ++i) m_bits[i] ^= rhs.m_bits[i]; //m_zero_unused_bits(); return *this; } template
dynamic_bitset
& dynamic_bitset
::operator-=(const dynamic_bitset& rhs) { assert(size() == rhs.size()); for (size_type i = 0; i < num_blocks(); ++i) m_bits[i] &= ~rhs.m_bits[i]; //m_zero_unused_bits(); return *this; } // // NOTE: // Note that the 'if (r != 0)' is crucial to avoid undefined // behavior when the left hand operand of >> isn't promoted to a // wider type (because rs would be too large). // template
dynamic_bitset
& dynamic_bitset
::operator<<=(size_type n) { if (n >= m_num_bits) return reset(); //else if (n > 0) { size_type const last = num_blocks() - 1; // num_blocks() is >= 1 size_type const div = n / bits_per_block; // div is <= last block_width_type const r = bit_index(n); block_type * const b = &m_bits[0]; if (r != 0) { block_width_type const rs = bits_per_block - r; for (size_type i = last-div; i>0; --i) { b[i+div] = (b[i] << r) | (b[i-1] >> rs); } b[div] = b[0] << r; } else { for (size_type i = last-div; i>0; --i) { b[i+div] = b[i]; } b[div] = b[0]; } // disable std::fill_n deprecated warning in MSVC++ 8.0 (warning C4996) // This will only work in MSVC++ 8.0 SP1, which brings up the warning // in the line of user code; otherwise, the warning will come up // in the line in the header itself, so if the user includes stdlib // headers before dynamic_bitset, he will still get the warning. #if defined(_MSC_VER) && _MSC_VER >= 1400 #pragma warning(push) #pragma warning(disable:4996) #endif // zero out div blocks at the less significant end std::fill_n(b, div, static_cast
(0)); #if defined(_MSC_VER) && _MSC_VER >= 1400 #pragma warning(pop) #endif // zero out any 1 bit that flowed into the unused part m_zero_unused_bits(); // thanks to Lester Gong } return *this; } // // NOTE: // see the comments to operator <<= // template
dynamic_bitset
& dynamic_bitset
::operator>>=(size_type n) { if (n >= m_num_bits) { return reset(); } //else if (n>0) { size_type const last = num_blocks() - 1; // num_blocks() is >= 1 size_type const div = n / bits_per_block; // div is <= last block_width_type const r = bit_index(n); block_type * const b = &m_bits[0]; if (r != 0) { block_width_type const ls = bits_per_block - r; for (size_type i = div; i < last; ++i) { b[i-div] = (b[i] >> r) | (b[i+1] << ls); } // r bits go to zero b[last-div] = b[last] >> r; } else { for (size_type i = div; i <= last; ++i) { b[i-div] = b[i]; } // note the '<=': the last iteration 'absorbs' // b[last-div] = b[last] >> 0; } // div blocks are zero filled at the most significant end std::fill_n(b + (num_blocks()-div), div, static_cast
(0)); } return *this; } template
dynamic_bitset
dynamic_bitset
::operator<<(size_type n) const { dynamic_bitset r(*this); return r <<= n; } template
dynamic_bitset
dynamic_bitset
::operator>>(size_type n) const { dynamic_bitset r(*this); return r >>= n; } //----------------------------------------------------------------------------- // basic bit operations template
dynamic_bitset
& dynamic_bitset
::set(size_type pos, bool val) { assert(pos < m_num_bits); if (val) m_bits[block_index(pos)] |= bit_mask(pos); else reset(pos); return *this; } template
dynamic_bitset
& dynamic_bitset
::set() { std::fill(m_bits.begin(), m_bits.end(), ~Block(0)); m_zero_unused_bits(); return *this; } template
dynamic_bitset
& dynamic_bitset
::reset(size_type pos) { assert(pos < m_num_bits); #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x // CodeWarrior 8 generates incorrect code when the &=~ is compiled, // use the |^ variation instead..
m_bits[block_index(pos)] |= bit_mask(pos); m_bits[block_index(pos)] ^= bit_mask(pos); #else m_bits[block_index(pos)] &= ~bit_mask(pos); #endif return *this; } template
dynamic_bitset
& dynamic_bitset
::reset() { std::fill(m_bits.begin(), m_bits.end(), Block(0)); return *this; } template
dynamic_bitset
& dynamic_bitset
::flip(size_type pos) { assert(pos < m_num_bits); m_bits[block_index(pos)] ^= bit_mask(pos); return *this; } template
dynamic_bitset
& dynamic_bitset
::flip() { for (size_type i = 0; i < num_blocks(); ++i) m_bits[i] = ~m_bits[i]; m_zero_unused_bits(); return *this; } template
bool dynamic_bitset
::m_unchecked_test(size_type pos) const { return (m_bits[block_index(pos)] & bit_mask(pos)) != 0; } template
bool dynamic_bitset
::test(size_type pos) const { assert(pos < m_num_bits); return m_unchecked_test(pos); } template
bool dynamic_bitset
::any() const { for (size_type i = 0; i < num_blocks(); ++i) if (m_bits[i]) return true; return false; } template
inline bool dynamic_bitset
::none() const { return !any(); } template
dynamic_bitset
dynamic_bitset
::operator~() const { dynamic_bitset b(*this); b.flip(); return b; } template
typename dynamic_bitset
::size_type dynamic_bitset
::count() const { using namespace detail::dynamic_bitset_count_impl; const bool no_padding = bits_per_block == CHAR_BIT * sizeof(Block); const bool enough_table_width = table_width >= CHAR_BIT; typedef mode_to_type< (no_padding && enough_table_width ? access_by_bytes : access_by_blocks) > m; return do_count(m_bits.begin(), num_blocks(), Block(0), static_cast
(0)); } //----------------------------------------------------------------------------- // conversions template
void to_string_helper(const dynamic_bitset
& b, stringT & s, bool dump_all) { typedef typename stringT::traits_type Tr; typedef typename stringT::value_type Ch; BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, std::locale()); const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0'); const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1'); // Note that this function may access (when // dump_all == true) bits beyond position size() - 1 typedef typename dynamic_bitset
::size_type size_type; const size_type len = dump_all? dynamic_bitset
::bits_per_block * b.num_blocks(): b.size(); s.assign (len, zero); for (size_type i = 0; i < len; ++i) { if (b.m_unchecked_test(i)) Tr::assign(s[len - 1 - i], one); } } // A comment similar to the one about the constructor from // basic_string can be done here. Thanks to James Kanze for // making me (Gennaro) realize this important separation of // concerns issue, as well as many things about i18n. // template
inline void to_string(const dynamic_bitset
& b, stringT& s) { to_string_helper(b, s, false); } // Differently from to_string this function dumps out // every bit of the internal representation (may be // useful for debugging purposes) // template
inline void dump_to_string(const dynamic_bitset
& b, stringT& s) { to_string_helper(b, s, true /* =dump_all*/); } template
inline void to_block_range(const dynamic_bitset
& b, BlockOutputIterator result) { // note how this copies *all* bits, including the // unused ones in the last block (which are zero) std::copy(b.m_bits.begin(), b.m_bits.end(), result); } template
unsigned long dynamic_bitset
:: to_ulong() const { if (m_num_bits == 0) return 0; // convention // Check for overflows. This may be a performance burden on very // large bitsets but is required by the specification, sorry if (find_next(ulong_width - 1) != npos) throw std::overflow_error("boost::dynamic_bitset::to_ulong overflow"); // Ok, from now on we can be sure there's no "on" bit // beyond the "allowed" positions typedef unsigned long result_type; /* if find_next() did its job correctly we don't need the if below, because all bits we care about are in the first block if (bits_per_block >= ulong_width) return static_cast
(m_bits[0]); */ size_type last_block = block_index( (std::min)( m_num_bits, (size_type)ulong_width ) - 1 ); result_type result = 0; for (size_type i = 0; i <= last_block; ++i) { assert((size_type)bits_per_block * i < (size_type)ulong_width); unsigned long piece = m_bits[i]; result |= (piece << (bits_per_block * i)); } return result; } template
inline typename dynamic_bitset
::size_type dynamic_bitset
::size() const { return m_num_bits; } template
inline typename dynamic_bitset
::size_type dynamic_bitset
::num_blocks() const { return m_bits.size(); } template
inline typename dynamic_bitset
::size_type dynamic_bitset
::max_size() const { // Semantics of vector<>::max_size() aren't very clear // (see lib issue 197) and many library implementations // simply return dummy values, _unrelated_ to the underlying // allocator. // // Given these problems, I was tempted to not provide this // function at all but the user could need it if he provides // his own allocator. // const size_type m = detail::vector_max_size_workaround(m_bits); return m <= (size_type(-1)/bits_per_block) ? m * bits_per_block : size_type(-1); } template
inline bool dynamic_bitset
::empty() const { return size() == 0; } template
bool dynamic_bitset
:: is_subset_of(const dynamic_bitset
& a) const { assert(size() == a.size()); for (size_type i = 0; i < num_blocks(); ++i) if (m_bits[i] & ~a.m_bits[i]) return false; return true; } template
bool dynamic_bitset
:: is_proper_subset_of(const dynamic_bitset
& a) const { assert(size() == a.size()); assert(num_blocks() == a.num_blocks()); bool proper = false; for (size_type i = 0; i < num_blocks(); ++i) { const Block & bt = m_bits[i]; const Block & ba = a.m_bits[i]; if (bt & ~ba) return false; // not a subset at all if (ba & ~bt) proper = true; } return proper; } template
bool dynamic_bitset
::intersects(const dynamic_bitset & b) const { size_type common_blocks = num_blocks() < b.num_blocks() ? num_blocks() : b.num_blocks(); for(size_type i = 0; i < common_blocks; ++i) { if(m_bits[i] & b.m_bits[i]) return true; } return false; } // -------------------------------- // lookup // look for the first bit "on", starting // from the block with index first_block // template
typename dynamic_bitset
::size_type dynamic_bitset
::m_do_find_from(size_type first_block) const { size_type i = first_block; // skip null blocks while (i < num_blocks() && m_bits[i] == 0) ++i; if (i >= num_blocks()) return npos; // not found return i * bits_per_block + boost::lowest_bit(m_bits[i]); } template
typename dynamic_bitset
::size_type dynamic_bitset
::find_first() const { return m_do_find_from(0); } template
typename dynamic_bitset
::size_type dynamic_bitset
::find_next(size_type pos) const { const size_type sz = size(); if (pos >= (sz-1) || sz == 0) return npos; ++pos; const size_type blk = block_index(pos); const block_width_type ind = bit_index(pos); // mask out bits before pos const Block fore = m_bits[blk] & ( ~Block(0) << ind ); return fore? blk * bits_per_block + lowest_bit(fore) : m_do_find_from(blk + 1); } //----------------------------------------------------------------------------- // comparison template
bool operator==(const dynamic_bitset
& a, const dynamic_bitset
& b) { return (a.m_num_bits == b.m_num_bits) && (a.m_bits == b.m_bits); } template
inline bool operator!=(const dynamic_bitset