Add support for Boost.Ref in match_results::format.

Update docs accordingly.
Fixes #4020.

[SVN r60678]
This commit is contained in:
John Maddock
2010-03-17 18:20:09 +00:00
parent 446604c734
commit 67f5369cae
37 changed files with 391 additions and 255 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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&)