Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<functional>: Make default_searcher ADL-proof #4379

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 40 additions & 40 deletions stl/inc/functional
Original file line number Diff line number Diff line change
Expand Up @@ -2484,21 +2484,21 @@ public:
_CONSTEXPR20 default_searcher(_FwdItPat _First, _FwdItPat _Last, _Pred_eq _Eq = _Pred_eq())
: _Data{_One_then_variadic_args_t{}, _STD move(_Eq), pair<_FwdItPat, _FwdItPat>{_First, _Last}} {
const auto& _Pat = _Data._Myval2;
_Adl_verify_range(_Pat.first, _Pat.second);
_STD _Adl_verify_range(_Pat.first, _Pat.second);
}

template <class _FwdItHaystack>
_NODISCARD _CONSTEXPR20 pair<_FwdItHaystack, _FwdItHaystack> operator()(
_FwdItHaystack _First, _FwdItHaystack _Last) const {
// search [_First, _Last) for the searcher's pattern
_Adl_verify_range(_First, _Last);
_STD _Adl_verify_range(_First, _Last);
const auto& _Eq = _Data._Get_first();
const auto& _Pat = _Data._Myval2;
_Adl_verify_range(_Pat.first, _Pat.second); // check again to ensure container is not destroyed
const auto _Result = _Search_pair_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last),
_Get_unwrapped(_Pat.first), _Get_unwrapped(_Pat.second), _Eq);
_Seek_wrapped(_Last, _Result.second);
_Seek_wrapped(_First, _Result.first);
_STD _Adl_verify_range(_Pat.first, _Pat.second); // check again to ensure container is not destroyed
const auto _Result = _STD _Search_pair_unchecked(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last),
_STD _Get_unwrapped(_Pat.first), _STD _Get_unwrapped(_Pat.second), _Eq);
_STD _Seek_wrapped(_Last, _Result.second);
_STD _Seek_wrapped(_First, _Result.first);
return {_First, _Last};
}

