@@ -1721,7 +1721,7 @@ public:
1721
1721
1722
1722
private:
1723
1723
// lexing
1724
- void _Error(regex_constants::error_type);
1724
+ [[noreturn]] void _Error(regex_constants::error_type);
1725
1725
1726
1726
bool _Is_esc() const;
1727
1727
void _Trans();
@@ -2912,7 +2912,8 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range2(const _Elem _Arg0, const _E
2912
2912
2913
2913
_Node->_Small->_Mark(_Ex0);
2914
2914
}
2915
- if (_Ex1 >= _Ex0) {
2915
+
2916
+ if ((_Flags & regex_constants::collate) || _Ex1 >= _Ex0) {
2916
2917
if (_Ex1 - _Ex0 < _Get_tmax()) {
2917
2918
for (; _Ex0 <= _Ex1; ++_Ex0) {
2918
2919
_Add_char_to_array(static_cast<_Elem>(_Ex0));
@@ -3364,6 +3365,20 @@ bool _Lookup_range(unsigned int _Ch, const _Buf<_Elem>* _Bufptr) { // check whet
3364
3365
return false;
3365
3366
}
3366
3367
3368
+ template <class _Elem, class _RxTraits>
3369
+ bool _Lookup_collating_range(const _Elem _Ch, const _Buf<_Elem>* const _Bufptr, const _RxTraits& _Traits) {
3370
+ const typename _RxTraits::string_type _Str = _Traits.transform(_STD addressof(_Ch), _STD addressof(_Ch) + 1);
3371
+ for (unsigned int _Ix = 0; _Ix < _Bufptr->_Size(); _Ix += 2) { // check current position
3372
+ const _Elem _Left = _Bufptr->_At(_Ix);
3373
+ const _Elem _Right = _Bufptr->_At(_Ix + 1);
3374
+ if (_Traits.transform(_STD addressof(_Left), _STD addressof(_Left) + 1) <= _Str
3375
+ && _Str <= _Traits.transform(_STD addressof(_Right), _STD addressof(_Right) + 1)) {
3376
+ return true;
3377
+ }
3378
+ }
3379
+ return false;
3380
+ }
3381
+
3367
3382
template <class _Elem, class _RxTraits>
3368
3383
bool _Lookup_equiv(typename _RxTraits::_Uelem _Ch, const _Sequence<_Elem>* _Eq, const _RxTraits& _Traits) {
3369
3384
// check whether _Ch is in _Eq
@@ -3407,35 +3422,36 @@ _BidIt _Lookup_coll(_BidIt _First, _BidIt _Last, const _Sequence<_Elem>* _Eq) {
3407
3422
template <class _BidIt, class _Elem, class _RxTraits, class _It>
3408
3423
bool _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Do_class(_Node_base* _Nx) { // apply bracket expression
3409
3424
bool _Found;
3410
- auto _Ch = static_cast<typename _RxTraits::_Uelem>( *_Tgt_state._Cur) ;
3425
+ _Elem _Ch = *_Tgt_state._Cur;
3411
3426
if (_Sflags & regex_constants::icase) {
3412
- _Ch = static_cast<typename _RxTraits::_Uelem>(_Traits.translate_nocase(static_cast<_Elem>(_Ch)));
3427
+ _Ch = _Traits.translate_nocase(_Ch);
3428
+ } else if (_Sflags & regex_constants::collate) {
3429
+ _Ch = _Traits.translate(_Ch);
3413
3430
}
3431
+ const auto _UCh = static_cast<typename _RxTraits::_Uelem>(_Ch);
3414
3432
3415
3433
_It _Res0 = _Tgt_state._Cur;
3416
3434
++_Res0;
3417
3435
_It _Resx;
3418
3436
_Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Nx);
3419
3437
if (_Node->_Coll
3420
- && (_Resx = _Lookup_coll(_Tgt_state._Cur, _End, _Node->_Coll))
3438
+ && (_Resx = _STD _Lookup_coll(_Tgt_state._Cur, _End, _Node->_Coll))
3421
3439
!= _Tgt_state._Cur) { // check for collation element
3422
3440
_Res0 = _Resx;
3423
3441
_Found = true;
3424
3442
} else if (_Node->_Ranges
3425
- && (_Lookup_range(static_cast<typename _RxTraits::_Uelem>(
3426
- _Sflags & regex_constants::collate ? _Traits.translate(static_cast<_Elem>(_Ch))
3427
- : static_cast<_Elem>(_Ch)),
3428
- _Node->_Ranges))) {
3443
+ && (_Sflags & regex_constants::collate ? _STD _Lookup_collating_range(_Ch, _Node->_Ranges, _Traits)
3444
+ : _STD _Lookup_range(_UCh, _Node->_Ranges))) {
3429
3445
_Found = true;
3430
- } else if (_Ch < _Bmp_max) {
3431
- _Found = _Node->_Small && _Node->_Small->_Find(_Ch );
3446
+ } else if (_UCh < _Bmp_max) {
3447
+ _Found = _Node->_Small && _Node->_Small->_Find(_UCh );
3432
3448
} else if (_Node->_Large
3433
3449
&& _STD find(_Node->_Large->_Str(), _Node->_Large->_Str() + _Node->_Large->_Size(), _Ch)
3434
3450
!= _Node->_Large->_Str() + _Node->_Large->_Size()) {
3435
3451
_Found = true;
3436
- } else if (_Node->_Classes != 0 && _Traits.isctype(static_cast<_Elem>( _Ch) , _Node->_Classes)) {
3452
+ } else if (_Node->_Classes != typename _RxTraits::char_class_type{} && _Traits.isctype(_Ch, _Node->_Classes)) {
3437
3453
_Found = true;
3438
- } else if (_Node->_Equiv && _Lookup_equiv(_Ch , _Node->_Equiv, _Traits)) {
3454
+ } else if (_Node->_Equiv && _STD _Lookup_equiv(_UCh , _Node->_Equiv, _Traits)) {
3439
3455
_Found = true;
3440
3456
} else {
3441
3457
_Found = false;
@@ -3762,34 +3778,36 @@ _BidIt _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Skip(_BidIt _First_arg, _BidIt
3762
3778
case _N_class:
3763
3779
{ // check for string match
3764
3780
for (; _First_arg != _Last; ++_First_arg) { // look for starting match
3765
- using _Uelem = typename _RxTraits::_Uelem;
3766
3781
bool _Found;
3767
- auto _Ch = static_cast<_Uelem>(*_First_arg);
3782
+ _Elem _Ch = *_First_arg;
3783
+ if (_Sflags & regex_constants::icase) {
3784
+ _Ch = _Traits.translate_nocase(_Ch);
3785
+ } else if (_Sflags & regex_constants::collate) {
3786
+ _Ch = _Traits.translate(_Ch);
3787
+ }
3788
+ const auto _UCh = static_cast<typename _RxTraits::_Uelem>(_Ch);
3789
+
3768
3790
_Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Nx);
3769
3791
_It _Next = _First_arg;
3770
3792
++_Next;
3771
3793
3772
- if (_Sflags & regex_constants::icase) {
3773
- _Ch = static_cast<_Uelem>(_Traits.translate_nocase(static_cast<_Elem>(_Ch)));
3774
- }
3775
-
3776
- if (_Node->_Coll && _Lookup_coll(_First_arg, _Next, _Node->_Coll) != _First_arg) {
3794
+ if (_Node->_Coll && _STD _Lookup_coll(_First_arg, _Next, _Node->_Coll) != _First_arg) {
3777
3795
_Found = true;
3778
3796
} else if (_Node->_Ranges
3779
- && (_Lookup_range(static_cast<_Uelem>(_Sflags & regex_constants::collate
3780
- ? _Traits.translate(static_cast<_Elem>(_Ch))
3781
- : static_cast<_Elem>(_Ch)),
3782
- _Node->_Ranges))) {
3797
+ && (_Sflags & regex_constants::collate
3798
+ ? _STD _Lookup_collating_range(_Ch, _Node->_Ranges, _Traits)
3799
+ : _STD _Lookup_range(_UCh, _Node->_Ranges))) {
3783
3800
_Found = true;
3784
- } else if (_Ch < _Bmp_max) {
3785
- _Found = _Node->_Small && _Node->_Small->_Find(_Ch );
3801
+ } else if (_UCh < _Bmp_max) {
3802
+ _Found = _Node->_Small && _Node->_Small->_Find(_UCh );
3786
3803
} else if (_Node->_Large
3787
3804
&& _STD find(_Node->_Large->_Str(), _Node->_Large->_Str() + _Node->_Large->_Size(), _Ch)
3788
3805
!= _Node->_Large->_Str() + _Node->_Large->_Size()) {
3789
3806
_Found = true;
3790
- } else if (_Node->_Classes && _Traits.isctype(static_cast<_Elem>(_Ch), _Node->_Classes)) {
3807
+ } else if (_Node->_Classes != typename _RxTraits::char_class_type{}
3808
+ && _Traits.isctype(_Ch, _Node->_Classes)) {
3791
3809
_Found = true;
3792
- } else if (_Node->_Equiv && _Lookup_equiv(_Ch , _Node->_Equiv, _Traits)) {
3810
+ } else if (_Node->_Equiv && _STD _Lookup_equiv(_UCh , _Node->_Equiv, _Traits)) {
3793
3811
_Found = true;
3794
3812
} else {
3795
3813
_Found = false;
@@ -3858,7 +3876,7 @@ _BidIt _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Skip(_BidIt _First_arg, _BidIt
3858
3876
}
3859
3877
3860
3878
template <class _FwdIt, class _Elem, class _RxTraits>
3861
- void _Parser<_FwdIt, _Elem, _RxTraits>::_Error(regex_constants::error_type _Code) { // handle error
3879
+ [[noreturn]] void _Parser<_FwdIt, _Elem, _RxTraits>::_Error(regex_constants::error_type _Code) { // handle error
3862
3880
_Xregex_error(_Code);
3863
3881
}
3864
3882
@@ -4171,7 +4189,14 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_ClassRanges() { // check for valid clas
4171
4189
_Chr2 = _Traits.translate(_Chr2);
4172
4190
}
4173
4191
4174
- if (static_cast<typename _RxTraits::_Uelem>(_Chr2) < static_cast<typename _RxTraits::_Uelem>(_Chr1)) {
4192
+ if (_Flags & regex_constants::collate) {
4193
+ const _Elem* const _Chr1_ptr = _STD addressof(_Chr1);
4194
+ const _Elem* const _Chr2_ptr = _STD addressof(_Chr2);
4195
+ if (_Traits.transform(_Chr2_ptr, _Chr2_ptr + 1) < _Traits.transform(_Chr1_ptr, _Chr1_ptr + 1)) {
4196
+ _Error(regex_constants::error_range);
4197
+ }
4198
+ } else if (static_cast<typename _RxTraits::_Uelem>(_Chr2)
4199
+ < static_cast<typename _RxTraits::_Uelem>(_Chr1)) {
4175
4200
_Error(regex_constants::error_range);
4176
4201
}
4177
4202
0 commit comments