Skip to content

Commit 71e404b

Browse files
Expand std::iter_swap and remove _Swap_adl (#3700)
Also - Move `std::iter_swap` from `<utility>` to `<algorithm>`. - In `_Partition_by_median_guess_unchecked`, only evaluate `_Prev_iter(_Glast)` once. Fixes #2692.
1 parent 0f61b6b commit 71e404b

File tree

22 files changed

+99
-79
lines changed

22 files changed

+99
-79
lines changed

stl/inc/algorithm

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,6 +3430,11 @@ _FwdIt2 swap_ranges(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _Dest) noe
34303430
}
34313431
#endif // _HAS_CXX17
34323432

3433+
_EXPORT_STD template <class _FwdIt1, class _FwdIt2>
3434+
_CONSTEXPR20 void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right) { // swap *_Left and *_Right
3435+
swap(*_Left, *_Right); // intentional ADL
3436+
}
3437+
34333438
_EXPORT_STD template <class _InIt, class _OutIt, class _Fn>
34343439
_CONSTEXPR20 _OutIt transform(const _InIt _First, const _InIt _Last, _OutIt _Dest, _Fn _Func) {
34353440
// transform [_First, _Last) with _Func
@@ -5349,7 +5354,7 @@ void _Random_shuffle1(_RanIt _First, _RanIt _Last, _RngFn& _RngFunc) {
53495354
_Diff _Off = _RngFunc(static_cast<_Diff>(_Target_index + 1));
53505355
_STL_ASSERT(0 <= _Off && _Off <= _Target_index, "random value out of range");
53515356
if (_Off != _Target_index) { // avoid self-move-assignment
5352-
_STD iter_swap(_UTarget, _UFirst + _Off);
5357+
swap(*_UTarget, *(_UFirst + _Off)); // intentional ADL
53535358
}
53545359
}
53555360
}
@@ -5559,7 +5564,7 @@ constexpr _FwdIt shift_right(_FwdIt _First, const _FwdIt _Last, _Iter_diff_t<_Fw
55595564

55605565
return _First;
55615566
}
5562-
_Swap_adl(*_Mid, *_Trail);
5567+
swap(*_Mid, *_Trail); // intentional ADL
55635568
}
55645569
}
55655570
}
@@ -5830,7 +5835,7 @@ _CONSTEXPR20 _FwdIt partition(_FwdIt _First, const _FwdIt _Last, _Pr _Pred) {
58305835
}
58315836
} while (!_Pred(*_ULast));
58325837

