mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
new uvalue api
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "meta_base/bitflags.hpp"
|
||||
#include "meta_base/cv_traits.hpp"
|
||||
#include "meta_base/cvref_traits.hpp"
|
||||
#include "meta_base/fixed_function.hpp"
|
||||
#include "meta_base/hash_combiner.hpp"
|
||||
|
||||
46
headers/meta.hpp/meta_base/cv_traits.hpp
Normal file
46
headers/meta.hpp/meta_base/cv_traits.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename From >
|
||||
struct cv_traits {
|
||||
static constexpr bool is_const = std::is_const_v<std::remove_reference_t<From>>;
|
||||
static constexpr bool is_volatile = std::is_volatile_v<std::remove_reference_t<From>>;
|
||||
|
||||
template < bool yesno, template < typename > typename Q, typename V >
|
||||
using apply_t_if = std::conditional_t<yesno, Q<V>, V>;
|
||||
|
||||
template < typename To >
|
||||
using add_to =
|
||||
apply_t_if<is_const, std::add_const_t,
|
||||
apply_t_if<is_volatile, std::add_volatile_t,
|
||||
To>>;
|
||||
|
||||
template < typename To >
|
||||
using copy_to = add_to<std::remove_cv_t<To>>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
struct add_cv {
|
||||
using type = typename cv_traits<From>::template add_to<To>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
struct copy_cv {
|
||||
using type = typename cv_traits<From>::template copy_to<To>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
using add_cv_t = typename add_cv<From, To>::type;
|
||||
|
||||
template < typename From, typename To >
|
||||
using copy_cv_t = typename copy_cv<From, To>::type;
|
||||
}
|
||||
@@ -21,12 +21,20 @@ namespace meta_hpp::detail
|
||||
using apply_t_if = std::conditional_t<yesno, Q<V>, V>;
|
||||
|
||||
template < typename To >
|
||||
using copy_to =
|
||||
using add_to =
|
||||
apply_t_if<is_lvalue, std::add_lvalue_reference_t,
|
||||
apply_t_if<is_rvalue, std::add_rvalue_reference_t,
|
||||
apply_t_if<is_const, std::add_const_t,
|
||||
apply_t_if<is_volatile, std::add_volatile_t,
|
||||
std::remove_cvref_t<To>>>>>;
|
||||
To>>>>;
|
||||
|
||||
template < typename To >
|
||||
using copy_to = add_to<std::remove_cvref_t<To>>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
struct add_cvref {
|
||||
using type = typename cvref_traits<From>::template add_to<To>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
@@ -34,6 +42,9 @@ namespace meta_hpp::detail
|
||||
using type = typename cvref_traits<From>::template copy_to<To>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
using add_cvref_t = typename add_cvref<From, To>::type;
|
||||
|
||||
template < typename From, typename To >
|
||||
using copy_cvref_t = typename copy_cvref<From, To>::type;
|
||||
}
|
||||
|
||||
@@ -61,22 +61,40 @@ namespace meta_hpp
|
||||
[[nodiscard]] uvalue operator[](std::size_t index) const;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::decay_t<T>& cast() &;
|
||||
[[nodiscard]] T get_as() &;
|
||||
template < typename T >
|
||||
[[nodiscard]] T get_as() &&;
|
||||
template < typename T >
|
||||
[[nodiscard]] T get_as() const &;
|
||||
template < typename T >
|
||||
[[nodiscard]] T get_as() const &&;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::decay_t<T>&& cast() &&;
|
||||
[[nodiscard]] T& get_as_ref() &;
|
||||
template < typename T >
|
||||
[[nodiscard]] T&& get_as_ref() &&;
|
||||
template < typename T >
|
||||
[[nodiscard]] const T& get_as_ref() const &;
|
||||
template < typename T >
|
||||
[[nodiscard]] const T&& get_as_ref() const &&;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] const std::decay_t<T>& cast() const &;
|
||||
[[nodiscard]] bool can_get_as() &;
|
||||
template < typename T >
|
||||
[[nodiscard]] bool can_get_as() &&;
|
||||
template < typename T >
|
||||
[[nodiscard]] bool can_get_as() const &;
|
||||
template < typename T >
|
||||
[[nodiscard]] bool can_get_as() const &&;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] const std::decay_t<T>&& cast() const &&;
|
||||
|
||||
[[nodiscard]] bool can_get_as_ref() &;
|
||||
template < typename T >
|
||||
[[nodiscard]] std::decay_t<T>* try_cast() noexcept;
|
||||
|
||||
[[nodiscard]] bool can_get_as_ref() &&;
|
||||
template < typename T >
|
||||
[[nodiscard]] const std::decay_t<T>* try_cast() const noexcept;
|
||||
[[nodiscard]] bool can_get_as_ref() const &;
|
||||
template < typename T >
|
||||
[[nodiscard]] bool can_get_as_ref() const &&;
|
||||
|
||||
friend bool operator<(const uvalue& l, const uvalue& r);
|
||||
friend bool operator==(const uvalue& l, const uvalue& r);
|
||||
@@ -98,3 +116,18 @@ namespace meta_hpp
|
||||
l.swap(r);
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < typename T, detail::decay_value_kind V >
|
||||
[[nodiscard]] auto get_as(V&& value) -> T;
|
||||
|
||||
template < typename T, detail::decay_value_kind V >
|
||||
[[nodiscard]] auto get_as_ref(V&& value) -> detail::add_cvref_t<V&&, T>;
|
||||
|
||||
template < typename T, detail::decay_value_kind V >
|
||||
[[nodiscard]] bool can_get_as(V&& value) noexcept;
|
||||
|
||||
template < typename T, detail::decay_value_kind V >
|
||||
[[nodiscard]] bool can_get_as_ref(V&& value) noexcept;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ namespace meta_hpp
|
||||
|
||||
.deref = +[]([[maybe_unused]] const uvalue& v) -> uvalue {
|
||||
if constexpr ( detail::has_deref_traits<Tp> ) {
|
||||
return detail::deref_traits<Tp>{}(v.cast<Tp>());
|
||||
return detail::deref_traits<Tp>{}(v.get_as_ref<Tp>());
|
||||
} else {
|
||||
detail::throw_exception_with("value type doesn't have value deref traits");
|
||||
}
|
||||
@@ -194,7 +194,7 @@ namespace meta_hpp
|
||||
|
||||
.index = +[]([[maybe_unused]] const uvalue& v, [[maybe_unused]] std::size_t i) -> uvalue {
|
||||
if constexpr ( detail::has_index_traits<Tp> ) {
|
||||
return detail::index_traits<Tp>{}(v.cast<Tp>(), i);
|
||||
return detail::index_traits<Tp>{}(v.get_as_ref<Tp>(), i);
|
||||
} else {
|
||||
detail::throw_exception_with("value type doesn't have value index traits");
|
||||
}
|
||||
@@ -202,7 +202,7 @@ namespace meta_hpp
|
||||
|
||||
.less = +[]([[maybe_unused]] const uvalue& l, [[maybe_unused]] const uvalue& r) -> bool {
|
||||
if constexpr ( detail::has_less_traits<Tp> ) {
|
||||
return detail::less_traits<Tp>{}(l.cast<Tp>(), r.cast<Tp>());
|
||||
return detail::less_traits<Tp>{}(l.get_as_ref<Tp>(), r.get_as_ref<Tp>());
|
||||
} else {
|
||||
detail::throw_exception_with("value type doesn't have value less traits");
|
||||
}
|
||||
@@ -210,7 +210,7 @@ namespace meta_hpp
|
||||
|
||||
.equals = +[]([[maybe_unused]] const uvalue& l, [[maybe_unused]] const uvalue& r) -> bool {
|
||||
if constexpr ( detail::has_equals_traits<Tp> ) {
|
||||
return detail::equals_traits<Tp>{}(l.cast<Tp>(), r.cast<Tp>());
|
||||
return detail::equals_traits<Tp>{}(l.get_as_ref<Tp>(), r.get_as_ref<Tp>());
|
||||
} else {
|
||||
detail::throw_exception_with("value type doesn't have value equals traits");
|
||||
}
|
||||
@@ -218,7 +218,7 @@ namespace meta_hpp
|
||||
|
||||
.istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] uvalue& v) -> std::istream& {
|
||||
if constexpr ( detail::has_istream_traits<Tp> ) {
|
||||
return detail::istream_traits<Tp>{}(is, v.cast<Tp>());
|
||||
return detail::istream_traits<Tp>{}(is, v.get_as_ref<Tp>());
|
||||
} else {
|
||||
detail::throw_exception_with("value type doesn't have value istream traits");
|
||||
}
|
||||
@@ -226,7 +226,7 @@ namespace meta_hpp
|
||||
|
||||
.ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const uvalue& v) -> std::ostream& {
|
||||
if constexpr ( detail::has_ostream_traits<Tp> ) {
|
||||
return detail::ostream_traits<Tp>{}(os, v.cast<Tp>());
|
||||
return detail::ostream_traits<Tp>{}(os, v.get_as_ref<Tp>());
|
||||
} else {
|
||||
detail::throw_exception_with("value type doesn't have value ostream traits");
|
||||
}
|
||||
@@ -327,85 +327,216 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::decay_t<T>& uvalue::cast() & {
|
||||
using Tp = std::decay_t<T>;
|
||||
|
||||
if ( Tp* ptr = try_cast<Tp>() ) {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
detail::throw_exception_with("bad value cast");
|
||||
T uvalue::get_as() & {
|
||||
return meta_hpp::get_as<T>(*this);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::decay_t<T>&& uvalue::cast() && {
|
||||
using Tp = std::decay_t<T>;
|
||||
|
||||
if ( Tp* ptr = try_cast<Tp>() ) {
|
||||
return std::move(*ptr);
|
||||
}
|
||||
|
||||
detail::throw_exception_with("bad value cast");
|
||||
T uvalue::get_as() && {
|
||||
return meta_hpp::get_as<T>(std::move(*this));
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
const std::decay_t<T>& uvalue::cast() const & {
|
||||
using Tp = std::decay_t<T>;
|
||||
|
||||
if ( const Tp* ptr = try_cast<const Tp>() ) {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
detail::throw_exception_with("bad value cast");
|
||||
T uvalue::get_as() const & {
|
||||
return meta_hpp::get_as<T>(*this);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
const std::decay_t<T>&& uvalue::cast() const && {
|
||||
using Tp = std::decay_t<T>;
|
||||
|
||||
if ( const Tp* ptr = try_cast<const Tp>() ) {
|
||||
return std::move(*ptr);
|
||||
}
|
||||
|
||||
detail::throw_exception_with("bad value cast");
|
||||
T uvalue::get_as() const && {
|
||||
// NOLINTNEXTLINE(*-move-const-arg)
|
||||
return meta_hpp::get_as<T>(std::move(*this));
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::decay_t<T>* uvalue::try_cast() noexcept {
|
||||
using Tp = std::decay_t<T>;
|
||||
T& uvalue::get_as_ref() & {
|
||||
return meta_hpp::get_as_ref<T>(*this);
|
||||
}
|
||||
|
||||
const any_type& from_type = get_type();
|
||||
template < typename T >
|
||||
T&& uvalue::get_as_ref() && {
|
||||
return meta_hpp::get_as_ref<T>(std::move(*this));
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
const T& uvalue::get_as_ref() const & {
|
||||
return meta_hpp::get_as_ref<T>(*this);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
const T&& uvalue::get_as_ref() const && {
|
||||
// NOLINTNEXTLINE(*-move-const-arg)
|
||||
return meta_hpp::get_as_ref<T>(std::move(*this));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::can_get_as() & {
|
||||
return meta_hpp::can_get_as<T>(*this);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::can_get_as() && {
|
||||
return meta_hpp::can_get_as<T>(std::move(*this));
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::can_get_as() const & {
|
||||
return meta_hpp::can_get_as<T>(*this);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::can_get_as() const && {
|
||||
// NOLINTNEXTLINE(*-move-const-arg)
|
||||
return meta_hpp::can_get_as<T>(std::move(*this));
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::can_get_as_ref() & {
|
||||
return meta_hpp::can_get_as_ref<T>(*this);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::can_get_as_ref() && {
|
||||
return meta_hpp::can_get_as_ref<T>(std::move(*this));
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::can_get_as_ref() const & {
|
||||
return meta_hpp::can_get_as_ref<T>(*this);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::can_get_as_ref() const && {
|
||||
// NOLINTNEXTLINE(*-move-const-arg)
|
||||
return meta_hpp::can_get_as_ref<T>(std::move(*this));
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < typename T, detail::decay_value_kind V >
|
||||
[[nodiscard]] auto get_as(V&& value) -> T {
|
||||
using Tp = std::decay_t<T>;
|
||||
static_assert(std::is_constructible_v<T, detail::add_cvref_t<V&&, Tp>>);
|
||||
|
||||
const any_type& from_type = value.get_type();
|
||||
const any_type& to_type = resolve_type<Tp>();
|
||||
|
||||
if ( from_type == to_type ) {
|
||||
return static_cast<Tp*>(data());
|
||||
using to_ptr_t = detail::add_cv_t<V, Tp>*;
|
||||
auto to_ptr = static_cast<to_ptr_t>(value.data());
|
||||
return static_cast<T>(*to_ptr);
|
||||
}
|
||||
|
||||
if ( from_type.is_class() && to_type.is_class() ) {
|
||||
void* to_ptr = detail::pointer_upcast(data(), from_type.as_class(), to_type.as_class());
|
||||
return static_cast<Tp*>(to_ptr);
|
||||
const auto is_a = [](const any_type& base, const any_type& derived){
|
||||
return (base == derived)
|
||||
|| (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class()));
|
||||
};
|
||||
|
||||
if ( is_a(to_type, from_type) ) {
|
||||
const class_type& to_class = to_type.as_class();
|
||||
const class_type& from_class = from_type.as_class();
|
||||
|
||||
using to_ptr_t = detail::add_cv_t<V, Tp>*;
|
||||
auto to_ptr = static_cast<to_ptr_t>(detail::pointer_upcast(value.data(), from_class, to_class));
|
||||
return static_cast<T>(*to_ptr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
if constexpr ( std::is_pointer_v<T> ) {
|
||||
if ( to_type.is_pointer() && from_type.is_nullptr() ) {
|
||||
return static_cast<T>(nullptr);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
const std::decay_t<T>* uvalue::try_cast() const noexcept {
|
||||
if ( to_type.is_pointer() && from_type.is_pointer() ) {
|
||||
const pointer_type& to_type_ptr = to_type.as_pointer();
|
||||
const bool to_type_ptr_readonly = to_type_ptr.get_flags().has(pointer_flags::is_readonly);
|
||||
|
||||
const pointer_type& from_type_ptr = from_type.as_pointer();
|
||||
const bool from_type_ptr_readonly = from_type_ptr.get_flags().has(pointer_flags::is_readonly);
|
||||
|
||||
const any_type& to_data_type = to_type_ptr.get_data_type();
|
||||
const any_type& from_data_type = from_type_ptr.get_data_type();
|
||||
|
||||
if ( to_type_ptr_readonly >= from_type_ptr_readonly ) {
|
||||
using from_data_ptr_t = detail::add_cv_t<V, void*>*;
|
||||
auto from_data_ptr = static_cast<from_data_ptr_t>(value.data());
|
||||
|
||||
if ( to_data_type.is_void() || to_data_type == from_data_type ) {
|
||||
return static_cast<T>(*from_data_ptr);
|
||||
}
|
||||
|
||||
if ( is_a(to_data_type, from_data_type) ) {
|
||||
const class_type& to_data_class = to_data_type.as_class();
|
||||
const class_type& from_data_class = from_data_type.as_class();
|
||||
|
||||
void* to_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class);
|
||||
return static_cast<T>(to_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
detail::throw_exception_with("bad value cast");
|
||||
}
|
||||
|
||||
template < typename T, detail::decay_value_kind V >
|
||||
[[nodiscard]] auto get_as_ref(V&& value) -> detail::add_cvref_t<V&&, T> {
|
||||
static_assert(!std::is_reference_v<T>);
|
||||
return get_as<detail::add_cvref_t<V&&, T>>(std::forward<V>(value));
|
||||
}
|
||||
|
||||
template < typename T, detail::decay_value_kind V >
|
||||
[[nodiscard]] bool can_get_as(V&& value) noexcept {
|
||||
using Tp = std::decay_t<T>;
|
||||
static_assert(std::is_constructible_v<T, detail::add_cvref_t<V&&, Tp>>);
|
||||
|
||||
const any_type& from_type = get_type();
|
||||
const any_type& from_type = value.get_type();
|
||||
const any_type& to_type = resolve_type<Tp>();
|
||||
|
||||
if ( from_type == to_type ) {
|
||||
return static_cast<const Tp*>(data());
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( from_type.is_class() && to_type.is_class() ) {
|
||||
const void* to_ptr = detail::pointer_upcast(data(), from_type.as_class(), to_type.as_class());
|
||||
return static_cast<const Tp*>(to_ptr);
|
||||
const auto is_a = [](const any_type& base, const any_type& derived){
|
||||
return (base == derived)
|
||||
|| (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class()));
|
||||
};
|
||||
|
||||
if ( is_a(to_type, from_type) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
if constexpr ( std::is_pointer_v<T> ) {
|
||||
if ( to_type.is_pointer() && from_type.is_nullptr() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( to_type.is_pointer() && from_type.is_pointer() ) {
|
||||
const pointer_type& to_type_ptr = to_type.as_pointer();
|
||||
const bool to_type_ptr_readonly = to_type_ptr.get_flags().has(pointer_flags::is_readonly);
|
||||
|
||||
const pointer_type& from_type_ptr = from_type.as_pointer();
|
||||
const bool from_type_ptr_readonly = from_type_ptr.get_flags().has(pointer_flags::is_readonly);
|
||||
|
||||
const any_type& to_data_type = to_type_ptr.get_data_type();
|
||||
const any_type& from_data_type = from_type_ptr.get_data_type();
|
||||
|
||||
if ( to_type_ptr_readonly >= from_type_ptr_readonly ) {
|
||||
if ( to_data_type.is_void() || is_a(to_data_type, from_data_type) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template < typename T, detail::decay_value_kind V >
|
||||
[[nodiscard]] bool can_get_as_ref(V&& value) noexcept {
|
||||
static_assert(!std::is_reference_v<T>);
|
||||
return can_get_as<detail::add_cvref_t<V&&, T>>(std::forward<V>(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,7 +551,7 @@ namespace meta_hpp
|
||||
const any_type& l_type = l.get_type();
|
||||
const any_type& r_type = resolve_type<T>();
|
||||
|
||||
return (l_type < r_type) || (l_type == r_type && l.cast<T>() < r);
|
||||
return (l_type < r_type) || (l_type == r_type && l.get_as_ref<T>() < r);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -432,7 +563,7 @@ namespace meta_hpp
|
||||
const any_type& l_type = resolve_type<T>();
|
||||
const any_type& r_type = r.get_type();
|
||||
|
||||
return (l_type < r_type) || (l_type == r_type && l < r.cast<T>());
|
||||
return (l_type < r_type) || (l_type == r_type && l < r.get_as_ref<T>());
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool operator<(const uvalue& l, const uvalue& r) {
|
||||
@@ -462,7 +593,7 @@ namespace meta_hpp
|
||||
const any_type& l_type = l.get_type();
|
||||
const any_type& r_type = resolve_type<T>();
|
||||
|
||||
return l_type == r_type && l.cast<T>() == r;
|
||||
return l_type == r_type && l.get_as_ref<T>() == r;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -474,7 +605,7 @@ namespace meta_hpp
|
||||
const any_type& l_type = resolve_type<T>();
|
||||
const any_type& r_type = r.get_type();
|
||||
|
||||
return l_type == r_type && l == r.cast<T>();
|
||||
return l_type == r_type && l == r.get_as_ref<T>();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool operator==(const uvalue& l, const uvalue& r) {
|
||||
|
||||
@@ -253,7 +253,7 @@ TEST_CASE("meta/meta_features/diamond") {
|
||||
CHECK_FALSE(a_inst.can_cast_to<D&>());
|
||||
CHECK_FALSE(a_inst.can_cast_to<E&>());
|
||||
|
||||
CHECK(&a_inst.cast<A&>() == a_val.try_cast<A>());
|
||||
CHECK(&a_inst.cast<A&>() == &a_val.get_as_ref<A>());
|
||||
}
|
||||
{
|
||||
meta::uvalue b_val{B{}};
|
||||
@@ -265,10 +265,10 @@ TEST_CASE("meta/meta_features/diamond") {
|
||||
CHECK_FALSE(b_inst.can_cast_to<D&>());
|
||||
CHECK_FALSE(b_inst.can_cast_to<E&>());
|
||||
|
||||
CHECK(&b_inst.cast<A&>() == b_val.try_cast<B>());
|
||||
CHECK(&b_inst.cast<B&>() == b_val.try_cast<B>());
|
||||
CHECK(&b_inst.cast<A&>() == &b_val.get_as_ref<B>());
|
||||
CHECK(&b_inst.cast<B&>() == &b_val.get_as_ref<B>());
|
||||
|
||||
CHECK(&b_inst.cast<A&>() == b_val.try_cast<B>());
|
||||
CHECK(&b_inst.cast<A&>() == &b_val.get_as_ref<B>());
|
||||
}
|
||||
{
|
||||
meta::uvalue c_val{C{}};
|
||||
@@ -280,8 +280,8 @@ TEST_CASE("meta/meta_features/diamond") {
|
||||
CHECK_FALSE(c_inst.can_cast_to<D&>());
|
||||
CHECK_FALSE(c_inst.can_cast_to<E&>());
|
||||
|
||||
CHECK(&c_inst.cast<A&>() == c_val.try_cast<C>());
|
||||
CHECK(&c_inst.cast<C&>() == c_val.try_cast<C>());
|
||||
CHECK(&c_inst.cast<A&>() == &c_val.get_as_ref<C>());
|
||||
CHECK(&c_inst.cast<C&>() == &c_val.get_as_ref<C>());
|
||||
}
|
||||
{
|
||||
meta::uvalue d_val{D{}};
|
||||
@@ -293,15 +293,15 @@ TEST_CASE("meta/meta_features/diamond") {
|
||||
CHECK(d_inst.can_cast_to<D&>());
|
||||
CHECK_FALSE(d_inst.can_cast_to<E&>());
|
||||
|
||||
CHECK(&d_inst.cast<A&>() == d_val.try_cast<D>());
|
||||
CHECK(&d_inst.cast<B&>() == d_val.try_cast<D>());
|
||||
CHECK(&d_inst.cast<C&>() == d_val.try_cast<D>());
|
||||
CHECK(&d_inst.cast<D&>() == d_val.try_cast<D>());
|
||||
CHECK(&d_inst.cast<A&>() == &d_val.get_as_ref<D>());
|
||||
CHECK(&d_inst.cast<B&>() == &d_val.get_as_ref<D>());
|
||||
CHECK(&d_inst.cast<C&>() == &d_val.get_as_ref<D>());
|
||||
CHECK(&d_inst.cast<D&>() == &d_val.get_as_ref<D>());
|
||||
|
||||
CHECK(&d_inst.cast<A&>() == d_val.try_cast<D>());
|
||||
CHECK(&d_inst.cast<B&>() == d_val.try_cast<D>());
|
||||
CHECK(&d_inst.cast<C&>() == d_val.try_cast<D>());
|
||||
CHECK(&d_inst.cast<D&>() == d_val.try_cast<D>());
|
||||
CHECK(&d_inst.cast<A&>() == &d_val.get_as_ref<D>());
|
||||
CHECK(&d_inst.cast<B&>() == &d_val.get_as_ref<D>());
|
||||
CHECK(&d_inst.cast<C&>() == &d_val.get_as_ref<D>());
|
||||
CHECK(&d_inst.cast<D&>() == &d_val.get_as_ref<D>());
|
||||
}
|
||||
{
|
||||
meta::uvalue e_val{E{}};
|
||||
@@ -313,7 +313,7 @@ TEST_CASE("meta/meta_features/diamond") {
|
||||
CHECK_FALSE(e_inst.can_cast_to<D&>());
|
||||
CHECK(e_inst.can_cast_to<E&>());
|
||||
|
||||
CHECK(&e_inst.cast<E&>() == e_val.try_cast<E>());
|
||||
CHECK(&e_inst.cast<E&>() == &e_val.get_as_ref<E>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ TEST_CASE("meta/meta_states/ctor") {
|
||||
CHECK_FALSE(clazz_type.create(10, 20));
|
||||
const meta::uvalue v = clazz_type.create(10);
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz<1>>());
|
||||
CHECK(v.cast<clazz<1>>().i == 10);
|
||||
CHECK(v.get_as_ref<clazz<1>>().i == 10);
|
||||
|
||||
CHECK(clazz_type.destroy(nullptr));
|
||||
CHECK(clazz_type.destroy(meta::uvalue{nullptr}));
|
||||
@@ -112,7 +112,7 @@ TEST_CASE("meta/meta_states/ctor") {
|
||||
CHECK_FALSE(clazz_type.create(10, 20));
|
||||
const meta::uvalue v = clazz_type.create(20);
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz<2>*>());
|
||||
CHECK(v.cast<clazz<2>*>()->i == 20);
|
||||
CHECK(v.get_as_ref<clazz<2>*>()->i == 20);
|
||||
CHECK(clazz_type.destroy(v));
|
||||
|
||||
CHECK(clazz_type.destroy(nullptr));
|
||||
@@ -133,7 +133,7 @@ TEST_CASE("meta/meta_states/ctor") {
|
||||
CHECK_FALSE(clazz_type.create(10, 20));
|
||||
const meta::uvalue v = clazz_type.create(30);
|
||||
CHECK(v.get_type() == meta::resolve_type<std::shared_ptr<clazz<3>>>());
|
||||
CHECK(v.cast<std::shared_ptr<clazz<3>>>()->i == 30);
|
||||
CHECK(v.get_as_ref<std::shared_ptr<clazz<3>>>()->i == 30);
|
||||
|
||||
CHECK(clazz_type.destroy(nullptr));
|
||||
CHECK(clazz_type.destroy(meta::uvalue{nullptr}));
|
||||
|
||||
@@ -247,14 +247,14 @@ TEST_CASE("meta/meta_states/member") {
|
||||
clazz_1 v;
|
||||
using ref_t = std::reference_wrapper<std::unique_ptr<int>>;
|
||||
CHECK(vm.get(v).get_type() == meta::resolve_type<ref_t>());
|
||||
CHECK(vm.get(v).try_cast<ref_t>()->get() == v.unique_int_member);
|
||||
CHECK(vm.get(v).get_as_ref<ref_t>().get() == v.unique_int_member);
|
||||
}
|
||||
|
||||
{
|
||||
const clazz_1 v;
|
||||
using ref_t = std::reference_wrapper<const std::unique_ptr<int>>;
|
||||
CHECK(vm.get(v).get_type() == meta::resolve_type<ref_t>());
|
||||
CHECK(vm.get(v).try_cast<ref_t>()->get() == v.unique_int_member);
|
||||
CHECK(vm.get(v).get_as_ref<ref_t>().get() == v.unique_int_member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ TEST_CASE("meta/meta_states/variable") {
|
||||
|
||||
using ref_t = std::reference_wrapper<std::unique_ptr<int>>;
|
||||
CHECK(vm.get().get_type() == meta::resolve_type<ref_t>());
|
||||
CHECK(vm.get().try_cast<ref_t>()->get() == clazz_1::unique_int_variable);
|
||||
CHECK(vm.get().get_as_ref<ref_t>().get() == clazz_1::unique_int_variable);
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(13);
|
||||
@@ -222,7 +222,7 @@ TEST_CASE("meta/meta_states/variable") {
|
||||
|
||||
using ref_t = std::reference_wrapper<const std::unique_ptr<int>>;
|
||||
CHECK(vm.get().get_type() == meta::resolve_type<ref_t>());
|
||||
CHECK(vm.get().try_cast<ref_t>()->get() == clazz_1::const_unique_int_variable);
|
||||
CHECK(vm.get().get_as_ref<ref_t>().get() == clazz_1::const_unique_int_variable);
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(12);
|
||||
|
||||
@@ -154,7 +154,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") {
|
||||
meta::uvalue v2{std::move(v1)};
|
||||
|
||||
CHECK_FALSE(v1);
|
||||
CHECK(v2.cast<ivec2>().x == 1);
|
||||
CHECK(v2.get_as_ref<ivec2>().x == 1);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 2);
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
@@ -170,8 +170,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") {
|
||||
meta::uvalue v1{ivec2{1,2}};
|
||||
meta::uvalue v2{std::as_const(v1)};
|
||||
|
||||
CHECK(v1.cast<ivec2>().x == 1);
|
||||
CHECK(v2.cast<ivec2>().y == 2);
|
||||
CHECK(v1.get_as_ref<ivec2>().x == 1);
|
||||
CHECK(v2.get_as_ref<ivec2>().y == 2);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 1);
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
@@ -191,8 +191,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") {
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.cast<ivec2>().x == 3);
|
||||
CHECK(v2.cast<ivec2>().x == 1);
|
||||
CHECK(v1.get_as_ref<ivec2>().x == 3);
|
||||
CHECK(v2.get_as_ref<ivec2>().x == 1);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 5);
|
||||
CHECK(ivec2::move_constructor_counter == 5);
|
||||
@@ -241,7 +241,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") {
|
||||
meta::uvalue v2{std::move(v1)};
|
||||
|
||||
CHECK_FALSE(v1);
|
||||
CHECK(v2.cast<ivec2_big>().x == 1);
|
||||
CHECK(v2.get_as_ref<ivec2_big>().x == 1);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
@@ -257,8 +257,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") {
|
||||
meta::uvalue v1{ivec2_big{1,2}};
|
||||
meta::uvalue v2{std::as_const(v1)};
|
||||
|
||||
CHECK(v1.cast<ivec2_big>().x == 1);
|
||||
CHECK(v2.cast<ivec2_big>().y == 2);
|
||||
CHECK(v1.get_as_ref<ivec2_big>().x == 1);
|
||||
CHECK(v2.get_as_ref<ivec2_big>().y == 2);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
@@ -278,8 +278,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") {
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.cast<ivec2_big>().x == 3);
|
||||
CHECK(v2.cast<ivec2_big>().x == 1);
|
||||
CHECK(v1.get_as_ref<ivec2_big>().x == 3);
|
||||
CHECK(v2.get_as_ref<ivec2_big>().x == 1);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 2);
|
||||
CHECK(ivec2_big::move_constructor_counter == 2);
|
||||
@@ -312,7 +312,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") {
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.cast<ivec2>().x == 1);
|
||||
CHECK(v1.get_as_ref<ivec2>().x == 1);
|
||||
CHECK_FALSE(v2);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 2);
|
||||
@@ -321,7 +321,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") {
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK_FALSE(v1);
|
||||
CHECK(v2.cast<ivec2>().y == 2);
|
||||
CHECK(v2.get_as_ref<ivec2>().y == 2);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 3);
|
||||
CHECK(ivec2::move_constructor_counter == 3);
|
||||
@@ -343,7 +343,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") {
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.cast<ivec2_big>().x == 3);
|
||||
CHECK(v1.get_as_ref<ivec2_big>().x == 3);
|
||||
CHECK_FALSE(v2);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
@@ -352,7 +352,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") {
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK_FALSE(v1);
|
||||
CHECK(v2.cast<ivec2_big>().y == 4);
|
||||
CHECK(v2.get_as_ref<ivec2_big>().y == 4);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
@@ -378,8 +378,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") {
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.cast<ivec2_big>().x == 3);
|
||||
CHECK(v2.cast<ivec2>().x == 1);
|
||||
CHECK(v1.get_as_ref<ivec2_big>().x == 3);
|
||||
CHECK(v2.get_as_ref<ivec2>().x == 1);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 2);
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
@@ -390,8 +390,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") {
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.cast<ivec2>().y == 2);
|
||||
CHECK(v2.cast<ivec2_big>().y == 4);
|
||||
CHECK(v1.get_as_ref<ivec2>().y == 2);
|
||||
CHECK(v2.get_as_ref<ivec2_big>().y == 4);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 3);
|
||||
CHECK(ivec2::move_constructor_counter == 3);
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct base0 {
|
||||
int i{21};
|
||||
};
|
||||
|
||||
struct base1 : virtual base0 {
|
||||
int j{42};
|
||||
};
|
||||
|
||||
struct base2 : virtual base0 {
|
||||
int k{84};
|
||||
};
|
||||
|
||||
struct derived : base1, base2 {
|
||||
int l{168};
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value3") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<base0>();
|
||||
|
||||
meta::class_<base1>()
|
||||
.base_<base0>();
|
||||
|
||||
meta::class_<base2>()
|
||||
.base_<base0>();
|
||||
|
||||
meta::class_<derived>()
|
||||
.base_<base1>()
|
||||
.base_<base2>();
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value3/cast") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("derived") {
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(v.get_type() == meta::resolve_type<derived>());
|
||||
|
||||
CHECK(v.cast<base0>().i == 21);
|
||||
CHECK(v.cast<base1>().j == 42);
|
||||
CHECK(v.cast<base2>().k == 84);
|
||||
CHECK(v.cast<derived>().l == 168);
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(v.get_type() == meta::resolve_type<derived>());
|
||||
|
||||
CHECK(v.cast<base0>().i == 21);
|
||||
CHECK(v.cast<base1>().j == 42);
|
||||
CHECK(v.cast<base2>().k == 84);
|
||||
CHECK(v.cast<derived>().l == 168);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value3/try_cast") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("derived") {
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(v.get_type() == meta::resolve_type<derived>());
|
||||
|
||||
CHECK((v.try_cast<base0>() && v.try_cast<base0>()->i == 21));
|
||||
CHECK((v.try_cast<base1>() && v.try_cast<base1>()->j == 42));
|
||||
CHECK((v.try_cast<base2>() && v.try_cast<base2>()->k == 84));
|
||||
CHECK((v.try_cast<derived>() && v.try_cast<derived>()->l == 168));
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(v.get_type() == meta::resolve_type<derived>());
|
||||
|
||||
CHECK((v.try_cast<base0>() && v.try_cast<base0>()->i == 21));
|
||||
CHECK((v.try_cast<base1>() && v.try_cast<base1>()->j == 42));
|
||||
CHECK((v.try_cast<base2>() && v.try_cast<base2>()->k == 84));
|
||||
CHECK((v.try_cast<derived>() && v.try_cast<derived>()->l == 168));
|
||||
}
|
||||
}
|
||||
}
|
||||
370
untests/meta_utilities/value4_tests.cpp
Normal file
370
untests/meta_utilities/value4_tests.cpp
Normal file
@@ -0,0 +1,370 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct base0 {
|
||||
int i{21};
|
||||
};
|
||||
|
||||
struct base1 : virtual base0 {
|
||||
int j{42};
|
||||
};
|
||||
|
||||
struct base2 : virtual base0 {
|
||||
int k{84};
|
||||
};
|
||||
|
||||
struct derived : base1, base2 {
|
||||
int l{168};
|
||||
};
|
||||
|
||||
struct derived2 : base1, base2 {
|
||||
int m{336};
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value4") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<base0>();
|
||||
|
||||
meta::class_<base1>()
|
||||
.base_<base0>();
|
||||
|
||||
meta::class_<base2>()
|
||||
.base_<base0>();
|
||||
|
||||
meta::class_<derived>()
|
||||
.base_<base1>()
|
||||
.base_<base2>();
|
||||
|
||||
meta::class_<derived2>()
|
||||
.base_<base1>()
|
||||
.base_<base2>();
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value4/get_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("from ref") {
|
||||
{
|
||||
derived d{};
|
||||
CHECK(meta::uvalue{d}.get_type() == meta::resolve_type<derived>());
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
CHECK(meta::uvalue{d}.get_type() == meta::resolve_type<derived>());
|
||||
}
|
||||
{
|
||||
derived d{};
|
||||
CHECK(meta::uvalue{std::move(d)}.get_type() == meta::resolve_type<derived>());
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
CHECK(meta::uvalue{std::move(d)}.get_type() == meta::resolve_type<derived>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("from ptr") {
|
||||
{
|
||||
derived d{};
|
||||
derived* pd = &d;
|
||||
CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type<derived*>());
|
||||
}
|
||||
{
|
||||
derived d{};
|
||||
derived* const pd = &d;
|
||||
CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type<derived*>());
|
||||
}
|
||||
{
|
||||
derived d{};
|
||||
const derived* pd = &d;
|
||||
CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type<const derived*>());
|
||||
}
|
||||
{
|
||||
derived d{};
|
||||
const derived* const pd = &d;
|
||||
CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type<const derived*>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value4/get_as_ref") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<derived>(std::declval<meta::uvalue&>())), derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<derived>(std::declval<meta::uvalue&&>())), derived&&>);
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<derived>(std::declval<const meta::uvalue&>())), const derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<derived>(std::declval<const meta::uvalue&&>())), const derived&&>);
|
||||
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<const derived>(std::declval<meta::uvalue&>())), const derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<const derived>(std::declval<meta::uvalue&&>())), const derived&&>);
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<const derived>(std::declval<const meta::uvalue&>())), const derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<const derived>(std::declval<const meta::uvalue&&>())), const derived&&>);
|
||||
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<volatile derived>(std::declval<meta::uvalue&>())), volatile derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<volatile derived>(std::declval<meta::uvalue&&>())), volatile derived&&>);
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<volatile derived>(std::declval<const meta::uvalue&>())), const volatile derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as_ref<volatile derived>(std::declval<const meta::uvalue&&>())), const volatile derived&&>);
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value4/get_as") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
static_assert(std::is_same_v<decltype(get_as<derived>(std::declval<meta::uvalue&>())), derived>);
|
||||
static_assert(std::is_same_v<decltype(get_as<derived>(std::declval<meta::uvalue&&>())), derived>);
|
||||
static_assert(std::is_same_v<decltype(get_as<derived>(std::declval<const meta::uvalue&>())), derived>);
|
||||
static_assert(std::is_same_v<decltype(get_as<derived>(std::declval<const meta::uvalue&&>())), derived>);
|
||||
|
||||
static_assert(std::is_same_v<decltype(get_as<derived&>(std::declval<meta::uvalue&>())), derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as<derived&>(std::declval<meta::uvalue&&>())), derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as<derived&>(std::declval<const meta::uvalue&>())), derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as<derived&>(std::declval<const meta::uvalue&&>())), derived&>);
|
||||
|
||||
static_assert(std::is_same_v<decltype(get_as<const derived&>(std::declval<meta::uvalue&>())), const derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as<const derived&>(std::declval<meta::uvalue&&>())), const derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as<const derived&>(std::declval<const meta::uvalue&>())), const derived&>);
|
||||
static_assert(std::is_same_v<decltype(get_as<const derived&>(std::declval<const meta::uvalue&&>())), const derived&>);
|
||||
|
||||
SUBCASE("derived to derived") {
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(get_as<derived>(v).l == 168);
|
||||
CHECK(get_as<derived&>(v).l == 168);
|
||||
// CHECK(get_as<derived&&>(v).l == 168);
|
||||
CHECK(get_as<const derived&>(v).l == 168);
|
||||
// CHECK(get_as<const derived&&>(v).l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = get_as<derived2>(v));
|
||||
CHECK_THROWS(std::ignore = get_as<derived2&>(v));
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2&>(v));
|
||||
}
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(get_as<derived>(std::move(v)).l == 168);
|
||||
// CHECK(get_as<derived&>(std::move(v)).l == 168);
|
||||
CHECK(get_as<derived&&>(std::move(v)).l == 168);
|
||||
CHECK(get_as<const derived&>(std::move(v)).l == 168);
|
||||
CHECK(get_as<const derived&&>(std::move(v)).l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = get_as<derived2>(std::move(v)));
|
||||
CHECK_THROWS(std::ignore = get_as<derived2&&>(std::move(v)));
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2&>(std::move(v)));
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2&&>(std::move(v)));
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(get_as<derived>(v).l == 168);
|
||||
// CHECK(get_as<derived&>(v).l == 168);
|
||||
// CHECK(get_as<derived&&>(v).l == 168);
|
||||
CHECK(get_as<const derived&>(v).l == 168);
|
||||
// CHECK(get_as<const derived&&>(v).l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = get_as<derived2>(v));
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2&>(v));
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(get_as<derived>(std::move(v)).l == 168);
|
||||
// CHECK(get_as<derived&>(std::move(v)).l == 168);
|
||||
// CHECK(get_as<derived&&>(std::move(v)).l == 168);
|
||||
CHECK(get_as<const derived&>(std::move(v)).l == 168);
|
||||
CHECK(get_as<const derived&&>(std::move(v)).l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = get_as<derived2>(std::move(v)));
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2&>(std::move(v)));
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2&&>(std::move(v)));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("derived to base") {
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(get_as<base2>(v).k == 84);
|
||||
CHECK(get_as<base2&>(v).k == 84);
|
||||
// CHECK(get_as<base2&&>(v).k == 84);
|
||||
CHECK(get_as<const base2&>(v).k == 84);
|
||||
// CHECK(get_as<const base2&&>(v).k == 84);
|
||||
}
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(get_as<base2>(std::move(v)).k == 84);
|
||||
// CHECK(get_as<base2&>(std::move(v)).k == 84);
|
||||
CHECK(get_as<base2&&>(std::move(v)).k == 84);
|
||||
CHECK(get_as<const base2&>(std::move(v)).k == 84);
|
||||
CHECK(get_as<const base2&&>(std::move(v)).k == 84);
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(get_as<base2>(v).k == 84);
|
||||
// CHECK(get_as<base2&>(v).k == 84);
|
||||
// CHECK(get_as<base2&&>(v).k == 84);
|
||||
CHECK(get_as<const base2&>(v).k == 84);
|
||||
// CHECK(get_as<const base2&&>(v).k == 84);
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(get_as<base2>(std::move(v)).k == 84);
|
||||
// CHECK(get_as<base2&>(std::move(v)).k == 84);
|
||||
// CHECK(get_as<base2&&>(std::move(v)).k == 84);
|
||||
CHECK(get_as<const base2&>(std::move(v)).k == 84);
|
||||
CHECK(get_as<const base2&&>(std::move(v)).k == 84);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("voidptr") {
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(get_as<void*>(v) == &d);
|
||||
CHECK(get_as<const void*>(v) == &d);
|
||||
CHECK(get_as<void*>(std::move(v)) == &d);
|
||||
CHECK(get_as<const void*>(std::move(v)) == &d);
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK_THROWS(std::ignore = get_as<void*>(v));
|
||||
CHECK(get_as<const void*>(v) == &d);
|
||||
CHECK_THROWS(std::ignore = get_as<void*>(std::move(v)));
|
||||
CHECK(get_as<const void*>(std::move(v)) == &d);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("nullptr") {
|
||||
{
|
||||
meta::uvalue v{nullptr};
|
||||
CHECK(get_as<void*>(v) == nullptr);
|
||||
CHECK(get_as<const void*>(v) == nullptr);
|
||||
CHECK(get_as<derived*>(v) == nullptr);
|
||||
CHECK(get_as<const derived*>(v) == nullptr);
|
||||
CHECK(get_as<void*>(std::move(v)) == nullptr);
|
||||
CHECK(get_as<const void*>(std::move(v)) == nullptr);
|
||||
CHECK(get_as<derived*>(std::move(v)) == nullptr);
|
||||
CHECK(get_as<const derived*>(std::move(v)) == nullptr);
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{nullptr};
|
||||
CHECK(get_as<void*>(v) == nullptr);
|
||||
CHECK(get_as<const void*>(v) == nullptr);
|
||||
CHECK(get_as<derived*>(v) == nullptr);
|
||||
CHECK(get_as<const derived*>(v) == nullptr);
|
||||
CHECK(get_as<void*>(std::move(v)) == nullptr);
|
||||
CHECK(get_as<const void*>(std::move(v)) == nullptr);
|
||||
CHECK(get_as<derived*>(std::move(v)) == nullptr);
|
||||
CHECK(get_as<const derived*>(std::move(v)) == nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("derived* to derived*") {
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(get_as<derived*>(v)->l == 168);
|
||||
CHECK(get_as<const derived*>(v)->l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = get_as<derived2*>(v));
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2*>(v));
|
||||
}
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(get_as<derived*>(std::move(v))->l == 168);
|
||||
CHECK(get_as<const derived*>(std::move(v))->l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = get_as<derived2*>(std::move(v)));
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2*>(std::move(v)));
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(get_as<const derived*>(v)->l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2*>(v));
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(get_as<const derived*>(std::move(v))->l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = get_as<const derived2*>(std::move(v)));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("derived* to base*") {
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(get_as<base2*>(v)->k == 84);
|
||||
CHECK(get_as<const base2*>(v)->k == 84);
|
||||
}
|
||||
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK_THROWS(std::ignore = get_as<base2*>(v));
|
||||
CHECK(get_as<const base2*>(v)->k == 84);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value4/can_get_as") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("derived to derived") {
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(can_get_as<derived>(v));
|
||||
CHECK(can_get_as<derived&>(v));
|
||||
// CHECK_FALSE(can_get_as<derived&&>(v));
|
||||
CHECK(can_get_as<const derived&>(v));
|
||||
// CHECK_FALSE(can_get_as<const derived&&>(v));
|
||||
|
||||
CHECK_FALSE(can_get_as<derived2>(v));
|
||||
CHECK_FALSE(can_get_as<derived2&>(v));
|
||||
CHECK_FALSE(can_get_as<const derived2&>(v));
|
||||
}
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(can_get_as<derived>(std::move(v)));
|
||||
// CHECK_FALSE(can_get_as<derived&>(std::move(v)));
|
||||
CHECK(can_get_as<derived&&>(std::move(v)));
|
||||
CHECK(can_get_as<const derived&>(std::move(v)));
|
||||
CHECK(can_get_as<const derived&&>(std::move(v)));
|
||||
|
||||
CHECK_FALSE(can_get_as<derived2>(std::move(v)));
|
||||
CHECK_FALSE(can_get_as<derived2&&>(std::move(v)));
|
||||
CHECK_FALSE(can_get_as<const derived2&>(std::move(v)));
|
||||
CHECK_FALSE(can_get_as<const derived2&&>(std::move(v)));
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(can_get_as<derived>(v));
|
||||
// CHECK_FALSE(can_get_as<derived&>(v));
|
||||
// CHECK_FALSE(can_get_as<derived&&>(v));
|
||||
CHECK(can_get_as<const derived&>(v));
|
||||
// CHECK_FALSE(can_get_as<const derived&&>(v));
|
||||
|
||||
CHECK_FALSE(can_get_as<derived2>(v));
|
||||
CHECK_FALSE(can_get_as<const derived2&>(v));
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(can_get_as<derived>(std::move(v)));
|
||||
// CHECK_FALSE(can_get_as<derived&>(std::move(v)));
|
||||
// CHECK_FALSE(can_get_as<derived&&>(std::move(v)));
|
||||
CHECK(can_get_as<const derived&>(std::move(v)));
|
||||
CHECK(can_get_as<const derived&&>(std::move(v)));
|
||||
|
||||
CHECK_FALSE(can_get_as<derived2>(std::move(v)));
|
||||
CHECK_FALSE(can_get_as<const derived2&>(std::move(v)));
|
||||
CHECK_FALSE(can_get_as<const derived2&&>(std::move(v)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,28 +105,19 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
|
||||
SUBCASE("cast types") {
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<meta::uvalue&>().cast<ivec2>()),
|
||||
decltype(std::declval<meta::uvalue&>().get_as_ref<ivec2>()),
|
||||
ivec2&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<meta::uvalue&&>().cast<ivec2>()),
|
||||
decltype(std::declval<meta::uvalue&&>().get_as_ref<ivec2>()),
|
||||
ivec2&&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const meta::uvalue&>().cast<ivec2>()),
|
||||
decltype(std::declval<const meta::uvalue&>().get_as_ref<ivec2>()),
|
||||
const ivec2&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const meta::uvalue&&>().cast<ivec2>()),
|
||||
decltype(std::declval<const meta::uvalue&&>().get_as_ref<ivec2>()),
|
||||
const ivec2&&>);
|
||||
}
|
||||
|
||||
SUBCASE("try_cast types") {
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<meta::uvalue>().try_cast<ivec2>()),
|
||||
ivec2*>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const meta::uvalue>().try_cast<ivec2>()),
|
||||
const ivec2*>);
|
||||
}
|
||||
|
||||
SUBCASE("ivec2{}") {
|
||||
{
|
||||
meta::uvalue val{};
|
||||
@@ -142,13 +133,13 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK_FALSE(*val);
|
||||
CHECK_FALSE(val[0]);
|
||||
|
||||
CHECK(val.try_cast<ivec2>() == nullptr);
|
||||
CHECK(std::as_const(val).try_cast<ivec2>() == nullptr);
|
||||
CHECK_FALSE(val.can_get_as_ref<ivec2>());
|
||||
CHECK_FALSE(std::as_const(val).can_get_as_ref<ivec2>());
|
||||
|
||||
CHECK_THROWS(std::ignore = val.cast<int>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).cast<int>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).cast<int>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast<int>());
|
||||
CHECK_THROWS(std::ignore = val.get_as_ref<int>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as_ref<int>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as_ref<int>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as_ref<int>());
|
||||
}
|
||||
|
||||
{
|
||||
@@ -204,20 +195,20 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(val == ivec2{1,2});
|
||||
CHECK(val == meta::uvalue{ivec2{1,2}});
|
||||
|
||||
CHECK(val.cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(val.get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
|
||||
CHECK_THROWS(std::ignore = val.cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = val.get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as_ref<ivec3>());
|
||||
|
||||
CHECK(*val.try_cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(*std::as_const(val).try_cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(val.try_cast<ivec3>() == nullptr);
|
||||
CHECK(std::as_const(val).try_cast<ivec3>() == nullptr);
|
||||
CHECK(val.get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK_FALSE(val.can_get_as_ref<ivec3>());
|
||||
CHECK_FALSE(std::as_const(val).can_get_as_ref<ivec3>());
|
||||
}
|
||||
|
||||
SUBCASE("const ivec2&") {
|
||||
@@ -238,20 +229,20 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(val == ivec2{1,2});
|
||||
CHECK(val == meta::uvalue{ivec2{1,2}});
|
||||
|
||||
CHECK(val.cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(val.get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
|
||||
CHECK_THROWS(std::ignore = val.cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = val.get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as_ref<ivec3>());
|
||||
|
||||
CHECK(*val.try_cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(*std::as_const(val).try_cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(val.try_cast<ivec3>() == nullptr);
|
||||
CHECK(std::as_const(val).try_cast<ivec3>() == nullptr);
|
||||
CHECK(val.get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK_FALSE(val.can_get_as_ref<ivec3>());
|
||||
CHECK_FALSE(std::as_const(val).can_get_as_ref<ivec3>());
|
||||
}
|
||||
|
||||
SUBCASE("ivec2&&") {
|
||||
@@ -266,20 +257,20 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(val == ivec2{1,2});
|
||||
CHECK(val == meta::uvalue{ivec2{1,2}});
|
||||
|
||||
CHECK(val.cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(val.get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
|
||||
CHECK_THROWS(std::ignore = val.cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = val.get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as_ref<ivec3>());
|
||||
|
||||
CHECK(*val.try_cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(*std::as_const(val).try_cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(val.try_cast<ivec3>() == nullptr);
|
||||
CHECK(std::as_const(val).try_cast<ivec3>() == nullptr);
|
||||
CHECK(val.get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK_FALSE(val.can_get_as_ref<ivec3>());
|
||||
CHECK_FALSE(std::as_const(val).can_get_as_ref<ivec3>());
|
||||
}
|
||||
|
||||
SUBCASE("const ivec2&&") {
|
||||
@@ -294,20 +285,20 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(val == ivec2{1,2});
|
||||
CHECK(val == meta::uvalue{ivec2{1,2}});
|
||||
|
||||
CHECK(val.cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(val.get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
|
||||
CHECK_THROWS(std::ignore = val.cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast<ivec3>());
|
||||
CHECK_THROWS(std::ignore = val.get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as_ref<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as_ref<ivec3>());
|
||||
|
||||
CHECK(*val.try_cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(*std::as_const(val).try_cast<ivec2>() == ivec2{1,2});
|
||||
CHECK(val.try_cast<ivec3>() == nullptr);
|
||||
CHECK(std::as_const(val).try_cast<ivec3>() == nullptr);
|
||||
CHECK(val.get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as_ref<ivec2>() == ivec2{1,2});
|
||||
CHECK_FALSE(val.can_get_as_ref<ivec3>());
|
||||
CHECK_FALSE(std::as_const(val).can_get_as_ref<ivec3>());
|
||||
}
|
||||
|
||||
SUBCASE("value(value&&)") {
|
||||
@@ -482,7 +473,7 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
const int* const pi = &i;
|
||||
const meta::uvalue v{*meta::uvalue{&pi}};
|
||||
CHECK(v.get_type() == meta::resolve_type<const int*>() );
|
||||
CHECK(v.cast<const int*>() == pi);
|
||||
CHECK(v.get_as_ref<const int*>() == pi);
|
||||
}
|
||||
{
|
||||
int i{42};
|
||||
@@ -584,8 +575,7 @@ TEST_CASE("meta/meta_utilities/value/functions") {
|
||||
{
|
||||
const meta::uvalue v{&ivec2::add};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2&(ivec2::*)(const ivec2&)>());
|
||||
CHECK((ivec2{1,2}.*(v.cast<decltype(&ivec2::add)>()))(ivec2{3,4}) == ivec2(4,6));
|
||||
CHECK((ivec2{1,2}.*(*v.try_cast<decltype(&ivec2::add)>()))(ivec2{3,4}) == ivec2(4,6));
|
||||
CHECK((ivec2{1,2}.*(v.get_as_ref<decltype(&ivec2::add)>()))(ivec2{3,4}) == ivec2(4,6));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,14 +583,12 @@ TEST_CASE("meta/meta_utilities/value/functions") {
|
||||
{
|
||||
const meta::uvalue v{iadd2};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2(*)(ivec2, ivec2)>());
|
||||
CHECK((v.cast<decltype(iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
CHECK((*v.try_cast<decltype(iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
CHECK((v.get_as_ref<decltype(&iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{&iadd2};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2(*)(ivec2, ivec2)>());
|
||||
CHECK((v.cast<decltype(&iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
CHECK((*v.try_cast<decltype(&iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
CHECK((v.get_as_ref<decltype(&iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user