-
Notifications
You must be signed in to change notification settings - Fork 448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature add variant_cast #129
Changes from 7 commits
6c5596c
9bd0a22
0ed9d74
8f9d65d
b14bcfe
7785fe5
55ffd53
6a9fb30
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,11 @@ class instance; | |
|
||
namespace detail | ||
{ | ||
template<class T> | ||
RTTR_INLINE T* unsafe_variant_cast(variant* operand) RTTR_NOEXCEPT; | ||
template<class T> | ||
RTTR_INLINE const T* unsafe_variant_cast(const variant* operand) RTTR_NOEXCEPT; | ||
|
||
struct data_address_container; | ||
template<typename T> | ||
struct empty_type_converter; | ||
|
@@ -423,6 +428,32 @@ class RTTR_API variant | |
*/ | ||
bool is_sequential_container() const; | ||
|
||
/*! | ||
* \brief Returns a reference to the containing value as type \p T. | ||
* | ||
* \code{.cpp} | ||
* struct custom_type | ||
* { | ||
* //... | ||
* }; | ||
* | ||
* variant var = custom_type{}; | ||
* if (var.is_type<custom_type>()) // yields to true | ||
* custom_type& value = var.get_value<custom_type>(); // extracts the value by reference | ||
* \endcode | ||
* | ||
* \remark Only call this method when it is possible to return the containing value as the given type \p T. | ||
* Use therefore the method \ref is_type(). | ||
* Otherwise the call leads to undefined behaviour. | ||
* Also make sure you don't clean this variant, when you still hold a reference to the containing value. | ||
* | ||
* \see is_type() | ||
* | ||
* \return A reference to the stored value. | ||
*/ | ||
template<typename T> | ||
T& get_value(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like that one. So such a functionality was not yet there. Its up to the user to call that with the right type. |
||
|
||
/*! | ||
* \brief Returns a reference to the containing value as type \p T. | ||
* | ||
|
@@ -1067,13 +1098,107 @@ class RTTR_API variant | |
friend struct detail::variant_data_base_policy; | ||
friend struct detail::variant_data_policy_nullptr_t; | ||
friend RTTR_API bool detail::variant_compare_less(const variant&, const type&, const variant&, const type&, bool& ok); | ||
template<class T> | ||
friend RTTR_INLINE T* detail::unsafe_variant_cast(variant* operand) RTTR_NOEXCEPT; | ||
|
||
|
||
detail::variant_data m_data; | ||
detail::variant_policy_func m_policy; | ||
}; | ||
|
||
///////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
/*! | ||
* \brief Returns a reference to the containing value as type \p T. | ||
* | ||
* \code{.cpp} | ||
* | ||
* variant var = std::string("hello world"); | ||
* std:string& value_ref = variant_cast<std::string&>(var); // extracts the value by reference | ||
* std:string value = variant_cast<std::string>(var); // copies the value | ||
* | ||
* \endcode | ||
* | ||
* \remark Extracting a value type, which is not stored in the variant, leads to undefined behaviour. | ||
* No exception or error code will be returned! | ||
*/ | ||
template<class T> | ||
T variant_cast(const variant& operand); | ||
|
||
/*! | ||
* \brief Returns a reference to the containing value as type \p T. | ||
* | ||
* \code{.cpp} | ||
* | ||
* variant var = std::string("hello world"); | ||
* std:string& value_ref = variant_cast<std::string&>(var); // extracts the value by reference | ||
* std:string value = variant_cast<std::string>(var); // copies the value | ||
* | ||
* \endcode | ||
* | ||
* \remark Extracting a value type, which is not stored in the variant, leads to undefined behaviour. | ||
* No exception or error code will be returned! | ||
*/ | ||
template<class T> | ||
T variant_cast(variant& operand); | ||
|
||
/*! | ||
* \brief Move the containing value from the variant into a type \p T. | ||
* | ||
* \code{.cpp} | ||
* | ||
* variant var = std::string("hello world"); | ||
* std::string& a = variant_cast<std::string&>(var); | ||
* std:string b = variant_cast<std::string>(std::move(var)); // move the value to 'b' | ||
* std::cout << "a: " << a << std::endl; // is now empty | ||
* std::cout << "b: " << b << std::endl; // prints "hello world" | ||
* | ||
* \endcode | ||
* | ||
* \remark Extracting a value type, which is not stored in the variant, leads to undefined behaviour. | ||
* No exception or error code will be returned! | ||
*/ | ||
template<class T> | ||
T variant_cast(variant&& operand); | ||
|
||
/*! | ||
* \brief Returns a pointer to the containing value with type \p T. | ||
* When the containing value is of type \p T, a valid pointer to the type will be returned. | ||
* Otherwise a `nullptr` is returned. | ||
* | ||
* \code{.cpp} | ||
* | ||
* variant var = std::string("hello world"); | ||
* std:string* a = variant_cast<std::string>(&var); // performs an internal type check and returns extracts the value by reference | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove |
||
* int* b = variant_cast<int>(&var); | ||
* std::cout << "a valid: " << a != nullptr << std::endl; | ||
* std::cout << "b valid: " << b != nullptr << std::endl; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably add "// b is nullptr" |
||
* \endcode | ||
* | ||
* \return A valid pointer, when the containing type is of type \p T; otherwise a `nullptr`. | ||
*/ | ||
template<class T> | ||
const T* variant_cast(const variant* operand) RTTR_NOEXCEPT; | ||
|
||
/*! | ||
* \brief Returns a pointer to the containing value with type \p T. | ||
* When the containing value is of type \p T, a valid pointer to the type will be returned. | ||
* Otherwise a `nullptr` is returned. | ||
* | ||
* \code{.cpp} | ||
* | ||
* variant var = std::string("hello world"); | ||
* std:string* a = variant_cast<std::string>(&var); // performs an internal type check and returns extracts the value by reference | ||
* int* b = variant_cast<int>(&var); | ||
* std::cout << "a valid: " << a != nullptr << std::endl; | ||
* std::cout << "b valid: " << b != nullptr << std::endl; | ||
* \endcode | ||
* | ||
* \return A valid pointer, when the containing type is of type \p T; otherwise a `nullptr`. | ||
*/ | ||
template<class T> | ||
T* variant_cast(variant* operand) RTTR_NOEXCEPT; | ||
|
||
} // end namespace rttr | ||
|
||
#include "rttr/detail/variant/variant_impl.h" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was that wrong before? and did you already had a get_value function before but not in the interface in
variant
(I supposearg
is a variant?)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I go "down" with a
const void*
, that's why I adjusted it.https://github.com/rttrorg/rttr/pull/129/files#diff-196fbfbb881e65b49f3262cd9ef3bf19R421