Updated concepts checks: Use of traits class is now in line with the std.

Added c_regex_traits and w32_regex_traits (first cuts).


[SVN r23030]
This commit is contained in:
John Maddock
2004-06-05 11:45:27 +00:00
parent bdb4c091f1
commit fce31e9800
32 changed files with 2667 additions and 407 deletions

View File

@ -0,0 +1,829 @@
/*
*
* Copyright (c) 2004
* Dr 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 concepts.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression concepts.
*/
#ifndef BOOST_REGEX_CONCEPTS_HPP_INCLUDED
#define BOOST_REGEX_CONCEPTS_HPP_INCLUDED
#include <boost/concept_archetype.hpp>
#include <boost/concept_check.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/static_assert.hpp>
#include <boost/regex.hpp>
#include <bitset>
#include <vector>
namespace boost{
//
// bitmask_archetype:
// this can be either an integer type, an enum, or a std::bitset,
// we use the latter as the architype as it offers the "strictest"
// of the possible interfaces:
//
typedef std::bitset<512> bitmask_archetype;
//
// char_architype:
// A strict model for the character type interface.
//
struct char_architype
{
// default constructable:
char_architype();
// copy constructable / assignable:
char_architype(const char_architype&);
char_architype& operator=(const char_architype&);
// constructable from an integral value:
char_architype(unsigned long val);
// comparable:
bool operator==(const char_architype&)const;
bool operator!=(const char_architype&)const;
bool operator<(const char_architype&)const;
bool operator<=(const char_architype&)const;
bool operator>=(const char_architype&)const;
bool operator>(const char_architype&)const;
// conversion to integral type:
operator long()const;
};
//
// char_architype can not be used with basic_string:
//
} // namespace boost
namespace std{
template<> struct char_traits<boost::char_architype>{};
}
namespace boost{
//
// regex_traits_architype:
// A strict interpretation of the regular expression traits class requirements.
//
template <class charT>
struct regex_traits_architype
{
public:
regex_traits_architype();
typedef charT char_type;
typedef std::size_t size_type;
typedef std::vector<char_type> string_type;
typedef copy_constructible_archetype<assignable_archetype<> > locale_type;
typedef bitmask_archetype char_class_type;
static size_type length(const char_type* ) { return 0; }
charT translate(charT ) const { return charT(); }
charT translate_nocase(charT ) const { return static_object<charT>::get(); }
template <class ForwardIterator>
string_type transform(ForwardIterator , ForwardIterator ) const
{ return static_object<string_type>::get(); }
template <class ForwardIterator>
string_type transform_primary(ForwardIterator , ForwardIterator ) const
{ return static_object<string_type>::get(); }
template <class ForwardIterator>
char_class_type lookup_classname(ForwardIterator , ForwardIterator ) const
{ return static_object<char_class_type>::get(); }
template <class ForwardIterator>
string_type lookup_collatename(ForwardIterator , ForwardIterator ) const
{ return static_object<string_type>::get(); }
bool isctype(charT, char_class_type) const
{ return false; }
int value(charT, int) const
{ return 0; }
locale_type imbue(locale_type l)
{ return l; }
locale_type getloc()const
{ return static_object<locale_type>::get(); }
private:
// this type is not copyable:
regex_traits_architype(const regex_traits_architype&);
regex_traits_architype& operator=(const regex_traits_architype&);
};
//
// alter this to std::tr1, to test a std implementation:
//
namespace global_regex_namespace = ::boost;
template <class Bitmask>
struct BitmaskConcept
{
void constraints()
{
function_requires<CopyConstructibleConcept<Bitmask> >();
function_requires<AssignableConcept<Bitmask> >();
m_mask1 = m_mask2 | m_mask3;
m_mask1 = m_mask2 & m_mask3;
m_mask1 = m_mask2 ^ m_mask3;
m_mask1 = ~m_mask2;
m_mask1 |= m_mask2;
m_mask1 &= m_mask2;
m_mask1 ^= m_mask2;
}
Bitmask m_mask1, m_mask2, m_mask3;
};
template <class traits>
struct RegexTraitsConcept
{
RegexTraitsConcept();
// required typedefs:
typedef typename traits::char_type char_type;
typedef typename traits::size_type size_type;
typedef typename traits::string_type string_type;
typedef typename traits::locale_type locale_type;
typedef typename traits::char_class_type char_class_type;
void constraints()
{
function_requires<UnsignedIntegerConcept<size_type> >();
function_requires<RandomAccessContainerConcept<string_type> >();
function_requires<DefaultConstructibleConcept<locale_type> >();
function_requires<CopyConstructibleConcept<locale_type> >();
function_requires<AssignableConcept<locale_type> >();
function_requires<BitmaskConcept<char_class_type> >();
size_type n = traits::length(m_pointer);
ignore_unused_variable_warning(n);
char_type c = m_ctraits.translate(m_char);
ignore_unused_variable_warning(c);
c = m_ctraits.translate_nocase(m_char);
//string_type::foobar bar;
string_type s1 = m_ctraits.transform(m_pointer, m_pointer);
ignore_unused_variable_warning(s1);
string_type s2 = m_ctraits.transform_primary(m_pointer, m_pointer);
ignore_unused_variable_warning(s2);
char_class_type cc = m_ctraits.lookup_classname(m_pointer, m_pointer);
ignore_unused_variable_warning(cc);
string_type s3 = m_ctraits.lookup_collatename(m_pointer, m_pointer);
ignore_unused_variable_warning(s3);
bool b = m_ctraits.isctype(m_char, cc);
ignore_unused_variable_warning(b);
int v = m_ctraits.value(m_char, 16);
ignore_unused_variable_warning(v);
locale_type l(m_ctraits.getloc());
m_traits.imbue(l);
ignore_unused_variable_warning(l);
}
traits m_traits;
const traits m_ctraits;
const char_type* m_pointer;
char_type m_char;
};
//
// helper class to compute what traits class a regular expression type is using:
//
template <class Regex>
struct regex_traits_computer;
template <class charT, class traits>
struct regex_traits_computer< global_regex_namespace::basic_regex<charT, traits> >
{
typedef traits type;
};
//
// BaseRegexConcept does not test anything dependent on basic_string,
// in case our charT does not have an associated char_traits:
//
template <class Regex>
struct BaseRegexConcept
{
typedef typename Regex::value_type value_type;
typedef typename Regex::size_type size_type;
typedef typename Regex::flag_type flag_type;
typedef typename Regex::locale_type locale_type;
typedef input_iterator_archetype<value_type> input_iterator_type;
// derived test types:
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 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;
typedef global_regex_namespace::regex_token_iterator<BidiIterator, value_type, traits_type> regex_token_iterator_type;
void global_constraints()
{
//
// test non-template components:
//
function_requires<BitmaskConcept<global_regex_namespace::regex_constants::syntax_option_type> >();
global_regex_namespace::regex_constants::syntax_option_type opts
= global_regex_namespace::regex_constants::icase
| global_regex_namespace::regex_constants::nosubs
| global_regex_namespace::regex_constants::optimize
| global_regex_namespace::regex_constants::collate
| global_regex_namespace::regex_constants::ECMAScript
| global_regex_namespace::regex_constants::basic
| global_regex_namespace::regex_constants::extended
| global_regex_namespace::regex_constants::awk
| global_regex_namespace::regex_constants::grep
| global_regex_namespace::regex_constants::egrep;
ignore_unused_variable_warning(opts);
function_requires<BitmaskConcept<global_regex_namespace::regex_constants::match_flag_type> >();
global_regex_namespace::regex_constants::match_flag_type mopts
= global_regex_namespace::regex_constants::match_default
| global_regex_namespace::regex_constants::match_not_bol
| global_regex_namespace::regex_constants::match_not_eol
| global_regex_namespace::regex_constants::match_not_bow
| global_regex_namespace::regex_constants::match_not_eow
| global_regex_namespace::regex_constants::match_any
| global_regex_namespace::regex_constants::match_not_null
| global_regex_namespace::regex_constants::match_continuous
| global_regex_namespace::regex_constants::match_partial
| global_regex_namespace::regex_constants::match_prev_avail
| global_regex_namespace::regex_constants::format_default
| global_regex_namespace::regex_constants::format_sed
| global_regex_namespace::regex_constants::format_perl
| global_regex_namespace::regex_constants::format_no_copy
| global_regex_namespace::regex_constants::format_first_only;
ignore_unused_variable_warning(mopts);
BOOST_STATIC_ASSERT((::boost::is_enum<global_regex_namespace::regex_constants::error_type>::value));
global_regex_namespace::regex_constants::error_type e1 = global_regex_namespace::regex_constants::error_collate;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_ctype;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_escape;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_backref;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_brack;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_paren;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_brace;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_badbrace;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_range;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_space;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_badrepeat;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_complexity;
ignore_unused_variable_warning(e1);
e1 = global_regex_namespace::regex_constants::error_stack;
ignore_unused_variable_warning(e1);
BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::runtime_error, global_regex_namespace::regex_error>::value ));
const global_regex_namespace::regex_error except(e1);
e1 = except.code();
typedef typename Regex::value_type value_type;
function_requires< RegexTraitsConcept<global_regex_namespace::regex_traits<char> > >();
function_requires< BaseRegexConcept<global_regex_namespace::basic_regex<char> > >();
}
void constraints()
{
global_constraints();
BOOST_STATIC_ASSERT((::boost::is_same< flag_type, global_regex_namespace::regex_constants::syntax_option_type>::value));
flag_type opts
= Regex::icase
| Regex::nosubs
| Regex::optimize
| Regex::collate
| Regex::ECMAScript
| Regex::basic
| Regex::extended
| Regex::awk
| Regex::grep
| Regex::egrep;
ignore_unused_variable_warning(opts);
function_requires<DefaultConstructibleConcept<Regex> >();
function_requires<CopyConstructibleConcept<Regex> >();
// Regex constructors:
Regex e1(m_pointer);
ignore_unused_variable_warning(e1);
Regex e2(m_pointer, m_flags);
ignore_unused_variable_warning(e2);
Regex e3(m_pointer, m_size, m_flags);
ignore_unused_variable_warning(e3);
Regex e4(in1, in2);
ignore_unused_variable_warning(e4);
Regex e5(in1, in2, m_flags);
ignore_unused_variable_warning(e5);
// assign etc:
Regex e;
e = m_pointer;
e = e1;
e.assign(e1);
e.assign(m_pointer);
e.assign(m_pointer, m_flags);
e.assign(m_pointer, m_size, m_flags);
e.assign(in1, in2);
e.assign(in1, in2, m_flags);
// access:
const Regex ce;
bool b = ce.empty();
ignore_unused_variable_warning(b);
size_type i = ce.mark_count();
ignore_unused_variable_warning(i);
m_flags = ce.flags();
e.imbue(ce.getloc());
e.swap(e1);
global_regex_namespace::swap(e, e1);
// sub_match:
BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::pair<BidiIterator, BidiIterator>, sub_match_type>::value));
typedef typename sub_match_type::value_type sub_value_type;
typedef typename sub_match_type::difference_type sub_diff_type;
typedef typename sub_match_type::iterator sub_iter_type;
BOOST_STATIC_ASSERT((::boost::is_same<sub_value_type, value_type>::value));
BOOST_STATIC_ASSERT((::boost::is_same<sub_iter_type, BidiIterator>::value));
b = m_sub.matched;
ignore_unused_variable_warning(b);
BidiIterator bi = m_sub.first;
ignore_unused_variable_warning(bi);
bi = m_sub.second;
ignore_unused_variable_warning(bi);
sub_diff_type diff = m_sub.length();
ignore_unused_variable_warning(diff);
// match_results tests:
typedef typename match_results_type::value_type mr_value_type;
typedef typename match_results_type::const_reference mr_const_reference;
typedef typename match_results_type::reference mr_reference;
typedef typename match_results_type::const_iterator mr_const_iterator;
typedef typename match_results_type::iterator mr_iterator;
typedef typename match_results_type::difference_type mr_difference_type;
typedef typename match_results_type::size_type mr_size_type;
typedef typename match_results_type::allocator_type mr_allocator_type;
typedef typename match_results_type::char_type mr_char_type;
typedef typename match_results_type::string_type mr_string_type;
match_results_type m1;
mr_allocator_type at;
match_results_type m2(at);
match_results_type m3(m1);
m1 = m2;
mr_size_type mrs = m_cresults.size();
ignore_unused_variable_warning(mrs);
mrs = m_cresults.max_size();
ignore_unused_variable_warning(mrs);
b = m_cresults.empty();
ignore_unused_variable_warning(b);
mr_difference_type mrd = m_cresults.length();
ignore_unused_variable_warning(mrd);
mrd = m_cresults.length(mrs);
ignore_unused_variable_warning(mrd);
mrd = m_cresults.position();
ignore_unused_variable_warning(mrd);
mrd = m_cresults.position(mrs);
ignore_unused_variable_warning(mrd);
mr_const_reference mrcr = m_cresults[m_size];
ignore_unused_variable_warning(mrcr);
mr_const_reference mrcr2 = m_cresults.prefix();
ignore_unused_variable_warning(mrcr2);
mr_const_reference mrcr3 = m_cresults.suffix();
ignore_unused_variable_warning(mrcr3);
mr_const_iterator mrci = m_cresults.begin();
ignore_unused_variable_warning(mrci);
mrci = m_cresults.end();
ignore_unused_variable_warning(mrci);
mr_allocator_type at2 = m_cresults.get_allocator();
m_results.swap(m_results);
global_regex_namespace::swap(m_results, m_results);
// regex_match:
b = global_regex_namespace::regex_match(m_in, m_in, m_results, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_in, m_in, m_results, e, m_mft);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_in, m_in, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_in, m_in, e, m_mft);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e, m_mft);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_pointer, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_pointer, e, m_mft);
ignore_unused_variable_warning(b);
// regex_search:
b = global_regex_namespace::regex_search(m_in, m_in, m_results, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_in, m_in, m_results, e, m_mft);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_in, m_in, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_in, m_in, e, m_mft);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e, m_mft);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_pointer, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_pointer, e, m_mft);
ignore_unused_variable_warning(b);
// regex_iterator:
typedef typename regex_iterator_type::regex_type rit_regex_type;
typedef typename regex_iterator_type::value_type rit_value_type;
typedef typename regex_iterator_type::difference_type rit_difference_type;
typedef typename regex_iterator_type::pointer rit_pointer;
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_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_convertible<rit_iterator_category*, std::forward_iterator_tag*>::value));
// this takes care of most of the checks needed:
function_requires<ForwardIteratorConcept<regex_iterator_type> >();
regex_iterator_type iter1(m_in, m_in, e);
ignore_unused_variable_warning(iter1);
regex_iterator_type iter2(m_in, m_in, e, m_mft);
ignore_unused_variable_warning(iter2);
// regex_token_iterator:
typedef typename regex_token_iterator_type::regex_type rtit_regex_type;
typedef typename regex_token_iterator_type::value_type rtit_value_type;
typedef typename regex_token_iterator_type::difference_type rtit_difference_type;
typedef typename regex_token_iterator_type::pointer rtit_pointer;
typedef typename regex_token_iterator_type::reference rtit_reference;
typedef typename regex_token_iterator_type::iterator_category rtit_iterator_category;
BOOST_STATIC_ASSERT((::boost::is_same<rtit_regex_type, Regex>::value));
BOOST_STATIC_ASSERT((::boost::is_same<rtit_value_type, sub_match_type>::value));
BOOST_STATIC_ASSERT((::boost::is_same<rtit_difference_type, std::ptrdiff_t>::value));
BOOST_STATIC_ASSERT((::boost::is_same<rtit_pointer, const sub_match_type*>::value));
BOOST_STATIC_ASSERT((::boost::is_same<rtit_reference, const sub_match_type&>::value));
BOOST_STATIC_ASSERT((::boost::is_convertible<rtit_iterator_category*, std::forward_iterator_tag*>::value));
// this takes care of most of the checks needed:
function_requires<ForwardIteratorConcept<regex_token_iterator_type> >();
regex_token_iterator_type ti1(m_in, m_in, e);
ignore_unused_variable_warning(ti1);
regex_token_iterator_type ti2(m_in, m_in, e, 0);
ignore_unused_variable_warning(ti2);
regex_token_iterator_type ti3(m_in, m_in, e, 0, m_mft);
ignore_unused_variable_warning(ti3);
std::vector<int> subs;
regex_token_iterator_type ti4(m_in, m_in, e, subs);
ignore_unused_variable_warning(ti4);
regex_token_iterator_type ti5(m_in, m_in, e, subs, m_mft);
ignore_unused_variable_warning(ti5);
static const int i_array[] = { 1, 2, 3, };
regex_token_iterator_type ti6(m_in, m_in, e, i_array);
ignore_unused_variable_warning(ti6);
regex_token_iterator_type ti7(m_in, m_in, e, i_array, m_mft);
ignore_unused_variable_warning(ti7);
}
pointer_type m_pointer;
flag_type m_flags;
size_type m_size;
input_iterator_type in1, in2;
const sub_match_type m_sub;
const value_type m_char;
match_results_type m_results;
const match_results_type m_cresults;
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;
private:
BaseRegexConcept();
BaseRegexConcept(const BaseRegexConcept&);
BaseRegexConcept& operator=(const BaseRegexConcept&);
};
//
// RegexConcept:
// Test every interface in the std:
//
template <class Regex>
struct RegexConcept
{
typedef typename Regex::value_type value_type;
typedef typename Regex::size_type size_type;
typedef typename Regex::flag_type flag_type;
typedef typename Regex::locale_type locale_type;
// derived test types:
typedef const value_type* pointer_type;
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 output_iterator_archetype<value_type> OutIterator;
void constraints()
{
function_requires<BaseRegexConcept<Regex> >();
// string based construct:
Regex e1(m_string);
ignore_unused_variable_warning(e1);
Regex e2(m_string, m_flags);
ignore_unused_variable_warning(e2);
// assign etc:
Regex e;
e = m_string;
e.assign(m_string);
e.assign(m_string, m_flags);
// sub_match:
string_type s(m_sub);
ignore_unused_variable_warning(s);
s = m_sub.str();
ignore_unused_variable_warning(s);
int i = m_sub.compare(m_string);
ignore_unused_variable_warning(i);
int i2 = m_sub.compare(m_sub);
ignore_unused_variable_warning(i2);
i2 = m_sub.compare(m_pointer);
ignore_unused_variable_warning(i2);
bool b = m_sub == m_sub;
ignore_unused_variable_warning(b);
b = m_sub != m_sub;
ignore_unused_variable_warning(b);
b = m_sub <= m_sub;
ignore_unused_variable_warning(b);
b = m_sub <= m_sub;
ignore_unused_variable_warning(b);
b = m_sub > m_sub;
ignore_unused_variable_warning(b);
b = m_sub >= m_sub;
ignore_unused_variable_warning(b);
b = m_sub == m_pointer;
ignore_unused_variable_warning(b);
b = m_sub != m_pointer;
ignore_unused_variable_warning(b);
b = m_sub <= m_pointer;
ignore_unused_variable_warning(b);
b = m_sub <= m_pointer;
ignore_unused_variable_warning(b);
b = m_sub > m_pointer;
ignore_unused_variable_warning(b);
b = m_sub >= m_pointer;
ignore_unused_variable_warning(b);
b = m_pointer == m_sub;
ignore_unused_variable_warning(b);
b = m_pointer != m_sub;
ignore_unused_variable_warning(b);
b = m_pointer <= m_sub;
ignore_unused_variable_warning(b);
b = m_pointer <= m_sub;
ignore_unused_variable_warning(b);
b = m_pointer > m_sub;
ignore_unused_variable_warning(b);
b = m_pointer >= m_sub;
ignore_unused_variable_warning(b);
b = m_sub == m_char;
ignore_unused_variable_warning(b);
b = m_sub != m_char;
ignore_unused_variable_warning(b);
b = m_sub <= m_char;
ignore_unused_variable_warning(b);
b = m_sub <= m_char;
ignore_unused_variable_warning(b);
b = m_sub > m_char;
ignore_unused_variable_warning(b);
b = m_sub >= m_char;
ignore_unused_variable_warning(b);
b = m_char == m_sub;
ignore_unused_variable_warning(b);
b = m_char != m_sub;
ignore_unused_variable_warning(b);
b = m_char <= m_sub;
ignore_unused_variable_warning(b);
b = m_char <= m_sub;
ignore_unused_variable_warning(b);
b = m_char > m_sub;
ignore_unused_variable_warning(b);
b = m_char >= m_sub;
ignore_unused_variable_warning(b);
b = m_sub == m_string;
ignore_unused_variable_warning(b);
b = m_sub != m_string;
ignore_unused_variable_warning(b);
b = m_sub <= m_string;
ignore_unused_variable_warning(b);
b = m_sub <= m_string;
ignore_unused_variable_warning(b);
b = m_sub > m_string;
ignore_unused_variable_warning(b);
b = m_sub >= m_string;
ignore_unused_variable_warning(b);
b = m_string == m_sub;
ignore_unused_variable_warning(b);
b = m_string != m_sub;
ignore_unused_variable_warning(b);
b = m_string <= m_sub;
ignore_unused_variable_warning(b);
b = m_string <= m_sub;
ignore_unused_variable_warning(b);
b = m_string > m_sub;
ignore_unused_variable_warning(b);
b = m_string >= m_sub;
ignore_unused_variable_warning(b);
// match results:
m_string = m_results.str();
ignore_unused_variable_warning(m_string);
m_string = m_results.str(0);
ignore_unused_variable_warning(m_string);
m_out = m_cresults.format(m_out, m_string);
m_out = m_cresults.format(m_out, m_string, m_mft);
m_string = m_cresults.format(m_string);
ignore_unused_variable_warning(m_string);
m_string = m_cresults.format(m_string, m_mft);
ignore_unused_variable_warning(m_string);
// regex_match:
b = global_regex_namespace::regex_match(m_string, m_smatch, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_string, m_smatch, e, m_mft);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_string, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_match(m_string, e, m_mft);
ignore_unused_variable_warning(b);
// regex_search:
b = global_regex_namespace::regex_search(m_string, m_smatch, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_string, m_smatch, e, m_mft);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_string, e);
ignore_unused_variable_warning(b);
b = global_regex_namespace::regex_search(m_string, e, m_mft);
ignore_unused_variable_warning(b);
// regex_replace:
m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string, m_mft);
m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string);
m_string = global_regex_namespace::regex_replace(m_string, e, m_string, m_mft);
ignore_unused_variable_warning(m_string);
m_string = global_regex_namespace::regex_replace(m_string, e, m_string);
ignore_unused_variable_warning(m_string);
}
flag_type m_flags;
string_type m_string;
const sub_match_type m_sub;
match_results_type m_results;
pointer_type m_pointer;
value_type m_char;
const match_results_type m_cresults;
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;
private:
RegexConcept();
RegexConcept(const RegexConcept&);
RegexConcept& operator=(const RegexConcept&);
};
//
// BoostRegexConcept:
// Test every interface in the Boost implementation:
//
template <class Regex>
struct BoostRegexConcept
{
typedef typename Regex::value_type value_type;
typedef typename Regex::size_type size_type;
typedef typename Regex::flag_type flag_type;
typedef typename Regex::locale_type locale_type;
// derived test types:
typedef const value_type* pointer_type;
typedef std::basic_string<value_type> string_type;
typedef typename Regex::const_iterator const_iterator;
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;
void constraints()
{
function_requires<RegexConcept<Regex> >();
const global_regex_namespace::regex_error except(global_regex_namespace::regex_constants::error_collate);
std::ptrdiff_t pt = except.position();
ignore_unused_variable_warning(pt);
const Regex ce, ce2;
m_stream << ce;
unsigned i = ce.error_code();
ignore_unused_variable_warning(i);
pointer_type p = ce.expression();
ignore_unused_variable_warning(p);
int i2 = ce.compare(ce2);
ignore_unused_variable_warning(i2);
bool b = ce == ce2;
ignore_unused_variable_warning(b);
b = ce != ce2;
ignore_unused_variable_warning(b);
b = ce < ce2;
ignore_unused_variable_warning(b);
b = ce > ce2;
ignore_unused_variable_warning(b);
b = ce <= ce2;
ignore_unused_variable_warning(b);
b = ce >= ce2;
ignore_unused_variable_warning(b);
i = ce.status();
ignore_unused_variable_warning(i);
size_type s = ce.max_size();
ignore_unused_variable_warning(s);
s = ce.size();
ignore_unused_variable_warning(s);
const_iterator pi = ce.begin();
ignore_unused_variable_warning(pi);
pi = ce.end();
ignore_unused_variable_warning(pi);
string_type s2 = ce.str();
ignore_unused_variable_warning(s2);
m_string = m_sub + m_sub;
ignore_unused_variable_warning(m_string);
m_string = m_sub + m_pointer;
ignore_unused_variable_warning(m_string);
m_string = m_pointer + m_sub;
ignore_unused_variable_warning(m_string);
m_string = m_sub + m_string;
ignore_unused_variable_warning(m_string);
m_string = m_string + m_sub;
ignore_unused_variable_warning(m_string);
m_string = m_sub + m_char;
ignore_unused_variable_warning(m_string);
m_string = m_char + m_sub;
ignore_unused_variable_warning(m_string);
m_stream << m_sub;
m_stream << m_cresults;
}
std::basic_ostream<value_type> m_stream;
sub_match_type m_sub;
pointer_type m_pointer;
string_type m_string;
const value_type m_char;
match_results_type m_results;
const match_results_type m_cresults;
private:
BoostRegexConcept();
BoostRegexConcept(const BoostRegexConcept&);
BoostRegexConcept& operator=(const BoostRegexConcept&);
};
}
#endif

