[libc++][PSTL] Implement <execution> contents
authorNikolas Klauser <nikolasklauser@berlin.de>
Fri, 13 Jan 2023 21:48:23 +0000 (22:48 +0100)
committerNikolas Klauser <n_klauser@apple.com>
Sun, 30 Apr 2023 03:41:38 +0000 (20:41 -0700)
Reviewed By: ldionne, #libc

Spies: libcxx-commits, arichardson

Differential Revision: https://reviews.llvm.org/D141888

libcxx/include/CMakeLists.txt
libcxx/include/__pstl/internal/glue_execution_defs.h [deleted file]
libcxx/include/__pstl_execution [deleted file]
libcxx/include/execution
libcxx/test/libcxx/utilities/expol/policies.compile.pass.cpp [new file with mode: 0644]
libcxx/test/std/utilities/expol/is_execution_policy.compile.pass.cpp [new file with mode: 0644]
libcxx/test/std/utilities/expol/policies.compile.pass.cpp [new file with mode: 0644]

index 3081dc3..d9a9fd5 100644 (file)
@@ -506,7 +506,6 @@ set(files
   __pstl/internal/execution_impl.h
   __pstl/internal/glue_algorithm_defs.h
   __pstl/internal/glue_algorithm_impl.h
-  __pstl/internal/glue_execution_defs.h
   __pstl/internal/glue_memory_defs.h
   __pstl/internal/glue_memory_impl.h
   __pstl/internal/glue_numeric_defs.h
@@ -534,7 +533,6 @@ set(files
   __pstl/internal/unseq_backend_simd.h
   __pstl/internal/utils.h
   __pstl_algorithm
-  __pstl_execution
   __pstl_memory
   __pstl_numeric
   __random/bernoulli_distribution.h
diff --git a/libcxx/include/__pstl/internal/glue_execution_defs.h b/libcxx/include/__pstl/internal/glue_execution_defs.h
deleted file mode 100644 (file)
index 8992667..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _PSTL_GLUE_EXECUTION_DEFS_H
-#define _PSTL_GLUE_EXECUTION_DEFS_H
-
-#include <type_traits>
-
-#include "execution_defs.h"
-#include "pstl_config.h"
-
-namespace std {
-// Type trait
-using __pstl::execution::is_execution_policy;
-#if defined(_PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT)
-#  if defined(__INTEL_COMPILER)
-template <class T>
-constexpr bool is_execution_policy_v = is_execution_policy<T>::value;
-#  else
-using __pstl::execution::is_execution_policy_v;
-#  endif
-#endif
-
-namespace execution {
-// Standard C++ policy classes
-using __pstl::execution::parallel_policy;
-using __pstl::execution::parallel_unsequenced_policy;
-using __pstl::execution::sequenced_policy;
-
-// Standard predefined policy instances
-using __pstl::execution::par;
-using __pstl::execution::par_unseq;
-using __pstl::execution::seq;
-
-// Implementation-defined names
-// Unsequenced policy is not yet standard, but for consistency
-// we include it into namespace std::execution as well
-using __pstl::execution::unseq;
-using __pstl::execution::unsequenced_policy;
-} // namespace execution
-} // namespace std
-
-#include "algorithm_impl.h"
-#include "numeric_impl.h"
-#include "parallel_backend.h"
-
-#endif /* _PSTL_GLUE_EXECUTION_DEFS_H */
diff --git a/libcxx/include/__pstl_execution b/libcxx/include/__pstl_execution
deleted file mode 100644 (file)
index 0e2cd44..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __PSTL_EXECUTION
-#define __PSTL_EXECUTION
-
-#include <pstl/internal/glue_execution_defs.h>
-
-#endif /* __PSTL_EXECUTION */
index b68cdfa..2caa608 100644 (file)
 #ifndef _LIBCPP_EXECUTION
 #define _LIBCPP_EXECUTION
 
+/*
+namespace std::execution {
+  struct sequenced_policy;
+  struct parallel_policy;
+  struct parallel_unsequenced_policy;
+  struct unsequenced_policy; // since C++20
+
+  inline constexpr sequenced_policy seq = implementation-defined;
+  inline constexpr parallel_policy par = implementation-defined;
+  inline constexpr parallel_unsequenced_policy par_unseq = implementation-defined;
+  inline constexpr unsequenced_policy unseq = implementation-defined; // since C++20
+}
+
+namespace std {
+  template <class T>
+  struct is_execution_policy;
+
+  template <class T>
+  inline constexpr bool is_execution_policy_v;
+}
+*/
+
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__type_traits/integral_constant.h>
 #include <version>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace execution {
+struct __disable_user_instantiations_tag {
+  explicit __disable_user_instantiations_tag() = default;
+};
+
+struct sequenced_policy {
+  constexpr explicit sequenced_policy(__disable_user_instantiations_tag) {}
+  sequenced_policy(const sequenced_policy&)            = delete;
+  sequenced_policy& operator=(const sequenced_policy&) = delete;
+};
+
+inline constexpr sequenced_policy seq{__disable_user_instantiations_tag{}};
+
+struct parallel_policy {
+  constexpr explicit parallel_policy(__disable_user_instantiations_tag) {}
+  parallel_policy(const parallel_policy&)            = delete;
+  parallel_policy& operator=(const parallel_policy&) = delete;
+};
+
+inline constexpr parallel_policy par{__disable_user_instantiations_tag{}};
+
+struct parallel_unsequenced_policy {
+  constexpr explicit parallel_unsequenced_policy(__disable_user_instantiations_tag) {}
+  parallel_unsequenced_policy(const parallel_unsequenced_policy&)            = delete;
+  parallel_unsequenced_policy& operator=(const parallel_unsequenced_policy&) = delete;
+};
+
+inline constexpr parallel_unsequenced_policy par_unseq{__disable_user_instantiations_tag{}};
+
+#  if _LIBCPP_STD_VER >= 20
+
+struct unsequenced_policy {
+  constexpr explicit unsequenced_policy(__disable_user_instantiations_tag) {}
+  unsequenced_policy(const unsequenced_policy&)            = delete;
+  unsequenced_policy& operator=(const unsequenced_policy&) = delete;
+};
+
+inline constexpr unsequenced_policy unseq{__disable_user_instantiations_tag{}};
+
+#  endif // _LIBCPP_STD_VER >= 20
+
+} // namespace execution
+
+template <class>
+inline constexpr bool is_execution_policy_v = false;
+
+template <>
+inline constexpr bool is_execution_policy_v<execution::sequenced_policy> = true;
+
+template <>
+inline constexpr bool is_execution_policy_v<execution::parallel_policy> = true;
+
+template <>
+inline constexpr bool is_execution_policy_v<execution::parallel_unsequenced_policy> = true;
+
+#  if _LIBCPP_STD_VER >= 20
+template <>
+inline constexpr bool is_execution_policy_v<execution::unsequenced_policy> = true;
+#  endif
+
+template <class _Tp>
+struct is_execution_policy : bool_constant<is_execution_policy_v<_Tp>> {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
+
 #endif // _LIBCPP_EXECUTION
diff --git a/libcxx/test/libcxx/utilities/expol/policies.compile.pass.cpp b/libcxx/test/libcxx/utilities/expol/policies.compile.pass.cpp
new file mode 100644 (file)
index 0000000..fb97cff
--- /dev/null
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure we don't allow copying the execution policies in any way to avoid users relying on it.
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// REQUIRES: with-pstl
+
+#include <execution>
+#include <type_traits>
+
+#include "test_macros.h"
+
+static_assert(!std::is_default_constructible_v<std::execution::sequenced_policy>);
+static_assert(!std::is_copy_constructible_v<std::execution::sequenced_policy>);
+static_assert(!std::is_move_constructible_v<std::execution::sequenced_policy>);
+static_assert(!std::is_copy_assignable_v<std::execution::sequenced_policy>);
+static_assert(!std::is_move_assignable_v<std::execution::sequenced_policy>);
+
+static_assert(!std::is_default_constructible_v<std::execution::parallel_policy>);
+static_assert(!std::is_copy_constructible_v<std::execution::parallel_policy>);
+static_assert(!std::is_move_constructible_v<std::execution::parallel_policy>);
+static_assert(!std::is_copy_assignable_v<std::execution::parallel_policy>);
+static_assert(!std::is_move_assignable_v<std::execution::parallel_policy>);
+
+static_assert(!std::is_default_constructible_v<std::execution::parallel_unsequenced_policy>);
+static_assert(!std::is_copy_constructible_v<std::execution::parallel_unsequenced_policy>);
+static_assert(!std::is_move_constructible_v<std::execution::parallel_unsequenced_policy>);
+static_assert(!std::is_copy_assignable_v<std::execution::parallel_unsequenced_policy>);
+static_assert(!std::is_move_assignable_v<std::execution::parallel_unsequenced_policy>);
+
+#if TEST_STD_VER >= 20
+static_assert(!std::is_default_constructible_v<std::execution::unsequenced_policy>);
+static_assert(!std::is_copy_constructible_v<std::execution::unsequenced_policy>);
+static_assert(!std::is_move_constructible_v<std::execution::unsequenced_policy>);
+static_assert(!std::is_copy_assignable_v<std::execution::unsequenced_policy>);
+static_assert(!std::is_move_assignable_v<std::execution::unsequenced_policy>);
+#endif
diff --git a/libcxx/test/std/utilities/expol/is_execution_policy.compile.pass.cpp b/libcxx/test/std/utilities/expol/is_execution_policy.compile.pass.cpp
new file mode 100644 (file)
index 0000000..57845c5
--- /dev/null
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// template<class T> struct is_execution_policy;
+// template<class T> constexpr bool is_execution_policy_v = is_execution_policy<T>::value;
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// REQUIRES: with-pstl
+
+#include <execution>
+
+#include "test_macros.h"
+
+static_assert(std::is_execution_policy<std::execution::sequenced_policy>::value);
+static_assert(std::is_execution_policy_v<std::execution::sequenced_policy>);
+static_assert(std::is_execution_policy<std::execution::parallel_policy>::value);
+static_assert(std::is_execution_policy_v<std::execution::parallel_policy>);
+static_assert(std::is_execution_policy<std::execution::parallel_unsequenced_policy>::value);
+static_assert(std::is_execution_policy_v<std::execution::parallel_unsequenced_policy>);
+
+#if TEST_STD_VER >= 20
+static_assert(std::is_execution_policy<std::execution::unsequenced_policy>::value);
+static_assert(std::is_execution_policy_v<std::execution::unsequenced_policy>);
+#endif
diff --git a/libcxx/test/std/utilities/expol/policies.compile.pass.cpp b/libcxx/test/std/utilities/expol/policies.compile.pass.cpp
new file mode 100644 (file)
index 0000000..4de439f
--- /dev/null
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// class sequenced_policy;
+// class parallel_policy;
+// class parallel_unsequenced_policy;
+// class unsequenced_policy; // since C++20
+//
+// inline constexpr sequenced_policy seq = implementation-defined;
+// inline constexpr parallel_policy par = implementation-defined;
+// inline constexpr parallel_unsequenced_policy par_unseq = implementation-defined;
+// inline constexpr unsequenced_policy unseq = implementation-defined; // since C++20
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// REQUIRES: with-pstl
+
+#include <execution>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class T>
+using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
+
+template <class T>
+TEST_NOINLINE void use(T&) {}
+
+static_assert(std::is_same_v<remove_cvref_t<decltype(std::execution::seq)>, std::execution::sequenced_policy>);
+static_assert(std::is_same_v<remove_cvref_t<decltype(std::execution::par)>, std::execution::parallel_policy>);
+static_assert(
+    std::is_same_v<remove_cvref_t<decltype(std::execution::par_unseq)>, std::execution::parallel_unsequenced_policy>);
+
+#if TEST_STD_VER >= 20
+static_assert(std::is_same_v<remove_cvref_t<decltype(std::execution::unseq)>, std::execution::unsequenced_policy>);
+#endif
+
+int main(int, char**) {
+  use(std::execution::seq);
+  use(std::execution::par);
+  use(std::execution::par_unseq);
+#if TEST_STD_VER >= 20
+  use(std::execution::unseq);
+#endif
+}