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