View File

@ -37,23 +37,13 @@ namespace boost{
#pragma warning(push)
#pragma warning(disable : 4275)
#endif
class BOOST_REGEX_DECL bad_pattern : public std::runtime_error
class BOOST_REGEX_DECL regex_error : public std::runtime_error
{
public:
explicit bad_pattern(const std::string& s) : std::runtime_error(s){};
~bad_pattern() throw();
};
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
class BOOST_REGEX_DECL bad_expression : public bad_pattern
{
public:
explicit bad_expression(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos)
: bad_pattern(s), m_error_code(err), m_position(pos) {}
~bad_expression() throw();
regex_constants::error_type errorno()const
explicit regex_error(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos);
explicit regex_error(regex_constants::error_type err);
~regex_error() throw();
regex_constants::error_type code()const
{ return m_error_code; }
std::ptrdiff_t position()const
{ return m_position; }
@ -62,12 +52,15 @@ private:
std::ptrdiff_t m_position;
};
typedef regex_error bad_pattern;
typedef regex_error bad_expression;
namespace re_detail{
BOOST_REGEX_DECL void BOOST_REGEX_CALL raise_runtime_error(const std::runtime_error& ex);
template <class traits>
void raise_error(const traits& t, unsigned code)
void raise_error(const traits& t, regex_constants::error_type code)
{
(void)t; // warning suppression
std::runtime_error e(t.error_string(code));

View File

@ -47,10 +47,15 @@ struct regex_data
typedef regex_constants::syntax_option_type flag_type;
typedef std::size_t size_type;
regex_data(const traits& t) : m_traits(t) {}
regex_data(){}
regex_data(const ::boost::shared_ptr<
::boost::regex_traits_wrapper<traits> >& t)
: m_ptraits(t) {}
regex_data()
: m_ptraits(new ::boost::regex_traits_wrapper<traits>()) {}
traits m_traits; // traits class instance
::boost::shared_ptr<
::boost::regex_traits_wrapper<traits>
> m_ptraits; // traits class instance
flag_type m_flags; // flags with which we were compiled
int m_status; // error code (0 implies OK).
const charT* m_expression; // the original expression
@ -78,7 +83,8 @@ public:
typedef const charT* const_iterator;
basic_regex_implementation(){}
basic_regex_implementation(const traits& t)
basic_regex_implementation(const ::boost::shared_ptr<
::boost::regex_traits_wrapper<traits> >& t)
: regex_data<charT, traits>(t) {}
void assign(const charT* arg_first,
const charT* arg_last,
@ -91,11 +97,11 @@ public:
locale_type BOOST_REGEX_CALL imbue(locale_type l)
{
return this->m_traits.imbue(l);
return this->m_ptraits->imbue(l);
}
locale_type BOOST_REGEX_CALL getloc()const
{
return this->m_traits.getloc();
return this->m_ptraits->getloc();
}
std::basic_string<charT> BOOST_REGEX_CALL str()const
{
@ -146,9 +152,9 @@ public:
{
return this->m_startmap;
}
const traits& get_traits()const
const ::boost::regex_traits_wrapper<traits>& get_traits()const
{
return this->m_traits;
return *(this->m_ptraits);
}
bool can_be_null()const
{
@ -218,7 +224,7 @@ public:
}
basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)
{
return assign(ptr, regex_constants::normal);
return assign(ptr);
}
//
@ -239,12 +245,7 @@ public:
basic_regex& assign(const charT* p1,
const charT* p2,
flag_type f = regex_constants::normal)
{
cow();
m_pimpl->assign(p1, p2, f);
return *this;
}
flag_type f = regex_constants::normal);
#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
template <class ST, class SA>
@ -262,8 +263,9 @@ public:
template <class InputIterator>
basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
{
std::basic_string<charT> a(arg_first, arg_last);
assign(a.data(), a.data() + a.size(), f);
typedef typename traits::string_type seq_type;
seq_type a(arg_first, arg_last);
assign(&*a.begin(), &*a.end(), f);
}
template <class ST, class SA>
@ -285,8 +287,11 @@ public:
InputIterator arg_last,
flag_type f = regex_constants::normal)
{
std::basic_string<charT> a(arg_first, arg_last);
return assign(a.data(), a.data() + a.size(), f);
typedef typename traits::string_type seq_type;
seq_type a(arg_first, arg_last);
const charT* p1 = &*a.begin();
const charT* p2 = &*a.end();
return assign(p1, p2, f);
}
#else
unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
@ -315,11 +320,7 @@ public:
//
// locale:
locale_type BOOST_REGEX_CALL imbue(locale_type l)
{
cow();
return m_pimpl->imbue(l);
}
locale_type BOOST_REGEX_CALL imbue(locale_type l);
locale_type BOOST_REGEX_CALL getloc()const
{
return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
@ -405,7 +406,7 @@ public:
{
return compare(e) == 0;
}
bool operator != (const basic_regex& e)
bool BOOST_REGEX_CALL operator != (const basic_regex& e)const
{
return compare(e) != 0;
}
@ -465,7 +466,7 @@ public:
assert(m_pimpl.get());
return m_pimpl->get_map();
}
const traits& get_traits()const
const ::boost::regex_traits_wrapper<traits>& get_traits()const
{
assert(m_pimpl.get());
return m_pimpl->get_traits();
@ -483,20 +484,51 @@ public:
private:
shared_ptr<re_detail::basic_regex_implementation<charT, traits> > m_pimpl;
void cow()
{
// copy-on-write
if(!m_pimpl.get())
{
m_pimpl = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>());
}
else if(!m_pimpl.unique())
{
m_pimpl = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>(m_pimpl->get_traits()));
}
}
};
//
// out of line members;
// these are the only members that mutate the basic_regex object,
// and are designed to provide the strong exception guarentee
// (in the event of a throw, the state of the object remains unchanged).
//
template <class charT, class traits>
basic_regex<charT, traits>& basic_regex<charT, traits>::assign(const charT* p1,
const charT* p2,
flag_type f)
{
shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp;
if(!m_pimpl.get())
{
temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>());
}
else if(!m_pimpl.unique())
{
temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
}
temp->assign(p1, p2, f);
temp.swap(m_pimpl);
return *this;
}
template <class charT, class traits>
typename basic_regex<charT, traits>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l)
{
shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp(new re_detail::basic_regex_implementation<charT, traits>());
locale_type result = temp->imbue(l);
temp.swap(m_pimpl);
return result;
}
//
// non-members:
//
template <class charT, class traits>
void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
{
e1.swap(e2);
}
#ifndef BOOST_NO_STD_LOCALE
template <class charT, class traits, class traits2>
std::basic_ostream<charT, traits>&

