1 /*
2    Copyright (c) Marshall Clow 2008-2012.
3 
4    Distributed under the Boost Software License, Version 1.0. (See accompanying
5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 */
7 
8 /// \file  copy_if.hpp
9 /// \brief Copy a subset of a sequence to a new sequence
10 /// \author Marshall Clow
11 
12 #ifndef BOOST_ALGORITHM_COPY_IF_HPP
13 #define BOOST_ALGORITHM_COPY_IF_HPP
14 
15 #include <algorithm>    // for std::copy_if, if available
16 #include <boost/range/begin.hpp>
17 #include <boost/range/end.hpp>
18 
19 namespace boost { namespace algorithm {
20 
21 /// \fn copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
22 /// \brief Copies all the elements from the input range that satisfy the
23 /// predicate to the output range.
24 /// \return The updated output iterator
25 ///
26 /// \param first    The start of the input sequence
27 /// \param last     One past the end of the input sequence
28 /// \param result   An output iterator to write the results into
29 /// \param p        A predicate for testing the elements of the range
30 /// \note           This function is part of the C++2011 standard library.
31 ///  We will use the standard one if it is available,
32 ///  otherwise we have our own implementation.
33 template<typename InputIterator, typename OutputIterator, typename Predicate>
34 OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
35 {
36     for ( ; first != last; ++first )
37         if (p(*first))
38             *result++ = *first;
39     return result;
40 }
41 
42 /// \fn copy_if ( const Range &r, OutputIterator result, Predicate p )
43 /// \brief Copies all the elements from the input range that satisfy the
44 /// predicate to the output range.
45 /// \return The updated output iterator
46 ///
47 /// \param r        The input range
48 /// \param result   An output iterator to write the results into
49 /// \param p        A predicate for testing the elements of the range
50 ///
51 template<typename Range, typename OutputIterator, typename Predicate>
52 OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p )
53 {
54     return boost::algorithm::copy_if (boost::begin (r), boost::end(r), result, p);
55 }
56 
57 
58 /// \fn copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
59 /// \brief Copies all the elements at the start of the input range that
60 ///     satisfy the predicate to the output range.
61 /// \return The updated input and output iterators
62 ///
63 /// \param first    The start of the input sequence
64 /// \param last     One past the end of the input sequence
65 /// \param result   An output iterator to write the results into
66 /// \param p        A predicate for testing the elements of the range
67 ///
68 template<typename InputIterator, typename OutputIterator, typename Predicate>
69 std::pair<InputIterator, OutputIterator>
copy_while(InputIterator first,InputIterator last,OutputIterator result,Predicate p)70 copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
71 {
72     for ( ; first != last && p(*first); ++first )
73         *result++ = *first;
74     return std::make_pair(first, result);
75 }
76 
77 /// \fn copy_while ( const Range &r, OutputIterator result, Predicate p )
78 /// \brief Copies all the elements at the start of the input range that
79 ///     satisfy the predicate to the output range.
80 /// \return The updated input and output iterators
81 ///
82 /// \param r        The input range
83 /// \param result   An output iterator to write the results into
84 /// \param p        A predicate for testing the elements of the range
85 ///
86 template<typename Range, typename OutputIterator, typename Predicate>
87 std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
copy_while(const Range & r,OutputIterator result,Predicate p)88 copy_while ( const Range &r, OutputIterator result, Predicate p )
89 {
90     return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p);
91 }
92 
93 
94 /// \fn copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
95 /// \brief Copies all the elements at the start of the input range that do not
96 ///     satisfy the predicate to the output range.
97 /// \return The updated output iterator
98 ///
99 /// \param first    The start of the input sequence
100 /// \param last     One past the end of the input sequence
101 /// \param result   An output iterator to write the results into
102 /// \param p        A predicate for testing the elements of the range
103 ///
104 template<typename InputIterator, typename OutputIterator, typename Predicate>
105 std::pair<InputIterator, OutputIterator>
copy_until(InputIterator first,InputIterator last,OutputIterator result,Predicate p)106 copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
107 {
108     for ( ; first != last && !p(*first); ++first )
109         *result++ = *first;
110     return std::make_pair(first, result);
111 }
112 
113 /// \fn copy_until ( const Range &r, OutputIterator result, Predicate p )
114 /// \brief Copies all the elements at the start of the input range that do not
115 ///     satisfy the predicate to the output range.
116 /// \return The updated output iterator
117 ///
118 /// \param r        The input range
119 /// \param result   An output iterator to write the results into
120 /// \param p        A predicate for testing the elements of the range
121 ///
122 template<typename Range, typename OutputIterator, typename Predicate>
123 std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
copy_until(const Range & r,OutputIterator result,Predicate p)124 copy_until ( const Range &r, OutputIterator result, Predicate p )
125 {
126     return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p);
127 }
128 
129 }} // namespace boost and algorithm
130 
131 #endif  // BOOST_ALGORITHM_COPY_IF_HPP
132