#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 ("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()); }