View File

@ -31,8 +31,14 @@ namespace re_detail{
template <class charT>
struct digraph : public std::pair<charT, charT>
{
digraph(charT c1 = 0, charT c2 = 0) : std::pair<charT, charT>(c1, c2){}
digraph(const std::basic_string<charT>& s) : std::pair<charT, charT>()
digraph() : std::pair<charT, charT>(0, 0){}
digraph(charT c1) : std::pair<charT, charT>(c1, 0){}
digraph(charT c1, charT c2) : std::pair<charT, charT>(c1, c2){}
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
digraph(const digraph<charT>& d) : std::pair<charT, charT>(d.first, d.second){}
#endif
template <class Seq>
digraph(const Seq& s) : std::pair<charT, charT>()
{
BOOST_ASSERT(s.size() <= 2);
BOOST_ASSERT(s.size());
@ -202,7 +208,8 @@ public:
void finalize(const charT* p1, const charT* p2);
protected:
regex_data<charT, traits>* m_pdata; // pointer to the basic_regex_data struct we are filling in
const traits& m_traits; // convenience reference to traits class
const ::boost::regex_traits_wrapper<traits>&
m_traits; // convenience reference to traits class
re_syntax_base* m_last_state; // the last state we added
bool m_icase; // true for case insensitive matches
unsigned m_repeater_id; // the id of the next repeater
@ -232,7 +239,7 @@ private:
template <class charT, class traits>
basic_regex_creator<charT, traits>::basic_regex_creator(regex_data<charT, traits>* data)
: m_pdata(data), m_traits(data->m_traits), m_last_state(0), m_repeater_id(0), m_has_backrefs(false), m_backrefs(0)
: m_pdata(data), m_traits(*(data->m_ptraits)), m_last_state(0), m_repeater_id(0), m_has_backrefs(false), m_backrefs(0)
{
m_pdata->m_data.clear();
static const charT w = 'w';
@ -245,11 +252,11 @@ basic_regex_creator<charT, traits>::basic_regex_creator(regex_data<charT, traits
m_lower_mask = m_traits.lookup_classname(l, l + 5);
m_upper_mask = m_traits.lookup_classname(u, u + 5);
m_alpha_mask = m_traits.lookup_classname(a, a + 5);
BOOST_ASSERT(m_word_mask);
BOOST_ASSERT(m_mask_space);
BOOST_ASSERT(m_lower_mask);
BOOST_ASSERT(m_upper_mask);
BOOST_ASSERT(m_alpha_mask);
BOOST_ASSERT(m_word_mask != 0);
BOOST_ASSERT(m_mask_space != 0);
BOOST_ASSERT(m_lower_mask != 0);
BOOST_ASSERT(m_upper_mask != 0);
BOOST_ASSERT(m_alpha_mask != 0);
}
template <class charT, class traits>
@ -329,7 +336,7 @@ template <class charT, class traits>
re_syntax_base* basic_regex_creator<charT, traits>::append_set(
const basic_char_set<charT, traits>& char_set, mpl::false_*)
{
typedef std::basic_string<charT> string_type;
typedef typename traits::string_type string_type;
typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;
typedef typename traits::char_class_type mask_type;
@ -414,9 +421,9 @@ re_syntax_base* basic_regex_creator<charT, traits>::append_set(
return 0;
}
charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s1.size() + s2.size() + 2) ) );
std::memcpy(p, s1.c_str(), sizeof(charT) * (s1.size() + 1));
std::memcpy(p, &*s1.begin(), sizeof(charT) * (s1.size() + 1));
p += s1.size() + 1;
std::memcpy(p, s2.c_str(), sizeof(charT) * (s2.size() + 1));
std::memcpy(p, &*s2.begin(), sizeof(charT) * (s2.size() + 1));
}
//
// now process the equivalence classes:
@ -436,7 +443,7 @@ re_syntax_base* basic_regex_creator<charT, traits>::append_set(
if(s.empty())
return 0; // invalid or unsupported equivalence class
charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s.size()+1) ) );
std::memcpy(p, s.c_str(), sizeof(charT) * (s.size() + 1));
std::memcpy(p, &*s.begin(), sizeof(charT) * (s.size() + 1));
++first;
}
//
@ -450,7 +457,7 @@ template <class charT, class traits>
re_syntax_base* basic_regex_creator<charT, traits>::append_set(
const basic_char_set<charT, traits>& char_set, mpl::true_*)
{
typedef std::basic_string<charT> string_type;
typedef typename traits::string_type string_type;
typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;
re_set* result = static_cast<re_set*>(append_state(syntax_element_set, sizeof(re_set)));
@ -529,7 +536,7 @@ re_syntax_base* basic_regex_creator<charT, traits>::append_set(
{
for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
{
if(this->m_traits.is_class(static_cast<charT>(i), m))
if(this->m_traits.isctype(static_cast<charT>(i), m))
result->_map[i] = true;
}
}
@ -817,7 +824,7 @@ void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state,
l_map[0] |= mask_init;
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
if(!m_traits.is_class(static_cast<charT>(i), m_word_mask))
if(!m_traits.isctype(static_cast<charT>(i), m_word_mask))
l_map[i] &= static_cast<unsigned char>(~mask);
}
}
@ -832,7 +839,7 @@ void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state,
l_map[0] |= mask_init;
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
if(m_traits.is_class(static_cast<charT>(i), m_word_mask))
if(m_traits.isctype(static_cast<charT>(i), m_word_mask))
l_map[i] &= static_cast<unsigned char>(~mask);
}
}

View File

