]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | // Copyright 2006-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 | // This header contains metafunctions/functions to get the equivalent | |
7 | // associative container for an unordered container, and compare the contents. | |
8 | ||
9 | #if !defined(BOOST_UNORDERED_TEST_HELPERS_TRACKER_HEADER) | |
10 | #define BOOST_UNORDERED_TEST_HELPERS_TRACKER_HEADER | |
11 | ||
7c673cae | 12 | #include "../objects/fwd.hpp" |
7c673cae | 13 | #include "./equivalent.hpp" |
b32b8144 | 14 | #include "./helpers.hpp" |
7c673cae | 15 | #include "./list.hpp" |
b32b8144 FG |
16 | #include "./metafunctions.hpp" |
17 | #include <algorithm> | |
18 | #include <iterator> | |
19 | #include <map> | |
20 | #include <set> | |
7c673cae | 21 | |
b32b8144 FG |
22 | namespace test { |
23 | template <typename X> struct equals_to_compare | |
24 | { | |
25 | typedef std::less<BOOST_DEDUCED_TYPENAME X::first_argument_type> type; | |
26 | }; | |
27 | ||
28 | template <> struct equals_to_compare<test::equal_to> | |
29 | { | |
30 | typedef test::less type; | |
31 | }; | |
32 | ||
33 | template <class X1, class X2> void compare_range(X1 const& x1, X2 const& x2) | |
34 | { | |
35 | typedef test::list<BOOST_DEDUCED_TYPENAME X1::value_type> value_list; | |
36 | value_list values1(x1.begin(), x1.end()); | |
37 | value_list values2(x2.begin(), x2.end()); | |
38 | values1.sort(); | |
39 | values2.sort(); | |
40 | BOOST_TEST(values1.size() == values2.size() && | |
41 | test::equal(values1.begin(), values1.end(), values2.begin(), | |
42 | test::equivalent)); | |
43 | } | |
44 | ||
45 | template <class X1, class X2, class T> | |
46 | void compare_pairs(X1 const& x1, X2 const& x2, T*) | |
47 | { | |
48 | test::list<T> values1(x1.first, x1.second); | |
49 | test::list<T> values2(x2.first, x2.second); | |
50 | values1.sort(); | |
51 | values2.sort(); | |
52 | BOOST_TEST(values1.size() == values2.size() && | |
53 | test::equal(values1.begin(), values1.end(), values2.begin(), | |
54 | test::equivalent)); | |
55 | } | |
56 | ||
57 | template <typename X, bool is_set = test::is_set<X>::value, | |
58 | bool has_unique_keys = test::has_unique_keys<X>::value> | |
59 | struct ordered_base; | |
60 | ||
61 | template <typename X> struct ordered_base<X, true, true> | |
62 | { | |
63 | typedef std::set<BOOST_DEDUCED_TYPENAME X::value_type, | |
64 | BOOST_DEDUCED_TYPENAME | |
65 | equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type> | |
66 | type; | |
67 | }; | |
68 | ||
69 | template <typename X> struct ordered_base<X, true, false> | |
70 | { | |
71 | typedef std::multiset<BOOST_DEDUCED_TYPENAME X::value_type, | |
72 | BOOST_DEDUCED_TYPENAME | |
73 | equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type> | |
74 | type; | |
75 | }; | |
76 | ||
77 | template <typename X> struct ordered_base<X, false, true> | |
78 | { | |
79 | typedef std::map<BOOST_DEDUCED_TYPENAME X::key_type, | |
80 | BOOST_DEDUCED_TYPENAME X::mapped_type, | |
81 | BOOST_DEDUCED_TYPENAME | |
82 | equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type> | |
83 | type; | |
84 | }; | |
85 | ||
86 | template <typename X> struct ordered_base<X, false, false> | |
87 | { | |
88 | typedef std::multimap<BOOST_DEDUCED_TYPENAME X::key_type, | |
89 | BOOST_DEDUCED_TYPENAME X::mapped_type, | |
90 | BOOST_DEDUCED_TYPENAME | |
91 | equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type> | |
92 | type; | |
93 | }; | |
94 | ||
95 | template <class X> class ordered : public ordered_base<X>::type | |
96 | { | |
97 | typedef BOOST_DEDUCED_TYPENAME ordered_base<X>::type base; | |
98 | ||
99 | public: | |
100 | typedef BOOST_DEDUCED_TYPENAME base::key_compare key_compare; | |
101 | ||
102 | ordered() : base() {} | |
103 | ||
104 | explicit ordered(key_compare const& kc) : base(kc) {} | |
105 | ||
106 | void compare(X const& x) { compare_range(x, *this); } | |
107 | ||
108 | void compare_key( | |
109 | X const& x, BOOST_DEDUCED_TYPENAME X::value_type const& val) | |
7c673cae | 110 | { |
b32b8144 FG |
111 | compare_pairs(x.equal_range(get_key<X>(val)), |
112 | this->equal_range(get_key<X>(val)), | |
113 | (BOOST_DEDUCED_TYPENAME X::value_type*)0); | |
7c673cae FG |
114 | } |
115 | ||
b32b8144 | 116 | template <class It> void insert_range(It b, It e) |
7c673cae | 117 | { |
b32b8144 FG |
118 | while (b != e) { |
119 | this->insert(*b); | |
120 | ++b; | |
121 | } | |
7c673cae | 122 | } |
b32b8144 FG |
123 | }; |
124 | ||
125 | template <class Equals> | |
126 | BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type create_compare( | |
127 | Equals const&) | |
128 | { | |
129 | BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type x; | |
130 | return x; | |
131 | } | |
132 | ||
133 | template <class X> ordered<X> create_ordered(X const& container) | |
134 | { | |
135 | return ordered<X>(create_compare(container.key_eq())); | |
136 | } | |
137 | ||
138 | template <class X1, class X2> | |
139 | void check_container(X1 const& container, X2 const& values) | |
140 | { | |
141 | ordered<X1> tracker = create_ordered(container); | |
142 | tracker.insert_range(values.begin(), values.end()); | |
143 | tracker.compare(container); | |
144 | } | |
7c673cae FG |
145 | } |
146 | ||
147 | #endif |