Improve the unordered tests support for some older compilers.

Better testing of elements with equivalent keys.


[SVN r7458]
This commit is contained in:
Daniel James
2007-07-17 23:17:21 +00:00
parent 6af2b965bb
commit aabf1a408b
11 changed files with 176 additions and 20 deletions

View File

@@ -12,6 +12,7 @@ namespace test
{ {
int generate(int const*); int generate(int const*);
char generate(char const*); char generate(char const*);
signed char generate(signed char const*);
std::string generate(std::string*); std::string generate(std::string*);
float generate(float const*); float generate(float const*);
template <class T1, class T2> template <class T1, class T2>

View File

@@ -56,6 +56,12 @@ namespace test
return (rand() >> 1) % (128-32) + 32; return (rand() >> 1) % (128-32) + 32;
} }
inline signed char generate(signed char const*)
{
using namespace std;
return rand();
}
inline std::string generate(std::string const*) inline std::string generate(std::string const*)
{ {
using namespace std; using namespace std;

View File

@@ -624,13 +624,14 @@ namespace exception
} }
return (std::numeric_limits<std::size_t>::max)(); return (std::numeric_limits<std::size_t>::max)();
} }
friend void swap(allocator<T>& x, allocator<T>& y)
{
std::swap(x.tag_, y.tag_);
}
}; };
template <class T>
void swap(allocator<T>& x, allocator<T>& y)
{
std::swap(x.tag_, y.tag_);
}
// It's pretty much impossible to write a compliant swap when these // It's pretty much impossible to write a compliant swap when these
// two can throw. So they don't. // two can throw. So they don't.

View File

@@ -50,7 +50,6 @@ namespace test
(x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_); (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
} }
friend object generate(object const*) { friend object generate(object const*) {
int* x = 0; int* x = 0;
return object(generate(x), generate(x)); return object(generate(x), generate(x));
@@ -62,6 +61,44 @@ namespace test
} }
}; };
// This object is usd to test how well the containers cope with equivalent keys.
class equivalent_object
{
friend class hash;
friend class equal_to;
friend class less;
int tag1_, tag2_;
public:
explicit equivalent_object(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
~equivalent_object() {
tag1_ = -1;
tag2_ = -1;
}
friend bool operator==(equivalent_object const& x1, equivalent_object const& x2) {
return x1.tag1_ == x2.tag1_;
}
friend bool operator!=(equivalent_object const& x1, equivalent_object const& x2) {
return x1.tag1_ != x2.tag1_;
}
friend bool operator<(equivalent_object const& x1, equivalent_object const& x2) {
return x1.tag1_ < x2.tag1_;
}
friend equivalent_object generate(equivalent_object const*) {
signed char* x = 0;
return equivalent_object(generate(x), generate(x));
}
friend std::ostream& operator<<(std::ostream& out, equivalent_object const& o)
{
return out<<"("<<o.tag1_<<","<<o.tag2_<<")";
}
};
class hash class hash
{ {
int type_; int type_;
@@ -79,6 +116,10 @@ namespace test
} }
} }
std::size_t operator()(equivalent_object const& x) const {
return x.tag1_;
}
std::size_t operator()(int x) const { std::size_t operator()(int x) const {
return x; return x;
} }
@@ -109,6 +150,10 @@ namespace test
} }
} }
bool operator()(equivalent_object const& x1, equivalent_object const& x2) const {
return x1 < x2;
}
std::size_t operator()(int x1, int x2) const { std::size_t operator()(int x1, int x2) const {
return x1 < x2; return x1 < x2;
} }
@@ -135,6 +180,10 @@ namespace test
} }
} }
bool operator()(equivalent_object const& x1, equivalent_object const& x2) const {
return x1 == x2;
}
std::size_t operator()(int x1, int x2) const { std::size_t operator()(int x1, int x2) const {
return x1 == x2; return x1 == x2;
} }
@@ -359,6 +408,51 @@ namespace test
bool equivalent_impl(allocator<T> const& x, allocator<T> const& y, test::derived_type) { bool equivalent_impl(allocator<T> const& x, allocator<T> const& y, test::derived_type) {
return x == y; return x == y;
} }
#if BOOST_WORKAROUND(__GNUC__, < 3)
void swap(test::object& x, test::object& y) {
test::object tmp;
tmp = x;
x = y;
y = tmp;
}
void swap(test::equivalent_object& x, test::equivalent_object& y) {
test::equivalent_object tmp;
tmp = x;
x = y;
y = tmp;
}
void swap(test::hash& x, test::hash& y) {
test::hash tmp;
tmp = x;
x = y;
y = tmp;
}
void swap(test::less& x, test::less& y) {
test::less tmp;
tmp = x;
x = y;
y = tmp;
}
void swap(test::equal_to& x, test::equal_to& y) {
test::equal_to tmp;
tmp = x;
x = y;
y = tmp;
}
template <class T>
void swap(test::allocator<T>& x, test::allocator<T>& y) {
test::allocator<T> tmp;
tmp = x;
x = y;
y = tmp;
}
#endif
} }
#endif #endif

