Skip to content

Commit c674bcb

Browse files
<functional>: Make default_searcher ADL-proof (#4379)
Co-authored-by: Stephan T. Lavavej <[email protected]>
1 parent 6682109 commit c674bcb

File tree

2 files changed

+104
-40
lines changed

2 files changed

+104
-40
lines changed

stl/inc/functional

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,21 +2484,21 @@ public:
24842484
_CONSTEXPR20 default_searcher(_FwdItPat _First, _FwdItPat _Last, _Pred_eq _Eq = _Pred_eq())
24852485
: _Data{_One_then_variadic_args_t{}, _STD move(_Eq), pair<_FwdItPat, _FwdItPat>{_First, _Last}} {
24862486
const auto& _Pat = _Data._Myval2;
2487-
_Adl_verify_range(_Pat.first, _Pat.second);
2487+
_STD _Adl_verify_range(_Pat.first, _Pat.second);
24882488
}
24892489

24902490
template <class _FwdItHaystack>
24912491
_NODISCARD _CONSTEXPR20 pair<_FwdItHaystack, _FwdItHaystack> operator()(
24922492
_FwdItHaystack _First, _FwdItHaystack _Last) const {
24932493
// search [_First, _Last) for the searcher's pattern
2494-
_Adl_verify_range(_First, _Last);
2494+
_STD _Adl_verify_range(_First, _Last);
24952495
const auto& _Eq = _Data._Get_first();
24962496
const auto& _Pat = _Data._Myval2;
2497-
_Adl_verify_range(_Pat.first, _Pat.second); // check again to ensure container is not destroyed
2498-
const auto _Result = _Search_pair_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last),
2499-
_Get_unwrapped(_Pat.first), _Get_unwrapped(_Pat.second), _Eq);
2500-
_Seek_wrapped(_Last, _Result.second);
2501-
_Seek_wrapped(_First, _Result.first);
2497+
_STD _Adl_verify_range(_Pat.first, _Pat.second); // check again to ensure container is not destroyed
2498+
const auto _Result = _STD _Search_pair_unchecked(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last),
2499+
_STD _Get_unwrapped(_Pat.first), _STD _Get_unwrapped(_Pat.second), _Eq);
2500+
_STD _Seek_wrapped(_Last, _Result.second);
2501+
_STD _Seek_wrapped(_First, _Result.first);
25022502
return {_First, _Last};
25032503
}
25042504

