forked from TartanLlama/expected
More testing
This commit is contained in:
@@ -1537,22 +1537,22 @@ public:
|
||||
constexpr bool has_value() const noexcept { return this->m_has_val; }
|
||||
constexpr const T &value() const & {
|
||||
if (!has_value())
|
||||
throw bad_expected_access<E>(err());
|
||||
throw bad_expected_access<E>(err().value());
|
||||
return val();
|
||||
}
|
||||
TL_EXPECTED_11_CONSTEXPR T &value() & {
|
||||
if (!has_value())
|
||||
throw bad_expected_access<E>(err());
|
||||
throw bad_expected_access<E>(err().value());
|
||||
return val();
|
||||
}
|
||||
constexpr const T &&value() const && {
|
||||
if (!has_value())
|
||||
throw bad_expected_access<E>(err());
|
||||
throw bad_expected_access<E>(err().value());
|
||||
return std::move(val());
|
||||
}
|
||||
TL_EXPECTED_11_CONSTEXPR T &&value() && {
|
||||
if (!has_value())
|
||||
throw bad_expected_access<E>(err());
|
||||
throw bad_expected_access<E>(err().value());
|
||||
return std::move(val());
|
||||
}
|
||||
constexpr const E &error() const & { return err().value(); }
|
||||
|
120
tests/bases.cpp
Normal file
120
tests/bases.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "catch.hpp"
|
||||
#include "expected.hpp"
|
||||
|
||||
TEST_CASE("Triviality", "[bases.triviality]") {
|
||||
REQUIRE(std::is_trivially_copy_constructible<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_trivially_copy_assignable<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_trivially_move_constructible<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_trivially_move_assignable<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_trivially_destructible<tl::expected<int,int>>::value);
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&) = default;
|
||||
T(T&&) = default;
|
||||
T& operator=(const T&) = default;
|
||||
T& operator=(T&&) = default;
|
||||
~T() = default;
|
||||
};
|
||||
REQUIRE(std::is_trivially_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_trivially_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_trivially_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_trivially_move_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_trivially_destructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&){}
|
||||
T(T&&) {};
|
||||
T& operator=(const T&) {}
|
||||
T& operator=(T&&) {};
|
||||
~T(){}
|
||||
};
|
||||
REQUIRE(!std::is_trivially_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_trivially_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_trivially_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_trivially_move_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_trivially_destructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Deletion", "[bases.deletion]") {
|
||||
REQUIRE(std::is_copy_constructible<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_copy_assignable<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_move_constructible<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_move_assignable<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_destructible<tl::expected<int,int>>::value);
|
||||
|
||||
{
|
||||
struct T {
|
||||
T()=default;
|
||||
};
|
||||
REQUIRE(std::is_default_constructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(int);
|
||||
};
|
||||
REQUIRE(!std::is_default_constructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&) = default;
|
||||
T(T&&) = default;
|
||||
T& operator=(const T&) = default;
|
||||
T& operator=(T&&) = default;
|
||||
~T() = default;
|
||||
};
|
||||
REQUIRE(std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_move_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_destructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&)=delete;
|
||||
T(T&&)=delete;
|
||||
T& operator=(const T&)=delete;
|
||||
T& operator=(T&&)=delete;
|
||||
};
|
||||
REQUIRE(!std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_move_assignable<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&)=delete;
|
||||
T(T&&)=default;
|
||||
T& operator=(const T&)=delete;
|
||||
T& operator=(T&&)=default;
|
||||
};
|
||||
REQUIRE(!std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_move_assignable<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&)=default;
|
||||
T(T&&)=delete;
|
||||
T& operator=(const T&)=default;
|
||||
T& operator=(T&&)=delete;
|
||||
};
|
||||
REQUIRE(std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||
//TODO see why this fails
|
||||
//REQUIRE(!std::is_move_constructible<tl::expected<T,int>>::value);
|
||||
//REQUIRE(!std::is_move_assignable<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
|
||||
}
|
6
tests/constexpr.cpp
Normal file
6
tests/constexpr.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "catch.hpp"
|
||||
#include "expected.hpp"
|
||||
|
||||
TEST_CASE("Constexpr", "[constexpr]") {
|
||||
//TODO
|
||||
}
|
@@ -18,6 +18,18 @@ TEST_CASE("Constructors", "[constructors]") {
|
||||
REQUIRE(e == 0);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int,int> e = tl::make_unexpected(0);
|
||||
REQUIRE(!e);
|
||||
REQUIRE(e.error() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int,int> e (tl::unexpect, 0);
|
||||
REQUIRE(!e);
|
||||
REQUIRE(e.error() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int,int> e (tl::in_place, 42);
|
||||
REQUIRE(e);
|
||||
|
6
tests/noexcept.cpp
Normal file
6
tests/noexcept.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "catch.hpp"
|
||||
#include "expected.hpp"
|
||||
|
||||
TEST_CASE("Noexcept", "[noexcept]") {
|
||||
//TODO
|
||||
}
|
36
tests/observers.cpp
Normal file
36
tests/observers.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "catch.hpp"
|
||||
#include "expected.hpp"
|
||||
|
||||
struct move_detector {
|
||||
move_detector() = default;
|
||||
move_detector(move_detector &&rhs) { rhs.been_moved = true; }
|
||||
bool been_moved = false;
|
||||
};
|
||||
|
||||
TEST_CASE("Observers", "[observers]") {
|
||||
tl::expected<int,int> o1 = 42;
|
||||
tl::expected<int,int> o2 {tl::unexpect, 0};
|
||||
const tl::expected<int,int> o3 = 42;
|
||||
|
||||
REQUIRE(*o1 == 42);
|
||||
REQUIRE(*o1 == o1.value());
|
||||
REQUIRE(o2.value_or(42) == 42);
|
||||
REQUIRE(o2.error() == 0);
|
||||
REQUIRE(o3.value() == 42);
|
||||
auto success = std::is_same<decltype(o1.value()), int &>::value;
|
||||
REQUIRE(success);
|
||||
success = std::is_same<decltype(o3.value()), const int &>::value;
|
||||
REQUIRE(success);
|
||||
success = std::is_same<decltype(std::move(o1).value()), int &&>::value;
|
||||
REQUIRE(success);
|
||||
|
||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||
success = std::is_same<decltype(std::move(o3).value()), const int &&>::value;
|
||||
REQUIRE(success);
|
||||
#endif
|
||||
|
||||
tl::expected<move_detector,int> o4{tl::in_place};
|
||||
move_detector o5 = std::move(o4).value();
|
||||
REQUIRE(o4->been_moved);
|
||||
REQUIRE(!o5.been_moved);
|
||||
}
|
6
tests/relops.cpp
Normal file
6
tests/relops.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "catch.hpp"
|
||||
#include "expected.hpp"
|
||||
|
||||
TEST_CASE("Relational operators", "[relops]") {
|
||||
//TODO
|
||||
}
|
Reference in New Issue
Block a user