new uvalue safe api

This commit is contained in:
BlackMATov
2023-02-10 23:09:52 +07:00
parent 214920da44
commit deeaebd6a6
7 changed files with 299 additions and 8 deletions

View File

@@ -31,6 +31,7 @@
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <set>
#include <span>
#include <string>

View File

@@ -110,6 +110,15 @@ namespace meta_hpp
[[nodiscard]] auto try_get_as() const noexcept //
-> std::conditional_t<detail::pointer_kind<T>, T, const T*>;
template < typename T >
[[nodiscard]] std::optional<T> safe_get_as() &&;
template < typename T >
[[nodiscard]] std::optional<T> safe_get_as() &;
template < typename T >
[[nodiscard]] std::optional<T> safe_get_as() const&;
private:
struct vtable_t;

View File

@@ -619,4 +619,55 @@ namespace meta_hpp
return nullptr;
}
template < typename T >
std::optional<T> uvalue::safe_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);
}
}
return std::nullopt;
}
template < typename T >
std::optional<T> uvalue::safe_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 *ptr;
}
}
return std::nullopt;
}
template < typename T >
std::optional<T> uvalue::safe_get_as() const& {
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 ( const T* ptr = try_get_as<T>() ) {
return *ptr;
}
}
return std::nullopt;
}
}