Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/heap/detail/heap_comparison.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/heap/detail/heap_comparison.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,245 @@ +// boost heap: heap node helper classes +// +// Copyright (C) 2010 Tim Blechmann +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HEAP_DETAIL_HEAP_COMPARISON_HPP +#define BOOST_HEAP_DETAIL_HEAP_COMPARISON_HPP + +#include <boost/assert.hpp> +#include <boost/static_assert.hpp> +#include <boost/concept/assert.hpp> +#include <boost/heap/heap_concepts.hpp> + +#ifdef BOOST_HEAP_SANITYCHECKS +#define BOOST_HEAP_ASSERT BOOST_ASSERT +#else +#define BOOST_HEAP_ASSERT(expression) +#endif + +namespace boost { +namespace heap { +namespace detail { + +template <typename Heap1, typename Heap2> +bool value_equality(Heap1 const & lhs, Heap2 const & rhs, + typename Heap1::value_type lval, typename Heap2::value_type rval) +{ + typename Heap1::value_compare const & cmp = lhs.value_comp(); + bool ret = !(cmp(lval, rval)) && !(cmp(rval, lval)); + + // if this assertion is triggered, the value_compare objects of lhs and rhs return different values + BOOST_ASSERT((ret == (!(rhs.value_comp()(lval, rval)) && !(rhs.value_comp()(rval, lval))))); + + return ret; +} + +template <typename Heap1, typename Heap2> +bool value_compare(Heap1 const & lhs, Heap2 const & rhs, + typename Heap1::value_type lval, typename Heap2::value_type rval) +{ + typename Heap1::value_compare const & cmp = lhs.value_comp(); + bool ret = cmp(lval, rval); + + // if this assertion is triggered, the value_compare objects of lhs and rhs return different values + BOOST_ASSERT((ret == rhs.value_comp()(lval, rval))); + return ret; +} + +struct heap_equivalence_copy +{ + template <typename Heap1, typename Heap2> + bool operator()(Heap1 const & lhs, Heap2 const & rhs) + { + BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap1>)); + BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap2>)); + + // if this assertion is triggered, the value_compare types are incompatible + BOOST_STATIC_ASSERT((boost::is_same<typename Heap1::value_compare, typename Heap2::value_compare>::value)); + + if (Heap1::constant_time_size && Heap2::constant_time_size) + if (lhs.size() != rhs.size()) + return false; + + if (lhs.empty() && rhs.empty()) + return true; + + Heap1 lhs_copy(lhs); + Heap2 rhs_copy(rhs); + + while (true) { + if (!value_equality(lhs_copy, rhs_copy, lhs_copy.top(), rhs_copy.top())) + return false; + + lhs_copy.pop(); + rhs_copy.pop(); + + if (lhs_copy.empty() && rhs_copy.empty()) + return true; + + if (lhs_copy.empty()) + return false; + + if (rhs_copy.empty()) + return false; + } + } +}; + + +struct heap_equivalence_iteration +{ + template <typename Heap1, typename Heap2> + bool operator()(Heap1 const & lhs, Heap2 const & rhs) + { + BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap1>)); + BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap2>)); + + // if this assertion is triggered, the value_compare types are incompatible + BOOST_STATIC_ASSERT((boost::is_same<typename Heap1::value_compare, typename Heap2::value_compare>::value)); + + if (Heap1::constant_time_size && Heap2::constant_time_size) + if (lhs.size() != rhs.size()) + return false; + + if (lhs.empty() && rhs.empty()) + return true; + + typename Heap1::ordered_iterator it1 = lhs.ordered_begin(); + typename Heap1::ordered_iterator it1_end = lhs.ordered_end(); + typename Heap1::ordered_iterator it2 = rhs.ordered_begin(); + typename Heap1::ordered_iterator it2_end = rhs.ordered_end(); + while (true) { + if (!value_equality(lhs, rhs, *it1, *it2)) + return false; + + ++it1; + ++it2; + + if (it1 == it1_end && it2 == it2_end) + return true; + + if (it1 == it1_end || it2 == it2_end) + return false; + } + } +}; + + +template <typename Heap1, + typename Heap2 + > +bool heap_equality(Heap1 const & lhs, Heap2 const & rhs) +{ + const bool use_ordered_iterators = Heap1::has_ordered_iterators && Heap2::has_ordered_iterators; + + typedef typename boost::mpl::if_c<use_ordered_iterators, + heap_equivalence_iteration, + heap_equivalence_copy + >::type equivalence_check; + + equivalence_check eq_check; + return eq_check(lhs, rhs); +} + + +struct heap_compare_iteration +{ + template <typename Heap1, + typename Heap2 + > + bool operator()(Heap1 const & lhs, Heap2 const & rhs) + { + typename Heap1::size_type left_size = lhs.size(); + typename Heap2::size_type right_size = rhs.size(); + if (left_size < right_size) + return true; + + if (left_size > right_size) + return false; + + typename Heap1::ordered_iterator it1 = lhs.ordered_begin(); + typename Heap1::ordered_iterator it1_end = lhs.ordered_end(); + typename Heap1::ordered_iterator it2 = rhs.ordered_begin(); + typename Heap1::ordered_iterator it2_end = rhs.ordered_end(); + while (true) { + if (value_compare(lhs, rhs, *it1, *it2)) + return true; + + if (value_compare(lhs, rhs, *it2, *it1)) + return false; + + ++it1; + ++it2; + + if (it1 == it1_end && it2 == it2_end) + return true; + + if (it1 == it1_end || it2 == it2_end) + return false; + } + } +}; + +struct heap_compare_copy +{ + template <typename Heap1, + typename Heap2 + > + bool operator()(Heap1 const & lhs, Heap2 const & rhs) + { + typename Heap1::size_type left_size = lhs.size(); + typename Heap2::size_type right_size = rhs.size(); + if (left_size < right_size) + return true; + + if (left_size > right_size) + return false; + + Heap1 lhs_copy(lhs); + Heap2 rhs_copy(rhs); + + while (true) { + if (value_compare(lhs_copy, rhs_copy, lhs_copy.top(), rhs_copy.top())) + return true; + + if (value_compare(lhs_copy, rhs_copy, rhs_copy.top(), lhs_copy.top())) + return false; + + lhs_copy.pop(); + rhs_copy.pop(); + + if (lhs_copy.empty() && rhs_copy.empty()) + return false; + } + } +}; + +template <typename Heap1, + typename Heap2 + > +bool heap_compare(Heap1 const & lhs, Heap2 const & rhs) +{ + const bool use_ordered_iterators = Heap1::has_ordered_iterators && Heap2::has_ordered_iterators; + + typedef typename boost::mpl::if_c<use_ordered_iterators, + heap_compare_iteration, + heap_compare_copy + >::type compare_check; + + compare_check check_object; + return check_object(lhs, rhs); +} + + +} /* namespace detail */ +} /* namespace heap */ +} /* namespace boost */ + + +#undef BOOST_HEAP_ASSERT + +#endif // BOOST_HEAP_DETAIL_HEAP_COMPARISON_HPP