mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-16 22:17:02 +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 return value policy
|
||||||
- add meta exception class;
|
- add meta exception class;
|
||||||
- add conversion of nullptr to any pointers;
|
- add conversion of nullptr to any pointers;
|
||||||
- add conversion of any pointers to void pointer ( identically cv-qualified );
|
|
||||||
- void value?
|
- void value?
|
||||||
- all string to hash?
|
- all string to hash?
|
||||||
|
|
||||||
|
|||||||
@@ -107,10 +107,12 @@ namespace meta_hpp::detail
|
|||||||
const any_type& to_data_type = to_type_ptr.get_data_type();
|
const any_type& to_data_type = to_type_ptr.get_data_type();
|
||||||
const any_type& from_data_type = from_type_array.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 ) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( to_type.is_pointer() && from_type.is_pointer() ) {
|
if ( to_type.is_pointer() && from_type.is_pointer() ) {
|
||||||
const pointer_type& to_type_ptr = to_type.as_pointer();
|
const pointer_type& to_type_ptr = to_type.as_pointer();
|
||||||
@@ -122,11 +124,13 @@ namespace meta_hpp::detail
|
|||||||
const any_type& to_data_type = to_type_ptr.get_data_type();
|
const any_type& to_data_type = to_type_ptr.get_data_type();
|
||||||
const any_type& from_data_type = from_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 ) {
|
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 true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if constexpr ( std::is_reference_v<To> ) {
|
if constexpr ( std::is_reference_v<To> ) {
|
||||||
const auto is_convertible = [this](){
|
const auto is_convertible = [this](){
|
||||||
@@ -209,7 +213,7 @@ namespace meta_hpp::detail
|
|||||||
const any_type& to_data_type = to_type_ptr.get_data_type();
|
const any_type& to_data_type = to_type_ptr.get_data_type();
|
||||||
const any_type& from_data_type = from_type_array.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_);
|
return static_cast<to_raw_type_cv>(data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +235,7 @@ namespace meta_hpp::detail
|
|||||||
|
|
||||||
void** from_data_ptr = static_cast<void**>(data_);
|
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);
|
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