Expand Down Expand Up @@ -2678,15 +2678,15 @@ pair<_RanItHaystack, _RanItHaystack> _Boyer_moore_search(
static_assert(is_same_v<typename _Delta1_t::_Value_t, _Iter_value_t<_RanItHaystack>>,
"boyer_moore_searcher requires matching iterator value types");
using _Diff = typename _Delta1_t::_Diff;
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
const auto _Pat_size = _Delta1._Pat_size;
if (_Pat_size == 0) {
return {_First, _First};
}

const auto _UPat_first = _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
const auto _UPat_first = _STD _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
const auto _Eq = _Delta1._Get_eq();
_Diff _Shift = _Pat_size - 1;
while (_Shift < _ULast - _UFirst) {
Expand All @@ -2696,8 +2696,8 @@ pair<_RanItHaystack, _RanItHaystack> _Boyer_moore_search(
_Diff _Idx = _Pat_size - 1;
do {
if (_Idx == 0) {
_Seek_wrapped(_Last, _UFirst + _Pat_size);
_Seek_wrapped(_First, _UFirst);
_STD _Seek_wrapped(_Last, _UFirst + _Pat_size);
_STD _Seek_wrapped(_First, _UFirst);
return {_First, _Last};
}

Expand All @@ -2708,8 +2708,8 @@ pair<_RanItHaystack, _RanItHaystack> _Boyer_moore_search(
}
}

_Seek_wrapped(_Last, _ULast);
_Seek_wrapped(_First, _ULast);
_STD _Seek_wrapped(_Last, _ULast);
_STD _Seek_wrapped(_First, _ULast);
return {_First, _Last};
}

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

auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
const auto _UPat_first = _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
const auto _UPat_first = _STD _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
const auto _Eq = _Delta1._Get_eq();
_Diff _Shift = _Pat_size - 1;
while (_Shift < _ULast - _UFirst) {
_UFirst += _Shift;
_Shift = _Delta1._Lookup(*_UFirst);
if (_Shift == 0) { // that is, *_UFirst == "_Pat.back()"
const auto _Candidate = _UFirst - (_Pat_size - 1);
if (_STD equal(_UPat_first, _UPat_first + (_Pat_size - 1), _Candidate, _Pass_fn(_Eq))) {
_Seek_wrapped(_Last, _Candidate + _Pat_size);
_Seek_wrapped(_First, _Candidate);
if (_STD equal(_UPat_first, _UPat_first + (_Pat_size - 1), _Candidate, _STD _Pass_fn(_Eq))) {
_STD _Seek_wrapped(_Last, _Candidate + _Pat_size);
_STD _Seek_wrapped(_First, _Candidate);
return {_First, _Last};
}

_Shift = 1;
}
}

_Seek_wrapped(_Last, _ULast);
_Seek_wrapped(_First, _ULast);
_STD _Seek_wrapped(_Last, _ULast);
_STD _Seek_wrapped(_First, _ULast);
return {_First, _Last};
}

Expand All @@ -2763,9 +2763,9 @@ struct _Single_delta1_type_boyer_moore_traits {
template <bool _Build_delta2>
static void* _Build_boyer_moore(_RanItPat _First, _RanItPat _Last, _Hash_ty _Hash_fn, _Pred_eq _Eq) {
// builds data tables for the Boyer-Moore string search algorithm
_Adl_verify_range(_First, _Last);
const auto _UFirst = _Get_unwrapped(_First);
const auto _Pat_size_raw = _Get_unwrapped(_Last) - _UFirst;
_STD _Adl_verify_range(_First, _Last);
const auto _UFirst = _STD _Get_unwrapped(_First);
const auto _Pat_size_raw = _STD _Get_unwrapped(_Last) - _UFirst;
using _CT = common_type_t<_Iter_diff_t<_RanItPat>, size_t>;
if (static_cast<_CT>(_Pat_size_raw) > static_cast<_CT>(SIZE_MAX)) {
_Xbad_alloc();
Expand All @@ -2784,7 +2784,7 @@ struct _Single_delta1_type_boyer_moore_traits {
*_Decode_aligned_block<_Atomic_counter_t>(_Buf) = 1;
void* const _Delta1 = _Decode_aligned_block<_Delta1_t>(_Buf);
if (_Build_delta2) {
_Build_boyer_moore_delta_2_table(
_STD _Build_boyer_moore_delta_2_table(
_Decode_aligned_block<_Diff>(_Buf, _Pat_size), _UFirst, _Pat_size_raw, _Eq);
}

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

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

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

if (_Build_delta2) {
equal_to<> _Eq;
_Build_boyer_moore_delta_2_table(
_STD _Build_boyer_moore_delta_2_table(
_Decode_aligned_block<_Diff>(_Buf, _Pat_size), _UFirst, _Pat_size_raw, _Eq);
}

Expand All @@ -2904,11 +2904,11 @@ struct _Boyer_moore_traits_wchar_t_mode {
if (*_Decode_aligned_block<bool>(_Data)) {
const auto _Delta1 = _Decode_aligned_block<_Big_table_t>(_Data);
const auto _Delta2 = _Decode_aligned_block<_Diff>(_Data, static_cast<size_t>(_Delta1->_Pat_size));
return _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
return _STD _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
} else {
const auto _Delta1 = _Decode_aligned_block<_Small_table_t>(_Data);
const auto _Delta2 = _Decode_aligned_block<_Diff>(_Data, static_cast<size_t>(_Delta1->_Pat_size));
return _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
return _STD _Boyer_moore_search(*_Delta1, _Delta2, _First, _Last);
}
}

Expand All @@ -2919,10 +2919,10 @@ struct _Boyer_moore_traits_wchar_t_mode {
(void) _Decode_aligned_block<_Atomic_counter_t>(_Data);
if (*_Decode_aligned_block<bool>(_Data)) {
const auto _Delta1 = _Decode_aligned_block<_Big_table_t>(_Data);
return _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
return _STD _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
} else {
const auto _Delta1 = _Decode_aligned_block<_Small_table_t>(_Data);
return _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
return _STD _Boyer_moore_horspool_search(*_Delta1, _First, _Last);
}
}

Expand Down Expand Up @@ -2977,7 +2977,7 @@ public:

boyer_moore_searcher& operator=(const boyer_moore_searcher& _Other) noexcept /* strengthened */ {
boyer_moore_searcher _Cpy(_Other);
swap(_Data, _Cpy._Data);
_STD swap(_Data, _Cpy._Data);
return *this;
}

Expand Down Expand Up @@ -3015,7 +3015,7 @@ public:

boyer_moore_horspool_searcher& operator=(const boyer_moore_horspool_searcher& _Other) noexcept /* strengthened */ {
boyer_moore_horspool_searcher _Cpy(_Other);
swap(_Data, _Cpy._Data);
_STD swap(_Data, _Cpy._Data);
return *this;
}

Expand Down
64 changes: 64 additions & 0 deletions tests/std/tests/P0220R1_searchers/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,70 @@ void test_case_randomized_cases() {
}
}

#ifndef _M_CEE // TRANSITION, VSO-1659496
template <class Tag, class T>
struct tagged_hash {
std::size_t operator()(const T& t) const {
return std::hash<T>{}(t);
}
};

template <class Tag>
struct tagged_equal {
template <class T, class U>
constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u)) {
return std::forward<T>(t) == std::forward<U>(u);
}
};

template <class T>
struct holder {
T t;
};

struct incomplete;

template <class T>
using validating_hash = tagged_hash<holder<incomplete>, T>;

using validating_equal = tagged_equal<holder<incomplete>>;

void test_adl_proof_default_searcher_on_iterators() {
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
using validator = holder<incomplete>*;
validator varr[1]{};
(void) std::search(varr, varr + 1, default_searcher<const validator*>{varr, varr + 1});
}

void test_adl_proof_default_searcher_on_functors() {
char carr[1]{};
(void) std::search(carr, carr + 1, default_searcher<const char*, validating_equal>{carr, carr + 1});

wchar_t wcarr[1]{};
(void) std::search(wcarr, wcarr + 1, default_searcher<const wchar_t*, validating_equal>{wcarr, wcarr + 1});

int iarr[1]{};
(void) std::search(iarr, iarr + 1, default_searcher<const int*, validating_equal>{iarr, iarr + 1});
}

template <template <class RanIt, class Hash, class PredEq> class Searcher>
void test_adl_proof_searcher_on_functors() {
char carr[1]{};
(void) std::search(carr, carr + 1, Searcher<const char*, validating_hash<char>, validating_equal>{carr, carr + 1});

wchar_t wcarr[1]{};
(void) std::search(
wcarr, wcarr + 1, Searcher<const wchar_t*, validating_hash<wchar_t>, validating_equal>{wcarr, wcarr + 1});

int iarr[1]{};
(void) std::search(iarr, iarr + 1, Searcher<const int*, validating_hash<int>, validating_equal>{iarr, iarr + 1});
}

void test_adl_proof_searcher_on_functors_all() {
test_adl_proof_searcher_on_functors<boyer_moore_searcher>();
test_adl_proof_searcher_on_functors<boyer_moore_horspool_searcher>();
}
#endif // ^^^ no workaround ^^^

int main() {
test_boyer_moore_table2_construction();

Expand Down