5833-
_STD iter_swap(_UFirst, _ULast); // out of place, swap and loop
5838+
swap(*_UFirst, *_ULast); // out of place, swap and loop; intentional ADL
58345839
++_UFirst;
58355840
}
58365841
} else {
@@ -5849,7 +5854,7 @@ _CONSTEXPR20 _FwdIt partition(_FwdIt _First, const _FwdIt _Last, _Pr _Pred) {
58495854

58505855
for (auto _UNext = _UFirst; ++_UNext != _ULast;) {
58515856
if (_Pred(*_UNext)) {
5852-
_STD iter_swap(_UFirst, _UNext); // out of place, swap and loop
5857+
swap(*_UFirst, *_UNext); // out of place, swap and loop; intentional ADL
58535858
++_UFirst;
58545859
}
58555860
}
@@ -7924,14 +7929,14 @@ template <class _RanIt, class _Pr>
79247929
_CONSTEXPR20 void _Med3_unchecked(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred) {
79257930
// sort median of three elements to middle
79267931
if (_DEBUG_LT_PRED(_Pred, *_Mid, *_First)) {
7927-
_STD iter_swap(_Mid, _First);
7932+
swap(*_Mid, *_First); // intentional ADL
79287933
}
79297934

79307935
if (_DEBUG_LT_PRED(_Pred, *_Last, *_Mid)) { // swap middle and last, then test first again
7931-
_STD iter_swap(_Last, _Mid);
7936+
swap(*_Last, *_Mid); // intentional ADL
79327937

79337938
if (_DEBUG_LT_PRED(_Pred, *_Mid, *_First)) {
7934-
_STD iter_swap(_Mid, _First);
7939+
swap(*_Mid, *_First); // intentional ADL
79357940
}
79367941
}
79377942
}
@@ -7980,20 +7985,21 @@ _CONSTEXPR20 pair<_RanIt, _RanIt> _Partition_by_median_guess_unchecked(_RanIt _F
79807985
} else if (_Pred(*_Gfirst, *_Pfirst)) {
79817986
break;
79827987
} else if (_Plast != _Gfirst) {
7983-
_STD iter_swap(_Plast, _Gfirst);
7988+
swap(*_Plast, *_Gfirst); // intentional ADL
79847989
++_Plast;
79857990
} else {
79867991
++_Plast;
79877992
}
79887993
}
79897994

79907995
for (; _First < _Glast; --_Glast) {
7991-
if (_DEBUG_LT_PRED(_Pred, *_Prev_iter(_Glast), *_Pfirst)) {
7996+
const auto _Glast_prev = _Prev_iter(_Glast);
7997+
if (_DEBUG_LT_PRED(_Pred, *_Glast_prev, *_Pfirst)) {
79927998
continue;
7993-
} else if (_Pred(*_Pfirst, *_Prev_iter(_Glast))) {
7999+
} else if (_Pred(*_Pfirst, *_Glast_prev)) {
79948000
break;
7995-
} else if (--_Pfirst != _Prev_iter(_Glast)) {
7996-
_STD iter_swap(_Pfirst, _Prev_iter(_Glast));
8001+
} else if (--_Pfirst != _Glast_prev) {
8002+
swap(*_Pfirst, *_Glast_prev); // intentional ADL
79978003
}
79988004
}
79998005

@@ -8003,21 +8009,21 @@ _CONSTEXPR20 pair<_RanIt, _RanIt> _Partition_by_median_guess_unchecked(_RanIt _F
80038009

80048010
if (_Glast == _First) { // no room at bottom, rotate pivot upward
80058011
if (_Plast != _Gfirst) {
8006-
_STD iter_swap(_Pfirst, _Plast);
8012+
swap(*_Pfirst, *_Plast); // intentional ADL
80078013
}
80088014

80098015
++_Plast;
8010-
_STD iter_swap(_Pfirst, _Gfirst);
8016+
swap(*_Pfirst, *_Gfirst); // intentional ADL
80118017
++_Pfirst;
80128018
++_Gfirst;
80138019
} else if (_Gfirst == _Last) { // no room at top, rotate pivot downward
80148020
if (--_Glast != --_Pfirst) {
8015-
_STD iter_swap(_Glast, _Pfirst);
8021+
swap(*_Glast, *_Pfirst); // intentional ADL
80168022
}
80178023

8018-
_STD iter_swap(_Pfirst, --_Plast);
8024+
swap(*_Pfirst, *--_Plast); // intentional ADL
80198025
} else {
8020-
_STD iter_swap(_Gfirst, --_Glast);
8026+
swap(*_Gfirst, *--_Glast); // intentional ADL
80218027
++_Gfirst;
80228028
}
80238029
}
@@ -10217,7 +10223,7 @@ _CONSTEXPR20 bool next_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred) {
1021710223
--_UMid;
1021810224
} while (!_DEBUG_LT_PRED(_Pred, *_UNext, *_UMid));
1021910225

10220-
_STD iter_swap(_UNext, _UMid);
10226+
swap(*_UNext, *_UMid); // intentional ADL
1022110227
_STD reverse(_UNext1, _ULast);
1022210228
return true;
1022310229
}
@@ -10321,7 +10327,7 @@ _CONSTEXPR20 bool prev_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred) {
1032110327
--_UMid;
1032210328
} while (!_DEBUG_LT_PRED(_Pred, *_UMid, *_UNext));
1032310329

