add conversion of any pointers to void pointer

This commit is contained in:
BlackMATov
2022-01-16 10:07:13 +07:00
parent f942f8ffa0
commit dffad68627
3 changed files with 134 additions and 7 deletions

View File

@@ -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?

View File

@@ -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);
}

View 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);
}
}