[Lldb-commits] [libcxx] [compiler-rt] [libunwind] [llvm] [clang] [libc] [flang] [clang-tools-extra] [lldb] [libc++] Implement ranges::iota (PR #68494)

2023-12-19 Thread James E T Smith via lldb-commits

https://github.com/jamesETsmith updated 
https://github.com/llvm/llvm-project/pull/68494

>From c4a3ccfbad090ad8314aa8ad53092edc8d5432bc Mon Sep 17 00:00:00 2001
From: James Smith 
Date: Thu, 28 Sep 2023 10:11:15 -0400
Subject: [PATCH 01/18] [libc++] Implement ranges::iota and
 ranges::out_value_result

---
 libcxx/include/CMakeLists.txt |   2 +
 libcxx/include/__algorithm/out_value_result.h |  52 +
 libcxx/include/__numeric/ranges_iota.h|  53 +
 libcxx/include/algorithm  |   4 +
 libcxx/include/numeric|   1 +
 libcxx/include/version|   2 +-
 .../out_value_result.pass.cpp | 102 ++
 .../numeric.iota/ranges.iota.pass.cpp |  52 +
 8 files changed, 267 insertions(+), 1 deletion(-)
 create mode 100644 libcxx/include/__algorithm/out_value_result.h
 create mode 100644 libcxx/include/__numeric/ranges_iota.h
 create mode 100644 
libcxx/test/std/algorithms/algorithms.results/out_value_result.pass.cpp
 create mode 100644 
libcxx/test/std/numerics/numeric.ops/numeric.iota/ranges.iota.pass.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 2ec755236dbaee..c6eb03f1d68e98 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -63,6 +63,7 @@ set(files
   __algorithm/next_permutation.h
   __algorithm/none_of.h
   __algorithm/nth_element.h
+  __algorithm/out_value_result.h
   __algorithm/partial_sort.h
   __algorithm/partial_sort_copy.h
   __algorithm/partition.h
@@ -561,6 +562,7 @@ set(files
   __numeric/partial_sum.h
   __numeric/pstl_reduce.h
   __numeric/pstl_transform_reduce.h
+  __numeric/ranges_iota.h
   __numeric/reduce.h
   __numeric/transform_exclusive_scan.h
   __numeric/transform_inclusive_scan.h
diff --git a/libcxx/include/__algorithm/out_value_result.h 
b/libcxx/include/__algorithm/out_value_result.h
new file mode 100644
index 00..8baffec7b9ef4d
--- /dev/null
+++ b/libcxx/include/__algorithm/out_value_result.h
@@ -0,0 +1,52 @@
+// -*- 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_OUT_VALUE_RESULT_H
+#define _LIBCPP___ALGORITHM_OUT_VALUE_RESULT_H
+
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template 
+struct out_value_result {
+  _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
+  _LIBCPP_NO_UNIQUE_ADDRESS _ValType1 value;
+
+  template 
+requires convertible_to && 
convertible_to
+  constexpr operator out_value_result<_OutIter2, _ValType2>() const& { return 
{out, value}; }
+
+  template 
+requires convertible_to<_OutIter1, _OutIter2> && convertible_to<_ValType1, 
_ValType2>
+  constexpr operator out_value_result<_OutIter2, _ValType2>() && { return 
{std::move(out), std::move(value)}; }
+};
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_OUT_VALUE_RESULT_H
diff --git a/libcxx/include/__numeric/ranges_iota.h 
b/libcxx/include/__numeric/ranges_iota.h
new file mode 100644
index 00..20311a68c2a348
--- /dev/null
+++ b/libcxx/include/__numeric/ranges_iota.h
@@ -0,0 +1,53 @@
+// -*- 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___NUMERIC_RANGES_IOTA_H
+#define _LIBCPP___NUMERIC_RANGES_IOTA_H
+
+#include <__algorithm/out_value_result.h>
+#include <__config>
+#include <__ranges/concepts.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 
+using iota_result = ranges::out_value_result<_Out, _Tp>;
+
+struct __iota_fn {
+  template  _Sent, 
weakly_incrementable _Tp>
+requires indirectly_writable<_Out, const _Tp&>
+  constexpr iota_result<_Out, _Tp> operator()(_Out __first, _Sent __last, _Tp 
__value) const {
+while (__first != __last) {
+  *__first = static_cast(__value);
+  ++__first;
+  ++__value;
+}
+return {std::move(__first), std::move(__value)};
+

[Lldb-commits] [llvm] [libunwind] [libc] [libcxx] [clang] [flang] [lldb] [clang-tools-extra] [compiler-rt] [libc++] Implement ranges::iota (PR #68494)

2023-12-19 Thread James E T Smith via lldb-commits

https://github.com/jamesETsmith updated 
https://github.com/llvm/llvm-project/pull/68494

>From c4a3ccfbad090ad8314aa8ad53092edc8d5432bc Mon Sep 17 00:00:00 2001
From: James Smith 
Date: Thu, 28 Sep 2023 10:11:15 -0400
Subject: [PATCH 01/19] [libc++] Implement ranges::iota and
 ranges::out_value_result

---
 libcxx/include/CMakeLists.txt |   2 +
 libcxx/include/__algorithm/out_value_result.h |  52 +
 libcxx/include/__numeric/ranges_iota.h|  53 +
 libcxx/include/algorithm  |   4 +
 libcxx/include/numeric|   1 +
 libcxx/include/version|   2 +-
 .../out_value_result.pass.cpp | 102 ++
 .../numeric.iota/ranges.iota.pass.cpp |  52 +
 8 files changed, 267 insertions(+), 1 deletion(-)
 create mode 100644 libcxx/include/__algorithm/out_value_result.h
 create mode 100644 libcxx/include/__numeric/ranges_iota.h
 create mode 100644 
libcxx/test/std/algorithms/algorithms.results/out_value_result.pass.cpp
 create mode 100644 
libcxx/test/std/numerics/numeric.ops/numeric.iota/ranges.iota.pass.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 2ec755236dbaee..c6eb03f1d68e98 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -63,6 +63,7 @@ set(files
   __algorithm/next_permutation.h
   __algorithm/none_of.h
   __algorithm/nth_element.h
+  __algorithm/out_value_result.h
   __algorithm/partial_sort.h
   __algorithm/partial_sort_copy.h
   __algorithm/partition.h
@@ -561,6 +562,7 @@ set(files
   __numeric/partial_sum.h
   __numeric/pstl_reduce.h
   __numeric/pstl_transform_reduce.h
+  __numeric/ranges_iota.h
   __numeric/reduce.h
   __numeric/transform_exclusive_scan.h
   __numeric/transform_inclusive_scan.h
diff --git a/libcxx/include/__algorithm/out_value_result.h 
b/libcxx/include/__algorithm/out_value_result.h
new file mode 100644
index 00..8baffec7b9ef4d
--- /dev/null
+++ b/libcxx/include/__algorithm/out_value_result.h
@@ -0,0 +1,52 @@
+// -*- 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_OUT_VALUE_RESULT_H
+#define _LIBCPP___ALGORITHM_OUT_VALUE_RESULT_H
+
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template 
+struct out_value_result {
+  _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
+  _LIBCPP_NO_UNIQUE_ADDRESS _ValType1 value;
+
+  template 
+requires convertible_to && 
convertible_to
+  constexpr operator out_value_result<_OutIter2, _ValType2>() const& { return 
{out, value}; }
+
+  template 
+requires convertible_to<_OutIter1, _OutIter2> && convertible_to<_ValType1, 
_ValType2>
+  constexpr operator out_value_result<_OutIter2, _ValType2>() && { return 
{std::move(out), std::move(value)}; }
+};
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_OUT_VALUE_RESULT_H
diff --git a/libcxx/include/__numeric/ranges_iota.h 
b/libcxx/include/__numeric/ranges_iota.h
new file mode 100644
index 00..20311a68c2a348
--- /dev/null
+++ b/libcxx/include/__numeric/ranges_iota.h
@@ -0,0 +1,53 @@
+// -*- 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___NUMERIC_RANGES_IOTA_H
+#define _LIBCPP___NUMERIC_RANGES_IOTA_H
+
+#include <__algorithm/out_value_result.h>
+#include <__config>
+#include <__ranges/concepts.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 
+using iota_result = ranges::out_value_result<_Out, _Tp>;
+
+struct __iota_fn {
+  template  _Sent, 
weakly_incrementable _Tp>
+requires indirectly_writable<_Out, const _Tp&>
+  constexpr iota_result<_Out, _Tp> operator()(_Out __first, _Sent __last, _Tp 
__value) const {
+while (__first != __last) {
+  *__first = static_cast(__value);
+  ++__first;
+  ++__value;
+}
+return {std::move(__first), std::move(__value)};
+

[Lldb-commits] [libc] [compiler-rt] [libunwind] [libcxx] [llvm] [clang] [clang-tools-extra] [lldb] [flang] [libc++] Implement ranges::iota (PR #68494)

2024-01-05 Thread James E T Smith via lldb-commits


@@ -0,0 +1,123 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "almost_satisfies_types.h"
+
+// Concepts to check different overloads of std::ranges::iota
+template 
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+  std::ranges::iota(std::forward(iter), std::forward(sent), 
std::forward(val));
+};
+
+template 
+concept HasIotaRange =
+requires(Range&& range, Value&& val) { 
std::ranges::iota(std::forward(range), std::forward(val)); };
+
+constexpr void test_constraints() {
+  // Test constraints of the iterator/sentinel overload
+  // ==
+  static_assert(HasIotaIter);
+
+  // !input_or_output_iterator
+  static_assert(!HasIotaIter);
+
+  // !sentinel_for
+  static_assert(!HasIotaIter);
+  static_assert(!HasIotaIter);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaIter);
+
+  // !indirectly writable 
+  static_assert(!HasIotaIter);
+
+  // Test constraints for the range overload
+  // ===
+  static_assert(HasIotaRange, int>);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaRange, 
WeaklyIncrementableNotMovable>);
+
+  // !ranges::output_range
+  static_assert(!HasIotaRange, 
OutputIteratorNotIndirectlyWritable>);
+}
+
+template 
+constexpr void test_result(std::array input, int starting_value, 
std::array const expected) {
+  { // (iterator, sentinel) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+std::same_as> decltype(auto) 
result =
+std::ranges::iota(std::move(in_begin), std::move(in_end), 
starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+
+  // The range overload adds the additional constraint that it must be an 
outputrange
+  // so skip this for the input iterators we test
+  if constexpr (!std::is_same_v> &&
+!std::is_same_v>) { // 
(range) overload

jamesETsmith wrote:

I was running into an error similar to the one below when I wrote the test 
(which is why I added the `if constexpr`). Do you know where the `void` is 
coming from that's causing the failure in the `output_iterator` concept?

```
# | 
/home/james/apps/llvm-project/libcxx/test/std/numerics/numeric.ops/numeric.iota/ranges.iota.pass.cpp:84:7:
 error: no matching function for call to object of type 'const 
__ranges_iota::__iota_fn'
# |84 |   std::ranges::iota(range, starting_value);
# |   |   ^
# | 
/home/james/apps/llvm-project/libcxx/test/std/numerics/numeric.ops/numeric.iota/ranges.iota.pass.cpp:96:3:
 note: in instantiation of function template specialization 
'test_result, 
sentinel_wrapper>, 1UL>' requested here
# |96 |   test_result({1}, 0, {0});
# |   |   ^
# | 
/home/james/apps/llvm-project/libcxx/test/std/numerics/numeric.ops/numeric.iota/ranges.iota.pass.cpp:102:78:
 note: in instantiation of function template specialization 
'test_results, 
sentinel_wrapper>>' requested here
# |   102 |   types::for_each(types::cpp20_input_iterator_list{}, 
[] { test_results(); });
# |   | 
 ^
# | /home/james/apps/llvm-project/libcxx/test/support/type_algorithms.h:52:23: 
note: in instantiation of function template specialization 
'test_results()::(anonymous class)::operator()>' 
requested here
# |52 |   swallow((f.template operator()(), 0)...);
# |   |   ^
# | 
/home/james/apps/llvm-project/libcxx/test/std/numerics/numeric.ops/numeric.iota/ranges.iota.pass.cpp:102:10:
 note: in instantiation of function template specialization 
'types::for_each, random_access_iterator, bidirectional_iterator, forward_iterator, 
cpp20_input_iterator, cpp17_input_iterator, (lambda at 
/home/james/apps/llvm-project/libcxx/test/std/numerics/numeric.ops/numeric.iota/ranges.iota.pass.cpp:102:61)>'
 requested here
# |   102 |   types::for_each(types::cpp20_input_iterator_list{}, 
[] { test_results(); });
# |   |  ^
# | 
/home/james/apps/llvm-project/build_llvmorg-18-init-15302-g028ce92e61f1/include/c++/v1/__numeric/ranges_iota.h:56:3:
 note: candidate template ignored: constraints not satisfied [with _Tp = int, 
_Range

[Lldb-commits] [llvm] [clang-tools-extra] [clang] [lldb] [compiler-rt] [libcxx] [libunwind] [libc] [flang] [libc++] Implement ranges::iota (PR #68494)

2024-01-05 Thread James E T Smith via lldb-commits


@@ -13,7 +13,7 @@
 // Range algorithms should return `std::ranges::dangling` when given a 
dangling range.
 

jamesETsmith wrote:

I agree and apologize for accidentally formatting this, it does make the diff 
harder to read. Do you want me to revert the formatting here or just keep this 
in mind in the future?

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


[Lldb-commits] [libcxx] [clang] [clang-tools-extra] [compiler-rt] [llvm] [flang] [lldb] [libunwind] [libc] [libc++] Implement ranges::iota (PR #68494)

2024-01-05 Thread James E T Smith via lldb-commits

https://github.com/jamesETsmith updated 
https://github.com/llvm/llvm-project/pull/68494

>From c4a3ccfbad090ad8314aa8ad53092edc8d5432bc Mon Sep 17 00:00:00 2001
From: James Smith 
Date: Thu, 28 Sep 2023 10:11:15 -0400
Subject: [PATCH 01/20] [libc++] Implement ranges::iota and
 ranges::out_value_result

---
 libcxx/include/CMakeLists.txt |   2 +
 libcxx/include/__algorithm/out_value_result.h |  52 +
 libcxx/include/__numeric/ranges_iota.h|  53 +
 libcxx/include/algorithm  |   4 +
 libcxx/include/numeric|   1 +
 libcxx/include/version|   2 +-
 .../out_value_result.pass.cpp | 102 ++
 .../numeric.iota/ranges.iota.pass.cpp |  52 +
 8 files changed, 267 insertions(+), 1 deletion(-)
 create mode 100644 libcxx/include/__algorithm/out_value_result.h
 create mode 100644 libcxx/include/__numeric/ranges_iota.h
 create mode 100644 
libcxx/test/std/algorithms/algorithms.results/out_value_result.pass.cpp
 create mode 100644 
libcxx/test/std/numerics/numeric.ops/numeric.iota/ranges.iota.pass.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 2ec755236dbaee..c6eb03f1d68e98 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -63,6 +63,7 @@ set(files
   __algorithm/next_permutation.h
   __algorithm/none_of.h
   __algorithm/nth_element.h
+  __algorithm/out_value_result.h
   __algorithm/partial_sort.h
   __algorithm/partial_sort_copy.h
   __algorithm/partition.h
@@ -561,6 +562,7 @@ set(files
   __numeric/partial_sum.h
   __numeric/pstl_reduce.h
   __numeric/pstl_transform_reduce.h
+  __numeric/ranges_iota.h
   __numeric/reduce.h
   __numeric/transform_exclusive_scan.h
   __numeric/transform_inclusive_scan.h
diff --git a/libcxx/include/__algorithm/out_value_result.h 
b/libcxx/include/__algorithm/out_value_result.h
new file mode 100644
index 00..8baffec7b9ef4d
--- /dev/null
+++ b/libcxx/include/__algorithm/out_value_result.h
@@ -0,0 +1,52 @@
+// -*- 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_OUT_VALUE_RESULT_H
+#define _LIBCPP___ALGORITHM_OUT_VALUE_RESULT_H
+
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template 
+struct out_value_result {
+  _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
+  _LIBCPP_NO_UNIQUE_ADDRESS _ValType1 value;
+
+  template 
+requires convertible_to && 
convertible_to
+  constexpr operator out_value_result<_OutIter2, _ValType2>() const& { return 
{out, value}; }
+
+  template 
+requires convertible_to<_OutIter1, _OutIter2> && convertible_to<_ValType1, 
_ValType2>
+  constexpr operator out_value_result<_OutIter2, _ValType2>() && { return 
{std::move(out), std::move(value)}; }
+};
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_OUT_VALUE_RESULT_H
diff --git a/libcxx/include/__numeric/ranges_iota.h 
b/libcxx/include/__numeric/ranges_iota.h
new file mode 100644
index 00..20311a68c2a348
--- /dev/null
+++ b/libcxx/include/__numeric/ranges_iota.h
@@ -0,0 +1,53 @@
+// -*- 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___NUMERIC_RANGES_IOTA_H
+#define _LIBCPP___NUMERIC_RANGES_IOTA_H
+
+#include <__algorithm/out_value_result.h>
+#include <__config>
+#include <__ranges/concepts.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 
+using iota_result = ranges::out_value_result<_Out, _Tp>;
+
+struct __iota_fn {
+  template  _Sent, 
weakly_incrementable _Tp>
+requires indirectly_writable<_Out, const _Tp&>
+  constexpr iota_result<_Out, _Tp> operator()(_Out __first, _Sent __last, _Tp 
__value) const {
+while (__first != __last) {
+  *__first = static_cast(__value);
+  ++__first;
+  ++__value;
+}
+return {std::move(__first), std::move(__value)};
+

[Lldb-commits] [libcxx] [clang] [clang-tools-extra] [compiler-rt] [llvm] [flang] [lldb] [libunwind] [libc] [libc++] Implement ranges::iota (PR #68494)

2024-01-05 Thread James E T Smith via lldb-commits


@@ -46,7 +46,7 @@
 "`P2255R2 `__","LWG","A type trait to detect 
reference binding to temporary","February 2022","",""
 "`P2273R3 `__","LWG","Making ``std::unique_ptr`` 
constexpr","February 2022","|Complete|","16.0"
 "`P2387R3 `__","LWG","Pipe support for user-defined 
range adaptors","February 2022","","","|ranges|"
-"`P2440R1 `__","LWG","``ranges::iota``, 
``ranges::shift_left`` and ``ranges::shift_right``","February 
2022","","","|ranges|"
+"`P2440R1 `__","LWG","``ranges::iota``, 
``ranges::shift_left`` and ``ranges::shift_right``","February 2022","|In 
progress|","","|ranges|"

jamesETsmith wrote:

Should be resolved by b3f260e

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


[Lldb-commits] [compiler-rt] [libunwind] [clang-tools-extra] [clang] [flang] [libcxx] [llvm] [lldb] [libc] [libc++] Implement ranges::iota (PR #68494)

2024-01-05 Thread James E T Smith via lldb-commits


@@ -0,0 +1,123 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "almost_satisfies_types.h"
+
+// Concepts to check different overloads of std::ranges::iota
+template 
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+  std::ranges::iota(std::forward(iter), std::forward(sent), 
std::forward(val));
+};
+
+template 
+concept HasIotaRange =
+requires(Range&& range, Value&& val) { 
std::ranges::iota(std::forward(range), std::forward(val)); };
+
+constexpr void test_constraints() {

jamesETsmith wrote:

Should be resolved by b3f260e

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


[Lldb-commits] [libcxx] [llvm] [libunwind] [flang] [libc] [lldb] [compiler-rt] [clang] [clang-tools-extra] [libc++] Implement ranges::iota (PR #68494)

2024-01-05 Thread James E T Smith via lldb-commits


@@ -0,0 +1,123 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "almost_satisfies_types.h"
+
+// Concepts to check different overloads of std::ranges::iota
+template 
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+  std::ranges::iota(std::forward(iter), std::forward(sent), 
std::forward(val));
+};
+
+template 
+concept HasIotaRange =
+requires(Range&& range, Value&& val) { 
std::ranges::iota(std::forward(range), std::forward(val)); };
+
+constexpr void test_constraints() {
+  // Test constraints of the iterator/sentinel overload
+  // ==
+  static_assert(HasIotaIter);
+
+  // !input_or_output_iterator
+  static_assert(!HasIotaIter);
+
+  // !sentinel_for
+  static_assert(!HasIotaIter);
+  static_assert(!HasIotaIter);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaIter);
+
+  // !indirectly writable 
+  static_assert(!HasIotaIter);
+
+  // Test constraints for the range overload
+  // ===
+  static_assert(HasIotaRange, int>);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaRange, 
WeaklyIncrementableNotMovable>);
+
+  // !ranges::output_range
+  static_assert(!HasIotaRange, 
OutputIteratorNotIndirectlyWritable>);
+}
+
+template 
+constexpr void test_result(std::array input, int starting_value, 
std::array const expected) {
+  { // (iterator, sentinel) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+std::same_as> decltype(auto) 
result =
+std::ranges::iota(std::move(in_begin), std::move(in_end), 
starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+
+  // The range overload adds the additional constraint that it must be an 
outputrange
+  // so skip this for the input iterators we test
+  if constexpr (!std::is_same_v> &&
+!std::is_same_v>) { // 
(range) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+auto range= std::ranges::subrange(std::move(in_begin), 
std::move(in_end));
+
+std::same_as> decltype(auto) 
result =
+std::ranges::iota(range, starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}

jamesETsmith wrote:

Should be resolved by b3f260e

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


[Lldb-commits] [llvm] [clang-tools-extra] [clang] [lldb] [compiler-rt] [libcxx] [libunwind] [libc] [flang] [libc++] Implement ranges::iota (PR #68494)

2024-01-05 Thread James E T Smith via lldb-commits


@@ -0,0 +1,123 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "almost_satisfies_types.h"
+
+// Concepts to check different overloads of std::ranges::iota
+template 
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+  std::ranges::iota(std::forward(iter), std::forward(sent), 
std::forward(val));
+};
+
+template 
+concept HasIotaRange =
+requires(Range&& range, Value&& val) { 
std::ranges::iota(std::forward(range), std::forward(val)); };
+
+constexpr void test_constraints() {
+  // Test constraints of the iterator/sentinel overload
+  // ==
+  static_assert(HasIotaIter);
+
+  // !input_or_output_iterator
+  static_assert(!HasIotaIter);
+
+  // !sentinel_for
+  static_assert(!HasIotaIter);
+  static_assert(!HasIotaIter);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaIter);
+
+  // !indirectly writable 
+  static_assert(!HasIotaIter);
+
+  // Test constraints for the range overload
+  // ===
+  static_assert(HasIotaRange, int>);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaRange, 
WeaklyIncrementableNotMovable>);
+
+  // !ranges::output_range
+  static_assert(!HasIotaRange, 
OutputIteratorNotIndirectlyWritable>);
+}
+
+template 
+constexpr void test_result(std::array input, int starting_value, 
std::array const expected) {
+  { // (iterator, sentinel) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+std::same_as> decltype(auto) 
result =
+std::ranges::iota(std::move(in_begin), std::move(in_end), 
starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+
+  // The range overload adds the additional constraint that it must be an 
outputrange
+  // so skip this for the input iterators we test
+  if constexpr (!std::is_same_v> &&
+!std::is_same_v>) { // 
(range) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+auto range= std::ranges::subrange(std::move(in_begin), 
std::move(in_end));
+
+std::same_as> decltype(auto) 
result =
+std::ranges::iota(range, starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+}
+
+template >
+constexpr void test_results() {
+  // Empty
+  test_result({}, 0, {});
+  // 1-element sequence
+  test_result({1}, 0, {0});
+  // Longer sequence
+  test_result({1, 2, 3, 4, 5}, 0, {0, 1, 2, 3, 4});
+}
+
+void test_results() {
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results();

jamesETsmith wrote:

Should be resolved by b3f260e

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


[Lldb-commits] [libcxx] [clang] [clang-tools-extra] [compiler-rt] [llvm] [flang] [lldb] [libunwind] [libc] [libc++] Implement ranges::iota (PR #68494)

2024-01-05 Thread James E T Smith via lldb-commits


@@ -0,0 +1,123 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "almost_satisfies_types.h"
+
+// Concepts to check different overloads of std::ranges::iota
+template 
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+  std::ranges::iota(std::forward(iter), std::forward(sent), 
std::forward(val));
+};
+
+template 
+concept HasIotaRange =
+requires(Range&& range, Value&& val) { 
std::ranges::iota(std::forward(range), std::forward(val)); };
+
+constexpr void test_constraints() {
+  // Test constraints of the iterator/sentinel overload
+  // ==
+  static_assert(HasIotaIter);
+
+  // !input_or_output_iterator
+  static_assert(!HasIotaIter);
+
+  // !sentinel_for
+  static_assert(!HasIotaIter);
+  static_assert(!HasIotaIter);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaIter);
+
+  // !indirectly writable 
+  static_assert(!HasIotaIter);
+
+  // Test constraints for the range overload
+  // ===
+  static_assert(HasIotaRange, int>);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaRange, 
WeaklyIncrementableNotMovable>);
+
+  // !ranges::output_range
+  static_assert(!HasIotaRange, 
OutputIteratorNotIndirectlyWritable>);
+}
+
+template 
+constexpr void test_result(std::array input, int starting_value, 
std::array const expected) {
+  { // (iterator, sentinel) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+std::same_as> decltype(auto) 
result =
+std::ranges::iota(std::move(in_begin), std::move(in_end), 
starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+
+  // The range overload adds the additional constraint that it must be an 
outputrange
+  // so skip this for the input iterators we test
+  if constexpr (!std::is_same_v> &&
+!std::is_same_v>) { // 
(range) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+auto range= std::ranges::subrange(std::move(in_begin), 
std::move(in_end));
+
+std::same_as> decltype(auto) 
result =
+std::ranges::iota(range, starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+}
+
+template >
+constexpr void test_results() {
+  // Empty
+  test_result({}, 0, {});
+  // 1-element sequence
+  test_result({1}, 0, {0});
+  // Longer sequence
+  test_result({1, 2, 3, 4, 5}, 0, {0, 1, 2, 3, 4});
+}
+
+void test_results() {
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results>();
+  test_results();
+}
+

jamesETsmith wrote:

Should be resolved by b3f260e

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


[Lldb-commits] [flang] [clang] [libunwind] [compiler-rt] [libc] [libcxx] [clang-tools-extra] [lldb] [llvm] [libc++] Implement ranges::iota (PR #68494)

2024-01-06 Thread James E T Smith via lldb-commits


@@ -1149,9 +1171,11 @@ struct Proxy {
   // Calling swap(Proxy{}, Proxy{}) would fail (pass prvalues)
 
   // Compare operators are defined for the convenience of the tests
-  friend constexpr bool operator==(const Proxy&, const Proxy&)
-requires (std::equality_comparable && !std::is_reference_v)
-  = default;
+  friend constexpr bool operator==(const Proxy& lhs, const Proxy& rhs)
+requires(std::equality_comparable && !std::is_reference_v)
+  {
+return lhs.data == rhs.data;
+  };

jamesETsmith wrote:

For this operator and the spaceship operator below, the default functions do 
not satisfy the requirements on the functions (e.g. `std::equality_comparable`) 
(see the previous discussion about it 
[here](https://github.com/llvm/llvm-project/pull/68494#issuecomment-1783604000)).
 

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


[Lldb-commits] [compiler-rt] [clang-tools-extra] [flang] [lldb] [llvm] [libcxx] [libunwind] [libc] [clang] [libc++] Implement ranges::iota (PR #68494)

2024-01-06 Thread James E T Smith via lldb-commits


@@ -0,0 +1,71 @@
+// -*- 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___NUMERIC_RANGES_IOTA_H
+#define _LIBCPP___NUMERIC_RANGES_IOTA_H
+
+#include <__algorithm/out_value_result.h>
+#include <__config>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/as_const.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 
+using iota_result = ranges::out_value_result<_Out, _Tp>;
+
+namespace __ranges_iota {
+struct __iota_fn {
+private:
+  // Private helper function
+  template 
+  _LIBCPP_HIDE_FROM_ABI static constexpr iota_result<_Out, _Tp> 
__iota_impl(_Out __first, _Sent __last, _Tp __value) {
+while (__first != __last) {
+  *__first = std::as_const(__value);
+  ++__first;
+  ++__value;
+}
+return {std::move(__first), std::move(__value)};
+  }

jamesETsmith wrote:

That's a fair point about the extra moves. I added a helper function at 
@philnik777's suggestion to fix problems in the `robust_against_*` tests caused 
by my initial implementation (see discussion 
[here](https://github.com/llvm/llvm-project/pull/68494#discussion_r1349577530)).
 Is there a way we could satisfy both requirements?

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


[Lldb-commits] [compiler-rt] [clang-tools-extra] [flang] [lldb] [llvm] [libcxx] [libunwind] [libc] [clang] [libc++] Implement ranges::iota (PR #68494)

2024-01-06 Thread James E T Smith via lldb-commits


@@ -0,0 +1,71 @@
+// -*- 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___NUMERIC_RANGES_IOTA_H
+#define _LIBCPP___NUMERIC_RANGES_IOTA_H
+
+#include <__algorithm/out_value_result.h>
+#include <__config>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/as_const.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 
+using iota_result = ranges::out_value_result<_Out, _Tp>;
+
+namespace __ranges_iota {

jamesETsmith wrote:

It's easy enough, I'll just remove it.

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


[Lldb-commits] [compiler-rt] [clang-tools-extra] [flang] [lldb] [llvm] [libcxx] [libunwind] [libc] [clang] [libc++] Implement ranges::iota (PR #68494)

2024-01-06 Thread James E T Smith via lldb-commits


@@ -0,0 +1,71 @@
+// -*- 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___NUMERIC_RANGES_IOTA_H
+#define _LIBCPP___NUMERIC_RANGES_IOTA_H
+
+#include <__algorithm/out_value_result.h>
+#include <__config>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/as_const.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 
+using iota_result = ranges::out_value_result<_Out, _Tp>;
+
+namespace __ranges_iota {
+struct __iota_fn {
+private:
+  // Private helper function
+  template 
+  _LIBCPP_HIDE_FROM_ABI static constexpr iota_result<_Out, _Tp> 
__iota_impl(_Out __first, _Sent __last, _Tp __value) {
+while (__first != __last) {
+  *__first = std::as_const(__value);
+  ++__first;
+  ++__value;
+}
+return {std::move(__first), std::move(__value)};
+  }
+
+public:
+  // Public facing interfaces
+  template  _Sent, 
weakly_incrementable _Tp>
+requires indirectly_writable<_Out, const _Tp&>
+  _LIBCPP_HIDE_FROM_ABI static constexpr iota_result<_Out, _Tp> 
operator()(_Out __first, _Sent __last, _Tp __value) {
+return __iota_impl(std::move(__first), std::move(__last), 
std::move(__value));
+  }
+
+  template  _Range>
+  _LIBCPP_HIDE_FROM_ABI static constexpr 
iota_result, _Tp>
+  operator()(_Range&& __r, _Tp __value) {
+return __iota_impl(ranges::begin(__r), ranges::end(__r), 
std::move(__value));
+  }
+};
+} // namespace __ranges_iota
+
+inline namespace __cpo {

jamesETsmith wrote:

Like the other namespace, this is easy enough so I'll just remove it now.

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


[Lldb-commits] [clang] [llvm] [flang] [libcxx] [libc] [clang-tools-extra] [compiler-rt] [lldb] [libunwind] [libc++] Implement ranges::iota (PR #68494)

2024-01-06 Thread James E T Smith via lldb-commits


@@ -13,7 +13,7 @@
 // Range algorithms should return `std::ranges::dangling` when given a 
dangling range.
 

jamesETsmith wrote:

This should be resolved with 
[be7faa6](https://github.com/llvm/llvm-project/pull/68494/commits/be7faa6fb11c09822a9a855c7cf1aecab4f4c773)

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


[Lldb-commits] [clang] [llvm] [flang] [libcxx] [libc] [clang-tools-extra] [compiler-rt] [lldb] [libunwind] [libc++] Implement ranges::iota (PR #68494)

2024-01-06 Thread James E T Smith via lldb-commits

https://github.com/jamesETsmith edited 
https://github.com/llvm/llvm-project/pull/68494
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [libunwind] [libc] [clang-tools-extra] [libcxx] [llvm] [lldb] [compiler-rt] [clang] [flang] [libc++] Implement ranges::iota (PR #68494)

2024-01-06 Thread James E T Smith via lldb-commits

jamesETsmith wrote:

@cjdb, thanks for taking a look! I've addressed some of your comments already 
and will try to wrap up the rest early next week. I've got plenty of time to 
work on this over the next couple of weeks so I shouldn't have a problem 
wrapping this up before the end of January

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


[Lldb-commits] [libc] [llvm] [lldb] [libunwind] [compiler-rt] [clang] [libcxx] [clang-tools-extra] [flang] [libc++] Implement ranges::iota (PR #68494)

2024-01-09 Thread James E T Smith via lldb-commits

https://github.com/jamesETsmith edited 
https://github.com/llvm/llvm-project/pull/68494
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [flang] [compiler-rt] [libunwind] [libc] [libcxx] [llvm] [clang] [lldb] [clang-tools-extra] [libc++] Implement ranges::iota (PR #68494)

2024-01-09 Thread James E T Smith via lldb-commits


@@ -0,0 +1,123 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "almost_satisfies_types.h"
+
+// Concepts to check different overloads of std::ranges::iota
+template 
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+  std::ranges::iota(std::forward(iter), std::forward(sent), 
std::forward(val));
+};
+
+template 
+concept HasIotaRange =
+requires(Range&& range, Value&& val) { 
std::ranges::iota(std::forward(range), std::forward(val)); };
+
+constexpr void test_constraints() {
+  // Test constraints of the iterator/sentinel overload
+  // ==
+  static_assert(HasIotaIter);
+
+  // !input_or_output_iterator
+  static_assert(!HasIotaIter);
+
+  // !sentinel_for
+  static_assert(!HasIotaIter);
+  static_assert(!HasIotaIter);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaIter);
+
+  // !indirectly writable 
+  static_assert(!HasIotaIter);
+
+  // Test constraints for the range overload
+  // ===
+  static_assert(HasIotaRange, int>);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaRange, 
WeaklyIncrementableNotMovable>);
+
+  // !ranges::output_range
+  static_assert(!HasIotaRange, 
OutputIteratorNotIndirectlyWritable>);
+}
+
+template 
+constexpr void test_result(std::array input, int starting_value, 
std::array const expected) {
+  { // (iterator, sentinel) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+std::same_as> decltype(auto) 
result =
+std::ranges::iota(std::move(in_begin), std::move(in_end), 
starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+
+  // The range overload adds the additional constraint that it must be an 
outputrange
+  // so skip this for the input iterators we test
+  if constexpr (!std::is_same_v> &&
+!std::is_same_v>) { // 
(range) overload

jamesETsmith wrote:

@philnik777 I found what's tripping up the `output_iterator` concept. It's 
this: 
https://github.com/jamesETsmith/llvm-project/blob/be7faa6fb11c09822a9a855c7cf1aecab4f4c773/libcxx/test/support/test_iterators.h#L652.
 Is there a special constraint for `cpp20_input_iterator` that requires the 
post-increment operator be implemented this way? 

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


[Lldb-commits] [compiler-rt] [flang] [clang] [clang-tools-extra] [llvm] [libcxx] [libc] [libunwind] [lldb] [libc++] Implement ranges::iota (PR #68494)

2024-01-09 Thread James E T Smith via lldb-commits


@@ -0,0 +1,171 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include 
+#include 
+#include 
+#include 
+#include  // TODO RM
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "almost_satisfies_types.h"
+
+//
+// Testing constraints
+//
+
+// Concepts to check different overloads of std::ranges::iota
+template 
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+  std::ranges::iota(std::forward(iter), std::forward(sent), 
std::forward(val));
+};
+
+template 
+concept HasIotaRange =
+requires(Range&& range, Value&& val) { 
std::ranges::iota(std::forward(range), std::forward(val)); };
+
+// Test constraints of the iterator/sentinel overload
+// ==
+static_assert(HasIotaIter);
+
+// !input_or_output_iterator
+static_assert(!HasIotaIter);
+
+// !sentinel_for
+static_assert(!HasIotaIter);
+static_assert(!HasIotaIter);
+
+// !weakly_incrementable
+static_assert(!HasIotaIter);
+
+// !indirectly writable 
+static_assert(!HasIotaIter);
+
+// Test constraints for the range overload
+// ===
+static_assert(HasIotaRange, int>);
+
+// !weakly_incrementable
+static_assert(!HasIotaRange, 
WeaklyIncrementableNotMovable>);
+
+// !ranges::output_range
+static_assert(!HasIotaRange, 
OutputIteratorNotIndirectlyWritable>);
+
+//
+// Testing results
+//
+
+struct DangerousCopyAssign {
+  int val;
+  using difference_type = int;
+
+  constexpr explicit DangerousCopyAssign(int v) : val(v) {}
+
+  // Needed in postfix
+  constexpr DangerousCopyAssign(DangerousCopyAssign const& other) { this->val 
= other.val; }
+
+  // mischievious copy assignment that we won't use if the
+  // std::as_const inside ranges::iota isn't working, this should perturb the
+  // results
+  constexpr DangerousCopyAssign& operator=(DangerousCopyAssign& a) {
+++a.val;
+this->val = a.val;
+return *this;
+  }
+
+  // safe copy assignment std::as_const inside ranges::iota should ensure this
+  // overload gets called
+  constexpr DangerousCopyAssign& operator=(DangerousCopyAssign const& a) {
+this->val = a.val;
+return *this;
+  }
+
+  constexpr bool operator==(DangerousCopyAssign const& rhs) { return this->val 
== rhs.val; }
+
+  // prefix
+  constexpr DangerousCopyAssign& operator++() {
+++(this->val);
+return *this;
+  }
+
+  // postfix
+  constexpr DangerousCopyAssign operator++(int) {
+auto tmp = *this;
+++this->val;
+return tmp;
+  }
+};
+
+template 
+constexpr void test_result(std::array input, T starting_value, 
std::array const expected) {
+  { // (iterator, sentinel) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+std::same_as> decltype(auto) result 
=
+std::ranges::iota(std::move(in_begin), std::move(in_end), 
starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+
+  // The range overload adds the additional constraint that it must be an 
outputrange
+  // so skip this for the input iterators we test
+  if constexpr (!std::is_same_v> &&
+!std::is_same_v>) { // (range) 
overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+auto range= std::ranges::subrange(std::move(in_begin), 
std::move(in_end));
+
+std::same_as> decltype(auto) result 
=
+std::ranges::iota(range, starting_value);
+assert(result.out == in_end);
+assert(result.value == starting_value + N);
+assert(std::ranges::equal(input, expected));
+  }

jamesETsmith wrote:

We may be able to get rid of the constraints inside the loop, we're discussing 
it here 
(https://github.com/llvm/llvm-project/pull/68494#discussion_r1442710770) at the 
moment. If we can ditch the conditional logic altogether, I'll keep this in the 
current test, otherwise, I'll take your suggestion and move it to a separate 
test case.

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


[Lldb-commits] [compiler-rt] [flang] [clang] [clang-tools-extra] [llvm] [libcxx] [libc] [libunwind] [lldb] [libc++] Implement ranges::iota (PR #68494)

2024-01-09 Thread James E T Smith via lldb-commits


@@ -0,0 +1,123 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "almost_satisfies_types.h"
+
+// Concepts to check different overloads of std::ranges::iota
+template 
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+  std::ranges::iota(std::forward(iter), std::forward(sent), 
std::forward(val));
+};
+
+template 
+concept HasIotaRange =
+requires(Range&& range, Value&& val) { 
std::ranges::iota(std::forward(range), std::forward(val)); };
+
+constexpr void test_constraints() {
+  // Test constraints of the iterator/sentinel overload
+  // ==
+  static_assert(HasIotaIter);
+
+  // !input_or_output_iterator
+  static_assert(!HasIotaIter);
+
+  // !sentinel_for
+  static_assert(!HasIotaIter);
+  static_assert(!HasIotaIter);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaIter);
+
+  // !indirectly writable 
+  static_assert(!HasIotaIter);
+
+  // Test constraints for the range overload
+  // ===
+  static_assert(HasIotaRange, int>);
+
+  // !weakly_incrementable
+  static_assert(!HasIotaRange, 
WeaklyIncrementableNotMovable>);
+
+  // !ranges::output_range
+  static_assert(!HasIotaRange, 
OutputIteratorNotIndirectlyWritable>);
+}
+
+template 
+constexpr void test_result(std::array input, int starting_value, 
std::array const expected) {
+  { // (iterator, sentinel) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+std::same_as> decltype(auto) 
result =
+std::ranges::iota(std::move(in_begin), std::move(in_end), 
starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+
+  // The range overload adds the additional constraint that it must be an 
outputrange
+  // so skip this for the input iterators we test
+  if constexpr (!std::is_same_v> &&
+!std::is_same_v>) { // 
(range) overload

jamesETsmith wrote:

I think I misunderstood the difference between `cppXX_output_iterator` in 
`test_iterators.h`. Chris' comments below pointed me in the right direction. 
After a bit of reading, I don't think that `cpp17_output_iterator` and 
`cpp20_output_iterator` should satisfy `std::output_iterator` because they're 
supposed to be as general as possible (at least that's my interpretation) and 
are only required to be `std::weakly_incrementable` not `std::incrementable`.

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


[Lldb-commits] [libc] [llvm] [clang] [libcxx] [clang-tools-extra] [flang] [compiler-rt] [lldb] [libunwind] [libc++] Implement ranges::iota (PR #68494)

2024-01-15 Thread James E T Smith via lldb-commits

https://github.com/jamesETsmith edited 
https://github.com/llvm/llvm-project/pull/68494
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [clang] [flang] [compiler-rt] [libunwind] [libc] [clang-tools-extra] [lldb] [libcxx] [llvm] [libc++] Implement ranges::iota (PR #68494)

2024-01-15 Thread James E T Smith via lldb-commits


@@ -1172,6 +1198,22 @@ struct Proxy {
 requires std::three_way_comparable_with, std::decay_t> {
 return lhs.data <=> rhs.data;
   }
+
+  // Needed to allow certain types to be weakly_incremental
+  constexpr Proxy& operator++()
+requires(HasPreIncrementOp)
+  {
+++data;
+return *this;
+  }
+
+  constexpr Proxy operator++(int)
+requires(HasPostIncrementOp)
+  {
+Proxy tmp = *this;
+operator++();
+return tmp;
+  }

jamesETsmith wrote:

Should be fixed by 
[2803493](https://github.com/llvm/llvm-project/pull/68494/commits/2803493cba2a05fce5b3379c8ba43989aa4eaf73)

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


[Lldb-commits] [clang] [flang] [compiler-rt] [libunwind] [libc] [clang-tools-extra] [lldb] [libcxx] [llvm] [libc++] Implement ranges::iota (PR #68494)

2024-01-15 Thread James E T Smith via lldb-commits


@@ -0,0 +1,171 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include 
+#include 
+#include 
+#include 
+#include  // TODO RM
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "almost_satisfies_types.h"
+
+//
+// Testing constraints
+//
+
+// Concepts to check different overloads of std::ranges::iota
+template 
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+  std::ranges::iota(std::forward(iter), std::forward(sent), 
std::forward(val));
+};
+
+template 
+concept HasIotaRange =
+requires(Range&& range, Value&& val) { 
std::ranges::iota(std::forward(range), std::forward(val)); };
+
+// Test constraints of the iterator/sentinel overload
+// ==
+static_assert(HasIotaIter);
+
+// !input_or_output_iterator
+static_assert(!HasIotaIter);
+
+// !sentinel_for
+static_assert(!HasIotaIter);
+static_assert(!HasIotaIter);
+
+// !weakly_incrementable
+static_assert(!HasIotaIter);
+
+// !indirectly writable 
+static_assert(!HasIotaIter);
+
+// Test constraints for the range overload
+// ===
+static_assert(HasIotaRange, int>);
+
+// !weakly_incrementable
+static_assert(!HasIotaRange, 
WeaklyIncrementableNotMovable>);
+
+// !ranges::output_range
+static_assert(!HasIotaRange, 
OutputIteratorNotIndirectlyWritable>);
+
+//
+// Testing results
+//
+
+struct DangerousCopyAssign {
+  int val;
+  using difference_type = int;
+
+  constexpr explicit DangerousCopyAssign(int v) : val(v) {}
+
+  // Needed in postfix
+  constexpr DangerousCopyAssign(DangerousCopyAssign const& other) { this->val 
= other.val; }
+
+  // mischievious copy assignment that we won't use if the
+  // std::as_const inside ranges::iota isn't working, this should perturb the
+  // results
+  constexpr DangerousCopyAssign& operator=(DangerousCopyAssign& a) {
+++a.val;
+this->val = a.val;
+return *this;
+  }
+
+  // safe copy assignment std::as_const inside ranges::iota should ensure this
+  // overload gets called
+  constexpr DangerousCopyAssign& operator=(DangerousCopyAssign const& a) {
+this->val = a.val;
+return *this;
+  }
+
+  constexpr bool operator==(DangerousCopyAssign const& rhs) { return this->val 
== rhs.val; }
+
+  // prefix
+  constexpr DangerousCopyAssign& operator++() {
+++(this->val);
+return *this;
+  }
+
+  // postfix
+  constexpr DangerousCopyAssign operator++(int) {
+auto tmp = *this;
+++this->val;
+return tmp;
+  }
+};
+
+template 
+constexpr void test_result(std::array input, T starting_value, 
std::array const expected) {
+  { // (iterator, sentinel) overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+std::same_as> decltype(auto) result 
=
+std::ranges::iota(std::move(in_begin), std::move(in_end), 
starting_value);
+assert(result.out == in_end);
+if constexpr (expected.size() > 0) {
+  assert(result.value == expected.back() + 1);
+} else {
+  assert(result.value == starting_value);
+}
+assert(std::ranges::equal(input, expected));
+  }
+
+  // The range overload adds the additional constraint that it must be an 
outputrange
+  // so skip this for the input iterators we test
+  if constexpr (!std::is_same_v> &&
+!std::is_same_v>) { // (range) 
overload
+auto in_begin = Iter(input.data());
+auto in_end   = Sent(Iter(input.data() + input.size()));
+auto range= std::ranges::subrange(std::move(in_begin), 
std::move(in_end));
+
+std::same_as> decltype(auto) result 
=
+std::ranges::iota(range, starting_value);
+assert(result.out == in_end);
+assert(result.value == starting_value + N);
+assert(std::ranges::equal(input, expected));
+  }

jamesETsmith wrote:

I've removed the conditional logic in 
[2803493](https://github.com/llvm/llvm-project/pull/68494/commits/2803493cba2a05fce5b3379c8ba43989aa4eaf73)

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


[Lldb-commits] [flang] [llvm] [libc] [lldb] [clang] [compiler-rt] [libunwind] [libcxx] [clang-tools-extra] [libc++] Implement ranges::iota (PR #68494)

2024-01-15 Thread James E T Smith via lldb-commits


@@ -1149,9 +1171,11 @@ struct Proxy {
   // Calling swap(Proxy{}, Proxy{}) would fail (pass prvalues)
 
   // Compare operators are defined for the convenience of the tests
-  friend constexpr bool operator==(const Proxy&, const Proxy&)
-requires (std::equality_comparable && !std::is_reference_v)
-  = default;
+  friend constexpr bool operator==(const Proxy& lhs, const Proxy& rhs)
+requires(std::equality_comparable && !std::is_reference_v)
+  {
+return lhs.data == rhs.data;
+  };

jamesETsmith wrote:

Thanks to an offline discussion with @Quuxplusone, I now know that these 
operators only started causing problems when I introduced the base class 
`ProxyDiffTBase` because the base subobject wasn't trivially comparable. Since 
the `operator==` for `Proxy` is used all over, when they stopped functioning 
properly a lot of tests started failing which is what prompted me to make those 
changes to begin with. At @Quuxplusone's suggestion, I've specified the 
comparison operators for the base class (and derived `Proxy` class) as default, 
undoing the changes we were talking about here and below.

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


[Lldb-commits] [clang] [libcxx] [llvm] [libunwind] [libc] [lldb] [compiler-rt] [clang-tools-extra] [flang] [libc++] Implement ranges::iota (PR #68494)

2024-01-16 Thread James E T Smith via lldb-commits

https://github.com/jamesETsmith edited 
https://github.com/llvm/llvm-project/pull/68494
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [libunwind] [compiler-rt] [libc] [clang-tools-extra] [lldb] [flang] [llvm] [libcxx] [clang] [libc++] Implement ranges::iota (PR #68494)

2024-01-31 Thread James E T Smith via lldb-commits


@@ -0,0 +1,54 @@
+// -*- 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___NUMERIC_RANGES_IOTA_H
+#define _LIBCPP___NUMERIC_RANGES_IOTA_H
+
+#include <__algorithm/out_value_result.h>
+#include <__config>
+#include <__ranges/concepts.h>
+#include <__utility/as_const.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 
+using iota_result = ranges::out_value_result<_Out, _Tp>;
+
+struct __iota_fn {
+  template  _Sent, 
weakly_incrementable _Tp>
+requires indirectly_writable<_Out, const _Tp&>
+  constexpr iota_result<_Out, _Tp> operator()(_Out __first, _Sent __last, _Tp 
__value) const {
+while (__first != __last) {
+  *__first = std::as_const(__value);
+  ++__first;
+  ++__value;
+}
+return {std::move(__first), std::move(__value)};
+  }
+
+  template  _Range>
+  constexpr iota_result, _Tp> 
operator()(_Range&& __r, _Tp __value) const {
+return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__value));

jamesETsmith wrote:

Sorry I've been slow on this. @philnik777 do you have any suggestions/comments 
about this?

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