The support table (https://en.cppreference.com/w/cpp/compiler_support.html) lists std::execution::unseq as implemented but it is missing in 15 STABLE. The example from https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag.html fails to compile with -DPARALLEL.
For reference: # c++ -std=c++20 -DPARALLEL unseq_test.cc unseq_test.cc:34:24: error: no member named 'seq' in namespace 'std::execution' 34 | measure(execution::seq, v); | ~~~~~~~~~~~^ unseq_test.cc:35:24: error: no member named 'unseq' in namespace 'std::execution' 35 | measure(execution::unseq, v); | ~~~~~~~~~~~^ unseq_test.cc:36:24: error: no member named 'par_unseq' in namespace 'std::execution' 36 | measure(execution::par_unseq, v); | ~~~~~~~~~~~^ unseq_test.cc:37:24: error: no member named 'par' in namespace 'std::execution' 37 | measure(execution::par, v); | ~~~~~~~~~~~^ 4 errors generated. The same happens on both, for example (note the 1500502 and 1600004): # uname -apKU FreeBSD 7950X3D-ZFS 16.0-CURRENT FreeBSD 16.0-CURRENT main-n281922-4872b48b175c GENERIC-NODEBUG amd64 amd64 1600004 1500502 # uname -apKU FreeBSD aarch64-main-pbase 16.0-CURRENT FreeBSD 16.0-CURRENT main-n281922-4872b48b175c GENERIC-NODEBUG arm64 aarch64 1600004 1600004 I will note: # c++ -std=c++20 -fexperimental-library -DPARALLEL unseq_test.cc unseq_test.cc:34:13: error: call to deleted constructor of 'std::execution::sequenced_policy' 34 | measure(execution::seq, v); | ^~~~~~~~~~~~~~ /usr/include/c++/v1/execution:52:3: note: 'sequenced_policy' has been explicitly marked deleted here 52 | sequenced_policy(const sequenced_policy&) = delete; | ^ unseq_test.cc:15:36: note: passing argument to parameter 'policy' here 15 | void measure([[maybe_unused]] auto policy, std::vector<std::uint64_t> v) | ^ unseq_test.cc:35:13: error: call to deleted constructor of 'std::execution::unsequenced_policy' 35 | measure(execution::unseq, v); | ^~~~~~~~~~~~~~~~ /usr/include/c++/v1/execution:86:3: note: 'unsequenced_policy' has been explicitly marked deleted here 86 | unsequenced_policy(const unsequenced_policy&) = delete; | ^ unseq_test.cc:15:36: note: passing argument to parameter 'policy' here 15 | void measure([[maybe_unused]] auto policy, std::vector<std::uint64_t> v) | ^ unseq_test.cc:36:13: error: call to deleted constructor of 'std::execution::parallel_unsequenced_policy' 36 | measure(execution::par_unseq, v); | ^~~~~~~~~~~~~~~~~~~~ /usr/include/c++/v1/execution:68:3: note: 'parallel_unsequenced_policy' has been explicitly marked deleted here 68 | parallel_unsequenced_policy(const parallel_unsequenced_policy&) = delete; | ^ unseq_test.cc:15:36: note: passing argument to parameter 'policy' here 15 | void measure([[maybe_unused]] auto policy, std::vector<std::uint64_t> v) | ^ unseq_test.cc:37:13: error: call to deleted constructor of 'std::execution::parallel_policy' 37 | measure(execution::par, v); | ^~~~~~~~~~~~~~ /usr/include/c++/v1/execution:60:3: note: 'parallel_policy' has been explicitly marked deleted here 60 | parallel_policy(const parallel_policy&) = delete; | ^ unseq_test.cc:15:36: note: passing argument to parameter 'policy' here 15 | void measure([[maybe_unused]] auto policy, std::vector<std::uint64_t> v) | ^ 4 errors generated. I wonder if this is an upstream issue relative to llvm19's libc++ . For reference: # g++15 -std=c++20 -DPARALLEL -Wl,-rpath=/usr/local/lib/gcc15 unseq_test.cc # ./a.out 341ms 341ms 339ms 339ms But on aarch64 main 16: # g++15 -std=c++20 -DPARALLEL unseq_test.cc # ./a.out ld-elf.so.1: /lib/libgcc_s.so.1: version GCC_4.5.0 required by /root/c_tests/a.out not found
The system llvm19 libc++ has . . . contrib/llvm-project/libcxx/modules/std/execution.inc with: // -*- 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 // //===----------------------------------------------------------------------===// #ifdef _LIBCPP_ENABLE_EXPERIMENTAL export namespace std { // [execpol.type], execution policy type trait using std::is_execution_policy; using std::is_execution_policy_v; } // namespace std export namespace std::execution { // [execpol.seq], sequenced execution policy using std::execution::sequenced_policy; // [execpol.par], parallel execution policy using std::execution::parallel_policy; // [execpol.parunseq], parallel and unsequenced execution policy using std::execution::parallel_unsequenced_policy; // [execpol.unseq], unsequenced execution policy using std::execution::unsequenced_policy; // [execpol.objects], execution policy objects using std::execution::par; using std::execution::par_unseq; using std::execution::seq; using std::execution::unseq; } // namespace std::execution #endif // _LIBCPP_ENABLE_EXPERIMENTAL So your reference material that you based the submittal on is just wrong as of llvm19 --unless it considers requiring use of -fexperimental-library to enable that part of the library as still being supported. And, my earlier report shows it is not actually supported even with -fexperimental-library specified. It looks to be an upstream issue, not a FreeBSD one. This was submitted to the wrong place.
(In reply to Mark Millard from comment #2) That was for a modules context. Going the other way . . . contrib/llvm-project/libcxx/include/exception has: #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_STD namespace execution { struct sequenced_policy { _LIBCPP_HIDE_FROM_ABI 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{}}; . . . (In reply to Mark Millard from comment #2) That was for a modules context. Going the other way . . . contrib/llvm-project/libcxx/include/exception has: #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_STD namespace execution { struct sequenced_policy { _LIBCPP_HIDE_FROM_ABI 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{}}; . . . # if _LIBCPP_STD_VER >= 20 struct unsequenced_policy { _LIBCPP_HIDE_FROM_ABI 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 . . . where contrib/llvm-project/libcxx/include/__config has: // Incomplete features get their own specific disabling flags. This makes it // easier to grep for target specific flags once the feature is complete. # if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY) # define _LIBCPP_HAS_NO_INCOMPLETE_PSTL # define _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN # define _LIBCPP_HAS_NO_EXPERIMENTAL_TZDB # define _LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM # endif And, again, -fexperimental-library is sufficient to end up with !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) . [But so is defined(_LIBCPP_BUILDING_LIBRARY) sufficient for that.]
(In reply to Mark Millard from comment #3) See: https://libcxx.llvm.org/Status/PSTL.html To see just how incomplete the parallel STL support is. So _LIBCPP_HAS_NO_INCOMPLETE_PSTL looks like it will be defined for a long time in default builds.