Subject: Re: [Boost-bugs] [Boost C++ Libraries] #12959: Regex class negation
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-04-11 22:36:06
#12959: Regex class negation
-------------------------------+-------------------------
Reporter: robic@⦠| Owner: johnmaddock
Type: Bugs | Status: new
Milestone: To Be Determined | Component: regex
Version: Boost 1.61.0 | Severity: Showstopper
Resolution: | Keywords:
-------------------------------+-------------------------
Comment (by robic@â¦):
A solution could be to keep a vector of individual class[[BR]]
instead of a mask for all classes ''cnclasses''[[BR]]
'''Only in a negated class, and only negative classes need to be
tracked.[[BR]]'''
The rest remains unchanged.
Something like this works (tested):[[BR]]
<boost\regex\v4\basic_regex_creator.hpp>[[BR]]
{{{
template <class charT, class traits>
class basic_char_set
{
private:
std::vector<unsigned __int64> m_NegNeg_Class;
public:
typedef typename std::vector<uint64_t>::const_iterator
cNNclass_list_iterator;
bool has_NegNegClasses()const
{
return m_NegNeg_Class.size() > 0 ? true : false;
}
cNNclass_list_iterator cn_begin()const
{
return m_NegNeg_Class.begin();
}
cNNclass_list_iterator cn_end()const
{
return m_NegNeg_Class.end();
}
void add_negated_class(m_type m)
{
if ( m_negate )
{
// if it's not already there, add it ..
bool bDoAdd = true;
for ( int i = 0; i < m_NegNeg_Class.size(); i++ )
{
if ( m_NegNeg_Class[i] == (unsigned __int64)m )
{
bDoAdd = false;
break;
}
}
if ( bDoAdd )
m_NegNeg_Class.insert( m_NegNeg_Class.end(), (unsigned
__int64)m );
}
else
m_negated_classes |= m;
m_empty = false;
}
}
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 typename basic_char_set<uint64_t, traits>::prop_list_iterator
cNegNegClas_item_iterator;
result->cNegNegClasses = 0;
if ( char_set.is_negated() )
{
result->cNegNegClasses =
static_cast<uint32_t>(::boost::BOOST_REGEX_DETAIL_NS::distance(char_set.cn_begin(),
char_set.cn_end()));
}
//
// now extend with all the negated negative character classes:
//
if ( result->isnot == true )
{
cNegNegClas_item_iterator cnfirst, cnlast;
cnfirst = char_set.cn_begin();
cnlast = char_set.cn_end();
while(cnfirst != cnlast)
{
uint64_t* p =
static_cast<uint64_t*>(this->m_pdata->m_data.extend(sizeof(uint64_t) *
1));
p[0] = *cnfirst;
if(flags() & regbase::icase)
{
// adjust class as needed:
if(((p[0] & m_lower_mask) == m_lower_mask) || ((p[0] &
m_upper_mask) == m_upper_mask))
p[0] |= m_alpha_mask;
}
++cnfirst;
}
}
}
}}}
<boost\regex\v4\perl_matcher.hpp>
{{{
template <class iterator, class charT, class traits_type, class
char_classT>
iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
iterator last,
const re_set_long<char_classT>* set_,
const regex_data<charT, traits_type>& e, bool
icase)
{
// try and match a single character from the neg-neg classes
if ( set_->cNegNegClasses && set_->isnot )
{
for(i = 0; i < set_->cNegNegClasses; i++)
{
uint64_t mask = *((uint64_t*)p);
if(traits_inst.isctype(col, (mask_type)mask) == false)
return set_->isnot ? next : ++next;
p += (sizeof(uint64_t*) / sizeof(charT));
}
}
// the rest unchanged
if( set_->cclasses != 0 )
{
if(traits_inst.isctype(col, set_->cclasses) == true)
return set_->isnot ? next : ++next;
}
if( set_->cnclasses != 0 )
{
if(traits_inst.isctype(col, set_->cnclasses) == false)
return set_->isnot ? next : ++next;
}
return set_->isnot ? ++next : next;
}
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/12959#comment:1> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-04-11 22:39:09 UTC