Fix several range constructor bugs: (a) btree_multiset's range constructor did not compile (b) btree_map's range constructor ignored the inputs! These bugs were masked by the test, which due to an oversight skipped the use of range constructors as part of the {base,unique,multi}_checker testing types. Verified that the corrected test fails without the fix, added an additional sanity check (which made the problem stand out independent of the problems discovered in btree_test.h)

pull/5/head
Joshua MacDonald 2013-02-05 22:04:33 -08:00
parent 5633058db4
commit c790956d18
5 changed files with 38 additions and 12 deletions

View File

@ -261,8 +261,7 @@ class btree_map_container : public btree_unique_container<Tree> {
btree_map_container(InputIterator b, InputIterator e,
const key_compare &comp = key_compare(),
const allocator_type &alloc = allocator_type())
: super_type(comp, alloc) {
insert(b, e);
: super_type(b, e, comp, alloc) {
}
// Insertion routines.
@ -303,7 +302,7 @@ class btree_multi_container : public btree_container<Tree> {
btree_multi_container(InputIterator b, InputIterator e,
const key_compare &comp = key_compare(),
const allocator_type &alloc = allocator_type())
: super_type(b, e, comp, alloc) {
: super_type(comp, alloc) {
insert(b, e);
}

View File

@ -33,7 +33,7 @@
namespace btree {
// The btree_map class is needed mainly for it's constructors.
// The btree_map class is needed mainly for its constructors.
template <typename Key, typename Value,
typename Compare = std::less<Key>,
typename Alloc = std::allocator<std::pair<const Key, Value> >,
@ -68,7 +68,7 @@ class btree_map : public btree_map_container<
btree_map(InputIterator b, InputIterator e,
const key_compare &comp = key_compare(),
const allocator_type &alloc = allocator_type())
: super_type(comp, alloc) {
: super_type(b, e, comp, alloc) {
}
};
@ -78,7 +78,7 @@ inline void swap(btree_map<K, V, C, A, N> &x,
x.swap(y);
}
// The btree_multimap class is needed mainly for it's constructors.
// The btree_multimap class is needed mainly for its constructors.
template <typename Key, typename Value,
typename Compare = std::less<Key>,
typename Alloc = std::allocator<std::pair<const Key, Value> >,

View File

@ -29,7 +29,7 @@
namespace btree {
// The btree_set class is needed mainly for it's constructors.
// The btree_set class is needed mainly for its constructors.
template <typename Key,
typename Compare = std::less<Key>,
typename Alloc = std::allocator<Key>,
@ -72,7 +72,7 @@ inline void swap(btree_set<K, C, A, N> &x, btree_set<K, C, A, N> &y) {
x.swap(y);
}
// The btree_multiset class is needed mainly for it's constructors.
// The btree_multiset class is needed mainly for its constructors.
template <typename Key,
typename Compare = std::less<Key>,
typename Alloc = std::allocator<Key>,

View File

@ -244,5 +244,24 @@ TEST(Btree, Comparison) {
EXPECT_TRUE(my_map != my_map_copy);
}
TEST(Btree, RangeCtorSanity) {
typedef btree_set<int, less<int>, allocator<int>, 256> test_set;
typedef btree_map<int, int, less<int>, allocator<int>, 256> test_map;
typedef btree_multiset<int, less<int>, allocator<int>, 256> test_mset;
typedef btree_multimap<int, int, less<int>, allocator<int>, 256> test_mmap;
vector<int> ivec;
ivec.push_back(1);
map<int, int> imap;
imap.insert(make_pair(1, 2));
test_mset tmset(ivec.begin(), ivec.end());
test_mmap tmmap(imap.begin(), imap.end());
test_set tset(ivec.begin(), ivec.end());
test_map tmap(imap.begin(), imap.end());
EXPECT_EQ(1, tmset.size());
EXPECT_EQ(1, tmmap.size());
EXPECT_EQ(1, tset.size());
EXPECT_EQ(1, tmap.size());
}
} // namespace
} // namespace btree

View File

@ -147,6 +147,13 @@ class base_checker {
const_tree_(tree_),
checker_(x.checker_) {
}
// Range constructor.
template <typename InputIterator>
base_checker(InputIterator b, InputIterator e)
: tree_(b, e),
const_tree_(tree_),
checker_(b, e) {
}
// Iterator routines.
iterator begin() { return tree_.begin(); }
@ -398,8 +405,8 @@ class unique_checker : public base_checker<TreeType, CheckerType> {
}
// Range constructor.
template <class InputIterator>
unique_checker(InputIterator b, InputIterator e) {
insert(b, e);
unique_checker(InputIterator b, InputIterator e)
: super_type(b, e) {
}
// Insertion routines.
@ -455,8 +462,8 @@ class multi_checker : public base_checker<TreeType, CheckerType> {
}
// Range constructor.
template <class InputIterator>
multi_checker(InputIterator b, InputIterator e) {
insert(b, e);
multi_checker(InputIterator b, InputIterator e)
: super_type(b, e) {
}
// Insertion routines.
@ -587,6 +594,7 @@ void DoTest(const char *name, T *b, const std::vector<V> &values) {
mutable_b.insert(values[i]);
mutable_b.value_check(values[i]);
}
assert(mutable_b.size() == values.size());
const_b.verify();
printf(" %s fullness=%0.2f overhead=%0.2f bytes-per-value=%0.2f\n",