#include "catch.hpp" #include "optional.hpp" TEST_CASE("Noexcept", "[noexcept]") { tl::optional o1{4}; tl::optional 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 ont; tl::optional ot; REQUIRE(noexcept(ont.swap(ont))); REQUIRE(!noexcept(ot.swap(ot))); #endif } SECTION("constructors") { REQUIRE(noexcept(tl::optional{})); REQUIRE(noexcept(tl::optional{tl::nullopt})); struct nothrow_move { nothrow_move(nothrow_move &&) noexcept = default; }; struct throw_move { throw_move(throw_move &&){}; }; using nothrow_opt = tl::optional; using throw_opt = tl::optional; REQUIRE(noexcept(nothrow_opt{std::declval()})); REQUIRE(!noexcept(throw_opt{std::declval()})); } 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 &) {} }; using nothrow_opt = tl::optional; using throw_opt = tl::optional; REQUIRE( noexcept(std::declval() = std::declval())); REQUIRE(!noexcept(std::declval() = std::declval())); } SECTION("observers") { REQUIRE(noexcept(static_cast(o1))); REQUIRE(noexcept(o1.has_value())); } SECTION("modifiers") { REQUIRE(noexcept(o1.reset())); } }