@ -119,8 +119,8 @@ void basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2,
template <class charT, class traits>
void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position)
{
std::string message = this->m_pdata->m_traits.error_string(error_code);
boost::bad_expression e(message, error_code, position);
std::string message = this->m_pdata->m_ptraits->error_string(error_code);
boost::regex_error e(message, error_code, position);
boost::throw_exception(e);
}
@ -256,7 +256,7 @@ bool basic_regex_parser<charT, traits>::parse_literal()
((this->flags()
& (regbase::main_option_type|regbase::mod_x|regbase::no_perl_ex))
!= regbase::mod_x)
|| !this->m_traits.is_class(*m_position, this->m_mask_space))
|| !this->m_traits.isctype(*m_position, this->m_mask_space))
this->append_literal(*m_position);
++m_position;
return true;
@ -584,7 +584,7 @@ bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
std::size_t min, max;
int v;
// skip whitespace:
while((m_position != m_end) && this->m_traits.is_class(*m_position, this->m_mask_space))
while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
++m_position;
// fail if at end:
if(this->m_position == this->m_end)
@ -592,7 +592,7 @@ bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
// get min:
v = this->m_traits.toi(m_position, m_end, 10);
// skip whitespace:
while((m_position != m_end) && this->m_traits.is_class(*m_position, this->m_mask_space))
while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
++m_position;
if(v < 0)
fail(regex_constants::error_badbrace, this->m_position - this->m_base);
@ -605,7 +605,7 @@ bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
// move on and error check:
++m_position;
// skip whitespace:
while((m_position != m_end) && this->m_traits.is_class(*m_position, this->m_mask_space))
while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
++m_position;
if(this->m_position == this->m_end)
fail(regex_constants::error_brace, this->m_position - this->m_base);
@ -619,7 +619,7 @@ bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
max = min;
}
// skip whitespace:
while((m_position != m_end) && this->m_traits.is_class(*m_position, this->m_mask_space))
while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
++m_position;
// OK now check trailing }:
if(this->m_position == this->m_end)
@ -759,7 +759,7 @@ bool basic_regex_parser<charT, traits>::parse_set()
== regex_constants::escape_type_class)
{
char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
if(m)
if(m != 0)
{
char_set.add_class(m);
break;
@ -770,7 +770,7 @@ bool basic_regex_parser<charT, traits>::parse_set()
{
// negated character classes aren't supported:
char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
if(m)
if(m != 0)
{
fail(regex_constants::error_escape, m_position - m_base);
}
@ -835,7 +835,7 @@ bool basic_regex_parser<charT, traits>::parse_inner_set(basic_char_set<charT, tr
fail(regex_constants::error_brack, m_position - m_base);
typedef typename traits::char_class_type mask_type;
mask_type m = this->m_traits.lookup_classname(name_first, name_last);
if(0 == m)
if(m == 0)
{
if(char_set.empty() && (name_last - name_first == 1))
{
@ -909,7 +909,7 @@ bool basic_regex_parser<charT, traits>::parse_inner_set(basic_char_set<charT, tr
template <class charT, class traits>
void basic_regex_parser<charT, traits>::parse_set_literal(basic_char_set<charT, traits>& char_set)
{
digraph<charT> start_range = get_next_set_literal(char_set);
digraph<charT> start_range(get_next_set_literal(char_set));
if(m_end == m_position)
fail(regex_constants::error_brack, m_position - m_base);
if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
@ -1006,7 +1006,7 @@ charT basic_regex_parser<charT, traits>::unescape_character()
charT result(0);
if(m_position == m_end)
fail(regex_constants::error_escape, m_position - m_base);
switch(this->m_traits.syntax_type(*m_position))
switch(this->m_traits.escape_syntax_type(*m_position))
{
case regex_constants::escape_type_control_a:
result = charT('\a');
@ -1127,7 +1127,7 @@ bool basic_regex_parser<charT, traits>::parse_backref()
this->append_literal(c);
}
else
fail(regex_constants::error_subreg, m_position - m_end);
fail(regex_constants::error_backref, m_position - m_end);
return true;
}
@ -1161,7 +1161,7 @@ bool basic_regex_parser<charT, traits>::parse_QE()
return false;
}
// check to see if it's a \E:
if(this->m_traits.syntax_type(*m_position) == regex_constants::escape_type_E)
if(this->m_traits.escape_syntax_type(*m_position) == regex_constants::escape_type_E)
{
++m_position;
end = m_position - 2;
@ -1450,7 +1450,7 @@ regex_constants::syntax_option_type basic_regex_parser<charT, traits>::parse_opt
}
while(!breakout);
if(*m_position == '-')
if(*m_position == static_cast<charT>('-'))
{
if(++m_position == m_end)
fail(regex_constants::error_paren, m_position - m_base);

View File

@ -0,0 +1,146 @@
/*
*
* Copyright (c) 2004
* Dr 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 c_regex_traits.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression traits class that wraps the global C locale.
*/
#ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED
#define BOOST_C_REGEX_TRAITS_HPP_INCLUDED
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#ifndef BOOST_REGEX_WORKAROUND_HPP
#include <boost/regex/v4/regex_workaround.hpp>
#endif
#include <cctype>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{
using ::strlen; using ::tolower;
}
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost{
template <class charT>
struct c_regex_traits;
template<>
struct BOOST_REGEX_DECL c_regex_traits<char>
{
c_regex_traits(){}
typedef char char_type;
typedef std::size_t size_type;
typedef std::string string_type;
struct locale_type{};
typedef boost::uint32_t char_class_type;
static size_type length(const char_type* p)
{
return (std::strlen)(p);
}
char translate(char c) const
{
return c;
}
char translate_nocase(char c) const
{
return (std::tolower)(c);
}
static string_type BOOST_REGEX_CALL transform(const char* p1, const char* p2);
static string_type BOOST_REGEX_CALL transform_primary(const char* p1, const char* p2);
static char_class_type BOOST_REGEX_CALL lookup_classname(const char* p1, const char* p2);
static string_type BOOST_REGEX_CALL lookup_collatename(const char* p1, const char* p2);
static bool BOOST_REGEX_CALL isctype(char, char_class_type);
static int BOOST_REGEX_CALL value(char, int);
locale_type imbue(locale_type l)
{ return l; }
locale_type getloc()const
{ return locale_type(); }
private:
// this type is not copyable:
c_regex_traits(const c_regex_traits&);
c_regex_traits& operator=(const c_regex_traits&);
};
#ifndef BOOST_NO_WREGEX
template<>
struct BOOST_REGEX_DECL c_regex_traits<wchar_t>
{
c_regex_traits(){}
typedef wchar_t char_type;
typedef std::size_t size_type;
typedef std::wstring string_type;
struct locale_type{};
typedef boost::uint32_t char_class_type;
static size_type length(const char_type* p)
{
return (std::wcslen)(p);
}
wchar_t translate(wchar_t c) const
{
return c;
}
wchar_t translate_nocase(wchar_t c) const
{
return (std::towlower)(c);
}
string_type BOOST_REGEX_CALL transform(const wchar_t* p1, const wchar_t* p2) const;
string_type BOOST_REGEX_CALL transform_primary(const wchar_t* p1, const wchar_t* p2) const;
char_class_type BOOST_REGEX_CALL lookup_classname(const wchar_t* p1, const wchar_t* p2) const;
string_type BOOST_REGEX_CALL lookup_collatename(const wchar_t* p1, const wchar_t* p2) const;
bool BOOST_REGEX_CALL isctype(wchar_t, char_class_type) const;
int BOOST_REGEX_CALL value(wchar_t, int) const;
locale_type imbue(locale_type l)
{ return l; }
locale_type getloc()const
{ return locale_type(); }
private:
// this type is not copyable:
c_regex_traits(const c_regex_traits&);
c_regex_traits& operator=(const c_regex_traits&);
};
#endif // BOOST_NO_WREGEX
}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif

View File

@ -67,8 +67,8 @@ public:
const charT* getnext() { return this->gptr(); }
protected:
std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n);
//typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
//typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
private:
parser_buf& operator=(const parser_buf&);
parser_buf(const parser_buf&);
@ -82,7 +82,6 @@ parser_buf<charT, traits>::setbuf(char_type* s, streamsize n)
return this;
}
#if 0
template<class charT, class traits>
typename parser_buf<charT, traits>::pos_type
parser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
@ -141,7 +140,6 @@ parser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)
}
return pos_type(off_type(-1));
}
#endif
//
// class cpp_regex_traits_base:
@ -422,13 +420,13 @@ typename cpp_regex_traits_implementation<charT>::string_type
case sort_fixed:
{
// get a regular sort key, and then truncate it:
result.assign(this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size()));
result.assign(this->m_pcollate->transform(p1, p2));
result.erase(this->m_collate_delim);
break;
}
case sort_delim:
// get a regular sort key, and then truncate everything after the delim:
result.assign(this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size()));
result.assign(this->m_pcollate->transform(p1, p2));
std::size_t i;
for(i = 0; i < result.size(); ++i)
{
@ -511,7 +509,9 @@ cpp_regex_traits_implementation<charT>::cpp_regex_traits_implementation(const st
//
// Error messages:
//
for(boost::regex_constants::error_type i = 0; i <= boost::regex_constants::error_unknown; ++i)
for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
i <= boost::regex_constants::error_unknown;
i = static_cast<boost::regex_constants::error_type>(i + 1))
{
const char* p = get_default_error_string(i);
string_type default_message;
@ -609,15 +609,6 @@ boost::shared_ptr<cpp_regex_traits_implementation<charT> > create_cpp_regex_trai
return boost::shared_ptr<cpp_regex_traits_implementation<charT> >(new cpp_regex_traits_implementation<charT>(l));
}
//
// helpers to suppress warnings:
//
template <class charT>
inline bool is_extended(charT c)
{ return c > 256; }
inline bool is_extended(char)
{ return false; }
} // re_detail
template <class charT>
@ -632,6 +623,8 @@ public:
typedef std::locale locale_type;
typedef boost::uint_least32_t char_class_type;
struct boost_extensions_tag{};
cpp_regex_traits()
: m_pimpl(re_detail::create_cpp_regex_traits<charT>(std::locale()))
{ }
@ -647,6 +640,14 @@ public:
{
return m_pimpl->escape_syntax_type(c);
}
charT translate(charT c) const
{
return c;
}
charT translate_nocase(charT c) const
{
return m_pimpl->m_pctype->tolower(c);
}
charT translate(charT c, bool icase) const
{
return icase ? m_pimpl->m_pctype->tolower(c) : c;
@ -675,7 +676,7 @@ public:
{
return m_pimpl->lookup_collatename(p1, p2);
}
bool is_class(charT c, char_class_type f) const
bool isctype(charT c, char_class_type f) const
{
typedef typename std::ctype<charT>::mask ctype_mask;
if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_base)
@ -693,6 +694,11 @@ public:
return false;
}
int toi(const charT*& p1, const charT* p2, int radix)const;
int value(charT c, int radix)const
{
const charT* pc = &c;
return toi(pc, pc + 1, radix);
}
locale_type imbue(locale_type l)
{
std::locale result(getloc());

View File

@ -30,29 +30,30 @@ namespace boost{
#ifdef __cplusplus
namespace regex_constants{
typedef unsigned error_type;
enum error_type{
static const error_type error_ok = 0; // not used
static const error_type error_no_match = 1; // not used
static const error_type error_bad_pattern = 2;
static const error_type error_collate = 3;
static const error_type error_ctype = 4;
static const error_type error_escape = 5;
static const error_type error_subreg = 6;
static const error_type error_brack = 7;
static const error_type error_paren = 8;
static const error_type error_brace = 9;
static const error_type error_badbrace = 10;
static const error_type error_range = 11;
static const error_type error_space = 12;
static const error_type error_badrepeat = 13;
static const error_type error_end = 14; // not used
static const error_type error_size = 15;
static const error_type error_right_paren = 16; // not used
static const error_type error_empty = 17;
static const error_type error_complexity = 18;
static const error_type error_stack = 19;
static const error_type error_unknown = 20;
error_ok = 0, // not used
error_no_match = 1, // not used
error_bad_pattern = 2,
error_collate = 3,
error_ctype = 4,
error_escape = 5,
error_backref = 6,
error_brack = 7,
error_paren = 8,
error_brace = 9,
error_badbrace = 10,
error_range = 11,
error_space = 12,
error_badrepeat = 13,
error_end = 14, // not used
error_size = 15,
error_right_paren = 16, // not used
error_empty = 17,
error_complexity = 18,
error_stack = 19,
error_unknown = 20
};
}
}

View File

@ -31,7 +31,7 @@ BOOST_REGEX_DECL void BOOST_REGEX_CALL verify_options(boost::regex::flag_type ef
template <class charT>
bool can_start(charT c, const unsigned char* map, unsigned char mask)
{
return ((c < 0) ? true : ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask));
return ((c < static_cast<charT>(0)) ? true : ((c >= static_cast<charT>(1 << CHAR_BIT)) ? true : map[c] & mask));
}
inline bool can_start(char c, const unsigned char* map, unsigned char mask)
{
@ -66,7 +66,9 @@ inline bool can_start(wchar_t c, const unsigned char* map, unsigned char mask)
// which succeeds when it should not.
//
#ifndef _RWSTD_VER
# define STR_COMP(s,p) s.compare(p)
template <class C, class T, class A>
inline int string_compare(const std::basic_string<C,T,A>& s, const C* p)
{ return s.compare(p); }
#else
template <class C, class T, class A>
inline int string_compare(const std::basic_string<C,T,A>& s, const C* p)
@ -77,13 +79,25 @@ inline int string_compare(const std::string& s, const char* p)
inline int string_compare(const std::wstring& s, const wchar_t* p)
{ return std::wcscmp(s.c_str(), p); }
#endif
# define STR_COMP(s,p) string_compare(s,p)
#endif
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
template <class Seq, class C>
inline int string_compare(const Seq& s, const C* p)
{
std::size_t i = 0;
while(p[i] && (p[i] == s[i]))
{
++i;
}
return s[i] - p[i];
}
#endif
# define STR_COMP(s,p) string_compare(s,p)
template<class charT>
inline const charT* re_skip_past_null(const charT* p)
{
while (*p != 0) ++p;
while (*p != static_cast<charT>(0)) ++p;
return ++p;
}
@ -101,7 +115,7 @@ iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
if(next == last) return next;
typedef typename traits_type::string_type traits_string_type;
const traits_type& traits_inst = e.m_traits;
const ::boost::regex_traits_wrapper<traits_type>& traits_inst = *(e.m_ptraits);
// dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never
// referenced
@ -112,12 +126,12 @@ iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
for(i = 0; i < set_->csingles; ++i)
{
ptr = next;
if(*p == 0)
if(*p == static_cast<charT>(0))
{
// treat null string as special case:
if(traits_inst.translate(*ptr, icase) != *p)
{
while(*p == 0)++p;
while(*p == static_cast<charT>(0))++p;
continue;
}
return set_->isnot ? next : (ptr == next) ? ++next : ptr;
@ -132,7 +146,7 @@ iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
++ptr;
}
if(*p == 0) // if null we've matched
if(*p == static_cast<charT>(0)) // if null we've matched
return set_->isnot ? next : (ptr == next) ? ++next : ptr;
p = re_skip_past_null(p); // skip null
@ -188,7 +202,7 @@ iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
}
}
}
if(traits_inst.is_class(col, set_->cclasses) == true)
if(traits_inst.isctype(col, set_->cclasses) == true)
return set_->isnot ? next : ++next;
return set_->isnot ? ++next : next;
}
@ -365,7 +379,7 @@ private:
// the expression being examined:
const basic_regex<char_type, traits>& re;
// the expression's traits class:
const traits& traits_inst;
const ::boost::regex_traits_wrapper<traits>& traits_inst;
// the next state in the machine being matched:
const re_syntax_base* pstate;
// matching flags in use:

View File

