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 41 namespace 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& iter_find(SequenceSequenceT & Result,RangeT & Input,FinderT Finder)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& iter_split(SequenceSequenceT & Result,RangeT & Input,FinderT Finder)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