mirror of
https://github.com/boostorg/regex.git
synced 2025-07-24 09:37:36 +02:00
Add support for Boost.Ref in match_results::format.
Update docs accordingly. Fixes #4020. [SVN r60678]
This commit is contained in:
@ -76,6 +76,46 @@ namespace std{
|
||||
typedef boost::char_architype char_type;
|
||||
};
|
||||
}
|
||||
//
|
||||
// Allocator architype:
|
||||
//
|
||||
template <class T>
|
||||
class allocator_architype
|
||||
{
|
||||
public:
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
typedef unsigned size_type;
|
||||
typedef int difference_type;
|
||||
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef allocator_architype<U> other;
|
||||
};
|
||||
|
||||
pointer address(reference r);
|
||||
const_pointer address(const_reference r);
|
||||
pointer allocate(size_type);
|
||||
pointer allocate(size_type, pointer);
|
||||
void deallocate(pointer, size_type);
|
||||
size_type max_size()const;
|
||||
|
||||
allocator_architype();
|
||||
allocator_architype(const allocator_architype&);
|
||||
|
||||
void construct(pointer, const_reference);
|
||||
void destroy(pointer);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
bool operator == (const allocator_architype<T>&, const allocator_architype<T>&);
|
||||
template <class T>
|
||||
bool operator != (const allocator_architype<T>&, const allocator_architype<T>&);
|
||||
|
||||
namespace boost{
|
||||
//
|
||||
// regex_traits_architype:
|
||||
@ -244,7 +284,8 @@ struct BaseRegexConcept
|
||||
typedef const value_type* pointer_type;
|
||||
typedef bidirectional_iterator_archetype<value_type> BidiIterator;
|
||||
typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
|
||||
typedef global_regex_namespace::match_results<BidiIterator> match_results_type;
|
||||
typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;
|
||||
typedef global_regex_namespace::match_results<BidiIterator> match_results_default_type;
|
||||
typedef output_iterator_archetype<value_type> OutIterator;
|
||||
typedef typename regex_traits_computer<Regex>::type traits_type;
|
||||
typedef global_regex_namespace::regex_iterator<BidiIterator, value_type, traits_type> regex_iterator_type;
|
||||
@ -318,7 +359,7 @@ struct BaseRegexConcept
|
||||
const global_regex_namespace::regex_error except(e1);
|
||||
e1 = except.code();
|
||||
|
||||
typedef typename Regex::value_type value_type;
|
||||
typedef typename Regex::value_type regex_value_type;
|
||||
function_requires< RegexTraitsConcept<global_regex_namespace::regex_traits<char> > >();
|
||||
function_requires< BaseRegexConcept<global_regex_namespace::basic_regex<char> > >();
|
||||
}
|
||||
@ -484,10 +525,10 @@ struct BaseRegexConcept
|
||||
typedef typename regex_iterator_type::reference rit_reference;
|
||||
typedef typename regex_iterator_type::iterator_category rit_iterator_category;
|
||||
BOOST_STATIC_ASSERT((::boost::is_same<rit_regex_type, Regex>::value));
|
||||
BOOST_STATIC_ASSERT((::boost::is_same<rit_value_type, match_results_type>::value));
|
||||
BOOST_STATIC_ASSERT((::boost::is_same<rit_value_type, match_results_default_type>::value));
|
||||
BOOST_STATIC_ASSERT((::boost::is_same<rit_difference_type, std::ptrdiff_t>::value));
|
||||
BOOST_STATIC_ASSERT((::boost::is_same<rit_pointer, const match_results_type*>::value));
|
||||
BOOST_STATIC_ASSERT((::boost::is_same<rit_reference, const match_results_type&>::value));
|
||||
BOOST_STATIC_ASSERT((::boost::is_same<rit_pointer, const match_results_default_type*>::value));
|
||||
BOOST_STATIC_ASSERT((::boost::is_same<rit_reference, const match_results_default_type&>::value));
|
||||
BOOST_STATIC_ASSERT((::boost::is_convertible<rit_iterator_category*, std::forward_iterator_tag*>::value));
|
||||
// this takes care of most of the checks needed:
|
||||
function_requires<ForwardIteratorConcept<regex_iterator_type> >();
|
||||
@ -540,7 +581,10 @@ struct BaseRegexConcept
|
||||
OutIterator m_out;
|
||||
BidiIterator m_in;
|
||||
global_regex_namespace::regex_constants::match_flag_type m_mft;
|
||||
global_regex_namespace::match_results<pointer_type> m_pmatch;
|
||||
global_regex_namespace::match_results<
|
||||
pointer_type,
|
||||
allocator_architype<global_regex_namespace::sub_match<pointer_type> > >
|
||||
m_pmatch;
|
||||
|
||||
BaseRegexConcept();
|
||||
BaseRegexConcept(const BaseRegexConcept&);
|
||||
@ -564,7 +608,7 @@ struct RegexConcept
|
||||
typedef std::basic_string<value_type> string_type;
|
||||
typedef boost::bidirectional_iterator_archetype<value_type> BidiIterator;
|
||||
typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
|
||||
typedef global_regex_namespace::match_results<BidiIterator> match_results_type;
|
||||
typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;
|
||||
typedef output_iterator_archetype<value_type> OutIterator;
|
||||
|
||||
|
||||
@ -739,7 +783,7 @@ struct RegexConcept
|
||||
OutIterator m_out;
|
||||
BidiIterator m_in;
|
||||
global_regex_namespace::regex_constants::match_flag_type m_mft;
|
||||
global_regex_namespace::match_results<typename string_type::const_iterator> m_smatch;
|
||||
global_regex_namespace::match_results<typename string_type::const_iterator, allocator_architype<global_regex_namespace::sub_match<typename string_type::const_iterator> > > m_smatch;
|
||||
|
||||
RegexConcept();
|
||||
RegexConcept(const RegexConcept&);
|
||||
@ -752,7 +796,7 @@ template <class M>
|
||||
struct functor1
|
||||
{
|
||||
typedef typename M::char_type char_type;
|
||||
const char_type* operator()(const M&)
|
||||
const char_type* operator()(const M&)const
|
||||
{
|
||||
static const char_type c = static_cast<char_type>(0);
|
||||
return &c;
|
||||
@ -762,7 +806,7 @@ template <class M>
|
||||
struct functor1b
|
||||
{
|
||||
typedef typename M::char_type char_type;
|
||||
std::vector<char_type> operator()(const M&)
|
||||
std::vector<char_type> operator()(const M&)const
|
||||
{
|
||||
static const std::vector<char_type> c;
|
||||
return c;
|
||||
@ -772,7 +816,7 @@ template <class M>
|
||||
struct functor2
|
||||
{
|
||||
template <class O>
|
||||
O operator()(const M& /*m*/, O i)
|
||||
O operator()(const M& /*m*/, O i)const
|
||||
{
|
||||
return i;
|
||||
}
|
||||
@ -781,7 +825,7 @@ template <class M>
|
||||
struct functor3
|
||||
{
|
||||
template <class O>
|
||||
O operator()(const M& /*m*/, O i, regex_constants::match_flag_type)
|
||||
O operator()(const M& /*m*/, O i, regex_constants::match_flag_type)const
|
||||
{
|
||||
return i;
|
||||
}
|
||||
@ -806,7 +850,8 @@ struct BoostRegexConcept
|
||||
typedef bidirectional_iterator_archetype<value_type> BidiIterator;
|
||||
typedef output_iterator_archetype<value_type> OutputIterator;
|
||||
typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
|
||||
typedef global_regex_namespace::match_results<BidiIterator> match_results_type;
|
||||
typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;
|
||||
typedef global_regex_namespace::match_results<BidiIterator> match_results_default_type;
|
||||
|
||||
void constraints()
|
||||
{
|
||||
@ -930,36 +975,90 @@ struct BoostRegexConcept
|
||||
//
|
||||
regex_constants::match_flag_type f = regex_constants::match_default;
|
||||
OutputIterator out = static_object<OutputIterator>::get();
|
||||
functor3<match_results_type> func3;
|
||||
out = regex_format(out, m_cresults, func3, f);
|
||||
out = regex_format(out, m_cresults, func3);
|
||||
functor2<match_results_type> func2;
|
||||
out = regex_format(out, m_cresults, func2, f);
|
||||
out = regex_format(out, m_cresults, func2);
|
||||
functor1<match_results_type> func1;
|
||||
out = regex_format(out, m_cresults, func1, f);
|
||||
out = regex_format(out, m_cresults, func1);
|
||||
|
||||
functor3<match_results_default_type> func3;
|
||||
functor2<match_results_default_type> func2;
|
||||
functor1<match_results_default_type> func1;
|
||||
|
||||
functor3<match_results_type> func3b;
|
||||
functor2<match_results_type> func2b;
|
||||
functor1<match_results_type> func1b;
|
||||
|
||||
m_string += regex_format(m_cresults, func3, f);
|
||||
m_string += regex_format(m_cresults, func3);
|
||||
m_string += regex_format(m_cresults, func2, f);
|
||||
m_string += regex_format(m_cresults, func2);
|
||||
m_string += regex_format(m_cresults, func1, f);
|
||||
m_string += regex_format(m_cresults, func1);
|
||||
out = regex_format(out, m_cresults, func3b, f);
|
||||
out = regex_format(out, m_cresults, func3b);
|
||||
out = regex_format(out, m_cresults, func2b, f);
|
||||
out = regex_format(out, m_cresults, func2b);
|
||||
out = regex_format(out, m_cresults, func1b, f);
|
||||
out = regex_format(out, m_cresults, func1b);
|
||||
out = regex_format(out, m_cresults, ref(func3b), f);
|
||||
out = regex_format(out, m_cresults, ref(func3b));
|
||||
out = regex_format(out, m_cresults, ref(func2b), f);
|
||||
out = regex_format(out, m_cresults, ref(func2b));
|
||||
out = regex_format(out, m_cresults, ref(func1b), f);
|
||||
out = regex_format(out, m_cresults, ref(func1b));
|
||||
out = regex_format(out, m_cresults, cref(func3b), f);
|
||||
out = regex_format(out, m_cresults, cref(func3b));
|
||||
out = regex_format(out, m_cresults, cref(func2b), f);
|
||||
out = regex_format(out, m_cresults, cref(func2b));
|
||||
out = regex_format(out, m_cresults, cref(func1b), f);
|
||||
out = regex_format(out, m_cresults, cref(func1b));
|
||||
|
||||
out = m_cresults.format(out, func3, f);
|
||||
out = m_cresults.format(out, func3);
|
||||
out = m_cresults.format(out, func2, f);
|
||||
out = m_cresults.format(out, func2);
|
||||
out = m_cresults.format(out, func1, f);
|
||||
out = m_cresults.format(out, func1);
|
||||
m_string += regex_format(m_cresults, func3b, f);
|
||||
m_string += regex_format(m_cresults, func3b);
|
||||
m_string += regex_format(m_cresults, func2b, f);
|
||||
m_string += regex_format(m_cresults, func2b);
|
||||
m_string += regex_format(m_cresults, func1b, f);
|
||||
m_string += regex_format(m_cresults, func1b);
|
||||
m_string += regex_format(m_cresults, ref(func3b), f);
|
||||
m_string += regex_format(m_cresults, ref(func3b));
|
||||
m_string += regex_format(m_cresults, ref(func2b), f);
|
||||
m_string += regex_format(m_cresults, ref(func2b));
|
||||
m_string += regex_format(m_cresults, ref(func1b), f);
|
||||
m_string += regex_format(m_cresults, ref(func1b));
|
||||
m_string += regex_format(m_cresults, cref(func3b), f);
|
||||
m_string += regex_format(m_cresults, cref(func3b));
|
||||
m_string += regex_format(m_cresults, cref(func2b), f);
|
||||
m_string += regex_format(m_cresults, cref(func2b));
|
||||
m_string += regex_format(m_cresults, cref(func1b), f);
|
||||
m_string += regex_format(m_cresults, cref(func1b));
|
||||
|
||||
m_string += m_cresults.format(func3, f);
|
||||
m_string += m_cresults.format(func3);
|
||||
m_string += m_cresults.format(func2, f);
|
||||
m_string += m_cresults.format(func2);
|
||||
m_string += m_cresults.format(func1, f);
|
||||
m_string += m_cresults.format(func1);
|
||||
out = m_cresults.format(out, func3b, f);
|
||||
out = m_cresults.format(out, func3b);
|
||||
out = m_cresults.format(out, func2b, f);
|
||||
out = m_cresults.format(out, func2b);
|
||||
out = m_cresults.format(out, func1b, f);
|
||||
out = m_cresults.format(out, func1b);
|
||||
out = m_cresults.format(out, ref(func3b), f);
|
||||
out = m_cresults.format(out, ref(func3b));
|
||||
out = m_cresults.format(out, ref(func2b), f);
|
||||
out = m_cresults.format(out, ref(func2b));
|
||||
out = m_cresults.format(out, ref(func1b), f);
|
||||
out = m_cresults.format(out, ref(func1b));
|
||||
out = m_cresults.format(out, cref(func3b), f);
|
||||
out = m_cresults.format(out, cref(func3b));
|
||||
out = m_cresults.format(out, cref(func2b), f);
|
||||
out = m_cresults.format(out, cref(func2b));
|
||||
out = m_cresults.format(out, cref(func1b), f);
|
||||
out = m_cresults.format(out, cref(func1b));
|
||||
|
||||
m_string += m_cresults.format(func3b, f);
|
||||
m_string += m_cresults.format(func3b);
|
||||
m_string += m_cresults.format(func2b, f);
|
||||
m_string += m_cresults.format(func2b);
|
||||
m_string += m_cresults.format(func1b, f);
|
||||
m_string += m_cresults.format(func1b);
|
||||
m_string += m_cresults.format(ref(func3b), f);
|
||||
m_string += m_cresults.format(ref(func3b));
|
||||
m_string += m_cresults.format(ref(func2b), f);
|
||||
m_string += m_cresults.format(ref(func2b));
|
||||
m_string += m_cresults.format(ref(func1b), f);
|
||||
m_string += m_cresults.format(ref(func1b));
|
||||
m_string += m_cresults.format(cref(func3b), f);
|
||||
m_string += m_cresults.format(cref(func3b));
|
||||
m_string += m_cresults.format(cref(func2b), f);
|
||||
m_string += m_cresults.format(cref(func2b));
|
||||
m_string += m_cresults.format(cref(func1b), f);
|
||||
m_string += m_cresults.format(cref(func1b));
|
||||
|
||||
out = regex_replace(out, m_in, m_in, ce, func3, f);
|
||||
out = regex_replace(out, m_in, m_in, ce, func3);
|
||||
@ -967,6 +1066,18 @@ struct BoostRegexConcept
|
||||
out = regex_replace(out, m_in, m_in, ce, func2);
|
||||
out = regex_replace(out, m_in, m_in, ce, func1, f);
|
||||
out = regex_replace(out, m_in, m_in, ce, func1);
|
||||
out = regex_replace(out, m_in, m_in, ce, ref(func3), f);
|
||||
out = regex_replace(out, m_in, m_in, ce, ref(func3));
|
||||
out = regex_replace(out, m_in, m_in, ce, ref(func2), f);
|
||||
out = regex_replace(out, m_in, m_in, ce, ref(func2));
|
||||
out = regex_replace(out, m_in, m_in, ce, ref(func1), f);
|
||||
out = regex_replace(out, m_in, m_in, ce, ref(func1));
|
||||
out = regex_replace(out, m_in, m_in, ce, cref(func3), f);
|
||||
out = regex_replace(out, m_in, m_in, ce, cref(func3));
|
||||
out = regex_replace(out, m_in, m_in, ce, cref(func2), f);
|
||||
out = regex_replace(out, m_in, m_in, ce, cref(func2));
|
||||
out = regex_replace(out, m_in, m_in, ce, cref(func1), f);
|
||||
out = regex_replace(out, m_in, m_in, ce, cref(func1));
|
||||
|
||||
functor3<match_results<typename string_type::const_iterator> > func3s;
|
||||
functor2<match_results<typename string_type::const_iterator> > func2s;
|
||||
@ -977,6 +1088,18 @@ struct BoostRegexConcept
|
||||
m_string += regex_replace(m_string, ce, func2s);
|
||||
m_string += regex_replace(m_string, ce, func1s, f);
|
||||
m_string += regex_replace(m_string, ce, func1s);
|
||||
m_string += regex_replace(m_string, ce, ref(func3s), f);
|
||||
m_string += regex_replace(m_string, ce, ref(func3s));
|
||||
m_string += regex_replace(m_string, ce, ref(func2s), f);
|
||||
m_string += regex_replace(m_string, ce, ref(func2s));
|
||||
m_string += regex_replace(m_string, ce, ref(func1s), f);
|
||||
m_string += regex_replace(m_string, ce, ref(func1s));
|
||||
m_string += regex_replace(m_string, ce, cref(func3s), f);
|
||||
m_string += regex_replace(m_string, ce, cref(func3s));
|
||||
m_string += regex_replace(m_string, ce, cref(func2s), f);
|
||||
m_string += regex_replace(m_string, ce, cref(func2s));
|
||||
m_string += regex_replace(m_string, ce, cref(func1s), f);
|
||||
m_string += regex_replace(m_string, ce, cref(func1s));
|
||||
}
|
||||
|
||||
std::basic_ostream<value_type> m_stream;
|
||||
|
@ -468,9 +468,9 @@ private:
|
||||
// matching flags in use:
|
||||
match_flag_type m_match_flags;
|
||||
// how many states we have examined so far:
|
||||
boost::uintmax_t state_count;
|
||||
std::ptrdiff_t state_count;
|
||||
// max number of states to examine before giving up:
|
||||
boost::uintmax_t max_state_count;
|
||||
std::ptrdiff_t max_state_count;
|
||||
// whether we should ignore case or not:
|
||||
bool icase;
|
||||
// set to true when (position == last), indicates that we may have a partial match:
|
||||
|
@ -98,23 +98,23 @@ void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std
|
||||
//
|
||||
// Calculate NS^2 first:
|
||||
//
|
||||
static const boost::uintmax_t k = 100000;
|
||||
boost::uintmax_t dist = boost::re_detail::distance(base, last);
|
||||
static const std::ptrdiff_t k = 100000;
|
||||
std::ptrdiff_t dist = boost::re_detail::distance(base, last);
|
||||
if(dist == 0)
|
||||
dist = 1;
|
||||
boost::uintmax_t states = re.size();
|
||||
std::ptrdiff_t states = re.size();
|
||||
if(states == 0)
|
||||
states = 1;
|
||||
states *= states;
|
||||
if((std::numeric_limits<boost::uintmax_t>::max)() / dist < states)
|
||||
if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
|
||||
{
|
||||
max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2;
|
||||
max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
|
||||
return;
|
||||
}
|
||||
states *= dist;
|
||||
if((std::numeric_limits<boost::uintmax_t>::max)() - k < states)
|
||||
if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
|
||||
{
|
||||
max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2;
|
||||
max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
|
||||
return;
|
||||
}
|
||||
states += k;
|
||||
@ -125,15 +125,15 @@ void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std
|
||||
// Now calculate N^2:
|
||||
//
|
||||
states = dist;
|
||||
if((std::numeric_limits<boost::uintmax_t>::max)() / dist < states)
|
||||
if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
|
||||
{
|
||||
max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2;
|
||||
max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
|
||||
return;
|
||||
}
|
||||
states *= dist;
|
||||
if((std::numeric_limits<boost::uintmax_t>::max)() - k < states)
|
||||
if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
|
||||
{
|
||||
max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2;
|
||||
max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
|
||||
return;
|
||||
}
|
||||
states += k;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#endif
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@ -895,7 +896,7 @@ private:
|
||||
// F must be a pointer, a function, or a class with a function call operator:
|
||||
//
|
||||
BOOST_STATIC_ASSERT((::boost::is_pointer<F>::value || ::boost::is_function<F>::value || ::boost::is_class<F>::value));
|
||||
static formatter_wrapper<F> f;
|
||||
static formatter_wrapper<typename unwrap_reference<F>::type> f;
|
||||
static M m;
|
||||
static O out;
|
||||
static boost::regex_constants::match_flag_type flags;
|
||||
@ -963,7 +964,7 @@ struct format_functor3
|
||||
template <class OutputIter>
|
||||
OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f)
|
||||
{
|
||||
return func(m, i, f);
|
||||
return unwrap_ref(func)(m, i, f);
|
||||
}
|
||||
template <class OutputIter, class Traits>
|
||||
OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
|
||||
@ -983,7 +984,7 @@ struct format_functor2
|
||||
template <class OutputIter>
|
||||
OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)
|
||||
{
|
||||
return func(m, i);
|
||||
return unwrap_ref(func)(m, i);
|
||||
}
|
||||
template <class OutputIter, class Traits>
|
||||
OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
|
||||
@ -1020,7 +1021,7 @@ struct format_functor1
|
||||
template <class OutputIter>
|
||||
OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)
|
||||
{
|
||||
return do_format_string(func(m), i);
|
||||
return do_format_string(unwrap_ref(func)(m), i);
|
||||
}
|
||||
template <class OutputIter, class Traits>
|
||||
OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
|
||||
|
Reference in New Issue
Block a user