/* | |
* | |
* Copyright (c) 2003 | |
* John Maddock | |
* | |
* Use, modification and distribution are subject to 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) | |
* | |
*/ | |
/* | |
* LOCATION: see http://www.boost.org for most recent version. | |
* FILE regex_iterator.hpp | |
* VERSION see <boost/version.hpp> | |
* DESCRIPTION: Provides regex_iterator implementation. | |
*/ | |
#ifndef BOOST_REGEX_V4_REGEX_ITERATOR_HPP | |
#define BOOST_REGEX_V4_REGEX_ITERATOR_HPP | |
#include <boost/shared_ptr.hpp> | |
namespace boost{ | |
#ifdef BOOST_MSVC | |
#pragma warning(push) | |
#pragma warning(disable: 4103) | |
#endif | |
#ifdef BOOST_HAS_ABI_HEADERS | |
# include BOOST_ABI_PREFIX | |
#endif | |
#ifdef BOOST_MSVC | |
#pragma warning(pop) | |
#endif | |
template <class BidirectionalIterator, | |
class charT, | |
class traits> | |
class regex_iterator_implementation | |
{ | |
typedef basic_regex<charT, traits> regex_type; | |
match_results<BidirectionalIterator> what; // current match | |
BidirectionalIterator base; // start of sequence | |
BidirectionalIterator end; // end of sequence | |
const regex_type re; // the expression | |
match_flag_type flags; // flags for matching | |
public: | |
regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f) | |
: base(), end(last), re(*p), flags(f){} | |
bool init(BidirectionalIterator first) | |
{ | |
base = first; | |
return regex_search(first, end, what, re, flags); | |
} | |
bool compare(const regex_iterator_implementation& that) | |
{ | |
if(this == &that) return true; | |
return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second); | |
} | |
const match_results<BidirectionalIterator>& get() | |
{ return what; } | |
bool next() | |
{ | |
//if(what.prefix().first != what[0].second) | |
// flags |= match_prev_avail; | |
BidirectionalIterator next_start = what[0].second; | |
match_flag_type f(flags); | |
if(!what.length()) | |
f |= regex_constants::match_not_initial_null; | |
//if(base != next_start) | |
// f |= regex_constants::match_not_bob; | |
bool result = regex_search(next_start, end, what, re, f, base); | |
if(result) | |
what.set_base(base); | |
return result; | |
} | |
private: | |
regex_iterator_implementation& operator=(const regex_iterator_implementation&); | |
}; | |
template <class BidirectionalIterator, | |
class charT = BOOST_DEDUCED_TYPENAME re_detail::regex_iterator_traits<BidirectionalIterator>::value_type, | |
class traits = regex_traits<charT> > | |
class regex_iterator | |
#ifndef BOOST_NO_STD_ITERATOR | |
: public std::iterator< | |
std::forward_iterator_tag, | |
match_results<BidirectionalIterator>, | |
typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type, | |
const match_results<BidirectionalIterator>*, | |
const match_results<BidirectionalIterator>& > | |
#endif | |
{ | |
private: | |
typedef regex_iterator_implementation<BidirectionalIterator, charT, traits> impl; | |
typedef shared_ptr<impl> pimpl; | |
public: | |
typedef basic_regex<charT, traits> regex_type; | |
typedef match_results<BidirectionalIterator> value_type; | |
typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type | |
difference_type; | |
typedef const value_type* pointer; | |
typedef const value_type& reference; | |
typedef std::forward_iterator_tag iterator_category; | |
regex_iterator(){} | |
regex_iterator(BidirectionalIterator a, BidirectionalIterator b, | |
const regex_type& re, | |
match_flag_type m = match_default) | |
: pdata(new impl(&re, b, m)) | |
{ | |
if(!pdata->init(a)) | |
{ | |
pdata.reset(); | |
} | |
} | |
regex_iterator(const regex_iterator& that) | |
: pdata(that.pdata) {} | |
regex_iterator& operator=(const regex_iterator& that) | |
{ | |
pdata = that.pdata; | |
return *this; | |
} | |
bool operator==(const regex_iterator& that)const | |
{ | |
if((pdata.get() == 0) || (that.pdata.get() == 0)) | |
return pdata.get() == that.pdata.get(); | |
return pdata->compare(*(that.pdata.get())); | |
} | |
bool operator!=(const regex_iterator& that)const | |
{ return !(*this == that); } | |
const value_type& operator*()const | |
{ return pdata->get(); } | |
const value_type* operator->()const | |
{ return &(pdata->get()); } | |
regex_iterator& operator++() | |
{ | |
cow(); | |
if(0 == pdata->next()) | |
{ | |
pdata.reset(); | |
} | |
return *this; | |
} | |
regex_iterator operator++(int) | |
{ | |
regex_iterator result(*this); | |
++(*this); | |
return result; | |
} | |
private: | |
pimpl pdata; | |
void cow() | |
{ | |
// copy-on-write | |
if(pdata.get() && !pdata.unique()) | |
{ | |
pdata.reset(new impl(*(pdata.get()))); | |
} | |
} | |
}; | |
typedef regex_iterator<const char*> cregex_iterator; | |
typedef regex_iterator<std::string::const_iterator> sregex_iterator; | |
#ifndef BOOST_NO_WREGEX | |
typedef regex_iterator<const wchar_t*> wcregex_iterator; | |
typedef regex_iterator<std::wstring::const_iterator> wsregex_iterator; | |
#endif | |
// make_regex_iterator: | |
template <class charT, class traits> | |
inline regex_iterator<const charT*, charT, traits> make_regex_iterator(const charT* p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default) | |
{ | |
return regex_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, m); | |
} | |
template <class charT, class traits, class ST, class SA> | |
inline regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default) | |
{ | |
return regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, m); | |
} | |
#ifdef BOOST_MSVC | |
#pragma warning(push) | |
#pragma warning(disable: 4103) | |
#endif | |
#ifdef BOOST_HAS_ABI_HEADERS | |
# include BOOST_ABI_SUFFIX | |
#endif | |
#ifdef BOOST_MSVC | |
#pragma warning(pop) | |
#endif | |
} // namespace boost | |
#endif // BOOST_REGEX_V4_REGEX_ITERATOR_HPP | |