@ -353,7 +353,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()
--t;
if(position != last)
{
if(is_separator(*t) && !((*t == '\r') && (*position == '\n')) )
if(is_separator(*t) && !((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n'))) )
{
pstate = pstate->next.p;
return true;
@ -382,7 +382,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()
// check that we're not in the middle of \r\n sequence
BidiIterator t(position);
--t;
if((*t == '\r') && (*position == '\n'))
if((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n')))
{
return false;
}
@ -449,9 +449,9 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()
{
// prev and this character must be opposites:
#if defined(BOOST_REGEX_USE_C_LOCALE) && defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
b = traits::is_class(*position, m_word_mask);
b = traits::isctype(*position, m_word_mask);
#else
b = traits_inst.is_class(*position, m_word_mask);
b = traits_inst.isctype(*position, m_word_mask);
#endif
}
else
@ -468,7 +468,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()
else
{
--position;
b ^= traits_inst.is_class(*position, m_word_mask);
b ^= traits_inst.isctype(*position, m_word_mask);
++position;
}
if(b)
@ -485,7 +485,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()
if(position == last)
return false;
// both prev and this character must be m_word_mask:
if(traits_inst.is_class(*position, m_word_mask))
if(traits_inst.isctype(*position, m_word_mask))
{
bool b;
if((position == base) && ((m_match_flags & match_prev_avail) == 0))
@ -493,7 +493,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()
else
{
--position;
b = traits_inst.is_class(*position, m_word_mask);
b = traits_inst.isctype(*position, m_word_mask);
++position;
}
if(b)
@ -510,7 +510,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
{
if(position == last)
return false; // can't be starting a word if we're already at the end of input
if(!traits_inst.is_class(*position, m_word_mask))
if(!traits_inst.isctype(*position, m_word_mask))
return false; // next character isn't a word character
if((position == base) && ((m_match_flags & match_prev_avail) == 0))
{
@ -522,7 +522,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
// otherwise inside buffer:
BidiIterator t(position);
--t;
if(traits_inst.is_class(*t, m_word_mask))
if(traits_inst.isctype(*t, m_word_mask))
return false; // previous character not non-word
}
// OK we have a match:
@ -537,7 +537,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
return false; // start of buffer can't be end of word
BidiIterator t(position);
--t;
if(traits_inst.is_class(*t, m_word_mask) == false)
if(traits_inst.isctype(*t, m_word_mask) == false)
return false; // previous character wasn't a word character
if(position == last)
@ -548,7 +548,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
else
{
// otherwise inside buffer:
if(traits_inst.is_class(*position, m_word_mask))
if(traits_inst.isctype(*position, m_word_mask))
return false; // next character is a word character
}
pstate = pstate->next.p;
@ -745,9 +745,9 @@ bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_word()
return true;
do
{
while((position != last) && traits_inst.is_class(*position, m_word_mask))
while((position != last) && traits_inst.isctype(*position, m_word_mask))
++position;
while((position != last) && !traits_inst.is_class(*position, m_word_mask))
while((position != last) && !traits_inst.isctype(*position, m_word_mask))
++position;
if(position == last)
break;

View File

@ -36,84 +36,6 @@ class match_results;
namespace re_detail{
//
// helper functions:
//
template <class charT>
std::ptrdiff_t global_length(const charT* p)
{
std::ptrdiff_t n = 0;
while(*p)
{
++p;
++n;
}
return n;
}
inline std::ptrdiff_t global_length(const char* p)
{
return (std::strlen)(p);
}
#ifndef BOOST_NO_WREGEX
inline std::ptrdiff_t global_length(const wchar_t* p)
{
return (std::wcslen)(p);
}
#endif
template <class charT>
inline charT global_lower(charT c)
{
return c;
}
template <class charT>
inline charT global_upper(charT c)
{
return c;
}
BOOST_REGEX_DECL char BOOST_REGEX_CALL global_lower(char c);
BOOST_REGEX_DECL char BOOST_REGEX_CALL global_upper(char c);
#ifndef BOOST_NO_WREGEX
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL global_lower(wchar_t c);
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL global_upper(wchar_t c);
#endif
template <class charT>
int global_value(charT c)
{
static const charT zero = '0';
static const charT nine = '9';
static const charT a = 'a';
static const charT f = 'f';
static const charT A = 'A';
static const charT F = 'F';
if((c >= zero) && (c <= nine))
return c - zero;
if((c >= a) && (c <= f))
return 10 + (c - a);
if((c >= A) && (c <= F))
return 10 + (c - A);
return -1;
}
template <class charT>
int global_toi(const charT*& p1, const charT* p2, int radix)
{
int next_value = global_value(*p1);
if((p1 == p2) || (next_value < 0) || (next_value >= radix))
return -1;
int result = 0;
while(p1 != p2)
{
next_value = global_value(*p1);
if((next_value < 0) || (next_value >= radix))
break;
result *= radix;
result += next_value;
++p1;
}
return result;
}
//
// struct trivial_format_traits:
// defines minimum localisation support for formatting
@ -136,9 +58,14 @@ struct trivial_format_traits
{
return ::boost::re_detail::global_upper(c);
}
static int toi(const charT*& p1, const charT* p2, int radix)
static int value(const charT c, int radix)
{
return global_toi(p1, p2, radix);
int result = global_value(c);
return result >= radix ? -1 : result;
}
int toi(const charT*& p1, const charT* p2, int radix)const
{
return global_toi(p1, p2, radix, *this);
}
};

View File

@ -51,7 +51,7 @@ public:
bool compare(const regex_iterator_implementation& that)
{
if(this == &that) return true;
return (re == that.re) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
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; }

View File

@ -107,6 +107,34 @@ inline bool regex_match(const char* str,
match_results<const char*> m;
return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
}
inline bool regex_match(const char* str,
cmatch& m,
const basic_regex<char, cpp_regex_traits<char> >& e,
match_flag_type flags = match_default)
{
return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
}
inline bool regex_match(const char* str,
const basic_regex<char, cpp_regex_traits<char> >& e,
match_flag_type flags = match_default)
{
match_results<const char*> m;
return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
}
inline bool regex_match(const char* str,
cmatch& m,
const basic_regex<char, c_regex_traits<char> >& e,
match_flag_type flags = match_default)
{
return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
}
inline bool regex_match(const char* str,
const basic_regex<char, c_regex_traits<char> >& e,
match_flag_type flags = match_default)
{
match_results<const char*> m;
return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
}
#ifndef BOOST_NO_WREGEX
inline bool regex_match(const wchar_t* str,
wcmatch& m,
@ -122,6 +150,34 @@ inline bool regex_match(const wchar_t* str,
match_results<const wchar_t*> m;
return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
}
inline bool regex_match(const wchar_t* str,
wcmatch& m,
const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e,
match_flag_type flags = match_default)
{
return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
}
inline bool regex_match(const wchar_t* str,
const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e,
match_flag_type flags = match_default)
{
match_results<const wchar_t*> m;
return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
}
inline bool regex_match(const wchar_t* str,
wcmatch& m,
const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e,
match_flag_type flags = match_default)
{
return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
}
inline bool regex_match(const wchar_t* str,
const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e,
match_flag_type flags = match_default)
{
match_results<const wchar_t*> m;
return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
}
#endif
inline bool regex_match(const std::string& s,
smatch& m,
@ -137,6 +193,34 @@ inline bool regex_match(const std::string& s,
match_results<std::string::const_iterator> m;
return regex_match(s.begin(), s.end(), m, e, flags);
}
inline bool regex_match(const std::string& s,
smatch& m,
const basic_regex<char, cpp_regex_traits<char> >& e,
match_flag_type flags = match_default)
{
return regex_match(s.begin(), s.end(), m, e, flags);
}
inline bool regex_match(const std::string& s,
const basic_regex<char, cpp_regex_traits<char> >& e,
match_flag_type flags = match_default)
{
match_results<std::string::const_iterator> m;
return regex_match(s.begin(), s.end(), m, e, flags);
}
inline bool regex_match(const std::string& s,
smatch& m,
const basic_regex<char, c_regex_traits<char> >& e,
match_flag_type flags = match_default)
{
return regex_match(s.begin(), s.end(), m, e, flags);
}
inline bool regex_match(const std::string& s,
const basic_regex<char, c_regex_traits<char> >& e,
match_flag_type flags = match_default)
{
match_results<std::string::const_iterator> m;
return regex_match(s.begin(), s.end(), m, e, flags);
}
#if !defined(BOOST_NO_WREGEX)
inline bool regex_match(const std::basic_string<wchar_t>& s,
match_results<std::basic_string<wchar_t>::const_iterator>& m,
@ -152,6 +236,34 @@ inline bool regex_match(const std::basic_string<wchar_t>& s,
match_results<std::basic_string<wchar_t>::const_iterator> m;
return regex_match(s.begin(), s.end(), m, e, flags);
}
inline bool regex_match(const std::basic_string<wchar_t>& s,
match_results<std::basic_string<wchar_t>::const_iterator>& m,
const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e,
match_flag_type flags = match_default)
{
return regex_match(s.begin(), s.end(), m, e, flags);
}
inline bool regex_match(const std::basic_string<wchar_t>& s,
const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e,
match_flag_type flags = match_default)
{
match_results<std::basic_string<wchar_t>::const_iterator> m;
return regex_match(s.begin(), s.end(), m, e, flags);
}
inline bool regex_match(const std::basic_string<wchar_t>& s,
match_results<std::basic_string<wchar_t>::const_iterator>& m,
const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e,
match_flag_type flags = match_default)
{
return regex_match(s.begin(), s.end(), m, e, flags);
}
inline bool regex_match(const std::basic_string<wchar_t>& s,
const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e,
match_flag_type flags = match_default)
{
match_results<std::basic_string<wchar_t>::const_iterator> m;
return regex_match(s.begin(), s.end(), m, e, flags);
}
#endif
#endif

View File

@ -63,7 +63,7 @@ bool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()
// output sub-expressions only:
for(unsigned i = 1; i < what.size(); ++i)
{
*(*p_out) = static_cast<string_type>(what[i]);
*(*p_out) = what.str(i);
++(*p_out);
if(0 == --*p_max) return false;
}
@ -75,7 +75,7 @@ bool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()
const sub_match<iterator_type>& sub = what[-1];
if((sub.first != sub.second) || (*p_max != initial_max))
{
*(*p_out) = static_cast<string_type>(sub);
*(*p_out) = sub.str();
++(*p_out);
return --*p_max;
}

View File

@ -113,7 +113,7 @@ public:
bool compare(const regex_token_iterator_implementation& that)
{
if(this == &that) return true;
return (re == that.re)
return (&re.get_data() == &that.re.get_data())
&& (end == that.end)
&& (flags == that.flags)
&& (N == that.N)

View File

@ -34,10 +34,19 @@
#ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
#include <boost/regex/v4/cpp_regex_traits.hpp>
#endif
#ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED
#include <boost/regex/v4/c_regex_traits.hpp>
#endif
#ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
#include <boost/regex/v4/w32_regex_traits.hpp>
#endif
#ifndef BOOST_REGEX_FWD_HPP_INCLUDED
#include <boost/regex_fwd.hpp>
#endif
#include "boost/mpl/aux_/has_xxx.hpp"
#include <boost/static_assert.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
@ -50,6 +59,99 @@ struct regex_traits : public implementationT
regex_traits() : implementationT() {}
};
//
// class regex_traits_wrapper.
// this is what our implementation will actually store;
// it provides default implementations of the "optional"
// interfaces that we support, in addition to the
// required "standard" ones:
//
namespace re_detail{
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
BOOST_MPL_HAS_XXX_TRAIT_DEF(boost_extensions_tag)
#else
template<class T>
struct has_boost_extensions_tag
{
BOOST_STATIC_CONSTANT(bool, value = false);
};
#endif
template <class BaseT>
struct default_wrapper : public BaseT
{
typedef typename BaseT::char_type char_type;
std::string error_string(::boost::regex_constants::error_type e)const
{
return ::boost::re_detail::get_default_error_string(e);
}
::boost::regex_constants::syntax_type syntax_type(char_type c)const
{
return ((c & 0x7f) == c) ? get_default_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::syntax_char;
}
::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c)const
{
return ((c & 0x7f) == c) ? get_default_escape_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::escape_type_identity;
}
int toi(const char_type*& p1, const char_type* p2, int radix)const
{
return ::boost::re_detail::global_toi(p1, p2, radix, *this);
}
char_type translate(char_type c, bool icase)const
{
return (icase ? this->translate_nocase(c) : this->translate(c));
}
char_type translate(char_type c)const
{
return BaseT::translate(c);
}
char_type tolower(char_type c)const
{
return ::boost::re_detail::global_lower(c);
}
char_type toupper(char_type c)const
{
return ::boost::re_detail::global_upper(c);
}
};
template <class BaseT, bool has_extensions>
struct compute_wrapper_base
{
typedef BaseT type;
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class BaseT>
struct compute_wrapper_base<BaseT, false>
{
typedef default_wrapper<BaseT> type;
};
#else
template <>
struct compute_wrapper_base<c_regex_traits<char>, false>
{
typedef default_wrapper<c_regex_traits<char> > type;
};
#ifndef BOOST_NO_WREGEX
template <>
struct compute_wrapper_base<c_regex_traits<wchar_t>, false>
{
typedef default_wrapper<c_regex_traits<wchar_t> > type;
};
#endif
#endif
} // namespace re_detail
template <class BaseT>
struct regex_traits_wrapper
: public ::boost::re_detail::compute_wrapper_base<
BaseT,
::boost::re_detail::has_boost_extensions_tag<BaseT>::value
>::type
{
};
} // namespace boost
#ifdef BOOST_HAS_ABI_HEADERS

View File

@ -23,10 +23,36 @@
# include BOOST_ABI_PREFIX
#endif
#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP
#include <boost/regex/v4/syntax_type.hpp>
#endif
#ifndef BOOST_REGEX_ERROR_TYPE_HPP
#include <boost/regex/v4/error_type.hpp>
#endif
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{
using ::strlen;
}
#endif
namespace boost{ namespace re_detail{
//
// helpers to suppress warnings:
//
template <class charT>
inline bool is_extended(charT c)
{ return c > 256; }
inline bool is_extended(char)
{ return false; }
BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_syntax(regex_constants::syntax_type n);
BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_error_string(regex_constants::error_type n);
BOOST_REGEX_DECL regex_constants::syntax_type BOOST_REGEX_CALL get_default_syntax_type(char c);
BOOST_REGEX_DECL regex_constants::escape_syntax_type BOOST_REGEX_CALL get_default_escape_syntax_type(char c);
// is charT c a combining character?
BOOST_REGEX_DECL bool BOOST_REGEX_CALL is_combining_implementation(uint_least16_t s);
@ -34,7 +60,7 @@ BOOST_REGEX_DECL bool BOOST_REGEX_CALL is_combining_implementation(uint_least16_
template <class charT>
inline bool is_combining(charT c)
{
return (c < 0) ? false : ((c > (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c)));
return (c < static_cast<charT>(0)) ? false : ((c > static_cast<charT>((std::numeric_limits<uint_least16_t>::max)())) ? false : is_combining_implementation(static_cast<unsigned short>(c)));
}
template <>
inline bool is_combining<char>(char)
@ -79,7 +105,7 @@ inline bool is_combining<wchar_t>(wchar_t c)
template <class charT>
inline bool is_separator(charT c)
{
return BOOST_REGEX_MAKE_BOOL((c == '\n') || (c == '\r') || (static_cast<int>(c) == 0x2028) || (static_cast<int>(c) == 0x2029));
return BOOST_REGEX_MAKE_BOOL((c == static_cast<charT>('\n')) || (c == static_cast<charT>('\r')) || (static_cast<int>(c) == 0x2028) || (static_cast<int>(c) == 0x2029));
}
template <>
inline bool is_separator<char>(char c)
@ -163,31 +189,82 @@ int get_default_class_id(const charT* p1, const charT* p2)
return -1;
}
#if 0
//
// parse_value:
// covert a character sequence into a value, return -1 if no digits found:
// helper functions:
//
template <class charT, class traits>
int parse_value(const charT*& p1, const charT* p2, const traits& traits_inst, int radix = 10)
template <class charT>
std::ptrdiff_t global_length(const charT* p)
{
return traits_inst.toi(p1, p2, radix);
#if 0
int value = 0;
if(traits_inst.value(*p1) < 0)
return -1;
while(p1 != p2)
std::ptrdiff_t n = 0;
while(*p)
{
int v2 = traits_inst.value(*p1);
if(v2 < 0) break;
value *= radix;
value += v2;
++p1;
++p;
++n;
}
return value;
#endif
return n;
}
inline std::ptrdiff_t global_length(const char* p)
{
return (std::strlen)(p);
}
#ifndef BOOST_NO_WREGEX
inline std::ptrdiff_t global_length(const wchar_t* p)
{
return (std::wcslen)(p);
}
#endif
template <class charT>
inline charT BOOST_REGEX_CALL global_lower(charT c)
{
return c;
}
template <class charT>
inline charT BOOST_REGEX_CALL global_upper(charT c)
{
return c;
}
BOOST_REGEX_DECL char BOOST_REGEX_CALL global_lower(char c);
BOOST_REGEX_DECL char BOOST_REGEX_CALL global_upper(char c);
#ifndef BOOST_NO_WREGEX
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL global_lower(wchar_t c);
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL global_upper(wchar_t c);
#endif
template <class charT>
int global_value(charT c)
{
static const charT zero = '0';
static const charT nine = '9';
static const charT a = 'a';
static const charT f = 'f';
static const charT A = 'A';
static const charT F = 'F';
if(c > f) return -1;
if(c >= a) return 10 + (c - a);
if(c > F) return -1;
if(c >= A) return 10 + (c - A);
if(c > nine) return -1;
if(c >= zero) return c - zero;
return -1;
}
template <class charT, class traits>
int global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)
{
int next_value = t.value(*p1, radix);
if((p1 == p2) || (next_value < 0) || (next_value >= radix))
return -1;
int result = 0;
while(p1 != p2)
{
next_value = t.value(*p1, radix);
if((next_value < 0) || (next_value >= radix))
break;
result *= radix;
result += next_value;
++p1;
}
return result;
}
} // re_detail
} // boost

View File

@ -78,6 +78,8 @@ namespace std{
using ::ptrdiff_t;
using ::size_t;
using ::abs;
using ::memset;
using ::memcpy;
}
#endif

View File

@ -42,11 +42,18 @@ struct sub_match : public std::pair<BidiIterator, BidiIterator>
sub_match() : std::pair<BidiIterator, BidiIterator>(), matched(false) {}
sub_match(BidiIterator i) : std::pair<BidiIterator, BidiIterator>(i, i), matched(false) {}
#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
template <class T, class A>
operator std::basic_string<value_type, T, A> ()const
{
return std::basic_string<value_type, T, A>(first, second);
}
#else
operator std::basic_string<value_type> ()const
{
return str();
}
#endif
difference_type BOOST_REGEX_CALL length()const
{
difference_type n = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
@ -71,6 +78,14 @@ struct sub_match : public std::pair<BidiIterator, BidiIterator>
return static_cast<int>(matched) - static_cast<int>(s.matched);
return str().compare(s.str());
}
int compare(const std::basic_string<value_type>& s)const
{
return str().compare(s);
}
int compare(const value_type* p)const
{
return str().compare(p);
}
bool operator==(const sub_match& that)const
{ return compare(that) == 0; }

View File

@ -0,0 +1,654 @@
/*
*
* Copyright (c) 2004
* Dr 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 w32_regex_traits.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression traits class w32_regex_traits.
*/
#ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
#define BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
#include <boost/regex/v4/regex_traits_defaults.hpp>
#endif
#ifdef BOOST_HAS_THREADS
#include <boost/regex/static_mutex.hpp>
#endif
#ifndef BOOST_REGEX_PRIMARY_TRANSFORM
#include <boost/regex/v4/primary_transform.hpp>
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4786)
#endif
namespace boost{
//
// forward declaration is needed by some compilers:
//
template <class charT>
class w32_regex_traits;
namespace re_detail{
//
// start by typedeffing the types we'll need:
//
typedef ::boost::uint32_t lcid_type; // placeholder for LCID.
typedef ::boost::shared_ptr<void> cat_type; // placeholder for dll HANDLE.
//
// then add wrappers around the actual Win32 API's (ie implementation hiding):
//
BOOST_REGEX_DECL lcid_type BOOST_REGEX_CALL w32_get_default_locale();
BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(char, lcid_type);
BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(wchar_t, lcid_type);
BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(char, lcid_type);
BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(wchar_t, lcid_type);
BOOST_REGEX_DECL cat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name);
BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type id, int i, const std::string& def);
BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type id, int i, const std::wstring& def);
BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const char* p1, const char* p2);
BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type id, const wchar_t* p1, const wchar_t* p2);
BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type);
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type);
BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type);
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type);
BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, char c);
BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, wchar_t c);
//
// class w32_regex_traits_base:
// acts as a container for locale and the facets we are using.
//
template <class charT>
struct w32_regex_traits_base
{
w32_regex_traits_base(lcid_type l)
{ imbue(l); }
lcid_type imbue(lcid_type l);
lcid_type m_locale;
};
template <class charT>
inline lcid_type w32_regex_traits_base<charT>::imbue(lcid_type l)
{
lcid_type result(m_locale);
m_locale = l;
return result;
}
//
// class w32_regex_traits_char_layer:
// implements methods that require specialisation for narrow characters:
//
template <class charT>
class w32_regex_traits_char_layer : public w32_regex_traits_base<charT>
{
typedef std::basic_string<charT> string_type;
typedef std::map<charT, regex_constants::syntax_type> map_type;
typedef typename map_type::const_iterator map_iterator_type;
public:
w32_regex_traits_char_layer(const lcid_type l);
regex_constants::syntax_type syntax_type(charT c)const
{
map_iterator_type i = m_char_map.find(c);
return ((i == m_char_map.end()) ? 0 : i->second);
}
regex_constants::escape_syntax_type escape_syntax_type(charT c) const
{
map_iterator_type i = m_char_map.find(c);
if(i == m_char_map.end())
{
if(::boost::re_detail::w32_is_lower(c, this->m_locale)) return regex_constants::escape_type_class;
if(::boost::re_detail::w32_is_upper(c, this->m_locale)) return regex_constants::escape_type_not_class;
return 0;
}
return i->second;
}
private:
string_type get_default_message(regex_constants::syntax_type);
// TODO: use a hash table when available!
map_type m_char_map;
};
template <class charT>
w32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
: w32_regex_traits_base<charT>(l)
{
// we need to start by initialising our syntax map so we know which
// character is used for which purpose:
cat_type cat;
std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
if(cat_name.size())
{
cat = ::boost::re_detail::w32_cat_open(cat_name);
if(!cat)
{
std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name);
boost::throw_exception(err);
}
}
//
// if we have a valid catalog then load our messages:
//
if(cat)
{
for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
{
string_type mss = ::boost::re_detail::w32_cat_get(cat, m_locale, i, get_default_message(i));
for(typename string_type::size_type j = 0; j < mss.size(); ++j)
{
m_char_map[mss[j]] = i;
}
}
}
else
{
for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
{
const char* ptr = get_default_syntax(i);
while(ptr && *ptr)
{
m_char_map[static_cast<charT>(*ptr)] = i;
++ptr;
}
}
}
}
template <class charT>
typename w32_regex_traits_char_layer<charT>::string_type
w32_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
{
const char* ptr = get_default_syntax(i);
string_type result;
while(ptr && *ptr)
{
result.append(1, static_cast<charT>(*ptr));
++ptr;
}
return result;
}
//
// specialised version for narrow characters:
//
template <>
class BOOST_REGEX_DECL w32_regex_traits_char_layer<char> : public w32_regex_traits_base<char>
{
typedef std::string string_type;
public:
w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
: w32_regex_traits_base<char>(l)
{
init();
}
regex_constants::syntax_type syntax_type(char c)const
{
return m_char_map[static_cast<unsigned char>(c)];
}
regex_constants::escape_syntax_type escape_syntax_type(char c) const
{
return m_char_map[static_cast<unsigned char>(c)];
}
private:
regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
void init();
};
//
// class w32_regex_traits_implementation:
// provides pimpl implementation for w32_regex_traits.
//
template <class charT>
class w32_regex_traits_implementation : public w32_regex_traits_char_layer<charT>
{
public:
typedef typename w32_regex_traits<charT>::char_class_type char_class_type;
BOOST_STATIC_CONSTANT(char_class_type, mask_word = 0x0400); // must be C1_DEFINED << 1
BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 0x0800); // must be C1_DEFINED << 2
BOOST_STATIC_CONSTANT(char_class_type, mask_base = 0x3ff); // all the masks used by the CT_CTYPE1 group
typedef std::basic_string<charT> string_type;
typedef charT char_type;
w32_regex_traits_implementation(::boost::re_detail::lcid_type l);
std::string error_string(regex_constants::error_type n) const
{
if(!m_error_strings.empty())
{
std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
}
return get_default_error_string(n);
}
char_class_type lookup_classname(const charT* p1, const charT* p2) const
{
char_class_type result = lookup_classname_imp(p1, p2);
if(result == 0)
{
typedef typename string_type::size_type size_type;
string_type temp(p1, p2);
for(size_type i = 0; i < temp.size(); ++i)
temp[i] = ::boost::re_detail::w32_tolower(temp[i], this->m_locale);
result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
}
return result;
}
string_type lookup_collatename(const charT* p1, const charT* p2) const;
string_type transform_primary(const charT* p1, const charT* p2) const;
string_type transform(const charT* p1, const charT* p2) const
{
return ::boost::re_detail::w32_transform(this->m_locale, p1, p2);
}
private:
std::map<int, std::string> m_error_strings; // error messages indexed by numberic ID
std::map<string_type, char_class_type> m_custom_class_names; // character class names
std::map<string_type, string_type> m_custom_collate_names; // collating element names
unsigned m_collate_type; // the form of the collation string
charT m_collate_delim; // the collation group delimiter
//
// helpers:
//
char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
};
template <class charT>
typename w32_regex_traits_implementation<charT>::string_type
w32_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
{
string_type result;
//
// What we do here depends upon the format of the sort key returned by
// sort key returned by this->transform:
//
switch(m_collate_type)
{
case sort_C:
case sort_unknown:
// the best we can do is translate to lower case, then get a regular sort key:
{
result.assign(p1, p2);
typedef typename string_type::size_type size_type;
for(size_type i = 0; i < result.size(); ++i)
result[i] = ::boost::re_detail::w32_tolower(result[i], this->m_locale);
result = this->transform(&*result.begin(), &*result.begin() + result.size());
break;
}
case sort_fixed:
{
// get a regular sort key, and then truncate it:
result.assign(this->transform(p1, p2));
result.erase(this->m_collate_delim);
break;
}
case sort_delim:
// get a regular sort key, and then truncate everything after the delim:
result.assign(this->transform(p1, p2));
std::size_t i;
for(i = 0; i < result.size(); ++i)
{
if(result[i] == m_collate_delim)
break;
}
result.erase(i);
break;
}
return result;
}
template <class charT>
typename w32_regex_traits_implementation<charT>::string_type
w32_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
{
typedef typename std::map<string_type, string_type>::const_iterator iter_type;
if(m_custom_collate_names.size())
{
iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
if(pos != m_custom_collate_names.end())
return pos->second;
}
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
std::string name(p1, p2);
#else
std::string name;
const charT* p0 = p1;
while(p0 != p2)
name.append(1, char(*p0++));
#endif
name = lookup_default_collate_name(name);
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
if(name.size())
return string_type(name.begin(), name.end());
#else
if(name.size())
{
string_type result;
typedef std::string::const_iterator iter;
iter b = name.begin();
iter e = name.end();
while(b != e)
result.append(1, charT(*b++));
return result;
}
#endif
if(p2 - p1 == 1)
return string_type(1, *p1);
return string_type();
}
template <class charT>
w32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::boost::re_detail::lcid_type l)
: w32_regex_traits_char_layer<charT>(l)
{
cat_type cat;
std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
if(cat_name.size())
{
cat = ::boost::re_detail::w32_cat_open(cat_name);
if(!cat)
{
std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name);
boost::throw_exception(err);
}
}
//
// if we have a valid catalog then load our messages:
//
if(cat)
{
//
// Error messages:
//
for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
i <= boost::regex_constants::error_unknown;
i = static_cast<boost::regex_constants::error_type>(i + 1))
{
const char* p = get_default_error_string(i);
string_type default_message;
while(*p)
{
default_message.append(1, static_cast<charT>(*p));
++p;
}
string_type s = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i+200, default_message);
std::string result;
for(std::string::size_type j = 0; j < s.size(); ++j)
{
result.append(1, static_cast<char>(s[j]));
}
m_error_strings[i] = result;
}
//
// Custom class names:
//
static const char_class_type masks[] =
{
0x0104u, // C1_ALPHA | C1_DIGIT
0x0100u, // C1_ALPHA
0x0020u, // C1_CNTRL
0x0004u, // C1_DIGIT
(~(0x0020u|0x0008u) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE
0x0002u, // C1_LOWER
(~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
0x0010u, // C1_PUNCT
0x0008u, // C1_SPACE
0x0001u, // C1_UPPER
0x0080u, // C1_XDIGIT
0x0040u, // C1_BLANK
w32_regex_traits_implementation<charT>::mask_word,
w32_regex_traits_implementation<charT>::mask_unicode,
};
static const string_type null_string;
for(unsigned int j = 0; j <= 13; ++j)
{
string_type s(::boost::re_detail::w32_cat_get(cat, this->m_locale, j+300, null_string));
if(s.size())
this->m_custom_class_names[s] = masks[j];
}
}
//
// get the collation format used by m_pcollate:
//
m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
}
template <class charT>
typename w32_regex_traits_implementation<charT>::char_class_type
w32_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
{
static const char_class_type masks[] =
{
0,
0x0104u, // C1_ALPHA | C1_DIGIT
0x0100u, // C1_ALPHA
0x0040u, // C1_BLANK
0x0020u, // C1_CNTRL
0x0004u, // C1_DIGIT
0x0004u, // C1_DIGIT
(~(0x0020u|0x0008u|0x0040) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE or C1_BLANK
0x0002u, // C1_LOWER
0x0002u, // C1_LOWER
(~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
0x0010u, // C1_PUNCT
0x0008u, // C1_SPACE
0x0008u, // C1_SPACE
0x0001u, // C1_UPPER
w32_regex_traits_implementation<charT>::mask_unicode,
0x0001u, // C1_UPPER
0x0104u | w32_regex_traits_implementation<charT>::mask_word,
0x0104u | w32_regex_traits_implementation<charT>::mask_word,
0x0080u, // C1_XDIGIT
};
if(m_custom_class_names.size())
{
typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
map_iter pos = m_custom_class_names.find(string_type(p1, p2));
if(pos != m_custom_class_names.end())
return pos->second;
}
std::size_t id = 1 + re_detail::get_default_class_id(p1, p2);
assert(id < sizeof(masks) / sizeof(masks[0]));
return masks[id];
}
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));
}
} // re_detail
template <class charT>
class w32_regex_traits
{
private:
typedef std::ctype<charT> ctype_type;
public:
typedef charT char_type;
typedef std::size_t size_type;
typedef std::basic_string<char_type> string_type;
typedef ::boost::re_detail::lcid_type locale_type;
typedef boost::uint_least32_t char_class_type;
struct boost_extensions_tag{};
w32_regex_traits()
: m_pimpl(re_detail::create_w32_regex_traits<charT>(::boost::re_detail::w32_get_default_locale()))
{ }
static size_type length(const char_type* p)
{
return std::char_traits<charT>::length(p);
}
regex_constants::syntax_type syntax_type(charT c)const
{
return m_pimpl->syntax_type(c);
}
regex_constants::escape_syntax_type escape_syntax_type(charT c) const
{
return m_pimpl->escape_syntax_type(c);
}
charT translate(charT c) const
{
return c;
}
charT translate_nocase(charT c) const
{
return ::boost::re_detail::w32_tolower(c, this->m_pimpl->m_locale);
}
charT translate(charT c, bool icase) const
{
return icase ? ::boost::re_detail::w32_tolower(c, this->m_pimpl->m_locale) : c;
}
charT tolower(charT c) const
{
return ::boost::re_detail::w32_tolower(c, this->m_pimpl->m_locale);
}
charT toupper(charT c) const
{
return ::boost::re_detail::w32_toupper(c, this->m_pimpl->m_locale);
}
string_type transform(const charT* p1, const charT* p2) const
{
return ::boost::re_detail::w32_transform(this->m_pimpl->m_locale, p1, p2);
}
string_type transform_primary(const charT* p1, const charT* p2) const
{
return m_pimpl->transform_primary(p1, p2);
}
char_class_type lookup_classname(const charT* p1, const charT* p2) const
{
return m_pimpl->lookup_classname(p1, p2);
}
string_type lookup_collatename(const charT* p1, const charT* p2) const
{
return m_pimpl->lookup_collatename(p1, p2);
}
bool isctype(charT c, char_class_type f) const
{
if((f & re_detail::w32_regex_traits_implementation<charT>::mask_base)
&& (::boost::re_detail::w32_is(this->m_pimpl->m_locale, f & re_detail::w32_regex_traits_implementation<charT>::mask_base, c)))
return true;
else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
return true;
else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_word) && (c == '_'))
return true;
return false;
}
int toi(const charT*& p1, const charT* p2, int radix)const
{
return ::boost::re_detail::global_toi(p1, p2, radix, *this);
}
int value(charT c, int radix)const
{
return ::boost::re_detail::global_value(c);
}
locale_type imbue(locale_type l)
{
::boost::re_detail::lcid_type result(getloc());
m_pimpl = re_detail::create_w32_regex_traits<charT>(l);
return result;
}
locale_type getloc()const
{
return m_pimpl->m_locale;
}
std::string error_string(regex_constants::error_type n) const
{
return m_pimpl->error_string(n);
}
//
// extension:
// set the name of the message catalog in use (defaults to "boost_regex").
//
static std::string catalog_name(const std::string& name);
static std::string get_catalog_name();
private:
boost::shared_ptr<re_detail::w32_regex_traits_implementation<charT> > m_pimpl;
//
// catalog name handler:
//
static std::string& get_catalog_name_inst();
#ifdef BOOST_HAS_THREADS
static static_mutex& get_mutex_inst();
#endif
};
template <class charT>
std::string w32_regex_traits<charT>::catalog_name(const std::string& name)
{
#ifdef BOOST_HAS_THREADS
static_mutex::scoped_lock lk(get_mutex_inst());
#endif
std::string result(get_catalog_name_inst());
get_catalog_name_inst() = name;
return result;
}
template <class charT>
std::string& w32_regex_traits<charT>::get_catalog_name_inst()
{
static std::string s_name;
return s_name;
}
template <class charT>
std::string w32_regex_traits<charT>::get_catalog_name()
{
#ifdef BOOST_HAS_THREADS
static_mutex::scoped_lock lk(get_mutex_inst());
#endif
std::string result(get_catalog_name_inst());
return result;
}
#ifdef BOOST_HAS_THREADS
template <class charT>
static_mutex& w32_regex_traits<charT>::get_mutex_inst()
{
static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;
return s_mutex;
}
#endif
} // boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif

