File indexing completed on 2025-01-18 09:38:07
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_HEAP_DETAIL_HEAP_COMPARISON_HPP
0010 #define BOOST_HEAP_DETAIL_HEAP_COMPARISON_HPP
0011
0012 #include <boost/assert.hpp>
0013 #include <boost/static_assert.hpp>
0014 #include <boost/concept/assert.hpp>
0015 #include <boost/heap/heap_concepts.hpp>
0016 #include <boost/type_traits/conditional.hpp>
0017
0018 #ifdef BOOST_HEAP_SANITYCHECKS
0019 #define BOOST_HEAP_ASSERT BOOST_ASSERT
0020 #else
0021 #define BOOST_HEAP_ASSERT(expression)
0022 #endif
0023
0024 namespace boost {
0025 namespace heap {
0026 namespace detail {
0027
0028 template <typename Heap1, typename Heap2>
0029 bool value_equality(Heap1 const & lhs, Heap2 const & rhs,
0030 typename Heap1::value_type lval, typename Heap2::value_type rval)
0031 {
0032 typename Heap1::value_compare const & cmp = lhs.value_comp();
0033 bool ret = !(cmp(lval, rval)) && !(cmp(rval, lval));
0034
0035
0036 BOOST_ASSERT((ret == (!(rhs.value_comp()(lval, rval)) && !(rhs.value_comp()(rval, lval)))));
0037
0038 return ret;
0039 }
0040
0041 template <typename Heap1, typename Heap2>
0042 bool value_compare(Heap1 const & lhs, Heap2 const & rhs,
0043 typename Heap1::value_type lval, typename Heap2::value_type rval)
0044 {
0045 typename Heap1::value_compare const & cmp = lhs.value_comp();
0046 bool ret = cmp(lval, rval);
0047
0048
0049 BOOST_ASSERT((ret == rhs.value_comp()(lval, rval)));
0050 return ret;
0051 }
0052
0053 struct heap_equivalence_copy
0054 {
0055 template <typename Heap1, typename Heap2>
0056 bool operator()(Heap1 const & lhs, Heap2 const & rhs)
0057 {
0058 BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap1>));
0059 BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap2>));
0060
0061
0062 BOOST_STATIC_ASSERT((boost::is_same<typename Heap1::value_compare, typename Heap2::value_compare>::value));
0063
0064 if (Heap1::constant_time_size && Heap2::constant_time_size)
0065 if (lhs.size() != rhs.size())
0066 return false;
0067
0068 if (lhs.empty() && rhs.empty())
0069 return true;
0070
0071 Heap1 lhs_copy(lhs);
0072 Heap2 rhs_copy(rhs);
0073
0074 while (true) {
0075 if (!value_equality(lhs_copy, rhs_copy, lhs_copy.top(), rhs_copy.top()))
0076 return false;
0077
0078 lhs_copy.pop();
0079 rhs_copy.pop();
0080
0081 if (lhs_copy.empty() && rhs_copy.empty())
0082 return true;
0083
0084 if (lhs_copy.empty())
0085 return false;
0086
0087 if (rhs_copy.empty())
0088 return false;
0089 }
0090 }
0091 };
0092
0093
0094 struct heap_equivalence_iteration
0095 {
0096 template <typename Heap1, typename Heap2>
0097 bool operator()(Heap1 const & lhs, Heap2 const & rhs)
0098 {
0099 BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap1>));
0100 BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap2>));
0101
0102
0103 BOOST_STATIC_ASSERT((boost::is_same<typename Heap1::value_compare, typename Heap2::value_compare>::value));
0104
0105 if (Heap1::constant_time_size && Heap2::constant_time_size)
0106 if (lhs.size() != rhs.size())
0107 return false;
0108
0109 if (lhs.empty() && rhs.empty())
0110 return true;
0111
0112 typename Heap1::ordered_iterator it1 = lhs.ordered_begin();
0113 typename Heap1::ordered_iterator it1_end = lhs.ordered_end();
0114 typename Heap1::ordered_iterator it2 = rhs.ordered_begin();
0115 typename Heap1::ordered_iterator it2_end = rhs.ordered_end();
0116 while (true) {
0117 if (!value_equality(lhs, rhs, *it1, *it2))
0118 return false;
0119
0120 ++it1;
0121 ++it2;
0122
0123 if (it1 == it1_end && it2 == it2_end)
0124 return true;
0125
0126 if (it1 == it1_end || it2 == it2_end)
0127 return false;
0128 }
0129 }
0130 };
0131
0132
0133 template <typename Heap1,
0134 typename Heap2
0135 >
0136 bool heap_equality(Heap1 const & lhs, Heap2 const & rhs)
0137 {
0138 const bool use_ordered_iterators = Heap1::has_ordered_iterators && Heap2::has_ordered_iterators;
0139
0140 typedef typename boost::conditional<use_ordered_iterators,
0141 heap_equivalence_iteration,
0142 heap_equivalence_copy
0143 >::type equivalence_check;
0144
0145 equivalence_check eq_check;
0146 return eq_check(lhs, rhs);
0147 }
0148
0149
0150 struct heap_compare_iteration
0151 {
0152 template <typename Heap1,
0153 typename Heap2
0154 >
0155 bool operator()(Heap1 const & lhs, Heap2 const & rhs)
0156 {
0157 typename Heap1::size_type left_size = lhs.size();
0158 typename Heap2::size_type right_size = rhs.size();
0159 if (left_size < right_size)
0160 return true;
0161
0162 if (left_size > right_size)
0163 return false;
0164
0165 typename Heap1::ordered_iterator it1 = lhs.ordered_begin();
0166 typename Heap1::ordered_iterator it1_end = lhs.ordered_end();
0167 typename Heap1::ordered_iterator it2 = rhs.ordered_begin();
0168 typename Heap1::ordered_iterator it2_end = rhs.ordered_end();
0169 while (true) {
0170 if (value_compare(lhs, rhs, *it1, *it2))
0171 return true;
0172
0173 if (value_compare(lhs, rhs, *it2, *it1))
0174 return false;
0175
0176 ++it1;
0177 ++it2;
0178
0179 if (it1 == it1_end && it2 == it2_end)
0180 return true;
0181
0182 if (it1 == it1_end || it2 == it2_end)
0183 return false;
0184 }
0185 }
0186 };
0187
0188 struct heap_compare_copy
0189 {
0190 template <typename Heap1,
0191 typename Heap2
0192 >
0193 bool operator()(Heap1 const & lhs, Heap2 const & rhs)
0194 {
0195 typename Heap1::size_type left_size = lhs.size();
0196 typename Heap2::size_type right_size = rhs.size();
0197 if (left_size < right_size)
0198 return true;
0199
0200 if (left_size > right_size)
0201 return false;
0202
0203 Heap1 lhs_copy(lhs);
0204 Heap2 rhs_copy(rhs);
0205
0206 while (true) {
0207 if (value_compare(lhs_copy, rhs_copy, lhs_copy.top(), rhs_copy.top()))
0208 return true;
0209
0210 if (value_compare(lhs_copy, rhs_copy, rhs_copy.top(), lhs_copy.top()))
0211 return false;
0212
0213 lhs_copy.pop();
0214 rhs_copy.pop();
0215
0216 if (lhs_copy.empty() && rhs_copy.empty())
0217 return false;
0218 }
0219 }
0220 };
0221
0222 template <typename Heap1,
0223 typename Heap2
0224 >
0225 bool heap_compare(Heap1 const & lhs, Heap2 const & rhs)
0226 {
0227 const bool use_ordered_iterators = Heap1::has_ordered_iterators && Heap2::has_ordered_iterators;
0228
0229 typedef typename boost::conditional<use_ordered_iterators,
0230 heap_compare_iteration,
0231 heap_compare_copy
0232 >::type compare_check;
0233
0234 compare_check check_object;
0235 return check_object(lhs, rhs);
0236 }
0237
0238
0239 }
0240 }
0241 }
0242
0243
0244 #undef BOOST_HEAP_ASSERT
0245
0246 #endif