[clang-tools-extra] [libcxx] [clang] [llvm] [libcxx] adds ranges::fold_left_with_iter and ranges::fold_left (PR #75259)

2023-12-28 Thread Christopher Di Bella via cfe-commits


@@ -0,0 +1,118 @@
+// -*- 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 _LIBCPP___ALGORITHM_FOLD_H
+#define _LIBCPP___ALGORITHM_FOLD_H
+
+#include <__concepts/assignable.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/invocable.h>
+#include <__concepts/movable.h>
+#include <__config>
+#include <__functional/invoke.h>
+#include <__functional/reference_wrapper.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/invoke.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+template 
+struct in_value_result {
+  _Ip in;
+  _Tp result;
+};
+
+template 
+using fold_left_with_iter_result = in_value_result<_Ip, _Tp>;
+
+template >
+concept __indirectly_binary_left_foldable_impl =
+convertible_to<_Rp, _Up> &&//
+movable<_Tp> &&//
+movable<_Up> &&//
+convertible_to<_Tp, _Up> &&//
+invocable<_Fp&, _Up, iter_reference_t<_Ip>> && //
+assignable_from<_Up&, invoke_result_t<_Fp&, _Up, iter_reference_t<_Ip>>>;
+
+template 
+concept __indirectly_binary_left_foldable =
+copy_constructible<_Fp> && //
+invocable<_Fp&, _Tp, iter_reference_t<_Ip>> && //
+__indirectly_binary_left_foldable_impl<_Fp, _Tp, _Ip, 
invoke_result_t<_Fp&, _Tp, iter_reference_t<_Ip>>>;
+
+struct __fold_left_with_iter {
+  template  _Sp, class _Tp, 
__indirectly_binary_left_foldable<_Tp, _Ip> _Fp>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto
+  operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) {
+using _Up = decay_t>>;
+
+if (__first == __last) {
+  return fold_left_with_iter_result<_Ip, _Up>{std::move(__first), 
_Up(std::move(__init))};
+}
+
+_Up __result = std::invoke(__f, std::move(__init), *__first);
+for (++__first; __first != __last; ++__first) {
+  __result = std::invoke(__f, std::move(__result), *__first);
+}
+
+return fold_left_with_iter_result<_Ip, _Up>{std::move(__first), 
std::move(__result)};
+  }
+
+  template > _Fp>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto 
operator()(_Rp&& __r, _Tp __init, _Fp __f) {
+auto __result = operator()(ranges::begin(__r), ranges::end(__r), 
std::move(__init), std::ref(__f));
+
+using _Up = decay_t>>;
+return fold_left_with_iter_result, _Up>{
+std::move(__result.in), std::move(__result.result)};
+  }
+};
+
+inline namespace __cpo {
+inline constexpr auto fold_left_with_iter = __fold_left_with_iter();
+} // namespace __cpo
+
+struct __fold_left {
+  template  _Sp, class _Tp, 
__indirectly_binary_left_foldable<_Tp, _Ip> _Fp>

cjdb wrote:

I am okay with the current resolution given that a discussion has happened, and 
am happy to make a dedicated migration patch for all `_Ip`/`_Sp` names. This 
has **not** been applied in #76534: I'll make a dedicated commit for that in 
about an hour.

I think that the contribution guidelines should probably issue guidance on what 
kinds of names we expect, especially when it comes to names that we want to 
have some element of consistency for. Perhaps that could be the subject of the 
new discussion.

https://github.com/llvm/llvm-project/pull/75259
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [libcxx] [clang] [llvm] [libcxx] adds ranges::fold_left_with_iter and ranges::fold_left (PR #75259)

2023-12-28 Thread Christopher Di Bella via cfe-commits


@@ -0,0 +1,315 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// 
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template S, class T,
+//  indirectly-binary-left-foldable F>
+//   constexpr see below ranges::fold_left_with_iter(I first, S last, T init, 
F f);
+//
+// template> F>
+//   constexpr see below ranges::fold_left_with_iter(R&& r, T init, F f);
+
+// template S, class T,
+//  indirectly-binary-left-foldable F>
+//   constexpr see below ranges::fold_left(I first, S last, T init, F f);
+//
+// template> F>
+//   constexpr see below ranges::fold_left(R&& r, T init, F f);
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_range.h"
+#include "invocable_with_telemetry.h"
+#include "maths.h"
+
+using std::ranges::fold_left;
+using std::ranges::fold_left_with_iter;
+
+template 
+concept is_in_value_result =
+std::same_as, T>>;
+
+template 
+concept is_dangling_with = std::same_as>;
+
+struct Long {

cjdb wrote:

Agreed. Renamed in #76534.

https://github.com/llvm/llvm-project/pull/75259
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [libcxx] [clang] [llvm] [libcxx] adds ranges::fold_left_with_iter and ranges::fold_left (PR #75259)

2023-12-28 Thread Christopher Di Bella via cfe-commits


@@ -0,0 +1,259 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// 
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Checks that `std::ranges::fold_left_with_iter`'s requirements reject 
parameters that don't meet

cjdb wrote:

Applied in #76534.

https://github.com/llvm/llvm-project/pull/75259
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [libcxx] [clang] [llvm] [libcxx] adds ranges::fold_left_with_iter and ranges::fold_left (PR #75259)

2023-12-28 Thread Christopher Di Bella via cfe-commits


@@ -0,0 +1,89 @@
+//===--===//
+//
+// 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 TEST_SUPPORT_INVOCABLE_WITH_TELEMETRY_H
+#define TEST_SUPPORT_INVOCABLE_WITH_TELEMETRY_H
+
+#include 
+#include 
+#include 
+#include 
+
+#if TEST_STD_VER < 20
+#  error invocable_with_telemetry requires C++20
+#else
+struct invocable_telemetry {

cjdb wrote:

Thoughts summarised in the comment below.

https://github.com/llvm/llvm-project/pull/75259
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [libcxx] [clang] [llvm] [libcxx] adds ranges::fold_left_with_iter and ranges::fold_left (PR #75259)

2023-12-21 Thread via cfe-commits


@@ -0,0 +1,104 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template 
+// struct in_value_result;
+
+#include 
+#include 
+#include 
+#include 
+
+#include "MoveOnly.h"
+
+struct A {
+  explicit A(int);
+};
+// no implicit conversion
+static_assert(!std::is_constructible_v, 
std::ranges::in_value_result>);
+
+struct B {
+  B(int);
+};
+// implicit conversion
+static_assert(std::is_constructible_v, 
std::ranges::in_value_result>);
+static_assert(std::is_constructible_v, 
std::ranges::in_value_result&>);
+static_assert(
+std::is_constructible_v, const 
std::ranges::in_value_result>);
+static_assert(
+std::is_constructible_v, const 
std::ranges::in_value_result&>);
+
+struct C {
+  C(int&);
+};
+static_assert(!std::is_constructible_v, 
std::ranges::in_value_result&>);
+
+// has to be convertible via const&
+static_assert(std::is_convertible_v&, 
std::ranges::in_value_result>);
+static_assert(
+std::is_convertible_v&, 
std::ranges::in_value_result>);
+static_assert(
+std::is_convertible_v&&, 
std::ranges::in_value_result>);
+static_assert(
+std::is_convertible_v&&, 
std::ranges::in_value_result>);
+
+// should be move constructible
+static_assert(std::is_move_constructible_v>);
+static_assert(std::is_move_constructible_v>);
+
+// should not copy constructible with move-only type
+static_assert(!std::is_copy_constructible_v>);
+static_assert(!std::is_copy_constructible_v>);
+
+struct NotConvertible {};
+// conversions should not work if there is no conversion
+static_assert(
+!std::is_convertible_v, 
std::ranges::in_value_result>);
+static_assert(
+!std::is_convertible_v, 
std::ranges::in_value_result>);
+
+template 
+struct ConvertibleFrom {
+  constexpr ConvertibleFrom(T c) : content{c} {}
+  T content;
+};
+
+constexpr bool test() {
+  {
+std::ranges::in_value_result res{10, 0.};
+assert(res.in == 10);
+assert(res.value == 0.);
+std::ranges::in_value_result, 
ConvertibleFrom> res2 = res;
+assert(res2.in.content == 10);
+assert(res2.value.content == 0.);
+  }

EricWF wrote:

Can we make clang-format do that for us? 

https://github.com/llvm/llvm-project/pull/75259
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [libcxx] [clang] [llvm] [libcxx] adds ranges::fold_left_with_iter and ranges::fold_left (PR #75259)

2023-12-21 Thread via cfe-commits


@@ -0,0 +1,104 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template 
+// struct in_value_result;
+
+#include 
+#include 
+#include 
+#include 
+
+#include "MoveOnly.h"
+
+struct A {
+  explicit A(int);
+};
+// no implicit conversion
+static_assert(!std::is_constructible_v, 
std::ranges::in_value_result>);
+
+struct B {
+  B(int);
+};
+// implicit conversion
+static_assert(std::is_constructible_v, 
std::ranges::in_value_result>);
+static_assert(std::is_constructible_v, 
std::ranges::in_value_result&>);
+static_assert(
+std::is_constructible_v, const 
std::ranges::in_value_result>);
+static_assert(
+std::is_constructible_v, const 
std::ranges::in_value_result&>);
+
+struct C {
+  C(int&);
+};
+static_assert(!std::is_constructible_v, 
std::ranges::in_value_result&>);
+
+// has to be convertible via const&
+static_assert(std::is_convertible_v&, 
std::ranges::in_value_result>);
+static_assert(
+std::is_convertible_v&, 
std::ranges::in_value_result>);
+static_assert(
+std::is_convertible_v&&, 
std::ranges::in_value_result>);
+static_assert(
+std::is_convertible_v&&, 
std::ranges::in_value_result>);
+
+// should be move constructible
+static_assert(std::is_move_constructible_v>);
+static_assert(std::is_move_constructible_v>);
+
+// should not copy constructible with move-only type

EricWF wrote:

Attaching to this comment, because the comment about names is attached to the 
same line.

I think the project should document any policies we wish to enforce inside our 
documentation. That way we aren't depending on the visibility of conversations, 
and we have a place to scope our discussions of said policy. Changes to the 
policy can then happen in PR's changing the documentation.  Further, it better 
provides all contributors the ability to weigh in, hopefully at the time, but 
also after the fact.

To keep in with my suggestion, I will create a PR documenting our documenting 
policy to root this discussion under.

https://github.com/llvm/llvm-project/pull/75259
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits