rvalue uvalue::get_as optimization

This commit is contained in:
BlackMATov
2023-01-12 10:31:07 +07:00
parent 5a54ea9bac
commit e2d5ae5e6d
6 changed files with 88 additions and 20 deletions

View File

@@ -2366,11 +2366,14 @@ namespace meta_hpp
[[nodiscard]] uvalue operator[](std::size_t index) const;
template < typename T >
[[nodiscard]] auto get_as()
[[nodiscard]] T get_as() &&;
template < typename T >
[[nodiscard]] auto get_as() &
-> std::conditional_t<detail::pointer_kind<T>, T, T&>;
template < typename T >
[[nodiscard]] auto get_as() const
[[nodiscard]] auto get_as() const &
-> std::conditional_t<detail::pointer_kind<T>, T, const T&>;
template < typename T >
@@ -5635,7 +5638,7 @@ namespace meta_hpp
}
for ( auto&& [_, evalue] : data_->evalues ) {
if ( evalue.get_value().get_as<Enum>() == value ) {
if ( evalue.get_value().template get_as<Enum>() == value ) {
return evalue.get_index().get_name();
}
}
@@ -8388,7 +8391,24 @@ namespace meta_hpp
}
template < typename T >
auto uvalue::get_as() -> std::conditional_t<detail::pointer_kind<T>, T, T&> {
[[nodiscard]] T uvalue::get_as() && {
static_assert(std::is_same_v<T, std::decay_t<T>>);
if constexpr ( detail::pointer_kind<T> ) {
if ( T ptr = try_get_as<T>(); ptr || get_type().is_nullptr() ) {
return ptr;
}
} else {
if ( T* ptr = try_get_as<T>() ) {
return std::move(*ptr);
}
}
detail::throw_exception_with("bad value cast");
}
template < typename T >
auto uvalue::get_as() & -> std::conditional_t<detail::pointer_kind<T>, T, T&> {
static_assert(std::is_same_v<T, std::decay_t<T>>);
if constexpr ( detail::pointer_kind<T> ) {
@@ -8405,7 +8425,7 @@ namespace meta_hpp
}
template < typename T >
auto uvalue::get_as() const -> std::conditional_t<detail::pointer_kind<T>, T, const T&> {
auto uvalue::get_as() const & -> std::conditional_t<detail::pointer_kind<T>, T, const T&> {
static_assert(std::is_same_v<T, std::decay_t<T>>);
if constexpr ( detail::pointer_kind<T> ) {

View File

@@ -91,7 +91,7 @@ TEST_CASE("meta/meta_utilities/value4/get_as") {
namespace meta = meta_hpp;
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&>().get_as<derived>()), derived&>);
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&&>().get_as<derived>()), derived&>);
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&&>().get_as<derived>()), derived>);
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&>().get_as<derived>()), const derived&>);
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&&>().get_as<derived>()), const derived&>);

View File

