xref: /llvm-project/libcxx/test/std/ranges/ranges_robust_against_no_unique_address.pass.cpp (revision 120b0bfbf0bade430fa9b19d78025ccd1d6148d0)
1*120b0bfbSHui //===----------------------------------------------------------------------===//
2*120b0bfbSHui //
3*120b0bfbSHui // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*120b0bfbSHui // See https://llvm.org/LICENSE.txt for license information.
5*120b0bfbSHui // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*120b0bfbSHui //
7*120b0bfbSHui //===----------------------------------------------------------------------===//
8*120b0bfbSHui 
9*120b0bfbSHui // UNSUPPORTED: c++03, c++11, c++14, c++17
10*120b0bfbSHui 
11*120b0bfbSHui // Test that views that use __movable_box do not overwrite overlapping subobjects.
12*120b0bfbSHui // https://github.com/llvm/llvm-project/issues/70506
13*120b0bfbSHui 
14*120b0bfbSHui #include <cassert>
15*120b0bfbSHui #include <ranges>
16*120b0bfbSHui 
17*120b0bfbSHui #include "test_macros.h"
18*120b0bfbSHui 
19*120b0bfbSHui struct Pred {
20*120b0bfbSHui   alignas(128) bool a{};
21*120b0bfbSHui 
22*120b0bfbSHui   Pred() noexcept            = default;
23*120b0bfbSHui   Pred(const Pred&) noexcept = default;
24*120b0bfbSHui   Pred(Pred&&) noexcept      = default;
25*120b0bfbSHui 
26*120b0bfbSHui   Pred& operator=(const Pred&) = delete;
27*120b0bfbSHui   Pred& operator=(Pred&&)      = delete;
28*120b0bfbSHui 
operator ()Pred29*120b0bfbSHui   constexpr bool operator()(const auto&...) const { return true; }
30*120b0bfbSHui };
31*120b0bfbSHui 
32*120b0bfbSHui struct View : std::ranges::view_base {
beginView33*120b0bfbSHui   constexpr int* begin() const { return nullptr; }
endView34*120b0bfbSHui   constexpr int* end() const { return nullptr; }
35*120b0bfbSHui };
36*120b0bfbSHui 
37*120b0bfbSHui template <class View>
38*120b0bfbSHui struct S {
39*120b0bfbSHui   [[no_unique_address]] View view{};
40*120b0bfbSHui   char c = 42;
41*120b0bfbSHui };
42*120b0bfbSHui 
43*120b0bfbSHui template <class View>
testOne()44*120b0bfbSHui constexpr void testOne() {
45*120b0bfbSHui   S<View> s1;
46*120b0bfbSHui   assert(s1.c == 42);
47*120b0bfbSHui   s1.view = View{};
48*120b0bfbSHui   assert(s1.c == 42);
49*120b0bfbSHui }
50*120b0bfbSHui 
test()51*120b0bfbSHui constexpr bool test() {
52*120b0bfbSHui   testOne<std::ranges::transform_view<View, Pred>>();
53*120b0bfbSHui   testOne<std::ranges::filter_view<View, Pred>>();
54*120b0bfbSHui   testOne<std::ranges::drop_while_view<View, Pred>>();
55*120b0bfbSHui   testOne<std::ranges::take_while_view<View, Pred>>();
56*120b0bfbSHui   testOne<std::ranges::single_view<Pred>>();
57*120b0bfbSHui 
58*120b0bfbSHui #if TEST_STD_VER >= 23
59*120b0bfbSHui   testOne<std::ranges::chunk_by_view<View, Pred>>();
60*120b0bfbSHui   testOne<std::ranges::repeat_view<Pred>>();
61*120b0bfbSHui #endif
62*120b0bfbSHui   return true;
63*120b0bfbSHui }
64*120b0bfbSHui 
main(int,char **)65*120b0bfbSHui int main(int, char**) {
66*120b0bfbSHui   static_assert(test());
67*120b0bfbSHui   test();
68*120b0bfbSHui 
69*120b0bfbSHui   return 0;
70*120b0bfbSHui }
71