Line data Source code
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& 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& 147 0 : 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 0 : 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 0 : 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 0 : 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 0 : transform_iter_type itEnd= 182 : ::boost::make_transform_iterator( 183 : find_iterator_type(), 184 : copy_range_type() ); 185 : 186 0 : SequenceSequenceT Tmp(itBegin, itEnd); 187 : 188 0 : Result.swap(Tmp); 189 0 : 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