Skip to content
Merged
86 changes: 58 additions & 28 deletions stl/inc/regex
Original file line number Diff line number Diff line change
Expand Up @@ -228,34 +228,54 @@ struct _Lex_compare_memcmp_classify_pred<_Elem, _Elem, _Std_char_traits_lt<_Elem
: _Lex_compare_memcmp_classify_pred_for_std_char_traits_lt<_Elem> {};

template <class _RxTraits>
struct _Cmp_cs { // functor to compare two character values for equality
struct _Cmp_icase { // functor to compare for equality following case-insensitive translation of both characters
using _Elem = typename _RxTraits::char_type;
_STATIC_CALL_OPERATOR bool operator()(_Elem _Ex1, _Elem _Ex2) _CONST_CALL_OPERATOR {
return _Ex1 == _Ex2;

explicit _Cmp_icase(const _RxTraits& _Tr) noexcept : _Traits(_Tr) {}

bool operator()(_Elem _Ex1, _Elem _Ex2) const {
return _Traits.translate_nocase(_Ex1) == _Traits.translate_nocase(_Ex2);
}

const _RxTraits& _Traits;
};

template <class _RxTraits>
struct _Cmp_icase { // functor to compare for case-insensitive equality
struct _Cmp_collate { // functor to compare for equality following collating translation of both characters
using _Elem = typename _RxTraits::char_type;

explicit _Cmp_icase(const _RxTraits& _Tr) noexcept : _Traits(_Tr) {}
explicit _Cmp_collate(const _RxTraits& _Tr) noexcept : _Traits(_Tr) {}

bool operator()(_Elem _Ex1, _Elem _Ex2) const {
return _Traits.translate_nocase(_Ex1) == _Traits.translate_nocase(_Ex2);
return _Traits.translate(_Ex1) == _Traits.translate(_Ex2);
}

const _RxTraits& _Traits;
};

template <class _RxTraits>
struct _Cmp_collate { // functor to compare for locale-specific equality
struct _Cmp_icase_translateleft {
// functor to compare for equality following collating translation of the left character
using _Elem = typename _RxTraits::char_type;

explicit _Cmp_collate(const _RxTraits& _Tr) noexcept : _Traits(_Tr) {}
explicit _Cmp_icase_translateleft(const _RxTraits& _Tr) noexcept : _Traits(_Tr) {}

bool operator()(_Elem _Ex1, _Elem _Ex2) const {
return _Traits.translate(_Ex1) == _Traits.translate(_Ex2);
return _Traits.translate_nocase(_Ex1) == _Ex2;
}

const _RxTraits& _Traits;
};

template <class _RxTraits>
struct _Cmp_collate_translateleft {
// functor to compare for equality following collating translation of the left character
using _Elem = typename _RxTraits::char_type;

explicit _Cmp_collate_translateleft(const _RxTraits& _Tr) noexcept : _Traits(_Tr) {}

bool operator()(_Elem _Ex1, _Elem _Ex2) const {
return _Traits.translate(_Ex1) == _Ex2;
}

const _RxTraits& _Traits;
Expand Down Expand Up @@ -2933,10 +2953,6 @@ void _Builder2<_FwdIt, _Elem, _RxTraits>::_Add_class() { // add bracket expressi

template <class _FwdIt, class _Elem, class _RxTraits>
void _Builder2<_FwdIt, _Elem, _RxTraits>::_Add_char_to_bitmap(_Elem _Ch) { // add character to accelerator table
if (_Flags & regex_constants::icase) {
_Ch = _Traits.translate_nocase(_Ch);
}

_Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Current);

if (!_Node->_Small) {
Expand All @@ -2948,10 +2964,6 @@ void _Builder2<_FwdIt, _Elem, _RxTraits>::_Add_char_to_bitmap(_Elem _Ch) { // ad

template <class _FwdIt, class _Elem, class _RxTraits>
void _Builder2<_FwdIt, _Elem, _RxTraits>::_Add_char_to_array(_Elem _Ch) { // append character to character array
if (_Flags & regex_constants::icase) {
_Ch = _Traits.translate_nocase(_Ch);
}

_Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Current);
if (!_Node->_Large) {
_Node->_Large = new _Buf<_Elem>;
Expand All @@ -2962,6 +2974,12 @@ void _Builder2<_FwdIt, _Elem, _RxTraits>::_Add_char_to_array(_Elem _Ch) { // app

template <class _FwdIt, class _Elem, class _RxTraits>
void _Builder2<_FwdIt, _Elem, _RxTraits>::_Add_char_to_class(_Elem _Ch) { // add character to bracket expression
if (_Flags & regex_constants::icase) {
_Ch = _Traits.translate_nocase(_Ch);
} else if (_Flags & regex_constants::collate) {
_Ch = _Traits.translate(_Ch);
}

if (static_cast<typename _RxTraits::_Uelem>(_Ch) < _Bmp_max) {
_Add_char_to_bitmap(_Ch);
} else {
Expand Down Expand Up @@ -3607,23 +3625,33 @@ _BidIt1 _Cmp_chrange(_BidIt1 _Begin1, _BidIt1 _End1, _BidIt2 _Begin2, _BidIt2 _E
return _Res;
}
}

return _Begin2 == _End2 ? _Begin1 : _Res;
}

template <class _BidIt1, class _BidIt2, class _RxTraits>
_BidIt1 _Compare(_BidIt1 _Begin1, _BidIt1 _End1, _BidIt2 _Begin2, _BidIt2 _End2, const _RxTraits& _Traits,
regex_constants::syntax_option_type _Sflags) { // compare character ranges
_BidIt1 _Res = _End1;
_BidIt1 _Compare_translate_both(_BidIt1 _Begin1, _BidIt1 _End1, _BidIt2 _Begin2, _BidIt2 _End2,
const _RxTraits& _Traits, regex_constants::syntax_option_type _Sflags) {
// compare character ranges, translating characters in both ranges according to syntax options
if (_Sflags & regex_constants::icase) {
_Res = _Cmp_chrange(_Begin1, _End1, _Begin2, _End2, _Cmp_icase<_RxTraits>{_Traits});
return _STD _Cmp_chrange(_Begin1, _End1, _Begin2, _End2, _Cmp_icase<_RxTraits>{_Traits});
} else if (_Sflags & regex_constants::collate) {
_Res = _Cmp_chrange(_Begin1, _End1, _Begin2, _End2, _Cmp_collate<_RxTraits>{_Traits});
return _STD _Cmp_chrange(_Begin1, _End1, _Begin2, _End2, _Cmp_collate<_RxTraits>{_Traits});
} else {
_Res = _Cmp_chrange(_Begin1, _End1, _Begin2, _End2, _Cmp_cs<_RxTraits>{});
return _STD _Cmp_chrange(_Begin1, _End1, _Begin2, _End2, equal_to<typename _RxTraits::char_type>{});
}
}

return _Res;
template <class _BidIt1, class _BidIt2, class _RxTraits>
_BidIt1 _Compare_translate_left(_BidIt1 _Begin1, _BidIt1 _End1, _BidIt2 _Begin2, _BidIt2 _End2,
const _RxTraits& _Traits, regex_constants::syntax_option_type _Sflags) {
// compare character ranges, translating characters in the left range according to syntax options
if (_Sflags & regex_constants::icase) {
return _STD _Cmp_chrange(_Begin1, _End1, _Begin2, _End2, _Cmp_icase_translateleft<_RxTraits>{_Traits});
} else if (_Sflags & regex_constants::collate) {
return _STD _Cmp_chrange(_Begin1, _End1, _Begin2, _End2, _Cmp_collate_translateleft<_RxTraits>{_Traits});
} else {
return _STD _Cmp_chrange(_Begin1, _End1, _Begin2, _End2, equal_to<typename _RxTraits::char_type>{});
}
}

template <class _Elem>
Expand Down Expand Up @@ -3896,7 +3924,7 @@ bool _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Match_pat(_Node_base* _N
{ // check for string match
_Node_str<_Elem>* _Node = static_cast<_Node_str<_Elem>*>(_Nx);
_It _Res0;
if ((_Res0 = _Compare(_Tgt_state._Cur, _End, _Node->_Data._Str(),
if ((_Res0 = _STD _Compare_translate_left(_Tgt_state._Cur, _End, _Node->_Data._Str(),
_Node->_Data._Str() + _Node->_Data._Size(), _Traits, _Sflags))
!= _Tgt_state._Cur) {
_Tgt_state._Cur = _Res0;
Expand Down Expand Up @@ -3971,7 +3999,8 @@ bool _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Match_pat(_Node_base* _N
_It _Bx = _Tgt_state._Grps[_Node->_Idx]._Begin;
_It _Ex = _Tgt_state._Grps[_Node->_Idx]._End;
if (_Bx != _Ex // _Bx == _Ex for zero-length match
&& (_Res0 = _Compare(_Tgt_state._Cur, _End, _Bx, _Ex, _Traits, _Sflags)) == _Tgt_state._Cur) {
&& (_Res0 = _STD _Compare_translate_both(_Tgt_state._Cur, _End, _Bx, _Ex, _Traits, _Sflags))
== _Tgt_state._Cur) {
_Failed = true;
} else {
_Tgt_state._Cur = _Res0;
Expand Down Expand Up @@ -4084,7 +4113,8 @@ _BidIt _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Skip(_BidIt _First_arg
_Node_str<_Elem>* _Node = static_cast<_Node_str<_Elem>*>(_Nx);
for (; _First_arg != _Last; ++_First_arg) { // look for starting match
_BidIt _Next = _First_arg;
if (_Compare(_First_arg, ++_Next, _Node->_Data._Str(), _Node->_Data._Str() + 1, _Traits, _Sflags)
if (_STD _Compare_translate_left(
_First_arg, ++_Next, _Node->_Data._Str(), _Node->_Data._Str() + 1, _Traits, _Sflags)
!= _First_arg) {
break;
}
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ tests\GH_005315_destructor_tombstones
tests\GH_005402_string_with_volatile_range
tests\GH_005421_vector_algorithms_integer_class_type_iterator
tests\GH_005472_do_not_overlap
tests\GH_005553_regex_character_translation
tests\LWG2381_num_get_floating_point
tests\LWG2597_complex_branch_cut
tests\LWG3018_shared_ptr_function
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_matrix.lst
Loading