Skip to content

Commit a61b5a8

Browse files
authored
Merge 2024-03 LWG Motion 9
P0493R5 Atomic minimum/maximum
2 parents 1a48eeb + 126bab4 commit a61b5a8

File tree

2 files changed

+119
-8
lines changed

2 files changed

+119
-8
lines changed

source/support.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@
572572
#define @\defnlibxname{cpp_lib_atomic_float}@ 201711L // freestanding, also in \libheader{atomic}
573573
#define @\defnlibxname{cpp_lib_atomic_is_always_lock_free}@ 201603L // freestanding, also in \libheader{atomic}
574574
#define @\defnlibxname{cpp_lib_atomic_lock_free_type_aliases}@ 201907L // also in \libheader{atomic}
575+
#define @\defnlibxname{cpp_lib_atomic_min_max}@ 202403L // freestanding, also in \libheader{atomic}
575576
#define @\defnlibxname{cpp_lib_atomic_ref}@ 201806L // freestanding, also in \libheader{atomic}
576577
#define @\defnlibxname{cpp_lib_atomic_shared_ptr}@ 201711L // also in \libheader{memory}
577578
#define @\defnlibxname{cpp_lib_atomic_value_initialization}@ 201911L // freestanding, also in \libheader{atomic}, \libheader{memory}

source/threads.tex

Lines changed: 118 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,7 +2265,34 @@
22652265
template<class T>
22662266
T atomic_fetch_xor_explicit(atomic<T>*, typename atomic<T>::value_type, // freestanding
22672267
memory_order) noexcept;
2268-
2268+
template<class T>
2269+
T atomic_fetch_max(volatile atomic<T>*, // freestanding
2270+
typename atomic<T>::value_type) noexcept;
2271+
template<class T>
2272+
T atomic_fetch_max(atomic<T>*, // freestanding
2273+
typename atomic<T>::value_type) noexcept;
2274+
template<class T>
2275+
T atomic_fetch_max_explicit(volatile atomic<T>*, // freestanding
2276+
typename atomic<T>::value_type,
2277+
memory_order) noexcept;
2278+
template<class T>
2279+
T atomic_fetch_max_explicit(atomic<T>*, // freestanding
2280+
typename atomic<T>::value_type,
2281+
memory_order) noexcept;
2282+
template<class T>
2283+
T atomic_fetch_min(volatile atomic<T>*, // freestanding
2284+
typename atomic<T>::value_type) noexcept;
2285+
template<class T>
2286+
T atomic_fetch_min(atomic<T>*, // freestanding
2287+
typename atomic<T>::value_type) noexcept;
2288+
template<class T>
2289+
T atomic_fetch_min_explicit(volatile atomic<T>*, // freestanding
2290+
typename atomic<T>::value_type,
2291+
memory_order) noexcept;
2292+
template<class T>
2293+
T atomic_fetch_min_explicit(atomic<T>*, // freestanding
2294+
typename atomic<T>::value_type,
2295+
memory_order) noexcept;
22692296
template<class T>
22702297
void atomic_wait(const volatile atomic<T>*, // freestanding
22712298
typename atomic<T>::value_type) noexcept;
@@ -3289,6 +3316,10 @@
32893316
memory_order = memory_order::seq_cst) const noexcept;
32903317
@\placeholdernc{integral-type}@ fetch_xor(@\placeholdernc{integral-type}@,
32913318
memory_order = memory_order::seq_cst) const noexcept;
3319+
@\placeholdernc{integral-type}@ fetch_max(@\placeholdernc{integral-type}@,
3320+
memory_order = memory_order::seq_cst) const noexcept;
3321+
@\placeholdernc{integral-type}@ fetch_min(@\placeholdernc{integral-type}@,
3322+
memory_order = memory_order::seq_cst) const noexcept;
32923323

32933324
@\placeholdernc{integral-type}@ operator++(int) const noexcept;
32943325
@\placeholdernc{integral-type}@ operator--(int) const noexcept;
@@ -3318,6 +3349,8 @@
33183349

