bitset.hpp
来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 908 行 · 第 1/3 页
HPP
908 行
// (C) Copyright Jeremy Siek 2001. Permission to copy, use, modify,// sell and distribute this software is granted provided this// copyright notice appears in all copies. This software is provided// "as is" without express or implied warranty, and with no claim as// to its suitability for any purpose./* * Copyright (c) 1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */#include <boost/config.hpp>#include <memory>#include <stdexcept>#include <algorithm>#include <string>#include <boost/config.hpp>#include <boost/pending/ct_if.hpp>#include <boost/graph/detail/bitset_adaptor.hpp>// This provides versions of std::bitset with both static and dynamic size.// UNDER CONSTRUCTION// replace this later#include <cassert>#define BOOST_ASSERT_THROW(expr, except) assert(expr)namespace boost { namespace detail { // structure to aid in counting bits template<bool dummy = true> struct bit_count { static unsigned char value[256]; }; // Mapping from 8 bit unsigned integers to the index of the first bit template<bool dummy = true> struct first_bit_location { static unsigned char value[256]; }; template <typename WordType> // this size is in bits struct word_traits { typedef WordType word_type; static const std::size_t word_size = CHAR_BIT * sizeof(word_type); }; //========================================================================= template <class WordTraits, class SizeType, class Derived> class bitset_base : public bitset_adaptor< SizeType, bitset_base<WordTraits, SizeType, Derived> > { // private: public: typedef SizeType size_type; typedef typename WordTraits::word_type word_type; static size_type s_which_word(size_type pos) { return pos / WordTraits::word_size; } static size_type s_which_byte(size_type pos) { return (pos % WordTraits::word_size) / CHAR_BIT; } static size_type s_which_bit(size_type pos) { return pos % WordTraits::word_size; } static word_type s_mask_bit(size_type pos) { return (static_cast<word_type>(1)) << s_which_bit(pos); } word_type& m_get_word(size_type pos) { return data()[s_which_word(pos)]; } word_type m_get_word(size_type pos) const { return data()[s_which_word(pos)]; } word_type& m_hi_word() { return data()[num_words() - 1]; } word_type m_hi_word() const { return data()[num_words() - 1]; } void m_sanitize_highest() { size_type extra_bits = size() % WordTraits::word_size; if (extra_bits) m_hi_word() &= ~((~static_cast<word_type>(0)) << extra_bits); } public: class reference { friend class bitset_base; word_type *m_word_ptr; size_type m_bit_pos; // left undefined reference(); reference(bitset_base& b, size_type pos ) { m_word_ptr = &b.m_get_word(pos); m_bit_pos = s_which_bit(pos); } public: ~reference() {} // for b[i] = x; reference& operator=(bool x) { if ( x ) *m_word_ptr |= s_mask_bit(m_bit_pos); else *m_word_ptr &= ~s_mask_bit(m_bit_pos); return *this; } // for b[i] = b[j]; reference& operator=(const reference& j) { if ( (*(j.m_word_ptr) & s_mask_bit(j.m_bit_pos)) ) *m_word_ptr |= s_mask_bit(m_bit_pos); else *m_word_ptr &= ~s_mask_bit(m_bit_pos); return *this; } // flips the bit bool operator~() const { return (*(m_word_ptr) & s_mask_bit(m_bit_pos)) == 0; } // for x = b[i]; operator bool() const { return (*(m_word_ptr) & s_mask_bit(m_bit_pos)) != 0; } // for b[i].flip(); reference& flip() { *m_word_ptr ^= s_mask_bit(m_bit_pos); return *this; } }; void init_from_ulong(unsigned long val) { reset(); const size_type n = (std::min)(sizeof(unsigned long) * CHAR_BIT, WordTraits::word_size * num_words()); for(size_type i = 0; i < n; ++i, val >>= 1) if ( val & 0x1 ) m_get_word(i) |= s_mask_bit(i); } // intersection: this = this & x Derived& operator&=(const Derived& x) { for (size_type i = 0; i < num_words(); ++i) data()[i] &= x.data()[i]; return static_cast<Derived&>(*this); } // union: this = this | x Derived& operator|=(const Derived& x) { for (size_type i = 0; i < num_words(); ++i) data()[i] |= x.data()[i]; return static_cast<Derived&>(*this); } // exclusive or: this = this ^ x Derived& operator^=(const Derived& x) { for (size_type i = 0; i < num_words(); ++i) data()[i] ^= x.data()[i]; return static_cast<Derived&>(*this); } // left shift Derived& operator<<=(size_type pos); // right shift Derived& operator>>=(size_type pos); Derived& set() { for (size_type i = 0; i < num_words(); ++i) data()[i] = ~static_cast<word_type>(0); m_sanitize_highest(); return static_cast<Derived&>(*this); } Derived& set(size_type pos, int val = true) { BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::set(pos,value)")); if (val) m_get_word(pos) |= s_mask_bit(pos); else m_get_word(pos) &= ~s_mask_bit(pos); return static_cast<Derived&>(*this); } Derived& reset() { for (size_type i = 0; i < num_words(); ++i) data()[i] = 0; return static_cast<Derived&>(*this); } Derived& reset(size_type pos) { BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::reset(pos)")); m_get_word(pos) &= ~s_mask_bit(pos); return static_cast<Derived&>(*this); } // compliment Derived operator~() const { return Derived(static_cast<const Derived&>(*this)).flip(); } Derived& flip() { for (size_type i = 0; i < num_words(); ++i) data()[i] = ~data()[i]; m_sanitize_highest(); return static_cast<Derived&>(*this); } Derived& flip(size_type pos) { BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::flip(pos)")); m_get_word(pos) ^= s_mask_bit(pos); return static_cast<Derived&>(*this); } // element access reference operator[](size_type pos) { return reference(*this, pos); } bool operator[](size_type pos) const { return test(pos); } unsigned long to_ulong() const; // to_string size_type count() const { size_type result = 0; const unsigned char* byte_ptr = (const unsigned char*)data(); const unsigned char* end_ptr = (const unsigned char*)(data() + num_words()); while ( byte_ptr < end_ptr ) { result += bit_count<>::value[*byte_ptr]; byte_ptr++; } return result; } // size() must be provided by Derived class bool operator==(const Derived& x) const { return std::equal(data(), data() + num_words(), x.data()); } bool operator!=(const Derived& x) const { return ! this->operator==(x); } bool test(size_type pos) const { BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::test(pos)")); return (m_get_word(pos) & s_mask_bit(pos)) != static_cast<word_type>(0); } bool any() const { for (size_type i = 0; i < num_words(); ++i) { if ( data()[i] != static_cast<word_type>(0) ) return true; } return false; } bool none() const { return !any(); } Derived operator<<(size_type pos) const { return Derived(static_cast<const Derived&>(*this)) <<= pos; } Derived operator>>(size_type pos) const { return Derived(static_cast<const Derived&>(*this)) >>= pos; } template <class CharT, class Traits, class Alloc> void m_copy_from_string(const basic_string<CharT,Traits,Alloc>& s, size_type pos, size_type n) { reset(); const size_type nbits = (std::min)(size(), (std::min)(n, s.size() - pos)); for (size_type i = 0; i < nbits; ++i) { switch(s[pos + nbits - i - 1]) { case '0': break; case '1': this->set(i); break; default: throw std::invalid_argument ("boost::bitset_base::m_copy_from_string(s, pos, n)"); } } } template <class CharT, class Traits, class Alloc> void m_copy_to_string(basic_string<CharT, Traits, Alloc>& s) const {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?