-
Notifications
You must be signed in to change notification settings - Fork 447
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
Conversation
Added 4 overloads of the method "variant_cast" In order to move values out, to return values by reference or to return a pointer to the underlying values, when the type does match: template<class T> T variant_cast(variant&& operand); template<class T> T variant_cast(variant& operand); template<class T> T variant_cast(const variant& operand); template<class T> const T* variant_cast(const variant* operand) RTTR_NOEXCEPT; template<class T> T* variant_cast(variant* operand) RTTR_NOEXCEPT; Additionally: - added non-const version of variant::get_value() - fixed copy-right year in root CMakeLists.txt file Fixes rttrorg#108
and fixed moveable test
@gabyx |
{ | ||
variant var = 12; | ||
|
||
auto value = variant_cast<int>(&var); |
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.
Is that correct: value is still bound to the var
. meaning if var gets destroyed, value
is dangling as well.
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.
yes, that is correct. Same as with variant::get_value<T>()
src/rttr/variant.h
Outdated
* \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 comment
The reason will be displayed to describe this comment to others. Learn more.
remove extracts
src/rttr/variant.h
Outdated
* 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; |
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.
Probably add "// b is nullptr"
{ | ||
const variant var = 12; | ||
|
||
auto value = variant_cast<int>(&var); |
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.
so the const semantic in variant_cast<...>
is neglected. meaning we dont write variant_cast<const int>
.
Wouldnt that be better? I see the benefits of the current implementation. I would leave it like that
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.
@gabyx
What would be better?
You cannot have a const-by-value
inside a variant. However, you can have a const int*
|
||
REQUIRE(var.get_type() == type::get<int>()); | ||
|
||
auto value = variant_cast<int>(var); |
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.
;) -> auto
has the semantic of always stripping references
== &
. So I think when you write auto value
this is always an lvalue (not an lvalue reference).
So it seems that this test is obsolete :-), but better leave it included :-)
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 know, but also this case can happen, thats why I added the test.
Its also in the section: SECTION("by value")
* \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 comment
The 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.
@@ -652,7 +652,7 @@ struct RTTR_API variant_data_policy_empty | |||
} | |||
case variant_policy_operation::GET_VALUE: | |||
{ | |||
arg.get_value<void*>() = nullptr; | |||
arg.get_value<const void*>() = nullptr; |
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 suppose arg
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
Added global "variant_cast" method
Added 4 overloads of the method "variant_cast"
In order to move values out, to return values by reference
or to return a pointer to the underlying values, when the type does match:
template
T variant_cast(variant&& operand);
template
T variant_cast(variant& operand);
template
T variant_cast(const variant& operand);
template
const T* variant_cast(const variant* operand) RTTR_NOEXCEPT;
template
T* variant_cast(variant* operand) RTTR_NOEXCEPT;
Additionally:
Fixes #108