Skip to content
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

[libc++] P2770R0: "Stashing stashing iterators for proper flattening" #66033

Merged
merged 20 commits into from
Dec 12, 2023

Conversation

JMazurkiewicz
Copy link
Contributor

@JMazurkiewicz JMazurkiewicz commented Sep 11, 2023

@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Sep 11, 2023
Copy link
Member

@EricWF EricWF left a comment

Choose a reason for hiding this comment

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

The __as_lvalue function makes me super nervous, and I would like to have those concerns addressed before moving forward.

libcxx/include/__ranges/join_view.h Show resolved Hide resolved
libcxx/include/regex Show resolved Hide resolved

// Check prvalue (reference is dangling)
{
[[maybe_unused]] std::same_as<int&> decltype(auto) check = std::ranges::__as_lvalue(0);
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, this test show exactly how dangerous this API is.

Why do you need it?

Copy link
Contributor Author

@JMazurkiewicz JMazurkiewicz Sep 12, 2023

Choose a reason for hiding this comment

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

The as-lvalue function is used by P2770 to fix joining ranges of xvalues (rvalue references), see LWG-3791 and example: https://godbolt.org/z/Ev17W3b5W.


namespace ranges {
template <class _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp& __as_lvalue(_Tp&& __t) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't like this function, and am very tempted to block the patch on it alone.
I think it's a dangerous way to hide lifetime bugs.

Can you apply the [[lifetimebound]] attribute to the parameter and see if it still works?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you apply the [[lifetimebound]] attribute to the parameter and see if it still works?

I've applied it and no error has occurred in range.join tests. I've also updated range.adaptor.helpers/as-lvalue.cpp test to verify that calling function with prvalue gives a warning.

@JMazurkiewicz JMazurkiewicz force-pushed the libcxx/ranges/stashing branch 4 times, most recently from e24fbe9 to 0967951 Compare September 13, 2023 09:27
@JMazurkiewicz JMazurkiewicz marked this pull request as ready for review September 13, 2023 11:58
@JMazurkiewicz JMazurkiewicz requested a review from a team as a code owner September 13, 2023 11:58
@JMazurkiewicz JMazurkiewicz force-pushed the libcxx/ranges/stashing branch 2 times, most recently from 21eb0e0 to 28d5f0c Compare September 14, 2023 14:02
@@ -0,0 +1,39 @@
// -*- C++ -*-
Copy link
Member

Choose a reason for hiding this comment

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

As a general guideline, we try not to add headers with generic names like helpers.h. If this utility is needed and it is needed relatively widely, it should be in something like __utility/as_lvalue.h. Otherwise it could just live in join_view.h.

Copy link
Contributor

Choose a reason for hiding this comment

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

Otherwise it could just live in join_view.h.

Hmm, according to the paper, as-lvalue should be shared between join_view and join_with_view, and thus it deseves a separated internal header.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds reasonable, what do you think about __utility/as_lvalue.h?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've moved as-lvalue to __utility/as_lvalue.h, but I've left it in ranges namespace since it is used only by join and join_with views.

@@ -46,6 +46,7 @@ Paper Status
clang doesn't issue a diagnostic for deprecated using template declarations.
.. [#note-P2520R0] P2520R0: Libc++ implemented this paper as a DR in C++20 as well.
.. [#note-P2711R1] P2711R1: ``join_with_view`` hasn't been done yet since this type isn't implemented yet.
.. [#note-P2770R0] P2770R0: Same as the above.
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand this note. I'm not sure the note will make sense once this is rendered as HTML?

@github-actions
Copy link

github-actions bot commented Sep 23, 2023

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 13da9a58c5c823eeda6af125ef6df9d8b0748bd2 710398a5f10f949eab07ef4e2767f3619bad5e61 -- libcxx/include/__utility/as_lvalue.h libcxx/test/libcxx/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.lifetimebound.verify.cpp libcxx/test/libcxx/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.pass.cpp libcxx/test/libcxx/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.outer.pass.cpp libcxx/test/libcxx/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.pass.cpp libcxx/test/libcxx/ranges/range.adaptors/range.join/range.join.iterator/types.h libcxx/test/std/ranges/range.adaptors/range.join/lwg3698.pass.cpp libcxx/include/__ranges/join_view.h libcxx/include/regex libcxx/include/utility libcxx/modules/std/ranges.inc libcxx/test/libcxx/ranges/range.adaptors/range.join/segmented_iterator.compile.pass.cpp libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.segmented.pass.cpp libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.segmented.pass.cpp libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.segmented.pass.cpp libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.segmented.pass.cpp libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp libcxx/test/std/ranges/iterator_robust_against_adl.compile.pass.cpp libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp libcxx/test/std/re/re.iter/re.regiter/types.pass.cpp libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp libcxx/test/std/re/re.iter/re.tokiter/types.pass.cpp libcxx/test/libcxx/ranges/range.adaptors/range.adaptor.helpers/tuple-for-each.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/base.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/begin.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/ctad.compile.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/ctad.verify.cpp libcxx/test/std/ranges/range.adaptors/range.join/ctor.default.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/ctor.view.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/end.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/general.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/arrow.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.default.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.other.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/decrement.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/eq.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/increment.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/iter.move.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/iter.swap.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/member_types.compile.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/star.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.default.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.other.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/eq.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/types.h
View the diff from clang-format here.
diff --git a/libcxx/include/__ranges/join_view.h b/libcxx/include/__ranges/join_view.h
index f80beda33b..4e9eea074d 100644
--- a/libcxx/include/__ranges/join_view.h
+++ b/libcxx/include/__ranges/join_view.h
@@ -110,8 +110,7 @@ namespace ranges {
     _LIBCPP_HIDE_FROM_ABI
     constexpr auto begin() {
       if constexpr (forward_range<_View>) {
-        constexpr bool __use_const = __simple_view<_View> &&
-                                     is_reference_v<range_reference_t<_View>>;
+        constexpr bool __use_const = __simple_view<_View> && is_reference_v<range_reference_t<_View>>;
         return __iterator<__use_const>{*this, ranges::begin(__base_)};
       } else {
         __outer_.__emplace(ranges::begin(__base_));
@@ -119,11 +118,9 @@ namespace ranges {
       }
     }
 
-    template<class _V2 = _View>
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr auto begin() const
-      requires forward_range<const _V2> &&
-               is_reference_v<range_reference_t<const _V2>> &&
+    template <class _V2 = _View>
+    _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+      requires forward_range<const _V2> && is_reference_v<range_reference_t<const _V2>> &&
                input_range<range_reference_t<const _V2>>
     {
       return __iterator<true>{*this, ranges::begin(__base_)};
@@ -141,17 +138,13 @@ namespace ranges {
         return __sentinel<__simple_view<_View>>{*this};
     }
 
-    template<class _V2 = _View>
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr auto end() const
-      requires forward_range<const _V2> &&
-               is_reference_v<range_reference_t<const _V2>> &&
+    template <class _V2 = _View>
+    _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+      requires forward_range<const _V2> && is_reference_v<range_reference_t<const _V2>> &&
                input_range<range_reference_t<const _V2>>
     {
       using _ConstInnerRange = range_reference_t<const _View>;
-      if constexpr (forward_range<_ConstInnerRange> &&
-                    common_range<const _View> &&
-                    common_range<_ConstInnerRange>) {
+      if constexpr (forward_range<_ConstInnerRange> && common_range<const _View> && common_range<_ConstInnerRange>) {
         return __iterator<true>{*this, ranges::end(__base_)};
       } else {
         return __sentinel<true>{*this};
@@ -218,8 +211,8 @@ namespace ranges {
 
     static constexpr bool __ref_is_glvalue = is_reference_v<range_reference_t<_Base>>;
 
-    static constexpr bool _OuterPresent = forward_range<_Base>;
-    using _OuterType                    = _If<_OuterPresent, _Outer, std::__empty>;
+    static constexpr bool _OuterPresent           = forward_range<_Base>;
+    using _OuterType                              = _If<_OuterPresent, _Outer, std::__empty>;
     _LIBCPP_NO_UNIQUE_ADDRESS _OuterType __outer_ = _OuterType();
 
     optional<_Inner> __inner_;
@@ -377,11 +370,8 @@ namespace ranges {
       return __tmp;
     }
 
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
-      requires __ref_is_glvalue &&
-               forward_range<_Base> &&
-               equality_comparable<iterator_t<range_reference_t<_Base>>>
+    _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
+      requires __ref_is_glvalue && forward_range<_Base> && equality_comparable<iterator_t<range_reference_t<_Base>>>
     {
       return __x.__outer_ == __y.__outer_ && __x.__inner_ == __y.__inner_;
     }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp
index 9beb3d282a..3e5f2b6f04 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp
@@ -20,10 +20,10 @@
 struct MoveOnlyOuter : SimpleForwardCommonOuter<ForwardCommonInner> {
   using SimpleForwardCommonOuter<ForwardCommonInner>::SimpleForwardCommonOuter;
 
-  constexpr MoveOnlyOuter(MoveOnlyOuter&&) = default;
+  constexpr MoveOnlyOuter(MoveOnlyOuter&&)      = default;
   constexpr MoveOnlyOuter(const MoveOnlyOuter&) = delete;
 
-  constexpr MoveOnlyOuter& operator=(MoveOnlyOuter&&) = default;
+  constexpr MoveOnlyOuter& operator=(MoveOnlyOuter&&)      = default;
   constexpr MoveOnlyOuter& operator=(const MoveOnlyOuter&) = delete;
 };
 
@@ -38,15 +38,15 @@ concept CanBePiped = requires(View&& view, T&& t) {
 };
 
 constexpr bool test() {
-  int buffer1[3] = {1, 2, 3};
-  int buffer2[2] = {4, 5};
-  int buffer3[4] = {6, 7, 8, 9};
+  int buffer1[3]      = {1, 2, 3};
+  int buffer2[2]      = {4, 5};
+  int buffer3[4]      = {6, 7, 8, 9};
   Foo nested[2][3][3] = {{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, {{10, 11, 12}, {13, 14, 15}, {16, 17, 18}}};
 
   {
     // Test `views::join(v)`
-    ForwardCommonInner inners[3] = {buffer1, buffer2, buffer3};
-    using Result = std::ranges::join_view<std::ranges::ref_view<ForwardCommonInner[3]>>;
+    ForwardCommonInner inners[3]          = {buffer1, buffer2, buffer3};
+    using Result                          = std::ranges::join_view<std::ranges::ref_view<ForwardCommonInner[3]>>;
     std::same_as<Result> decltype(auto) v = std::views::join(inners);
     assert(std::ranges::next(v.begin(), 9) == v.end());
     assert(&(*v.begin()) == buffer1);
@@ -54,8 +54,8 @@ constexpr bool test() {
 
   {
     // Test `views::join(move-only-view)`
-    ForwardCommonInner inners[3] = {buffer1, buffer2, buffer3};
-    using Result = std::ranges::join_view<MoveOnlyOuter>;
+    ForwardCommonInner inners[3]          = {buffer1, buffer2, buffer3};
+    using Result                          = std::ranges::join_view<MoveOnlyOuter>;
     std::same_as<Result> decltype(auto) v = std::views::join(MoveOnlyOuter{inners});
     assert(std::ranges::next(v.begin(), 9) == v.end());
     assert(&(*v.begin()) == buffer1);
@@ -80,7 +80,7 @@ constexpr bool test() {
     // Test `v | views::join`
     ForwardCommonInner inners[3] = {buffer1, buffer2, buffer3};
 
-    using Result = std::ranges::join_view<std::ranges::ref_view<ForwardCommonInner[3]>>;
+    using Result                          = std::ranges::join_view<std::ranges::ref_view<ForwardCommonInner[3]>>;
     std::same_as<Result> decltype(auto) v = inners | std::views::join;
     assert(std::ranges::next(v.begin(), 9) == v.end());
     assert(&(*v.begin()) == buffer1);
@@ -89,8 +89,8 @@ constexpr bool test() {
 
   {
     // Test `move-only-view | views::join`
-    ForwardCommonInner inners[3] = {buffer1, buffer2, buffer3};
-    using Result = std::ranges::join_view<MoveOnlyOuter>;
+    ForwardCommonInner inners[3]          = {buffer1, buffer2, buffer3};
+    using Result                          = std::ranges::join_view<MoveOnlyOuter>;
     std::same_as<Result> decltype(auto) v = MoveOnlyOuter{inners} | std::views::join;
     assert(std::ranges::next(v.begin(), 9) == v.end());
     assert(&(*v.begin()) == buffer1);
@@ -112,7 +112,7 @@ constexpr bool test() {
   {
     // Test `adaptor | views::join`
     auto join_twice = std::views::join | std::views::join;
-    auto jv = nested | join_twice;
+    auto jv         = nested | join_twice;
     ASSERT_SAME_TYPE(std::ranges::range_reference_t<decltype(jv)>, Foo&);
 
     assert(&(*jv.begin()) == &nested[0][0][0]);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/base.pass.cpp
index caf018b582..6fdc637f6f 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/base.pass.cpp
@@ -18,7 +18,7 @@
 #include "types.h"
 
 constexpr bool hasLValueQualifiedBase(auto&& view) {
-    return requires { view.base(); };
+  return requires { view.base(); };
 }
 
 constexpr bool test() {
@@ -26,7 +26,7 @@ constexpr bool test() {
 
   {
     ChildView children[4] = {ChildView(buffer[0]), ChildView(buffer[1]), ChildView(buffer[2]), ChildView(buffer[3])};
-    auto jv = std::ranges::join_view(ParentView{children});
+    auto jv               = std::ranges::join_view(ParentView{children});
     assert(std::move(jv).base().ptr_ == children);
 
     static_assert(!hasLValueQualifiedBase(jv));
@@ -38,7 +38,7 @@ constexpr bool test() {
     assert(jv.base().base() == buffer + 0);
 
     static_assert(hasLValueQualifiedBase(jv));
-    ASSERT_SAME_TYPE(decltype(jv.base()), std::ranges::ref_view<int [4][4]>);
+    ASSERT_SAME_TYPE(decltype(jv.base()), std::ranges::ref_view<int[4][4]>);
   }
 
   {
@@ -46,7 +46,7 @@ constexpr bool test() {
     assert(jv.base().base() == buffer + 0);
 
     static_assert(hasLValueQualifiedBase(jv));
-    ASSERT_SAME_TYPE(decltype(jv.base()), std::ranges::ref_view<int [4][4]>);
+    ASSERT_SAME_TYPE(decltype(jv.base()), std::ranges::ref_view<int[4][4]>);
   }
 
   return true;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/begin.pass.cpp
index 005d0d1d2d..b11cae35f8 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/begin.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/begin.pass.cpp
@@ -47,21 +47,24 @@ constexpr bool test() {
 
   {
     ChildView children[4] = {ChildView(buffer[0]), ChildView(buffer[1]), ChildView(buffer[2]), ChildView(buffer[3])};
-    auto jv = std::ranges::join_view(ParentView{children});
+    auto jv               = std::ranges::join_view(ParentView{children});
     assert(*jv.begin() == 1111);
   }
 
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0], 4), CopyableChild(buffer[1], 0), CopyableChild(buffer[2], 1),
-                                 CopyableChild(buffer[3], 0)};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0], 4),
+        CopyableChild(buffer[1], 0),
+        CopyableChild(buffer[2], 1),
+        CopyableChild(buffer[3], 0)};
     auto jv = std::ranges::join_view(ParentView{children});
     assert(*jv.begin() == 1111);
   }
 
   // Parent is empty.
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]),
-                                 CopyableChild(buffer[3])};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]), CopyableChild(buffer[3])};
     std::ranges::join_view jv(ParentView(children, 0));
     assert(jv.begin() == jv.end());
   }
@@ -89,24 +92,33 @@ constexpr bool test() {
 
   // Has all empty children.
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0], 0), CopyableChild(buffer[1], 0), CopyableChild(buffer[2], 0),
-                                 CopyableChild(buffer[3], 0)};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0], 0),
+        CopyableChild(buffer[1], 0),
+        CopyableChild(buffer[2], 0),
+        CopyableChild(buffer[3], 0)};
     auto jv = std::ranges::join_view(ParentView{children});
     assert(jv.begin() == jv.end());
   }
 
   // First child is empty, others are not.
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0], 4), CopyableChild(buffer[1], 0), CopyableChild(buffer[2], 0),
-                                 CopyableChild(buffer[3], 0)};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0], 4),
+        CopyableChild(buffer[1], 0),
+        CopyableChild(buffer[2], 0),
+        CopyableChild(buffer[3], 0)};
     auto jv = std::ranges::join_view(ParentView{children});
     assert(*jv.begin() == 1111);
   }
 
   // Last child is empty, others are not.
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0], 4), CopyableChild(buffer[1], 4), CopyableChild(buffer[2], 4),
-                                 CopyableChild(buffer[3], 0)};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0], 4),
+        CopyableChild(buffer[1], 4),
+        CopyableChild(buffer[2], 4),
+        CopyableChild(buffer[3], 0)};
     auto jv = std::ranges::join_view(ParentView{children});
     assert(*jv.begin() == 1111);
   }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/ctad.compile.pass.cpp
