[libcxx-commits] [PATCH] D60480: [libc++] Integrate the PSTL into libc++

Richard Smith - zygoloid via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jun 25 15:23:30 PDT 2019


rsmith added inline comments.


================
Comment at: libcxx/include/algorithm:5790
+// otherwise just pull in forward declarations.
+#include <pstl/internal/pstl_config.h>
+#if defined(__PSTL_EXECUTION_POLICIES_DEFINED)
----------------
dexonsmith wrote:
> ldionne wrote:
> > EricWF wrote:
> > > ldionne wrote:
> > > > The same pattern is repeated in other files. Basically, we check whether `<execution>` has been included, and if so, then we provide all the definitions. Otherwise, we just provide forward declarations to avoid the compile-time overhead if you just `#include <algorithm>` but don't care about the parallel algorithms.
> > > > 
> > > I really really really dislike this pattern. We shouldn't do it.
> > > I don't think this is how you should structure a library.
> > > 
> > > Are there other alternatives?
> > I dislike it too. The only alternative I can think of is to unconditionally include the definitions, however this may impose a compile-time hit on everyone that's not using the parallel algorithms.
> @bruno, will this pattern cause a problem for Clang modules (esp. with local submodule visibility)?
This won't work with modules (neither Clang modules with local submodule visibility, nor C++20 modules). We will build `<algorithm>` in a context where `<execution>` has not been included, and vice versa, and neither of them will contain definitions of the parallel algorithms. More fundamentally, we should not be trying to create a situation where we have two headers and including both of them together provides more content than the union of the content provided by including the two separately -- that's bad header design and inevitably will lead to problems.

One possible alternative design approach:

 * `<algorithm>` provides definitions of the algorithms that forward to `ExecutionPolicy::__<algorithm>(<args>)` if they exist, or otherwise forward to the non-execution-policy overload if `ExecutionPolicy::<some tag member>` exists (indicating that the template argument was a real execution policy that just doesn't happen to specialize that algorithm), and otherwise produce an error that the argument is not an execution policy.
 * `<execution>` defines the specialized algorithms for each execution policy as static member functions on the execution policy.

This adds minimal cost to code that only includes `<algorithm>` and not `<execution>` while keeping both headers modular. It also supports the easy addition of new implementation-specific execution policies, defining one policy as a refinement of another, and gives an easy way for an implementation to be conforming in the absence of a `pstl` implementation (or to provide an easy non-parallel implementation for single-threaded builds): just define the execution policy objects with no members other than the "I'm a real execution policy" tag member.

Would that work?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60480/new/

https://reviews.llvm.org/D60480





More information about the libcxx-commits mailing list