[libcxx-commits] [libcxx] [libc++] constexpr atomic and atomic_ref (PR #98765)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jul 14 00:44:11 PDT 2024


================
@@ -109,110 +109,189 @@ struct __atomic_ref_base {
 
   _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept { return __atomic_is_lock_free(sizeof(_Tp), __ptr_); }
 
-  _LIBCPP_HIDE_FROM_ABI void store(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+  store(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept
       _LIBCPP_CHECK_STORE_MEMORY_ORDER(__order) {
     _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
         __order == memory_order::relaxed || __order == memory_order::release || __order == memory_order::seq_cst,
         "atomic_ref: memory order argument to atomic store operation is invalid");
-    __atomic_store(__ptr_, __clear_padding(__desired), std::__to_gcc_order(__order));
+    if (__libcpp_is_constant_evaluated()) {
+      *__ptr_ = __desired;
+    } else {
+      __atomic_store(__ptr_, __clear_padding(__desired), std::__to_gcc_order(__order));
+    }
   }
 
-  _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Tp operator=(_Tp __desired) const noexcept {
     store(__desired);
     return __desired;
   }
 
-  _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __order = memory_order::seq_cst) const noexcept
-      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__order) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Tp
+  load(memory_order __order = memory_order::seq_cst) const noexcept _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__order) {
     _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
         __order == memory_order::relaxed || __order == memory_order::consume || __order == memory_order::acquire ||
             __order == memory_order::seq_cst,
         "atomic_ref: memory order argument to atomic load operation is invalid");
-    alignas(_Tp) byte __mem[sizeof(_Tp)];
-    auto* __ret = reinterpret_cast<_Tp*>(__mem);
-    __atomic_load(__ptr_, __ret, std::__to_gcc_order(__order));
-    return *__ret;
+    if (__libcpp_is_constant_evaluated()) {
+      return *__ptr_;
+    } else {
+      alignas(_Tp) byte __mem[sizeof(_Tp)];
+      auto* __ret = reinterpret_cast<_Tp*>(__mem);
+      __atomic_load(__ptr_, __ret, std::__to_gcc_order(__order));
+      return *__ret;
+    }
   }
 
-  _LIBCPP_HIDE_FROM_ABI operator _Tp() const noexcept { return load(); }
-
-  _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept {
-    alignas(_Tp) byte __mem[sizeof(_Tp)];
-    auto* __ret = reinterpret_cast<_Tp*>(__mem);
-    __atomic_exchange(__ptr_, __clear_padding(__desired), __ret, std::__to_gcc_order(__order));
-    return *__ret;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 operator _Tp() const noexcept { return load(); }
+
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Tp
+  exchange(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept {
+    if (__libcpp_is_constant_evaluated()) {
+      _Tp tmp = *__ptr_;
+      *__ptr_ = __desired;
+      return tmp;
----------------
philnik777 wrote:

```suggestion
      return std::exchange(*__ptr_, __desired);
```


https://github.com/llvm/llvm-project/pull/98765


More information about the libcxx-commits mailing list