View File

@ -19,6 +19,12 @@
#define BOOST_REGEX_SOURCE
#include <boost/regex/regex_traits.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{
using ::memset;
}
#endif
namespace boost{ namespace re_detail{
void cpp_regex_traits_char_layer<char>::init()

View File

@ -35,7 +35,7 @@ typedef boost::match_flag_type match_flag_type;
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::sprintf;
using ::sprintf; using ::strcpy; using ::strcat;
}
#endif

View File

@ -39,6 +39,11 @@ namespace std{
using ::fopen;
using ::fclose;
using ::FILE;
using ::strcpy;
using ::strcpy;
using ::strcat;
using ::strcmp;
using ::strlen;
}
#endif

View File

@ -25,6 +25,8 @@
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::sprintf;
using ::strcpy;
using ::strcmp;
}
#endif
@ -104,9 +106,9 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA* expression, const char
result = static_cast<regex*>(expression->guts)->error_code();
#ifndef BOOST_NO_EXCEPTIONS
}
catch(const boost::bad_expression& be)
catch(const boost::regex_error& be)
{
result = be.errorno();
result = be.code();
}
catch(...)
{
@ -158,11 +160,10 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA*
{
std::string p;
if((e) && (e->re_magic == magic_value))
p = static_cast<regex*>(e->guts)->get_traits().error_string(code);
p = static_cast<regex*>(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code));
else
{
boost::regex_traits<char> t;
p = t.error_string(code);
p = re_detail::get_default_error_string(static_cast< ::boost::regex_constants::error_type>(code));
}
std::size_t len = p.size();
if(len < buf_size)

View File

@ -50,8 +50,11 @@ namespace boost{
// that dll builds contain the Virtual table for these
// types - this ensures that exceptions can be thrown
// from the dll and caught in an exe.
bad_pattern::~bad_pattern() throw() {}
bad_expression::~bad_expression() throw() {}
regex_error::regex_error(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos)
: std::runtime_error(s), m_error_code(err), m_position(pos) {}
regex_error::regex_error(regex_constants::error_type err)
: std::runtime_error(::boost::re_detail::get_default_error_string(err)), m_error_code(err), m_position(0) {}
regex_error::~regex_error() throw() {}
namespace re_detail{

View File

@ -277,5 +277,396 @@ BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL global_upper(wchar_t c)
}
#endif
BOOST_REGEX_DECL regex_constants::escape_syntax_type BOOST_REGEX_CALL get_default_escape_syntax_type(char c)
{
//
// char_syntax determines how the compiler treats a given character
// in a regular expression.
//
static regex_constants::escape_syntax_type char_syntax[] = {
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /* */ // 32
regex_constants::escape_type_identity, /*!*/
regex_constants::escape_type_identity, /*"*/
regex_constants::escape_type_identity, /*#*/
regex_constants::escape_type_identity, /*$*/
regex_constants::escape_type_identity, /*%*/
regex_constants::escape_type_identity, /*&*/
regex_constants::escape_type_end_buffer, /*'*/
regex_constants::syntax_open_mark, /*(*/
regex_constants::syntax_close_mark, /*)*/
regex_constants::escape_type_identity, /***/
regex_constants::syntax_plus, /*+*/
regex_constants::escape_type_identity, /*,*/
regex_constants::escape_type_identity, /*-*/
regex_constants::escape_type_identity, /*.*/
regex_constants::escape_type_identity, /*/*/
regex_constants::escape_type_decimal, /*0*/
regex_constants::escape_type_backref, /*1*/
regex_constants::escape_type_backref, /*2*/
regex_constants::escape_type_backref, /*3*/
regex_constants::escape_type_backref, /*4*/
regex_constants::escape_type_backref, /*5*/
regex_constants::escape_type_backref, /*6*/
regex_constants::escape_type_backref, /*7*/
regex_constants::escape_type_backref, /*8*/
regex_constants::escape_type_backref, /*9*/
regex_constants::escape_type_identity, /*:*/
regex_constants::escape_type_identity, /*;*/
regex_constants::escape_type_left_word, /*<*/
regex_constants::escape_type_identity, /*=*/
regex_constants::escape_type_right_word, /*>*/
regex_constants::syntax_question, /*?*/
regex_constants::escape_type_identity, /*@*/
regex_constants::escape_type_start_buffer, /*A*/
regex_constants::escape_type_not_word_assert, /*B*/
regex_constants::escape_type_C, /*C*/
regex_constants::escape_type_not_class, /*D*/
regex_constants::escape_type_E, /*E*/
regex_constants::escape_type_not_class, /*F*/
regex_constants::escape_type_G, /*G*/
regex_constants::escape_type_not_class, /*H*/
regex_constants::escape_type_not_class, /*I*/
regex_constants::escape_type_not_class, /*J*/
regex_constants::escape_type_not_class, /*K*/
regex_constants::escape_type_not_class, /*L*/
regex_constants::escape_type_not_class, /*M*/
regex_constants::escape_type_not_class, /*N*/
regex_constants::escape_type_not_class, /*O*/
regex_constants::escape_type_not_class, /*P*/
regex_constants::escape_type_Q, /*Q*/
regex_constants::escape_type_not_class, /*R*/
regex_constants::escape_type_not_class, /*S*/
regex_constants::escape_type_not_class, /*T*/
regex_constants::escape_type_not_class, /*U*/
regex_constants::escape_type_not_class, /*V*/
regex_constants::escape_type_not_class, /*W*/
regex_constants::escape_type_X, /*X*/
regex_constants::escape_type_not_class, /*Y*/
regex_constants::escape_type_Z, /*Z*/
regex_constants::escape_type_identity, /*[*/
regex_constants::escape_type_identity, /*\*/
regex_constants::escape_type_identity, /*]*/
regex_constants::escape_type_identity, /*^*/
regex_constants::escape_type_identity, /*_*/
regex_constants::escape_type_start_buffer, /*`*/
regex_constants::escape_type_control_a, /*a*/
regex_constants::escape_type_word_assert, /*b*/
regex_constants::escape_type_ascii_control, /*c*/
regex_constants::escape_type_class, /*d*/
regex_constants::escape_type_e, /*e*/
regex_constants::escape_type_control_f, /*f*/
regex_constants::escape_type_class, /*g*/
regex_constants::escape_type_class, /*h*/
regex_constants::escape_type_class, /*i*/
regex_constants::escape_type_class, /*j*/
regex_constants::escape_type_class, /*k*/
regex_constants::escape_type_class, /*l*/
regex_constants::escape_type_class, /*m*/
regex_constants::escape_type_control_n, /*n*/
regex_constants::escape_type_class, /*o*/
regex_constants::escape_type_class, /*p*/
regex_constants::escape_type_class, /*q*/
regex_constants::escape_type_control_r, /*r*/
regex_constants::escape_type_class, /*s*/
regex_constants::escape_type_control_t, /*t*/
regex_constants::escape_type_class, /*u*/
regex_constants::escape_type_control_v, /*v*/
regex_constants::escape_type_class, /*w*/
regex_constants::escape_type_hex, /*x*/
regex_constants::escape_type_class, /*y*/
regex_constants::escape_type_end_buffer, /*z*/
regex_constants::syntax_open_brace, /*{*/
regex_constants::syntax_or, /*|*/
regex_constants::syntax_close_brace, /*}*/
regex_constants::escape_type_identity, /*~*/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
regex_constants::escape_type_identity, /*<2A>*/
};
return char_syntax[(unsigned char)c];
}
BOOST_REGEX_DECL regex_constants::syntax_type BOOST_REGEX_CALL get_default_syntax_type(char c)
{
//
// char_syntax determines how the compiler treats a given character
// in a regular expression.
//
static regex_constants::syntax_type char_syntax[] = {
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_newline, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /* */ // 32
regex_constants::syntax_not, /*!*/
regex_constants::syntax_char, /*"*/
regex_constants::syntax_hash, /*#*/
regex_constants::syntax_dollar, /*$*/
regex_constants::syntax_char, /*%*/
regex_constants::syntax_char, /*&*/
regex_constants::syntax_char, /*'*/
regex_constants::syntax_open_mark, /*(*/
regex_constants::syntax_close_mark, /*)*/
regex_constants::syntax_star, /***/
regex_constants::syntax_plus, /*+*/
regex_constants::syntax_comma, /*,*/
regex_constants::syntax_dash, /*-*/
regex_constants::syntax_dot, /*.*/
regex_constants::syntax_char, /*/*/
regex_constants::syntax_digit, /*0*/
regex_constants::syntax_digit, /*1*/
regex_constants::syntax_digit, /*2*/
regex_constants::syntax_digit, /*3*/
regex_constants::syntax_digit, /*4*/
regex_constants::syntax_digit, /*5*/
regex_constants::syntax_digit, /*6*/
regex_constants::syntax_digit, /*7*/
regex_constants::syntax_digit, /*8*/
regex_constants::syntax_digit, /*9*/
regex_constants::syntax_colon, /*:*/
regex_constants::syntax_char, /*;*/
regex_constants::escape_type_left_word, /*<*/
regex_constants::syntax_equal, /*=*/
regex_constants::escape_type_right_word, /*>*/
regex_constants::syntax_question, /*?*/
regex_constants::syntax_char, /*@*/
regex_constants::syntax_char, /*A*/
regex_constants::syntax_char, /*B*/
regex_constants::syntax_char, /*C*/
regex_constants::syntax_char, /*D*/
regex_constants::syntax_char, /*E*/
regex_constants::syntax_char, /*F*/
regex_constants::syntax_char, /*G*/
regex_constants::syntax_char, /*H*/
regex_constants::syntax_char, /*I*/
regex_constants::syntax_char, /*J*/
regex_constants::syntax_char, /*K*/
regex_constants::syntax_char, /*L*/
regex_constants::syntax_char, /*M*/
regex_constants::syntax_char, /*N*/
regex_constants::syntax_char, /*O*/
regex_constants::syntax_char, /*P*/
regex_constants::syntax_char, /*Q*/
regex_constants::syntax_char, /*R*/
regex_constants::syntax_char, /*S*/
regex_constants::syntax_char, /*T*/
regex_constants::syntax_char, /*U*/
regex_constants::syntax_char, /*V*/
regex_constants::syntax_char, /*W*/
regex_constants::syntax_char, /*X*/
regex_constants::syntax_char, /*Y*/
regex_constants::syntax_char, /*Z*/
regex_constants::syntax_open_set, /*[*/
regex_constants::syntax_escape, /*\*/
regex_constants::syntax_close_set, /*]*/
regex_constants::syntax_caret, /*^*/
regex_constants::syntax_char, /*_*/
regex_constants::syntax_char, /*`*/
regex_constants::syntax_char, /*a*/
regex_constants::syntax_char, /*b*/
regex_constants::syntax_char, /*c*/
regex_constants::syntax_char, /*d*/
regex_constants::syntax_char, /*e*/
regex_constants::syntax_char, /*f*/
regex_constants::syntax_char, /*g*/
regex_constants::syntax_char, /*h*/
regex_constants::syntax_char, /*i*/
regex_constants::syntax_char, /*j*/
regex_constants::syntax_char, /*k*/
regex_constants::syntax_char, /*l*/
regex_constants::syntax_char, /*m*/
regex_constants::syntax_char, /*n*/
regex_constants::syntax_char, /*o*/
regex_constants::syntax_char, /*p*/
regex_constants::syntax_char, /*q*/
regex_constants::syntax_char, /*r*/
regex_constants::syntax_char, /*s*/
regex_constants::syntax_char, /*t*/
regex_constants::syntax_char, /*u*/
regex_constants::syntax_char, /*v*/
regex_constants::syntax_char, /*w*/
regex_constants::syntax_char, /*x*/
regex_constants::syntax_char, /*y*/
regex_constants::syntax_char, /*z*/
regex_constants::syntax_open_brace, /*{*/
regex_constants::syntax_or, /*|*/
regex_constants::syntax_close_brace, /*}*/
regex_constants::syntax_char, /*~*/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
regex_constants::syntax_char, /*<2A>*/
};
return char_syntax[(unsigned char)c];
}
} // re_detail
} // boost

