From fcddac20ccbfb01b104aa881597d6a824bb7a358 Mon Sep 17 00:00:00 2001 From: yaito3014 Date: Fri, 6 Feb 2026 20:13:20 +0900 Subject: [PATCH] Implement unsafe_get --- include/iris/rvariant/rvariant.hpp | 81 ++++++++++++++++++++++++++++++ test/rvariant/get_visit_test.cpp | 36 +++++++++++++ 2 files changed, 117 insertions(+) diff --git a/include/iris/rvariant/rvariant.hpp b/include/iris/rvariant/rvariant.hpp index 3954460..b5d71a5 100644 --- a/include/iris/rvariant/rvariant.hpp +++ b/include/iris/rvariant/rvariant.hpp @@ -1211,6 +1211,87 @@ template requires is_ttp_specialization_of_v constexpr T const&& get(rvariant const&&) = delete; +// ------------------------------------------------- + +template +[[nodiscard]] constexpr variant_alternative_t>& +unsafe_get(rvariant& v IRIS_LIFETIMEBOUND) noexcept +{ + static_assert(I < sizeof...(Ts)); + return detail::unwrap_recursive(detail::raw_get(detail::forward_storage&>(v))); +} + +template +[[nodiscard]] constexpr variant_alternative_t>&& +unsafe_get(rvariant&& v IRIS_LIFETIMEBOUND) noexcept // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) +{ + static_assert(I < sizeof...(Ts)); + return detail::unwrap_recursive(detail::raw_get(detail::forward_storage&&>(v))); +} + +template +[[nodiscard]] constexpr variant_alternative_t> const& +unsafe_get(rvariant const& v IRIS_LIFETIMEBOUND) noexcept +{ + static_assert(I < sizeof...(Ts)); + return detail::unwrap_recursive(detail::raw_get(detail::forward_storage const&>(v))); +} + +template +[[nodiscard]] constexpr variant_alternative_t> const&& +unsafe_get(rvariant const&& v IRIS_LIFETIMEBOUND) noexcept +{ + return detail::unwrap_recursive(detail::raw_get(detail::forward_storage const&&>(v))); +} + +template +[[nodiscard]] constexpr T& +unsafe_get(rvariant& v IRIS_LIFETIMEBOUND) noexcept +{ + constexpr std::size_t I = detail::exactly_once_index_v>; + return detail::unwrap_recursive(detail::raw_get(detail::forward_storage&>(v))); +} + +template +[[nodiscard]] constexpr T&& +unsafe_get(rvariant&& v IRIS_LIFETIMEBOUND) noexcept // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) +{ + constexpr std::size_t I = detail::exactly_once_index_v>; + return detail::unwrap_recursive(detail::raw_get(detail::forward_storage&&>(v))); +} + +template +[[nodiscard]] constexpr T const& +unsafe_get(rvariant const& v IRIS_LIFETIMEBOUND) noexcept +{ + constexpr std::size_t I = detail::exactly_once_index_v>; + return detail::unwrap_recursive(detail::raw_get(detail::forward_storage const&>(v))); +} + +template +[[nodiscard]] constexpr T const&& +unsafe_get(rvariant const&& v IRIS_LIFETIMEBOUND) noexcept +{ + constexpr std::size_t I = detail::exactly_once_index_v>; + return detail::unwrap_recursive(detail::raw_get(detail::forward_storage const&&>(v))); +} + +template + requires is_ttp_specialization_of_v +constexpr T& unsafe_get(rvariant&) = delete; + +template + requires is_ttp_specialization_of_v +constexpr T&& unsafe_get(rvariant&&) = delete; + +template + requires is_ttp_specialization_of_v +constexpr T const& unsafe_get(rvariant const&) = delete; + +template + requires is_ttp_specialization_of_v +constexpr T const&& unsafe_get(rvariant const&&) = delete; + // --------------------------------------------- template diff --git a/test/rvariant/get_visit_test.cpp b/test/rvariant/get_visit_test.cpp index 158187f..50905f1 100644 --- a/test/rvariant/get_visit_test.cpp +++ b/test/rvariant/get_visit_test.cpp @@ -151,6 +151,42 @@ TEST_CASE("get", "[wrapper]") REQUIRE(iris::get(std::move(var)) == 42); } } + +TEST_CASE("unsafe_get") +{ + { + iris::rvariant var = 42; + REQUIRE(iris::unsafe_get<0>(std::as_const(var)) == 42); + REQUIRE(iris::unsafe_get<0>(var) == 42); + REQUIRE(iris::unsafe_get<0>(std::move(std::as_const(var))) == 42); + REQUIRE(iris::unsafe_get<0>(std::move(var)) == 42); + } + { + iris::rvariant var = 42; + REQUIRE(iris::unsafe_get(std::as_const(var)) == 42); + REQUIRE(iris::unsafe_get(var) == 42); + REQUIRE(iris::unsafe_get(std::move(std::as_const(var))) == 42); + REQUIRE(iris::unsafe_get(std::move(var)) == 42); + } +} + +TEST_CASE("unsafe_get", "[wrapper]") +{ + { + iris::rvariant, float> var = 42; + REQUIRE(iris::unsafe_get<0>(std::as_const(var)) == 42); + REQUIRE(iris::unsafe_get<0>(var) == 42); + REQUIRE(iris::unsafe_get<0>(std::move(std::as_const(var))) == 42); + REQUIRE(iris::unsafe_get<0>(std::move(var)) == 42); + } + { + iris::rvariant, float> var = 42; + REQUIRE(iris::unsafe_get(std::as_const(var)) == 42); + REQUIRE(iris::unsafe_get(var) == 42); + REQUIRE(iris::unsafe_get(std::move(std::as_const(var))) == 42); + REQUIRE(iris::unsafe_get(std::move(var)) == 42); + } +} // NOLINTEND(performance-move-const-arg) TEST_CASE("get_if")