index a8eafc5a9c..0b78f74d50 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/ctad.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/ctad.compile.pass.cpp
@@ -15,25 +15,25 @@
 #include <utility>
 
 struct Child {
-  int *begin() const;
-  int *end() const;
+  int* begin() const;
+  int* end() const;
 };
 
 struct View : std::ranges::view_base {
-  Child *begin() const;
-  Child *end() const;
+  Child* begin() const;
+  Child* end() const;
 };
 
 struct Range {
-  Child *begin() const;
-  Child *end() const;
+  Child* begin() const;
+  Child* end() const;
 };
 
 struct BorrowedRange {
-  Child *begin() const;
-  Child *end() const;
+  Child* begin() const;
+  Child* end() const;
 };
-template<>
+template <>
 inline constexpr bool std::ranges::enable_borrowed_range<BorrowedRange> = true;
 
 struct NestedChildren : std::ranges::view_base {
@@ -42,41 +42,27 @@ struct NestedChildren : std::ranges::view_base {
 };
 
 void testCTAD() {
-    View v;
-    Range r;
-    BorrowedRange br;
+  View v;
+  Range r;
+  BorrowedRange br;
 
-    static_assert(std::same_as<
-        decltype(std::ranges::join_view(v)),
-        std::ranges::join_view<View>
-    >);
-    static_assert(std::same_as<
-        decltype(std::ranges::join_view(std::move(v))),
-        std::ranges::join_view<View>
-    >);
-    static_assert(std::same_as<
-        decltype(std::ranges::join_view(r)),
-        std::ranges::join_view<std::ranges::ref_view<Range>>
-    >);
-    static_assert(std::same_as<
-        decltype(std::ranges::join_view(std::move(r))),
-        std::ranges::join_view<std::ranges::owning_view<Range>>
-    >);
-    static_assert(std::same_as<
-        decltype(std::ranges::join_view(br)),
-        std::ranges::join_view<std::ranges::ref_view<BorrowedRange>>
-    >);
-    static_assert(std::same_as<
-        decltype(std::ranges::join_view(std::move(br))),
-        std::ranges::join_view<std::ranges::owning_view<BorrowedRange>>
-    >);
+  static_assert(std::same_as< decltype(std::ranges::join_view(v)), std::ranges::join_view<View> >);
+  static_assert(std::same_as< decltype(std::ranges::join_view(std::move(v))), std::ranges::join_view<View> >);
+  static_assert(
+      std::same_as< decltype(std::ranges::join_view(r)), std::ranges::join_view<std::ranges::ref_view<Range>> >);
+  static_assert(std::same_as< decltype(std::ranges::join_view(std::move(r))),
+                              std::ranges::join_view<std::ranges::owning_view<Range>> >);
+  static_assert(std::same_as< decltype(std::ranges::join_view(br)),
+                              std::ranges::join_view<std::ranges::ref_view<BorrowedRange>> >);
+  static_assert(std::same_as< decltype(std::ranges::join_view(std::move(br))),
+                              std::ranges::join_view<std::ranges::owning_view<BorrowedRange>> >);
 
-    NestedChildren n;
-    std::ranges::join_view jv(n);
+  NestedChildren n;
+  std::ranges::join_view jv(n);
 
-    // CTAD generated from the copy constructor instead of joining the join_view
-    static_assert(std::same_as< decltype(std::ranges::join_view(jv)), decltype(jv) >);
+  // CTAD generated from the copy constructor instead of joining the join_view
+  static_assert(std::same_as< decltype(std::ranges::join_view(jv)), decltype(jv) >);
 
-    // CTAD generated from the move constructor instead of joining the join_view
-    static_assert(std::same_as< decltype(std::ranges::join_view(std::move(jv))), decltype(jv) >);
+  // CTAD generated from the move constructor instead of joining the join_view
+  static_assert(std::same_as< decltype(std::ranges::join_view(std::move(jv))), decltype(jv) >);
 }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/ctad.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/ctad.verify.cpp
index 2c6eea5005..928aa4e986 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/ctad.verify.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/ctad.verify.cpp
@@ -17,7 +17,7 @@
 
 #include "test_iterators.h"
 
-template<class T>
+template <class T>
 struct Range {
   friend T* begin(Range&) { return nullptr; }
   friend T* begin(Range const&) { return nullptr; }
@@ -27,5 +27,6 @@ struct Range {
 
 void testExplicitCTAD() {
   Range<Range<int>> r;
-  std::ranges::join_view v = r; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'join_view'}}
+  std::ranges::join_view v =
+      r; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'join_view'}}
 }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/ctor.default.pass.cpp
