#include #include #include #include #include namespace { struct identity_projection { template const T& operator()(const T& val) noexcept { return val; } }; } TEST_CASE ("equal", "[optional]") { using vcpkg::Optional; CHECK(Optional{} == Optional{}); CHECK_FALSE(Optional{} == Optional{42}); CHECK_FALSE(Optional{42} == Optional{}); CHECK_FALSE(Optional{1729} == Optional{42}); CHECK(Optional{42} == Optional{42}); } TEST_CASE ("ref conversion", "[optional]") { using vcpkg::Optional; Optional i_empty; Optional i_1 = 1; const Optional ci_1 = 1; Optional ref_empty = i_empty; Optional cref_empty = i_empty; Optional ref_1 = i_1; Optional cref_1 = ci_1; REQUIRE(ref_empty.has_value() == false); REQUIRE(cref_empty.has_value() == false); REQUIRE(ref_1.get() == i_1.get()); REQUIRE(cref_1.get() == ci_1.get()); ref_empty = i_1; cref_empty = ci_1; REQUIRE(ref_empty.get() == i_1.get()); REQUIRE(cref_empty.get() == ci_1.get()); const int x = 5; cref_1 = x; REQUIRE(cref_1.get() == &x); } TEST_CASE ("value conversion", "[optional]") { using vcpkg::Optional; Optional j = 1; Optional i = j; Optional cstr = "hello, world!"; Optional cppstr = cstr; std::vector v{1, 2, 3}; Optional&> o_v(v); REQUIRE(o_v.has_value()); REQUIRE(o_v.get()->size() == 3); Optional> o_w(std::move(o_v)); REQUIRE(o_w.has_value()); REQUIRE(o_w.get()->size() == 3); // Moving from Optional<&> should not move the underlying object REQUIRE(o_v.has_value()); REQUIRE(o_v.get()->size() == 3); } TEST_CASE ("optional.map", "[optional]") { using vcpkg::NullOpt; using vcpkg::nullopt; using vcpkg::Optional; const Optional> move_only; Optional m = move_only.map([](auto&& p) { return p.get(); }); Optional> n = move_only.map([](auto&& p) -> Optional { return p ? Optional{p.get()} : nullopt; }); Optional o = move_only.map([](auto&&) { return nullopt; }); Optional five = 5; struct MoveTest { int operator()(int&&) { return 1; } int operator()(const int&) { return -1; } } move_test; Optional dst = std::move(five).map(move_test); REQUIRE(dst == 1); Optional dst2 = five.map(move_test); REQUIRE(dst2 == -1); } TEST_CASE ("common_projection", "[optional]") { using vcpkg::Util::common_projection; std::vector input; CHECK(!common_projection(input, identity_projection{}).has_value()); input.push_back(42); CHECK(common_projection(input, identity_projection{}).value_or_exit(VCPKG_LINE_INFO) == 42); input.push_back(42); CHECK(common_projection(input, identity_projection{}).value_or_exit(VCPKG_LINE_INFO) == 42); input.push_back(1729); CHECK(!common_projection(input, identity_projection{}).has_value()); }