new version (from the sandbox)

[SVN r22648]
This commit is contained in:
Gennaro Prota
2004-04-18 09:11:17 +00:00
parent e445e12e06
commit 6e9450562e
3 changed files with 1914 additions and 132 deletions

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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