Skip to content

Commit 41799d3

Browse files
committed
Take into account that the underlying container is not necessarily a std::vector in max_size()
The vector_max_size_workaround() we had in place, and one of the test cases, only considered std::vectors, which are no longer the only allowed containers. This commit fixes "Allow choosing the underlying container type".
1 parent 957ee38 commit 41799d3

File tree

4 files changed

+19
-7
lines changed

4 files changed

+19
-7
lines changed

include/boost/dynamic_bitset/detail/dynamic_bitset.hpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <memory>
2121
#include <type_traits>
2222
#include <utility>
23+
#include <vector>
2324

2425
namespace boost {
2526

@@ -90,21 +91,28 @@ struct value_to_type
9091
// from vector<>::max_size. This tries to get more
9192
// meaningful info.
9293
//
93-
template< typename T >
94-
BOOST_DYNAMIC_BITSET_CONSTEXPR20 typename T::size_type
95-
vector_max_size_workaround( const T & v ) noexcept
94+
template< typename T, typename Allocator >
95+
BOOST_DYNAMIC_BITSET_CONSTEXPR20 typename std::vector< T, Allocator >::size_type
96+
max_size_workaround( const std::vector< T, Allocator > & v ) noexcept
9697
{
97-
typedef typename T::allocator_type allocator_type;
98+
typedef typename std::vector< T, Allocator >::allocator_type allocator_type;
9899

99100
const allocator_type & alloc = v.get_allocator();
100101

101102
const typename std::allocator_traits< allocator_type >::size_type alloc_max =
102103
std::allocator_traits< allocator_type >::max_size( alloc );
103104

104-
const typename T::size_type container_max = v.max_size();
105+
const typename std::vector< T, Allocator >::size_type container_max = v.max_size();
105106
return alloc_max < container_max ? alloc_max : container_max;
106107
}
107108

109+
template< typename Container >
110+
BOOST_DYNAMIC_BITSET_CONSTEXPR20 typename Container::size_type
111+
max_size_workaround( const Container & c ) noexcept
112+
{
113+
return c.max_size();
114+
}
115+
108116
// for static_asserts
109117
template< typename T >
110118
struct allowed_block_type

include/boost/dynamic_bitset/impl/dynamic_bitset.ipp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ dynamic_bitset< Block, AllocatorOrContainer >::max_size() const noexcept
12831283
// allocator.
12841284

12851285
const size_type m = detail::dynamic_bitset_impl::
1286-
vector_max_size_workaround( m_bits );
1286+
max_size_workaround( m_bits );
12871287

12881288
return m <= ( size_type( -1 ) / bits_per_block ) ? m * bits_per_block : size_type( -1 );
12891289
}

test/bitset_test.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,6 @@ struct bitset_test
344344
{
345345
BOOST_TEST( b.max_size() > 0 );
346346
BOOST_TEST( b.max_size() >= b.size() );
347-
BOOST_TEST( b.max_size() / bits_per_block <= std::allocator_traits< typename Bitset::allocator_type >::max_size( b.get_allocator() ) );
348347
}
349348

350349
// move constructor (absent from std::bitset)

test/dyn_bitset_unit_tests1.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,11 @@ run_test_cases()
603603
bitset_test< Bitset >::max_size( b );
604604
}
605605
#endif
606+
{
607+
typedef boost::dynamic_bitset< Block, small_vector< Block > > Bitset;
608+
Bitset b;
609+
bitset_test< Bitset >::max_size( b );
610+
}
606611
// Test copy-initialize with default constructor
607612
{
608613
bitset_type b[ 1 ] = {};

0 commit comments

Comments
 (0)