Merge unordered and hash.

Improved Codegear support in unordered.
Another warning suppression in hash.


[SVN r58223]
This commit is contained in:
Daniel James
2009-12-07 19:26:26 +00:00
parent 144d8963a3
commit 02bf8f288e
13 changed files with 265 additions and 86 deletions

View File

@ -102,5 +102,10 @@ First official release.
* Buckets are allocated lazily which means that constructing an empty container * Buckets are allocated lazily which means that constructing an empty container
will not allocate any memory. will not allocate any memory.
[h2 Boost 1.42.0]
* Support instantiating the containers with incomplete value types.
* Reduced the number of warnings (mostly in tests).
[endsect] [endsect]

View File

@ -288,6 +288,9 @@ namespace boost { namespace unordered_detail {
{ {
if (node_) { if (node_) {
if (value_constructed_) { if (value_constructed_) {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { hash_node<Alloc, Grouped> x; };
#endif
boost::unordered_detail::destroy(&node_->value()); boost::unordered_detail::destroy(&node_->value());
} }

View File

@ -38,16 +38,16 @@
namespace boost namespace boost
{ {
template <class Key, class T, class Hash, class Pred, class Alloc> template <class K, class T, class H, class P, class A>
class unordered_map class unordered_map
{ {
public: public:
typedef Key key_type; typedef K key_type;
typedef std::pair<const Key, T> value_type; typedef std::pair<const K, T> value_type;
typedef T mapped_type; typedef T mapped_type;
typedef Hash hasher; typedef H hasher;
typedef Pred key_equal; typedef P key_equal;
typedef Alloc allocator_type; typedef A allocator_type;
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
private: private:
@ -58,7 +58,7 @@ namespace boost
allocator_type, value_type>::type allocator_type, value_type>::type
value_allocator; value_allocator;
typedef boost::unordered_detail::map<Key, Hash, Pred, typedef boost::unordered_detail::map<K, H, P,
value_allocator> types; value_allocator> types;
typedef BOOST_DEDUCED_TYPENAME types::impl table; typedef BOOST_DEDUCED_TYPENAME types::impl table;
@ -177,7 +177,7 @@ namespace boost
} }
#else #else
unordered_map(boost::unordered_detail::move_from< unordered_map(boost::unordered_detail::move_from<
unordered_map<Key, T, Hash, Pred, Alloc> unordered_map<K, T, H, P, A>
> other) > other)
: table_(other.source.table_, boost::unordered_detail::move_tag()) : table_(other.source.table_, boost::unordered_detail::move_tag())
{ {
@ -284,6 +284,7 @@ namespace boost
} }
#else #else
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
std::pair<iterator, bool> emplace(value_type const& v = value_type()) std::pair<iterator, bool> emplace(value_type const& v = value_type())
{ {
return boost::unordered_detail::pair_cast<iterator, bool>( return boost::unordered_detail::pair_cast<iterator, bool>(
@ -294,6 +295,7 @@ namespace boost
{ {
return iterator(table_.emplace(v).first); return iterator(table_.emplace(v).first);
} }
#endif
#define BOOST_UNORDERED_EMPLACE(z, n, _) \ #define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \ template < \
@ -511,9 +513,9 @@ namespace boost
} }
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Key, T, Hash, Pred, Alloc>( friend bool operator==<K, T, H, P, A>(
unordered_map const&, unordered_map const&); unordered_map const&, unordered_map const&);
friend bool operator!=<Key, T, Hash, Pred, Alloc>( friend bool operator!=<K, T, H, P, A>(
unordered_map const&, unordered_map const&); unordered_map const&, unordered_map const&);
#endif #endif
}; // class template unordered_map }; // class template unordered_map
@ -522,6 +524,9 @@ namespace boost
inline bool operator==(unordered_map<K, T, H, P, A> const& m1, inline bool operator==(unordered_map<K, T, H, P, A> const& m1,
unordered_map<K, T, H, P, A> const& m2) unordered_map<K, T, H, P, A> const& m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_map<K,T,H,P,A> x; };
#endif
return m1.table_.equals(m2.table_); return m1.table_.equals(m2.table_);
} }
@ -529,6 +534,9 @@ namespace boost
inline bool operator!=(unordered_map<K, T, H, P, A> const& m1, inline bool operator!=(unordered_map<K, T, H, P, A> const& m1,
unordered_map<K, T, H, P, A> const& m2) unordered_map<K, T, H, P, A> const& m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_map<K,T,H,P,A> x; };
#endif
return !m1.table_.equals(m2.table_); return !m1.table_.equals(m2.table_);
} }
@ -536,20 +544,23 @@ namespace boost
inline void swap(unordered_map<K, T, H, P, A> &m1, inline void swap(unordered_map<K, T, H, P, A> &m1,
unordered_map<K, T, H, P, A> &m2) unordered_map<K, T, H, P, A> &m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_map<K,T,H,P,A> x; };
#endif
m1.swap(m2); m1.swap(m2);
} }
template <class Key, class T, class Hash, class Pred, class Alloc> template <class K, class T, class H, class P, class A>
class unordered_multimap class unordered_multimap
{ {
public: public:
typedef Key key_type; typedef K key_type;
typedef std::pair<const Key, T> value_type; typedef std::pair<const K, T> value_type;
typedef T mapped_type; typedef T mapped_type;
typedef Hash hasher; typedef H hasher;
typedef Pred key_equal; typedef P key_equal;
typedef Alloc allocator_type; typedef A allocator_type;
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
private: private:
@ -560,7 +571,7 @@ namespace boost
allocator_type, value_type>::type allocator_type, value_type>::type
value_allocator; value_allocator;
typedef boost::unordered_detail::multimap<Key, Hash, Pred, typedef boost::unordered_detail::multimap<K, H, P,
value_allocator> types; value_allocator> types;
typedef BOOST_DEDUCED_TYPENAME types::impl table; typedef BOOST_DEDUCED_TYPENAME types::impl table;
@ -680,7 +691,7 @@ namespace boost
} }
#else #else
unordered_multimap(boost::unordered_detail::move_from< unordered_multimap(boost::unordered_detail::move_from<
unordered_multimap<Key, T, Hash, Pred, Alloc> unordered_multimap<K, T, H, P, A>
> other) > other)
: table_(other.source.table_, boost::unordered_detail::move_tag()) : table_(other.source.table_, boost::unordered_detail::move_tag())
{ {
@ -786,6 +797,7 @@ namespace boost
} }
#else #else
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
iterator emplace(value_type const& v = value_type()) iterator emplace(value_type const& v = value_type())
{ {
return iterator(table_.emplace(v)); return iterator(table_.emplace(v));
@ -796,7 +808,7 @@ namespace boost
{ {
return iterator(table_.emplace(v)); return iterator(table_.emplace(v));
} }
#endif
#define BOOST_UNORDERED_EMPLACE(z, n, _) \ #define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \ template < \
@ -999,9 +1011,9 @@ namespace boost
} }
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Key, T, Hash, Pred, Alloc>( friend bool operator==<K, T, H, P, A>(
unordered_multimap const&, unordered_multimap const&); unordered_multimap const&, unordered_multimap const&);
friend bool operator!=<Key, T, Hash, Pred, Alloc>( friend bool operator!=<K, T, H, P, A>(
unordered_multimap const&, unordered_multimap const&); unordered_multimap const&, unordered_multimap const&);
#endif #endif
}; // class template unordered_multimap }; // class template unordered_multimap
@ -1010,6 +1022,9 @@ namespace boost
inline bool operator==(unordered_multimap<K, T, H, P, A> const& m1, inline bool operator==(unordered_multimap<K, T, H, P, A> const& m1,
unordered_multimap<K, T, H, P, A> const& m2) unordered_multimap<K, T, H, P, A> const& m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_multimap<K,T,H,P,A> x; };
#endif
return m1.table_.equals(m2.table_); return m1.table_.equals(m2.table_);
} }
@ -1017,6 +1032,9 @@ namespace boost
inline bool operator!=(unordered_multimap<K, T, H, P, A> const& m1, inline bool operator!=(unordered_multimap<K, T, H, P, A> const& m1,
unordered_multimap<K, T, H, P, A> const& m2) unordered_multimap<K, T, H, P, A> const& m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_multimap<K,T,H,P,A> x; };
#endif
return !m1.table_.equals(m2.table_); return !m1.table_.equals(m2.table_);
} }
@ -1024,6 +1042,9 @@ namespace boost
inline void swap(unordered_multimap<K, T, H, P, A> &m1, inline void swap(unordered_multimap<K, T, H, P, A> &m1,
unordered_multimap<K, T, H, P, A> &m2) unordered_multimap<K, T, H, P, A> &m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_multimap<K,T,H,P,A> x; };
#endif
m1.swap(m2); m1.swap(m2);
} }

