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_SET_ALGORITHM_HPP_INCLUDED
10 #define BOOST_RANGE_ALGORITHM_SET_ALGORITHM_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 <algorithm>
17 
18 namespace boost
19 {
20     namespace range
21     {
22 
23 /// \brief template function includes
24 ///
25 /// range-based version of the includes std algorithm
26 ///
27 /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
28 /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
29 /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
30 template<class SinglePassRange1, class SinglePassRange2>
includes(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2)31 inline bool includes(const SinglePassRange1& rng1,
32                      const SinglePassRange2& rng2)
33 {
34     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
35     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
36     return std::includes(boost::begin(rng1),boost::end(rng1),
37                          boost::begin(rng2),boost::end(rng2));
38 }
39 
40 /// \overload
41 template<class SinglePassRange1, class SinglePassRange2,
42          class BinaryPredicate>
includes(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,BinaryPredicate pred)43 inline bool includes(const SinglePassRange1& rng1,
44                      const SinglePassRange2& rng2,
45                      BinaryPredicate         pred)
46 {
47     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
48     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
49     return std::includes(boost::begin(rng1), boost::end(rng1),
50                          boost::begin(rng2), boost::end(rng2), pred);
51 }
52 
53 /// \brief template function set_union
54 ///
55 /// range-based version of the set_union std algorithm
56 ///
57 /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
58 /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
59 /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
60 template<class SinglePassRange1, class SinglePassRange2,
61          class OutputIterator>
set_union(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,OutputIterator out)62 inline OutputIterator set_union(const SinglePassRange1& rng1,
63                                 const SinglePassRange2& rng2,
64                                 OutputIterator          out)
65 {
66     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
67     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
68     return std::set_union(boost::begin(rng1), boost::end(rng1),
69                           boost::begin(rng2), boost::end(rng2), out);
70 }
71 
72 /// \overload
73 template<class SinglePassRange1, class SinglePassRange2,
74          class OutputIterator, class BinaryPredicate>
set_union(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,OutputIterator out,BinaryPredicate pred)75 inline OutputIterator set_union(const SinglePassRange1& rng1,
76                                 const SinglePassRange2& rng2,
77                                 OutputIterator          out,
78                                 BinaryPredicate         pred)
79 {
80     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
81     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
82     return std::set_union(boost::begin(rng1), boost::end(rng1),
83                           boost::begin(rng2), boost::end(rng2), out, pred);
84 }
85 
86 /// \brief template function set_intersection
87 ///
88 /// range-based version of the set_intersection std algorithm
89 ///
90 /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
91 /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
92 /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
93 template<class SinglePassRange1, class SinglePassRange2,
94          class OutputIterator>
set_intersection(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,OutputIterator out)95 inline OutputIterator set_intersection(const SinglePassRange1& rng1,
96                                        const SinglePassRange2& rng2,
97                                        OutputIterator          out)
98 {
99     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
100     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
101     return std::set_intersection(boost::begin(rng1), boost::end(rng1),
102                                  boost::begin(rng2), boost::end(rng2), out);
103 }
104 
105 /// \overload
106 template<class SinglePassRange1, class SinglePassRange2,
107          class OutputIterator, class BinaryPredicate>
set_intersection(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,OutputIterator out,BinaryPredicate pred)108 inline OutputIterator set_intersection(const SinglePassRange1& rng1,
109                                        const SinglePassRange2& rng2,
110                                        OutputIterator          out,
111                                        BinaryPredicate         pred)
112 {
113     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
114     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
115     return std::set_intersection(boost::begin(rng1), boost::end(rng1),
116                                  boost::begin(rng2), boost::end(rng2),
117                                  out, pred);
118 }
119 
120 /// \brief template function set_difference
121 ///
122 /// range-based version of the set_difference std algorithm
123 ///
124 /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
125 /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
126 /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
127 template<class SinglePassRange1, class SinglePassRange2,
128          class OutputIterator>
set_difference(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,OutputIterator out)129 inline OutputIterator set_difference(const SinglePassRange1& rng1,
130                                      const SinglePassRange2& rng2,
131                                      OutputIterator out)
132 {
133     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
134     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
135     return std::set_difference(boost::begin(rng1), boost::end(rng1),
136                                boost::begin(rng2), boost::end(rng2), out);
137 }
138 
139 /// \overload
140 template<class SinglePassRange1, class SinglePassRange2,
141          class OutputIterator, class BinaryPredicate>
set_difference(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,OutputIterator out,BinaryPredicate pred)142 inline OutputIterator set_difference(const SinglePassRange1& rng1,
143                                      const SinglePassRange2& rng2,
144                                      OutputIterator          out,
145                                      BinaryPredicate         pred)
146 {
147     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
148     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
149     return std::set_difference(
150         boost::begin(rng1), boost::end(rng1),
151         boost::begin(rng2), boost::end(rng2), out, pred);
152 }
153 
154 /// \brief template function set_symmetric_difference
155 ///
156 /// range-based version of the set_symmetric_difference std algorithm
157 ///
158 /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
159 /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
160 /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
161 template<class SinglePassRange1, class SinglePassRange2,
162          class OutputIterator>
163 inline OutputIterator
set_symmetric_difference(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,OutputIterator out)164 set_symmetric_difference(const SinglePassRange1& rng1,
165                          const SinglePassRange2& rng2,
166                          OutputIterator          out)
167 {
168     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
169     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
170     return std::set_symmetric_difference(boost::begin(rng1), boost::end(rng1),
171                                          boost::begin(rng2), boost::end(rng2), out);
172 }
173 
174 /// \overload
175 template<class SinglePassRange1, class SinglePassRange2,
176          class OutputIterator, class BinaryPredicate>
177 inline OutputIterator
set_symmetric_difference(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,OutputIterator out,BinaryPredicate pred)178 set_symmetric_difference(const SinglePassRange1& rng1,
179                          const SinglePassRange2& rng2,
180                          OutputIterator          out,
181                          BinaryPredicate         pred)
182 {
183     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
184     BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
185     return std::set_symmetric_difference(
186         boost::begin(rng1), boost::end(rng1),
187         boost::begin(rng2), boost::end(rng2), out, pred);
188 }
189 
190     } // namespace range
191     using range::includes;
192     using range::set_union;
193     using range::set_intersection;
194     using range::set_difference;
195     using range::set_symmetric_difference;
196 } // namespace boost
197 
198 #endif // include guard
199