index 0daff7d3b3..003990332c 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/ctor.default.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/ctor.default.pass.cpp
@@ -34,7 +34,7 @@ constexpr bool test() {
     assert(jv.base().i == 0);
   }
 
-  static_assert( std::default_initializable<std::ranges::join_view<ParentView<ChildView>>>);
+  static_assert(std::default_initializable<std::ranges::join_view<ParentView<ChildView>>>);
   static_assert(!std::default_initializable<std::ranges::join_view<CopyableParent>>);
 
   return true;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/ctor.view.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/ctor.view.pass.cpp
index 75d4c7e591..21f3ba8e25 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/ctor.view.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/ctor.view.pass.cpp
@@ -21,7 +21,7 @@ constexpr bool test() {
 
   {
     ChildView children[4] = {ChildView(buffer[0]), ChildView(buffer[1]), ChildView(buffer[2]), ChildView(buffer[3])};
-    auto jv = std::ranges::join_view(ParentView{children});
+    auto jv               = std::ranges::join_view(ParentView{children});
     assert(std::move(jv).base().ptr_ == children);
   }
 
@@ -32,7 +32,7 @@ constexpr bool test() {
 
   {
     // Test explicitness.
-    static_assert( std::is_constructible_v<std::ranges::join_view<ParentView<ChildView>>, ParentView<ChildView>>);
+    static_assert(std::is_constructible_v<std::ranges::join_view<ParentView<ChildView>>, ParentView<ChildView>>);
     static_assert(!std::is_convertible_v<std::ranges::join_view<ParentView<ChildView>>, ParentView<ChildView>>);
   }
 
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/end.pass.cpp
index 516ba25a0e..b7502d9a8d 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/end.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/end.pass.cpp
@@ -22,10 +22,7 @@
 #include "types.h"
 
 template <class T>
-concept HasConstEnd = requires (const T& t){
-  t.end();
-};
-
+concept HasConstEnd = requires(const T& t) { t.end(); };
 
 // | ID | outer  | outer   | outer  | inner | inner   | inner  |     end()     |    end()     |
 // |    | simple | forward | common | l_ref | forward | common |               |    const     |
@@ -232,14 +229,19 @@ constexpr bool test() {
 
   // Has some empty children.
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0], 4), CopyableChild(buffer[1], 0), CopyableChild(buffer[2], 1), CopyableChild(buffer[3], 0)};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0], 4),
+        CopyableChild(buffer[1], 0),
+        CopyableChild(buffer[2], 1),
+        CopyableChild(buffer[3], 0)};
     auto jv = std::ranges::join_view(ParentView(children));
     assert(jv.end() == std::ranges::next(jv.begin(), 5));
   }
 
   // Parent is empty.
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]), CopyableChild(buffer[3])};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]), CopyableChild(buffer[3])};
     std::ranges::join_view jv(ParentView(children, 0));
     assert(jv.end() == jv.begin());
   }