View File

@@ -95,9 +95,14 @@ int main()
assign_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); assign_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); assign_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests1((boost::unordered_set<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
assign_tests1((boost::unordered_multiset<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
assign_tests1((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
assign_tests1((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
assign_tests2((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); assign_tests2((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests2((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); assign_tests2((boost::unordered_multiset<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
assign_tests2((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); assign_tests2((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
assign_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); assign_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
return boost::report_errors(); return boost::report_errors();

View File

@@ -273,6 +273,15 @@ int main()
std::cerr<<"Test1 unordered_multimap<test::object, test::object>\n"; std::cerr<<"Test1 unordered_multimap<test::object, test::object>\n";
constructor_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); constructor_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test1 unordered_set<test::equivalent_object>\n";
constructor_tests1((boost::unordered_set<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"Test1 unordered_multiset<test::equivalent_object>\n";
constructor_tests1((boost::unordered_multiset<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"Test1 unordered_map<test::equivalent_object, test::equivalent_object>\n";
constructor_tests1((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"Test1 unordered_multimap<test::equivalent_object, test::equivalent_object>\n";
constructor_tests1((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"Test2 unordered_set<test::object>\n"; std::cerr<<"Test2 unordered_set<test::object>\n";
constructor_tests2((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); constructor_tests2((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test2 unordered_multiset<test::object>\n"; std::cerr<<"Test2 unordered_multiset<test::object>\n";
@@ -282,6 +291,15 @@ int main()
std::cerr<<"Test2 unordered_multimap<test::object, test::object>\n"; std::cerr<<"Test2 unordered_multimap<test::object, test::object>\n";
constructor_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); constructor_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test2 unordered_set<test::equivalent_object>\n";
constructor_tests2((boost::unordered_set<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"Test2 unordered_multiset<test::equivalent_object>\n";
constructor_tests2((boost::unordered_multiset<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"Test2 unordered_map<test::equivalent_object, test::equivalent_object>\n";
constructor_tests2((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"Test2 unordered_multimap<test::equivalent_object, test::equivalent_object>\n";
constructor_tests2((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"Map Test unordered_map<test::object, test::object>\n"; std::cerr<<"Map Test unordered_map<test::object, test::object>\n";
map_constructor_test((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); map_constructor_test((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Map Test unordered_multimap<test::object, test::object>\n"; std::cerr<<"Map Test unordered_multimap<test::object, test::object>\n";

View File

@@ -100,5 +100,10 @@ int main()
copy_construct_tests2((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); copy_construct_tests2((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
copy_construct_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); copy_construct_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
copy_construct_tests2((boost::unordered_set<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
copy_construct_tests2((boost::unordered_multiset<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
copy_construct_tests2((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
copy_construct_tests2((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
return boost::report_errors(); return boost::report_errors();
} }

View File

@@ -49,8 +49,8 @@ typedef boost::unordered_multimap<int, int,
typedef boost::unordered_multimap<int, int, typedef boost::unordered_multimap<int, int,
collision2_hash, std::equal_to<int>, collision2_hash, std::equal_to<int>,
test::allocator<std::pair<int const, int> > > collide_map2; test::allocator<std::pair<int const, int> > > collide_map2;
typedef collide_map::value_type pair; typedef collide_map::value_type collide_value;
typedef std::list<pair> list; typedef std::list<collide_value> collide_list;
void empty_range_tests() void empty_range_tests()
@@ -63,8 +63,8 @@ void empty_range_tests()
void single_item_tests() void single_item_tests()
{ {
list init; collide_list init;
init.push_back(pair(1,1)); init.push_back(collide_value(1,1));
collide_map x(init.begin(), init.end()); collide_map x(init.begin(), init.end());
x.erase(x.begin(), x.begin()); x.erase(x.begin(), x.begin());
@@ -77,9 +77,9 @@ void single_item_tests()
void two_equivalent_item_tests() void two_equivalent_item_tests()
{ {
list init; collide_list init;
init.push_back(pair(1,1)); init.push_back(collide_value(1,1));
init.push_back(pair(1,2)); init.push_back(collide_value(1,2));
{ {
collide_map x(init.begin(), init.end()); collide_map x(init.begin(), init.end());
@@ -109,8 +109,8 @@ void two_equivalent_item_tests()
template<class Range1, class Range2> template<class Range1, class Range2>
bool compare(Range1 const& x, Range2 const& y) bool compare(Range1 const& x, Range2 const& y)
{ {
list a; collide_list a;
list b; collide_list b;
std::copy(x.begin(), x.end(), std::back_inserter(a)); std::copy(x.begin(), x.end(), std::back_inserter(a));
std::copy(y.begin(), y.end(), std::back_inserter(b)); std::copy(y.begin(), y.end(), std::back_inserter(b));
a.sort(); a.sort();
@@ -121,7 +121,7 @@ bool compare(Range1 const& x, Range2 const& y)
template <class Container> template <class Container>
bool general_erase_range_test(Container& x, int start, int end) bool general_erase_range_test(Container& x, int start, int end)
{ {
list l; collide_list l;
std::copy(x.begin(), x.end(), std::back_inserter(l)); std::copy(x.begin(), x.end(), std::back_inserter(l));
l.erase(boost::next(l.begin(), start), boost::next(l.begin(), end)); l.erase(boost::next(l.begin(), start), boost::next(l.begin(), end));
x.erase(boost::next(x.begin(), start), boost::next(x.begin(), end)); x.erase(boost::next(x.begin(), start), boost::next(x.begin(), end));
@@ -134,7 +134,7 @@ void erase_subrange_tests(Container const& x)
for(std::size_t length = 0; length < x.size(); ++length) { for(std::size_t length = 0; length < x.size(); ++length) {
for(std::size_t position = 0; position < x.size() - length; ++position) { for(std::size_t position = 0; position < x.size() - length; ++position) {
Container y(x); Container y(x);
list init; collide_list init;
std::copy(y.begin(), y.end(), std::back_inserter(init)); std::copy(y.begin(), y.end(), std::back_inserter(init));
if(!general_erase_range_test(y, position, position + length)) { if(!general_erase_range_test(y, position, position + length)) {
BOOST_ERROR("general_erase_range_test failed."); BOOST_ERROR("general_erase_range_test failed.");
@@ -153,7 +153,7 @@ void x_by_y_erase_range_tests(Container*, int values, int duplicates)
for(int i = 0; i < values; ++i) { for(int i = 0; i < values; ++i) {
for(int j = 0; j < duplicates; ++j) { for(int j = 0; j < duplicates; ++j) {
y.insert(pair(i, j)); y.insert(collide_value(i, j));
} }
} }

View File

@@ -135,5 +135,14 @@ int main()
std::cerr<<"\nErase unordered_multimap<test::object,..>.\n"; std::cerr<<"\nErase unordered_multimap<test::object,..>.\n";
erase_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); erase_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"\nErase unordered_set<test::equivalent_object,..>.\n";
erase_tests1((boost::unordered_set<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"\nErase unordered_multiset<test::equivalent_object,..>.\n";
erase_tests1((boost::unordered_multiset<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"\nErase unordered_map<test::equivalent_object,..>.\n";
erase_tests1((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
std::cerr<<"\nErase unordered_multimap<test::equivalent_object,..>.\n";
erase_tests1((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
return boost::report_errors(); return boost::report_errors();
} }

View File

@@ -88,5 +88,10 @@ int main()
find_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); find_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
find_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); find_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
find_tests1((boost::unordered_set<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
find_tests1((boost::unordered_multiset<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
find_tests1((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
find_tests1((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
return 0; return 0;
} }

View File

@@ -269,6 +269,11 @@ int main()
unique_insert_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); unique_insert_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
equivalent_insert_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); equivalent_insert_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
unique_insert_tests1((boost::unordered_set<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
equivalent_insert_tests1((boost::unordered_multiset<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
unique_insert_tests1((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
equivalent_insert_tests1((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
insert_tests2((boost::unordered_set<int>*) 0); insert_tests2((boost::unordered_set<int>*) 0);
insert_tests2((boost::unordered_multiset<int>*) 0); insert_tests2((boost::unordered_multiset<int>*) 0);
insert_tests2((boost::unordered_map<int, int>*) 0); insert_tests2((boost::unordered_map<int, int>*) 0);
@@ -279,11 +284,18 @@ int main()
insert_tests2((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); insert_tests2((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
insert_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); insert_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
insert_tests2((boost::unordered_set<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
insert_tests2((boost::unordered_multiset<test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
insert_tests2((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
insert_tests2((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
map_tests((boost::unordered_map<int, int>*) 0); map_tests((boost::unordered_map<int, int>*) 0);
map_tests((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); map_tests((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
map_tests((boost::unordered_map<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
associative_insert_range_test((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); associative_insert_range_test((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
associative_insert_range_test((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0); associative_insert_range_test((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
associative_insert_range_test((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
return boost::report_errors(); return boost::report_errors();
} }