mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
nullptr type
This commit is contained in:
1
TODO.md
1
TODO.md
@@ -3,7 +3,6 @@
|
|||||||
- add array value access
|
- add array value access
|
||||||
- add return value policy
|
- add return value policy
|
||||||
- add meta exception class;
|
- add meta exception class;
|
||||||
- add conversion of nullptr to any pointers;
|
|
||||||
- void value?
|
- void value?
|
||||||
- all string to hash?
|
- all string to hash?
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "meta_types/function_type.hpp"
|
#include "meta_types/function_type.hpp"
|
||||||
#include "meta_types/member_type.hpp"
|
#include "meta_types/member_type.hpp"
|
||||||
#include "meta_types/method_type.hpp"
|
#include "meta_types/method_type.hpp"
|
||||||
|
#include "meta_types/nullptr_type.hpp"
|
||||||
#include "meta_types/number_type.hpp"
|
#include "meta_types/number_type.hpp"
|
||||||
#include "meta_types/pointer_type.hpp"
|
#include "meta_types/pointer_type.hpp"
|
||||||
#include "meta_types/reference_type.hpp"
|
#include "meta_types/reference_type.hpp"
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ namespace meta_hpp
|
|||||||
class function_type;
|
class function_type;
|
||||||
class member_type;
|
class member_type;
|
||||||
class method_type;
|
class method_type;
|
||||||
|
class nullptr_type;
|
||||||
class number_type;
|
class number_type;
|
||||||
class pointer_type;
|
class pointer_type;
|
||||||
class reference_type;
|
class reference_type;
|
||||||
@@ -138,6 +139,7 @@ namespace meta_hpp
|
|||||||
struct function_type_data;
|
struct function_type_data;
|
||||||
struct member_type_data;
|
struct member_type_data;
|
||||||
struct method_type_data;
|
struct method_type_data;
|
||||||
|
struct nullptr_type_data;
|
||||||
struct number_type_data;
|
struct number_type_data;
|
||||||
struct pointer_type_data;
|
struct pointer_type_data;
|
||||||
struct reference_type_data;
|
struct reference_type_data;
|
||||||
@@ -151,6 +153,7 @@ namespace meta_hpp
|
|||||||
using function_type_data_ptr = std::shared_ptr<function_type_data>;
|
using function_type_data_ptr = std::shared_ptr<function_type_data>;
|
||||||
using member_type_data_ptr = std::shared_ptr<member_type_data>;
|
using member_type_data_ptr = std::shared_ptr<member_type_data>;
|
||||||
using method_type_data_ptr = std::shared_ptr<method_type_data>;
|
using method_type_data_ptr = std::shared_ptr<method_type_data>;
|
||||||
|
using nullptr_type_data_ptr = std::shared_ptr<nullptr_type_data>;
|
||||||
using number_type_data_ptr = std::shared_ptr<number_type_data>;
|
using number_type_data_ptr = std::shared_ptr<number_type_data>;
|
||||||
using pointer_type_data_ptr = std::shared_ptr<pointer_type_data>;
|
using pointer_type_data_ptr = std::shared_ptr<pointer_type_data>;
|
||||||
using reference_type_data_ptr = std::shared_ptr<reference_type_data>;
|
using reference_type_data_ptr = std::shared_ptr<reference_type_data>;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace meta_hpp
|
|||||||
function_,
|
function_,
|
||||||
member_,
|
member_,
|
||||||
method_,
|
method_,
|
||||||
|
nullptr_,
|
||||||
number_,
|
number_,
|
||||||
pointer_,
|
pointer_,
|
||||||
reference_,
|
reference_,
|
||||||
@@ -45,6 +46,9 @@ namespace meta_hpp::detail
|
|||||||
template < typename T >
|
template < typename T >
|
||||||
concept method_kind = std::is_member_function_pointer_v<T>;
|
concept method_kind = std::is_member_function_pointer_v<T>;
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
concept nullptr_kind = std::is_null_pointer_v<T>;
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
concept number_kind = std::is_arithmetic_v<T>;
|
concept number_kind = std::is_arithmetic_v<T>;
|
||||||
|
|
||||||
@@ -65,6 +69,7 @@ namespace meta_hpp::detail
|
|||||||
if constexpr ( function_kind<T> ) { return type_kind::function_; }
|
if constexpr ( function_kind<T> ) { return type_kind::function_; }
|
||||||
if constexpr ( member_kind<T> ) { return type_kind::member_; }
|
if constexpr ( member_kind<T> ) { return type_kind::member_; }
|
||||||
if constexpr ( method_kind<T> ) { return type_kind::method_; }
|
if constexpr ( method_kind<T> ) { return type_kind::method_; }
|
||||||
|
if constexpr ( nullptr_kind<T> ) { return type_kind::nullptr_; }
|
||||||
if constexpr ( number_kind<T> ) { return type_kind::number_; }
|
if constexpr ( number_kind<T> ) { return type_kind::number_; }
|
||||||
if constexpr ( pointer_kind<T> ) { return type_kind::pointer_; }
|
if constexpr ( pointer_kind<T> ) { return type_kind::pointer_; }
|
||||||
if constexpr ( reference_kind<T> ) { return type_kind::reference_; }
|
if constexpr ( reference_kind<T> ) { return type_kind::reference_; }
|
||||||
@@ -119,6 +124,12 @@ namespace meta_hpp::detail
|
|||||||
using kind_type_data = method_type_data;
|
using kind_type_data = method_type_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct type_kind_traits<type_kind::nullptr_> {
|
||||||
|
using kind_type = nullptr_type;
|
||||||
|
using kind_type_data = nullptr_type_data;
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct type_kind_traits<type_kind::number_> {
|
struct type_kind_traits<type_kind::number_> {
|
||||||
using kind_type = number_type;
|
using kind_type = number_type;
|
||||||
|
|||||||
@@ -40,9 +40,6 @@ namespace meta_hpp::detail
|
|||||||
|
|
||||||
template < reference_kind Reference >
|
template < reference_kind Reference >
|
||||||
struct reference_traits;
|
struct reference_traits;
|
||||||
|
|
||||||
template < void_kind Void >
|
|
||||||
struct void_traits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ namespace meta_hpp
|
|||||||
std::is_same_v<T, function_type> ||
|
std::is_same_v<T, function_type> ||
|
||||||
std::is_same_v<T, member_type> ||
|
std::is_same_v<T, member_type> ||
|
||||||
std::is_same_v<T, method_type> ||
|
std::is_same_v<T, method_type> ||
|
||||||
|
std::is_same_v<T, nullptr_type> ||
|
||||||
std::is_same_v<T, number_type> ||
|
std::is_same_v<T, number_type> ||
|
||||||
std::is_same_v<T, pointer_type> ||
|
std::is_same_v<T, pointer_type> ||
|
||||||
std::is_same_v<T, reference_type> ||
|
std::is_same_v<T, reference_type> ||
|
||||||
@@ -135,6 +136,7 @@ namespace meta_hpp
|
|||||||
any_type(const function_type& other) noexcept;
|
any_type(const function_type& other) noexcept;
|
||||||
any_type(const member_type& other) noexcept;
|
any_type(const member_type& other) noexcept;
|
||||||
any_type(const method_type& other) noexcept;
|
any_type(const method_type& other) noexcept;
|
||||||
|
any_type(const nullptr_type& other) noexcept;
|
||||||
any_type(const number_type& other) noexcept;
|
any_type(const number_type& other) noexcept;
|
||||||
any_type(const pointer_type& other) noexcept;
|
any_type(const pointer_type& other) noexcept;
|
||||||
any_type(const reference_type& other) noexcept;
|
any_type(const reference_type& other) noexcept;
|
||||||
@@ -147,6 +149,7 @@ namespace meta_hpp
|
|||||||
[[nodiscard]] bool is_function() const noexcept;
|
[[nodiscard]] bool is_function() const noexcept;
|
||||||
[[nodiscard]] bool is_member() const noexcept;
|
[[nodiscard]] bool is_member() const noexcept;
|
||||||
[[nodiscard]] bool is_method() const noexcept;
|
[[nodiscard]] bool is_method() const noexcept;
|
||||||
|
[[nodiscard]] bool is_nullptr() const noexcept;
|
||||||
[[nodiscard]] bool is_number() const noexcept;
|
[[nodiscard]] bool is_number() const noexcept;
|
||||||
[[nodiscard]] bool is_pointer() const noexcept;
|
[[nodiscard]] bool is_pointer() const noexcept;
|
||||||
[[nodiscard]] bool is_reference() const noexcept;
|
[[nodiscard]] bool is_reference() const noexcept;
|
||||||
@@ -159,6 +162,7 @@ namespace meta_hpp
|
|||||||
[[nodiscard]] function_type as_function() const noexcept;
|
[[nodiscard]] function_type as_function() const noexcept;
|
||||||
[[nodiscard]] member_type as_member() const noexcept;
|
[[nodiscard]] member_type as_member() const noexcept;
|
||||||
[[nodiscard]] method_type as_method() const noexcept;
|
[[nodiscard]] method_type as_method() const noexcept;
|
||||||
|
[[nodiscard]] nullptr_type as_nullptr() const noexcept;
|
||||||
[[nodiscard]] number_type as_number() const noexcept;
|
[[nodiscard]] number_type as_number() const noexcept;
|
||||||
[[nodiscard]] pointer_type as_pointer() const noexcept;
|
[[nodiscard]] pointer_type as_pointer() const noexcept;
|
||||||
[[nodiscard]] reference_type as_reference() const noexcept;
|
[[nodiscard]] reference_type as_reference() const noexcept;
|
||||||
@@ -352,6 +356,20 @@ namespace meta_hpp
|
|||||||
friend auto detail::data_access<method_type>(const method_type&);
|
friend auto detail::data_access<method_type>(const method_type&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class nullptr_type final {
|
||||||
|
public:
|
||||||
|
nullptr_type() = default;
|
||||||
|
nullptr_type(detail::nullptr_type_data_ptr data);
|
||||||
|
|
||||||
|
[[nodiscard]] bool is_valid() const noexcept;
|
||||||
|
[[nodiscard]] explicit operator bool() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] type_id get_id() const noexcept;
|
||||||
|
private:
|
||||||
|
detail::nullptr_type_data_ptr data_;
|
||||||
|
friend auto detail::data_access<nullptr_type>(const nullptr_type&);
|
||||||
|
};
|
||||||
|
|
||||||
class number_type final {
|
class number_type final {
|
||||||
public:
|
public:
|
||||||
number_type() = default;
|
number_type() = default;
|
||||||
@@ -530,6 +548,14 @@ namespace meta_hpp::detail
|
|||||||
[[nodiscard]] static method_type_data_ptr get_static();
|
[[nodiscard]] static method_type_data_ptr get_static();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nullptr_type_data final : type_data_base {
|
||||||
|
template < nullptr_kind Nullptr >
|
||||||
|
explicit nullptr_type_data(type_list<Nullptr>);
|
||||||
|
|
||||||
|
template < nullptr_kind Nullptr >
|
||||||
|
[[nodiscard]] static nullptr_type_data_ptr get_static();
|
||||||
|
};
|
||||||
|
|
||||||
struct number_type_data final : type_data_base {
|
struct number_type_data final : type_data_base {
|
||||||
const bitflags<number_flags> flags;
|
const bitflags<number_flags> flags;
|
||||||
const std::size_t size;
|
const std::size_t size;
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ namespace meta_hpp
|
|||||||
inline any_type::any_type(const method_type& other) noexcept
|
inline any_type::any_type(const method_type& other) noexcept
|
||||||
: data_{detail::data_access(other)} {}
|
: data_{detail::data_access(other)} {}
|
||||||
|
|
||||||
|
inline any_type::any_type(const nullptr_type& other) noexcept
|
||||||
|
: data_{detail::data_access(other)} {}
|
||||||
|
|
||||||
inline any_type::any_type(const number_type& other) noexcept
|
inline any_type::any_type(const number_type& other) noexcept
|
||||||
: data_{detail::data_access(other)} {}
|
: data_{detail::data_access(other)} {}
|
||||||
|
|
||||||
@@ -91,6 +94,10 @@ namespace meta_hpp
|
|||||||
return data_ && data_->kind == type_kind::method_;
|
return data_ && data_->kind == type_kind::method_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool any_type::is_nullptr() const noexcept {
|
||||||
|
return data_ && data_->kind == type_kind::nullptr_;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool any_type::is_number() const noexcept {
|
inline bool any_type::is_number() const noexcept {
|
||||||
return data_ && data_->kind == type_kind::number_;
|
return data_ && data_->kind == type_kind::number_;
|
||||||
}
|
}
|
||||||
@@ -149,6 +156,12 @@ namespace meta_hpp
|
|||||||
: method_type{};
|
: method_type{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline nullptr_type any_type::as_nullptr() const noexcept {
|
||||||
|
return is_nullptr()
|
||||||
|
? nullptr_type{std::static_pointer_cast<detail::nullptr_type_data>(data_)}
|
||||||
|
: nullptr_type{};
|
||||||
|
}
|
||||||
|
|
||||||
inline number_type any_type::as_number() const noexcept {
|
inline number_type any_type::as_number() const noexcept {
|
||||||
return is_number()
|
return is_number()
|
||||||
? number_type{std::static_pointer_cast<detail::number_type_data>(data_)}
|
? number_type{std::static_pointer_cast<detail::number_type_data>(data_)}
|
||||||
|
|||||||
45
headers/meta.hpp/meta_types/nullptr_type.hpp
Normal file
45
headers/meta.hpp/meta_types/nullptr_type.hpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../meta_base.hpp"
|
||||||
|
#include "../meta_types.hpp"
|
||||||
|
|
||||||
|
namespace meta_hpp::detail
|
||||||
|
{
|
||||||
|
template < nullptr_kind Nullptr >
|
||||||
|
struct nullptr_tag {};
|
||||||
|
|
||||||
|
template < nullptr_kind Nullptr >
|
||||||
|
// NOLINTNEXTLINE(readability-named-parameter)
|
||||||
|
nullptr_type_data::nullptr_type_data(type_list<Nullptr>)
|
||||||
|
: type_data_base{type_id{type_list<nullptr_tag<Nullptr>>{}}, type_kind::nullptr_} {}
|
||||||
|
|
||||||
|
template < nullptr_kind Nullptr >
|
||||||
|
nullptr_type_data_ptr nullptr_type_data::get_static() {
|
||||||
|
static nullptr_type_data_ptr data = std::make_shared<nullptr_type_data>(type_list<Nullptr>{});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace meta_hpp
|
||||||
|
{
|
||||||
|
inline nullptr_type::nullptr_type(detail::nullptr_type_data_ptr data)
|
||||||
|
: data_{std::move(data)} {}
|
||||||
|
|
||||||
|
inline bool nullptr_type::is_valid() const noexcept {
|
||||||
|
return !!data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline nullptr_type::operator bool() const noexcept {
|
||||||
|
return is_valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline type_id nullptr_type::get_id() const noexcept {
|
||||||
|
return data_->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -97,6 +97,10 @@ namespace meta_hpp::detail
|
|||||||
};
|
};
|
||||||
|
|
||||||
if constexpr ( std::is_pointer_v<To> ) {
|
if constexpr ( std::is_pointer_v<To> ) {
|
||||||
|
if ( to_type.is_pointer() && from_type.is_nullptr() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ( to_type.is_pointer() && from_type.is_array() ) {
|
if ( to_type.is_pointer() && from_type.is_array() ) {
|
||||||
const pointer_type& to_type_ptr = to_type.as_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 bool to_type_ptr_readonly = to_type_ptr.get_flags().has(pointer_flags::is_readonly);
|
||||||
@@ -206,6 +210,10 @@ namespace meta_hpp::detail
|
|||||||
const any_type& to_type = resolve_type<to_raw_type>();
|
const any_type& to_type = resolve_type<to_raw_type>();
|
||||||
|
|
||||||
if constexpr ( std::is_pointer_v<To> ) {
|
if constexpr ( std::is_pointer_v<To> ) {
|
||||||
|
if ( to_type.is_pointer() && from_type.is_nullptr() ) {
|
||||||
|
return static_cast<to_raw_type_cv>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
if ( to_type.is_pointer() && from_type.is_array() ) {
|
if ( to_type.is_pointer() && from_type.is_array() ) {
|
||||||
const pointer_type& to_type_ptr = to_type.as_pointer();
|
const pointer_type& to_type_ptr = to_type.as_pointer();
|
||||||
const array_type& from_type_array = from_type.as_array();
|
const array_type& from_type_array = from_type.as_array();
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace
|
|||||||
return v.x * v.x + v.y * v.y;
|
return v.x * v.x + v.y * v.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool arg_nullptr(const void* ptr) { return ptr == nullptr; }
|
||||||
static int arg_bounded_arr(ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
static int arg_bounded_arr(ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
||||||
static int arg_unbounded_arr(ivec2 vs[]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
static int arg_unbounded_arr(ivec2 vs[]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
||||||
static int arg_bounded_const_arr(const ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
static int arg_bounded_const_arr(const ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
||||||
@@ -37,6 +38,7 @@ TEST_CASE("meta/meta_states/function") {
|
|||||||
meta::class_<ivec2>()
|
meta::class_<ivec2>()
|
||||||
.function_("iadd", &ivec2::iadd)
|
.function_("iadd", &ivec2::iadd)
|
||||||
.function_("ilength2", &ivec2::ilength2)
|
.function_("ilength2", &ivec2::ilength2)
|
||||||
|
.function_("arg_nullptr", &ivec2::arg_nullptr)
|
||||||
.function_("arg_bounded_arr", &ivec2::arg_bounded_arr)
|
.function_("arg_bounded_arr", &ivec2::arg_bounded_arr)
|
||||||
.function_("arg_unbounded_arr", &ivec2::arg_unbounded_arr)
|
.function_("arg_unbounded_arr", &ivec2::arg_unbounded_arr)
|
||||||
.function_("arg_bounded_const_arr", &ivec2::arg_bounded_const_arr)
|
.function_("arg_bounded_const_arr", &ivec2::arg_bounded_const_arr)
|
||||||
@@ -114,6 +116,19 @@ TEST_CASE("meta/meta_states/function") {
|
|||||||
CHECK(func.invoke(ivec2{2,3}).value() == 13);
|
CHECK(func.invoke(ivec2{2,3}).value() == 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("arg_null") {
|
||||||
|
const meta::function func = ivec2_type.get_function("arg_nullptr");
|
||||||
|
REQUIRE(func);
|
||||||
|
|
||||||
|
CHECK(func.is_invocable_with<int*>());
|
||||||
|
CHECK(func.is_invocable_with<const int*>());
|
||||||
|
CHECK(func.is_invocable_with<nullptr_t>());
|
||||||
|
|
||||||
|
int i{42};
|
||||||
|
CHECK(func.invoke(&i) == false);
|
||||||
|
CHECK(func.invoke(nullptr) == true);
|
||||||
|
}
|
||||||
|
|
||||||
SUBCASE("arg_arr") {
|
SUBCASE("arg_arr") {
|
||||||
ivec2 bounded_arr[2]{{1,2},{3,4}};
|
ivec2 bounded_arr[2]{{1,2},{3,4}};
|
||||||
ivec2* unbounded_arr = bounded_arr;
|
ivec2* unbounded_arr = bounded_arr;
|
||||||
|
|||||||
@@ -162,10 +162,28 @@ TEST_CASE("meta/meta_types/any_type") {
|
|||||||
CHECK(type.is_method());
|
CHECK(type.is_method());
|
||||||
CHECK(type.get_kind() == meta::type_kind::method_);
|
CHECK(type.get_kind() == meta::type_kind::method_);
|
||||||
|
|
||||||
|
CHECK_FALSE(type.is_nullptr());
|
||||||
|
CHECK_FALSE(type.as_nullptr());
|
||||||
|
|
||||||
|
const meta::method_type& specific_type = type.as_method();
|
||||||
|
REQUIRE(specific_type);
|
||||||
|
CHECK(specific_type.get_id() == type.get_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("nullptr") {
|
||||||
|
const meta::any_type& type = meta::resolve_type(nullptr);
|
||||||
|
|
||||||
|
REQUIRE(type);
|
||||||
|
REQUIRE(type == meta::resolve_type<nullptr_t>());
|
||||||
|
REQUIRE(type.get_id() == meta::resolve_type<nullptr_t>().get_id());
|
||||||
|
|
||||||
|
CHECK(type.is_nullptr());
|
||||||
|
CHECK(type.get_kind() == meta::type_kind::nullptr_);
|
||||||
|
|
||||||
CHECK_FALSE(type.is_number());
|
CHECK_FALSE(type.is_number());
|
||||||
CHECK_FALSE(type.as_number());
|
CHECK_FALSE(type.as_number());
|
||||||
|
|
||||||
const meta::method_type& specific_type = type.as_method();
|
const meta::nullptr_type& specific_type = type.as_nullptr();
|
||||||
REQUIRE(specific_type);
|
REQUIRE(specific_type);
|
||||||
CHECK(specific_type.get_id() == type.get_id());
|
CHECK(specific_type.get_id() == type.get_id());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,13 +46,16 @@ TEST_CASE("meta/meta_utilities/arg7") {
|
|||||||
meta::class_<D>().base_<B>().base_<C>();
|
meta::class_<D>().base_<B>().base_<C>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/arg7/cast") {
|
TEST_CASE("meta/meta_utilities/arg7/cast/to_void") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
using meta::detail::arg;
|
using meta::detail::arg;
|
||||||
|
|
||||||
SUBCASE("int*") {
|
SUBCASE("int* -> void*") {
|
||||||
int i{42};
|
int i{42};
|
||||||
|
|
||||||
|
static_assert(std::is_invocable_v<void(void*), int*>);
|
||||||
|
static_assert(std::is_invocable_v<void(const void*), int*>);
|
||||||
|
|
||||||
CHECK(arg{&i}.can_cast_to<void*>());
|
CHECK(arg{&i}.can_cast_to<void*>());
|
||||||
CHECK(arg{&i}.can_cast_to<const void*>());
|
CHECK(arg{&i}.can_cast_to<const void*>());
|
||||||
|
|
||||||
@@ -60,9 +63,12 @@ TEST_CASE("meta/meta_utilities/arg7/cast") {
|
|||||||
CHECK(arg{&i}.cast<const void*>() == &i);
|
CHECK(arg{&i}.cast<const void*>() == &i);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("const int*") {
|
SUBCASE("const int* -> void*") {
|
||||||
const int i{42};
|
const int i{42};
|
||||||
|
|
||||||
|
static_assert(!std::is_invocable_v<void(void*), const int*>);
|
||||||
|
static_assert(std::is_invocable_v<void(const void*), const int*>);
|
||||||
|
|
||||||
CHECK_FALSE(arg{&i}.can_cast_to<void*>());
|
CHECK_FALSE(arg{&i}.can_cast_to<void*>());
|
||||||
CHECK(arg{&i}.can_cast_to<const void*>());
|
CHECK(arg{&i}.can_cast_to<const void*>());
|
||||||
|
|
||||||
@@ -70,7 +76,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast") {
|
|||||||
CHECK(arg{&i}.cast<const void*>() == &i);
|
CHECK(arg{&i}.cast<const void*>() == &i);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("D*") {
|
SUBCASE("D* -> void*") {
|
||||||
D d;
|
D d;
|
||||||
|
|
||||||
static_assert(std::is_invocable_v<void(void*), D*>);
|
static_assert(std::is_invocable_v<void(void*), D*>);
|
||||||
@@ -83,7 +89,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast") {
|
|||||||
CHECK(arg{&d}.cast<const void*>() == &d);
|
CHECK(arg{&d}.cast<const void*>() == &d);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("const D*") {
|
SUBCASE("const D* -> void*") {
|
||||||
const D d;
|
const D d;
|
||||||
|
|
||||||
static_assert(!std::is_invocable_v<void(void*), const D*>);
|
static_assert(!std::is_invocable_v<void(void*), const D*>);
|
||||||
@@ -96,7 +102,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast") {
|
|||||||
CHECK(arg{&d}.cast<const void*>() == &d);
|
CHECK(arg{&d}.cast<const void*>() == &d);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("D[2]") {
|
SUBCASE("D[2] -> void*") {
|
||||||
D arr[2];
|
D arr[2];
|
||||||
|
|
||||||
static_assert(std::is_invocable_v<void(void*), D (&) [2]>);
|
static_assert(std::is_invocable_v<void(void*), D (&) [2]>);
|
||||||
@@ -109,7 +115,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast") {
|
|||||||
CHECK(arg{arr}.cast<const void*>() == &arr);
|
CHECK(arg{arr}.cast<const void*>() == &arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("const D[2]") {
|
SUBCASE("const D[2] -> void*") {
|
||||||
const D arr[2];
|
const D arr[2];
|
||||||
|
|
||||||
static_assert(!std::is_invocable_v<void(void*), const D (&) [2]>);
|
static_assert(!std::is_invocable_v<void(void*), const D (&) [2]>);
|
||||||
@@ -122,3 +128,69 @@ TEST_CASE("meta/meta_utilities/arg7/cast") {
|
|||||||
CHECK(arg{arr}.cast<const void*>() == &arr);
|
CHECK(arg{arr}.cast<const void*>() == &arr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/meta_utilities/arg7/cast/from_nullptr") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
using meta::detail::arg;
|
||||||
|
|
||||||
|
SUBCASE("nullptr -> *") {
|
||||||
|
static_assert(std::is_invocable_v<void(int*), nullptr_t>);
|
||||||
|
static_assert(std::is_invocable_v<void(int*), nullptr_t&>);
|
||||||
|
static_assert(std::is_invocable_v<void(int*), nullptr_t&&>);
|
||||||
|
static_assert(std::is_invocable_v<void(int*), const nullptr_t>);
|
||||||
|
static_assert(std::is_invocable_v<void(int*), const nullptr_t&>);
|
||||||
|
static_assert(std::is_invocable_v<void(int*), const nullptr_t&&>);
|
||||||
|
|
||||||
|
static_assert(std::is_invocable_v<void(const D*), nullptr_t>);
|
||||||
|
static_assert(std::is_invocable_v<void(const D*), nullptr_t&>);
|
||||||
|
static_assert(std::is_invocable_v<void(const D*), nullptr_t&&>);
|
||||||
|
static_assert(std::is_invocable_v<void(const D*), const nullptr_t>);
|
||||||
|
static_assert(std::is_invocable_v<void(const D*), const nullptr_t&>);
|
||||||
|
static_assert(std::is_invocable_v<void(const D*), const nullptr_t&&>);
|
||||||
|
|
||||||
|
nullptr_t n1{nullptr};
|
||||||
|
const nullptr_t n2{nullptr};
|
||||||
|
|
||||||
|
CHECK(arg{n1}.can_cast_to<int*>());
|
||||||
|
CHECK(arg{std::move(n1)}.can_cast_to<int*>());
|
||||||
|
CHECK(arg{n2}.can_cast_to<int*>());
|
||||||
|
CHECK(arg{std::move(n2)}.can_cast_to<int*>());
|
||||||
|
|
||||||
|
CHECK(arg{n1}.can_cast_to<const int*>());
|
||||||
|
CHECK(arg{std::move(n1)}.can_cast_to<const int*>());
|
||||||
|
CHECK(arg{n2}.can_cast_to<const int*>());
|
||||||
|
CHECK(arg{std::move(n2)}.can_cast_to<const int*>());
|
||||||
|
|
||||||
|
CHECK(arg{n1}.can_cast_to<D*>());
|
||||||
|
CHECK(arg{std::move(n1)}.can_cast_to<D*>());
|
||||||
|
CHECK(arg{n2}.can_cast_to<D*>());
|
||||||
|
CHECK(arg{std::move(n2)}.can_cast_to<D*>());
|
||||||
|
|
||||||
|
CHECK(arg{n1}.can_cast_to<const D*>());
|
||||||
|
CHECK(arg{std::move(n1)}.can_cast_to<const D*>());
|
||||||
|
CHECK(arg{n2}.can_cast_to<const D*>());
|
||||||
|
CHECK(arg{std::move(n2)}.can_cast_to<const D*>());
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
CHECK(arg{n1}.cast<int*>() == nullptr);
|
||||||
|
CHECK(arg{std::move(n1)}.cast<int*>() == nullptr);
|
||||||
|
CHECK(arg{n2}.cast<int*>() == nullptr);
|
||||||
|
CHECK(arg{std::move(n2)}.cast<int*>() == nullptr);
|
||||||
|
|
||||||
|
CHECK(arg{n1}.cast<const int*>() == nullptr);
|
||||||
|
CHECK(arg{std::move(n1)}.cast<const int*>() == nullptr);
|
||||||
|
CHECK(arg{n2}.cast<const int*>() == nullptr);
|
||||||
|
CHECK(arg{std::move(n2)}.cast<const int*>() == nullptr);
|
||||||
|
|
||||||
|
CHECK(arg{n1}.cast<D*>() == nullptr);
|
||||||
|
CHECK(arg{std::move(n1)}.cast<D*>() == nullptr);
|
||||||
|
CHECK(arg{n2}.cast<D*>() == nullptr);
|
||||||
|
CHECK(arg{std::move(n2)}.cast<D*>() == nullptr);
|
||||||
|
|
||||||
|
CHECK(arg{n1}.cast<const D*>() == nullptr);
|
||||||
|
CHECK(arg{std::move(n1)}.cast<const D*>() == nullptr);
|
||||||
|
CHECK(arg{n2}.cast<const D*>() == nullptr);
|
||||||
|
CHECK(arg{std::move(n2)}.cast<const D*>() == nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user