10324-
_STD iter_swap(_UNext, _UMid);
10330+
swap(*_UNext, *_UMid); // intentional ADL
1032510331
_STD reverse(_UNext1, _ULast);
1032610332
return true;
1032710333
}

stl/inc/deque

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1455,12 +1455,13 @@ public:
14551455
}
14561456

14571457
void swap(deque& _Right) noexcept /* strengthened */ {
1458+
using _STD swap;
14581459
if (this != _STD addressof(_Right)) {
14591460
_Pocs(_Getal(), _Right._Getal());
14601461
auto& _My_data = _Get_data();
14611462
auto& _Right_data = _Right._Get_data();
14621463
_My_data._Swap_proxy_and_iterators(_Right_data);
1463-
_Swap_adl(_My_data._Map, _Right_data._Map);
1464+
swap(_My_data._Map, _Right_data._Map); // intentional ADL
14641465
_STD swap(_My_data._Mapsize, _Right_data._Mapsize);
14651466
_STD swap(_My_data._Myoff, _Right_data._Myoff);
14661467
_STD swap(_My_data._Mysize, _Right_data._Mysize);

stl/inc/execution

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3346,7 +3346,7 @@ pair<_FwdIt, _Iter_diff_t<_FwdIt>> _Partition_with_count_unchecked(_FwdIt _First
33463346
}
33473347
} while (!_Pred(*_Last));
33483348

3349-
_STD iter_swap(_First, _Last); // out of place, swap and loop
3349+
swap(*_First, *_Last); // out of place, swap and loop; intentional ADL
33503350
++_First;
33513351
++_Trues;
33523352
}
@@ -3367,7 +3367,7 @@ pair<_FwdIt, _Iter_diff_t<_FwdIt>> _Partition_with_count_unchecked(_FwdIt _First
33673367

33683368
for (_FwdIt _Next = _First; ++_Next != _Last;) {
33693369
if (_Pred(*_Next)) {
3370-
_STD iter_swap(_First, _Next); // out of place, swap and loop
3370+
swap(*_First, *_Next); // out of place, swap and loop; intentional ADL
33713371
++_First;
33723372
++_Trues;
33733373
}
@@ -3387,7 +3387,7 @@ pair<_FwdIt, _Iter_diff_t<_FwdIt>> _Partition_swap_backward(
33873387
while (_First != _Last) {
33883388
--_Last;
33893389
if (_Pred(*_Last)) {
3390-
_STD iter_swap(_Beginning_of_falses, _Last);
3390+
swap(*_Beginning_of_falses, *_Last); // intentional ADL
33913391
++_Beginning_of_falses;
33923392
++_Trues;
33933393
if (_Beginning_of_falses == _First) {
@@ -3399,7 +3399,7 @@ pair<_FwdIt, _Iter_diff_t<_FwdIt>> _Partition_swap_backward(
33993399
} else {
34003400
for (; _First != _Last; ++_First) {
34013401
if (_Pred(*_First)) {
3402-
_STD iter_swap(_First, _Beginning_of_falses);
3402+
swap(*_First, *_Beginning_of_falses); // intentional ADL
34033403
++_Beginning_of_falses;
34043404
++_Trues;
34053405
}

stl/inc/expected

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ public:
8383
// [expected.un.swap]
8484
constexpr void swap(unexpected& _Other) noexcept(is_nothrow_swappable_v<_Err>) {
8585
static_assert(is_swappable_v<_Err>, "E must be swappable");
86-
_Swap_adl(_Unexpected, _Other._Unexpected);
86+
using _STD swap;
87+
swap(_Unexpected, _Other._Unexpected); // intentional ADL
8788
}
8889

8990
friend constexpr void swap(unexpected& _Left, unexpected& _Right) noexcept(is_nothrow_swappable_v<_Err>)
@@ -518,8 +519,9 @@ public:
518519
&& is_move_constructible_v<_Ty> && is_move_constructible_v<_Err> //
519520
&& (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>)
520521
{
522+
using _STD swap;
521523
if (_Has_value && _Other._Has_value) {
522-
_Swap_adl(_Value, _Other._Value);
524+
swap(_Value, _Other._Value); // intentional ADL
523525
} else if (_Has_value) {
524526
if constexpr (is_nothrow_move_constructible_v<_Err>) {
525527
_Err _Tmp(_STD move(_Other._Unexpected));
@@ -560,7 +562,7 @@ public:
560562
} else if (_Other._Has_value) {
561563
_Other.swap(*this);
562564
} else {
563-
_Swap_adl(_Unexpected, _Other._Unexpected);
565+
swap(_Unexpected, _Other._Unexpected); // intentional ADL
564566
}
565567
}
566568

@@ -1344,6 +1346,7 @@ public:
13441346
is_nothrow_move_constructible_v<_Err>&& is_nothrow_swappable_v<_Err>) //
13451347
requires is_swappable_v<_Err> && is_move_constructible_v<_Err>
13461348
{
1349+
using _STD swap;
13471350
if (_Has_value && _Other._Has_value) {
13481351
// nothing
13491352
} else if (_Has_value) {
@@ -1361,14 +1364,15 @@ public:
13611364
_Has_value = true;
13621365
_Other._Has_value = false;
13631366
} else {
1364-
_Swap_adl(_Unexpected, _Other._Unexpected);
1367+
swap(_Unexpected, _Other._Unexpected); // intentional ADL
13651368
}
13661369
}
13671370

13681371
friend constexpr void swap(expected& _Left, expected& _Right) noexcept(
13691372
is_nothrow_move_constructible_v<_Err>&& is_nothrow_swappable_v<_Err>)
13701373
requires is_swappable_v<_Err> && is_move_constructible_v<_Err>
13711374
{
1375+
using _STD swap;
13721376
if (_Left._Has_value && _Right._Has_value) {
13731377
// nothing
13741378
} else if (_Left._Has_value) {
@@ -1386,7 +1390,7 @@ public:
13861390
_Left._Has_value = true;
13871391
_Right._Has_value = false;
13881392
} else {
1389-
_Swap_adl(_Left._Unexpected, _Right._Unexpected);
1393+
swap(_Left._Unexpected, _Right._Unexpected); // intentional ADL
13901394
}
13911395
}
13921396

stl/inc/forward_list

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1097,10 +1097,11 @@ public:
10971097
}
10981098

10991099
void swap(forward_list& _Right) noexcept /* strengthened */ {
1100+
using _STD swap;
11001101
if (this != _STD addressof(_Right)) {
11011102
_Pocs(_Getal(), _Right._Getal());
11021103
_Swap_proxy_and_iterators(_Right);
1103-
_Swap_adl(_Mypair._Myval2._Myhead, _Right._Mypair._Myval2._Myhead);
1104+
swap(_Mypair._Myval2._Myhead, _Right._Mypair._Myval2._Myhead); // intentional ADL
11041105
}
11051106
}
11061107

stl/inc/hash_map

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ namespace stdext {
3030
using _STD swap;
3131
using _STD _Hash;
3232
using _STD _Is_nothrow_swappable;
33-
using _STD _Swap_adl;
3433
using _STD _Xout_of_range;
3534

3635
template <class _Kty, // key type
@@ -102,7 +101,8 @@ namespace stdext {
102101
}
103102

104103
void swap(_Hmap_traits& _Rhs) noexcept(_Is_nothrow_swappable<_Tr>::value) {
105-
_Swap_adl(static_cast<_Tr&>(*this), static_cast<_Tr&>(_Rhs));
104+
using _STD swap;
105+
swap(static_cast<_Tr&>(*this), static_cast<_Tr&>(_Rhs)); // intentional ADL
106106
_STD swap(_Max_buckets, _Rhs._Max_buckets);
107107
}
108108

stl/inc/hash_set

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ namespace stdext {
2727
using _STD swap;
2828
using _STD _Hash;
2929
using _STD _Is_nothrow_swappable;
30-
using _STD _Swap_adl;
3130

3231
template <class _Kty, // key type (same as value type)
3332
class _Tr, // comparator predicate type
@@ -79,7 +78,8 @@ namespace stdext {
7978
}
8079

8180
void swap(_Hset_traits& _Rhs) noexcept(_Is_nothrow_swappable<_Tr>::value) {
82-
_Swap_adl(static_cast<_Tr&>(*this), static_cast<_Tr&>(_Rhs));
81+
using _STD swap;
82+
swap(static_cast<_Tr&>(*this), static_cast<_Tr&>(_Rhs)); // intentional ADL
8383
_STD swap(_Max_buckets, _Rhs._Max_buckets);
8484
}
8585

stl/inc/list

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,10 +957,11 @@ public:
957957

958958
private:
959959
void _Swap_val(list& _Right) noexcept { // swap with _Right, same allocator
960+
using _STD swap;
960961
auto& _My_data = _Mypair._Myval2;
961962
auto& _Right_data = _Right._Mypair._Myval2;
962963
_My_data._Swap_proxy_and_iterators(_Right_data);
963-
_Swap_adl(_My_data._Myhead, _Right_data._Myhead);
964+
swap(_My_data._Myhead, _Right_data._Myhead); // intentional ADL
964965
_STD swap(_My_data._Mysize, _Right_data._Mysize);
965966
}
966967

stl/inc/memory

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3280,8 +3280,9 @@ public:
32803280
}
32813281

32823282
_CONSTEXPR23 void swap(unique_ptr& _Right) noexcept {
3283-
_Swap_adl(_Mypair._Myval2, _Right._Mypair._Myval2);
3284-
_Swap_adl(_Mypair._Get_first(), _Right._Mypair._Get_first());
3283+
using _STD swap;
3284+
swap(_Mypair._Myval2, _Right._Mypair._Myval2); // intentional ADL
3285+
swap(_Mypair._Get_first(), _Right._Mypair._Get_first()); // intentional ADL
32853286
}
32863287

32873288
_CONSTEXPR23 ~unique_ptr() noexcept {
@@ -3418,8 +3419,9 @@ public:
34183419
}
34193420

34203421
_CONSTEXPR23 void swap(unique_ptr& _Right) noexcept {
3421-
_Swap_adl(_Mypair._Myval2, _Right._Mypair._Myval2);
3422-
_Swap_adl(_Mypair._Get_first(), _Right._Mypair._Get_first());
3422+
using _STD swap;
3423+
swap(_Mypair._Myval2, _Right._Mypair._Myval2); // intentional ADL
3424+
swap(_Mypair._Get_first(), _Right._Mypair._Get_first()); // intentional ADL
34233425
}
34243426

34253427
_CONSTEXPR23 ~unique_ptr() noexcept {

stl/inc/optional

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,14 +351,15 @@ public:
351351
"optional<T>::swap requires T to be move constructible (N4950 [optional.swap]/1).");
352352
static_assert(!is_move_constructible_v<_Ty> || is_swappable_v<_Ty>,
353353
"optional<T>::swap requires T to be swappable (N4950 [optional.swap]/2).");
354+
using _STD swap;
354355
if constexpr (_Is_trivially_swappable_v<_Ty>) {
355356
using _TrivialBaseTy = _Optional_destruct_base<_Ty>;
356357
_STD swap(static_cast<_TrivialBaseTy&>(*this), static_cast<_TrivialBaseTy&>(_Right));
357358
} else {
358359
const bool _Engaged = this->_Has_value;
359360
if (_Engaged == _Right._Has_value) {
360361
if (_Engaged) {
361-
_Swap_adl(**this, *_Right);
362+
swap(**this, *_Right); // intentional ADL
362363
}
363364
} else {
364365
optional& _Source = _Engaged ? *this : _Right;

0 commit comments

Comments
 (0)