Skip to content

Commit 475cbf0

Browse files
authored
[libc++] Implement ranges::iota (llvm#68494)
# Overview As a disclaimer, this is my first PR to LLVM and while I've tried to ensure I've followed the LLVM and libc++ contributing guidelines, there's probably a good chance I missed something. If I have, just let me know and I'll try to correct it as soon as I can. This PR implements `std::ranges::iota` and `std::ranges::out_value_result` outlined in [P2440r1](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2440r1.html). As outlined in the paper above, I've: - Implemented `out_value_result` and added to `<algorithm>` - Added `out_value_result`, `iota_result`, and two overloads of `iota` to `std::ranges` in `<numeric>` - Updated the version macro `__cpp_lib_ranges_iota` in `<version>` I've also added tests for `ranges::iota` and `ranges::out_value_result`. Lastly, I added those structs to the appropriate module files. Partially implements llvm#105184 EDIT: Forgot to mention in the original post, thanks to @hawkinsw for taking a look at a preliminary version of this PR! # TODOs - [x] Updating the range [status doc](https://github.com/jamesETsmith/llvm-project/blob/main/libcxx/docs/Status/RangesMajorFeatures.csv) - [x] Ensure all comments from https://reviews.llvm.org/D121436 are addressed here - [X] EDIT (I'll do this in a separate PR). ~~I'm open to implementing the rest of P2440r1 (`ranges::shift_left` and `ranges::shift_right`) if that's ok, I just wanted to get feedback on `ranges::iota` first~~ - [x] I've been having trouble building the modules locally and want to make sure that's working properly Closes: llvm#134060
1 parent 1379999 commit 475cbf0

22 files changed

+585
-68
lines changed

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ Status
374374
---------------------------------------------------------- -----------------
375375
``__cpp_lib_ranges_find_last`` ``202207L``
376376
---------------------------------------------------------- -----------------
377-
``__cpp_lib_ranges_iota`` *unimplemented*
377+
``__cpp_lib_ranges_iota`` ``202202L``
378378
---------------------------------------------------------- -----------------
379379
``__cpp_lib_ranges_join_with`` *unimplemented*
380380
---------------------------------------------------------- -----------------

libcxx/docs/Status/Cxx23.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ Library Working Group Issues Status
4040
.. csv-table::
4141
:file: Cxx23Issues.csv
4242
:header-rows: 1
43-
:widths: auto
43+
:widths: auto

libcxx/docs/Status/Cxx23Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","|Partial|","","Implemented the type traits only."
4747
"`P2273R3 <https://wg21.link/P2273R3>`__","Making ``std::unique_ptr`` constexpr","2022-02 (Virtual)","|Complete|","16",""
4848
"`P2387R3 <https://wg21.link/P2387R3>`__","Pipe support for user-defined range adaptors","2022-02 (Virtual)","|Complete|","19",""
49-
"`P2440R1 <https://wg21.link/P2440R1>`__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","","",""
49+
"`P2440R1 <https://wg21.link/P2440R1>`__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","|Partial|","","Only ``ranges::iota`` is implemented."
5050
"`P2441R2 <https://wg21.link/P2441R2>`__","``views::join_with``","2022-02 (Virtual)","|In Progress|","",""
5151
"`P2442R1 <https://wg21.link/P2442R1>`__","Windowing range adaptors: ``views::chunk`` and ``views::slide``","2022-02 (Virtual)","","",""
5252
"`P2443R1 <https://wg21.link/P2443R1>`__","``views::chunk_by``","2022-02 (Virtual)","|Complete|","18",""

libcxx/include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ set(files
6464
__algorithm/next_permutation.h
6565
__algorithm/none_of.h
6666
__algorithm/nth_element.h
67+
__algorithm/out_value_result.h
6768
__algorithm/partial_sort.h
6869
__algorithm/partial_sort_copy.h
6970
__algorithm/partition.h
@@ -615,6 +616,7 @@ set(files
615616
__numeric/midpoint.h
616617
__numeric/partial_sum.h
617618
__numeric/pstl.h
619+
__numeric/ranges_iota.h
618620
__numeric/reduce.h
619621
__numeric/saturation_arithmetic.h
620622
__numeric/transform_exclusive_scan.h
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP___ALGORITHM_OUT_VALUE_RESULT_H
11+
#define _LIBCPP___ALGORITHM_OUT_VALUE_RESULT_H
12+
13+
#include <__concepts/convertible_to.h>
14+
#include <__config>
15+
#include <__utility/move.h>
16+
17+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18+
# pragma GCC system_header
19+
#endif
20+
21+
_LIBCPP_PUSH_MACROS
22+
#include <__undef_macros>
23+
24+
_LIBCPP_BEGIN_NAMESPACE_STD
25+
26+
#if _LIBCPP_STD_VER >= 23
27+
28+
namespace ranges {
29+
30+
template <class _OutIter1, class _ValType1>
31+
struct out_value_result {
32+
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
33+
_LIBCPP_NO_UNIQUE_ADDRESS _ValType1 value;
34+
35+
template <class _OutIter2, class _ValType2>
36+
requires convertible_to<const _OutIter1&, _OutIter2> && convertible_to<const _ValType1&, _ValType2>
37+
_LIBCPP_HIDE_FROM_ABI constexpr operator out_value_result<_OutIter2, _ValType2>() const& {
38+
return {out, value};
39+
}
40+
41+
template <class _OutIter2, class _ValType2>
42+
requires convertible_to<_OutIter1, _OutIter2> && convertible_to<_ValType1, _ValType2>
43+
_LIBCPP_HIDE_FROM_ABI constexpr operator out_value_result<_OutIter2, _ValType2>() && {
44+
return {std::move(out), std::move(value)};
45+
}
46+
};
47+
48+
} // namespace ranges
49+
50+
#endif // _LIBCPP_STD_VER >= 23
51+
52+
_LIBCPP_END_NAMESPACE_STD
53+
54+
_LIBCPP_POP_MACROS
55+
56+
#endif // _LIBCPP___ALGORITHM_OUT_VALUE_RESULT_H
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP___NUMERIC_RANGES_IOTA_H
11+
#define _LIBCPP___NUMERIC_RANGES_IOTA_H
12+
13+
#include <__algorithm/out_value_result.h>
14+
#include <__config>
15+
#include <__iterator/concepts.h>
16+
#include <__ranges/access.h>
17+
#include <__ranges/concepts.h>
18+
#include <__ranges/dangling.h>
19+
#include <__utility/as_const.h>
20+
#include <__utility/move.h>
21+
22+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23+
# pragma GCC system_header
24+
#endif
25+
26+
_LIBCPP_PUSH_MACROS
27+
#include <__undef_macros>
28+
29+
_LIBCPP_BEGIN_NAMESPACE_STD
30+
31+
#if _LIBCPP_STD_VER >= 23
32+
namespace ranges {
33+
template <typename _Out, typename _Tp>
34+
using iota_result = ranges::out_value_result<_Out, _Tp>;
35+
36+
struct __iota_fn {
37+
public:
38+
template <input_or_output_iterator _Out, sentinel_for<_Out> _Sent, weakly_incrementable _Tp>
39+
requires indirectly_writable<_Out, const _Tp&>
40+
_LIBCPP_HIDE_FROM_ABI static constexpr iota_result<_Out, _Tp> operator()(_Out __first, _Sent __last, _Tp __value) {
41+
while (__first != __last) {
42+
*__first = std::as_const(__value);
43+
++__first;
44+
++__value;
45+
}
46+
return {std::move(__first), std::move(__value)};
47+
}
48+
49+
template <weakly_incrementable _Tp, ranges::output_range<const _Tp&> _Range>
50+
_LIBCPP_HIDE_FROM_ABI static constexpr iota_result<ranges::borrowed_iterator_t<_Range>, _Tp>
51+
operator()(_Range&& __r, _Tp __value) {
52+
return operator()(ranges::begin(__r), ranges::end(__r), std::move(__value));
53+
}
54+
};
55+
56+
inline constexpr auto iota = __iota_fn{};
57+
} // namespace ranges
58+
59+
#endif // _LIBCPP_STD_VER >= 23
60+
61+
_LIBCPP_END_NAMESPACE_STD
62+
63+
_LIBCPP_POP_MACROS
64+
65+
#endif // _LIBCPP___NUMERIC_RANGES_IOTA_H

libcxx/include/algorithm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ namespace ranges {
4545
template <class I, class T>
4646
struct in_value_result; // since C++23
4747
48+
template <class O, class T>
49+
struct out_value_result; // since C++23
50+
4851
template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
4952
indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> // since C++20
5053
constexpr I min_element(I first, S last, Comp comp = {}, Proj proj = {});
@@ -1936,6 +1939,7 @@ template <class BidirectionalIterator, class Compare>
19361939
# include <__algorithm/in_out_result.h>
19371940
# include <__algorithm/lexicographical_compare_three_way.h>
19381941
# include <__algorithm/min_max_result.h>
1942+
# include <__algorithm/out_value_result.h>
19391943
# include <__algorithm/ranges_adjacent_find.h>
19401944
# include <__algorithm/ranges_all_of.h>
19411945
# include <__algorithm/ranges_any_of.h>

libcxx/include/module.modulemap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ module std [system] {
490490
module next_permutation { header "__algorithm/next_permutation.h" }
491491
module none_of { header "__algorithm/none_of.h" }
492492
module nth_element { header "__algorithm/nth_element.h" }
493+
module out_value_result { header "__algorithm/out_value_result.h" }
493494
module partial_sort_copy { header "__algorithm/partial_sort_copy.h" }
494495
module partial_sort { header "__algorithm/partial_sort.h" }
495496
module partition_copy { header "__algorithm/partition_copy.h" }
@@ -1727,6 +1728,7 @@ module std [system] {
17271728
module partial_sum { header "__numeric/partial_sum.h" }
17281729
module pstl { header "__numeric/pstl.h" }
17291730
module reduce { header "__numeric/reduce.h" }
1731+
module ranges_iota { header "__numeric/ranges_iota.h" }
17301732
module saturation_arithmetic { header "__numeric/saturation_arithmetic.h" }
17311733
module transform_exclusive_scan { header "__numeric/transform_exclusive_scan.h" }
17321734
module transform_inclusive_scan { header "__numeric/transform_inclusive_scan.h" }

libcxx/include/numeric

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ constexpr T saturate_cast(U x) noexcept; // freestanding, Sin
172172
# include <__numeric/gcd_lcm.h>
173173
# include <__numeric/inclusive_scan.h>
174174
# include <__numeric/pstl.h>
175+
# include <__numeric/ranges_iota.h>
175176
# include <__numeric/reduce.h>
176177
# include <__numeric/transform_exclusive_scan.h>
177178
# include <__numeric/transform_inclusive_scan.h>

libcxx/include/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ __cpp_lib_void_t 201411L <type_traits>
513513
# define __cpp_lib_ranges_chunk_by 202202L
514514
# define __cpp_lib_ranges_contains 202207L
515515
# define __cpp_lib_ranges_find_last 202207L
516-
// # define __cpp_lib_ranges_iota 202202L
516+
# define __cpp_lib_ranges_iota 202202L
517517
// # define __cpp_lib_ranges_join_with 202202L
518518
# define __cpp_lib_ranges_repeat 202207L
519519
// # define __cpp_lib_ranges_slide 202202L

0 commit comments

Comments
 (0)