Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
698bdd6
[libc++] Implement `views::join_with`
JMazurkiewicz Feb 2, 2024
b631ccd
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Nov 21, 2024
2370857
Add `[[nodiscard]]` to private functions
JMazurkiewicz Nov 21, 2024
b4afb2c
Add third template argument in `__join_with_view_iterator_category`
JMazurkiewicz Nov 21, 2024
7523023
Add missing <includes>
JMazurkiewicz Nov 27, 2024
5714983
Clang 17 is no longer supported
JMazurkiewicz Nov 27, 2024
6778426
Implement LWG-4074
JMazurkiewicz Nov 27, 2024
3a73fac
Usa `[[no_unique_address]]` in `join_with_view::sentinel`
JMazurkiewicz Nov 27, 2024
f6f603d
Cleanup `[[no_unique_address]]` tests
JMazurkiewicz Nov 28, 2024
e55c077
Test when result of `operator*` is type different from `range_referen…
JMazurkiewicz Nov 28, 2024
5a3996a
Various cleanups
JMazurkiewicz Nov 28, 2024
8b3e36c
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Dec 16, 2024
ee942ce
Fix formatting
JMazurkiewicz Dec 16, 2024
56d8850
Fix `example.pass.cpp` test
JMazurkiewicz Dec 16, 2024
15efa6f
Fix `19.rst` file
JMazurkiewicz Dec 16, 2024
f267d76
Enable `iterator/no_unique_address.compile.pass.cpp` test for MSVC
JMazurkiewicz Dec 16, 2024
3ad462c
Fix formatting (again)
JMazurkiewicz Dec 16, 2024
fb5ab01
Remove empty `test_end` function
JMazurkiewicz Jan 9, 2025
4ab1ee2
Test explicitness of default constructor of `join_with_view`
JMazurkiewicz Jan 9, 2025
bf1eeac
Test explicitness of `join_with_view::iterator(iterator<!Const>)` con…
JMazurkiewicz Jan 9, 2025
3771be9
Test explicitness of default constructor of `join_with_view::iterator`
JMazurkiewicz Jan 9, 2025
04942c0
Parametrise `test_pre_increment` on `ref-is-glvalue` being `true` or …
JMazurkiewicz Jan 9, 2025
42ce9c2
Add extra test for `iter_move` (make sure it calls underlying `iter_m…
JMazurkiewicz Jan 9, 2025
21896e9
Remove GCC workaround from `increment.pass.cpp`
JMazurkiewicz Jan 9, 2025
19e4fa2
Add extra test for `iter_swap` (make sure it calls underlying `iter_s…
JMazurkiewicz Jan 9, 2025
14471bc
Make sure `CIter` and `Iter` are different types (`ctor.not_const.pas…
JMazurkiewicz Jan 9, 2025
52ad025
Make sure `CIter` and `Iter` are different types (`eq.pass.cpp`)
JMazurkiewicz Jan 9, 2025
d52bdbf
Make sure `CSent` and `Sent` are different types (`ctor.not_const.pas…
JMazurkiewicz Jan 9, 2025
96eae0b
Make sure `CSent` and `Sent` are different types (`eq.pass.cpp`)
JMazurkiewicz Jan 9, 2025
0dc76bb
Add missing `<array>` include in `iter_swap.pass.cpp`
JMazurkiewicz Jan 13, 2025
9760ec3
Fix `sentinel::operator==`
JMazurkiewicz Jan 13, 2025
8ebaa0c
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Jan 16, 2025
d9d0033
Fix formatting
JMazurkiewicz Jan 16, 2025
d3c014f
Clarify some comments in `test_post_increment`
JMazurkiewicz Jan 17, 2025
abe8ab9
Use `_LIBCPP_NODEBUG` attribute
JMazurkiewicz Jan 28, 2025
4972ccc
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Jan 28, 2025
4601812
[NFC] Use `// REQUIRES: std-at-least-c++23`
JMazurkiewicz Jan 28, 2025
9847c22
More `_LIBCPP_NODEBUG`
JMazurkiewicz Jan 28, 2025
6a4a0a4
Fix unstable ABI tests
JMazurkiewicz Jan 30, 2025
dfe5543
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Jan 30, 2025
60264b0
Target LLVM 21
JMazurkiewicz Jan 30, 2025
36861f1
Trigger CI due to GitHub "incident"
JMazurkiewicz Jan 30, 2025
966b3bb
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Feb 8, 2025
3d54775
Add links to GitHub in `21.rst`
JMazurkiewicz Mar 18, 2025
10fdb29
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Mar 18, 2025
30d02a1
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Mar 31, 2025
6950e48
Don't use `std::is_trivial` (deprecated in C++26)
JMazurkiewicz Apr 14, 2025
41b935b
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Apr 14, 2025
a0420dc
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz May 8, 2025
95ea7bc
`is_reference_v<range_reference_t<_Base>>` => `is_reference_v<_InnerB…
JMazurkiewicz May 15, 2025
8ab29fb
`[[__nodiscard__]]` => `[[nodiscard]]`
JMazurkiewicz May 15, 2025
7198928
Add static member function in `__sentinel` to access priavate member …
JMazurkiewicz May 15, 2025
6cb18ac
Fix `iter_swap.pass.cpp` (friendship issues)
JMazurkiewicz May 15, 2025
37525db
Add `static_cast<bool>` in `end.pass.cpp` to avoid truncation warning…
JMazurkiewicz May 15, 2025
de46d63
Update synopsis in `<ranges>` (LWG-4074)
JMazurkiewicz May 20, 2025
fa9e257
Merge remote-tracking branch 'upstream/main' into libcxx/ranges/join_…
JMazurkiewicz Jun 11, 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
Prev Previous commit
Next Next commit
Implement LWG-4074
  • Loading branch information
JMazurkiewicz committed Nov 27, 2024
commit 67784267be6c04786ff9bed56026e2b63134b2f0
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx2cIssues.csv
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"`LWG4060 <https://wg21.link/LWG4060>`__","``submdspan`` preconditions do not forbid creating invalid pointer","2024-06 (St. Louis)","","",""
"`LWG4061 <https://wg21.link/LWG4061>`__","Should ``std::basic_format_context`` be default-constructible/copyable/movable?","2024-06 (St. Louis)","|Complete|","19",""
"`LWG4071 <https://wg21.link/LWG4071>`__","``reference_wrapper`` comparisons are not SFINAE-friendly","2024-06 (St. Louis)","|Complete|","19",""
"`LWG4074 <https://wg21.link/LWG4074>`__","``compatible-joinable-ranges`` is underconstrained","2024-06 (St. Louis)","","",""
"`LWG4074 <https://wg21.link/LWG4074>`__","``compatible-joinable-ranges`` is underconstrained","2024-06 (St. Louis)","|Complete|","20",""
"`LWG4076 <https://wg21.link/LWG4076>`__","``concat_view`` should be freestanding","2024-06 (St. Louis)","","",""
"`LWG4079 <https://wg21.link/LWG4079>`__","Missing Preconditions in ``concat_view::iterator``\`s conversion constructor","2024-06 (St. Louis)","","",""
"`LWG4082 <https://wg21.link/LWG4082>`__","``views::concat(r)`` is well-formed when ``r`` is an ``output_range``","2024-06 (St. Louis)","","",""
Expand Down
40 changes: 40 additions & 0 deletions libcxx/include/__ranges/concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
#ifndef _LIBCPP___RANGES_CONCEPTS_H
#define _LIBCPP___RANGES_CONCEPTS_H

#include <__concepts/common_reference_with.h>
#include <__concepts/constructible.h>
#include <__concepts/convertible_to.h>
#include <__concepts/movable.h>
#include <__concepts/same_as.h>
#include <__config>
Expand All @@ -25,6 +27,8 @@
#include <__ranges/enable_view.h>
#include <__ranges/size.h>
#include <__type_traits/add_pointer.h>
#include <__type_traits/common_reference.h>
#include <__type_traits/common_type.h>
#include <__type_traits/is_reference.h>
#include <__type_traits/remove_cvref.h>
#include <__type_traits/remove_reference.h>
Expand Down Expand Up @@ -133,6 +137,42 @@ concept viewable_range =
(is_lvalue_reference_v<_Tp> ||
(movable<remove_reference_t<_Tp>> && !__is_std_initializer_list<remove_cvref_t<_Tp>>))));