View File

@ -114,9 +114,9 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wcha
result = static_cast<wregex*>(expression->guts)->error_code();
#ifndef BOOST_NO_EXCEPTIONS
}
catch(const boost::bad_expression& be)
catch(const boost::regex_error& be)
{
result = be.errorno();
result = be.code();
}
catch(...)
{
@ -168,18 +168,19 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int code, const regex_tW*
#endif
if(code <= REG_E_UNKNOWN)
{
regex_traits<wchar_t> rt;
const regex_traits<wchar_t>* pt = &rt;
if(e && (e->re_magic == wmagic_value))
pt = &static_cast<wregex*>(e->guts)->get_traits();
(void)pt; // warning suppression
std::string p = pt->error_string(code);
if(p.size() < buf_size)
std::string p;
if((e) && (e->re_magic == wmagic_value))
p = static_cast<wregex*>(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code));
else
{
std::copy(p.begin(), p.end(), buf);
buf[p.size()] = 0;
p = re_detail::get_default_error_string(static_cast< ::boost::regex_constants::error_type>(code));
}
return p.size() + 1;
std::size_t len = p.size();
if(len < buf_size)
{
std::copy(p.c_str(), p.c_str() + p.size() + 1, buf);
}
return len + 1;
}
if(buf_size)
*buf = 0;

