Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73393 - in sandbox/bloom_filter/trunk/boost/bloom_filter: . detail
From: cpp.cabrera_at_[hidden]
Date: 2011-07-26 17:23:54


Author: alejandro
Date: 2011-07-26 17:23:52 EDT (Tue, 26 Jul 2011)
New Revision: 73393
URL: http://svn.boost.org/trac/boost/changeset/73393

Log:
Major refactoring on apply_hash:
        - combined dynamic_apply_hash and apply_hash into a single meta-function.

Updated basic_bloom_filter and dynamic_bloom_filter:
        - both use new version of apply_hash.
        - added incompatible_size_exception for pairwise operations

Working on refactoring counting_apply_hash.

Bug:
        - counting_bloom_filter: bin_exceptions do not trigger.
Text files modified:
   sandbox/bloom_filter/trunk/boost/bloom_filter/basic_bloom_filter.hpp | 18 +++--
   sandbox/bloom_filter/trunk/boost/bloom_filter/counting_bloom_filter.hpp | 42 +++++++-------
   sandbox/bloom_filter/trunk/boost/bloom_filter/detail/apply_hash.hpp | 119 ++++++++++-----------------------------
   sandbox/bloom_filter/trunk/boost/bloom_filter/detail/counting_apply_hash.hpp | 64 ++++++++++++++-------
   sandbox/bloom_filter/trunk/boost/bloom_filter/detail/exceptions.hpp | 15 +++-
   sandbox/bloom_filter/trunk/boost/bloom_filter/dynamic_bloom_filter.hpp | 65 +++++++++++++--------
   6 files changed, 158 insertions(+), 165 deletions(-)

Modified: sandbox/bloom_filter/trunk/boost/bloom_filter/basic_bloom_filter.hpp
==============================================================================
--- sandbox/bloom_filter/trunk/boost/bloom_filter/basic_bloom_filter.hpp (original)
+++ sandbox/bloom_filter/trunk/boost/bloom_filter/basic_bloom_filter.hpp 2011-07-26 17:23:52 EDT (Tue, 26 Jul 2011)
@@ -12,11 +12,7 @@
 
 #ifndef BOOST_BLOOM_FILTER_BLOOM_FILTER_HPP
 #define BOOST_BLOOM_FILTER_BLOOM_FILTER_HPP 1
-/**
- * \author Alejandro Cabrera
- * \brief A generic Bloom filter providing compile-time unrolling
- * of hash function application.
- */
+
 #include <cmath>
 #include <bitset>
 
@@ -40,7 +36,10 @@
     public:
       typedef T value_type;
       typedef T key_type;
+ typedef std::bitset<Size> bitset_type;
       typedef HashFunctions hash_function_type;
+ typedef basic_bloom_filter<T, Size,
+ HashFunctions> this_type;
 
     public:
       basic_bloom_filter() {}
@@ -87,7 +86,8 @@
 
       void insert(const T& t) {
         static const unsigned N = mpl::size<HashFunctions>::value - 1;
- detail::apply_hash<N, T, Size, HashFunctions>::insert(t, bits);
+ detail::apply_hash<N,
+ this_type>::insert(t, bits);
       }
 
       template <typename InputIterator>
@@ -99,7 +99,9 @@
 
       bool probably_contains(const T& t) const {
         static const unsigned N = mpl::size<HashFunctions>::value - 1;
- return detail::apply_hash<N, T, Size, HashFunctions>::contains(t, bits);
+ return detail::
+ apply_hash<N,
+ this_type>::contains(t, bits);
       }
 
       void clear() {
@@ -133,7 +135,7 @@
                  const basic_bloom_filter<_T, _Size, _HashFunctions>&);
       
     private:
- std::bitset<Size> bits;
+ bitset_type bits;
     };
 
     template<class _T, size_t _Size, class _HashFunctions>

Modified: sandbox/bloom_filter/trunk/boost/bloom_filter/counting_bloom_filter.hpp
==============================================================================
--- sandbox/bloom_filter/trunk/boost/bloom_filter/counting_bloom_filter.hpp (original)
+++ sandbox/bloom_filter/trunk/boost/bloom_filter/counting_bloom_filter.hpp 2011-07-26 17:23:52 EDT (Tue, 26 Jul 2011)
@@ -59,7 +59,7 @@
       // can have internal fragmentation if the calculation for
       // bins_per_slot has a remainder. The severity of the internal
       // fragmentation is equal to the remainder * the number of slots.