# if _LIBCPP_STD_VER >= 23

template <class... _Rs>
using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;

template <class... _Rs>
using __concat_value_t = common_type_t<range_value_t<_Rs>...>;

template <class... _Rs>
using __concat_rvalue_reference_t = common_reference_t<range_rvalue_reference_t<_Rs>...>;

template <class _Ref, class _RRef, class _It>
concept __concat_indirectly_readable_impl = requires(const _It __it) {
{ *__it } -> convertible_to<_Ref>;
{ ranges::iter_move(__it) } -> convertible_to<_RRef>;
};

template <class... _Rs>
concept __concat_indirectly_readable =
common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&> &&
common_reference_with<__concat_reference_t<_Rs...>&&, __concat_rvalue_reference_t<_Rs...>&&> &&
common_reference_with<__concat_rvalue_reference_t<_Rs...>&&, const __concat_value_t<_Rs...>&> &&
(__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
__concat_rvalue_reference_t<_Rs...>,
iterator_t<_Rs>> &&
...);

template <class... _Rs>
concept __concatable = requires {
typename __concat_reference_t<_Rs...>;
typename __concat_value_t<_Rs...>;
typename __concat_rvalue_reference_t<_Rs...>;
} && __concat_indirectly_readable<_Rs...>;

# endif // _LIBCPP_STD_VER >= 23

} // namespace ranges

