update boost
This commit is contained in:
@@ -34,7 +34,7 @@ namespace boost { namespace detail {
|
||||
#endif
|
||||
|
||||
//
|
||||
#if (defined __BORLANDC__ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))) \
|
||||
#if (defined BOOST_BORLANDC && BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))) \
|
||||
|| (defined BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// Copyright (c) 2014 Glen Joseph Fernandes
|
||||
// (glenjofe@gmail.com)
|
||||
// Copyright (c) 2018 Evgeny Shulgin
|
||||
// Copyright (c) 2019 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -19,6 +20,7 @@
|
||||
#include <cstddef>
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/detail/workaround.hpp"
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
|
||||
#if ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#include <intrin.h>
|
||||
@@ -29,6 +31,14 @@ namespace boost {
|
||||
namespace detail {
|
||||
namespace dynamic_bitset_impl {
|
||||
|
||||
template<class T>
|
||||
struct max_limit {
|
||||
BOOST_STATIC_CONSTEXPR T value = static_cast<T>(-1);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR_OR_CONST T max_limit<T>::value;
|
||||
|
||||
// Gives (read-)access to the object representation
|
||||
// of an object of type T (3.9p4). CANNOT be used
|
||||
// on a base sub-object
|
||||
@@ -85,126 +95,129 @@ namespace boost {
|
||||
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
|
||||
//
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
|
||||
};
|
||||
const unsigned int table_width = 8;
|
||||
template <bool b>
|
||||
const byte_type count_table<b>::table[] =
|
||||
{
|
||||
// Automatically generated by GPTableGen.exe v.1.0
|
||||
//
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
|
||||
};
|
||||
|
||||
|
||||
// overload for access by bytes
|
||||
//
|
||||
// Some platforms have fast popcount operation, that allow us to implement
|
||||
// counting bits much more efficiently
|
||||
//
|
||||
template <typename ValueType>
|
||||
BOOST_FORCEINLINE std::size_t popcount(ValueType value) BOOST_NOEXCEPT
|
||||
{
|
||||
std::size_t num = 0u;
|
||||
while (value) {
|
||||
num += count_table<>::table[value & ((1u<<table_width) - 1)];
|
||||
value >>= table_width;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
inline std::size_t do_count(Iterator first, std::size_t length,
|
||||
int /*dummy param*/,
|
||||
value_to_type<access_by_bytes>* )
|
||||
{
|
||||
std::size_t num = 0;
|
||||
if (length)
|
||||
{
|
||||
const byte_type * p = object_representation(&*first);
|
||||
length *= sizeof(*first);
|
||||
#if (((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))) \
|
||||
&& (defined(__POPCNT__) || defined(__AVX__))
|
||||
|
||||
do {
|
||||
num += count_table<>::table[*p];
|
||||
++p;
|
||||
--length;
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned short>(unsigned short value) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<std::size_t>(__popcnt16(value));
|
||||
}
|
||||
|
||||
} while (length);
|
||||
}
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned int>(unsigned int value) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<std::size_t>(__popcnt(value));
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
// Some platforms have fast popcount operation, that allow us to implement
|
||||
// counting bits much more efficiently
|
||||
//
|
||||
template <typename ValueType>
|
||||
BOOST_FORCEINLINE std::size_t popcount(ValueType value) BOOST_NOEXCEPT
|
||||
{
|
||||
std::size_t num = 0;
|
||||
while (value) {
|
||||
num += count_table<>::table[value & ((1u<<table_width) - 1)];
|
||||
value >>= table_width;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
#if ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))
|
||||
|
||||
/*
|
||||
per https://github.com/boostorg/dynamic_bitset/issues/33
|
||||
this code does not support older cpus properly...
|
||||
it needs to check for cpuid support to avoid undefined behavior
|
||||
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned short>(unsigned short value) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<std::size_t>(__popcnt16(value));
|
||||
}
|
||||
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned int>(unsigned int value) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<std::size_t>(__popcnt(value));
|
||||
}
|
||||
|
||||
#ifdef _M_X64
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned __int64>(unsigned __int64 value) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<std::size_t>(__popcnt64(value));
|
||||
}
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned __int64>(unsigned __int64 value) BOOST_NOEXCEPT
|
||||
{
|
||||
#if defined(_M_X64)
|
||||
return static_cast<std::size_t>(__popcnt64(value));
|
||||
#else
|
||||
return static_cast<std::size_t>(__popcnt(static_cast< unsigned int >(value))) + static_cast<std::size_t>(__popcnt(static_cast< unsigned int >(value >> 32)));
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
#elif defined(BOOST_GCC) || defined(__clang__) || (defined(BOOST_INTEL) && defined(__GNUC__))
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned int>(unsigned int value) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_popcount(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned long>(unsigned long value) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_popcountl(value);
|
||||
}
|
||||
// Note: gcc builtins are implemented by compiler runtime when the target CPU may not support the necessary instructions
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned short>(unsigned short value) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<unsigned int>(__builtin_popcount(static_cast<unsigned int>(value)));
|
||||
}
|
||||
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned int>(unsigned int value) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<unsigned int>(__builtin_popcount(value));
|
||||
}
|
||||
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<unsigned long>(unsigned long value) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<unsigned int>(__builtin_popcountl(value));
|
||||
}
|
||||
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<boost::ulong_long_type>(boost::ulong_long_type value) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<unsigned int>(__builtin_popcountll(value));
|
||||
}
|
||||
|
||||
template <>
|
||||
BOOST_FORCEINLINE std::size_t popcount<boost::ulong_long_type>(boost::ulong_long_type value) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_popcountll(value);
|
||||
}
|
||||
#endif
|
||||
|
||||
// overload for access by blocks
|
||||
//
|
||||
template <typename Iterator, typename ValueType>
|
||||
inline std::size_t do_count(Iterator first, std::size_t length, ValueType,
|
||||
value_to_type<access_by_blocks>*)
|
||||
{
|
||||
std::size_t num = 0;
|
||||
while (length){
|
||||
num += popcount<ValueType>(*first);
|
||||
++first;
|
||||
--length;
|
||||
}
|
||||
// overload for access by blocks
|
||||
//
|
||||
template <typename Iterator, typename ValueType>
|
||||
inline std::size_t do_count(Iterator first, std::size_t length, ValueType,
|
||||
value_to_type<access_by_blocks>*)
|
||||
{
|
||||
std::size_t num1 = 0u, num2 = 0u;
|
||||
while (length >= 2u) {
|
||||
num1 += popcount<ValueType>(*first);
|
||||
++first;
|
||||
num2 += popcount<ValueType>(*first);
|
||||
++first;
|
||||
length -= 2u;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
if (length > 0u)
|
||||
num1 += popcount<ValueType>(*first);
|
||||
|
||||
return num1 + num2;
|
||||
}
|
||||
|
||||
// overload for access by bytes
|
||||
//
|
||||
template <typename Iterator>
|
||||
inline std::size_t do_count(Iterator first, std::size_t length,
|
||||
int /*dummy param*/,
|
||||
value_to_type<access_by_bytes>*)
|
||||
{
|
||||
if (length > 0u) {
|
||||
const byte_type* p = object_representation(&*first);
|
||||
length *= sizeof(*first);
|
||||
|
||||
return do_count(p, length, static_cast<byte_type>(0u),
|
||||
static_cast< value_to_type<access_by_blocks>* >(0));
|
||||
}
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
|
||||
@@ -225,14 +238,8 @@ namespace boost {
|
||||
|
||||
const allocator_type& alloc = v.get_allocator();
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef std::allocator_traits<allocator_type> allocator_traits;
|
||||
|
||||
const typename allocator_traits::size_type alloc_max =
|
||||
allocator_traits::max_size(alloc);
|
||||
#else
|
||||
const typename allocator_type::size_type alloc_max = alloc.max_size();
|
||||
#endif
|
||||
typename boost::allocator_size_type<allocator_type>::type alloc_max =
|
||||
boost::allocator_max_size(alloc);
|
||||
|
||||
const typename T::size_type container_max = v.max_size();
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <iterator> // used to implement append(Iter, Iter)
|
||||
#include <vector>
|
||||
#include <climits> // for CHAR_BIT
|
||||
|
||||
@@ -43,13 +44,13 @@
|
||||
#include "boost/dynamic_bitset_fwd.hpp"
|
||||
#include "boost/dynamic_bitset/detail/dynamic_bitset.hpp"
|
||||
#include "boost/dynamic_bitset/detail/lowest_bit.hpp"
|
||||
#include "boost/detail/iterator.hpp" // used to implement append(Iter, Iter)
|
||||
#include "boost/move/move.hpp"
|
||||
#include "boost/limits.hpp"
|
||||
#include "boost/static_assert.hpp"
|
||||
#include "boost/utility/addressof.hpp"
|
||||
#include "boost/detail/no_exceptions_support.hpp"
|
||||
#include "boost/core/addressof.hpp"
|
||||
#include "boost/core/no_exceptions_support.hpp"
|
||||
#include "boost/throw_exception.hpp"
|
||||
#include "boost/functional/hash/hash.hpp"
|
||||
|
||||
|
||||
namespace boost {
|
||||
@@ -127,8 +128,10 @@ public:
|
||||
typedef bool const_reference;
|
||||
|
||||
// constructors, etc.
|
||||
dynamic_bitset() : m_num_bits(0) {}
|
||||
|
||||
explicit
|
||||
dynamic_bitset(const Allocator& alloc = Allocator());
|
||||
dynamic_bitset(const Allocator& alloc);
|
||||
|
||||
explicit
|
||||
dynamic_bitset(size_type num_bits, unsigned long value = 0,
|
||||
@@ -244,7 +247,7 @@ public:
|
||||
{
|
||||
assert(first != last);
|
||||
block_width_type r = count_extra_bits();
|
||||
std::size_t d = boost::detail::distance(first, last);
|
||||
std::size_t d = std::distance(first, last);
|
||||
m_bits.reserve(num_blocks() + d);
|
||||
if (r == 0) {
|
||||
for( ; first != last; ++first)
|
||||
@@ -264,7 +267,7 @@ public:
|
||||
void append(BlockInputIterator first, BlockInputIterator last) // strong guarantee
|
||||
{
|
||||
if (first != last) {
|
||||
typename detail::iterator_traits<BlockInputIterator>::iterator_category cat;
|
||||
typename std::iterator_traits<BlockInputIterator>::iterator_category cat;
|
||||
m_append(first, last, cat);
|
||||
}
|
||||
}
|
||||
@@ -290,6 +293,8 @@ public:
|
||||
dynamic_bitset& flip(size_type n, size_type len);
|
||||
dynamic_bitset& flip(size_type n);
|
||||
dynamic_bitset& flip();
|
||||
reference at(size_type n);
|
||||
bool at(size_type n) const;
|
||||
bool test(size_type n) const;
|
||||
bool test_set(size_type n, bool val = true);
|
||||
bool all() const;
|
||||
@@ -354,7 +359,8 @@ public:
|
||||
template <typename B, typename A, typename stringT>
|
||||
friend void to_string_helper(const dynamic_bitset<B, A> & b, stringT & s, bool dump_all);
|
||||
|
||||
|
||||
template <typename B, typename A>
|
||||
friend std::size_t hash_value(const dynamic_bitset<B, A>& a);
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -371,6 +377,7 @@ private:
|
||||
void m_zero_unused_bits();
|
||||
bool m_check_invariants() const;
|
||||
|
||||
static bool m_not_empty(Block x){ return x != Block(0); };
|
||||
size_type m_do_find_from(size_type first_block) const;
|
||||
|
||||
block_width_type count_extra_bits() const BOOST_NOEXCEPT { return bit_index(size()); }
|
||||
@@ -380,7 +387,7 @@ private:
|
||||
static Block bit_mask(size_type first, size_type last) BOOST_NOEXCEPT
|
||||
{
|
||||
Block res = (last == bits_per_block - 1)
|
||||
? static_cast<Block>(~0)
|
||||
? detail::dynamic_bitset_impl::max_limit<Block>::value
|
||||
: ((Block(1) << (last + 1)) - 1);
|
||||
res ^= (Block(1) << first) - 1;
|
||||
return res;
|
||||
@@ -402,7 +409,7 @@ private:
|
||||
}
|
||||
inline static Block set_block_full(Block) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<Block>(~0);
|
||||
return detail::dynamic_bitset_impl::max_limit<Block>::value;
|
||||
}
|
||||
inline static Block reset_block_partial(Block block, size_type first,
|
||||
size_type last) BOOST_NOEXCEPT
|
||||
@@ -760,7 +767,7 @@ 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);
|
||||
const block_type v = value? detail::dynamic_bitset_impl::max_limit<Block>::value : Block(0);
|
||||
|
||||
if (required_blocks != old_num_blocks) {
|
||||
m_bits.resize(required_blocks, v); // s.g. (copy)
|
||||
@@ -1041,7 +1048,7 @@ template <typename Block, typename Allocator>
|
||||
dynamic_bitset<Block, Allocator>&
|
||||
dynamic_bitset<Block, Allocator>::set()
|
||||
{
|
||||
std::fill(m_bits.begin(), m_bits.end(), static_cast<Block>(~0));
|
||||
std::fill(m_bits.begin(), m_bits.end(), detail::dynamic_bitset_impl::max_limit<Block>::value);
|
||||
m_zero_unused_bits();
|
||||
return *this;
|
||||
}
|
||||
@@ -1109,6 +1116,25 @@ bool dynamic_bitset<Block, Allocator>::m_unchecked_test(size_type pos) const
|
||||
return (m_bits[block_index(pos)] & bit_mask(pos)) != 0;
|
||||
}
|
||||
|
||||
template <typename Block, typename Allocator>
|
||||
typename dynamic_bitset<Block, Allocator>::reference
|
||||
dynamic_bitset<Block, Allocator>::at(size_type pos)
|
||||
{
|
||||
if (pos >= m_num_bits)
|
||||
BOOST_THROW_EXCEPTION(std::out_of_range("boost::dynamic_bitset::at out_of_range"));
|
||||
|
||||
return (*this)[pos];
|
||||
}
|
||||
|
||||
template <typename Block, typename Allocator>
|
||||
bool dynamic_bitset<Block, Allocator>::at(size_type pos) const
|
||||
{
|
||||
if (pos >= m_num_bits)
|
||||
BOOST_THROW_EXCEPTION(std::out_of_range("boost::dynamic_bitset::at out_of_range"));
|
||||
|
||||
return (*this)[pos];
|
||||
}
|
||||
|
||||
template <typename Block, typename Allocator>
|
||||
bool dynamic_bitset<Block, Allocator>::test(size_type pos) const
|
||||
{
|
||||
@@ -1134,7 +1160,7 @@ bool dynamic_bitset<Block, Allocator>::all() const
|
||||
}
|
||||
|
||||
const block_width_type extra_bits = count_extra_bits();
|
||||
block_type const all_ones = static_cast<Block>(~0);
|
||||
block_type const all_ones = detail::dynamic_bitset_impl::max_limit<Block>::value;
|
||||
|
||||
if (extra_bits == 0) {
|
||||
for (size_type i = 0, e = num_blocks(); i < e; ++i) {
|
||||
@@ -1437,15 +1463,14 @@ bool dynamic_bitset<Block, Allocator>::intersects(const dynamic_bitset & b) cons
|
||||
// look for the first bit "on", starting
|
||||
// from the block with index first_block
|
||||
//
|
||||
|
||||
template <typename Block, typename Allocator>
|
||||
typename dynamic_bitset<Block, Allocator>::size_type
|
||||
dynamic_bitset<Block, Allocator>::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;
|
||||
size_type i = std::distance(m_bits.begin(),
|
||||
std::find_if(m_bits.begin() + first_block, m_bits.end(), m_not_empty) );
|
||||
|
||||
if (i >= num_blocks())
|
||||
return npos; // not found
|
||||
@@ -1622,6 +1647,17 @@ inline bool operator>=(const dynamic_bitset<Block, Allocator>& a,
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// hash operations
|
||||
|
||||
template <typename Block, typename Allocator>
|
||||
inline std::size_t hash_value(const dynamic_bitset<Block, Allocator>& a)
|
||||
{
|
||||
std::size_t res = hash_value(a.m_num_bits);
|
||||
boost::hash_combine(res, a.m_bits);
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// stream operations
|
||||
|
||||
@@ -2092,7 +2128,7 @@ bool dynamic_bitset<Block, Allocator>::m_check_invariants() const
|
||||
{
|
||||
const block_width_type extra_bits = count_extra_bits();
|
||||
if (extra_bits > 0) {
|
||||
const block_type mask = block_type(~0) << extra_bits;
|
||||
const block_type mask = detail::dynamic_bitset_impl::max_limit<Block>::value << extra_bits;
|
||||
if ((m_highest_block() & mask) != 0)
|
||||
return false;
|
||||
}
|
||||
@@ -2106,8 +2142,26 @@ bool dynamic_bitset<Block, Allocator>::m_check_invariants() const
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#undef BOOST_BITSET_CHAR
|
||||
|
||||
// std::hash support
|
||||
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) && !defined(BOOST_DYNAMIC_BITSET_NO_STD_HASH)
|
||||
#include <functional>
|
||||
namespace std
|
||||
{
|
||||
template<typename Block, typename Allocator>
|
||||
struct hash< boost::dynamic_bitset<Block, Allocator> >
|
||||
{
|
||||
typedef boost::dynamic_bitset<Block, Allocator> argument_type;
|
||||
typedef std::size_t result_type;
|
||||
result_type operator()(const argument_type& a) const BOOST_NOEXCEPT
|
||||
{
|
||||
boost::hash<argument_type> hasher;
|
||||
return hasher(a);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // include guard
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#define BOOST_DYNAMIC_BITSET_SERIALIZATION_HPP
|
||||
|
||||
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#include <boost/core/nvp.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace boost {
|
||||
public:
|
||||
template <typename Ar>
|
||||
static void serialize(Ar& ar, dynamic_bitset<Block, Allocator>& bs, unsigned) {
|
||||
ar & serialization::make_nvp("m_num_bits", bs.m_num_bits)
|
||||
& serialization::make_nvp("m_bits", bs.m_bits);
|
||||
ar & boost::make_nvp("m_num_bits", bs.m_num_bits)
|
||||
& boost::make_nvp("m_bits", bs.m_bits);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user