min_element.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright Neil Groves 2009. Use, modification and
  2. // distribution is subject to the Boost Software License, Version
  3. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. //
  6. // Copyright 2019 Glen Joseph Fernandes (glenjofe@gmail.com)
  7. //
  8. // For more information, see http://www.boost.org/libs/range/
  9. //
  10. #ifndef BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
  11. #define BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
  12. #include <boost/concept_check.hpp>
  13. #include <boost/range/begin.hpp>
  14. #include <boost/range/end.hpp>
  15. #include <boost/range/concepts.hpp>
  16. #include <boost/range/detail/less.hpp>
  17. #include <boost/range/detail/range_return.hpp>
  18. namespace boost
  19. {
  20. namespace range
  21. {
  22. namespace detail
  23. {
  24. template<typename Iterator, class Predicate>
  25. inline Iterator
  26. min_element(Iterator first, Iterator last, Predicate comp)
  27. {
  28. if (first == last) {
  29. return last;
  30. }
  31. Iterator result = first;
  32. while (++first != last) {
  33. if (comp(*first, *result)) {
  34. result = first;
  35. }
  36. }
  37. return result;
  38. }
  39. } // namespace detail
  40. /// \brief template function min_element
  41. ///
  42. /// range-based version of the min_element std algorithm
  43. ///
  44. /// \pre ForwardRange is a model of the ForwardRangeConcept
  45. /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
  46. template<class ForwardRange>
  47. inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  48. min_element(ForwardRange& rng)
  49. {
  50. BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
  51. return detail::min_element(boost::begin(rng), boost::end(rng), detail::less());
  52. }
  53. /// \overload
  54. template<class ForwardRange>
  55. inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
  56. min_element(const ForwardRange& rng)
  57. {
  58. BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
  59. return detail::min_element(boost::begin(rng), boost::end(rng), detail::less());
  60. }
  61. /// \overload
  62. template<class ForwardRange, class BinaryPredicate>
  63. inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  64. min_element(ForwardRange& rng, BinaryPredicate pred)
  65. {
  66. BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
  67. return detail::min_element(boost::begin(rng), boost::end(rng), pred);
  68. }
  69. /// \overload
  70. template<class ForwardRange, class BinaryPredicate>
  71. inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
  72. min_element(const ForwardRange& rng, BinaryPredicate pred)
  73. {
  74. BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
  75. return detail::min_element(boost::begin(rng), boost::end(rng), pred);
  76. }
  77. // range_return overloads
  78. /// \overload
  79. template<range_return_value re, class ForwardRange>
  80. inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
  81. min_element(ForwardRange& rng)
  82. {
  83. BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
  84. return range_return<ForwardRange,re>::pack(
  85. detail::min_element(boost::begin(rng), boost::end(rng), detail::less()),
  86. rng);
  87. }
  88. /// \overload
  89. template<range_return_value re, class ForwardRange>
  90. inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
  91. min_element(const ForwardRange& rng)
  92. {
  93. BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
  94. return range_return<const ForwardRange,re>::pack(
  95. detail::min_element(boost::begin(rng), boost::end(rng), detail::less()),
  96. rng);
  97. }
  98. /// \overload
  99. template<range_return_value re, class ForwardRange, class BinaryPredicate>
  100. inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
  101. min_element(ForwardRange& rng, BinaryPredicate pred)
  102. {
  103. BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
  104. return range_return<ForwardRange,re>::pack(
  105. detail::min_element(boost::begin(rng), boost::end(rng), pred),
  106. rng);
  107. }
  108. /// \overload
  109. template<range_return_value re, class ForwardRange, class BinaryPredicate>
  110. inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
  111. min_element(const ForwardRange& rng, BinaryPredicate pred)
  112. {
  113. BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
  114. return range_return<const ForwardRange,re>::pack(
  115. detail::min_element(boost::begin(rng), boost::end(rng), pred),
  116. rng);
  117. }
  118. } // namespace range
  119. using range::min_element;
  120. } // namespace boost
  121. #endif // include guard