33193350
\indexlibrarymember{fetch_add}{atomic_ref<\placeholder{integral-type}>}%
33203351
\indexlibrarymember{fetch_and}{atomic_ref<\placeholder{integral-type}>}%
3352+
\indexlibrarymember{fetch_max}{atomic_ref<\placeholder{integral-type}>}%
3353+
\indexlibrarymember{fetch_min}{atomic_ref<\placeholder{integral-type}>}%
33213354
\indexlibrarymember{fetch_or}{atomic_ref<\placeholder{integral-type}>}%
33223355
\indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{integral-type}>}%
33233356
\indexlibrarymember{fetch_xor}{atomic_ref<\placeholder{integral-type}>}%
@@ -3343,14 +3376,20 @@
33433376
\pnum
33443377
\indextext{signed integer representation!two's complement}%
33453378
\remarks
3346-
For signed integer types,
3379+
Except for \tcode{fetch_max} and \tcode{fetch_min}, for signed integer types
33473380
the result is as if the object value and parameters
33483381
were converted to their corresponding unsigned types,
33493382
the computation performed on those types, and
33503383
the result converted back to the signed type.
33513384
\begin{note}
33523385
There are no undefined results arising from the computation.
33533386
\end{note}
3387+
3388+
\pnum
3389+
For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum
3390+
computation is performed as if by \tcode{max} and \tcode{min} algorithms
3391+
\iref{alg.min.max}, respectively, with the object value and the first
3392+
parameter as the arguments.
33543393
\end{itemdescr}
33553394

33563395
\indexlibrarymember{operator+=}{atomic_ref<\placeholder{integral-type}>}%
@@ -3522,6 +3561,8 @@
35223561

35233562
T* fetch_add(difference_type, memory_order = memory_order::seq_cst) const noexcept;
35243563
T* fetch_sub(difference_type, memory_order = memory_order::seq_cst) const noexcept;
3564+
T* fetch_max(T*, memory_order = memory_order::seq_cst) const noexcept;
3565+
T* fetch_min(T*, memory_order = memory_order::seq_cst) const noexcept;
35253566

35263567
T* operator++(int) const noexcept;
35273568
T* operator--(int) const noexcept;
@@ -3548,6 +3589,8 @@
35483589

35493590
\indexlibrarymember{fetch_add}{atomic_ref<T*>}%
35503591
\indexlibrarymember{fetch_sub}{atomic_ref<T*>}%
3592+
\indexlibrarymember{fetch_max}{atomic_ref<T*>}%
3593+
\indexlibrarymember{fetch_min}{atomic_ref<T*>}%
35513594
\begin{itemdecl}
35523595
T* fetch_@\placeholdernc{key}@(difference_type operand, memory_order order = memory_order::seq_cst) const noexcept;
35533596
\end{itemdecl}
@@ -3574,8 +3617,22 @@
35743617
\remarks
35753618
The result may be an undefined address,
35763619
but the operations otherwise have no undefined behavior.
3620+
3621+
\pnum
3622+
For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum
3623+
computation is performed as if by \tcode{max} and \tcode{min}
3624+
algorithms\iref{alg.min.max}, respectively, with the object value and the first
3625+
parameter as the arguments.
3626+
3627+
\begin{note}
3628+
If the pointers point to different complete objects (or subobjects thereof),
3629+
the \tcode{<} operator does not establish a strict weak ordering
3630+
(\tref{cpp17.lessthancomparable}, \ref{expr.rel}).
3631+
\end{note}
35773632
\end{itemdescr}
35783633

3634+
3635+
35793636
\indexlibrarymember{operator+=}{atomic_ref<T*>}%
35803637
\indexlibrarymember{operator-=}{atomic_ref<T*>}%
35813638
\begin{itemdecl}
@@ -4301,6 +4358,14 @@
43014358
memory_order = memory_order::seq_cst) volatile noexcept;
43024359
@\placeholdernc{integral-type}@ fetch_xor(@\placeholdernc{integral-type}@,
43034360
memory_order = memory_order::seq_cst) noexcept;
4361+
@\placeholdernc{integral-type}@ fetch_max( @\placeholdernc{integral-type}@,
4362+
memory_order = memory_order::seq_cst) volatile noexcept;
4363+
@\placeholdernc{integral-type}@ fetch_max( @\placeholdernc{integral-type}@,
4364+
memory_order = memory_order::seq_cst) noexcept;
4365+
@\placeholdernc{integral-type}@ fetch_min( @\placeholdernc{integral-type}@,
4366+
memory_order = memory_order::seq_cst) volatile noexcept;
4367+
@\placeholdernc{integral-type}@ fetch_min( @\placeholdernc{integral-type}@,
4368+
memory_order = memory_order::seq_cst) noexcept;
43044369

43054370
@\placeholdernc{integral-type}@ operator++(int) volatile noexcept;
43064371
@\placeholdernc{integral-type}@ operator++(int) noexcept;
@@ -4357,32 +4422,44 @@
43574422
\tcode{add} &
43584423
\tcode{+} &
43594424
addition &
4425+
\tcode{and} &
4426+
\tcode{\&} &
4427+
bitwise and \\
43604428
\tcode{sub} &
43614429
\tcode{-} &
4362-
subtraction \\
4430+
subtraction &
43634431
\tcode{or} &
43644432
\tcode{|} &
4365-
bitwise inclusive or &
4433+
bitwise inclusive or \\
4434+
\tcode{max} &
4435+
&
4436+
maximum &
43664437
\tcode{xor} &
43674438
\tcode{\caret} &
43684439
bitwise exclusive or \\
4369-
\tcode{and} &
4370-
\tcode{\&} &
4371-
bitwise and &&&\\
4440+
\tcode{min} &
4441+
&
4442+
minimum &&&\\
43724443
\end{floattable}
43734444

