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 // 7 // For more information, see http://www.boost.org/libs/range/ 8 // 9 #ifndef BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED 10 #define BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED 11 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/range_return.hpp> 17 #include <algorithm> 18 19 namespace boost 20 { 21 namespace range 22 { 23 24 /// \brief template function find_end 25 /// 26 /// range-based version of the find_end std algorithm 27 /// 28 /// \pre ForwardRange1 is a model of the ForwardRangeConcept 29 /// \pre ForwardRange2 is a model of the ForwardRangeConcept 30 /// \pre BinaryPredicate is a model of the BinaryPredicateConcept 31 template< class ForwardRange1, class ForwardRange2 > 32 inline BOOST_DEDUCED_TYPENAME disable_if< 33 is_const<ForwardRange1>, 34 BOOST_DEDUCED_TYPENAME range_iterator< ForwardRange1 >::type 35 >::type 36 find_end(ForwardRange1 & rng1, const ForwardRange2& rng2) 37 { 38 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> )); 39 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> )); 40 41 return std::find_end(boost::begin(rng1),boost::end(rng1), 42 boost::begin(rng2),boost::end(rng2)); 43 } 44 45 /// \overload 46 template< class ForwardRange1, class ForwardRange2 > 47 inline BOOST_DEDUCED_TYPENAME range_iterator< const ForwardRange1 >::type 48 find_end(const ForwardRange1 & rng1, const ForwardRange2& rng2) 49 { 50 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> )); 51 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> )); 52 53 return std::find_end(boost::begin(rng1),boost::end(rng1), 54 boost::begin(rng2),boost::end(rng2)); 55 } 56 57 /// \overload 58 template< class ForwardRange1, class ForwardRange2, class BinaryPredicate > 59 inline BOOST_DEDUCED_TYPENAME disable_if< 60 is_const<ForwardRange1>, 61 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type 62 >::type 63 find_end(ForwardRange1 & rng1, const ForwardRange2& rng2, BinaryPredicate pred) 64 { 65 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> )); 66 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> )); 67 68 return std::find_end(boost::begin(rng1),boost::end(rng1), 69 boost::begin(rng2),boost::end(rng2),pred); 70 } 71 72 /// \overload 73 template< class ForwardRange1, class ForwardRange2, class BinaryPredicate > 74 inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type 75 find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) 76 { 77 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> )); 78 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> )); 79 80 return std::find_end(boost::begin(rng1),boost::end(rng1), 81 boost::begin(rng2),boost::end(rng2),pred); 82 } 83 84 /// \overload 85 template< range_return_value re, class ForwardRange1, class ForwardRange2 > 86 inline BOOST_DEDUCED_TYPENAME disable_if< 87 is_const<ForwardRange1>, 88 BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type 89 >::type 90 find_end(ForwardRange1& rng1, const ForwardRange2& rng2) 91 { 92 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> )); 93 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> )); 94 95 return range_return<ForwardRange1,re>:: 96 pack(std::find_end(boost::begin(rng1), boost::end(rng1), 97 boost::begin(rng2), boost::end(rng2)), 98 rng1); 99 } 100 101 /// \overload 102 template< range_return_value re, class ForwardRange1, class ForwardRange2 > 103 inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type 104 find_end(const ForwardRange1& rng1, const ForwardRange2& rng2) 105 { 106 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> )); 107 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> )); 108 109 return range_return<const ForwardRange1,re>:: 110 pack(std::find_end(boost::begin(rng1), boost::end(rng1), 111 boost::begin(rng2), boost::end(rng2)), 112 rng1); 113 } 114 115 /// \overload 116 template< range_return_value re, class ForwardRange1, class ForwardRange2, 117 class BinaryPredicate > 118 inline BOOST_DEDUCED_TYPENAME disable_if< 119 is_const<ForwardRange1>, 120 BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type 121 >::type 122 find_end(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) 123 { 124 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> )); 125 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> )); 126 127 return range_return<ForwardRange1,re>:: 128 pack(std::find_end(boost::begin(rng1), boost::end(rng1), 129 boost::begin(rng2), boost::end(rng2), pred), 130 rng1); 131 } 132 133 /// \overload 134 template< range_return_value re, class ForwardRange1, class ForwardRange2, 135 class BinaryPredicate > 136 inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type 137 find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) 138 { 139 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> )); 140 BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> )); 141 142 return range_return<const ForwardRange1,re>:: 143 pack(std::find_end(boost::begin(rng1), boost::end(rng1), 144 boost::begin(rng2), boost::end(rng2), pred), 145 rng1); 146 } 147 148 } // namespace range 149 using range::find_end; 150 } // namespace boost 151 152 #endif // include guard 153