@@ -2678,15 +2678,15 @@ pair<_RanItHaystack, _RanItHaystack> _Boyer_moore_search(
26782678
static_assert(is_same_v<typename _Delta1_t::_Value_t, _Iter_value_t<_RanItHaystack>>,
26792679
"boyer_moore_searcher requires matching iterator value types");
26802680
using _Diff = typename _Delta1_t::_Diff;
2681-
_Adl_verify_range(_First, _Last);
2682-
auto _UFirst = _Get_unwrapped(_First);
2683-
const auto _ULast = _Get_unwrapped(_Last);
2681+
_STD _Adl_verify_range(_First, _Last);
2682+
auto _UFirst = _STD _Get_unwrapped(_First);
2683+
const auto _ULast = _STD _Get_unwrapped(_Last);
26842684
const auto _Pat_size = _Delta1._Pat_size;
26852685
if (_Pat_size == 0) {
26862686
return {_First, _First};
26872687
}
26882688

2689-
const auto _UPat_first = _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
2689+
const auto _UPat_first = _STD _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
26902690
const auto _Eq = _Delta1._Get_eq();
26912691
_Diff _Shift = _Pat_size - 1;
26922692
while (_Shift < _ULast - _UFirst) {
@@ -2696,8 +2696,8 @@ pair<_RanItHaystack, _RanItHaystack> _Boyer_moore_search(
26962696
_Diff _Idx = _Pat_size - 1;
26972697
do {
26982698
if (_Idx == 0) {
2699-
_Seek_wrapped(_Last, _UFirst + _Pat_size);
2700-
_Seek_wrapped(_First, _UFirst);
2699+
_STD _Seek_wrapped(_Last, _UFirst + _Pat_size);
2700+
_STD _Seek_wrapped(_First, _UFirst);
27012701
return {_First, _Last};
27022702
}
27032703

@@ -2708,8 +2708,8 @@ pair<_RanItHaystack, _RanItHaystack> _Boyer_moore_search(
27082708
}
27092709
}
27102710

2711-
_Seek_wrapped(_Last, _ULast);
2712-
_Seek_wrapped(_First, _ULast);
2711+
_STD _Seek_wrapped(_Last, _ULast);
2712+
_STD _Seek_wrapped(_First, _ULast);
27132713
return {_First, _Last};
27142714
}
27152715

@@ -2719,34 +2719,34 @@ pair<_RanItHaystack, _RanItHaystack> _Boyer_moore_horspool_search(
27192719
static_assert(is_same_v<typename _Delta1_t::_Value_t, _Iter_value_t<_RanItHaystack>>,
27202720
"boyer_moore_horspool_searcher requires matching iterator value types");
27212721
using _Diff = typename _Delta1_t::_Diff;
2722-
_Adl_verify_range(_First, _Last);
2722+
_STD _Adl_verify_range(_First, _Last);
27232723
const auto _Pat_size = _Delta1._Pat_size;
27242724
if (_Pat_size == 0) {
27252725
return {_First, _First};
27262726
}
27272727

2728-
auto _UFirst = _Get_unwrapped(_First);
2729-
const auto _ULast = _Get_unwrapped(_Last);
2730-
const auto _UPat_first = _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
2728+
auto _UFirst = _STD _Get_unwrapped(_First);
2729+
const auto _ULast = _STD _Get_unwrapped(_Last);
2730+
const auto _UPat_first = _STD _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
27312731
const auto _Eq = _Delta1._Get_eq();
27322732
_Diff _Shift = _Pat_size - 1;
27332733
while (_Shift < _ULast - _UFirst) {
27342734
_UFirst += _Shift;
27352735
_Shift = _Delta1._Lookup(*_UFirst);
27362736
if (_Shift == 0) { // that is, *_UFirst == "_Pat.back()"
27372737
const auto _Candidate = _UFirst - (_Pat_size - 1);
2738-
if (_STD equal(_UPat_first, _UPat_first + (_Pat_size - 1), _Candidate, _Pass_fn(_Eq))) {
2739-
_Seek_wrapped(_Last, _Candidate + _Pat_size);
2740-
_Seek_wrapped(_First, _Candidate);
2738+
if (_STD equal(_UPat_first, _UPat_first + (_Pat_size - 1), _Candidate, _STD _Pass_fn(_Eq))) {
2739+
_STD _Seek_wrapped(_Last, _Candidate + _Pat_size);
2740+
_STD _Seek_wrapped(_First, _Candidate);
27412741
return {_First, _Last};
27422742
}
27432743

27442744
_Shift = 1;
27452745
}
27462746
}
27472747

2748-
_Seek_wrapped(_Last, _ULast);
2749-
_Seek_wrapped(_First, _ULast);
2748+
_STD _Seek_wrapped(_Last, _ULast);
2749+
_STD _Seek_wrapped(_First, _ULast);
27502750
return {_First, _Last};
27512751
}
27522752

@@ -2763,9 +2763,9 @@ struct _Single_delta1_type_boyer_moore_traits {
27632763
template <bool _Build_delta2>
27642764
static void* _Build_boyer_moore(_RanItPat _First, _RanItPat _Last, _Hash_ty _Hash_fn, _Pred_eq _Eq) {
27652765
// builds data tables for the Boyer-Moore string search algorithm
2766-
_Adl_verify_range(_First, _Last);
2767-
const auto _UFirst = _Get_unwrapped(_First);
2768-
const auto _Pat_size_raw = _Get_unwrapped(_Last) - _UFirst;
2766+
_STD _Adl_verify_range(_First, _Last);
2767+
const auto _UFirst = _STD _Get_unwrapped(_First);
2768+
const auto _Pat_size_raw = _STD _Get_unwrapped(_Last) - _UFirst;
27692769
using _CT = common_type_t<_Iter_diff_t<_RanItPat>, size_t>;
27702770
if (static_cast<_CT>(_Pat_size_raw) > static_cast<_CT>(SIZE_MAX)) {
27712771
_Xbad_alloc();
@@ -2784,7 +2784,7 @@ struct _Single_delta1_type_boyer_moore_traits {
27842784
*_Decode_aligned_block<_Atomic_counter_t>(_Buf) = 1;
27852785
void* const _Delta1 = _Decode_aligned_block<_Delta1_t>(_Buf);
27862786
if (_Build_delta2) {
2787-
_Build_boyer_moore_delta_2_table(
2787+
_STD _Build_boyer_moore_delta_2_table(
27882788
_Decode_aligned_block<_Diff>(_Buf, _Pat_size), _UFirst, _Pat_size_raw, _Eq);
27892789
}
27902790

@@ -2799,7 +2799,7 @@ struct _Single_delta1_type_boyer_moore_traits {
27992799
(void) _Decode_aligned_block<_Atomic_counter_t>(_Data);
28002800
const auto _Delta1 = _Decode_aligned_block<_Delta1_t>(_Data);
28012801
const auto _Delta2 = _Decode_aligned_block<_Diff>(_Data, static_cast<size_t>(_Delta1->_Pat_size));
2802-
return _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
2802+
return _STD _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
28032803
}
28042804

28052805
template <class _RanItHaystack>
@@ -2808,7 +2808,7 @@ struct _Single_delta1_type_boyer_moore_traits {
28082808
// decodes data tables for the Boyer-Moore string search algorithm
28092809
(void) _Decode_aligned_block<_Atomic_counter_t>(_Data);
28102810
const auto _Delta1 = _Decode_aligned_block<_Delta1_t>(_Data);
2811-
return _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
2811+
return _STD _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
28122812
}
28132813

28142814
static void _Destroy(void* const _Base) noexcept {
@@ -2841,9 +2841,9 @@ struct _Boyer_moore_traits_wchar_t_mode {
28412841
template <bool _Build_delta2>
28422842
static void* _Build_boyer_moore(_RanItPat _First, _RanItPat _Last, _Unused_parameter, _Unused_parameter) {
28432843
// builds data tables for the Boyer-Moore string search algorithm
2844-
_Adl_verify_range(_First, _Last);
2845-
const auto _UFirst = _Get_unwrapped(_First);
2846-
const auto _ULast = _Get_unwrapped(_Last);
2844+
_STD _Adl_verify_range(_First, _Last);
2845+
const auto _UFirst = _STD _Get_unwrapped(_First);
2846+
const auto _ULast = _STD _Get_unwrapped(_Last);
28472847
const auto _Pat_size_raw = _ULast - _UFirst;
28482848
using _CT = common_type_t<_Iter_diff_t<_RanItPat>, size_t>;
28492849
if (static_cast<_CT>(_Pat_size_raw) > static_cast<_CT>(SIZE_MAX)) {
@@ -2889,7 +2889,7 @@ struct _Boyer_moore_traits_wchar_t_mode {
28892889

28902890
if (_Build_delta2) {
28912891
equal_to<> _Eq;
2892-
_Build_boyer_moore_delta_2_table(
2892+
_STD _Build_boyer_moore_delta_2_table(
28932893
_Decode_aligned_block<_Diff>(_Buf, _Pat_size), _UFirst, _Pat_size_raw, _Eq);
28942894
}
28952895

@@ -2904,11 +2904,11 @@ struct _Boyer_moore_traits_wchar_t_mode {
29042904
if (*_Decode_aligned_block<bool>(_Data)) {
29052905
const auto _Delta1 = _Decode_aligned_block<_Big_table_t>(_Data);
29062906
const auto _Delta2 = _Decode_aligned_block<_Diff>(_Data, static_cast<size_t>(_Delta1->_Pat_size));
2907-
return _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
2907+
return _STD _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
29082908
} else {
29092909
const auto _Delta1 = _Decode_aligned_block<_Small_table_t>(_Data);
29102910
const auto _Delta2 = _Decode_aligned_block<_Diff>(_Data, static_cast<size_t>(_Delta1->_Pat_size));
2911-
return _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
2911+
return _STD _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
29122912
}
29132913
}
29142914

@@ -2919,10 +2919,10 @@ struct _Boyer_moore_traits_wchar_t_mode {
29192919
(void) _Decode_aligned_block<_Atomic_counter_t>(_Data);
29202920
if (*_Decode_aligned_block<bool>(_Data)) {
29212921
const auto _Delta1 = _Decode_aligned_block<_Big_table_t>(_Data);
2922-
return _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
2922+
return _STD _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
29232923
} else {
29242924
const auto _Delta1 = _Decode_aligned_block<_Small_table_t>(_Data);
2925-
return _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
2925+
return _STD _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
29262926
}
29272927
}
29282928

@@ -2977,7 +2977,7 @@ public:
29772977

29782978
boyer_moore_searcher& operator=(const boyer_moore_searcher& _Other) noexcept /* strengthened */ {
29792979
boyer_moore_searcher _Cpy(_Other);
2980-
swap(_Data, _Cpy._Data);
2980+
_STD swap(_Data, _Cpy._Data);
29812981
return *this;
29822982
}
29832983

@@ -3015,7 +3015,7 @@ public:
30153015

30163016
boyer_moore_horspool_searcher& operator=(const boyer_moore_horspool_searcher& _Other) noexcept /* strengthened */ {
30173017
boyer_moore_horspool_searcher _Cpy(_Other);
3018-
swap(_Data, _Cpy._Data);
3018+
_STD swap(_Data, _Cpy._Data);
30193019
return *this;
30203020
}
30213021

tests/std/tests/P0220R1_searchers/test.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,70 @@ void test_case_randomized_cases() {
437437
}
438438
}
439439

440+
#ifndef _M_CEE // TRANSITION, VSO-1659496
441+
template <class Tag, class T>
442+
struct tagged_hash {
443+
std::size_t operator()(const T& t) const {
444+
return std::hash<T>{}(t);
445+
}
446+
};
447+
448+
template <class Tag>
449+
struct tagged_equal {
450+
template <class T, class U>
451+
constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u)) {
452+
return std::forward<T>(t) == std::forward<U>(u);
453+
}
454+
};
455+
456+
template <class T>
457+
struct holder {
458+
T t;
459+
};
460+
461+
struct incomplete;
462+
463+
template <class T>
464+
using validating_hash = tagged_hash<holder<incomplete>, T>;
465+
466+
using validating_equal = tagged_equal<holder<incomplete>>;
467+
468+
void test_adl_proof_default_searcher_on_iterators() { // COMPILE-ONLY
469+
using validator = holder<incomplete>*;
470+
validator varr[1]{};
471+
(void) std::search(varr, varr + 1, default_searcher<const validator*>{varr, varr + 1});
472+
}
473+
474+
void test_adl_proof_default_searcher_on_functors() { // COMPILE-ONLY
475+
char carr[1]{};
476+
(void) std::search(carr, carr + 1, default_searcher<const char*, validating_equal>{carr, carr + 1});
477+
478+
wchar_t wcarr[1]{};
479+
(void) std::search(wcarr, wcarr + 1, default_searcher<const wchar_t*, validating_equal>{wcarr, wcarr + 1});
480+
481+
int iarr[1]{};
482+
(void) std::search(iarr, iarr + 1, default_searcher<const int*, validating_equal>{iarr, iarr + 1});
483+
}
484+
485+
template <template <class RanIt, class Hash, class PredEq> class Searcher>
486+
void test_adl_proof_searcher_on_functors() { // COMPILE-ONLY
487+
char carr[1]{};
488+
(void) std::search(carr, carr + 1, Searcher<const char*, validating_hash<char>, validating_equal>{carr, carr + 1});
489+
490+
wchar_t wcarr[1]{};
491+
(void) std::search(
492+
wcarr, wcarr + 1, Searcher<const wchar_t*, validating_hash<wchar_t>, validating_equal>{wcarr, wcarr + 1});
493+
494+
int iarr[1]{};
495+
(void) std::search(iarr, iarr + 1, Searcher<const int*, validating_hash<int>, validating_equal>{iarr, iarr + 1});
496+
}
497+
498+
void test_adl_proof_searcher_on_functors_all() { // COMPILE-ONLY
499+
test_adl_proof_searcher_on_functors<boyer_moore_searcher>();
500+
test_adl_proof_searcher_on_functors<boyer_moore_horspool_searcher>();
501+
}
502+
#endif // ^^^ no workaround ^^^
503+
440504
int main() {
441505
test_boyer_moore_table2_construction();
442506

0 commit comments

Comments
 (0)