diff --git a/CMakeLists.txt b/CMakeLists.txt index eb9448b..6004a8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,11 @@ target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR}) # Make test executable set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests/noexcept.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/tests/noexcept.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/make_optional.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/in_place.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/relops.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/nullopt.cpp) + add_executable(tests ${TEST_SOURCES}) target_link_libraries(tests Catch) diff --git a/tests/in_place.cpp b/tests/in_place.cpp new file mode 100644 index 0000000..07254e4 --- /dev/null +++ b/tests/in_place.cpp @@ -0,0 +1,41 @@ +#include "catch.hpp" +#include "optional.hpp" + +#include +#include + +struct takes_init_and_variadic { + std::vector v; + std::tuple t; + template + takes_init_and_variadic(std::initializer_list l, Args &&... args) + : v(l), t(std::forward(args)...) {} +}; + +TEST_CASE("In place", "[in_place]") { + tl::optional o1{tl::in_place}; + tl::optional o2(tl::in_place); + REQUIRE(o1); + REQUIRE(o1 == 0); + REQUIRE(o2); + REQUIRE(o2 == 0); + + tl::optional o3(tl::in_place, 42); + REQUIRE(o3 == 42); + + tl::optional> o4(tl::in_place, 0, 1); + REQUIRE(o4); + REQUIRE(std::get<0>(*o4) == 0); + REQUIRE(std::get<1>(*o4) == 1); + + tl::optional> o5(tl::in_place, {0, 1}); + REQUIRE(o5); + REQUIRE((*o5)[0] == 0); + REQUIRE((*o5)[1] == 1); + + tl::optional o6(tl::in_place, {0, 1}, 2, 3); + REQUIRE(o6->v[0] == 0); + REQUIRE(o6->v[1] == 1); + REQUIRE(std::get<0>(o6->t) == 2); + REQUIRE(std::get<1>(o6->t) == 3); +} diff --git a/tests/make_optional.cpp b/tests/make_optional.cpp new file mode 100644 index 0000000..817e3f2 --- /dev/null +++ b/tests/make_optional.cpp @@ -0,0 +1,40 @@ +#include "catch.hpp" +#include "optional.hpp" + +#include +#include + +struct takes_init_and_variadic { + std::vector v; + std::tuple t; + template + takes_init_and_variadic(std::initializer_list l, Args &&... args) + : v(l), t(std::forward(args)...) {} +}; + +TEST_CASE("Make optional", "[make_optional]") { + auto o1 = tl::make_optional(42); + auto o2 = tl::optional(42); + + constexpr bool is_same = std::is_same>::value; + REQUIRE(is_same); + REQUIRE(o1 == o2); + + auto o3 = tl::make_optional>(0, 1, 2, 3); + REQUIRE(std::get<0>(*o3) == 0); + REQUIRE(std::get<1>(*o3) == 1); + REQUIRE(std::get<2>(*o3) == 2); + REQUIRE(std::get<3>(*o3) == 3); + + auto o4 = tl::make_optional>({0, 1, 2, 3}); + REQUIRE(o4.value()[0] == 0); + REQUIRE(o4.value()[1] == 1); + REQUIRE(o4.value()[2] == 2); + REQUIRE(o4.value()[3] == 3); + + auto o5 = tl::make_optional({0, 1}, 2, 3); + REQUIRE(o5->v[0] == 0); + REQUIRE(o5->v[1] == 1); + REQUIRE(std::get<0>(o5->t) == 2); + REQUIRE(std::get<1>(o5->t) == 3); +} diff --git a/tests/relops.cpp b/tests/relops.cpp new file mode 100644 index 0000000..2f388e7 --- /dev/null +++ b/tests/relops.cpp @@ -0,0 +1,153 @@ +#include "catch.hpp" +#include "optional.hpp" + +TEST_CASE("Relational ops", "[relops]") { + tl::optional o1{4}; + tl::optional o2{42}; + tl::optional o3{}; + + SECTION("self simple") { + REQUIRE(!(o1 == o2)); + REQUIRE(o1 == o1); + REQUIRE(o1 != o2); + REQUIRE(!(o1 != o1)); + REQUIRE(o1 < o2); + REQUIRE(!(o1 < o1)); + REQUIRE(!(o1 > o2)); + REQUIRE(!(o1 > o1)); + REQUIRE(o1 <= o2); + REQUIRE(o1 <= o1); + REQUIRE(!(o1 >= o2)); + REQUIRE(o1 >= o1); + } + + SECTION("nullopt simple") { + REQUIRE(!(o1 == tl::nullopt)); + REQUIRE(!(tl::nullopt == o1)); + REQUIRE(o1 != tl::nullopt); + REQUIRE(tl::nullopt != o1); + REQUIRE(!(o1 < tl::nullopt)); + REQUIRE(tl::nullopt < o1); + REQUIRE(o1 > tl::nullopt); + REQUIRE(!(tl::nullopt > o1)); + REQUIRE(!(o1 <= tl::nullopt)); + REQUIRE(tl::nullopt <= o1); + REQUIRE(o1 >= tl::nullopt); + REQUIRE(!(tl::nullopt >= o1)); + + REQUIRE(o3 == tl::nullopt); + REQUIRE(tl::nullopt == o3); + REQUIRE(!(o3 != tl::nullopt)); + REQUIRE(!(tl::nullopt != o3)); + REQUIRE(!(o3 < tl::nullopt)); + REQUIRE(!(tl::nullopt < o3)); + REQUIRE(!(o3 > tl::nullopt)); + REQUIRE(!(tl::nullopt > o3)); + REQUIRE(o3 <= tl::nullopt); + REQUIRE(tl::nullopt <= o3); + REQUIRE(o3 >= tl::nullopt); + REQUIRE(tl::nullopt >= o3); + } + + SECTION("with T simple") { + REQUIRE(!(o1 == 1)); + REQUIRE(!(1 == o1)); + REQUIRE(o1 != 1); + REQUIRE(1 != o1); + REQUIRE(!(o1 < 1)); + REQUIRE(1 < o1); + REQUIRE(o1 > 1); + REQUIRE(!(1 > o1)); + REQUIRE(!(o1 <= 1)); + REQUIRE(1 <= o1); + REQUIRE(o1 >= 1); + REQUIRE(!(1 >= o1)); + + REQUIRE(o1 == 4); + REQUIRE(4 == o1); + REQUIRE(!(o1 != 4)); + REQUIRE(!(4 != o1)); + REQUIRE(!(o1 < 4)); + REQUIRE(!(4 < o1)); + REQUIRE(!(o1 > 4)); + REQUIRE(!(4 > o1)); + REQUIRE(o1 <= 4); + REQUIRE(4 <= o1); + REQUIRE(o1 >= 4); + REQUIRE(4 >= o1); + } + + tl::optional o4{"hello"}; + tl::optional o5{"xyz"}; + + SECTION("self complex") { + REQUIRE(!(o4 == o5)); + REQUIRE(o4 == o4); + REQUIRE(o4 != o5); + REQUIRE(!(o4 != o4)); + REQUIRE(o4 < o5); + REQUIRE(!(o4 < o4)); + REQUIRE(!(o4 > o5)); + REQUIRE(!(o4 > o4)); + REQUIRE(o4 <= o5); + REQUIRE(o4 <= o4); + REQUIRE(!(o4 >= o5)); + REQUIRE(o4 >= o4); + } + + SECTION("nullopt complex") { + REQUIRE(!(o4 == tl::nullopt)); + REQUIRE(!(tl::nullopt == o4)); + REQUIRE(o4 != tl::nullopt); + REQUIRE(tl::nullopt != o4); + REQUIRE(!(o4 < tl::nullopt)); + REQUIRE(tl::nullopt < o4); + REQUIRE(o4 > tl::nullopt); + REQUIRE(!(tl::nullopt > o4)); + REQUIRE(!(o4 <= tl::nullopt)); + REQUIRE(tl::nullopt <= o4); + REQUIRE(o4 >= tl::nullopt); + REQUIRE(!(tl::nullopt >= o4)); + + REQUIRE(o3 == tl::nullopt); + REQUIRE(tl::nullopt == o3); + REQUIRE(!(o3 != tl::nullopt)); + REQUIRE(!(tl::nullopt != o3)); + REQUIRE(!(o3 < tl::nullopt)); + REQUIRE(!(tl::nullopt < o3)); + REQUIRE(!(o3 > tl::nullopt)); + REQUIRE(!(tl::nullopt > o3)); + REQUIRE(o3 <= tl::nullopt); + REQUIRE(tl::nullopt <= o3); + REQUIRE(o3 >= tl::nullopt); + REQUIRE(tl::nullopt >= o3); + } + + SECTION("with T complex") { + REQUIRE(!(o4 == "a")); + REQUIRE(!("a" == o4)); + REQUIRE(o4 != "a"); + REQUIRE("a" != o4); + REQUIRE(!(o4 < "a")); + REQUIRE("a" < o4); + REQUIRE(o4 > "a"); + REQUIRE(!("a" > o4)); + REQUIRE(!(o4 <= "a")); + REQUIRE("a" <= o4); + REQUIRE(o4 >= "a"); + REQUIRE(!("a" >= o4)); + + REQUIRE(o4 == "hello"); + REQUIRE("hello" == o4); + REQUIRE(!(o4 != "hello")); + REQUIRE(!("hello" != o4)); + REQUIRE(!(o4 < "hello")); + REQUIRE(!("hello" < o4)); + REQUIRE(!(o4 > "hello")); + REQUIRE(!("hello" > o4)); + REQUIRE(o4 <= "hello"); + REQUIRE("hello" <= o4); + REQUIRE(o4 >= "hello"); + REQUIRE("hello" >= o4); + } +}