View File

@ -17,11 +17,11 @@
namespace boost namespace boost
{ {
template <class Key, template <class K,
class T, class T,
class Hash = hash<Key>, class H = hash<K>,
class Pred = std::equal_to<Key>, class P = std::equal_to<K>,
class Alloc = std::allocator<std::pair<const Key, T> > > class A = std::allocator<std::pair<const K, T> > >
class unordered_map; class unordered_map;
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
bool operator==(unordered_map<K, T, H, P, A> const&, bool operator==(unordered_map<K, T, H, P, A> const&,
@ -33,11 +33,11 @@ namespace boost
void swap(unordered_map<K, T, H, P, A>&, void swap(unordered_map<K, T, H, P, A>&,
unordered_map<K, T, H, P, A>&); unordered_map<K, T, H, P, A>&);
template <class Key, template <class K,
class T, class T,
class Hash = hash<Key>, class H = hash<K>,
class Pred = std::equal_to<Key>, class P = std::equal_to<K>,
class Alloc = std::allocator<std::pair<const Key, T> > > class A = std::allocator<std::pair<const K, T> > >
class unordered_multimap; class unordered_multimap;
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
bool operator==(unordered_multimap<K, T, H, P, A> const&, bool operator==(unordered_multimap<K, T, H, P, A> const&,

View File

@ -38,16 +38,16 @@
namespace boost namespace boost
{ {
template <class Value, class Hash, class Pred, class Alloc> template <class T, class H, class P, class A>
class unordered_set class unordered_set
{ {
public: public:
typedef Value key_type; typedef T key_type;
typedef Value value_type; typedef T value_type;
typedef Hash hasher; typedef H hasher;
typedef Pred key_equal; typedef P key_equal;
typedef Alloc allocator_type; typedef A allocator_type;
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
private: private:
@ -58,7 +58,7 @@ namespace boost
allocator_type, value_type>::type allocator_type, value_type>::type
value_allocator; value_allocator;
typedef boost::unordered_detail::set<Hash, Pred, typedef boost::unordered_detail::set<H, P,
value_allocator> types; value_allocator> types;
typedef BOOST_DEDUCED_TYPENAME types::impl table; typedef BOOST_DEDUCED_TYPENAME types::impl table;
@ -171,7 +171,7 @@ namespace boost
} }
#else #else
unordered_set(boost::unordered_detail::move_from< unordered_set(boost::unordered_detail::move_from<
unordered_set<Value, Hash, Pred, Alloc> unordered_set<T, H, P, A>
> other) > other)
: table_(other.source.table_, boost::unordered_detail::move_tag()) : table_(other.source.table_, boost::unordered_detail::move_tag())
{ {
@ -478,9 +478,9 @@ namespace boost
} }
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Value, Hash, Pred, Alloc>( friend bool operator==<T, H, P, A>(
unordered_set const&, unordered_set const&); unordered_set const&, unordered_set const&);
friend bool operator!=<Value, Hash, Pred, Alloc>( friend bool operator!=<T, H, P, A>(
unordered_set const&, unordered_set const&); unordered_set const&, unordered_set const&);
#endif #endif
}; // class template unordered_set }; // class template unordered_set
@ -489,6 +489,9 @@ namespace boost
inline bool operator==(unordered_set<T, H, P, A> const& m1, inline bool operator==(unordered_set<T, H, P, A> const& m1,
unordered_set<T, H, P, A> const& m2) unordered_set<T, H, P, A> const& m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_set<T,H,P,A> x; };
#endif
return m1.table_.equals(m2.table_); return m1.table_.equals(m2.table_);
} }
@ -496,6 +499,9 @@ namespace boost
inline bool operator!=(unordered_set<T, H, P, A> const& m1, inline bool operator!=(unordered_set<T, H, P, A> const& m1,
unordered_set<T, H, P, A> const& m2) unordered_set<T, H, P, A> const& m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_set<T,H,P,A> x; };
#endif
return !m1.table_.equals(m2.table_); return !m1.table_.equals(m2.table_);
} }
@ -503,19 +509,22 @@ namespace boost
inline void swap(unordered_set<T, H, P, A> &m1, inline void swap(unordered_set<T, H, P, A> &m1,
unordered_set<T, H, P, A> &m2) unordered_set<T, H, P, A> &m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_set<T,H,P,A> x; };
#endif
m1.swap(m2); m1.swap(m2);
} }
template <class Value, class Hash, class Pred, class Alloc> template <class T, class H, class P, class A>
class unordered_multiset class unordered_multiset
{ {
public: public:
typedef Value key_type; typedef T key_type;
typedef Value value_type; typedef T value_type;
typedef Hash hasher; typedef H hasher;
typedef Pred key_equal; typedef P key_equal;
typedef Alloc allocator_type; typedef A allocator_type;
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
private: private:
@ -526,7 +535,7 @@ namespace boost
allocator_type, value_type>::type allocator_type, value_type>::type
value_allocator; value_allocator;
typedef boost::unordered_detail::multiset<Hash, Pred, typedef boost::unordered_detail::multiset<H, P,
value_allocator> types; value_allocator> types;
typedef BOOST_DEDUCED_TYPENAME types::impl table; typedef BOOST_DEDUCED_TYPENAME types::impl table;
@ -640,7 +649,7 @@ namespace boost
} }
#else #else
unordered_multiset(boost::unordered_detail::move_from< unordered_multiset(boost::unordered_detail::move_from<
unordered_multiset<Value, Hash, Pred, Alloc> unordered_multiset<T, H, P, A>
> other) > other)
: table_(other.source.table_, boost::unordered_detail::move_tag()) : table_(other.source.table_, boost::unordered_detail::move_tag())
{ {
@ -943,9 +952,9 @@ namespace boost
} }
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Value, Hash, Pred, Alloc>( friend bool operator==<T, H, P, A>(
unordered_multiset const&, unordered_multiset const&); unordered_multiset const&, unordered_multiset const&);
friend bool operator!=<Value, Hash, Pred, Alloc>( friend bool operator!=<T, H, P, A>(
unordered_multiset const&, unordered_multiset const&); unordered_multiset const&, unordered_multiset const&);
#endif #endif
}; // class template unordered_multiset }; // class template unordered_multiset
@ -954,6 +963,9 @@ namespace boost
inline bool operator==(unordered_multiset<T, H, P, A> const& m1, inline bool operator==(unordered_multiset<T, H, P, A> const& m1,
unordered_multiset<T, H, P, A> const& m2) unordered_multiset<T, H, P, A> const& m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_multiset<T,H,P,A> x; };
#endif
return m1.table_.equals(m2.table_); return m1.table_.equals(m2.table_);
} }
@ -961,6 +973,9 @@ namespace boost
inline bool operator!=(unordered_multiset<T, H, P, A> const& m1, inline bool operator!=(unordered_multiset<T, H, P, A> const& m1,
unordered_multiset<T, H, P, A> const& m2) unordered_multiset<T, H, P, A> const& m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_multiset<T,H,P,A> x; };
#endif
return !m1.table_.equals(m2.table_); return !m1.table_.equals(m2.table_);
} }
@ -968,6 +983,9 @@ namespace boost
inline void swap(unordered_multiset<T, H, P, A> &m1, inline void swap(unordered_multiset<T, H, P, A> &m1,
unordered_multiset<T, H, P, A> &m2) unordered_multiset<T, H, P, A> &m2)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { unordered_multiset<T,H,P,A> x; };
#endif
m1.swap(m2); m1.swap(m2);
} }