View File

@ -9,84 +9,87 @@
*
*/
#include <cstdlib> // for abort
#include <boost/regex.hpp>
#if defined(BOOST_MSVC)
// this lets us compile at warning level 4 without seeing concept-check related warnings
# pragma warning(disable:4100)
#endif
#include <boost/concept_archetype.hpp>
#include <boost/concept_check.hpp>
#ifdef __BORLANDC__
#pragma option -w-8019 -w-8004 -w-8008
#endif
#include <boost/regex.hpp>
#include <boost/regex/concepts.hpp>
#include <boost/detail/workaround.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ using ::abort; }
#endif
boost::re_detail::digraph<boost::char_architype> get_next_set_literal();
int main()
{
// VC6 and VC7 can't cope with the iterator architypes,
// don't bother testing as it doesn't work:
#if !BOOST_WORKAROUND(_MSC_VER, < 1310)
typedef boost::bidirectional_iterator_archetype<char> iterator_type;
typedef boost::input_iterator_archetype<char> input_iterator_type;
input_iterator_type i, j;
#if!defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__GNUC__, < 3)
boost::regex r(i, j);
r.assign(i, j);
#else
boost::regex r;
#endif
iterator_type a, b;
boost::detail::dummy_constructor dummy;
boost::output_iterator_archetype<char> out(dummy);
std::string s;
boost::match_results<iterator_type> what;
boost::regex_match(a, b, r);
boost::regex_match(a, b, what, r);
boost::regex_search(a, b, r);
boost::regex_search(a, b, what, r);
out = boost::regex_replace(out, a, b, r, s, boost::match_default);
s = boost::regex_replace(s, r, s, boost::match_default);
out = what.format(out, s, boost::format_default);
s = what.format(s, boost::format_default);
#if !BOOST_WORKAROUND(_MSC_VER, < 1310) && !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__GNUC__, < 3)
boost::function_requires<
boost::ForwardIteratorConcept<
boost::regex_iterator<iterator_type>
boost::RegexTraitsConcept<
boost::regex_traits<char>
>
>();
// this fails with glibc++v2 :
#if !BOOST_WORKAROUND(__GNUC__, < 3) && !BOOST_WORKAROUND(BOOST_MSVC, <1300)
boost::function_requires<
boost::ForwardIteratorConcept<
boost::regex_token_iterator<iterator_type>
boost::BoostRegexConcept<
boost::basic_regex<char, boost::cpp_regex_traits<char> >
>
>();
#ifndef BOOST_NO_WREGEX
boost::function_requires<
boost::BoostRegexConcept<
boost::basic_regex<wchar_t, boost::cpp_regex_traits<wchar_t> >
>
>();
#endif
boost::function_requires<
boost::BoostRegexConcept<
boost::basic_regex<char, boost::c_regex_traits<char> >
>
>();
#ifndef BOOST_NO_WREGEX
boost::function_requires<
boost::BoostRegexConcept<
boost::basic_regex<wchar_t, boost::c_regex_traits<wchar_t> >
>
>();
#endif
boost::function_requires<
boost::RegexTraitsConcept<
boost::regex_traits<char>
>
>();
boost::function_requires<
boost::BoostRegexConcept<
boost::basic_regex<char, boost::w32_regex_traits<char> >
>
>();
#ifndef BOOST_NO_WREGEX
boost::function_requires<
boost::BoostRegexConcept<
boost::basic_regex<wchar_t, boost::w32_regex_traits<wchar_t> >
>
>();
#endif
//
// verify basic_regex member functions:
//
const char* c_exp = "abc";
r = c_exp;
r = r;
r = s;
if((r.mark_count()) || (0 == r.max_size()) || (r.empty()) || (0 == r.size()) || (r.begin() == r.end())) std::abort();
r.assign(r);
r.assign(c_exp);
r.assign(c_exp, boost::regex::perl);
r.assign(c_exp, 1, boost::regex::perl);
r.assign(s);
r.assign(s, boost::regex::perl);
r.assign(c_exp, c_exp+1);
r.assign(c_exp, c_exp+1, boost::regex::perl);
//
// now test the regex_traits concepts:
//
typedef boost::basic_regex<char, boost::regex_traits_architype<char> > regex_traits_tester_type1;
boost::function_requires<
boost::BoostRegexConcept<
regex_traits_tester_type1
>
>();
typedef boost::basic_regex<boost::char_architype, boost::regex_traits_architype<boost::char_architype> > regex_traits_tester_type2;
boost::function_requires<
boost::BaseRegexConcept<
regex_traits_tester_type2
>
>();
#endif
return 0;
}

View File

@ -1,71 +0,0 @@
/*
*
* Copyright (c) 2003
* Dr 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)
*
*/
#include <boost/regex.hpp>
#include <boost/concept_archetype.hpp>
#if defined(BOOST_MSVC)
// this lets us compile at warning level 4 without seeing concept-check related warnings
# pragma warning(disable:4100)
#endif
#include <boost/concept_check.hpp>
#include <boost/detail/workaround.hpp>
int main()
{
#ifndef BOOST_NO_WREGEX
// VC6 and VC7 can't cope with the iterator architypes,
// don't bother testing as it doesn't work:
#if !BOOST_WORKAROUND(_MSC_VER, < 1310)
typedef boost::bidirectional_iterator_archetype<wchar_t> iterator_type;
typedef boost::input_iterator_archetype<wchar_t> input_iterator_type;
input_iterator_type i, j;
#if!defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
boost::wregex r(i, j);
r.assign(i, j);
#else
boost::wregex r;
#endif
iterator_type a, b;
boost::detail::dummy_constructor dummy;
boost::output_iterator_archetype<wchar_t> out(dummy);
std::wstring s;
boost::match_results<iterator_type> what;
boost::regex_match(a, b, r);
boost::regex_match(a, b, what, r);
boost::regex_search(a, b, r);
boost::regex_search(a, b, what, r);
out = boost::regex_replace(out, a, b, r, s, boost::match_default);
s = boost::regex_replace(s, r, s, boost::match_default);
out = what.format(out, s, boost::format_default);
s = what.format(s, boost::format_default);
boost::function_requires<
boost::ForwardIteratorConcept<
boost::regex_iterator<iterator_type>
>
>();
// this fails with glibc++v2 :
#if !BOOST_WORKAROUND(__GNUC__, < 3) && !BOOST_WORKAROUND(BOOST_MSVC, <1300)
boost::function_requires<
boost::ForwardIteratorConcept<
boost::regex_token_iterator<iterator_type>
>
>();
#endif // GCC 2.x
#endif // MSVC 6
#endif // BOOST_NO_WREGEX
return 0;
}

View File

@ -15,8 +15,12 @@
template <class charT, class tagT>
void test(const charT& c, const tagT& tag)
{
boost::basic_regex<charT> e;
test(e, tag);
boost::basic_regex<charT, boost::cpp_regex_traits<charT> > e1;
test(e1, tag);
boost::basic_regex<charT, boost::c_regex_traits<charT> > e2;
test(e2, tag);
boost::basic_regex<charT, boost::w32_regex_traits<charT> > e3;
test(e3, tag);
// test old depecated code:
test_deprecated(c, tag);
}

View File

@ -229,7 +229,7 @@ void test_deprecated(const char&, const test_invalid_regex_tag&)
// OK try and compile the expression:
boost::regex_tA re;
if(regcompA(&re, expression.c_str(), posix_options) == 0)
if(boost::regcompA(&re, expression.c_str(), posix_options) == 0)
{
boost::regfreeA(&re);
BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" unexpectedly compiled with the POSIX C API.", char);
@ -281,7 +281,7 @@ void test_deprecated(const wchar_t&, const test_invalid_regex_tag&)
// OK try and compile the expression:
boost::regex_tW re;
if(regcompW(&re, expression.c_str(), posix_options) == 0)
if(boost::regcompW(&re, expression.c_str(), posix_options) == 0)
{
boost::regfreeW(&re);
BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" unexpectedly compiled with the POSIX C API.", wchar_t);

View File

@ -87,7 +87,7 @@ template<class charT, class traits>
void test_regex_iterator(boost::basic_regex<charT, traits>& r)
{
typedef typename std::basic_string<charT>::const_iterator const_iterator;
typedef boost::regex_iterator<const_iterator> test_iterator;
typedef boost::regex_iterator<const_iterator, charT, traits> test_iterator;
const std::basic_string<charT>& search_text = test_info<charT>::search_text();
boost::regex_constants::match_flag_type opts = test_info<charT>::match_options();
const int* answer_table = test_info<charT>::answer_table();