|
623 | 623 | \indexlibrary{\idxcode{atomic}!constructor}%
|
624 | 624 | \indexlibrary{\idxcode{atomic<T*>}!constructor}%
|
625 | 625 | \indexlibrary{\idxcode{atomic<\placeholder{integral}>}!constructor}%
|
| 626 | +\indexlibrary{\idxcode{atomic<\placeholder{floating-point}>}!constructor}% |
626 | 627 | \begin{itemdecl}
|
627 | 628 | atomic() noexcept = default;
|
628 | 629 | \end{itemdecl}
|
|
639 | 640 | \indexlibrary{\idxcode{atomic}!constructor}%
|
640 | 641 | \indexlibrary{\idxcode{atomic<T*>}!constructor}%
|
641 | 642 | \indexlibrary{\idxcode{atomic<\placeholder{integral}>}!constructor}%
|
| 643 | +\indexlibrary{\idxcode{atomic<\placeholder{floating-point}>}!constructor}% |
642 | 644 | \begin{itemdecl}
|
643 | 645 | constexpr atomic(T desired) noexcept;
|
644 | 646 | \end{itemdecl}
|
|
678 | 680 | \indexlibrarymember{is_always_lock_free}{atomic}%
|
679 | 681 | \indexlibrarymember{is_always_lock_free}{atomic<T*>}%
|
680 | 682 | \indexlibrarymember{is_always_lock_free}{atomic<\placeholder{integral}>}%
|
| 683 | +\indexlibrarymember{is_always_lock_free}{atomic<\placeholder{floating-point}>}% |
681 | 684 | \begin{itemdecl}
|
682 | 685 | static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@;
|
683 | 686 | \end{itemdecl}
|
|
696 | 699 | \indexlibrarymember{is_lock_free}{atomic}%
|
697 | 700 | \indexlibrarymember{is_lock_free}{atomic<T*>}%
|
698 | 701 | \indexlibrarymember{is_lock_free}{atomic<\placeholder{integral}>}%
|
| 702 | +\indexlibrarymember{is_lock_free}{atomic<\placeholder{floating-point}>}% |
699 | 703 | \begin{itemdecl}
|
700 | 704 | bool is_lock_free() const volatile noexcept;
|
701 | 705 | bool is_lock_free() const noexcept;
|
|
715 | 719 | \indexlibrarymember{store}{atomic}%
|
716 | 720 | \indexlibrarymember{store}{atomic<T*>}%
|
717 | 721 | \indexlibrarymember{store}{atomic<\placeholder{integral}>}%
|
| 722 | +\indexlibrarymember{store}{atomic<\placeholder{floating-point}>}% |
718 | 723 | \begin{itemdecl}
|
719 | 724 | void store(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
|
720 | 725 | void store(T desired, memory_order order = memory_order::seq_cst) noexcept;
|
|
734 | 739 | \indexlibrarymember{operator=}{atomic}%
|
735 | 740 | \indexlibrarymember{operator=}{atomic<T*>}%
|
736 | 741 | \indexlibrarymember{operator=}{atomic<\placeholder{integral}>}%
|
| 742 | +\indexlibrarymember{operator=}{atomic<\placeholder{floating-point}>}% |
737 | 743 | \begin{itemdecl}
|
738 | 744 | T operator=(T desired) volatile noexcept;
|
739 | 745 | T operator=(T desired) noexcept;
|
|
752 | 758 | \indexlibrarymember{load}{atomic}%
|
753 | 759 | \indexlibrarymember{load}{atomic<T*>}%
|
754 | 760 | \indexlibrarymember{load}{atomic<\placeholder{integral}>}%
|
| 761 | +\indexlibrarymember{load}{atomic<\placeholder{floating-point}>}% |
755 | 762 | \begin{itemdecl}
|
756 | 763 | T load(memory_order order = memory_order::seq_cst) const volatile noexcept;
|
757 | 764 | T load(memory_order order = memory_order::seq_cst) const noexcept;
|
|
771 | 778 | \indexlibrarymember{operator \placeholder{type}}{atomic}%
|
772 | 779 | \indexlibrarymember{operator T*}{atomic<T*>}%
|
773 | 780 | \indexlibrarymember{operator \placeholder{integral}}{atomic<\placeholder{integral}>}%
|
| 781 | +\indexlibrarymember{operator \placeholder{floating-point}}{atomic<\placeholder{floating-point}>}% |
774 | 782 | \begin{itemdecl}
|
775 | 783 | operator T() const volatile noexcept;
|
776 | 784 | operator T() const noexcept;
|
|
787 | 795 | \indexlibrarymember{exchange}{atomic}%
|
788 | 796 | \indexlibrarymember{exchange}{atomic<T*>}%
|
789 | 797 | \indexlibrarymember{exchange}{atomic<\placeholder{integral}>}%
|
| 798 | +\indexlibrarymember{exchange}{atomic<\placeholder{floating-point}>}% |
790 | 799 | \begin{itemdecl}
|
791 | 800 | T exchange(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
|
792 | 801 | T exchange(T desired, memory_order order = memory_order::seq_cst) noexcept;
|
|
810 | 819 | \indexlibrarymember{compare_exchange_weak}{atomic}%
|
811 | 820 | \indexlibrarymember{compare_exchange_weak}{atomic<T*>}%
|
812 | 821 | \indexlibrarymember{compare_exchange_weak}{atomic<\placeholder{integral}>}%
|
| 822 | +\indexlibrarymember{compare_exchange_weak}{atomic<\placeholder{floating-point}>}% |
813 | 823 | \indexlibrarymember{compare_exchange_strong}{atomic}%
|
814 | 824 | \indexlibrarymember{compare_exchange_strong}{atomic<T*>}%
|
815 | 825 | \indexlibrarymember{compare_exchange_strong}{atomic<\placeholder{integral}>}%
|
| 826 | +\indexlibrarymember{compare_exchange_strong}{atomic<\placeholder{floating-point}>}% |
816 | 827 | \begin{itemdecl}
|
817 | 828 | bool compare_exchange_weak(T& expected, T desired,
|
818 | 829 | memory_order success, memory_order failure) volatile noexcept;
|
|
1116 | 1127 | \effects Equivalent to: \tcode{return fetch_\placeholder{key}(operand) \placeholder{op} operand;}
|
1117 | 1128 | \end{itemdescr}
|
1118 | 1129 |
|
| 1130 | +\rSec2[atomics.types.float]{Specializations for floating-point types} |
| 1131 | + |
| 1132 | +\indexlibrary{\idxcode{atomic<\placeholder{floating-point}>}}% |
| 1133 | +\pnum |
| 1134 | +There are specializations of the \tcode{atomic} |
| 1135 | +template for the floating-point types |
| 1136 | +\tcode{float}, |
| 1137 | +\tcode{double}, and |
| 1138 | +\tcode{long double}. |
| 1139 | +For each such floating-point type \tcode{\placeholdernc{floating-point}}, |
| 1140 | +the specialization \tcode{atomic<\placeholder{floating-point}>} |
| 1141 | +provides additional atomic operations appropriate to floating-point types. |
| 1142 | + |
| 1143 | +\begin{codeblock} |
| 1144 | +namespace std { |
| 1145 | + template<> struct atomic<@\placeholder{floating-point}@> { |
| 1146 | + static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@; |
| 1147 | + bool is_lock_free() const volatile noexcept; |
| 1148 | + bool is_lock_free() const noexcept; |
| 1149 | + void store(@\placeholdernc{floating-point}@, memory_order = memory_order_seq_cst) volatile noexcept; |
| 1150 | + void store(@\placeholdernc{floating-point}@, memory_order = memory_order_seq_cst) noexcept; |
| 1151 | + @\placeholdernc{floating-point}@ load(memory_order = memory_order_seq_cst) volatile noexcept; |
| 1152 | + @\placeholdernc{floating-point}@ load(memory_order = memory_order_seq_cst) noexcept; |
| 1153 | + operator @\placeholdernc{floating-point}@() volatile noexcept; |
| 1154 | + operator @\placeholdernc{floating-point}@() noexcept; |
| 1155 | + @\placeholdernc{floating-point}@ exchange(@\placeholdernc{floating-point}@, |
| 1156 | + memory_order = memory_order_seq_cst) volatile noexcept; |
| 1157 | + @\placeholdernc{floating-point}@ exchange(@\placeholdernc{floating-point}@, |
| 1158 | + memory_order = memory_order_seq_cst) noexcept; |
| 1159 | + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, |
| 1160 | + memory_order, memory_order) volatile noexcept; |
| 1161 | + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, |
| 1162 | + memory_order, memory_order) noexcept; |
| 1163 | + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, |
| 1164 | + memory_order, memory_order) volatile noexcept; |
| 1165 | + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, |
| 1166 | + memory_order, memory_order) noexcept; |
| 1167 | + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, |
| 1168 | + memory_order = memory_order_seq_cst) volatile noexcept; |
| 1169 | + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, |
| 1170 | + memory_order = memory_order_seq_cst) noexcept; |
| 1171 | + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, |
| 1172 | + memory_order = memory_order_seq_cst) volatile noexcept; |
| 1173 | + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, |
| 1174 | + memory_order = memory_order_seq_cst) noexcept; |
| 1175 | + |
| 1176 | + @\placeholdernc{floating-point}@ fetch_add(@\placeholdernc{floating-point}@, |
| 1177 | + memory_order = memory_order_seq_cst) volatile noexcept; |
| 1178 | + @\placeholdernc{floating-point}@ fetch_add(@\placeholdernc{floating-point}@, |
| 1179 | + memory_order = memory_order_seq_cst) noexcept; |
| 1180 | + @\placeholdernc{floating-point}@ fetch_sub(@\placeholdernc{floating-point}@, |
| 1181 | + memory_order = memory_order_seq_cst) volatile noexcept; |
| 1182 | + @\placeholdernc{floating-point}@ fetch_sub(@\placeholdernc{floating-point}@, |
| 1183 | + memory_order = memory_order_seq_cst) noexcept; |
| 1184 | + |
| 1185 | + atomic() noexcept = default; |
| 1186 | + constexpr atomic(@\placeholder{floating-point}@) noexcept; |
| 1187 | + atomic(const atomic&) = delete; |
| 1188 | + atomic& operator=(const atomic&) = delete; |
| 1189 | + atomic& operator=(const atomic&) volatile = delete; |
| 1190 | + @\placeholdernc{floating-point}@ operator=(@\placeholder{floating-point}@) volatile noexcept; |
| 1191 | + @\placeholdernc{floating-point}@ operator=(@\placeholder{floating-point}@) noexcept; |
| 1192 | + |
| 1193 | + @\placeholdernc{floating-point}@ operator+=(@\placeholder{floating-point}@) volatile noexcept; |
| 1194 | + @\placeholdernc{floating-point}@ operator+=(@\placeholder{floating-point}@) noexcept; |
| 1195 | + @\placeholdernc{floating-point}@ operator-=(@\placeholder{floating-point}@) volatile noexcept; |
| 1196 | + @\placeholdernc{floating-point}@ operator-=(@\placeholder{floating-point}@) noexcept; |
| 1197 | + }; |
| 1198 | +} |
| 1199 | +\end{codeblock} |
| 1200 | + |
| 1201 | +\pnum |
| 1202 | +The atomic floating-point specializations |
| 1203 | +are standard-layout structs. |
| 1204 | +They each have a trivial default constructor |
| 1205 | +and a trivial destructor. |
| 1206 | + |
| 1207 | +\pnum |
| 1208 | +Descriptions are provided below only for members that differ from the primary template. |
| 1209 | + |
| 1210 | +\pnum |
| 1211 | +The following operations perform arithmetic addition and subtraction computations. |
| 1212 | +The key, operator, and computation correspondence are identified in |
| 1213 | +Table~\ref{tab:atomic.arithmetic.computations}. |
| 1214 | + |
| 1215 | +\indexlibrary{\idxcode{atomic_fetch_add}}% |
| 1216 | +\indexlibrary{\idxcode{atomic_fetch_sub}}% |
| 1217 | +\indexlibrary{\idxcode{atomic_fetch_add_explicit}}% |
| 1218 | +\indexlibrary{\idxcode{atomic_fetch_sub_explicit}}% |
| 1219 | +\indexlibrarymember{fetch_add}{atomic<\placeholder{floating-point}>}% |
| 1220 | +\indexlibrarymember{fetch_sub}{atomic<\placeholder{floating-point}>}% |
| 1221 | +\begin{itemdecl} |
| 1222 | +T A::fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order_seq_cst) volatile noexcept; |
| 1223 | +T A::fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order_seq_cst) noexcept; |
| 1224 | +\end{itemdecl} |
| 1225 | + |
| 1226 | +\begin{itemdescr} |
| 1227 | +\pnum |
| 1228 | +\effects |
| 1229 | +Atomically replaces the value pointed to by \tcode{this} |
| 1230 | +with the result of the computation applied to the value pointed |
| 1231 | +to by \tcode{this} and the given \tcode{operand}. |
| 1232 | +Memory is affected according to the value of \tcode{order}. |
| 1233 | +These operations are atomic read-modify-write operations\iref{intro.multithread}. |
| 1234 | + |
| 1235 | +\pnum |
| 1236 | +\returns |
| 1237 | +Atomically, the value pointed to by \tcode{this} immediately before the effects. |
| 1238 | + |
| 1239 | +\pnum |
| 1240 | +\remarks |
| 1241 | +If the result is not a representable value for its type\iref{expr.pre} |
| 1242 | +the result is unspecified, but the operations otherwise have no undefined |
| 1243 | +behavior. Atomic arithmetic operations on \tcode{\placeholder{floating-point}} |
| 1244 | +should conform to the \tcode{std::numeric_limits<\placeholder{floating-point}>} |
| 1245 | +traits associated with the floating-point type\iref{limits.syn}. |
| 1246 | +The floating-point environment\iref{cfenv} for atomic arithmetic operations |
| 1247 | +on \tcode{\placeholder{floating-point}} may be different than the |
| 1248 | +calling thread's floating-point environment. |
| 1249 | +\end{itemdescr} |
| 1250 | + |
| 1251 | +\indexlibrarymember{operator+=}{atomic<T*>}% |
| 1252 | +\indexlibrarymember{operator-=}{atomic<T*>}% |
| 1253 | +\indexlibrarymember{operator+=}{atomic<\placeholder{floating-point}>}% |
| 1254 | +\indexlibrarymember{operator-=}{atomic<\placeholder{floating-point}>}% |
| 1255 | +\begin{itemdecl} |
| 1256 | +T operator @\placeholder{op}@=(T operand) volatile noexcept; |
| 1257 | +T operator @\placeholder{op}@=(T operand) noexcept; |
| 1258 | +\end{itemdecl} |
| 1259 | + |
| 1260 | +\begin{itemdescr} |
| 1261 | +\pnum |
| 1262 | +\effects |
| 1263 | +Equivalent to: \tcode{return fetch_\placeholder{key}(operand) \placeholder{op} operand;} |
| 1264 | + |
| 1265 | +\pnum |
| 1266 | +\remarks |
| 1267 | +If the result is not a representable value for its type\iref{expr.pre} |
| 1268 | +the result is unspecified, but the operations otherwise have no undefined |
| 1269 | +behavior. Atomic arithmetic operations on \tcode{\placeholder{floating-point}} |
| 1270 | +should conform to the \tcode{std::numeric_limits<\placeholder{floating-point}>} |
| 1271 | +traits associated with the floating-point type\iref{limits.syn}. |
| 1272 | +The floating-point environment\iref{cfenv} for atomic arithmetic operations |
| 1273 | +on \tcode{\placeholder{floating-point}} may be different than the |
| 1274 | +calling thread's floating-point environment. |
| 1275 | +\end{itemdescr} |
| 1276 | + |
1119 | 1277 | \rSec2[atomics.types.pointer]{Partial specialization for pointers}
|
1120 | 1278 | \indexlibrary{\idxcode{atomic<T*>}}%
|
1121 | 1279 |
|
|
0 commit comments