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 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 75 RangeT&& Input, 76 #else 77 RangeT& Input, 78 #endif 79 FinderT Finder ) 80 { 81 BOOST_CONCEPT_ASSERT(( 82 FinderConcept< 83 FinderT, 84 BOOST_STRING_TYPENAME range_iterator<RangeT>::type> 85 )); 86 87 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input)); 88 89 typedef BOOST_STRING_TYPENAME 90 range_iterator<RangeT>::type input_iterator_type; 91 typedef find_iterator<input_iterator_type> find_iterator_type; 92 typedef detail::copy_iterator_rangeF< 93 BOOST_STRING_TYPENAME 94 range_value<SequenceSequenceT>::type, 95 input_iterator_type> copy_range_type; 96 97 input_iterator_type InputEnd=::boost::end(lit_input); 98 99 typedef transform_iterator<copy_range_type, find_iterator_type> 100 transform_iter_type; 101 102 transform_iter_type itBegin= 103 ::boost::make_transform_iterator( 104 find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), 105 copy_range_type()); 106 107 transform_iter_type itEnd= 108 ::boost::make_transform_iterator( 109 find_iterator_type(), 110 copy_range_type()); 111 112 SequenceSequenceT Tmp(itBegin, itEnd); 113 114 Result.swap(Tmp); 115 return Result; 116 } 117 118 // iterate split ---------------------------------------------------// 119 120 //! Split find algorithm 121 /*! 122 This algorithm executes a given finder in iteration on the input, 123 until the end of input is reached, or no match is found. 124 Iteration is done using built-in find_iterator, so the real 125 searching is performed only when needed. 126 Each match is used as a separator of segments. These segments are then 127 returned in the result. 128 129 \param Result A 'container container' to contain the result of search. 130 Both outer and inner container must have constructor taking a pair 131 of iterators as an argument. 132 Typical type of the result is 133 \c std::vector<boost::iterator_range<iterator>> 134 (each element of such a vector will container a range delimiting 135 a match). 136 \param Input A container which will be searched. 137 \param Finder A finder object used for searching 138 \return A reference to the result 139 140 \note Prior content of the result will be overwritten. 141 */ 142 template< 143 typename SequenceSequenceT, 144 typename RangeT, 145 typename FinderT > 146 inline SequenceSequenceT& iter_split(SequenceSequenceT & Result,RangeT && Input,FinderT Finder)147 iter_split( 148 SequenceSequenceT& Result, 149 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 150 RangeT&& Input, 151 #else 152 RangeT& Input, 153 #endif 154 FinderT Finder ) 155 { 156 BOOST_CONCEPT_ASSERT(( 157 FinderConcept<FinderT, 158 BOOST_STRING_TYPENAME range_iterator<RangeT>::type> 159 )); 160 161 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input)); 162 163 typedef BOOST_STRING_TYPENAME 164 range_iterator<RangeT>::type input_iterator_type; 165 typedef split_iterator<input_iterator_type> find_iterator_type; 166 typedef detail::copy_iterator_rangeF< 167 BOOST_STRING_TYPENAME 168 range_value<SequenceSequenceT>::type, 169 input_iterator_type> copy_range_type; 170 171 input_iterator_type InputEnd=::boost::end(lit_input); 172 173 typedef transform_iterator<copy_range_type, find_iterator_type> 174 transform_iter_type; 175 176 transform_iter_type itBegin= 177 ::boost::make_transform_iterator( 178 find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), 179 copy_range_type() ); 180 181 transform_iter_type itEnd= 182 ::boost::make_transform_iterator( 183 find_iterator_type(), 184 copy_range_type() ); 185 186 SequenceSequenceT Tmp(itBegin, itEnd); 187 188 Result.swap(Tmp); 189 return Result; 190 } 191 192 } // namespace algorithm 193 194 // pull names to the boost namespace 195 using algorithm::iter_find; 196 using algorithm::iter_split; 197 198 } // namespace boost 199 200 201 #endif // BOOST_STRING_ITER_FIND_HPP 202