1 
2 // Copyright 2005-2009 Daniel James.
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #if !defined(BOOST_UNORDERED_TESTS_EQUIVALENT_HEADER)
7 #define BOOST_UNORDERED_TESTS_EQUIVALENT_HEADER
8 
9 #include "./fwd.hpp"
10 #include "./list.hpp"
11 #include "./metafunctions.hpp"
12 #include <algorithm>
13 #include <boost/core/lightweight_test.hpp>
14 #include <boost/unordered_map.hpp>
15 #include <boost/unordered_set.hpp>
16 
17 namespace test {
18   template <class T1, class T2>
equivalent_impl(T1 const & x,T2 const & y,base_type)19   bool equivalent_impl(T1 const& x, T2 const& y, base_type)
20   {
21     return x == y;
22   }
23 
24   template <class T>
equivalent_impl(boost::hash<T> const &,boost::hash<T> const &,derived_type)25   bool equivalent_impl(
26     boost::hash<T> const&, boost::hash<T> const&, derived_type)
27   {
28     return true;
29   }
30 
31   template <class T>
equivalent_impl(std::equal_to<T> const &,std::equal_to<T> const &,derived_type)32   bool equivalent_impl(
33     std::equal_to<T> const&, std::equal_to<T> const&, derived_type)
34   {
35     return true;
36   }
37 
38   template <class T1, class T2, class T3, class T4>
equivalent_impl(std::pair<T1,T2> const & x1,std::pair<T3,T4> const & x2,derived_type)39   bool equivalent_impl(
40     std::pair<T1, T2> const& x1, std::pair<T3, T4> const& x2, derived_type)
41   {
42     return equivalent_impl(x1.first, x2.first, derived) &&
43            equivalent_impl(x1.second, x2.second, derived);
44   }
45 
46   struct equivalent_type
47   {
equivalent_typetest::equivalent_type48     equivalent_type() {}
49 
50     template <class T1, class T2>
operator ()test::equivalent_type51     bool operator()(T1 const& x, T2 const& y) const
52     {
53       return equivalent_impl(x, y, derived);
54     }
55   };
56 
57   const equivalent_type equivalent;
58 
59   template <class Container> class unordered_equivalence_tester
60   {
61     typename Container::size_type size_;
62     typename Container::hasher hasher_;
63     typename Container::key_equal key_equal_;
64     float max_load_factor_;
65 
66     typedef test::list<typename Container::value_type> value_list;
67     value_list values_;
68 
69   public:
unordered_equivalence_tester(Container const & x)70     unordered_equivalence_tester(Container const& x)
71         : size_(x.size()), hasher_(x.hash_function()), key_equal_(x.key_eq()),
72           max_load_factor_(x.max_load_factor()), values_(x.begin(), x.end())
73     {
74       values_.sort();
75     }
76 
operator ()(Container const & x) const77     bool operator()(Container const& x) const
78     {
79       if (!((size_ == x.size()) &&
80             (test::equivalent(hasher_, x.hash_function())) &&
81             (test::equivalent(key_equal_, x.key_eq())) &&
82             (max_load_factor_ == x.max_load_factor()) &&
83             (values_.size() == x.size())))
84         return false;
85 
86       value_list copy(x.begin(), x.end());
87       copy.sort();
88       return values_ == copy;
89     }
90 
91   private:
92     unordered_equivalence_tester();
93   };
94 }
95 
96 #endif
97