File: noexcept.cpp

package info (click to toggle)
tl-optional 1.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 344 kB
  • sloc: cpp: 2,570; sh: 26; makefile: 8
file content (100 lines) | stat: -rw-r--r-- 2,975 bytes parent folder | download
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <catch2/catch_all.hpp>
#include <tl/optional.hpp>

TEST_CASE("Noexcept", "[noexcept]") {
  tl::optional<int> o1{4};
  tl::optional<int> o2{42};

  SECTION("comparison with nullopt") {
    REQUIRE(noexcept(o1 == tl::nullopt));
    REQUIRE(noexcept(tl::nullopt == o1));
    REQUIRE(noexcept(o1 != tl::nullopt));
    REQUIRE(noexcept(tl::nullopt != o1));
    REQUIRE(noexcept(o1 < tl::nullopt));
    REQUIRE(noexcept(tl::nullopt < o1));
    REQUIRE(noexcept(o1 <= tl::nullopt));
    REQUIRE(noexcept(tl::nullopt <= o1));
    REQUIRE(noexcept(o1 > tl::nullopt));
    REQUIRE(noexcept(tl::nullopt > o1));
    REQUIRE(noexcept(o1 >= tl::nullopt));
    REQUIRE(noexcept(tl::nullopt >= o1));
  }

  SECTION("swap") {
      //TODO see why this fails
#if !defined(_MSC_VER) || _MSC_VER > 1900
    REQUIRE(noexcept(swap(o1, o2)) == noexcept(o1.swap(o2)));

    struct nothrow_swappable {
      nothrow_swappable &swap(const nothrow_swappable &) noexcept {
        return *this;
      }
    };

    struct throw_swappable {
      throw_swappable() = default;
      throw_swappable(const throw_swappable &) {}
      throw_swappable(throw_swappable &&) {}
      throw_swappable &swap(const throw_swappable &) { return *this; }
    };

    tl::optional<nothrow_swappable> ont;
    tl::optional<throw_swappable> ot;

    REQUIRE(noexcept(ont.swap(ont)));
    REQUIRE(!noexcept(ot.swap(ot)));
    #endif
  }

  SECTION("constructors") {
      //TODO see why this fails
#if !defined(_MSC_VER) || _MSC_VER > 1900
    REQUIRE(noexcept(tl::optional<int>{}));
    REQUIRE(noexcept(tl::optional<int>{tl::nullopt}));

    struct nothrow_move {
      nothrow_move(nothrow_move &&) noexcept = default;
    };

    struct throw_move {
      throw_move(throw_move &&){};
    };

    using nothrow_opt = tl::optional<nothrow_move>;
    using throw_opt = tl::optional<throw_move>;

    REQUIRE(std::is_nothrow_move_constructible<nothrow_opt>::value);
    REQUIRE(!std::is_nothrow_move_constructible<throw_opt>::value);
#endif
  }

  SECTION("assignment") {
    REQUIRE(noexcept(o1 = tl::nullopt));

    struct nothrow_move_assign {
      nothrow_move_assign() = default;
      nothrow_move_assign(nothrow_move_assign &&) noexcept = default;
      nothrow_move_assign &operator=(const nothrow_move_assign &) = default;
    };

    struct throw_move_assign {
      throw_move_assign() = default;
      throw_move_assign(throw_move_assign &&){};
      throw_move_assign &operator=(const throw_move_assign &) { return *this; }
    };

    using nothrow_opt = tl::optional<nothrow_move_assign>;
    using throw_opt = tl::optional<throw_move_assign>;

    REQUIRE(
        noexcept(std::declval<nothrow_opt>() = std::declval<nothrow_opt>()));
    REQUIRE(!noexcept(std::declval<throw_opt>() = std::declval<throw_opt>()));
  }

  SECTION("observers") {
    REQUIRE(noexcept(static_cast<bool>(o1)));
    REQUIRE(noexcept(o1.has_value()));
  }

  SECTION("modifiers") { REQUIRE(noexcept(o1.reset())); }
}