43744445
\indexlibraryglobal{atomic_fetch_add}%
43754446
\indexlibraryglobal{atomic_fetch_and}%
4447+
\indexlibraryglobal{atomic_fetch_max}%
4448+
\indexlibraryglobal{atomic_fetch_min}%
43764449
\indexlibraryglobal{atomic_fetch_or}%
43774450
\indexlibraryglobal{atomic_fetch_sub}%
43784451
\indexlibraryglobal{atomic_fetch_xor}%
43794452
\indexlibraryglobal{atomic_fetch_add_explicit}%
43804453
\indexlibraryglobal{atomic_fetch_and_explicit}%
4454+
\indexlibraryglobal{atomic_fetch_max_explicit}%
4455+
\indexlibraryglobal{atomic_fetch_min_explicit}%
43814456
\indexlibraryglobal{atomic_fetch_or_explicit}%
43824457
\indexlibraryglobal{atomic_fetch_sub_explicit}%
43834458
\indexlibraryglobal{atomic_fetch_xor_explicit}%
43844459
\indexlibrarymember{fetch_add}{atomic<\placeholder{integral-type}>}%
43854460
\indexlibrarymember{fetch_and}{atomic<\placeholder{integral-type}>}%
4461+
\indexlibrarymember{fetch_max}{atomic<\placeholder{integral-type}>}%
4462+
\indexlibrarymember{fetch_min}{atomic<\placeholder{integral-type}>}%
43864463
\indexlibrarymember{fetch_or}{atomic<\placeholder{integral-type}>}%
43874464
\indexlibrarymember{fetch_sub}{atomic<\placeholder{integral-type}>}%
43884465
\indexlibrarymember{fetch_xor}{atomic<\placeholder{integral-type}>}%
@@ -4412,7 +4489,7 @@
44124489
\pnum
44134490
\indextext{signed integer representation!two's complement}%
44144491
\remarks
4415-
For signed integer types,
4492+
Except for \tcode{fetch_max} and \tcode{fetch_min}, for signed integer types
44164493
the result is as if the object value and parameters
44174494
were converted to their corresponding unsigned types,
44184495
the computation performed on those types, and
@@ -4421,6 +4498,11 @@
44214498
There are no undefined results arising from the computation.
44224499
\end{note}
44234500

4501+
\pnum
4502+
For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum
4503+
computation is performed as if by \tcode{max} and \tcode{min} algorithms
4504+
\iref{alg.min.max}, respectively, with the object value and the first parameter
4505+
as the arguments.
44244506
\end{itemdescr}
44254507

44264508
\indexlibrarymember{operator+=}{atomic<T*>}%
@@ -4659,6 +4741,10 @@
46594741
T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
46604742
T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept;
46614743
T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
4744+
T* fetch_max(T*, memory_order = memory_order::seq_cst) volatile noexcept;
4745+
T* fetch_max(T*, memory_order = memory_order::seq_cst) noexcept;
4746+
T* fetch_min(T*, memory_order = memory_order::seq_cst) volatile noexcept;
4747+
T* fetch_min(T*, memory_order = memory_order::seq_cst) noexcept;
46624748

46634749
T* operator++(int) volatile noexcept;
46644750
T* operator++(int) noexcept;
@@ -4712,13 +4798,25 @@
47124798
\tcode{sub} &
47134799
\tcode{-} &
47144800
subtraction \\
4801+
\tcode{max} &
4802+
&
4803+
maximum &
4804+
\tcode{min} &
4805+
&
4806+
minimum \\
47154807
\end{floattable}
47164808

47174809
\indexlibraryglobal{atomic_fetch_add}%
4810+
\indexlibraryglobal{atomic_fetch_max}%
4811+
\indexlibraryglobal{atomic_fetch_min}%
47184812
\indexlibraryglobal{atomic_fetch_sub}%
47194813
\indexlibraryglobal{atomic_fetch_add_explicit}%
4814+
\indexlibraryglobal{atomic_fetch_max_explicit}%
4815+
\indexlibraryglobal{atomic_fetch_min_explicit}%
47204816
\indexlibraryglobal{atomic_fetch_sub_explicit}%
47214817
\indexlibrarymember{fetch_add}{atomic<T*>}%
4818+
\indexlibrarymember{fetch_max}{atomic<T*>}%
4819+
\indexlibrarymember{fetch_min}{atomic<T*>}%
47224820
\indexlibrarymember{fetch_sub}{atomic<T*>}%
47234821
\begin{itemdecl}
47244822
T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept;
@@ -4754,6 +4852,18 @@
47544852
\remarks
47554853
The result may be an undefined address,
47564854
but the operations otherwise have no undefined behavior.
4855+
4856+
\pnum
4857+
For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum
4858+
computation is performed as if by \tcode{max} and \tcode{min}
4859+
algorithms\iref{alg.min.max}, respectively, with the object value and the first
4860+
parameter as the arguments.
4861+
4862+
\begin{note}
4863+
If the pointers point to different complete objects (or subobjects thereof),
4864+
the \tcode{<} operator does not establish a strict weak ordering
4865+
(\tref{cpp17.lessthancomparable}, \ref{expr.rel}).
4866+
\end{note}
47574867
\end{itemdescr}
47584868

47594869
\indexlibrarymember{operator+=}{atomic<T*>}%

0 commit comments

Comments
 (0)