@@ -79,6 +79,11 @@ __declspec(noalias) void __stdcall __std_replace_4(
79
79
void* _First, void* _Last, uint32_t _Old_val, uint32_t _New_val) noexcept;
80
80
__declspec(noalias) void __stdcall __std_replace_8(
81
81
void* _First, void* _Last, uint64_t _Old_val, uint64_t _New_val) noexcept;
82
+
83
+ void* __stdcall __std_unique_1(void* _First, void* _Last) noexcept;
84
+ void* __stdcall __std_unique_2(void* _First, void* _Last) noexcept;
85
+ void* __stdcall __std_unique_4(void* _First, void* _Last) noexcept;
86
+ void* __stdcall __std_unique_8(void* _First, void* _Last) noexcept;
82
87
} // extern "C"
83
88
84
89
_STD_BEGIN
@@ -205,6 +210,21 @@ __declspec(noalias) void _Replace_vectorized(
205
210
}
206
211
}
207
212
213
+ template <class _Ty>
214
+ _Ty* _Unique_vectorized(_Ty* const _First, _Ty* const _Last) noexcept {
215
+ if constexpr (sizeof(_Ty) == 1) {
216
+ return reinterpret_cast<_Ty*>(::__std_unique_1(_First, _Last));
217
+ } else if constexpr (sizeof(_Ty) == 2) {
218
+ return reinterpret_cast<_Ty*>(::__std_unique_2(_First, _Last));
219
+ } else if constexpr (sizeof(_Ty) == 4) {
220
+ return reinterpret_cast<_Ty*>(::__std_unique_4(_First, _Last));
221
+ } else if constexpr (sizeof(_Ty) == 8) {
222
+ return reinterpret_cast<_Ty*>(::__std_unique_8(_First, _Last));
223
+ } else {
224
+ _STL_INTERNAL_STATIC_ASSERT(false); // Unexpected size
225
+ }
226
+ }
227
+
208
228
// Can we activate the vector algorithms for find_first_of?
209
229
template <class _It1, class _It2, class _Pr>
210
230
constexpr bool _Vector_alg_in_find_first_of_is_safe = _Equal_memcmp_is_safe<_It1, _It2, _Pr>;
@@ -219,6 +239,10 @@ template <class _Iter, class _Ty1, class _Ty2>
219
239
constexpr bool _Vector_alg_in_ranges_replace_is_safe =
220
240
_Vector_alg_in_replace_is_safe<_Iter, _Ty1> // can search and replace
221
241
&& _Vector_alg_in_find_is_safe_elem<_Ty2, _Iter_value_t<_Iter>>; // replacement fits
242
+
243
+ // Can we activate the vector algorithms for unique?
244
+ template <class _Iter, class _Pr>
245
+ constexpr bool _Vector_alg_in_unique_is_safe = _Equal_memcmp_is_safe<_Iter, _Iter, _Pr>;
222
246
_STD_END
223
247
#endif // _USE_STD_VECTOR_ALGORITHMS
224
248
@@ -4869,6 +4893,25 @@ _NODISCARD_UNIQUE_ALG _CONSTEXPR20 _FwdIt unique(_FwdIt _First, _FwdIt _Last, _P
4869
4893
_STD _Adl_verify_range(_First, _Last);
4870
4894
auto _UFirst = _STD _Get_unwrapped(_First);
4871
4895
const auto _ULast = _STD _Get_unwrapped(_Last);
4896
+
4897
+ #if _USE_STD_VECTOR_ALGORITHMS
4898
+ if constexpr (_Vector_alg_in_unique_is_safe<decltype(_UFirst), _Pr>) {
4899
+ if (!_STD _Is_constant_evaluated()) {
4900
+ const auto _First_ptr = _STD _To_address(_UFirst);
4901
+ const auto _Result = _STD _Unique_vectorized(_First_ptr, _STD _To_address(_ULast));
4902
+
4903
+ if constexpr (is_pointer_v<decltype(_UFirst)>) {
4904
+ _UFirst = _Result;
4905
+ } else {
4906
+ _UFirst += _Result - _First_ptr;
4907
+ }
4908
+
4909
+ _STD _Seek_wrapped(_Last, _UFirst);
4910
+ return _Last;
4911
+ }
4912
+ }
4913
+ #endif // _USE_STD_VECTOR_ALGORITHMS
4914
+
4872
4915
if (_UFirst != _ULast) {
4873
4916
for (auto _UFirstb = _UFirst; ++_UFirst != _ULast; _UFirstb = _UFirst) {
4874
4917
if (_Pred(*_UFirstb, *_UFirst)) { // copy down
@@ -4945,6 +4988,24 @@ namespace ranges {
4945
4988
_STL_INTERNAL_STATIC_ASSERT(sentinel_for<_Se, _It>);
4946
4989
_STL_INTERNAL_STATIC_ASSERT(indirect_equivalence_relation<_Pr, projected<_It, _Pj>>);
4947
4990
4991
+ #if _USE_STD_VECTOR_ALGORITHMS
4992
+ if constexpr (is_same_v<_Pj, identity> && sized_sentinel_for<_Se, _It>
4993
+ && _Vector_alg_in_unique_is_safe<_It, _Pr>) {
4994
+ if (!_STD is_constant_evaluated()) {
4995
+ const auto _Size = _Last - _First;
4996
+ const auto _First_ptr = _STD to_address(_First);
4997
+ const auto _Last_ptr = _First_ptr + static_cast<size_t>(_Size);
4998
+ const auto _Result = _STD _Unique_vectorized(_First_ptr, _Last_ptr);
4999
+
5000
+ if constexpr (is_pointer_v<_It>) {
5001
+ return {_Result, _Last_ptr};
5002
+ } else {
5003
+ return {_First + (_Result - _First_ptr), _First + _Size};
5004
+ }
5005
+ }
5006
+ }
5007
+ #endif // _USE_STD_VECTOR_ALGORITHMS
5008
+
4948
5009
auto _Current = _First;
4949
5010
if (_First == _Last) {
4950
5011
return {_STD move(_Current), _STD move(_First)};
0 commit comments