mirror of
https://github.com/TartanLlama/expected.git
synced 2025-08-03 02:44:30 +02:00
More testing
This commit is contained in:
@@ -1537,22 +1537,22 @@ public:
|
|||||||
constexpr bool has_value() const noexcept { return this->m_has_val; }
|
constexpr bool has_value() const noexcept { return this->m_has_val; }
|
||||||
constexpr const T &value() const & {
|
constexpr const T &value() const & {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
throw bad_expected_access<E>(err());
|
throw bad_expected_access<E>(err().value());
|
||||||
return val();
|
return val();
|
||||||
}
|
}
|
||||||
TL_EXPECTED_11_CONSTEXPR T &value() & {
|
TL_EXPECTED_11_CONSTEXPR T &value() & {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
throw bad_expected_access<E>(err());
|
throw bad_expected_access<E>(err().value());
|
||||||
return val();
|
return val();
|
||||||
}
|
}
|
||||||
constexpr const T &&value() const && {
|
constexpr const T &&value() const && {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
throw bad_expected_access<E>(err());
|
throw bad_expected_access<E>(err().value());
|
||||||
return std::move(val());
|
return std::move(val());
|
||||||
}
|
}
|
||||||
TL_EXPECTED_11_CONSTEXPR T &&value() && {
|
TL_EXPECTED_11_CONSTEXPR T &&value() && {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
throw bad_expected_access<E>(err());
|
throw bad_expected_access<E>(err().value());
|
||||||
return std::move(val());
|
return std::move(val());
|
||||||
}
|
}
|
||||||
constexpr const E &error() const & { return err().value(); }
|
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);
|
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);
|
tl::expected<int,int> e (tl::in_place, 42);
|
||||||
REQUIRE(e);
|
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