#endif // _LIBCPP_STD_VER >= 20
Expand Down
18 changes: 7 additions & 11 deletions libcxx/include/__ranges/join_with_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 23

namespace ranges {
template <class _Range, class _Pattern>
concept __compatible_joinable_ranges =
common_with<range_value_t<_Range>, range_value_t<_Pattern>> &&
common_reference_with<range_reference_t<_Range>, range_reference_t<_Pattern>> &&
common_reference_with<range_rvalue_reference_t<_Range>, range_rvalue_reference_t<_Pattern>>;

template <class _Range>
concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;

template <input_range _View, forward_range _Pattern>
requires view<_View> && input_range<range_reference_t<_View>> && view<_Pattern> &&
__compatible_joinable_ranges<range_reference_t<_View>, _Pattern>
__concatable<range_reference_t<_View>, _Pattern>
class join_with_view : public view_interface<join_with_view<_View, _Pattern>> {
using _InnerRng = range_reference_t<_View>;

Expand Down Expand Up @@ -121,7 +115,8 @@ class join_with_view : public view_interface<join_with_view<_View, _Pattern>> {

[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
requires forward_range<const _View> && forward_range<const _Pattern> &&
is_reference_v<range_reference_t<const _View>> && input_range<range_reference_t<const _View>>
is_reference_v<range_reference_t<const _View>> && input_range<range_reference_t<const _View>> &&
__concatable<range_reference_t<const _View>, const _Pattern>
{
return __iterator<true>{*this, ranges::begin(__base_)};
}
Expand All @@ -137,7 +132,8 @@ class join_with_view : public view_interface<join_with_view<_View, _Pattern>> {

[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
requires forward_range<const _View> && forward_range<const _Pattern> &&
is_reference_v<range_reference_t<const _View>> && input_range<range_reference_t<const _View>>
is_reference_v<range_reference_t<const _View>> && input_range<range_reference_t<const _View>> &&
__concatable<range_reference_t<const _View>, const _Pattern>
{
using _InnerConstRng = range_reference_t<const _View>;
if constexpr (forward_range<_InnerConstRng> && common_range<const _View> && common_range<_InnerConstRng>)
Expand Down Expand Up @@ -187,7 +183,7 @@ struct __join_with_view_iterator_category<_Base, _PatternBase, _InnerBase> {

template <input_range _View, forward_range _Pattern>
requires view<_View> && input_range<range_reference_t<_View>> && view<_Pattern> &&
__compatible_joinable_ranges<range_reference_t<_View>, _Pattern>
__concatable<range_reference_t<_View>, _Pattern>
template <bool _Const>
struct join_with_view<_View, _Pattern>::__iterator
: public __join_with_view_iterator_category<__maybe_const<_Const, _View>, __maybe_const<_Const, _Pattern>> {
Expand Down Expand Up @@ -395,7 +391,7 @@ struct join_with_view<_View, _Pattern>::__iterator

template <input_range _View, forward_range _Pattern>
requires view<_View> && input_range<range_reference_t<_View>> && view<_Pattern> &&
__compatible_joinable_ranges<range_reference_t<_View>, _Pattern>
__concatable<range_reference_t<_View>, _Pattern>
template <bool _Const>
struct join_with_view<_View, _Pattern>::__sentinel {
private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ constexpr void test_const_begin() {
using JWV = std::ranges::join_with_view<MaybeSimpleForwardView<true>, MaybeSimplePattern<true>>;
static_assert(std::same_as<std::ranges::iterator_t<JWV&>, std::ranges::iterator_t<const JWV&>>);
}

{ // Check LWG-4074: compatible-joinable-ranges is underconstrained
static_assert(!JoinWithViewHasConstBegin<BasicVectorView<int, ViewProperties{}, forward_iterator>,
lwg4074::PatternWithProxyConstAccess>);
}
}

constexpr bool test() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <vector>

#include "test_iterators.h"
#include "../types.h"

template <class View, class Pattern>
concept CanFormJoinWithView = requires { typename std::ranges::join_with_view<View, Pattern>; };
Expand Down Expand Up @@ -133,7 +134,7 @@ static_assert(!CanFormJoinWithView<View, Pattern>);

// join_with_view is not valid when `range_reference_t<View>` and pattern
// does not model together compatible-joinable-ranges
namespace test_when_used_ranges_are_not_compatible_joinable_ranges {
namespace test_when_used_ranges_are_not_concatable {
using std::ranges::range_reference_t;
using std::ranges::range_rvalue_reference_t;
using std::ranges::range_value_t;
Expand All @@ -144,15 +145,15 @@ struct View : std::ranges::view_base {
InnerRange* end();
};

namespace no_common_range_value_type {
namespace no_concat_reference_t {
struct ValueType {};

struct InnerRange {
struct It {
using difference_type = ptrdiff_t;
struct value_type {};

using difference_type = std::ptrdiff_t;
using value_type = ValueType;
struct reference {
operator value_type();
operator float();
};

It& operator++();
Expand All @@ -165,28 +166,42 @@ struct InnerRange {
};

struct Pattern : std::ranges::view_base {
const float* begin();
const float* end();
struct It {
using difference_type = std::ptrdiff_t;
using value_type = ValueType;
struct reference {
operator value_type();
};

It& operator++();
It operator++(int);
reference operator*() const;
bool operator==(const It&) const;
friend value_type&& iter_move(const It&);
};

It begin();
It end();
};

static_assert(std::ranges::input_range<InnerRange>);
static_assert(std::ranges::forward_range<Pattern>);
static_assert(std::ranges::view<Pattern>);
static_assert(!std::common_with<range_value_t<InnerRange>, range_value_t<Pattern>>);
static_assert(std::common_reference_with<range_reference_t<InnerRange>, range_reference_t<Pattern>>);
static_assert(!std::common_reference_with<range_reference_t<InnerRange>, range_reference_t<Pattern>>);
static_assert(std::common_with<range_value_t<InnerRange>, range_value_t<Pattern>>);
static_assert(std::common_reference_with<range_rvalue_reference_t<InnerRange>, range_rvalue_reference_t<Pattern>>);
static_assert(!CanFormJoinWithView<View<InnerRange>, Pattern>);
} // namespace no_common_range_value_type

namespace no_common_range_reference_type {
struct ValueType {};
} // namespace no_concat_reference_t

namespace no_concat_value_t {
struct InnerRange {
struct It {
using difference_type = ptrdiff_t;
using value_type = ValueType;
using difference_type = std::ptrdiff_t;
struct value_type {};

struct reference {
operator value_type();
operator float();
};

It& operator++();
Expand All @@ -199,34 +214,20 @@ struct InnerRange {
};

struct Pattern : std::ranges::view_base {
struct It {
using difference_type = ptrdiff_t;
using value_type = ValueType;
struct reference {
operator value_type();
};

It& operator++();
It operator++(int);
reference operator*() const;
bool operator==(const It&) const;
friend value_type&& iter_move(const It&);
};

It begin();
It end();
const float* begin();
const float* end();
};

static_assert(std::ranges::input_range<InnerRange>);
static_assert(std::ranges::forward_range<Pattern>);
static_assert(std::ranges::view<Pattern>);
static_assert(std::common_with<range_value_t<InnerRange>, range_value_t<Pattern>>);
static_assert(!std::common_reference_with<range_reference_t<InnerRange>, range_reference_t<Pattern>>);
static_assert(std::common_reference_with<range_reference_t<InnerRange>, range_reference_t<Pattern>>);
static_assert(!std::common_with<range_value_t<InnerRange>, range_value_t<Pattern>>);
static_assert(std::common_reference_with<range_rvalue_reference_t<InnerRange>, range_rvalue_reference_t<Pattern>>);
static_assert(!CanFormJoinWithView<View<InnerRange>, Pattern>);
} // namespace no_common_range_reference_type
} // namespace no_concat_value_t

namespace no_common_range_rvalue_reference_type {
namespace no_concat_rvalue_reference_t {
struct InnerRange {
using It = cpp20_input_iterator<int*>;
It begin();
Expand All @@ -235,7 +236,7 @@ struct InnerRange {

struct Pattern : std::ranges::view_base {
struct It {
using difference_type = ptrdiff_t;
using difference_type = std::ptrdiff_t;
struct value_type {
operator int() const;
};
Expand All @@ -258,9 +259,31 @@ struct Pattern : std::ranges::view_base {
static_assert(std::ranges::input_range<InnerRange>);
static_assert(std::ranges::forward_range<Pattern>);
static_assert(std::ranges::view<Pattern>);
static_assert(std::common_with<range_value_t<InnerRange>, range_value_t<Pattern>>);
static_assert(std::common_reference_with<range_reference_t<InnerRange>, range_reference_t<Pattern>>);
static_assert(std::common_with<range_value_t<InnerRange>, range_value_t<Pattern>>);
static_assert(!std::common_reference_with<range_rvalue_reference_t<InnerRange>, range_rvalue_reference_t<Pattern>>);
static_assert(!CanFormJoinWithView<View<InnerRange>, Pattern>);
} // namespace no_common_range_rvalue_reference_type
} // namespace test_when_used_ranges_are_not_compatible_joinable_ranges
} // namespace no_concat_rvalue_reference_t

namespace not_concat_indirectly_readable { // Required after LWG-4074 ("compatible-joinable-ranges is underconstrained")
struct InnerRange {
using It = cpp20_input_iterator<int*>;
It begin();
sentinel_wrapper<It> end();
};

struct Pattern : std::ranges::view_base {
lwg4074::Iter begin();
lwg4074::Iter end();
};

static_assert(std::ranges::input_range<InnerRange>);
static_assert(std::ranges::forward_range<Pattern>);
static_assert(std::ranges::view<Pattern>);
static_assert(std::common_reference_with<range_reference_t<InnerRange>, range_reference_t<Pattern>>);
static_assert(std::common_with<range_value_t<InnerRange>, range_value_t<Pattern>>);
static_assert(std::common_reference_with<range_rvalue_reference_t<InnerRange>, range_rvalue_reference_t<Pattern>>);
LIBCPP_STATIC_ASSERT(!std::ranges::__concat_indirectly_readable<InnerRange, Pattern>);
static_assert(!CanFormJoinWithView<View<InnerRange>, Pattern>);
} // namespace not_concat_indirectly_readable
} // namespace test_when_used_ranges_are_not_concatable
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ constexpr bool test() {
static_assert(std::same_as<Sentinel, ConstSentinel>);
}

// Check LWG-4074: compatible-joinable-ranges is underconstrained
static_assert(!JoinWithViewHasConstEnd<BasicVectorView<int, ViewProperties{}, forward_iterator>,
lwg4074::PatternWithProxyConstAccess>);

return true;
}

Expand Down
Loading