@@ -267,21 +269,33 @@ constexpr bool test() {
 
   // Has all empty children.
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0], 0), CopyableChild(buffer[1], 0), CopyableChild(buffer[2], 0), CopyableChild(buffer[3], 0)};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0], 0),
+        CopyableChild(buffer[1], 0),
+        CopyableChild(buffer[2], 0),
+        CopyableChild(buffer[3], 0)};
     auto jv = std::ranges::join_view(ParentView(children));
     assert(jv.end() == jv.begin());
   }
 
   // First child is empty, others are not.
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0], 4), CopyableChild(buffer[1], 0), CopyableChild(buffer[2], 0), CopyableChild(buffer[3], 0)};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0], 4),
+        CopyableChild(buffer[1], 0),
+        CopyableChild(buffer[2], 0),
+        CopyableChild(buffer[3], 0)};
     auto jv = std::ranges::join_view(ParentView(children));
     assert(jv.end() == std::ranges::next(jv.begin(), 4));
   }
 
   // Last child is empty, others are not.
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0], 4), CopyableChild(buffer[1], 4), CopyableChild(buffer[2], 4), CopyableChild(buffer[3], 0)};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0], 4),
+        CopyableChild(buffer[1], 4),
+        CopyableChild(buffer[2], 4),
+        CopyableChild(buffer[3], 0)};
     auto jv = std::ranges::join_view(ParentView(children));
     assert(jv.end() == std::ranges::next(jv.begin(), 12));
   }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/general.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/general.pass.cpp
