[libcxx-commits] [libcxx] [libc++][PSTL] Add backend for forwaring to mem functions (PR #102448)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 15 09:41:36 PDT 2024
================
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 _LIBCPP___PSTL_BACKENDS_FORWARD_TO_MEM_FUNCS_H
+#define _LIBCPP___PSTL_BACKENDS_FORWARD_TO_MEM_FUNCS_H
+
+#include <__algorithm/copy_move_common.h>
+#include <__algorithm/equal.h>
+#include <__config>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/dispatch.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _ExecutionPolicy>
+struct __copy<__forward_to_mem_funcs_backend_tag, _ExecutionPolicy> {
+ template <class _Policy,
+ class _In,
+ class _Out,
+ enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_Out*>
+ operator()(_Policy&&, _In* __first, _In* __last, _Out* __result) const noexcept {
+ return std::__constexpr_memmove(__result, __first, __element_count(__last - __first));
+ }
----------------
ldionne wrote:
I would like to drive towards something like this:
```c++
template <class _Policy, class _InputIterator, class _OutputIterator>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_OutputIterator>
operator()(_Policy&&, _InputIterator __first, _InputIterator __last, _OutputIterator __result) const noexcept {
using _In = typename iterator_traits<_InputIterator>::value_type;
using _Out = typename iterator_traits<_OutputIterator>::value_type;
if constexpr (__can_lower_copy_assignment_to_memmove<_In, _Out>::value && contiguous_iterator<whatever>) {
return std::__constexpr_memmove(std::__to_address(__result), std::__to_address(__first), __element_count(__last - __first));
} else {
using _NextBackend = __find_next_backend<__current_configuration, __forward_to_mem_funcs_backend_tag>; // This basically gives you the first backend that has an implementation for this algo after __forward_to_mem_funcs_backend_tag.
}
}
```
This makes it less likely that invalid SFINAE will silently result in this implementation being skipped. I would also really really like to keep a single level of specialization+tag based dispatching, instead of also bringing in SFINAE of the `operator()` itself.
I think we might need to do something like:
```c++
template <class _ExecutionPolicy, class _BackendConfiguration>
struct __copy<__forward_to_mem_funcs_backend_tag, _ExecutionPolicy, _BackendConfiguration> {
// Use _BackendConfiguration to dispatch to the next. That backend configuration represents the cursor within the `__backend_configuration<...>` object, basically.
};
```
Alternatively, we can also decide to bundle multiple things in a single template parameter, which might make things more future proof:
```c++
template <class _DispatchArguments>
struct __copy<__forward_to_mem_funcs_backend_tag, _DispatchArguments> {
// Use _DispatchArguments::__backend_configuration
// or _DispatchArguments::__execution_policy
// or maybe more in the future.
};
```
https://github.com/llvm/llvm-project/pull/102448
More information about the libcxx-commits
mailing list