Claw  1.7.3
algorithm.tpp
1 /*
2  CLAW - a C++ Library Absolutely Wonderful
3 
4  CLAW is a free library without any particular aim but being useful to
5  anyone.
6 
7  Copyright (C) 2005-2011 Julien Jorge
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 
23  contact: julien.jorge@gamned.org
24 */
25 /**
26  * \file algorithm.tpp
27  * \brief Generic algorithms on sequences.
28  * \author Julien Jorge
29  */
30 
31 /*----------------------------------------------------------------------------*/
32 /**
33  * \brief Apply an unary function to all members of a sequence.
34  *
35  * This function works like std::for_each() but allows the function to apply
36  * non-const methods to its argument.
37  *
38  * \param first Iterator on the first element of the sequence.
39  * \param last Iterator just past the end of the sequence.
40  * \param f Function to apply to the elements of the sequence.
41  *
42  * \remark The return value of the unary function is ignored.
43  */
44 template<typename InputIterator, typename UnaryFunction>
45 UnaryFunction claw::inplace_for_each
46 ( InputIterator first, InputIterator last, UnaryFunction f )
47 {
48  for (; first!=last; ++first)
49  f(*first);
50 
51  return f;
52 } // inplace_for_each()
53 
54 /*----------------------------------------------------------------------------*/
55 /**
56  * \brief Find the position in a range of the first element not in the
57  * elements of a given range.
58  *
59  * \param first1 Iterator on the first element of the sequence in which we
60  * search.
61  * \param last1 Iterator just past the end of the sequence in which we search.
62  * \param first2 Iterator on the first element of the range of the elements to
63  * skip.
64  * \param last2 Iterator just past the end of the range of the elements to
65  * skip.
66  */
67 template<typename ForwardIterator1, typename ForwardIterator2>
68 ForwardIterator1 claw::find_first_not_of
69 ( ForwardIterator1 first1, ForwardIterator1 last1,
70  ForwardIterator2 first2, ForwardIterator2 last2 )
71 {
72  for ( ; first1!=last1; ++first1 )
73  {
74  bool found(false);
75  for ( ForwardIterator2 it(first2); !found && (it!=last2); ++it )
76  found = *first1 == *it;
77 
78  if (!found)
79  return first1;
80  }
81 
82  return last1;
83 } // find_first_not_of()
84 
85 /*----------------------------------------------------------------------------*/
86 /**
87  * \brief Replace a set of elements in a range by other elements.
88  * \param first Iterator on the first element in the range to modify.
89  * \param last Iterator just past the end of the range to modify.
90  * \param e1_first Iterator on the first element to replace.
91  * \param e1_last Iterator just past the last element to replace.
92  * \param e2_first Iterator on the first element to replace with.
93  * \param e2_last Iterator just past the last element to replace with.
94  *
95  * \return The number of replaced elements.
96  *
97  * Each element *(e1_first + i) will be replaced with *(e2_first + i).
98  * If the range (\a e1_first, \a e1_last) is smaller than
99  * (\a e2_first, \a e2_last), the latter will be completed by repeating its last
100  * element.
101  *
102  * \b Example :
103  * <tt>
104  * int* r = { 1, 0, 1, 1, 0, 2, 3, 0, 5, 1 };
105  * unsigned int* e1 = { 0, 1, 2 };
106  * unsigned int* e2 = { 1, 0 };
107  * claw::replace( r, r+10, e1, e1+3, e2, e2+2 );
108  * // r is now { 0, 1, 0, 0, 1, 0, 3, 1, 5, 0 }
109  * </tt>
110  */
111 template<typename ForwardIterator1, typename ForwardIterator2,
112  typename ForwardIterator3>
113 std::size_t claw::replace
114 ( ForwardIterator1 first, ForwardIterator1 last,
115  ForwardIterator2 e1_first, ForwardIterator2 e1_last,
116  ForwardIterator3 e2_first, ForwardIterator3 e2_last )
117 {
118  if ( (e1_first == e1_last) || (e2_first == e2_last) )
119  return 0;
120 
121  std::size_t count(0);
122 
123  for ( ; first != last; ++first )
124  {
125  bool stop(false);
126  ForwardIterator3 r(e2_first);
127 
128  for (ForwardIterator2 it=e1_first; !stop && (it!=e1_last); ++it)
129  {
130  if ( *first == *it )
131  {
132  *first = *r;
133  ++count;
134  stop = true;
135  }
136  else
137  {
138  ForwardIterator3 n=r;
139  ++n;
140  if (n!=e2_last)
141  r = n;
142  }
143  }
144  }
145 
146  return count;
147 } // replace()