summaryrefslogtreecommitdiffstats
path: root/ext/boost/algorithm/minmax_element.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'ext/boost/algorithm/minmax_element.hpp')
-rw-r--r--ext/boost/algorithm/minmax_element.hpp551
1 files changed, 551 insertions, 0 deletions
diff --git a/ext/boost/algorithm/minmax_element.hpp b/ext/boost/algorithm/minmax_element.hpp
new file mode 100644
index 0000000000..0d2efd8cd8
--- /dev/null
+++ b/ext/boost/algorithm/minmax_element.hpp
@@ -0,0 +1,551 @@
+// (C) Copyright Herve Bronnimann 2004.
+//
+// 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)
+
+/*
+ Revision history:
+ 1 July 2004
+ Split the code into two headers to lessen dependence on
+ Boost.tuple. (Herve)
+ 26 June 2004
+ Added the code for the boost minmax library. (Herve)
+*/
+
+#ifndef BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
+#define BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
+
+/* PROPOSED STANDARD EXTENSIONS:
+ *
+ * minmax_element(first, last)
+ * Effect: std::make_pair( std::min_element(first, last),
+ * std::max_element(first, last) );
+ *
+ * minmax_element(first, last, comp)
+ * Effect: std::make_pair( std::min_element(first, last, comp),
+ * std::max_element(first, last, comp) );
+ */
+
+#include <utility> // for std::pair and std::make_pair
+
+namespace boost {
+
+ namespace detail { // for obtaining a uniform version of minmax_element
+ // that compiles with VC++ 6.0 -- avoid the iterator_traits by
+ // having comparison object over iterator, not over dereferenced value
+
+ template <typename Iterator>
+ struct less_over_iter {
+ bool operator()(Iterator const& it1,
+ Iterator const& it2) const { return *it1 < *it2; }
+ };
+
+ template <typename Iterator, class BinaryPredicate>
+ struct binary_pred_over_iter {
+ explicit binary_pred_over_iter(BinaryPredicate const& p ) : m_p( p ) {}
+ bool operator()(Iterator const& it1,
+ Iterator const& it2) const { return m_p(*it1, *it2); }
+ private:
+ BinaryPredicate m_p;
+ };
+
+ // common base for the two minmax_element overloads
+
+ template <typename ForwardIter, class Compare >
+ std::pair<ForwardIter,ForwardIter>
+ basic_minmax_element(ForwardIter first, ForwardIter last, Compare comp)
+ {
+ if (first == last)
+ return std::make_pair(last,last);
+
+ ForwardIter min_result = first;
+ ForwardIter max_result = first;
+
+ // if only one element
+ ForwardIter second = first; ++second;
+ if (second == last)
+ return std::make_pair(min_result, max_result);
+
+ // treat first pair separately (only one comparison for first two elements)
+ ForwardIter potential_min_result = last;
+ if (comp(first, second))
+ max_result = second;
+ else {
+ min_result = second;
+ potential_min_result = first;
+ }
+
+ // then each element by pairs, with at most 3 comparisons per pair
+ first = ++second; if (first != last) ++second;
+ while (second != last) {
+ if (comp(first, second)) {
+ if (comp(first, min_result)) {
+ min_result = first;
+ potential_min_result = last;
+ }
+ if (comp(max_result, second))
+ max_result = second;
+ } else {
+ if (comp(second, min_result)) {
+ min_result = second;
+ potential_min_result = first;
+ }
+ if (comp(max_result, first))
+ max_result = first;
+ }
+ first = ++second;
+ if (first != last) ++second;
+ }
+
+ // if odd number of elements, treat last element
+ if (first != last) { // odd number of elements
+ if (comp(first, min_result))
+ min_result = first, potential_min_result = last;
+ else if (comp(max_result, first))
+ max_result = first;
+ }
+
+ // resolve min_result being incorrect with one extra comparison
+ // (in which case potential_min_result is necessarily the correct result)
+ if (potential_min_result != last
+ && !comp(min_result, potential_min_result))
+ min_result = potential_min_result;
+
+ return std::make_pair(min_result,max_result);
+ }
+
+ } // namespace detail
+
+ template <typename ForwardIter>
+ std::pair<ForwardIter,ForwardIter>
+ minmax_element(ForwardIter first, ForwardIter last)
+ {
+ return detail::basic_minmax_element(first, last,
+ detail::less_over_iter<ForwardIter>() );
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ std::pair<ForwardIter,ForwardIter>
+ minmax_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
+ {
+ return detail::basic_minmax_element(first, last,
+ detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
+ }
+
+}
+
+/* PROPOSED BOOST EXTENSIONS
+ * In the description below, [rfirst,rlast) denotes the reversed range
+ * of [first,last). Even though the iterator type of first and last may
+ * be only a Forward Iterator, it is possible to explain the semantics
+ * by assuming that it is a Bidirectional Iterator. In the sequel,
+ * reverse(ForwardIterator&) returns the reverse_iterator adaptor.
+ * This is not how the functions would be implemented!
+ *
+ * first_min_element(first, last)
+ * Effect: std::min_element(first, last);
+ *
+ * first_min_element(first, last, comp)
+ * Effect: std::min_element(first, last, comp);
+ *
+ * last_min_element(first, last)
+ * Effect: reverse( std::min_element(reverse(last), reverse(first)) );
+ *
+ * last_min_element(first, last, comp)
+ * Effect: reverse( std::min_element(reverse(last), reverse(first), comp) );
+ *
+ * first_max_element(first, last)
+ * Effect: std::max_element(first, last);
+ *
+ * first_max_element(first, last, comp)
+ * Effect: max_element(first, last);
+ *
+ * last_max_element(first, last)
+ * Effect: reverse( std::max_element(reverse(last), reverse(first)) );
+ *
+ * last_max_element(first, last, comp)
+ * Effect: reverse( std::max_element(reverse(last), reverse(first), comp) );
+ *
+ * first_min_first_max_element(first, last)
+ * Effect: std::make_pair( first_min_element(first, last),
+ * first_max_element(first, last) );
+ *
+ * first_min_first_max_element(first, last, comp)
+ * Effect: std::make_pair( first_min_element(first, last, comp),
+ * first_max_element(first, last, comp) );
+ *
+ * first_min_last_max_element(first, last)
+ * Effect: std::make_pair( first_min_element(first, last),
+ * last_max_element(first, last) );
+ *
+ * first_min_last_max_element(first, last, comp)
+ * Effect: std::make_pair( first_min_element(first, last, comp),
+ * last_max_element(first, last, comp) );
+ *
+ * last_min_first_max_element(first, last)
+ * Effect: std::make_pair( last_min_element(first, last),
+ * first_max_element(first, last) );
+ *
+ * last_min_first_max_element(first, last, comp)
+ * Effect: std::make_pair( last_min_element(first, last, comp),
+ * first_max_element(first, last, comp) );
+ *
+ * last_min_last_max_element(first, last)
+ * Effect: std::make_pair( last_min_element(first, last),
+ * last_max_element(first, last) );
+ *
+ * last_min_last_max_element(first, last, comp)
+ * Effect: std::make_pair( last_min_element(first, last, comp),
+ * last_max_element(first, last, comp) );
+ */
+
+namespace boost {
+
+ // Min_element and max_element variants
+
+ namespace detail { // common base for the overloads
+
+ template <typename ForwardIter, class BinaryPredicate>
+ ForwardIter
+ basic_first_min_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ if (first == last) return last;
+ ForwardIter min_result = first;
+ while (++first != last)
+ if (comp(first, min_result))
+ min_result = first;
+ return min_result;
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ ForwardIter
+ basic_last_min_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ if (first == last) return last;
+ ForwardIter min_result = first;
+ while (++first != last)
+ if (!comp(min_result, first))
+ min_result = first;
+ return min_result;
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ ForwardIter
+ basic_first_max_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ if (first == last) return last;
+ ForwardIter max_result = first;
+ while (++first != last)
+ if (comp(max_result, first))
+ max_result = first;
+ return max_result;
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ ForwardIter
+ basic_last_max_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ if (first == last) return last;
+ ForwardIter max_result = first;
+ while (++first != last)
+ if (!comp(first, max_result))
+ max_result = first;
+ return max_result;
+ }
+
+ } // namespace detail
+
+ template <typename ForwardIter>
+ ForwardIter
+ first_min_element(ForwardIter first, ForwardIter last)
+ {
+ return detail::basic_first_min_element(first, last,
+ detail::less_over_iter<ForwardIter>() );
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ ForwardIter
+ first_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
+ {
+ return detail::basic_first_min_element(first, last,
+ detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
+ }
+
+ template <typename ForwardIter>
+ ForwardIter
+ last_min_element(ForwardIter first, ForwardIter last)
+ {
+ return detail::basic_last_min_element(first, last,
+ detail::less_over_iter<ForwardIter>() );
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ ForwardIter
+ last_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
+ {
+ return detail::basic_last_min_element(first, last,
+ detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
+ }
+
+ template <typename ForwardIter>
+ ForwardIter
+ first_max_element(ForwardIter first, ForwardIter last)
+ {
+ return detail::basic_first_max_element(first, last,
+ detail::less_over_iter<ForwardIter>() );
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ ForwardIter
+ first_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
+ {
+ return detail::basic_first_max_element(first, last,
+ detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
+ }
+
+ template <typename ForwardIter>
+ ForwardIter
+ last_max_element(ForwardIter first, ForwardIter last)
+ {
+ return detail::basic_last_max_element(first, last,
+ detail::less_over_iter<ForwardIter>() );
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ ForwardIter
+ last_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
+ {
+ return detail::basic_last_max_element(first, last,
+ detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
+ }
+
+
+ // Minmax_element variants -- comments removed
+
+ namespace detail {
+
+ template <typename ForwardIter, class BinaryPredicate>
+ std::pair<ForwardIter,ForwardIter>
+ basic_first_min_last_max_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ if (first == last)
+ return std::make_pair(last,last);
+
+ ForwardIter min_result = first;
+ ForwardIter max_result = first;
+
+ ForwardIter second = ++first;
+ if (second == last)
+ return std::make_pair(min_result, max_result);
+
+ if (comp(second, min_result))
+ min_result = second;
+ else
+ max_result = second;
+
+ first = ++second; if (first != last) ++second;
+ while (second != last) {
+ if (!comp(second, first)) {
+ if (comp(first, min_result))
+ min_result = first;
+ if (!comp(second, max_result))
+ max_result = second;
+ } else {
+ if (comp(second, min_result))
+ min_result = second;
+ if (!comp(first, max_result))
+ max_result = first;
+ }
+ first = ++second; if (first != last) ++second;
+ }
+
+ if (first != last) {
+ if (comp(first, min_result))
+ min_result = first;
+ else if (!comp(first, max_result))
+ max_result = first;
+ }
+
+ return std::make_pair(min_result, max_result);
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ std::pair<ForwardIter,ForwardIter>
+ basic_last_min_first_max_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ if (first == last) return std::make_pair(last,last);
+
+ ForwardIter min_result = first;
+ ForwardIter max_result = first;
+
+ ForwardIter second = ++first;
+ if (second == last)
+ return std::make_pair(min_result, max_result);
+
+ if (comp(max_result, second))
+ max_result = second;
+ else
+ min_result = second;
+
+ first = ++second; if (first != last) ++second;
+ while (second != last) {
+ if (comp(first, second)) {
+ if (!comp(min_result, first))
+ min_result = first;
+ if (comp(max_result, second))
+ max_result = second;
+ } else {
+ if (!comp(min_result, second))
+ min_result = second;
+ if (comp(max_result, first))
+ max_result = first;
+ }
+ first = ++second; if (first != last) ++second;
+ }
+
+ if (first != last) {
+ if (!comp(min_result, first))
+ min_result = first;
+ else if (comp(max_result, first))
+ max_result = first;
+ }
+
+ return std::make_pair(min_result, max_result);
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ std::pair<ForwardIter,ForwardIter>
+ basic_last_min_last_max_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ if (first == last) return std::make_pair(last,last);
+
+ ForwardIter min_result = first;
+ ForwardIter max_result = first;
+
+ ForwardIter second = first; ++second;
+ if (second == last)
+ return std::make_pair(min_result,max_result);
+
+ ForwardIter potential_max_result = last;
+ if (comp(first, second))
+ max_result = second;
+ else {
+ min_result = second;
+ potential_max_result = second;
+ }
+
+ first = ++second; if (first != last) ++second;
+ while (second != last) {
+ if (comp(first, second)) {
+ if (!comp(min_result, first))
+ min_result = first;
+ if (!comp(second, max_result)) {
+ max_result = second;
+ potential_max_result = last;
+ }
+ } else {
+ if (!comp(min_result, second))
+ min_result = second;
+ if (!comp(first, max_result)) {
+ max_result = first;
+ potential_max_result = second;
+ }
+ }
+ first = ++second;
+ if (first != last) ++second;
+ }
+
+ if (first != last) {
+ if (!comp(min_result, first))
+ min_result = first;
+ if (!comp(first, max_result)) {
+ max_result = first;
+ potential_max_result = last;
+ }
+ }
+
+ if (potential_max_result != last
+ && !comp(potential_max_result, max_result))
+ max_result = potential_max_result;
+
+ return std::make_pair(min_result,max_result);
+ }
+
+ } // namespace detail
+
+ template <typename ForwardIter>
+ inline std::pair<ForwardIter,ForwardIter>
+ first_min_first_max_element(ForwardIter first, ForwardIter last)
+ {
+ return minmax_element(first, last);
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ inline std::pair<ForwardIter,ForwardIter>
+ first_min_first_max_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ return minmax_element(first, last, comp);
+ }
+
+ template <typename ForwardIter>
+ std::pair<ForwardIter,ForwardIter>
+ first_min_last_max_element(ForwardIter first, ForwardIter last)
+ {
+ return detail::basic_first_min_last_max_element(first, last,
+ detail::less_over_iter<ForwardIter>() );
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ inline std::pair<ForwardIter,ForwardIter>
+ first_min_last_max_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ return detail::basic_first_min_last_max_element(first, last,
+ detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
+ }
+
+ template <typename ForwardIter>
+ std::pair<ForwardIter,ForwardIter>
+ last_min_first_max_element(ForwardIter first, ForwardIter last)
+ {
+ return detail::basic_last_min_first_max_element(first, last,
+ detail::less_over_iter<ForwardIter>() );
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ inline std::pair<ForwardIter,ForwardIter>
+ last_min_first_max_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ return detail::basic_last_min_first_max_element(first, last,
+ detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
+ }
+
+ template <typename ForwardIter>
+ std::pair<ForwardIter,ForwardIter>
+ last_min_last_max_element(ForwardIter first, ForwardIter last)
+ {
+ return detail::basic_last_min_last_max_element(first, last,
+ detail::less_over_iter<ForwardIter>() );
+ }
+
+ template <typename ForwardIter, class BinaryPredicate>
+ inline std::pair<ForwardIter,ForwardIter>
+ last_min_last_max_element(ForwardIter first, ForwardIter last,
+ BinaryPredicate comp)
+ {
+ return detail::basic_last_min_last_max_element(first, last,
+ detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
+ }
+
+} // namespace boost
+
+#endif // BOOST_ALGORITHM_MINMAX_ELEMENT_HPP