summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/24_iterators/common_iterator/100823.cc
blob: b42dd087ab2dbe99c0ff97761078a06a12988d7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// { dg-options "-std=gnu++20 -D_GLIBCXX_ASSERTIONS" }
// { dg-do run { target c++20 } }
#include <iterator>
#include <testsuite_iterators.h>
#include <testsuite_hooks.h>

void
test_triviality()
{
  using I = std::common_iterator<int*, const int*>;

  // Cannot be trivial, because it has to initialize members.
  static_assert( ! std::is_trivially_default_constructible_v<I> );

  static_assert( std::is_trivially_destructible_v<I> );
  static_assert( std::is_trivially_copy_constructible_v<I> );
  static_assert( std::is_trivially_copy_assignable_v<I> );
  static_assert( std::is_trivially_move_constructible_v<I> );
  static_assert( std::is_trivially_move_assignable_v<I> );
}

void
test_valueless_assignment()
{
  int x[1] { };
  __gnu_test::test_forward_range<int> r(x);
  using Iter = decltype(r.begin());
  using Sent = decltype(r.end());

  std::common_iterator<Iter, Sent> i;
  const std::common_iterator<Iter, Sent> j(r.begin());
  try
  {
    struct Bomb
    {
      bool operator==(Iter) const { return true; }
      operator Sent() const { throw 1; }
    };
    std::common_iterator<Iter, Bomb> b{Bomb{}};
    i = b; // Throws, leaving i valueless-by-exception.
    VERIFY(false);
  }
  catch (int)
  {
    std::common_iterator<Iter, Sent> k(i);

    // PR libstdc++/100823
    k = i; // Valid even though both operands are valueless.

    i = j; // No longer valueless.
  }
  VERIFY( i == j );
}

int main()
{
  test_valueless_assignment();
}