View File

@ -17,10 +17,10 @@
namespace boost namespace boost
{ {
template <class Value, template <class T,
class Hash = hash<Value>, class H = hash<T>,
class Pred = std::equal_to<Value>, class P = std::equal_to<T>,
class Alloc = std::allocator<Value> > class A = std::allocator<T> >
class unordered_set; class unordered_set;
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
bool operator==(unordered_set<T, H, P, A> const&, bool operator==(unordered_set<T, H, P, A> const&,
@ -32,10 +32,10 @@ namespace boost
void swap(unordered_set<T, H, P, A> &m1, void swap(unordered_set<T, H, P, A> &m1,
unordered_set<T, H, P, A> &m2); unordered_set<T, H, P, A> &m2);
template <class Value, template <class T,
class Hash = hash<Value>, class H = hash<T>,
class Pred = std::equal_to<Value>, class P = std::equal_to<T>,
class Alloc = std::allocator<Value> > class A = std::allocator<T> >
class unordered_multiset; class unordered_multiset;
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
bool operator==(unordered_multiset<T, H, P, A> const&, bool operator==(unordered_multiset<T, H, P, A> const&,

View File

@ -126,8 +126,9 @@ struct input_range_construct_test : public range<T>, objects
input_range_construct_test() : range<T>(60) {} input_range_construct_test() : range<T>(60) {}
void run() const { void run() const {
T x(test::input_iterator(this->values.begin()), BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
test::input_iterator(this->values.end()), begin = this->values.begin(), end = this->values.end();
T x(test::input_iterator(begin), test::input_iterator(end),
0, hash, equal_to, allocator); 0, hash, equal_to, allocator);
} }
}; };

View File

@ -10,7 +10,6 @@
#include "../helpers/random_values.hpp" #include "../helpers/random_values.hpp"
#include "../helpers/invariants.hpp" #include "../helpers/invariants.hpp"
#include "../helpers/strong.hpp" #include "../helpers/strong.hpp"
#include "../helpers/input_iterator.hpp"
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <cmath> #include <cmath>

View File

@ -7,7 +7,8 @@
#define BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER #define BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp> #include <boost/iterator.hpp>
#include <boost/iterator/iterator_traits.hpp>
namespace test namespace test
{ {
@ -16,7 +17,7 @@ namespace test
{ {
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type value_type; typedef BOOST_DEDUCED_TYPENAME Iterator::value_type value_type;
proxy(value_type const& v) : v_(v) {} explicit proxy(value_type const& v) : v_(v) {}
proxy(proxy const& x) : v_(x.v_) {} proxy(proxy const& x) : v_(x.v_) {}
operator value_type const&() const { return v_; } operator value_type const&() const { return v_; }
@ -27,22 +28,44 @@ namespace test
template <class Iterator> template <class Iterator>
struct input_iterator_adaptor struct input_iterator_adaptor
: boost::iterator_adaptor< : public boost::iterator<
input_iterator_adaptor<Iterator>, Iterator, std::input_iterator_tag,
boost::use_default, std::input_iterator_tag, BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
proxy<Iterator> > std::ptrdiff_t,
BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type,
proxy<Iterator>
>
{ {
typedef boost::iterator_adaptor< typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type
input_iterator_adaptor<Iterator>, Iterator, value_type;
boost::use_default, std::input_iterator_tag,
proxy<Iterator> > base; input_iterator_adaptor()
: base_() {}
explicit input_iterator_adaptor(Iterator it = Iterator()) explicit input_iterator_adaptor(Iterator& it)
: base(it) {} : base_(&it) {}
proxy<Iterator> operator*() const {
return proxy<Iterator>(**base_);
}
value_type* operator->() const {
return &**base_;
}
input_iterator_adaptor& operator++() {
++*base_; return *this;
}
//input_iterator_adaptor operator++(int) {
//}
bool operator==(input_iterator_adaptor const& x) const {
return *base_ == *x.base_;
}
bool operator!=(input_iterator_adaptor const& x) const {
return *base_ != *x.base_;
}
private:
Iterator* base_;
}; };
template <class Iterator> template <class Iterator>
input_iterator_adaptor<Iterator> input_iterator(Iterator it) input_iterator_adaptor<Iterator> input_iterator(Iterator& it)
{ {
return input_iterator_adaptor<Iterator>(it); return input_iterator_adaptor<Iterator>(it);
} }

View File

@ -245,8 +245,12 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa
std::cerr<<"Construct 8 - from input iterator\n"; std::cerr<<"Construct 8 - from input iterator\n";
{ {
test::random_values<T> v(100, generator); test::random_values<T> v(100, generator);
T x(test::input_iterator(v.begin()), test::input_iterator(v.end()), 0, hf1, eq1); BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
T y(test::input_iterator(x.begin()), test::input_iterator(x.end()), 0, hf2, eq2); v_begin = v.begin(), v_end = v.end();
T x(test::input_iterator(v_begin), test::input_iterator(v_end), 0, hf1, eq1);
BOOST_DEDUCED_TYPENAME T::const_iterator
x_begin = x.begin(), x_end = x.end();
T y(test::input_iterator(x_begin), test::input_iterator(x_end), 0, hf2, eq2);
test::check_container(x, v); test::check_container(x, v);
test::check_container(y, x); test::check_container(y, x);
test::check_equivalent_keys(x); test::check_equivalent_keys(x);

View File

@ -8,35 +8,129 @@
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
namespace x
{
struct D { boost::unordered_map<D, D> x; };
}
namespace test namespace test
{ {
// Declare, but don't define some types.
struct value; struct value;
struct hash; struct hash;
struct equals; struct equals;
template <class T> template <class T>
struct malloc_allocator; struct malloc_allocator;
// Declare some instances
typedef boost::unordered_map<value, value, hash, equals, malloc_allocator<std::pair<value const, value> > > map; typedef boost::unordered_map<value, value, hash, equals, malloc_allocator<std::pair<value const, value> > > map;
typedef boost::unordered_multimap<value, value, hash, equals, malloc_allocator<std::pair<value const, value> > > multimap; typedef boost::unordered_multimap<value, value, hash, equals, malloc_allocator<std::pair<value const, value> > > multimap;
typedef boost::unordered_set<value, hash, equals, malloc_allocator<value> > set; typedef boost::unordered_set<value, hash, equals, malloc_allocator<value> > set;
typedef boost::unordered_multiset<value, hash, equals, malloc_allocator<value> > multiset; typedef boost::unordered_multiset<value, hash, equals, malloc_allocator<value> > multiset;
struct value {}; // Now define the types which are stored as members, as they are needed for
struct hash { std::size_t operator()(value const&) const { return 0; } }; // declaring struct members.
struct equals { bool operator()(value const&, value const&) const { return true; } };
struct hash {
template <typename T>
std::size_t operator()(T const&) const { return 0; }
};
struct equals {
template <typename T>
bool operator()(T const&, T const&) const { return true; }
};
} }
#include "../helpers/allocator.hpp" #include "../helpers/allocator.hpp"
int main() { namespace test
{
// Declare some members of a structs.
//
// Incomplete hash, equals and allocator aren't here supported at the moment.
struct struct1 {
boost::unordered_map<struct1, struct1, hash, equals, malloc_allocator<std::pair<struct1 const, struct1> > > x;
};
struct struct2 {
boost::unordered_multimap<struct2, struct2, hash, equals, malloc_allocator<std::pair<struct2 const, struct2> > > x;
};
struct struct3 {
boost::unordered_set<struct3, hash, equals, malloc_allocator<struct3> > x;
};
struct struct4 {
boost::unordered_multiset<struct4, hash, equals, malloc_allocator<struct4> > x;
};
// Now define the value type.
struct value {};
// Create some instances.
test::map m1; test::map m1;
test::multimap m2; test::multimap m2;
test::set s1; test::set s1;
test::multiset s2; test::multiset s2;
test::struct1 c1;
test::struct2 c2;
test::struct3 c3;
test::struct4 c4;
// Now declare, but don't define, the operators required for comparing elements.
std::size_t hash_value(value const&);
bool operator==(value const&, value const&);
std::size_t hash_value(struct1 const&);
std::size_t hash_value(struct2 const&);
std::size_t hash_value(struct3 const&);
std::size_t hash_value(struct4 const&);
test::value x; bool operator==(struct1 const&, struct1 const&);
m1[x] = x; bool operator==(struct2 const&, struct2 const&);
m2.insert(std::make_pair(x, x)); bool operator==(struct3 const&, struct3 const&);
s1.insert(x); bool operator==(struct4 const&, struct4 const&);
s2.insert(x);
// And finally use these
void use_types()
{
test::value x;
m1[x] = x;
m2.insert(std::make_pair(x, x));
s1.insert(x);
s2.insert(x);
c1.x.insert(std::make_pair(c1, c1));
c2.x.insert(std::make_pair(c2, c2));
c3.x.insert(c3);
c4.x.insert(c4);
}
// And finally define the operators required for comparing elements.
std::size_t hash_value(value const&) { return 0; }
bool operator==(value const&, value const&) { return true; }
std::size_t hash_value(struct1 const&) { return 0; }
std::size_t hash_value(struct2 const&) { return 0; }
std::size_t hash_value(struct3 const&) { return 0; }
std::size_t hash_value(struct4 const&) { return 0; }
bool operator==(struct1 const&, struct1 const&) { return true; }
bool operator==(struct2 const&, struct2 const&) { return true; }
bool operator==(struct3 const&, struct3 const&) { return true; }
bool operator==(struct4 const&, struct4 const&) { return true; }
}
int main() {
// This could just be a compile test, but I like to be able to run these
// things. It's probably irrational, but I find it reassuring.
test::use_types();
} }

View File

@ -213,7 +213,9 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
X x; X x;
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
x.insert(test::input_iterator(v.begin()), test::input_iterator(v.end())); BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
begin = v.begin(), end = v.end();
x.insert(test::input_iterator(begin), test::input_iterator(end));
test::check_container(x, v); test::check_container(x, v);
test::check_equivalent_keys(x); test::check_equivalent_keys(x);

View File

@ -13,6 +13,15 @@ void foo(boost::unordered_set<int>& x1,
boost::unordered_multiset<int>& x3, boost::unordered_multiset<int>& x3,
boost::unordered_multimap<int, int>& x4) boost::unordered_multimap<int, int>& x4)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy {
boost::unordered_set<int> x1;
boost::unordered_map<int, int> x2;
boost::unordered_multiset<int> x3;
boost::unordered_multimap<int, int> x4;
};
#endif
x1.insert(1); x1.insert(1);
x2[2] = 2; x2[2] = 2;
x3.insert(3); x3.insert(3);