Skip to content

[libc++] Implement ranges::iota #68494

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 50 commits into from
Apr 5, 2025
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
c4a3ccf
[libc++] Implement ranges::iota and ranges::out_value_result
jamesETsmith Sep 28, 2023
1b808ec
Merge branch 'main' of https://github.com/llvm/llvm-project into rang…
jamesETsmith Sep 28, 2023
574c94c
[libc++] Implement ranges::iota: update module and docs info
jamesETsmith Sep 29, 2023
e4cfe00
[libc++] Implement ranges::iota: fixing formatting issues for out_val…
jamesETsmith Sep 29, 2023
7cdfea2
[libc++] Implement ranges::iota: Cleaning up tests for ranges::iota a…
jamesETsmith Oct 7, 2023
a1d015c
[libc++] Implement ranges::iota: Cleaning up tests for ranges::iota a…
jamesETsmith Oct 7, 2023
ab4c67d
[libc++] Implement ranges::iota: Using clang-format-17 to make CI che…
jamesETsmith Oct 7, 2023
c44d7d6
Merge branch 'main' of https://github.com/llvm/llvm-project into rang…
jamesETsmith Oct 7, 2023
a455f42
[libc++] Implement ranges::iota: Adding helper function to implementa…
jamesETsmith Oct 25, 2023
08e3c77
[libc++] Implement ranges::iota: Adding tests to ranges_robust_agains…
jamesETsmith Oct 26, 2023
e658ec2
[libc++] Implement ranges::iota: Merging with main and handling confl…
jamesETsmith Oct 26, 2023
67fcac1
[libc++] Implement ranges::iota: Fixing formatting problems
jamesETsmith Oct 26, 2023
b132784
[libc++] Implement ranges::iota: Addressing comments about out_value_…
jamesETsmith Oct 26, 2023
88e271a
[libc++] Implement ranges::iota: Updating Proxy<T> in test_iterators.…
jamesETsmith Oct 27, 2023
ff5bf79
[libc++] Implement ranges::iota: Fixing some of the buildkite errors,…
jamesETsmith Oct 28, 2023
b8f07b8
[libc++] Implement ranges::iota: Explicitly adding #include for range…
jamesETsmith Oct 30, 2023
a4d34fd
[libc++] Implement ranges::iota: Explicitly adding #include for range…
jamesETsmith Oct 30, 2023
334088f
:Merge branch 'main' of https://github.com/llvm/llvm-project into ran…
jamesETsmith Oct 30, 2023
8153244
[libc++] Implement ranges::iota: Adding #ifdef _LIBCPP_STD_VER >= 23 …
jamesETsmith Oct 31, 2023
a872e39
[libc++] Implement ranges::iota: Missing a few more #if TEST_STD_VER …
jamesETsmith Nov 4, 2023
0f538aa
Merge branch 'main' of https://github.com/llvm/llvm-project into rang…
jamesETsmith Nov 4, 2023
b84859b
[libc++] Implement ranges::iota: Removing several of the ranges_robus…
jamesETsmith Nov 5, 2023
3bd4c6d
[libc++] Implement ranges::iota: Updating with upstream main and reso…
jamesETsmith Nov 15, 2023
6be79e2
[libc++] Implement ranges::iota: Updating with upstream and fixing co…
jamesETsmith Dec 13, 2023
7cde8ed
Merge branch 'main' of https://github.com/llvm/llvm-project into rang…
jamesETsmith Dec 16, 2023
074d685
Merge branch 'main' of https://github.com/llvm/llvm-project into rang…
jamesETsmith Dec 18, 2023
72125ea
[libc++] Implement ranges::iota: Updating with upstream and adding st…
jamesETsmith Dec 18, 2023
ce909e8
Merge branch 'main' of https://github.com/llvm/llvm-project into rang…
jamesETsmith Dec 19, 2023
028ce92
[libc++] Implement ranges::iota: Fixing formatting problems with test…
jamesETsmith Dec 19, 2023
b3f260e
[libc++] Implement ranges::iota: Improving ranges::iota tests and doc…
jamesETsmith Jan 5, 2024
be7faa6
[libc++] Implement ranges::iota: Removing unnecessary namespaces in r…
jamesETsmith Jan 6, 2024
20b848b
[libc++] Implement ranges::iota: Refactoring some of Proxy's member f…
jamesETsmith Jan 15, 2024
2803493
[libc++] Implement ranges::iota: Undoing some problematic additions t…
jamesETsmith Jan 15, 2024
5f0389c
[libc++] Implement ranges::iota: Fixing review comments on ranges.iot…
jamesETsmith Apr 28, 2024
79d6cc5
[libc++] Implementing ranges::iota: Adding user-defined type tests an…
jamesETsmith Apr 28, 2024
07b8183
[libc++] Implementing ranges::iota: Reverting to original strategy fo…
jamesETsmith Apr 28, 2024
3d5ad73
[libc++] Implementing ranges::iota: Updating branch with llvm-project…
jamesETsmith Apr 30, 2024
fd81400
[libc++] Implementing ranges::iota: Needed to include __undef_macros …
jamesETsmith May 3, 2024
3285f4e
[libc++] Implementing ranges::iota: Fixing autogenerated version.vers…
jamesETsmith May 3, 2024
cea6379
Merge branch 'main' of github.com:llvm/llvm-project into ranges_iota
jamesETsmith May 7, 2024
3f0670f
[libc++] Implementing ranges::iota: Simplifying some tests, adding st…
jamesETsmith May 22, 2024
a7e77b1
[libc++] Implementing ranges::iota: Updating with upstream main and r…
jamesETsmith Jul 22, 2024
d50b7a1
[libc++] Implementing ranges::iota: Accidentally manually updated the…
jamesETsmith Jul 24, 2024
b4008ad
[libc++] Implementing ranges::iota: Cleanup and addressing comments f…
jamesETsmith Jul 26, 2024
240d4f0
[libc++] Implementing ranges::iota: Updating with upstream main
jamesETsmith Mar 27, 2025
8f5ffc3
[libc++] Implementing ranges::iota: Including out_value_result got st…
jamesETsmith Mar 27, 2025
b99c8d8
[libc++] Implementing ranges::iota: Needed to add __iterator/concepts…
jamesETsmith Apr 1, 2025
dc29b80
[libc++] implementing ranges::iota: Fixing the Cxx23Paper.csv doc for…
jamesETsmith Apr 2, 2025
e325de4
[libc++] implementing ranges::iota: Switching the wording in Cxx23Pap…
jamesETsmith Apr 2, 2025
913a8d8
[libc++] implementing ranges::iota: the header for out_value_result.h…
jamesETsmith Apr 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libcxx/docs/FeatureTestMacroTable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_ranges_contains`` ``202207L``
---------------------------------------------------------- -----------------
``__cpp_lib_ranges_iota`` *unimplemented*
``__cpp_lib_ranges_iota`` ``202202L``
---------------------------------------------------------- -----------------
``__cpp_lib_ranges_join_with`` *unimplemented*
---------------------------------------------------------- -----------------
Expand Down
1 change: 1 addition & 0 deletions libcxx/docs/Status/Cxx23.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Paper Status
.. [#note-P2693R1] P2693R1: The formatter for ``std::thread::id`` is implemented.
The formatter for ``stacktrace`` is not implemented, since ``stacktrace`` is
not implemented yet.
.. [#note-P2440R1] P2440R1: ranges::shift_left and ranges::shift_right have not been implemented yet.

.. _issues-status-cxx23:

Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx23Papers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"`P2255R2 <https://wg21.link/P2255R2>`__","LWG","A type trait to detect reference binding to temporary","February 2022","",""
"`P2273R3 <https://wg21.link/P2273R3>`__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Complete|","16.0"
"`P2387R3 <https://wg21.link/P2387R3>`__","LWG","Pipe support for user-defined range adaptors","February 2022","|Complete|","19.0","|ranges|"
"`P2440R1 <https://wg21.link/P2440R1>`__","LWG","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","February 2022","","","|ranges|"
"`P2440R1 <https://wg21.link/P2440R1>`__","LWG","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","February 2022","|In progress| [#note-P2440R1]_","","|ranges|"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to @Zingam's suggestion to mark this as |Partial|.

"`P2441R2 <https://wg21.link/P2441R2>`__","LWG","``views::join_with``","February 2022","|In Progress|","","|ranges|"
"`P2442R1 <https://wg21.link/P2442R1>`__","LWG","Windowing range adaptors: ``views::chunk`` and ``views::slide``","February 2022","","","|ranges|"
"`P2443R1 <https://wg21.link/P2443R1>`__","LWG","``views::chunk_by``","February 2022","|Complete|","18.0","|ranges|"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/docs/Status/RangesAlgorithms.csv
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ C++23,`shift_left <https://wg21.link/p2440r1>`_,Unassigned,No patch yet,Not star
C++23,`shift_right <https://wg21.link/p2440r1>`_,Unassigned,No patch yet,Not started
C++23,`iota (algorithm) <https://wg21.link/p2440r1>`_,Unassigned,No patch yet,Not started
C++23,`fold <https://wg21.link/p2322r5>`_,Unassigned,No patch yet,Not started
C++23,`contains <https://wg21.link/p2302r2>`_,Zijun Zhao,No patch yet,In Progress
C++23,`ranges::iota <https://wg21.link/P2440R1>`_, James E T Smith, `PR68494 <https://github.com/llvm/llvm-project/pull/68494>`_, In Progress
C++23,`contains <https://wg21.link/p2302r2>`_,Zijun Zhao, `#65148 <https://github.com/llvm/llvm-project/pull/65148>`_,Complete
C++23,`fold_left_with_iter <https://wg21.link/p2322r6>`_,Christopher Di Bella,N/A,Complete
C++23,`fold_left <https://wg21.link/p2322r6>`_,Christopher Di Bella,N/A,Complete
Expand Down
1 change: 1 addition & 0 deletions libcxx/docs/Status/RangesMajorFeatures.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ Standard,Name,Assignee,CL,Status
C++23,`ranges::to <https://wg21.link/P1206R7>`_,Konstantin Varlamov,`D142335 <https://reviews.llvm.org/D142335>`_,Complete
C++23,`Pipe support for user-defined range adaptors <https://wg21.link/P2387R3>`_,"Louis Dionne, Jakub Mazurkiewicz, and Xiaoyang Liu",Various,Complete
C++23,`Formatting Ranges <https://wg21.link/P2286R8>`_,Mark de Wever,Various,Complete
C++23, `ranges::iota <https://wg21.link/P2440R1>`_, James E T Smith, `PR68494 <https://github.com/llvm/llvm-project/pull/68494>`_, In Progress
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/In Progress/Complete (which it will be once this patch is merged, right?).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will only be partial after this PR is merged because that paper contains two other methods ranges::shift_left and ranges::shift_right.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also the option to mark this as |Partial|, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion @Zingam, I've updated this to |Partial|

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe I'd call this a "major ranges feature"; this is an important ranges feature, but isn't quite as large as the other things on this list; I'd remove this change.

C++20,`Stashing stashing iterators for proper flattening <https://wg21.link/P2770R0>`_,Jakub Mazurkiewicz,Various,In progress
2 changes: 2 additions & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,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
Expand Down Expand Up @@ -576,6 +577,7 @@ set(files
__numeric/partial_sum.h
__numeric/pstl_reduce.h
__numeric/pstl_transform_reduce.h
__numeric/ranges_iota.h
__numeric/reduce.h
__numeric/saturation_arithmetic.h
__numeric/transform_exclusive_scan.h
Expand Down
56 changes: 56 additions & 0 deletions libcxx/include/__algorithm/out_value_result.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// -*- 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 <class _OutIter1, class _ValType1>
struct out_value_result {
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
_LIBCPP_NO_UNIQUE_ADDRESS _ValType1 value;

template <class _OutIter2, class _ValType2>
requires convertible_to<const _OutIter1&, _OutIter2> && convertible_to<const _ValType1&, _ValType2>
_LIBCPP_HIDE_FROM_ABI constexpr operator out_value_result<_OutIter2, _ValType2>() const& {
return {out, value};
}

template <class _OutIter2, class _ValType2>
requires convertible_to<_OutIter1, _OutIter2> && convertible_to<_ValType1, _ValType2>
_LIBCPP_HIDE_FROM_ABI 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
64 changes: 64 additions & 0 deletions libcxx/include/__numeric/ranges_iota.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// -*- 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_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER >= 23
namespace ranges {
template <typename _Out, typename _Tp>
using iota_result = ranges::out_value_result<_Out, _Tp>;

struct __iota_fn {
public:
template <input_or_output_iterator _Out, sentinel_for<_Out> _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) {
while (__first != __last) {
*__first = std::as_const(__value);
++__first;
++__value;
}
return {std::move(__first), std::move(__value)};
}

template <weakly_incrementable _Tp, ranges::output_range<const _Tp&> _Range>
_LIBCPP_HIDE_FROM_ABI static constexpr iota_result<ranges::borrowed_iterator_t<_Range>, _Tp>
operator()(_Range&& __r, _Tp __value) {
return __iota_fn::operator()(ranges::begin(__r), ranges::end(__r), std::move(__value));
}
};

inline constexpr auto iota = __iota_fn{};
} // namespace ranges

#endif // _LIBCPP_STD_VER >= 23

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___NUMERIC_RANGES_IOTA_H
4 changes: 4 additions & 0 deletions libcxx/include/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ namespace ranges {
template <class I>
struct in_found_result; // since C++20

template <class O, class T>
struct out_value_result; // since C++23

template <class I, class T>
struct in_value_result; // since C++23

Expand Down Expand Up @@ -1842,6 +1845,7 @@ template <class BidirectionalIterator, class Compare>
#include <__algorithm/next_permutation.h>
#include <__algorithm/none_of.h>
#include <__algorithm/nth_element.h>
#include <__algorithm/out_value_result.h>
#include <__algorithm/partial_sort.h>
#include <__algorithm/partial_sort_copy.h>
#include <__algorithm/partition.h>
Expand Down
5 changes: 5 additions & 0 deletions libcxx/include/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,7 @@ module std_private_algorithm_move_backward [system
module std_private_algorithm_next_permutation [system] { header "__algorithm/next_permutation.h" }
module std_private_algorithm_none_of [system] { header "__algorithm/none_of.h" }
module std_private_algorithm_nth_element [system] { header "__algorithm/nth_element.h" }
module std_private_algorithm_out_value_result [system] { header "__algorithm/out_value_result.h" }
module std_private_algorithm_partial_sort [system] { header "__algorithm/partial_sort.h" }
module std_private_algorithm_partial_sort_copy [system] { header "__algorithm/partial_sort_copy.h" }
module std_private_algorithm_partition [system] { header "__algorithm/partition.h" }
Expand Down Expand Up @@ -1586,6 +1587,10 @@ module std_private_numeric_pstl_transform_reduce [system] {
export *
}
module std_private_numeric_reduce [system] { header "__numeric/reduce.h" }
module std_private_numeric_ranges_iota [system] {
header "__numeric/ranges_iota.h"
export std_private_algorithm_out_value_result
}
module std_private_numeric_saturation_arithmetic [system] { header "__numeric/saturation_arithmetic.h" }
module std_private_numeric_transform_exclusive_scan [system] { header "__numeric/transform_exclusive_scan.h" }
module std_private_numeric_transform_inclusive_scan [system] { header "__numeric/transform_inclusive_scan.h" }
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/numeric
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ constexpr T saturate_cast(U x) noexcept; // freestanding, Sin
#include <__numeric/partial_sum.h>
#include <__numeric/pstl_reduce.h>
#include <__numeric/pstl_transform_reduce.h>
#include <__numeric/ranges_iota.h>
#include <__numeric/reduce.h>
#include <__numeric/saturation_arithmetic.h>
#include <__numeric/transform_exclusive_scan.h>
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/version
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
// # define __cpp_lib_ranges_chunk 202202L
# define __cpp_lib_ranges_chunk_by 202202L
# define __cpp_lib_ranges_contains 202207L
// # define __cpp_lib_ranges_iota 202202L
# define __cpp_lib_ranges_iota 202202L
// # define __cpp_lib_ranges_join_with 202202L
# define __cpp_lib_ranges_repeat 202207L
// # define __cpp_lib_ranges_slide 202202L
Expand Down
4 changes: 3 additions & 1 deletion libcxx/modules/std/algorithm.inc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export namespace std {
using std::ranges::in_value_result;
#endif
using std::ranges::min_max_result;
// using std::ranges::out_value_result;
#if _LIBCPP_STD_VER >= 23
using std::ranges::out_value_result;
#endif
} // namespace ranges

// [alg.nonmodifying], non-modifying sequence operations
Expand Down
8 changes: 6 additions & 2 deletions libcxx/modules/std/numeric.inc
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ export namespace std {
using std::iota;

namespace ranges {
// using std::ranges::iota_result;
// using std::ranges::iota;

#if _LIBCPP_STD_VER >= 23
using std::ranges::iota;
using std::ranges::iota_result;
#endif // _LIBCPP_STD_VER >= 23

} // namespace ranges

// [numeric.ops.gcd], greatest common divisor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ static_assert(sizeof(std::ranges::in_out_out_result<Empty, Empty, char>) == 2);
static_assert(sizeof(std::ranges::in_out_out_result<int, Empty, Empty2>) == sizeof(int));
static_assert(sizeof(std::ranges::in_out_out_result<Empty, Empty, Empty>) == 3);

#if TEST_STD_VER >= 23
#if _LIBCPP_STD_VER >= 23
static_assert(sizeof(std::ranges::out_value_result<Empty, int>) == sizeof(int));
static_assert(sizeof(std::ranges::out_value_result<int, Empty>) == sizeof(int));
static_assert(sizeof(std::ranges::out_value_result<Empty, Empty>) == 2);

static_assert(sizeof(std::ranges::in_value_result<Empty, int>) == sizeof(int));
static_assert(sizeof(std::ranges::in_value_result<int, Empty>) == sizeof(int));
Expand Down
Loading
Loading