mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
add conversion of any pointers to void pointer
This commit is contained in:
1
TODO.md
1
TODO.md
@@ -4,7 +4,6 @@
|
||||
- add return value policy
|
||||
- add meta exception class;
|
||||
- add conversion of nullptr to any pointers;
|
||||
- add conversion of any pointers to void pointer ( identically cv-qualified );
|
||||
- void value?
|
||||
- all string to hash?
|
||||
|
||||
|
||||
@@ -107,8 +107,10 @@ namespace meta_hpp::detail
|
||||
const any_type& to_data_type = to_type_ptr.get_data_type();
|
||||
const any_type& from_data_type = from_type_array.get_data_type();
|
||||
|
||||
if ( is_a(to_data_type, from_data_type) && to_type_ptr_readonly >= from_type_array_readonly ) {
|
||||
return true;
|
||||
if ( to_type_ptr_readonly >= from_type_array_readonly ) {
|
||||
if ( to_data_type.is_void() || is_a(to_data_type, from_data_type) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,8 +124,10 @@ namespace meta_hpp::detail
|
||||
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 ( is_a(to_data_type, from_data_type) && to_type_ptr_readonly >= from_type_ptr_readonly ) {
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,7 +213,7 @@ namespace meta_hpp::detail
|
||||
const any_type& to_data_type = to_type_ptr.get_data_type();
|
||||
const any_type& from_data_type = from_type_array.get_data_type();
|
||||
|
||||
if ( to_data_type == from_data_type ) {
|
||||
if ( to_data_type.is_void() || to_data_type == from_data_type ) {
|
||||
return static_cast<to_raw_type_cv>(data_);
|
||||
}
|
||||
|
||||
@@ -231,7 +235,7 @@ namespace meta_hpp::detail
|
||||
|
||||
void** from_data_ptr = static_cast<void**>(data_);
|
||||
|
||||
if ( to_data_type == from_data_type ) {
|
||||
if ( to_data_type.is_void() || to_data_type == from_data_type ) {
|
||||
return static_cast<to_raw_type_cv>(*from_data_ptr);
|
||||
}
|
||||
|
||||
|
||||
124
untests/meta_utilities/arg7_tests.cpp
Normal file
124
untests/meta_utilities/arg7_tests.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*******************************************************************************
|
||||
* 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)
|
||||
******************************************************************************/
|
||||
|
||||
#include "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct A {
|
||||
A() = default;
|
||||
virtual ~A() = default;
|
||||
|
||||
A(A&&) = delete;
|
||||
A(const A&) = delete;
|
||||
A& operator=(A&&) = delete;
|
||||
A& operator=(const A&) = delete;
|
||||
|
||||
int i = 1;
|
||||
};
|
||||
|
||||
struct B : virtual A {
|
||||
int i = 2;
|
||||
};
|
||||
|
||||
struct C : virtual A {
|
||||
int i = 3;
|
||||
};
|
||||
|
||||
struct D : B, C {
|
||||
int i = 4;
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/arg7") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
// * <- B <- *
|
||||
// A D
|
||||
// * <- C <- *
|
||||
|
||||
meta::class_<A>();
|
||||
meta::class_<B>().base_<A>();
|
||||
meta::class_<C>().base_<A>();
|
||||
meta::class_<D>().base_<B>().base_<C>();
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/arg7/cast") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::arg;
|
||||
|
||||
SUBCASE("int*") {
|
||||
int i{42};
|
||||
|
||||
CHECK(arg{&i}.can_cast_to<void*>());
|
||||
CHECK(arg{&i}.can_cast_to<const void*>());
|
||||
|
||||
CHECK(arg{&i}.cast<void*>() == &i);
|
||||
CHECK(arg{&i}.cast<const void*>() == &i);
|
||||
}
|
||||
|
||||
SUBCASE("const int*") {
|
||||
const int i{42};
|
||||
|
||||
CHECK_FALSE(arg{&i}.can_cast_to<void*>());
|
||||
CHECK(arg{&i}.can_cast_to<const void*>());
|
||||
|
||||
CHECK_THROWS(std::ignore = arg{&i}.cast<void*>());
|
||||
CHECK(arg{&i}.cast<const void*>() == &i);
|
||||
}
|
||||
|
||||
SUBCASE("D*") {
|
||||
D d;
|
||||
|
||||
static_assert(std::is_invocable_v<void(void*), D*>);
|
||||
static_assert(std::is_invocable_v<void(const void*), D*>);
|
||||
|
||||
CHECK(arg{&d}.can_cast_to<void*>());
|
||||
CHECK(arg{&d}.can_cast_to<const void*>());
|
||||
|
||||
CHECK(arg{&d}.cast<void*>() == &d);
|
||||
CHECK(arg{&d}.cast<const void*>() == &d);
|
||||
}
|
||||
|
||||
SUBCASE("const D*") {
|
||||
const D d;
|
||||
|
||||
static_assert(!std::is_invocable_v<void(void*), const D*>);
|
||||
static_assert(std::is_invocable_v<void(const void*), const D*>);
|
||||
|
||||
CHECK_FALSE(arg{&d}.can_cast_to<void*>());
|
||||
CHECK(arg{&d}.can_cast_to<const void*>());
|
||||
|
||||
CHECK_THROWS(std::ignore = arg{&d}.cast<void*>());
|
||||
CHECK(arg{&d}.cast<const void*>() == &d);
|
||||
}
|
||||
|
||||
SUBCASE("D[2]") {
|
||||
D arr[2];
|
||||
|
||||
static_assert(std::is_invocable_v<void(void*), D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const void*), D (&) [2]>);
|
||||
|
||||
CHECK(arg{arr}.can_cast_to<void*>());
|
||||
CHECK(arg{arr}.can_cast_to<const void*>());
|
||||
|
||||
CHECK(arg{arr}.cast<void*>() == &arr);
|
||||
CHECK(arg{arr}.cast<const void*>() == &arr);
|
||||
}
|
||||
|
||||
SUBCASE("const D[2]") {
|
||||
const D arr[2];
|
||||
|
||||
static_assert(!std::is_invocable_v<void(void*), const D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const void*), const D (&) [2]>);
|
||||
|
||||
CHECK_FALSE(arg{arr}.can_cast_to<void*>());
|
||||
CHECK(arg{arr}.can_cast_to<const void*>());
|
||||
|
||||
CHECK_THROWS(std::ignore = arg{arr}.cast<void*>());
|
||||
CHECK(arg{arr}.cast<const void*>() == &arr);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user