protected:
template<typename T, typename... Us> friend T& get(variant<Us...> &v);
template<typename T, typename... Us> friend const T& get(const variant<Us...> &v);
+ template<typename T, typename... Us> friend T* get_if(variant<Us...> *v) noexcept;
+ template<typename T, typename... Us> friend const T* get_if(const variant<Us...> *v) noexcept;
+
template<typename... Us> friend bool operator==(const variant<Us...> &lhs,
const variant<Us...> &rhs);
Memory memory;
};
// FIMXE: visit
+ template<typename T, typename... Types>
+ T* get_if(util::variant<Types...>* v) noexcept;
+
+ template<typename T, typename... Types>
+ const T* get_if(const util::variant<Types...>* v) noexcept;
template<typename T, typename... Types>
T& get(util::variant<Types...> &v);
}
template<typename T, typename... Types>
- T& get(util::variant<Types...> &v)
+ T* get_if(util::variant<Types...>* v) noexcept
{
const constexpr std::size_t t_index =
util::type_list_index<T, Types...>::value;
- if (v.index() == t_index)
- return *(T*)(&v.memory); // workaround for ICC 2019
+ if (v && v->index() == t_index)
+ return (T*)(&v->memory); // workaround for ICC 2019
// original code: return reinterpret_cast<T&>(v.memory);
- else
- throw_error(bad_variant_access());
+ return nullptr;
}
template<typename T, typename... Types>
- const T& get(const util::variant<Types...> &v)
+ const T* get_if(const util::variant<Types...>* v) noexcept
{
const constexpr std::size_t t_index =
util::type_list_index<T, Types...>::value;
- if (v.index() == t_index)
- return *(const T*)(&v.memory); // workaround for ICC 2019
+ if (v && v->index() == t_index)
+ return (const T*)(&v->memory); // workaround for ICC 2019
// original code: return reinterpret_cast<const T&>(v.memory);
+ return nullptr;
+ }
+
+ template<typename T, typename... Types>
+ T& get(util::variant<Types...> &v)
+ {
+ if (auto* p = get_if<T>(&v))
+ return *p;
+ else
+ throw_error(bad_variant_access());
+ }
+
+ template<typename T, typename... Types>
+ const T& get(const util::variant<Types...> &v)
+ {
+ if (auto* p = get_if<T>(&v))
+ return *p;
else
throw_error(bad_variant_access());
}
EXPECT_EQ(3.14f, util::get<float>(tv1));
}
+TEST(Variant, GetIf)
+{
+ const TestVar cv(42);
+
+ // Test const& get_if()
+ EXPECT_EQ(nullptr, util::get_if<std::string>(&cv));
+ ASSERT_NE(nullptr, util::get_if<int>(&cv));
+ EXPECT_EQ(42, *util::get_if<int>(&cv));
+
+ // Test &get_if
+ TestVar cv2(std::string("42"));
+ EXPECT_EQ(nullptr, util::get_if<int>(&cv2));
+ ASSERT_NE(nullptr, util::get_if<std::string>(&cv2));
+ EXPECT_EQ("42", *util::get_if<std::string>(&cv2));
+}
+
TEST(Variant, Get)
{
const TestVar cv(42);