index f92eb418fa..68b3850b05 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/general.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/general.pass.cpp
@@ -29,16 +29,16 @@ bool isEqual(R& r, I i) {
 int main(int, char**) {
   {
     int buffer[4][4] = {{1111, 2222, 3333, 4444}, {555, 666, 777, 888}, {99, 1010, 1111, 1212}, {13, 14, 15, 16}};
-    int* flattened = reinterpret_cast<int*>(buffer);
+    int* flattened   = reinterpret_cast<int*>(buffer);
 
     ChildView children[4] = {ChildView(buffer[0]), ChildView(buffer[1]), ChildView(buffer[2]), ChildView(buffer[3])};
-    auto jv = std::ranges::join_view(ParentView(children));
+    auto jv               = std::ranges::join_view(ParentView(children));
     assert(isEqual(jv, flattened));
   }
 
   {
     std::vector<std::string> vec = {"Hello", ",", " ", "World", "!"};
-    std::string check = "Hello, World!";
+    std::string check            = "Hello, World!";
     std::ranges::join_view jv(vec);
     assert(isEqual(jv, check.begin()));
   }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/arrow.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/arrow.pass.cpp
index ddcf66bfe7..7834a2e8d1 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/arrow.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/arrow.pass.cpp
@@ -23,14 +23,14 @@ template <class Base>
 struct move_only_input_iter_with_arrow {
   Base it_;
 
-  using value_type = std::iter_value_t<Base>;
-  using difference_type = std::intptr_t;
+  using value_type       = std::iter_value_t<Base>;
+  using difference_type  = std::intptr_t;
   using iterator_concept = std::input_iterator_tag;
 
   constexpr move_only_input_iter_with_arrow(Base it) : it_(std::move(it)) {}
-  constexpr move_only_input_iter_with_arrow(move_only_input_iter_with_arrow&&) = default;
-  constexpr move_only_input_iter_with_arrow(const move_only_input_iter_with_arrow&) = delete;
-  constexpr move_only_input_iter_with_arrow& operator=(move_only_input_iter_with_arrow&&) = default;
+  constexpr move_only_input_iter_with_arrow(move_only_input_iter_with_arrow&&)                 = default;
+  constexpr move_only_input_iter_with_arrow(const move_only_input_iter_with_arrow&)            = delete;
+  constexpr move_only_input_iter_with_arrow& operator=(move_only_input_iter_with_arrow&&)      = default;
   constexpr move_only_input_iter_with_arrow& operator=(const move_only_input_iter_with_arrow&) = delete;
 
   constexpr move_only_input_iter_with_arrow& operator++() {
@@ -41,7 +41,8 @@ struct move_only_input_iter_with_arrow {
 
   constexpr std::iter_reference_t<Base> operator*() const { return *it_; }
   constexpr auto operator->() const
-    requires(HasArrow<Base> && std::copyable<Base>) {
+    requires(HasArrow<Base> && std::copyable<Base>)
+  {
     return it_;
   }
 };
@@ -72,8 +73,8 @@ template <class Base>
 struct arrow_input_iter {
   Base it_;
 
-  using value_type = std::iter_value_t<Base>;
-  using difference_type = std::intptr_t;
+  using value_type       = std::iter_value_t<Base>;
+  using difference_type  = std::intptr_t;
   using iterator_concept = std::input_iterator_tag;
 
   arrow_input_iter() = default;
@@ -96,14 +97,15 @@ static_assert(std::ranges::input_range<ArrowInner>);
 static_assert(HasArrow<std::ranges::iterator_t<ArrowInner>>);
 
 constexpr bool test() {
-  Box buffer[4][4] = {{{1111}, {2222}, {3333}, {4444}},
-                      {{555}, {666}, {777}, {888}},
-                      {{99}, {1010}, {1111}, {1212}},
-                      {{13}, {14}, {15}, {16}}};
+  Box buffer[4][4] = {
+      {{1111}, {2222}, {3333}, {4444}},
+      {{555}, {666}, {777}, {888}},
+      {{99}, {1010}, {1111}, {1212}},
+      {{13}, {14}, {15}, {16}}};
 
   {
     // Copyable input iterator with arrow.
-    using BoxView = ValueView<Box>;
+    using BoxView              = ValueView<Box>;
     ValueView<Box> children[4] = {BoxView(buffer[0]), BoxView(buffer[1]), BoxView(buffer[2]), BoxView(buffer[3])};
     std::ranges::join_view jv(ValueView<ValueView<Box>>{children});
     assert(jv.begin()->x == 1111);
@@ -137,7 +139,7 @@ constexpr bool test() {
     // LWG3500 `join_view::iterator::operator->()` is bogus
     // `operator->` should not be defined if inner iterator does not have `operator->`
     // !has-arrow<InnerIter> && copyable<InnerIter>
-    using Inner = BufferView<forward_iterator<Box*>>;
+    using Inner     = BufferView<forward_iterator<Box*>>;
     Inner inners[2] = {buffer[0], buffer[1]};
     std::ranges::join_view jv{inners};
     static_assert(!HasArrow<decltype(std::ranges::begin(inners[0]))>);
@@ -151,7 +153,7 @@ constexpr bool test() {
     static_assert(HasArrow<decltype(std::ranges::begin(inners[0]))>);
     static_assert(HasArrow<decltype(jv.begin())>);
 
-    auto jv_it = jv.begin();
+    auto jv_it                                         = jv.begin();
     std::same_as<arrow_input_iter<Box*>> auto arrow_it = jv_it.operator->();
     assert(arrow_it->x == 1111);
   }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.default.pass.cpp
index 82fe824fad..d940b078f5 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.default.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.default.pass.cpp
@@ -25,7 +25,7 @@ struct view : std::ranges::view_base {
 
 template <class It>
 constexpr void test_default_constructible() {
-  using JoinView = std::ranges::join_view<view<It>>;
+  using JoinView     = std::ranges::join_view<view<It>>;
   using JoinIterator = std::ranges::iterator_t<JoinView>;
   static_assert(std::is_default_constructible_v<JoinIterator>);
   [[maybe_unused]] JoinIterator it;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.other.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.other.pass.cpp
index e220b2cfea..5f59ec4483 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.other.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/ctor.other.pass.cpp
@@ -21,24 +21,30 @@
 
 using ConstCompatibleInner = BufferView<int*>;
 
-using ConstIncompatibleInner = BufferView<forward_iterator<const int*>, forward_iterator<const int*>,
-                                          bidirectional_iterator<int*>, bidirectional_iterator<int*>>;
+using ConstIncompatibleInner =
+    BufferView<forward_iterator<const int*>,
+               forward_iterator<const int*>,
+               bidirectional_iterator<int*>,
+               bidirectional_iterator<int*>>;
 
 template <class Inner>
 using ConstCompatibleOuter = BufferView<const Inner*, const Inner*, Inner*, Inner*>;
 
 template <class Inner>
-using ConstIncompatibleOuter = BufferView<forward_iterator<const Inner*>, forward_iterator<const Inner*>,
-                                          bidirectional_iterator<Inner*>, bidirectional_iterator<Inner*>>;
+using ConstIncompatibleOuter =
+    BufferView<forward_iterator<const Inner*>,
+               forward_iterator<const Inner*>,
+               bidirectional_iterator<Inner*>,
+               bidirectional_iterator<Inner*>>;
 
 constexpr bool test() {
   int buffer[4][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]),
-                                 CopyableChild(buffer[3])};
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]), CopyableChild(buffer[3])};
     std::ranges::join_view jv(ForwardCopyableParent{children});
-    auto iter1 = jv.begin();
-    using iterator = decltype(iter1);
+    auto iter1           = jv.begin();
+    using iterator       = decltype(iter1);
     using const_iterator = decltype(std::as_const(jv).begin());
     static_assert(!std::is_same_v<iterator, const_iterator>);
     const_iterator iter2 = iter1;
@@ -53,7 +59,7 @@ constexpr bool test() {
     ConstIncompatibleInner inners[2] = {buffer[0], buffer[1]};
     ConstCompatibleOuter<ConstIncompatibleInner> outer{inners};
     std::ranges::join_view jv(outer);
-    using iterator = decltype(jv.begin());
+    using iterator       = decltype(jv.begin());
     using const_iterator = decltype(std::as_const(jv).begin());
     static_assert(!std::is_same_v<iterator, const_iterator>);
 
@@ -66,7 +72,7 @@ constexpr bool test() {
     ConstCompatibleInner inners[2] = {buffer[0], buffer[1]};
     ConstIncompatibleOuter<ConstCompatibleInner> outer{inners};
     std::ranges::join_view jv(outer);
-    using iterator = decltype(jv.begin());
+    using iterator       = decltype(jv.begin());
     using const_iterator = decltype(std::as_const(jv).begin());
     static_assert(!std::is_same_v<iterator, const_iterator>);
 
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/decrement.pass.cpp
index 29720d93ba..149f39bcb0 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/decrement.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/decrement.pass.cpp
@@ -107,7 +107,7 @@ constexpr bool test() {
   {
     // basic type checking
     std::ranges::join_view jv(buffer);
-    auto iter1 = std::ranges::next(jv.begin(), 4);
+    auto iter1     = std::ranges::next(jv.begin(), 4);
     using iterator = decltype(iter1);
 
     decltype(auto) iter2 = --iter1;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/eq.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/eq.pass.cpp
index 5c831f33e6..593268e3a6 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/eq.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/eq.pass.cpp
@@ -54,7 +54,7 @@ constexpr bool test() {
 
   {
     // !equality_comparable<iterator_t<range_reference_t<Base>>>;
-    using Inner = BufferView<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>;
+    using Inner     = BufferView<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>;
     Inner inners[1] = {buffer[0]};
     std::ranges::join_view jv{inners};
     auto iter = jv.begin();
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/increment.pass.cpp
index dada91462a..05241e63f1 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/increment.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/increment.pass.cpp
@@ -23,8 +23,8 @@
 constexpr bool test() {
   // This way if we read past end we'll catch the error.
   int buffer1[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
-  int dummy = 42;
-  (void) dummy;
+  int dummy         = 42;
+  (void)dummy;
   int buffer2[2][4] = {{9, 10, 11, 12}, {13, 14, 15, 16}};
 
   // operator++(int);
@@ -37,7 +37,7 @@ constexpr bool test() {
   }
 
   {
-    using IntView = ValueView<int>;
+    using IntView       = ValueView<int>;
     IntView children[4] = {IntView(buffer1[0]), IntView(buffer1[1]), IntView(buffer2[0]), IntView(buffer2[1])};
     std::ranges::join_view jv(ValueView<IntView>{children});
     auto iter = jv.begin();
@@ -67,20 +67,30 @@ constexpr bool test() {
 
   // Has some empty children.
   {
-    CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 1), CopyableChild(buffer2[1], 0)};
-    auto jv = std::ranges::join_view(ParentView(children));
+    CopyableChild children[4] = {
+        CopyableChild(buffer1[0], 4),
+        CopyableChild(buffer1[1], 0),
+        CopyableChild(buffer2[0], 1),
+        CopyableChild(buffer2[1], 0)};
+    auto jv   = std::ranges::join_view(ParentView(children));
     auto iter = jv.begin();
-    assert(*iter == 1); iter++;
-    assert(*iter == 2); iter++;
-    assert(*iter == 3); iter++;
-    assert(*iter == 4); iter++;
-    assert(*iter == 9); iter++;
+    assert(*iter == 1);
+    iter++;
+    assert(*iter == 2);
+    iter++;
+    assert(*iter == 3);
+    iter++;
+    assert(*iter == 4);
+    iter++;
+    assert(*iter == 9);
+    iter++;
     assert(iter == jv.end());
   }
 
   // Parent is empty.
   {
-    CopyableChild children[4] = {CopyableChild(buffer1[0]), CopyableChild(buffer1[1]), CopyableChild(buffer2[0]), CopyableChild(buffer2[1])};
+    CopyableChild children[4] = {
+        CopyableChild(buffer1[0]), CopyableChild(buffer1[1]), CopyableChild(buffer2[0]), CopyableChild(buffer2[1])};
     std::ranges::join_view jv(ParentView(children, 0));
     assert(jv.begin() == jv.end());
   }
@@ -90,10 +100,14 @@ constexpr bool test() {
     CopyableChild children[1] = {CopyableChild(buffer1[0])};
     std::ranges::join_view jv(ParentView(children, 1));
     auto iter = jv.begin();
-    assert(*iter == 1); iter++;
-    assert(*iter == 2); iter++;
-    assert(*iter == 3); iter++;
-    assert(*iter == 4); iter++;
+    assert(*iter == 1);
+    iter++;
+    assert(*iter == 2);
+    iter++;
+    assert(*iter == 3);
+    iter++;
+    assert(*iter == 4);
+    iter++;
     assert(iter == jv.end());
   }
 
@@ -102,7 +116,8 @@ constexpr bool test() {
     CopyableChild children[1] = {CopyableChild(buffer1[0], 1)};
     std::ranges::join_view jv(ParentView(children, 1));
     auto iter = jv.begin();
-    assert(*iter == 1); iter++;
+    assert(*iter == 1);
+    iter++;
     assert(iter == jv.end());
   }
 
@@ -115,27 +130,43 @@ constexpr bool test() {
 
   // Has all empty children.
   {
-    CopyableChild children[4] = {CopyableChild(buffer1[0], 0), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)};
+    CopyableChild children[4] = {
+        CopyableChild(buffer1[0], 0),
+        CopyableChild(buffer1[1], 0),
+        CopyableChild(buffer2[0], 0),
+        CopyableChild(buffer2[1], 0)};
     auto jv = std::ranges::join_view(ParentView(children));
     assert(jv.begin() == jv.end());
   }
 
   // First child is empty, others are not.
   {
-    CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)};
-    auto jv = std::ranges::join_view(ParentView(children));
+    CopyableChild children[4] = {
+        CopyableChild(buffer1[0], 4),
+        CopyableChild(buffer1[1], 0),
+        CopyableChild(buffer2[0], 0),
+        CopyableChild(buffer2[1], 0)};
+    auto jv   = std::ranges::join_view(ParentView(children));
     auto iter = jv.begin();
-    assert(*iter == 1); iter++;
-    assert(*iter == 2); iter++;
-    assert(*iter == 3); iter++;
-    assert(*iter == 4); iter++;
+    assert(*iter == 1);
+    iter++;
+    assert(*iter == 2);
+    iter++;
+    assert(*iter == 3);
+    iter++;
+    assert(*iter == 4);
+    iter++;
     assert(iter == jv.end());
   }
 
   // Last child is empty, others are not.
   {
-    CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 4), CopyableChild(buffer2[0], 4), CopyableChild(buffer2[1], 0)};
-    auto jv = std::ranges::join_view(ParentView(children));
+    CopyableChild children[4] = {
+        CopyableChild(buffer1[0], 4),
+        CopyableChild(buffer1[1], 4),
+        CopyableChild(buffer2[0], 4),
+        CopyableChild(buffer2[1], 0)};
+    auto jv   = std::ranges::join_view(ParentView(children));
     auto iter = jv.begin();
     for (int i = 1; i < 13; ++i) {
       assert(*iter == i);
@@ -153,7 +184,7 @@ constexpr bool test() {
   }
 
   {
-    using IntView = ValueView<int>;
+    using IntView       = ValueView<int>;
     IntView children[4] = {IntView(buffer1[0]), IntView(buffer1[1]), IntView(buffer2[0]), IntView(buffer2[1])};
     std::ranges::join_view jv(ValueView<IntView>{children});
     auto iter = jv.begin();
@@ -167,7 +198,7 @@ constexpr bool test() {
   {
     // check return value
     std::ranges::join_view jv(buffer1);
-    auto iter = jv.begin();
+    auto iter      = jv.begin();
     using iterator = decltype(iter);
 
     decltype(auto) iter2 = ++iter;
@@ -190,7 +221,7 @@ constexpr bool test() {
   {
     // !forward_range<Base>
     BufferView<int*> inners[2] = {buffer1[0], buffer1[1]};
-    using Outer = SimpleInputCommonOuter<BufferView<int*>>;
+    using Outer                = SimpleInputCommonOuter<BufferView<int*>>;
     std::ranges::join_view jv{Outer(inners)};
     auto iter = jv.begin();
     static_assert(std::is_void_v<decltype(iter++)>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/member_types.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/member_types.compile.pass.cpp
index b9b9d73d77..6cee608570 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/member_types.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/member_types.compile.pass.cpp
@@ -16,13 +16,13 @@
 #include "test_macros.h"
 #include "../types.h"
 
-template<class T>
+template <class T>
 struct ForwardView : std::ranges::view_base {
   forward_iterator<T*> begin() const;
   sentinel_wrapper<forward_iterator<T*>> end() const;
 };
 
-template<class T>
+template <class T>
 struct InputView : std::ranges::view_base {
   cpp17_input_iterator<T*> begin() const;
   sentinel_wrapper<cpp17_input_iterator<T*>> end() const;
@@ -31,8 +31,8 @@ struct InputView : std::ranges::view_base {
 template <class T, class V>
 struct diff_type_iter {
   using iterator_category = std::input_iterator_tag;
-  using value_type = V;
-  using difference_type = T;
+  using value_type        = V;
+  using difference_type   = T;
 
   V& operator*() const;
   diff_type_iter& operator++();
@@ -46,7 +46,7 @@ struct DiffTypeRange : std::ranges::view_base {
   diff_type_iter<T, V> end() const;
 };
 
-template<class T>
+template <class T>
 concept HasIterCategory = requires { typename T::iterator_category; };
 
 void test() {
@@ -96,20 +96,20 @@ void test() {
   {
     // !ref-is-glvalue
     using Outer = InnerRValue<BidiCommonOuter<BidiCommonInner>>;
-    using Iter = std::ranges::iterator_t<std::ranges::join_view<Outer>>;
+    using Iter  = std::ranges::iterator_t<std::ranges::join_view<Outer>>;
     static_assert(!HasIterCategory<Iter>);
     static_assert(std::is_same_v<Iter::iterator_concept, std::input_iterator_tag>);
   }
 
   {
     // value_type == inner's value_type
-    using Inner = IterMoveSwapAwareView;
-    using InnerValue = std::ranges::range_value_t<Inner>;
+    using Inner          = IterMoveSwapAwareView;
+    using InnerValue     = std::ranges::range_value_t<Inner>;
     using InnerReference = std::ranges::range_reference_t<Inner>;
     static_assert(!std::is_same_v<InnerValue, std::remove_cvref<InnerReference>>);
 
     using Outer = BidiCommonOuter<Inner>;
-    using Iter = std::ranges::iterator_t<std::ranges::join_view<Outer>>;
+    using Iter  = std::ranges::iterator_t<std::ranges::join_view<Outer>>;
     static_assert(std::is_same_v<InnerValue, std::pair<int, int>>);
     static_assert(std::is_same_v<Iter::value_type, std::pair<int, int>>);
   }
@@ -118,7 +118,7 @@ void test() {
     // difference_type
     using Inner = DiffTypeRange<std::intptr_t>;
     using Outer = DiffTypeRange<std::ptrdiff_t, Inner>;
-    using Iter = std::ranges::iterator_t<std::ranges::join_view<Outer>>;
+    using Iter  = std::ranges::iterator_t<std::ranges::join_view<Outer>>;
     static_assert(std::is_same_v<Iter::difference_type, std::common_type_t<std::intptr_t, std::ptrdiff_t>>);
   }
 }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/star.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/star.pass.cpp
index 73457b826d..9e0997144d 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/star.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.iterator/star.pass.cpp
@@ -34,8 +34,8 @@ constexpr bool test() {
   }
   {
     ChildView children[4] = {ChildView(buffer[0]), ChildView(buffer[1]), ChildView(buffer[2]), ChildView(buffer[3])};
-    auto jv = std::ranges::join_view(ParentView(children));
-    auto iter = jv.begin();
+    auto jv               = std::ranges::join_view(ParentView(children));
+    auto iter             = jv.begin();
     for (int i = 1; i < 17; ++i) {
       assert(*iter == i);
       ++iter;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.default.pass.cpp
index 42fcc733e1..2d63cf7605 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.default.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.default.pass.cpp
@@ -18,7 +18,7 @@
 
 constexpr bool test() {
   std::ranges::sentinel_t<std::ranges::join_view<CopyableParent>> sent;
-  (void) sent;
+  (void)sent;
 
   return true;
 }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.other.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.other.pass.cpp
index 5ef3e7416e..032c1ec2c3 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.other.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.other.pass.cpp
@@ -34,7 +34,7 @@ struct convertible_sentinel_wrapper {
 struct ConstConvertibleView : BufferView<BufferView<int*>*> {
   using BufferView<BufferView<int*>*>::BufferView;
 
-  using sentinel = convertible_sentinel_wrapper<BufferView<int*>*>;
+  using sentinel       = convertible_sentinel_wrapper<BufferView<int*>*>;
   using const_sentinel = convertible_sentinel_wrapper<const BufferView<int*>*>;
 
   constexpr BufferView<int*>* begin() { return data_; }
@@ -53,7 +53,7 @@ constexpr bool test() {
     BufferView<int*> inners[] = {buffer[0], buffer[1], buffer[2]};
     ConstConvertibleView outer(inners);
     std::ranges::join_view jv(outer);
-    auto sent1 = jv.end();
+    auto sent1                                        = jv.end();
     std::ranges::sentinel_t<const decltype(jv)> sent2 = sent1;
     assert(std::as_const(jv).begin() != sent2);
     assert(std::ranges::next(std::as_const(jv).begin(), 12) == sent2);
@@ -67,10 +67,12 @@ constexpr bool test() {
     // const sentinel cannot be created from the underlying non-const sentinel
     using Inner = BufferView<int*>;
     using ConstInconvertibleOuter =
-        BufferView<forward_iterator<const Inner*>, sentinel_wrapper<forward_iterator<const Inner*>>,
-                   bidirectional_iterator<Inner*>, sentinel_wrapper<bidirectional_iterator<Inner*>>>;
-    using JoinView = std::ranges::join_view<ConstInconvertibleOuter>;
-    using sentinel = std::ranges::sentinel_t<JoinView>;
+        BufferView<forward_iterator<const Inner*>,
+                   sentinel_wrapper<forward_iterator<const Inner*>>,
+                   bidirectional_iterator<Inner*>,
+                   sentinel_wrapper<bidirectional_iterator<Inner*>>>;
+    using JoinView       = std::ranges::join_view<ConstInconvertibleOuter>;
+    using sentinel       = std::ranges::sentinel_t<JoinView>;
     using const_sentinel = std::ranges::sentinel_t<const JoinView>;
     static_assert(!std::constructible_from<sentinel, const_sentinel>);
     static_assert(!std::constructible_from<const_sentinel, sentinel>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp
index 1ac6827733..26f68a9c5c 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp
@@ -19,7 +19,8 @@
 constexpr bool test() {
   int buffer[4][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
 
-  CopyableChild children[4] = {CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]), CopyableChild(buffer[3])};
+  CopyableChild children[4] = {
+      CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]), CopyableChild(buffer[3])};
   CopyableParent parent{children};
   std::ranges::join_view jv(parent);
   std::ranges::sentinel_t<decltype(jv)> sent(jv);
@@ -35,7 +36,7 @@ int main(int, char**) {
   {
     // Test explicitness.
     using Parent = std::ranges::join_view<ParentView<ChildView>>;
-    static_assert( std::is_constructible_v<std::ranges::sentinel_t<Parent>, Parent&>);
+    static_assert(std::is_constructible_v<std::ranges::sentinel_t<Parent>, Parent&>);
     static_assert(!std::is_convertible_v<std::ranges::sentinel_t<Parent>, Parent&>);
   }
 
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/eq.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/eq.pass.cpp
index bc7d4bec94..97fdef5a8e 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/eq.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/eq.pass.cpp
@@ -21,14 +21,13 @@
 #include "../types.h"
 
 template <class Iter, class Sent>
-concept EqualityComparable = std::invocable<std::equal_to<>, const Iter&, const Sent&> ;
+concept EqualityComparable = std::invocable<std::equal_to<>, const Iter&, const Sent&>;
 
-using Iterator = random_access_iterator<BufferView<int*>*>;
+using Iterator      = random_access_iterator<BufferView<int*>*>;
 using ConstIterator = random_access_iterator<const BufferView<int*>*>;
 
 template <bool Const>
 struct ConstComparableSentinel {
-
   using Iter = std::conditional_t<Const, ConstIterator, Iterator>;
   Iter iter_;
 
@@ -78,10 +77,10 @@ constexpr bool test() {
 
   // test iterator<true> == sentinel<true>
   {
-    CopyableChild children[4] = {CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]),
-                                 CopyableChild(buffer[3])};
-    using ParentT             = std::remove_all_extents_t<decltype(children)>;
-    const auto jv             = std::ranges::join_view(ForwardParentView<ParentT>(children));
+    CopyableChild children[4] = {
+        CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]), CopyableChild(buffer[3])};
+    using ParentT = std::remove_all_extents_t<decltype(children)>;
+    const auto jv = std::ranges::join_view(ForwardParentView<ParentT>(children));
     assert(jv.end() == std::ranges::next(jv.begin(), 16));
   }
 
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/types.h b/libcxx/test/std/ranges/range.adaptors/range.join/types.h
index c1378dc114..9f64b8cc20 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/types.h
@@ -24,20 +24,20 @@ inline int globalBuffer[4][4] = {
     {13, 14, 15, 16},
 };
 
-template <template<class...> class Iter>
+template <template <class...> class Iter>
 struct ChildViewBase : std::ranges::view_base {
   int* ptr_;
 
-  using iterator = Iter<int*>;
+  using iterator       = Iter<int*>;
   using const_iterator = Iter<const int*>;
-  using sentinel = sentinel_wrapper<iterator>;
+  using sentinel       = sentinel_wrapper<iterator>;
   using const_sentinel = sentinel_wrapper<const_iterator>;
 
   constexpr ChildViewBase(int* ptr = globalBuffer[0]) : ptr_(ptr) {}
-  ChildViewBase(const ChildViewBase&) = delete;
-  ChildViewBase(ChildViewBase&&) = default;
+  ChildViewBase(const ChildViewBase&)            = delete;
+  ChildViewBase(ChildViewBase&&)                 = default;
   ChildViewBase& operator=(const ChildViewBase&) = delete;
-  ChildViewBase& operator=(ChildViewBase&&) = default;
+  ChildViewBase& operator=(ChildViewBase&&)      = default;
 
   constexpr iterator begin() { return iterator(ptr_); }
   constexpr const_iterator begin() const { return const_iterator(ptr_); }
@@ -53,24 +53,24 @@ inline ChildView globalChildren[4] = {
     ChildView(globalBuffer[3]),
 };
 
-template <class T, template<class...> class Iter = cpp17_input_iterator>
+template <class T, template <class...> class Iter = cpp17_input_iterator>
 struct ParentView : std::ranges::view_base {
   T* ptr_;
   unsigned size_;
 
-  using iterator = Iter<T*>;
+  using iterator       = Iter<T*>;
   using const_iterator = Iter<const T*>;
-  using sentinel = sentinel_wrapper<iterator>;
+  using sentinel       = sentinel_wrapper<iterator>;
   using const_sentinel = sentinel_wrapper<const_iterator>;
 
   constexpr ParentView(T* ptr, unsigned size = 4) : ptr_(ptr), size_(size) {}
   constexpr ParentView(ChildView* ptr = globalChildren, unsigned size = 4)
     requires std::same_as<ChildView, T>
-  : ptr_(ptr), size_(size) {}
-  ParentView(const ParentView&) = delete;
-  ParentView(ParentView&&) = default;
+      : ptr_(ptr), size_(size) {}
+  ParentView(const ParentView&)            = delete;
+  ParentView(ParentView&&)                 = default;
   ParentView& operator=(const ParentView&) = delete;
-  ParentView& operator=(ParentView&&) = default;
+  ParentView& operator=(ParentView&&)      = default;
 
   constexpr iterator begin() { return iterator(ptr_); }
   constexpr const_iterator begin() const { return const_iterator(ptr_); }
@@ -81,16 +81,16 @@ struct ParentView : std::ranges::view_base {
 template <class T>
 ParentView(T*) -> ParentView<T>;
 
-template<class T>
+template <class T>
 using ForwardParentView = ParentView<T, forward_iterator>;
 
 struct CopyableChild : std::ranges::view_base {
   int* ptr_;
   unsigned size_;
 
-  using iterator = cpp17_input_iterator<int*>;
+  using iterator       = cpp17_input_iterator<int*>;
   using const_iterator = cpp17_input_iterator<const int*>;
-  using sentinel = sentinel_wrapper<iterator>;
+  using sentinel       = sentinel_wrapper<iterator>;
   using const_sentinel = sentinel_wrapper<const_iterator>;
 
   constexpr CopyableChild(int* ptr = globalBuffer[0], unsigned size = 4) : ptr_(ptr), size_(size) {}
@@ -101,13 +101,13 @@ struct CopyableChild : std::ranges::view_base {
   constexpr const_sentinel end() const { return const_sentinel(const_iterator(ptr_ + size_)); }
 };
 
-template<template<class...> class Iter>
+template <template <class...> class Iter>
 struct CopyableParentTemplate : std::ranges::view_base {
   CopyableChild* ptr_;
 
-  using iterator = Iter<CopyableChild*>;
+  using iterator       = Iter<CopyableChild*>;
   using const_iterator = Iter<const CopyableChild*>;
-  using sentinel = sentinel_wrapper<iterator>;
+  using sentinel       = sentinel_wrapper<iterator>;
   using const_sentinel = sentinel_wrapper<const_iterator>;
 
   constexpr CopyableParentTemplate(CopyableChild* ptr) : ptr_(ptr) {}
@@ -118,7 +118,7 @@ struct CopyableParentTemplate : std::ranges::view_base {
   constexpr const_sentinel end() const { return const_sentinel(const_iterator(ptr_ + 4)); }
 };
 
-using CopyableParent = CopyableParentTemplate<cpp17_input_iterator>;
+using CopyableParent        = CopyableParentTemplate<cpp17_input_iterator>;
 using ForwardCopyableParent = CopyableParentTemplate<forward_iterator>;
 
 struct Box {
@@ -132,7 +132,7 @@ struct InputValueIter {
   typedef int difference_type;
   typedef T reference;
 
-  T* ptr_ = nullptr;
+  T* ptr_                    = nullptr;
   constexpr InputValueIter() = default;
   constexpr InputValueIter(T* ptr) : ptr_(ptr) {}
 
@@ -159,12 +159,12 @@ struct ValueView : std::ranges::view_base {
   constexpr ValueView(ValueView&& other) : ptr_(other.ptr_) { other.ptr_.ptr_ = nullptr; }
 
   constexpr ValueView& operator=(ValueView&& other) {
-    ptr_ = other.ptr_;
+    ptr_       = other.ptr_;
     other.ptr_ = InputValueIter<T>(nullptr);
     return *this;
   }
 
-  ValueView(const ValueView&) = delete;
+  ValueView(const ValueView&)            = delete;
   ValueView& operator=(const ValueView&) = delete;
 
   constexpr InputValueIter<T> begin() const { return ptr_; }
@@ -173,7 +173,6 @@ struct ValueView : std::ranges::view_base {
 
 template <class Iter, class Sent = Iter, class NonConstIter = Iter, class NonConstSent = Sent>
 struct BufferView : std::ranges::view_base {
-
   using T = std::iter_value_t<Iter>;
   T* data_;
   std::size_t size_;
@@ -183,13 +182,15 @@ struct BufferView : std::ranges::view_base {
   constexpr BufferView(T* p, std::size_t s) : data_(p), size_(s) {}
 
   constexpr NonConstIter begin()
-    requires(!std::is_same_v<Iter, NonConstIter>) {
+    requires(!std::is_same_v<Iter, NonConstIter>)
+  {
     return NonConstIter(this->data_);
   }
   constexpr Iter begin() const { return Iter(this->data_); }
 
   constexpr NonConstSent end()
-    requires(!std::is_same_v<Sent, NonConstSent>) {
+    requires(!std::is_same_v<Sent, NonConstSent>)
+  {
     if constexpr (std::is_same_v<NonConstIter, NonConstSent>) {
       return NonConstIter(this->data_ + this->size_);
     } else {
@@ -242,8 +243,11 @@ static_assert(std::ranges::common_range<SimpleInputCommonOuter<>>);
 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleInputCommonOuter<>>);
 
 template <class Inner = BufferView<int*>>
-using NonSimpleInputCommonOuter = BufferView<common_input_iterator<const Inner*>, common_input_iterator<const Inner*>,
-                                             common_input_iterator< Inner*>, common_input_iterator< Inner*>>;
+using NonSimpleInputCommonOuter =
+    BufferView<common_input_iterator<const Inner*>,
+               common_input_iterator<const Inner*>,
+               common_input_iterator< Inner*>,
+               common_input_iterator< Inner*>>;
 static_assert(!std::ranges::forward_range<NonSimpleInputCommonOuter<>>);
 static_assert(!std::ranges::bidirectional_range<NonSimpleInputCommonOuter<>>);
 static_assert(std::ranges::common_range<NonSimpleInputCommonOuter<>>);
@@ -257,8 +261,11 @@ static_assert(std::ranges::common_range<SimpleForwardCommonOuter<>>);
 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleForwardCommonOuter<>>);
 
 template <class Inner = BufferView<int*>>
-using NonSimpleForwardCommonOuter = BufferView<forward_iterator<const Inner*>, forward_iterator<const Inner*>,
-                                               forward_iterator<Inner*>, forward_iterator<Inner*>>;
+using NonSimpleForwardCommonOuter =
+    BufferView<forward_iterator<const Inner*>,
+               forward_iterator<const Inner*>,
+               forward_iterator<Inner*>,
+               forward_iterator<Inner*>>;
 static_assert(std::ranges::forward_range<NonSimpleForwardCommonOuter<>>);
 static_assert(!std::ranges::bidirectional_range<NonSimpleForwardCommonOuter<>>);
 static_assert(std::ranges::common_range<NonSimpleForwardCommonOuter<>>);
@@ -273,8 +280,10 @@ LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleForwardNonCommonOuter<>>);
 
 template <class Inner = BufferView<int*>>
 using NonSimpleForwardNonCommonOuter =
-    BufferView<forward_iterator<const Inner*>, sentinel_wrapper<forward_iterator<const Inner*>>,
-               forward_iterator<Inner*>, sentinel_wrapper<forward_iterator<Inner*>>>;
+    BufferView<forward_iterator<const Inner*>,
+               sentinel_wrapper<forward_iterator<const Inner*>>,
+               forward_iterator<Inner*>,
+               sentinel_wrapper<forward_iterator<Inner*>>>;
 static_assert(std::ranges::forward_range<NonSimpleForwardNonCommonOuter<>>);
 static_assert(!std::ranges::bidirectional_range<NonSimpleForwardNonCommonOuter<>>);
 static_assert(!std::ranges::common_range<NonSimpleForwardNonCommonOuter<>>);
@@ -291,11 +300,13 @@ template <class It>
 struct copying_iterator {
   It it_ = It();
 
-  using value_type = typename std::iterator_traits<It>::value_type;
+  using value_type      = typename std::iterator_traits<It>::value_type;
   using difference_type = typename std::iterator_traits<It>::difference_type;
-  using pointer = typename std::iterator_traits<It>::pointer;
+  using pointer         = typename std::iterator_traits<It>::pointer;
 
-  copying_iterator() requires std::default_initializable<It> = default;
+  copying_iterator()
+    requires std::default_initializable<It>
+  = default;
   constexpr copying_iterator(It it) : it_(std::move(it)) {}
 
   // makes a copy of underlying operator* to create a PRValue
@@ -306,17 +317,20 @@ struct copying_iterator {
     return *this;
   }
   constexpr copying_iterator& operator--()
-    requires std::bidirectional_iterator<It> {
+    requires std::bidirectional_iterator<It>
+  {
     --it_;
     return *this;
   }
   constexpr copying_iterator operator++(int)
-    requires std::forward_iterator<It> {
+    requires std::forward_iterator<It>
+  {
     return copying_iterator(it_++);
   }
   constexpr void operator++(int) { return it_++; }
   constexpr copying_iterator operator--(int)
-    requires std::bidirectional_iterator<It> {
+    requires std::bidirectional_iterator<It>
+  {
     return copying_iterator(it_--);
   }
 
@@ -325,10 +339,9 @@ struct copying_iterator {
 
 template <class Outer>
 struct InnerRValue : Outer {
-
-  using iterator = copying_iterator<std::ranges::iterator_t<Outer>>;
+  using iterator       = copying_iterator<std::ranges::iterator_t<Outer>>;
   using const_iterator = copying_iterator<std::ranges::iterator_t<const Outer>>;
-  using sentinel = copying_iterator<std::ranges::sentinel_t<Outer>>;
+  using sentinel       = copying_iterator<std::ranges::sentinel_t<Outer>>;
   using const_sentinel = copying_iterator<std::ranges::sentinel_t<const Outer>>;
 
   using Outer::Outer;
@@ -336,13 +349,15 @@ struct InnerRValue : Outer {
 
   constexpr iterator begin() { return Outer::begin(); }
   constexpr const_iterator begin() const
-    requires std::ranges::range<const Outer> {
+    requires std::ranges::range<const Outer>
+  {
     return Outer::begin();
   }
 
   constexpr auto end() { return iterator{Outer::end()}; }
   constexpr auto end() const
-    requires std::ranges::range<const Outer> {
+    requires std::ranges::range<const Outer>
+  {
     return const_iterator{Outer::end()};
   }
 };
@@ -353,19 +368,18 @@ LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<InnerRValue<SimpleForwardCommonO
 static_assert(!std::is_lvalue_reference_v<std::ranges::range_reference_t<InnerRValue<SimpleForwardCommonOuter<>>>>);
 
 struct move_swap_aware_iter {
-
   // This is a proxy-like iterator where `reference` is a prvalue, and
   // `reference` and `value_type` are distinct types (similar to `zip_view::iterator`).
-  using value_type = std::pair<int, int>;
-  using reference = std::pair<int&, int&>;
+  using value_type       = std::pair<int, int>;
+  using reference        = std::pair<int&, int&>;
   using rvalue_reference = std::pair<int&&, int&&>;
 
-  using difference_type = std::intptr_t;
+  using difference_type  = std::intptr_t;
   using iterator_concept = std::input_iterator_tag;
 
   int* iter_move_called = nullptr;
   int* iter_swap_called = nullptr;
-  int* i_ = nullptr;
+  int* i_               = nullptr;
 
   constexpr move_swap_aware_iter& operator++() {
     ++i_;

@ldionne ldionne assigned ldionne and unassigned var-const Nov 29, 2023
Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

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

Thanks! This is almost good to go, but I am still seeing two review comments I had left which I don't think have been addressed.

//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer if we did UNSUPPORTED: c++03, c++11 so we can use C++14 constexpr. It's nice that you try to make it work in C++11, but TBH I think we should prioritize readability for these tests -- at the end of the day __as_lvalue is also not going to be used in C++11 mode so I'm not too shocked about not having coverage for it in that mode.

Then you can use multiple statements in the function below.

}
}

_LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent& __parent, _Outer __outer)
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this has been addressed (unless I missed it)?

}

{
// LWG3569 Inner iterator not default_initializable
Copy link
Member

Choose a reason for hiding this comment

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

Not addressed (unless I missed)?

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

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

LGTM, we can merge once CI is green. Thanks!

@JMazurkiewicz
Copy link
Contributor Author

Ping @ldionne, CI is green (except for code formatting).

@ldionne
Copy link
Member

ldionne commented Dec 12, 2023

Thanks for the ping (and the patch!)

@ldionne ldionne merged commit 6a66467 into llvm:main Dec 12, 2023
42 of 43 checks passed
@JMazurkiewicz JMazurkiewicz deleted the libcxx/ranges/stashing branch December 12, 2023 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants