You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
193 lines
7.2 KiB
193 lines
7.2 KiB
// Boost string_algo library iter_find.hpp header file ---------------------------// |
|
|
|
// Copyright Pavol Droba 2002-2003. |
|
// |
|
// Distributed under the Boost Software License, Version 1.0. |
|
// (See accompanying file LICENSE_1_0.txt or copy at |
|
// http://www.boost.org/LICENSE_1_0.txt) |
|
|
|
// See http://www.boost.org/ for updates, documentation, and revision history. |
|
|
|
#ifndef BOOST_STRING_ITER_FIND_HPP |
|
#define BOOST_STRING_ITER_FIND_HPP |
|
|
|
#include <boost/algorithm/string/config.hpp> |
|
#include <algorithm> |
|
#include <iterator> |
|
#include <boost/iterator/transform_iterator.hpp> |
|
|
|
#include <boost/range/iterator_range.hpp> |
|
#include <boost/range/begin.hpp> |
|
#include <boost/range/end.hpp> |
|
#include <boost/range/iterator.hpp> |
|
#include <boost/range/value_type.hpp> |
|
#include <boost/range/as_literal.hpp> |
|
|
|
#include <boost/algorithm/string/concept.hpp> |
|
#include <boost/algorithm/string/find_iterator.hpp> |
|
#include <boost/algorithm/string/detail/util.hpp> |
|
|
|
/*! \file |
|
Defines generic split algorithms. Split algorithms can be |
|
used to divide a sequence into several part according |
|
to a given criteria. Result is given as a 'container |
|
of containers' where elements are copies or references |
|
to extracted parts. |
|
|
|
There are two algorithms provided. One iterates over matching |
|
substrings, the other one over the gaps between these matches. |
|
*/ |
|
|
|
namespace boost { |
|
namespace algorithm { |
|
|
|
// iterate find ---------------------------------------------------// |
|
|
|
//! Iter find algorithm |
|
/*! |
|
This algorithm executes a given finder in iteration on the input, |
|
until the end of input is reached, or no match is found. |
|
Iteration is done using built-in find_iterator, so the real |
|
searching is performed only when needed. |
|
In each iteration new match is found and added to the result. |
|
|
|
\param Result A 'container container' to contain the result of search. |
|
Both outer and inner container must have constructor taking a pair |
|
of iterators as an argument. |
|
Typical type of the result is |
|
\c std::vector<boost::iterator_range<iterator>> |
|
(each element of such a vector will container a range delimiting |
|
a match). |
|
\param Input A container which will be searched. |
|
\param Finder A Finder object used for searching |
|
\return A reference the result |
|
|
|
\note Prior content of the result will be overwritten. |
|
*/ |
|
template< |
|
typename SequenceSequenceT, |
|
typename RangeT, |
|
typename FinderT > |
|
inline SequenceSequenceT& |
|
iter_find( |
|
SequenceSequenceT& Result, |
|
RangeT& Input, |
|
FinderT Finder ) |
|
{ |
|
BOOST_CONCEPT_ASSERT(( |
|
FinderConcept< |
|
FinderT, |
|
BOOST_STRING_TYPENAME range_iterator<RangeT>::type> |
|
)); |
|
|
|
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input)); |
|
|
|
typedef BOOST_STRING_TYPENAME |
|
range_iterator<RangeT>::type input_iterator_type; |
|
typedef find_iterator<input_iterator_type> find_iterator_type; |
|
typedef detail::copy_iterator_rangeF< |
|
BOOST_STRING_TYPENAME |
|
range_value<SequenceSequenceT>::type, |
|
input_iterator_type> copy_range_type; |
|
|
|
input_iterator_type InputEnd=::boost::end(lit_input); |
|
|
|
typedef transform_iterator<copy_range_type, find_iterator_type> |
|
transform_iter_type; |
|
|
|
transform_iter_type itBegin= |
|
::boost::make_transform_iterator( |
|
find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), |
|
copy_range_type()); |
|
|
|
transform_iter_type itEnd= |
|
::boost::make_transform_iterator( |
|
find_iterator_type(), |
|
copy_range_type()); |
|
|
|
SequenceSequenceT Tmp(itBegin, itEnd); |
|
|
|
Result.swap(Tmp); |
|
return Result; |
|
} |
|
|
|
// iterate split ---------------------------------------------------// |
|
|
|
//! Split find algorithm |
|
/*! |
|
This algorithm executes a given finder in iteration on the input, |
|
until the end of input is reached, or no match is found. |
|
Iteration is done using built-in find_iterator, so the real |
|
searching is performed only when needed. |
|
Each match is used as a separator of segments. These segments are then |
|
returned in the result. |
|
|
|
\param Result A 'container container' to container the result of search. |
|
Both outer and inner container must have constructor taking a pair |
|
of iterators as an argument. |
|
Typical type of the result is |
|
\c std::vector<boost::iterator_range<iterator>> |
|
(each element of such a vector will container a range delimiting |
|
a match). |
|
\param Input A container which will be searched. |
|
\param Finder A finder object used for searching |
|
\return A reference the result |
|
|
|
\note Prior content of the result will be overwritten. |
|
*/ |
|
template< |
|
typename SequenceSequenceT, |
|
typename RangeT, |
|
typename FinderT > |
|
inline SequenceSequenceT& |
|
iter_split( |
|
SequenceSequenceT& Result, |
|
RangeT& Input, |
|
FinderT Finder ) |
|
{ |
|
BOOST_CONCEPT_ASSERT(( |
|
FinderConcept<FinderT, |
|
BOOST_STRING_TYPENAME range_iterator<RangeT>::type> |
|
)); |
|
|
|
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input)); |
|
|
|
typedef BOOST_STRING_TYPENAME |
|
range_iterator<RangeT>::type input_iterator_type; |
|
typedef split_iterator<input_iterator_type> find_iterator_type; |
|
typedef detail::copy_iterator_rangeF< |
|
BOOST_STRING_TYPENAME |
|
range_value<SequenceSequenceT>::type, |
|
input_iterator_type> copy_range_type; |
|
|
|
input_iterator_type InputEnd=::boost::end(lit_input); |
|
|
|
typedef transform_iterator<copy_range_type, find_iterator_type> |
|
transform_iter_type; |
|
|
|
transform_iter_type itBegin= |
|
::boost::make_transform_iterator( |
|
find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), |
|
copy_range_type() ); |
|
|
|
transform_iter_type itEnd= |
|
::boost::make_transform_iterator( |
|
find_iterator_type(), |
|
copy_range_type() ); |
|
|
|
SequenceSequenceT Tmp(itBegin, itEnd); |
|
|
|
Result.swap(Tmp); |
|
return Result; |
|
} |
|
|
|
} // namespace algorithm |
|
|
|
// pull names to the boost namespace |
|
using algorithm::iter_find; |
|
using algorithm::iter_split; |
|
|
|
} // namespace boost |
|
|
|
|
|
#endif // BOOST_STRING_ITER_FIND_HPP
|
|
|