mirror of
https://github.com/boostorg/dynamic_bitset.git
synced 2026-02-02 08:42:17 +00:00
new version (from the sandbox)
[SVN r22648]
This commit is contained in:
@@ -1,129 +1,88 @@
|
||||
// (C) Copyright Chuck Allison and Jeremy Siek 2001, 2002.
|
||||
// --------------------------------------------------
|
||||
//
|
||||
// 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.
|
||||
// (C) Copyright Chuck Allison and Jeremy Siek 2001 - 2002.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// With optimizations by Gennaro Prota.
|
||||
|
||||
#ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP
|
||||
#define BOOST_DETAIL_DYNAMIC_BITSET_HPP
|
||||
|
||||
#include <cstddef> // for std::size_t
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/detail/iterator.hpp"
|
||||
#include "boost/detail/workaround.hpp"
|
||||
//#include "boost/static_assert.hpp" // gps
|
||||
|
||||
#if !(defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || defined(__BORLANDC__))
|
||||
#define BOOST_DYN_BITSET_USE_FRIENDS
|
||||
// ---- Configuration stuff -----------------------
|
||||
// NOTE: gps
|
||||
// - Should be moved to a configuration file
|
||||
//
|
||||
#if (defined __BORLANDC__ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))) \
|
||||
|| (defined BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
|
||||
#endif
|
||||
|
||||
// if we can't use friends then private members are exposed
|
||||
//
|
||||
#if defined(BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS)
|
||||
#define BOOST_DYNAMIC_BITSET_PRIVATE public
|
||||
#else
|
||||
#define BOOST_DYNAMIC_BITSET_PRIVATE private
|
||||
#endif
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Forward references
|
||||
template <typename BlockInputIterator>
|
||||
std::size_t initial_num_blocks(BlockInputIterator first,
|
||||
BlockInputIterator last,
|
||||
std::input_iterator_tag);
|
||||
template <typename BlockForwardIterator>
|
||||
std::size_t initial_num_blocks(BlockForwardIterator first,
|
||||
BlockForwardIterator last,
|
||||
std::forward_iterator_tag);
|
||||
|
||||
// The following 2 classes make sure that the bitset
|
||||
// gets allocated in an exception safe manner
|
||||
template <typename Allocator>
|
||||
class dynamic_bitset_alloc_base {
|
||||
public:
|
||||
dynamic_bitset_alloc_base(const Allocator& alloc)
|
||||
: m_alloc(alloc) { }
|
||||
protected:
|
||||
Allocator m_alloc;
|
||||
};
|
||||
|
||||
|
||||
template <typename Block, typename Allocator>
|
||||
class dynamic_bitset_base :
|
||||
#ifdef BOOST_DYN_BITSET_USE_FRIENDS
|
||||
protected
|
||||
#else
|
||||
public
|
||||
#endif
|
||||
dynamic_bitset_alloc_base<Allocator>
|
||||
// Gives (read-)access to the object representation
|
||||
// of an object of type T (3.9p4). CANNOT be used
|
||||
// on a base sub-object
|
||||
//
|
||||
template <typename T>
|
||||
inline const unsigned char * object_representation (T* p)
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
#ifndef BOOST_DYN_BITSET_USE_FRIENDS
|
||||
public:
|
||||
#endif
|
||||
enum { bits_per_block = CHAR_BIT * sizeof(Block) };
|
||||
public:
|
||||
dynamic_bitset_base()
|
||||
: m_bits(0), m_num_bits(0), m_num_blocks(0) { }
|
||||
return static_cast<const unsigned char *>(static_cast<const void *>(p));
|
||||
}
|
||||
|
||||
dynamic_bitset_base(size_type num_bits, const Allocator& alloc)
|
||||
: dynamic_bitset_alloc_base<Allocator>(alloc),
|
||||
m_bits(dynamic_bitset_alloc_base<Allocator>::
|
||||
m_alloc.allocate(calc_num_blocks(num_bits), static_cast<void const *>(0))),
|
||||
m_num_bits(num_bits),
|
||||
m_num_blocks(calc_num_blocks(num_bits))
|
||||
{
|
||||
using namespace std;
|
||||
memset(m_bits, 0, m_num_blocks * sizeof(Block)); // G.P.S. ask to Jeremy
|
||||
}
|
||||
~dynamic_bitset_base() {
|
||||
if (m_bits)
|
||||
this->m_alloc.deallocate(m_bits, m_num_blocks);
|
||||
}
|
||||
#ifdef BOOST_DYN_BITSET_USE_FRIENDS
|
||||
protected:
|
||||
#endif
|
||||
Block* m_bits;
|
||||
size_type m_num_bits;
|
||||
size_type m_num_blocks;
|
||||
|
||||
static size_type word(size_type bit) { return bit / bits_per_block; } // [gps]
|
||||
static size_type offset(size_type bit){ return bit % bits_per_block; } // [gps]
|
||||
static Block mask1(size_type bit) { return Block(1) << offset(bit); }
|
||||
static Block mask0(size_type bit) { return ~(Block(1) << offset(bit)); }
|
||||
static size_type calc_num_blocks(size_type num_bits)
|
||||
{ return (num_bits + bits_per_block - 1) / bits_per_block; }
|
||||
};
|
||||
// This function is only used to workaround a g++ bug
|
||||
// See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8419
|
||||
//
|
||||
template <typename T>
|
||||
inline T make_non_const(T t) { return t; }
|
||||
|
||||
|
||||
// ------- count table implementation --------------
|
||||
// ------- count function implementation --------------
|
||||
|
||||
typedef unsigned char byte_t;
|
||||
namespace dynamic_bitset_count_impl {
|
||||
|
||||
// only count<true> has a definition
|
||||
#if 0
|
||||
// This was giving Intel C++ and Borland C++ trouble -JGS
|
||||
template <bool = true> struct count;
|
||||
template <> struct count <true> {
|
||||
#else
|
||||
template <bool bogus = true>
|
||||
struct count {
|
||||
#endif
|
||||
typedef byte_t element_type;
|
||||
static const byte_t table[];
|
||||
BOOST_STATIC_CONSTANT (unsigned int, max_bit = 8); // must be a power of two
|
||||
typedef unsigned char byte_type;
|
||||
|
||||
};
|
||||
//typedef count<true> table_t;
|
||||
enum mode { access_by_bytes, access_by_blocks };
|
||||
|
||||
template <mode> struct mode_to_type {};
|
||||
|
||||
// the table: wrapped in a class template, so
|
||||
// that it is only instantiated if/when needed
|
||||
//
|
||||
#if 0
|
||||
// Intel C++ and Borland C++ trouble -JGS
|
||||
template <>
|
||||
const byte_t count <true>::table[] =
|
||||
#else
|
||||
template <bool bogus>
|
||||
const byte_t count<bogus>::table[] =
|
||||
#endif
|
||||
template <bool dummy_name = true>
|
||||
struct count_table { static const byte_type table[]; };
|
||||
|
||||
template <>
|
||||
struct count_table<false> { /* no table */ };
|
||||
|
||||
|
||||
const unsigned int table_width = 8;
|
||||
template <bool b>
|
||||
const byte_type count_table<b>::table[] =
|
||||
{
|
||||
// Automatically generated by GPTableGen.exe v.1.0
|
||||
//
|
||||
@@ -138,39 +97,96 @@ namespace boost {
|
||||
};
|
||||
|
||||
|
||||
// overload for access by bytes
|
||||
//
|
||||
|
||||
template <typename Iterator>
|
||||
inline std::size_t do_count(Iterator first, std::size_t length,
|
||||
int /*dummy param*/,
|
||||
mode_to_type<access_by_bytes>* )
|
||||
{
|
||||
std::size_t num = 0;
|
||||
if (length)
|
||||
{
|
||||
const byte_type * p = object_representation(&*first);
|
||||
length *= sizeof(*first);
|
||||
|
||||
do {
|
||||
num += count_table<>::table[*p];
|
||||
++p;
|
||||
--length;
|
||||
|
||||
} while (length);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
// overload for access by blocks
|
||||
//
|
||||
template <typename Iterator, typename ValueType>
|
||||
inline std::size_t do_count(Iterator first, std::size_t length, ValueType,
|
||||
mode_to_type<access_by_blocks>*)
|
||||
{
|
||||
std::size_t num = 0;
|
||||
while (length){
|
||||
|
||||
ValueType value = *first;
|
||||
while (value) {
|
||||
num += count_table<>::table[value & ((1u<<table_width) - 1)];
|
||||
value >>= table_width;
|
||||
}
|
||||
|
||||
++first;
|
||||
--length;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
} // dynamic_bitset_count_impl
|
||||
// -------------------------------------------------------
|
||||
|
||||
template <typename BlockInputIterator>
|
||||
std::size_t initial_num_blocks(BlockInputIterator first,
|
||||
BlockInputIterator last,
|
||||
std::input_iterator_tag)
|
||||
{
|
||||
return 0;
|
||||
|
||||
// Some library implementations simply return a dummy
|
||||
// value such as
|
||||
//
|
||||
// size_type(-1) / sizeof(T)
|
||||
//
|
||||
// from vector<>::max_size. This tries to get out more
|
||||
// meaningful info.
|
||||
//
|
||||
template <typename T>
|
||||
typename T::size_type vector_max_size_workaround(const T & v) {
|
||||
|
||||
typedef typename T::allocator_type allocator_type;
|
||||
|
||||
const typename allocator_type::size_type alloc_max =
|
||||
v.get_allocator().max_size();
|
||||
const typename T::size_type container_max = v.max_size();
|
||||
|
||||
return alloc_max < container_max?
|
||||
alloc_max :
|
||||
container_max;
|
||||
}
|
||||
|
||||
template <typename BlockForwardIterator>
|
||||
std::size_t initial_num_blocks(BlockForwardIterator first,
|
||||
BlockForwardIterator last,
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
std::size_t n = 0;
|
||||
while (first != last)
|
||||
++first, ++n;
|
||||
return n;
|
||||
}
|
||||
// for static_asserts
|
||||
template <typename T>
|
||||
struct dynamic_bitset_allowed_block_type {
|
||||
enum { value = T(-1) > 0 }; // ensure T has no sign
|
||||
};
|
||||
|
||||
template <typename BlockInputIterator>
|
||||
std::size_t initial_num_blocks(BlockInputIterator first,
|
||||
BlockInputIterator last)
|
||||
{
|
||||
typename detail::iterator_traits<BlockInputIterator>::iterator_category cat;
|
||||
return initial_num_blocks(first, last, cat);
|
||||
}
|
||||
template <>
|
||||
struct dynamic_bitset_allowed_block_type<bool> {
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_DETAIL_DYNAMIC_BITSET_HPP
|
||||
#endif // include guard
|
||||
|
||||
|
||||
1762
include/boost/dynamic_bitset/dynamic_bitset.hpp
Normal file
1762
include/boost/dynamic_bitset/dynamic_bitset.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,16 @@
|
||||
// (C) Copyright Chuck Allison and Jeremy Siek 2001, 2002.
|
||||
// --------------------------------------------------
|
||||
//
|
||||
// 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.
|
||||
// (C) Copyright Chuck Allison and Jeremy Siek 2001 - 2002.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// See http://www.boost.org/libs/dynamic_bitset for documentation.
|
||||
|
||||
#ifndef BOOST_DYNAMIC_BITSET_FWD_HPP
|
||||
#define BOOST_DYNAMIC_BITSET_FWD_HPP
|
||||
@@ -21,4 +25,4 @@ class dynamic_bitset;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_DYNAMIC_BITSET_FWD_HPP
|
||||
#endif // include guard
|
||||
|
||||
Reference in New Issue
Block a user