Started to improve docs.

Added more tests.
Added code to speed up traits class construction and usage.
Tweeked extern template code.


[SVN r25002]
This commit is contained in:
John Maddock
2004-09-10 12:16:52 +00:00
parent f1ef6b6e9a
commit 0c7dbadc30
52 changed files with 4388 additions and 1534 deletions
+197 -4
View File
@@ -51,6 +51,7 @@ public:
bool parse_inner_set(basic_char_set<charT, traits>& char_set);
bool parse_QE();
bool parse_perl_extension();
bool add_emacs_code(bool negate);
digraph<charT> get_next_set_literal(basic_char_set<charT, traits>& char_set);
charT unescape_character();
regex_constants::syntax_option_type parse_options();
@@ -183,6 +184,22 @@ bool basic_regex_parser<charT, traits>::parse_basic()
++m_position;
return parse_repeat();
}
case regex_constants::syntax_plus:
if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
return parse_literal();
else
{
++m_position;
return parse_repeat(1);
}
case regex_constants::syntax_question:
if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
return parse_literal();
else
{
++m_position;
return parse_repeat(0, 1);
}
case regex_constants::syntax_open_set:
return parse_set();
default:
@@ -301,7 +318,10 @@ bool basic_regex_parser<charT, traits>::parse_open_paren()
//
// begin by checking for a perl-style (?...) extension:
//
if((this->flags() & (regbase::main_option_type | regbase::no_perl_ex)) == 0)
if(
((this->flags() & (regbase::main_option_type | regbase::no_perl_ex)) == 0)
|| ((this->flags() & (regbase::main_option_type | regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
)
{
if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
return parse_perl_extension();
@@ -377,7 +397,7 @@ template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_basic_escape()
{
++m_position;
bool result;
bool result = true;
switch(this->m_traits.escape_syntax_type(*m_position))
{
case regex_constants::syntax_open_mark:
@@ -418,7 +438,97 @@ bool basic_regex_parser<charT, traits>::parse_basic_escape()
break;
case regex_constants::syntax_digit:
return parse_backref();
case regex_constants::escape_type_start_buffer:
if(this->flags() & regbase::emacs_ex)
{
++m_position;
this->append_state(syntax_element_buffer_start);
}
else
result = parse_literal();
break;
case regex_constants::escape_type_end_buffer:
if(this->flags() & regbase::emacs_ex)
{
++m_position;
this->append_state(syntax_element_buffer_end);
}
else
result = parse_literal();
break;
case regex_constants::escape_type_word_assert:
if(this->flags() & regbase::emacs_ex)
{
++m_position;
this->append_state(syntax_element_word_boundary);
}
else
result = parse_literal();
break;
case regex_constants::escape_type_not_word_assert:
if(this->flags() & regbase::emacs_ex)
{
++m_position;
this->append_state(syntax_element_within_word);
}
else
result = parse_literal();
break;
case regex_constants::escape_type_left_word:
if(this->flags() & regbase::emacs_ex)
{
++m_position;
this->append_state(syntax_element_word_start);
}
else
result = parse_literal();
break;
case regex_constants::escape_type_right_word:
if(this->flags() & regbase::emacs_ex)
{
++m_position;
this->append_state(syntax_element_word_end);
}
else
result = parse_literal();
break;
default:
if(this->flags() & regbase::emacs_ex)
{
bool negate = true;
switch(*m_position)
{
case 'w':
negate = false;
// fall through:
case 'W':
{
basic_char_set<charT, traits> char_set;
if(negate)
char_set.negate();
char_set.add_class(this->m_word_mask);
if(0 == this->append_set(char_set))
{
fail(regex_constants::error_ctype, m_position - m_base);
return false;
}
++m_position;
return true;
}
case 's':
negate = false;
// fall through:
case 'S':
return add_emacs_code(negate);
case 'c':
case 'C':
// not supported yet:
fail(regex_constants::error_escape, m_position - m_base);
return false;
default:
break;
}
}
result = parse_literal();
break;
}
@@ -447,7 +557,7 @@ bool basic_regex_parser<charT, traits>::parse_extended_escape()
char_set.add_class(m);
if(0 == this->append_set(char_set))
{
fail(regex_constants::error_range, m_position - m_base);
fail(regex_constants::error_ctype, m_position - m_base);
return false;
}
++m_position;
@@ -533,7 +643,11 @@ bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_
// when we get to here we may have a non-greedy ? mark still to come:
//
if((m_position != m_end)
&& (0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex))))
&& (
(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
|| ((regbase::basic_syntax_group|regbase::emacs_ex) == (this->flags() & (regbase::main_option_type | regbase::emacs_ex)))
)
)
{
// OK we have a perl regex, check for a '?':
if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
@@ -1622,6 +1736,85 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
return true;
}
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::add_emacs_code(bool negate)
{
//
// parses an emacs style \sx or \Sx construct.
//
if(++m_position == m_end)
{
fail(regex_constants::error_escape, m_position - m_base);
return false;
}
basic_char_set<charT, traits> char_set;
if(negate)
char_set.negate();
static const charT s_punct[] = { 'p', 'u', 'n', 'c', 't', };
switch(*m_position)
{
case 's':
case ' ':
char_set.add_class(this->m_mask_space);
break;
case 'w':
char_set.add_class(this->m_word_mask);
break;
case '_':
char_set.add_single(digraph<charT>(charT('$')));
char_set.add_single(digraph<charT>(charT('&')));
char_set.add_single(digraph<charT>(charT('*')));
char_set.add_single(digraph<charT>(charT('+')));
char_set.add_single(digraph<charT>(charT('-')));
char_set.add_single(digraph<charT>(charT('_')));
char_set.add_single(digraph<charT>(charT('<')));
char_set.add_single(digraph<charT>(charT('>')));
break;
case '.':
char_set.add_class(this->m_traits.lookup_classname(s_punct, s_punct+5));
break;
case '(':
char_set.add_single(digraph<charT>(charT('(')));
char_set.add_single(digraph<charT>(charT('[')));
char_set.add_single(digraph<charT>(charT('{')));
break;
case ')':
char_set.add_single(digraph<charT>(charT(')')));
char_set.add_single(digraph<charT>(charT(']')));
char_set.add_single(digraph<charT>(charT('}')));
break;
case '"':
char_set.add_single(digraph<charT>(charT('"')));
char_set.add_single(digraph<charT>(charT('\'')));
char_set.add_single(digraph<charT>(charT('`')));
break;
case '\'':
char_set.add_single(digraph<charT>(charT('\'')));
char_set.add_single(digraph<charT>(charT(',')));
char_set.add_single(digraph<charT>(charT('#')));
break;
case '<':
char_set.add_single(digraph<charT>(charT(';')));
break;
case '>':
char_set.add_single(digraph<charT>(charT('\n')));
char_set.add_single(digraph<charT>(charT('\f')));
break;
default:
fail(regex_constants::error_ctype, m_position - m_base);
return false;
}
if(0 == this->append_set(char_set))
{
fail(regex_constants::error_ctype, m_position - m_base);
return false;
}
++m_position;
return true;
}
template <class charT, class traits>
regex_constants::syntax_option_type basic_regex_parser<charT, traits>::parse_options()
{
+54 -9
View File
@@ -30,11 +30,14 @@
#include <boost/regex/v4/regex_traits_defaults.hpp>
#endif
#ifdef BOOST_HAS_THREADS
#include <boost/regex/static_mutex.hpp>
#include <boost/regex/pending/static_mutex.hpp>
#endif
#ifndef BOOST_REGEX_PRIMARY_TRANSFORM
#include <boost/regex/v4/primary_transform.hpp>
#endif
#ifndef BOOST_REGEX_OBJECT_CACHE_HPP
#include <boost/regex/pending/object_cache.hpp>
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -165,6 +168,25 @@ struct cpp_regex_traits_base
std::messages<charT> const* m_pmessages;
#endif
std::collate<charT> const* m_pcollate;
bool operator<(const cpp_regex_traits_base& b)const
{
if(m_pctype == b.m_pctype)
{
if(m_pmessages == b.m_pmessages)
{
return m_pcollate < b.m_pcollate;
}
return m_pmessages < b.m_pmessages;
}
return m_pctype < b.m_pctype;
}
bool operator==(const cpp_regex_traits_base& b)const
{
return (m_pctype == b.m_pctype)
&& (m_pmessages == b.m_pmessages)
&& (m_pcollate == b.m_pcollate);
}
};
template <class charT>
@@ -191,7 +213,17 @@ class cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>
typedef std::map<charT, regex_constants::syntax_type> map_type;
typedef typename map_type::const_iterator map_iterator_type;
public:
cpp_regex_traits_char_layer(const std::locale& l);
cpp_regex_traits_char_layer(const std::locale& l)
: cpp_regex_traits_base<charT>(l)
{
init();
}
cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)
: cpp_regex_traits_base<charT>(b)
{
init();
}
void init();
regex_constants::syntax_type syntax_type(charT c)const
{
@@ -217,8 +249,7 @@ private:
};
template <class charT>
cpp_regex_traits_char_layer<charT>::cpp_regex_traits_char_layer(const std::locale& l)
: cpp_regex_traits_base<charT>(l)
void cpp_regex_traits_char_layer<charT>::init()
{
// we need to start by initialising our syntax map so we know which
// character is used for which purpose:
@@ -307,6 +338,11 @@ public:
{
init();
}
cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)
: cpp_regex_traits_base<char>(l)
{
init();
}
regex_constants::syntax_type syntax_type(char c)const
{
@@ -393,7 +429,16 @@ public:
typedef std::basic_string<charT> string_type;
typedef charT char_type;
//cpp_regex_traits_implementation();
cpp_regex_traits_implementation(const std::locale& l);
cpp_regex_traits_implementation(const std::locale& l)
: cpp_regex_traits_char_layer<charT>(l), m_is(&m_sbuf)
{
init();
}
cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)
: cpp_regex_traits_char_layer<charT>(l), m_is(&m_sbuf)
{
init();
}
std::string error_string(regex_constants::error_type n) const
{
if(!m_error_strings.empty())
@@ -429,6 +474,7 @@ private:
// helpers:
//
char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
void init();
#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
public:
bool isctype(charT c, char_class_type m)const;
@@ -605,8 +651,7 @@ typename cpp_regex_traits_implementation<charT>::string_type
}
template <class charT>
cpp_regex_traits_implementation<charT>::cpp_regex_traits_implementation(const std::locale& l)
: cpp_regex_traits_char_layer<charT>(l), m_is(&m_sbuf)
void cpp_regex_traits_implementation<charT>::init()
{
#ifndef BOOST_NO_STD_MESSAGES
#ifndef __IBMCPP__
@@ -798,8 +843,8 @@ bool cpp_regex_traits_implementation<charT>::isctype(const charT c, char_class_t
template <class charT>
boost::shared_ptr<cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
{
// TODO: create a cache for previously constructed objects.
return boost::shared_ptr<cpp_regex_traits_implementation<charT> >(new cpp_regex_traits_implementation<charT>(l));
cpp_regex_traits_base<charT> key(l);
return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);
}
} // re_detail
+3 -1
View File
@@ -57,7 +57,7 @@ template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T >;
# include BOOST_ABI_SUFFIX
#endif
#elif defined(BOOST_MSVC)
#elif defined(BOOST_MSVC) || defined(BOOST_INTEL) || defined(__GNUC__)
# ifndef BOOST_REGEX_INSTANTIATE
# define template extern template
@@ -69,6 +69,8 @@ template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T >;
# endif
template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T >;
template class BOOST_REGEX_DECL match_results< const BOOST_REGEX_CHAR_T* >;
template class BOOST_REGEX_DECL match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >;
# ifdef BOOST_MSVC
# pragma warning(pop)
+2 -2
View File
@@ -71,7 +71,7 @@ public:
// size:
size_type size() const
{ return m_subs.size() - 2; }
{ return empty() ? 0 : m_subs.size() - 2; }
size_type max_size() const
{ return m_subs.max_size(); }
bool empty() const
@@ -235,7 +235,7 @@ public:
size_type len = m_subs.size();
if(len > n + 2)
{
m_subs.erase(m_subs.begin()+n+2);
m_subs.erase(m_subs.begin()+n+2, m_subs.end());
std::fill(m_subs.begin(), m_subs.end(), v);
}
else
+1 -1
View File
@@ -20,7 +20,7 @@
#include <new>
#ifdef BOOST_HAS_THREADS
#include <boost/regex/static_mutex.hpp>
#include <boost/regex/pending/static_mutex.hpp>
#endif
#ifdef BOOST_HAS_ABI_HEADERS
@@ -54,7 +54,9 @@ perl_matcher<BidiIterator, Allocator, traits>::perl_matcher(BidiIterator first,
estimate_max_state_count(static_cast<category*>(0));
if(!(m_match_flags & (match_perl|match_posix)))
{
if((re.flags() & regbase::no_perl_ex) == 0)
if((re.flags() & (regbase::main_option_type|regbase::no_perl_ex)) == 0)
m_match_flags |= match_perl;
else if((re.flags() & (regbase::main_option_type|regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
m_match_flags |= match_perl;
else
m_match_flags |= match_posix;
@@ -80,15 +82,17 @@ perl_matcher<BidiIterator, Allocator, traits>::perl_matcher(BidiIterator first,
template <class BidiIterator, class Allocator, class traits>
void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)
{
static const difference_type k = 100000;
difference_type dist = boost::re_detail::distance(base, last);
traits_size_type states = static_cast<traits_size_type>(re.size());
states *= states;
difference_type lim = (std::numeric_limits<difference_type>::max)() - 100000 - states;
if(dist > (difference_type)(lim / states))
max_state_count = lim;
difference_type lim = ((std::numeric_limits<difference_type>::max)() - k) / states;
if(dist >= lim)
max_state_count = (std::numeric_limits<difference_type>::max)();
else
max_state_count = 100000 + states * dist;
max_state_count = k + states * dist;
}
template <class BidiIterator, class Allocator, class traits>
void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)
{
+2 -1
View File
@@ -64,6 +64,7 @@ public:
no_intervals = 1 << 9, // {x,y} not allowed
bk_plus_qm = 1 << 10, // uses \+ and \?
bk_vbar = 1 << 11, // use \| for alternatives
emacs_ex = 1 << 12, // enables emacs extensions
//
// options common to all groups:
@@ -83,7 +84,7 @@ public:
basic = basic_syntax_group | collate | no_escape_in_lists,
extended = no_bk_refs | collate | no_perl_ex | no_escape_in_lists,
normal = 0,
emacs = basic | no_char_classes | no_intervals,
emacs = basic_syntax_group | collate | emacs_ex | bk_vbar,
awk = no_bk_refs | collate | no_perl_ex,
grep = basic | newline_alt,
egrep = extended | newline_alt,
+6 -6
View File
@@ -81,6 +81,12 @@
#ifndef BOOST_REGEX_V4_MATCH_RESULTS_HPP
#include <boost/regex/v4/match_results.hpp>
#endif
#ifndef BOOST_REGEX_V4_PROTECTED_CALL_HPP
#include <boost/regex/v4/protected_call.hpp>
#endif
#ifndef BOOST_REGEX_MATCHER_HPP
#include <boost/regex/v4/perl_matcher.hpp>
#endif
//
// template instances:
@@ -136,12 +142,6 @@ typedef match_results<std::wstring::const_iterator> wsmatch;
#endif
} // namespace boost
#ifndef BOOST_REGEX_V4_PROTECTED_CALL_HPP
#include <boost/regex/v4/protected_call.hpp>
#endif
#ifndef BOOST_REGEX_MATCHER_HPP
#include <boost/regex/v4/perl_matcher.hpp>
#endif
#ifndef BOOST_REGEX_MATCH_HPP
#include <boost/regex/v4/regex_match.hpp>
#endif
+1 -1
View File
@@ -53,7 +53,7 @@
#include <boost/regex_fwd.hpp>
#endif
#include "boost/mpl/aux_/has_xxx.hpp"
#include "boost/mpl/has_xxx.hpp"
#include <boost/static_assert.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
+5 -2
View File
@@ -23,11 +23,14 @@
#include <boost/regex/v4/regex_traits_defaults.hpp>
#endif
#ifdef BOOST_HAS_THREADS
#include <boost/regex/static_mutex.hpp>
#include <boost/regex/pending/static_mutex.hpp>
#endif
#ifndef BOOST_REGEX_PRIMARY_TRANSFORM
#include <boost/regex/v4/primary_transform.hpp>
#endif
#ifndef BOOST_REGEX_OBJECT_CACHE_HPP
#include <boost/regex/pending/object_cache.hpp>
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -534,7 +537,7 @@ template <class charT>
boost::shared_ptr<w32_regex_traits_implementation<charT> > create_w32_regex_traits(::boost::re_detail::lcid_type l BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
{
// TODO: create a cache for previously constructed objects.
return boost::shared_ptr<w32_regex_traits_implementation<charT> >(new w32_regex_traits_implementation<charT>(l));
return boost::object_cache< ::boost::re_detail::lcid_type, w32_regex_traits_implementation<charT> >::get(l, 5);
}
} // re_detail