- // this check prevents internal fragmentation
+ // This check prevents internal fragmentation
       BOOST_STATIC_ASSERT( ((sizeof(Block) * 8) % BitsPerBin) == 0);
 
       // a slot is one element position in the array
@@ -72,17 +72,16 @@
       static const size_t mask =
         static_cast<Block>(0 - 1) >> (slot_bits - BitsPerBin);
 
- private:
- typedef boost::array<Block, array_size> bucket_type;
- typedef typename bucket_type::iterator bucket_iterator;
- typedef typename bucket_type::const_iterator bucket_const_iterator;
-
     public:
       typedef T value_type;
       typedef T key_type;
       typedef HashFunctions hash_function_type;
       typedef Block block_type;
 
+ typedef boost::array<Block, array_size> bucket_type;
+ typedef typename bucket_type::iterator bucket_iterator;
+ typedef typename bucket_type::const_iterator bucket_const_iterator;
+
     public:
       counting_bloom_filter()
       {
@@ -130,13 +129,6 @@
       size_t count() const {
         size_t ret = 0;
 
- /*
- std::cout << "Num Bins: " << NumBins << "\n"
- << "Bins Per Slot: " << bins_per_slot << "\n"
- << "Bits Per Bin: " << BitsPerBin << "\n"
- << "Array Size: " << array_size << "\n";
- */
-
         for (bucket_const_iterator i = this->bits.begin(),
                end = this->bits.end();
              i != end; ++i) {
@@ -144,14 +136,6 @@
             size_t offset_bits = bin * BitsPerBin;
             size_t target_bits = (*i >> offset_bits) & mask;
 
- /*
- std::cout << "(count) targeting pos: " << std::distance(i, end) - 1
- << " with offset: " << offset_bits
- << " and bin: " << bin
- << " with slot value: " << *i
- << " and bin value: " << target_bits << "\n";
- */
-
             if (target_bits > 0)
               ++ret;
           }
@@ -217,11 +201,27 @@
 
       counting_bloom_filter& operator|=(const counting_bloom_filter& rhs)
       {
+ const bucket_iterator this_end = this->bits.end();
+ bucket_iterator this_start = this->bits.begin();
+ bucket_iterator rhs_start = rhs.bits.begin();
+
+ for (; this_start != this_end; ++this_start, ++rhs_start) {
+ *this_start |= *rhs_start;
+ }
+
         return *this;
       }
 
       counting_bloom_filter& operator&=(const counting_bloom_filter& rhs)
       {
+ const bucket_iterator this_end = this->bits.end();
+ bucket_iterator this_start = this->bits.begin();
+ bucket_iterator rhs_start = rhs.bits.begin();
+
+ for (; this_start != this_end; ++this_start, ++rhs_start) {
+ *this_start &= *rhs_start;
+ }
+
         return *this;
       }
 

Modified: sandbox/bloom_filter/trunk/boost/bloom_filter/detail/apply_hash.hpp
==============================================================================
--- sandbox/bloom_filter/trunk/boost/bloom_filter/detail/apply_hash.hpp (original)
+++ sandbox/bloom_filter/trunk/boost/bloom_filter/detail/apply_hash.hpp 2011-07-26 17:23:52 EDT (Tue, 26 Jul 2011)
@@ -13,122 +13,67 @@
 #ifndef BOOST_BLOOM_FILTER_APPLY_HASH_HPP
 #define BOOST_BLOOM_FILTER_APPLY_HASH_HPP
 
-#include <bitset>
-#include <boost/dynamic_bitset.hpp>
 #include <boost/mpl/at.hpp>
 
 namespace boost {
   namespace bloom_filters {
     namespace detail {
 
- /*************************************************************************
- * static bloom filter
- ************************************************************************/
       template <size_t N,
- typename T,
- size_t Size,
- class HashFunctions>
+ typename Container>
       struct apply_hash
       {
- static void insert(const T& t, std::bitset<Size>& _bits) {
- typedef typename boost::mpl::at_c<HashFunctions, N>::type Hash;
- static Hash hasher;
-
- _bits[hasher(t) % Size] = true;
- apply_hash<N-1, T, Size, HashFunctions>::insert(t, _bits);
- }
-
- static bool contains(const T& t, const std::bitset<Size>& _bits) {
- typedef typename boost::mpl::at_c<HashFunctions, N>::type Hash;
- static Hash hasher;
+ typedef typename Container::value_type value_type;
+ typedef typename Container::bitset_type bitset_type;
+ typedef typename Container::hash_function_type hash_function_type;
 
- return (_bits[hasher(t) % Size] &&
- apply_hash<N-1, T, Size, HashFunctions>::contains(t, _bits));
- }
- };
-
- template <typename T,
- size_t Size,
- class HashFunctions>
- struct apply_hash<0, T, Size, HashFunctions>
- {
- static void insert(const T& t, std::bitset<Size>& _bits) {
- typedef typename boost::mpl::at_c<HashFunctions, 0>::type Hash;
+ static void insert(const value_type& t,
+ bitset_type& _bits)
+ {
+ typedef typename boost::mpl::at_c<hash_function_type, N>::type Hash;
           static Hash hasher;
 
- _bits[hasher(t) % Size] = true;
+ _bits[hasher(t) % _bits.size()] = true;
+ apply_hash<N-1, Container>::insert(t, _bits);
         }
 
- static bool contains(const T& t, const std::bitset<Size>& _bits) {
- typedef typename boost::mpl::at_c<HashFunctions, 0>::type Hash;
+ static bool contains(const value_type& t,
+ const bitset_type& _bits)
+ {
+ typedef typename boost::mpl::at_c<hash_function_type, N>::type Hash;
           static Hash hasher;
 
- return (_bits[hasher(t) % Size]);
+ return (_bits[hasher(t) % _bits.size()] &&
+ apply_hash<N-1, Container>::contains(t, _bits));
         }
       };
 
- /*************************************************************************
- * dynamic bloom filter
- ************************************************************************/
- template <size_t N,
- typename T,
- class HashFunctions,
- typename Block,
- class Allocator>
- struct dynamic_apply_hash
+ template <typename Container>
+ struct apply_hash<0, Container>
       {
- static void insert(const T& t, boost::dynamic_bitset<Block, Allocator>& _bits,
- const size_t size) {
- typedef typename boost::mpl::at_c<HashFunctions, N>::type Hash;
- static Hash hasher;
-
- _bits[hasher(t) % size] = true;
- dynamic_apply_hash<N-1,
- T,
- HashFunctions,
- Block,
- Allocator>::insert(t, _bits, size);
- }
-
- static bool contains(const T& t,
- const boost::dynamic_bitset<Block, Allocator>& _bits,
- const size_t size) {
- typedef typename boost::mpl::at_c<HashFunctions, N>::type Hash;
- static Hash hasher;
+ typedef typename Container::value_type value_type;
+ typedef typename Container::bitset_type bitset_type;
+ typedef typename Container::hash_function_type hash_function_type;
 
- return (_bits[hasher(t) % size] &&
- dynamic_apply_hash<N-1,
- T,
- HashFunctions,
- Block,
- Allocator>::contains(t, _bits, size));
- }
- };
-
- template <typename T,
- class HashFunctions,
- typename Block,
- class Allocator>
- struct dynamic_apply_hash<0, T, HashFunctions, Block, Allocator>
- {
- static void insert(const T& t,
- boost::dynamic_bitset<Block, Allocator>& _bits,
- const size_t size) {
- typedef typename boost::mpl::at_c<HashFunctions, 0>::type Hash;
+ static void insert(const value_type& t,
+ bitset_type& _bits)
+ {
+ typedef typename boost::mpl::at_c<hash_function_type, 0>::type Hash;
           static Hash hasher;
 
- _bits[hasher(t) % size] = true;
+ _bits[hasher(t) % _bits.size()] = true;
         }
 
- static bool contains(const T& t,
- const boost::dynamic_bitset<Block, Allocator>& _bits,
- const size_t size) {
- typedef typename boost::mpl::at_c<HashFunctions, 0>::type Hash;
+ static bool contains(const value_type& t,
+ const bitset_type& _bits)
+ {
+ typedef typename boost::mpl::at_c<hash_function_type, 0>::type Hash;
           static Hash hasher;
 
- return (_bits[hasher(t) % size]);
+ return (_bits[hasher(t) % _bits.size()]);
         }
       };
+
     } // namespace detail
   } // namespace bloom_filter
 } // namespace boost

Modified: sandbox/bloom_filter/trunk/boost/bloom_filter/detail/counting_apply_hash.hpp
==============================================================================
--- sandbox/bloom_filter/trunk/boost/bloom_filter/detail/counting_apply_hash.hpp (original)
+++ sandbox/bloom_filter/trunk/boost/bloom_filter/detail/counting_apply_hash.hpp 2011-07-26 17:23:52 EDT (Tue, 26 Jul 2011)
@@ -18,6 +18,8 @@
 #include <boost/array.hpp>
 #include <boost/mpl/at.hpp>
 
+#include <boost/bloom_filter/detail/exceptions.hpp>
+
 namespace boost {
   namespace bloom_filters {
     namespace detail {
@@ -43,11 +45,15 @@
           typedef typename boost::mpl::at_c<HashFunctions, N>::type Hash;
           static Hash hasher;
           
- size_t hash_val = Hash(t) % NumBins;
- size_t pos = hash_val / BinsPerSlot;
- size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
+ const size_t hash_val = Hash(t) % NumBins;
+ const size_t pos = hash_val / BinsPerSlot;
+ const size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
           size_t target_bits = (_slots[pos] >> offset_bits) & MASK;
- ++target_bits;
+ ++target_bits;
+
+ if (target_bits == 0)
+ throw bin_overflow_exception();
+
           _slots[pos] |= (target_bits << offset_bits);
 
           counting_apply_hash<N-1, T, NumBins,
@@ -60,11 +66,16 @@
           typedef typename boost::mpl::at_c<HashFunctions, N>::type Hash;
           static Hash hasher;
           
- size_t hash_val = hasher(t) % NumBins;
- size_t pos = hash_val / BinsPerSlot;
- size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
+ const size_t hash_val = hasher(t) % NumBins;
+ const size_t pos = hash_val / BinsPerSlot;
+ const size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
           size_t target_bits = (_slots[pos] >> offset_bits) & MASK;
+
+ if (target_bits == 0)
+ throw bin_underflow_exception();
+
           --target_bits;
+
           _slots[pos] |= (target_bits << offset_bits);
 
           counting_apply_hash<N-1, T, NumBins,
@@ -77,10 +88,10 @@
           typedef typename boost::mpl::at_c<HashFunctions, N>::type Hash;
           static Hash hasher;
           
- size_t hash_val = hasher(t) % NumBins;
- size_t pos = hash_val / BinsPerSlot;
- size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
- size_t target_bits = (_slots[pos] >> offset_bits) & MASK;
+ const size_t hash_val = hasher(t) % NumBins;
+ const size_t pos = hash_val / BinsPerSlot;
+ const size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
+ const size_t target_bits = (_slots[pos] >> offset_bits) & MASK;
 
           return ((target_bits > 0) &&
                   counting_apply_hash<N-1, T, NumBins,
@@ -115,11 +126,16 @@
                     << " incoming value: " << t << "\n";
           */
 
- size_t hash_val = hasher(t) % NumBins;
- size_t pos = hash_val / BinsPerSlot;
- size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
+ const size_t hash_val = hasher(t) % NumBins;
+ const size_t pos = hash_val / BinsPerSlot;
+ const size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
           size_t target_bits = (_slots[pos] >> offset_bits) & MASK;
+
           ++target_bits;
+
+ if (target_bits == 0)
+ throw bin_overflow_exception();
+
           _slots[pos] &= ~(MASK << offset_bits);
           _slots[pos] |= (target_bits << offset_bits);
 
@@ -146,11 +162,17 @@
                     << " incoming value: " << t << "\n";
           */
           
- size_t hash_val = hasher(t) % NumBins;
- size_t pos = hash_val / BinsPerSlot;
- size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
+ const size_t hash_val = hasher(t) % NumBins;
+ const size_t pos = hash_val / BinsPerSlot;
+ const size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
           size_t target_bits = (_slots[pos] >> offset_bits) & MASK;
+
+
+ if (target_bits == 0)
+ throw bin_underflow_exception();
+
           --target_bits;
+
           _slots[pos] &= ~(MASK << offset_bits);
           _slots[pos] |= (target_bits << offset_bits);
 
@@ -177,10 +199,10 @@
                     << " incoming value: " << t << "\n";
           */
           
- size_t hash_val = hasher(t) % NumBins;
- size_t pos = hash_val / BinsPerSlot;
- size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
- size_t target_bits = (_slots[pos] >> offset_bits) & MASK;
+ const size_t hash_val = hasher(t) % NumBins;
+ const size_t pos = hash_val / BinsPerSlot;
+ const size_t offset_bits = (hash_val % BinsPerSlot) * BitsPerBin;
+ const size_t target_bits = (_slots[pos] >> offset_bits) & MASK;
 
           /*
           std::cout << "(contains) checked bits at pos " << pos

Modified: sandbox/bloom_filter/trunk/boost/bloom_filter/detail/exceptions.hpp
==============================================================================
--- sandbox/bloom_filter/trunk/boost/bloom_filter/detail/exceptions.hpp (original)
+++ sandbox/bloom_filter/trunk/boost/bloom_filter/detail/exceptions.hpp 2011-07-26 17:23:52 EDT (Tue, 26 Jul 2011)
@@ -19,20 +19,27 @@
   namespace bloom_filters {
     namespace detail {
 
- class underflow : public std::exception {
+ class bin_underflow_exception : public std::exception {
         virtual const char *
         what() const throw() {
- return "boost::bloom_filters::detail::underflow";
+ return "boost::bloom_filters::detail::bin_underflow_exception";
         }
       };
 
- class overrflow : public std::exception {
+ class bin_overflow_exception : public std::exception {
         virtual const char *
         what() const throw() {
- return "boost::bloom_filters::detail::overflow";
+ return "boost::bloom_filters::detail::bin_overflow_exception";
         }
       };
 
+ class incompatible_size_exception : public std::exception {
+ virtual const char *
+ what() const throw() {
+ return "boost::bloom_filters::detail::incompatible_size_exception";
+ }
+ };
+
     } // namespace detail
   } // namespace bloom_filter
 } // namespace boost

Modified: sandbox/bloom_filter/trunk/boost/bloom_filter/dynamic_bloom_filter.hpp
==============================================================================
--- sandbox/bloom_filter/trunk/boost/bloom_filter/dynamic_bloom_filter.hpp (original)
+++ sandbox/bloom_filter/trunk/boost/bloom_filter/dynamic_bloom_filter.hpp 2011-07-26 17:23:52 EDT (Tue, 26 Jul 2011)
@@ -12,13 +12,8 @@
 
 #ifndef BOOST_BLOOM_FILTER_DYNAMIC_BLOOM_FILTER_HPP
 #define BOOST_BLOOM_FILTER_DYNAMIC_BLOOM_FILTER_HPP 1
-/**
- * \author Alejandro Cabrera
- * \brief A generic Bloom filter providing compile-time unrolling
- * of hash function application.
- */
+
 #include <cmath>
-#include <cassert>
 
 #include <boost/config.hpp>
 #include <boost/mpl/vector.hpp>
@@ -26,6 +21,7 @@
 #include <boost/dynamic_bitset.hpp>
 
 #include <boost/bloom_filter/detail/apply_hash.hpp>
+#include <boost/bloom_filter/detail/exceptions.hpp>
 #include <boost/bloom_filter/hash/default.hpp>
 
 namespace boost {
@@ -41,19 +37,22 @@
       typedef HashFunctions hash_function_type;
       typedef Block block_type;
       typedef Allocator allocator_type;
+ typedef dynamic_bitset<block_type, allocator_type> bitset_type;
+ typedef dynamic_bloom_filter<T, HashFunctions,
+ Block, Allocator> this_type;
 
     public:
       
       // constructors
       dynamic_bloom_filter() {}
       
- explicit dynamic_bloom_filter(const size_t bit_capacity) : bits(bit_capacity) {}
+ explicit dynamic_bloom_filter(const size_t bit_capacity) :
+ bits(bit_capacity) {}
       
       template <typename InputIterator>
- dynamic_bloom_filter(const size_t bit_capacity,
- const InputIterator start,
+ dynamic_bloom_filter(const InputIterator start,
                            const InputIterator end)
- : bits(bit_capacity)
+ : bits(std::distance(start, end) * 4)
       {
         for (InputIterator i = start; i != end; ++i)
           this->insert(*i);
@@ -62,7 +61,7 @@
       // query functions
       static BOOST_CONSTEXPR size_t num_hash_functions() {
         return mpl::size<HashFunctions>::value;
- };
+ }
 
       double false_positive_rate() const {
         const double n = static_cast<double>(this->bits.count());
@@ -71,11 +70,11 @@
         static const double e =
           2.718281828459045235360287471352662497757247093699959574966;
         return std::pow(1 - std::pow(e, -k * n / m), k);
- };
+ }
 
       size_t count() const {
         return this->bits.count();
- };
+ }
 
       size_t bit_capacity() const {
         return this->bits.size();
@@ -88,8 +87,8 @@
       // core operations
       void insert(const T& t) {
         static const unsigned N = mpl::size<HashFunctions>::value - 1;
- detail::dynamic_apply_hash<N, T, HashFunctions, Block, Allocator>::
- insert(t, bits, bits.size());
+ detail::apply_hash<N, this_type>::
+ insert(t, bits);
       }
 
       template <typename InputIterator>
@@ -102,8 +101,8 @@
       bool probably_contains(const T& t) const {
         static const unsigned N = mpl::size<HashFunctions>::value - 1;
         return detail::
- dynamic_apply_hash<N, T, HashFunctions, Block, Allocator>::
- contains(t, bits, bits.size());
+ apply_hash<N, this_type>::
+ contains(t, bits);
       }
 
       // auxilliary operations
@@ -124,8 +123,10 @@
 
       template <typename _T, typename _HashFunctions,
                 typename _Block, typename _Allocator>
- friend bool operator==(const dynamic_bloom_filter<_T, _HashFunctions, _Block, _Allocator>&,
- const dynamic_bloom_filter<_T, _HashFunctions, _Block, _Allocator>&);
+ friend bool operator==(const dynamic_bloom_filter<_T, _HashFunctions,
+ _Block, _Allocator>&,
+ const dynamic_bloom_filter<_T, _HashFunctions,
+ _Block, _Allocator>&);
 
       template <typename _T, typename _HashFunctions,
                 typename _Block, typename _Allocator>
@@ -139,19 +140,25 @@
                                                         _Allocator>&);
 
       dynamic_bloom_filter& operator|=(const dynamic_bloom_filter& rhs) {
- assert(this->bit_capacity() == rhs.bit_capacity());
+ if(this->bit_capacity() != rhs.bit_capacity()) {
+ throw detail::incompatible_size_exception();
+ }
+
         this->bits |= rhs.bits;
         return *this;
       }
 
       dynamic_bloom_filter& operator&=(const dynamic_bloom_filter& rhs) {
- assert(this->bit_capacity() == rhs.bit_capacity());
+ if(this->bit_capacity() != rhs.bit_capacity()) {
+ throw detail::incompatible_size_exception();
+ }
+
         this->bits &= rhs.bits;
         return *this;
       }
 
     private:
- dynamic_bitset<block_type, allocator_type> bits;
+ bitset_type bits;
     };
 
     template<class T, class HashFunctions,
@@ -164,7 +171,10 @@
                                          HashFunctions,
                                          Block, Allocator>& rhs)
     {
- assert(lhs.bit_capacity() == rhs.bit_capacity());
+ if(lhs.bit_capacity() != rhs.bit_capacity()) {
+ throw detail::incompatible_size_exception();
+ }
+
       dynamic_bloom_filter<T, HashFunctions, Block, Allocator> ret(lhs);
       ret |= rhs;
       return ret;
@@ -180,7 +190,10 @@
                                          HashFunctions,
                                          Block, Allocator>& rhs)
     {
- assert(lhs.bit_capacity() == rhs.bit_capacity());
+ if(lhs.bit_capacity() != rhs.bit_capacity()) {
+ throw detail::incompatible_size_exception();
+ }
+
       dynamic_bloom_filter<T, HashFunctions, Block, Allocator> ret(lhs);
       ret &= rhs;
       return ret;
@@ -197,6 +210,10 @@
                                           HashFunctions,
                                           Block, Allocator>& rhs)
     {
+ if(lhs.bit_capacity() != rhs.bit_capacity()) {
+ throw detail::incompatible_size_exception();
+ }
+
       return lhs.bits == rhs.bits;
     }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk