@@ -79,6 +79,11 @@ __declspec(noalias) void __stdcall __std_replace_4(
7979 void* _First, void* _Last, uint32_t _Old_val, uint32_t _New_val) noexcept;
8080__declspec(noalias) void __stdcall __std_replace_8(
8181 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;
8287} // extern "C"
8388
8489_STD_BEGIN
@@ -205,6 +210,21 @@ __declspec(noalias) void _Replace_vectorized(
205210 }
206211}
207212
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+
208228// Can we activate the vector algorithms for find_first_of?
209229template <class _It1, class _It2, class _Pr>
210230constexpr 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>
219239constexpr bool _Vector_alg_in_ranges_replace_is_safe =
220240 _Vector_alg_in_replace_is_safe<_Iter, _Ty1> // can search and replace
221241 && _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>;
222246_STD_END
223247#endif // _USE_STD_VECTOR_ALGORITHMS
224248
@@ -4869,6 +4893,25 @@ _NODISCARD_UNIQUE_ALG _CONSTEXPR20 _FwdIt unique(_FwdIt _First, _FwdIt _Last, _P
48694893 _STD _Adl_verify_range(_First, _Last);
48704894 auto _UFirst = _STD _Get_unwrapped(_First);
48714895 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+
48724915 if (_UFirst != _ULast) {
48734916 for (auto _UFirstb = _UFirst; ++_UFirst != _ULast; _UFirstb = _UFirst) {
48744917 if (_Pred(*_UFirstb, *_UFirst)) { // copy down
@@ -4945,6 +4988,24 @@ namespace ranges {
49454988 _STL_INTERNAL_STATIC_ASSERT(sentinel_for<_Se, _It>);
49464989 _STL_INTERNAL_STATIC_ASSERT(indirect_equivalence_relation<_Pr, projected<_It, _Pj>>);
49474990
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+
49485009 auto _Current = _First;
49495010 if (_First == _Last) {
49505011 return {_STD move(_Current), _STD move(_First)};
0 commit comments