@@ -111,7 +111,7 @@ TEST_CASE("meta/meta_utilities/value") {
ivec2&>);
static_assert(std::is_same_v<
decltype(std::declval<meta::uvalue&&>().get_as<ivec2>()),
ivec2&>);
ivec2>);
static_assert(std::is_same_v<
decltype(std::declval<const meta::uvalue&>().get_as<ivec2>()),
const ivec2&>);
@@ -166,8 +166,15 @@ TEST_CASE("meta/meta_utilities/value") {
CHECK(val.get_as<ivec2>() == ivec2{1,2});
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
CHECK(std::move(val).get_as<ivec2>() == ivec2{1,2});
CHECK(std::move(std::as_const(val)).get_as<ivec2>() == ivec2{1,2});
{
meta::uvalue val_copy{val};
CHECK(std::move(val_copy).get_as<ivec2>() == ivec2{1,2});
}
{
meta::uvalue val_copy{val};
CHECK(std::move(std::as_const(val_copy)).get_as<ivec2>() == ivec2{1,2});
}
CHECK_THROWS(std::ignore = val.get_as<ivec3>());
CHECK_THROWS(std::ignore = std::as_const(val).get_as<ivec3>());
@@ -199,8 +206,15 @@ TEST_CASE("meta/meta_utilities/value") {
CHECK(val.get_as<ivec2>() == ivec2{1,2});
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
CHECK(std::move(val).get_as<ivec2>() == ivec2{1,2});
CHECK(std::move(std::as_const(val)).get_as<ivec2>() == ivec2{1,2});
{
meta::uvalue val_copy{val};
CHECK(std::move(val_copy).get_as<ivec2>() == ivec2{1,2});
}
{
meta::uvalue val_copy{val};
CHECK(std::move(std::as_const(val_copy)).get_as<ivec2>() == ivec2{1,2});
}
CHECK_THROWS(std::ignore = val.get_as<ivec3>());
CHECK_THROWS(std::ignore = std::as_const(val).get_as<ivec3>());
@@ -226,8 +240,15 @@ TEST_CASE("meta/meta_utilities/value") {
CHECK(val.get_as<ivec2>() == ivec2{1,2});
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
CHECK(std::move(val).get_as<ivec2>() == ivec2{1,2});
CHECK(std::move(std::as_const(val)).get_as<ivec2>() == ivec2{1,2});
{
meta::uvalue val_copy{val};
CHECK(std::move(val_copy).get_as<ivec2>() == ivec2{1,2});
}
{
meta::uvalue val_copy{val};
CHECK(std::move(std::as_const(val_copy)).get_as<ivec2>() == ivec2{1,2});
}
CHECK_THROWS(std::ignore = val.get_as<ivec3>());
CHECK_THROWS(std::ignore = std::as_const(val).get_as<ivec3>());
@@ -253,8 +274,15 @@ TEST_CASE("meta/meta_utilities/value") {
CHECK(val.get_as<ivec2>() == ivec2{1,2});
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
CHECK(std::move(val).get_as<ivec2>() == ivec2{1,2});
CHECK(std::move(std::as_const(val)).get_as<ivec2>() == ivec2{1,2});
{
meta::uvalue val_copy{val};
CHECK(std::move(val_copy).get_as<ivec2>() == ivec2{1,2});
}
{
meta::uvalue val_copy{val};
CHECK(std::move(std::as_const(val_copy)).get_as<ivec2>() == ivec2{1,2});
}
CHECK_THROWS(std::ignore = val.get_as<ivec3>());
CHECK_THROWS(std::ignore = std::as_const(val).get_as<ivec3>());

View File

@@ -76,7 +76,7 @@ namespace meta_hpp
}
for ( auto&& [_, evalue] : data_->evalues ) {
if ( evalue.get_value().get_as<Enum>() == value ) {
if ( evalue.get_value().template get_as<Enum>() == value ) {
return evalue.get_index().get_name();
}
}

View File

@@ -86,11 +86,14 @@ namespace meta_hpp
[[nodiscard]] uvalue operator[](std::size_t index) const;
template < typename T >
[[nodiscard]] auto get_as()
[[nodiscard]] T get_as() &&;
template < typename T >
[[nodiscard]] auto get_as() &
-> std::conditional_t<detail::pointer_kind<T>, T, T&>;
template < typename T >
[[nodiscard]] auto get_as() const
[[nodiscard]] auto get_as() const &
-> std::conditional_t<detail::pointer_kind<T>, T, const T&>;
template < typename T >

View File

@@ -326,7 +326,24 @@ namespace meta_hpp
}
template < typename T >
auto uvalue::get_as() -> std::conditional_t<detail::pointer_kind<T>, T, T&> {
[[nodiscard]] T uvalue::get_as() && {
static_assert(std::is_same_v<T, std::decay_t<T>>);
if constexpr ( detail::pointer_kind<T> ) {
if ( T ptr = try_get_as<T>(); ptr || get_type().is_nullptr() ) {
return ptr;
}
} else {
if ( T* ptr = try_get_as<T>() ) {
return std::move(*ptr);
}
}
detail::throw_exception_with("bad value cast");
}
template < typename T >
auto uvalue::get_as() & -> std::conditional_t<detail::pointer_kind<T>, T, T&> {
static_assert(std::is_same_v<T, std::decay_t<T>>);
if constexpr ( detail::pointer_kind<T> ) {
@@ -343,7 +360,7 @@ namespace meta_hpp
}
template < typename T >
auto uvalue::get_as() const -> std::conditional_t<detail::pointer_kind<T>, T, const T&> {
auto uvalue::get_as() const & -> std::conditional_t<detail::pointer_kind<T>, T, const T&> {
static_assert(std::is_same_v<T, std::decay_t<T>>);
if constexpr ( detail::pointer_kind<T> ) {