[libcxx-commits] [libcxx] [libc++][pstl] Implementation of parallel std::destroy() and std::destroy_n() (PR #211888)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 29 08:38:44 PDT 2026


================
@@ -0,0 +1,149 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+//           class ForwardIterator,
+//           class Size>
+//   void destroy_n(ExecutionPolicy&& exec, ForwardIterator first, Size n);
+
+#include <atomic>
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <limits>
+#include <memory>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(destroy_n);
+
+static_assert(sfinae_test_destroy_n<int, int*, int>);
+static_assert(!sfinae_test_destroy_n<std::execution::parallel_policy, int*, int>);
+
+struct Counted {
+  std::atomic_int* counter_;
+  Counted(std::atomic_int* counter) : counter_(counter) { counter_->fetch_add(1); }
+  Counted(Counted const& other) : counter_(other.counter_) { counter_->fetch_add(1); }
+  ~Counted() { counter_->fetch_sub(1); }
+  friend void operator&(Counted) = delete;
+};
+
+template <class Iter>
+struct TestCounted {
+  template <class ExecutionPolicy>
+  void operator()(ExecutionPolicy&& policy) {
+    {
+      // Test destroy_n() with a range of Counted objects.
+      // Ranges vary in size from 0 to 1073.
+      // Each object has its own counter.
+      std::atomic_int counters[1073];
+      std::fill_n(std::begin(counters), std::size(counters), 0);
+
+      using Alloc = std::allocator<Counted>;
+      Alloc alloc;
+      Counted* pool = std::allocator_traits<Alloc>::allocate(alloc, std::size(counters));
+
+      runway_sample(std::size(counters) + 1, [&](size_t size) {
+        for (std::size_t i = 0; i < size; ++i) {
+          std::allocator_traits<Alloc>::construct(alloc, std::addressof(pool[i]), &counters[i]);
+        }
+        assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 1; }));
+
+        std::destroy_n(policy, Iter(pool), size);
+        ASSERT_SAME_TYPE(decltype(std::destroy_n(policy, Iter(pool), size)), void);
+        assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 0; }));
+      });
+
+      std::allocator_traits<Alloc>::deallocate(alloc, pool, std::size(counters));
+    }
+  }
+};
+
+#if TEST_STD_VER > 17
----------------
ldionne wrote:

Same comments apply to this file!

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


More information about the libcxx-commits mailing list