1// Boost string_algo library iter_find.hpp header file ---------------------------//
2
3// Copyright Pavol Droba 2002-2003.
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9// See http://www.boost.org/ for updates, documentation, and revision history.
10
11#ifndef BOOST_STRING_ITER_FIND_HPP
12#define BOOST_STRING_ITER_FIND_HPP
13
14#include <boost/algorithm/string/config.hpp>
15#include <algorithm>
16#include <iterator>
17#include <boost/iterator/transform_iterator.hpp>
18
19#include <boost/range/iterator_range_core.hpp>
20#include <boost/range/begin.hpp>
21#include <boost/range/end.hpp>
22#include <boost/range/iterator.hpp>
23#include <boost/range/value_type.hpp>
24#include <boost/range/as_literal.hpp>
25
26#include <boost/algorithm/string/concept.hpp>
27#include <boost/algorithm/string/find_iterator.hpp>
28#include <boost/algorithm/string/detail/util.hpp>
29
30/*! \file
31 Defines generic split algorithms. Split algorithms can be
32 used to divide a sequence into several part according
33 to a given criteria. Result is given as a 'container
34 of containers' where elements are copies or references
35 to extracted parts.
36
37 There are two algorithms provided. One iterates over matching
38 substrings, the other one over the gaps between these matches.
39*/
40
41namespace boost {
42 namespace algorithm {
43
44// iterate find ---------------------------------------------------//
45
46 //! Iter find algorithm
47 /*!
48 This algorithm executes a given finder in iteration on the input,
49 until the end of input is reached, or no match is found.
50 Iteration is done using built-in find_iterator, so the real
51 searching is performed only when needed.
52 In each iteration new match is found and added to the result.
53
54 \param Result A 'container container' to contain the result of search.
55 Both outer and inner container must have constructor taking a pair
56 of iterators as an argument.
57 Typical type of the result is
58 \c std::vector<boost::iterator_range<iterator>>
59 (each element of such a vector will container a range delimiting
60 a match).
61 \param Input A container which will be searched.
62 \param Finder A Finder object used for searching
63 \return A reference to the result
64
65 \note Prior content of the result will be overwritten.
66 */
67 template<
68 typename SequenceSequenceT,
69 typename RangeT,
70 typename FinderT >
71 inline SequenceSequenceT&
72 iter_find(
73 SequenceSequenceT& Result,
74 RangeT& Input,
75 FinderT Finder )
76 {
77 BOOST_CONCEPT_ASSERT((
78 FinderConcept<
79 FinderT,
80 BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
81 ));
82
83 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
84
85 typedef BOOST_STRING_TYPENAME
86 range_iterator<RangeT>::type input_iterator_type;
87 typedef find_iterator<input_iterator_type> find_iterator_type;
88 typedef detail::copy_iterator_rangeF<
89 BOOST_STRING_TYPENAME
90 range_value<SequenceSequenceT>::type,
91 input_iterator_type> copy_range_type;
92
93 input_iterator_type InputEnd=::boost::end(lit_input);
94
95 typedef transform_iterator<copy_range_type, find_iterator_type>
96 transform_iter_type;
97
98 transform_iter_type itBegin=
99 ::boost::make_transform_iterator(
100 find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
101 copy_range_type());
102
103 transform_iter_type itEnd=
104 ::boost::make_transform_iterator(
105 find_iterator_type(),
106 copy_range_type());
107
108 SequenceSequenceT Tmp(itBegin, itEnd);
109
110 Result.swap(Tmp);
111 return Result;
112 }
113
114// iterate split ---------------------------------------------------//
115
116 //! Split find algorithm
117 /*!
118 This algorithm executes a given finder in iteration on the input,
119 until the end of input is reached, or no match is found.
120 Iteration is done using built-in find_iterator, so the real
121 searching is performed only when needed.
122 Each match is used as a separator of segments. These segments are then
123 returned in the result.
124
125 \param Result A 'container container' to contain the result of search.
126 Both outer and inner container must have constructor taking a pair
127 of iterators as an argument.
128 Typical type of the result is
129 \c std::vector<boost::iterator_range<iterator>>
130 (each element of such a vector will container a range delimiting
131 a match).
132 \param Input A container which will be searched.
133 \param Finder A finder object used for searching
134 \return A reference to the result
135
136 \note Prior content of the result will be overwritten.
137 */
138 template<
139 typename SequenceSequenceT,
140 typename RangeT,
141 typename FinderT >
142 inline SequenceSequenceT&
143 iter_split(
144 SequenceSequenceT& Result,
145 RangeT& Input,
146 FinderT Finder )
147 {
148 BOOST_CONCEPT_ASSERT((
149 FinderConcept<FinderT,
150 BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
151 ));
152
153 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
154
155 typedef BOOST_STRING_TYPENAME
156 range_iterator<RangeT>::type input_iterator_type;
157 typedef split_iterator<input_iterator_type> find_iterator_type;
158 typedef detail::copy_iterator_rangeF<
159 BOOST_STRING_TYPENAME
160 range_value<SequenceSequenceT>::type,
161 input_iterator_type> copy_range_type;
162
163 input_iterator_type InputEnd=::boost::end(lit_input);
164
165 typedef transform_iterator<copy_range_type, find_iterator_type>
166 transform_iter_type;
167
168 transform_iter_type itBegin=
169 ::boost::make_transform_iterator(
170 find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
171 copy_range_type() );
172
173 transform_iter_type itEnd=
174 ::boost::make_transform_iterator(
175 find_iterator_type(),
176 copy_range_type() );
177
178 SequenceSequenceT Tmp(itBegin, itEnd);
179
180 Result.swap(Tmp);
181 return Result;
182 }
183
184 } // namespace algorithm
185
186 // pull names to the boost namespace
187 using algorithm::iter_find;
188 using algorithm::iter_split;
189
190} // namespace boost
191
192
193#endif // BOOST_STRING_ITER_FIND_HPP
194