Allow std::locale's to not have a messages facet installed (fixes some STLPort issues).

Allow match_results to handle singular iterators.
Update docs to match.

[SVN r57860]
This commit is contained in:
John Maddock
2009-11-23 10:45:44 +00:00
parent 1f38675c1c
commit a83329dd28
36 changed files with 324 additions and 212 deletions

View File

@ -187,6 +187,7 @@ struct cpp_regex_traits_base
#ifndef BOOST_NO_STD_MESSAGES
if(m_pmessages == b.m_pmessages)
{
return m_pcollate < b.m_pcollate;
}
return m_pmessages < b.m_pmessages;
#else
@ -212,7 +213,7 @@ std::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)
m_locale = l;
m_pctype = &BOOST_USE_FACET(std::ctype<charT>, l);
#ifndef BOOST_NO_STD_MESSAGES
m_pmessages = &BOOST_USE_FACET(std::messages<charT>, l);
m_pmessages = BOOST_HAS_FACET(std::messages<charT>, l) ? &BOOST_USE_FACET(std::messages<charT>, l) : 0;
#endif
m_pcollate = &BOOST_USE_FACET(std::collate<charT>, l);
return result;
@ -276,7 +277,7 @@ void cpp_regex_traits_char_layer<charT>::init()
typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
#endif
std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
if(cat_name.size())
if(cat_name.size() && (this->m_pmessages != 0))
{
cat = this->m_pmessages->open(
cat_name,
@ -309,7 +310,8 @@ void cpp_regex_traits_char_layer<charT>::init()
}
catch(...)
{
this->m_pmessages->close(cat);
if(this->m_pmessages)
this->m_pmessages->close(cat);
throw;
}
#endif
@ -653,7 +655,7 @@ void cpp_regex_traits_implementation<charT>::init()
typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
#endif
std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
if(cat_name.size())
if(cat_name.size() && (this->m_pmessages != 0))
{
cat = this->m_pmessages->open(
cat_name,

View File

@ -74,16 +74,30 @@ public:
// construct/copy/destroy:
explicit match_results(const Allocator& a = Allocator())
#ifndef BOOST_NO_STD_ALLOCATOR
: m_subs(a), m_base(), m_last_closed_paren(0) {}
: m_subs(a), m_base(), m_last_closed_paren(0), m_is_singular(true) {}
#else
: m_subs(), m_base(), m_last_closed_paren(0) { (void)a; }
: m_subs(), m_base(), m_last_closed_paren(0), m_is_singular(true) { (void)a; }
#endif
match_results(const match_results& m)
: m_subs(m.m_subs), m_base(m.m_base) {}
: m_subs(m.m_subs), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular)
{
if(!m_is_singular)
{
m_base = m.m_base;
m_null = m.m_null;
}
}
match_results& operator=(const match_results& m)
{
m_subs = m.m_subs;
m_base = m.m_base;
m_named_subs = m.m_named_subs;
m_last_closed_paren = m.m_last_closed_paren;
m_is_singular = m.m_is_singular;
if(!m_is_singular)
{
m_base = m.m_base;
m_null = m.m_null;
}
return *this;
}
~match_results(){}
@ -98,6 +112,8 @@ public:
// element access:
difference_type length(int sub = 0) const
{
if(m_is_singular)
raise_logic_error();
sub += 2;
if((sub < (int)m_subs.size()) && (sub > 0))
return m_subs[sub].length();
@ -105,6 +121,8 @@ public:
}
difference_type length(const char_type* sub) const
{
if(m_is_singular)
raise_logic_error();
const char_type* end = sub;
while(*end) ++end;
return length(named_subexpression_index(sub, end));
@ -112,6 +130,8 @@ public:
template <class charT>
difference_type length(const charT* sub) const
{
if(m_is_singular)
raise_logic_error();
const charT* end = sub;
while(*end) ++end;
return length(named_subexpression_index(sub, end));
@ -123,6 +143,8 @@ public:
}
difference_type position(size_type sub = 0) const
{
if(m_is_singular)
raise_logic_error();
sub += 2;
if(sub < m_subs.size())
{
@ -154,6 +176,8 @@ public:
}
string_type str(int sub = 0) const
{
if(m_is_singular)
raise_logic_error();
sub += 2;
string_type result;
if(sub < (int)m_subs.size() && (sub > 0))
@ -187,6 +211,8 @@ public:
}
const_reference operator[](int sub) const
{
if(m_is_singular && m_subs.empty())
raise_logic_error();
sub += 2;
if(sub < (int)m_subs.size() && (sub >= 0))
{
@ -199,6 +225,8 @@ public:
//
const_reference named_subexpression(const char_type* i, const char_type* j) const
{
if(m_is_singular)
raise_logic_error();
int index = m_named_subs->get_id(i, j);
return index > 0 ? (*this)[index] : m_null;
}
@ -215,6 +243,8 @@ public:
}
int named_subexpression_index(const char_type* i, const char_type* j) const
{
if(m_is_singular)
raise_logic_error();
int index = m_named_subs->get_id(i, j);
return index > 0 ? index : -20;
}
@ -266,11 +296,15 @@ public:
const_reference prefix() const
{
if(m_is_singular)
raise_logic_error();
return (*this)[-1];
}
const_reference suffix() const
{
if(m_is_singular)
raise_logic_error();
return (*this)[-2];
}
const_iterator begin() const
@ -287,6 +321,8 @@ public:
Functor fmt,
match_flag_type flags = format_default) const
{
if(m_is_singular)
raise_logic_error();
typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator>::type F;
F func(fmt);
return func(*this, out, flags);
@ -294,6 +330,8 @@ public:
template <class Functor>
string_type format(Functor fmt, match_flag_type flags = format_default) const
{
if(m_is_singular)
raise_logic_error();
std::basic_string<char_type> result;
re_detail::string_out_iterator<std::basic_string<char_type> > i(result);
@ -310,6 +348,8 @@ public:
match_flag_type flags,
const RegexT& re) const
{
if(m_is_singular)
raise_logic_error();
typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator, traits_type>::type F;
F func(fmt);
@ -320,6 +360,8 @@ public:
match_flag_type flags,
const RegexT& re) const
{
if(m_is_singular)
raise_logic_error();
typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
std::basic_string<char_type> result;
re_detail::string_out_iterator<std::basic_string<char_type> > i(result);
@ -333,6 +375,8 @@ public:
const_reference get_last_closed_paren()const
{
if(m_is_singular)
raise_logic_error();
return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];
}
@ -347,13 +391,39 @@ public:
void swap(match_results& that)
{
std::swap(m_subs, that.m_subs);
std::swap(m_base, that.m_base);
std::swap(m_named_subs, that.m_named_subs);
std::swap(m_last_closed_paren, that.m_last_closed_paren);
std::swap(m_is_singular, that.m_is_singular);
if(m_is_singular)
{
if(!that.m_is_singular)
{
m_base = that.m_base;
m_null = that.m_null;
}
}
else if(that.m_is_singular)
{
that.m_base = m_base;
that.m_null = m_null;
}
else
{
std::swap(m_base, that.m_base);
std::swap(m_null, that.m_null);
}
}
bool operator==(const match_results& that)const
{
return (m_subs == that.m_subs) && (m_base == that.m_base);
if(m_is_singular)
{
return that.m_is_singular;
}
else if(that.m_is_singular)
{
return false;
}
return (m_subs == that.m_subs) && (m_base == that.m_base) && (m_last_closed_paren == that.m_last_closed_paren);
}
bool operator!=(const match_results& that)const
{ return !(*this == that); }
@ -363,6 +433,8 @@ public:
const capture_sequence_type& captures(int i)const
{
if(m_is_singular)
raise_logic_error();
return (*this)[i].captures();
}
#endif
@ -379,6 +451,7 @@ public:
m_null.first = i;
m_null.second = i;
m_null.matched = false;
m_is_singular = false;
}
void BOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)
@ -396,6 +469,7 @@ public:
m_null.first = i;
m_null.second = i;
m_null.matched = false;
m_is_singular = false;
}
}
void BOOST_REGEX_CALL set_size(size_type n, BidiIterator i, BidiIterator j)
@ -462,16 +536,32 @@ public:
}
private:
vector_type m_subs; // subexpressions
BidiIterator m_base; // where the search started from
sub_match<BidiIterator> m_null; // a null match
boost::shared_ptr<named_sub_type> m_named_subs;
int m_last_closed_paren;
//
// Error handler called when an uninitialized match_results is accessed:
//
static void raise_logic_error()
{
std::logic_error e("Attempt to access an uninitialzed boost::match_results<> class.");
boost::throw_exception(e);
}
vector_type m_subs; // subexpressions
BidiIterator m_base; // where the search started from
sub_match<BidiIterator> m_null; // a null match
boost::shared_ptr<named_sub_type> m_named_subs; // Shared copy of named subs in the regex object
int m_last_closed_paren; // Last ) to be seen - used for formatting
bool m_is_singular; // True if our stored iterators are singular
};
template <class BidiIterator, class Allocator>
void BOOST_REGEX_CALL match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)
{
if(m_is_singular)
{
*this = m;
return;
}
const_iterator p1, p2;
p1 = begin();
p2 = m.begin();