mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2026-03-22 12:55:37 +07:00
@@ -85,6 +85,20 @@
|
||||
"BUILD_WITH_SANITIZERS": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-arm64-san-no-exceptions",
|
||||
"inherits": "macos-arm64-san",
|
||||
"cacheVariables": {
|
||||
"BUILD_WITH_NO_EXCEPTIONS": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-arm64-san-no-rtti",
|
||||
"inherits": "macos-arm64-san",
|
||||
"cacheVariables": {
|
||||
"BUILD_WITH_NO_RTTI": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-x64",
|
||||
"inherits": "macos-base",
|
||||
@@ -100,6 +114,20 @@
|
||||
"BUILD_WITH_SANITIZERS": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-x64-san-no-exceptions",
|
||||
"inherits": "macos-x64-san",
|
||||
"cacheVariables": {
|
||||
"BUILD_WITH_NO_EXCEPTIONS": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-x64-san-no-rtti",
|
||||
"inherits": "macos-x64-san",
|
||||
"cacheVariables": {
|
||||
"BUILD_WITH_NO_RTTI": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-base",
|
||||
"hidden": true,
|
||||
@@ -218,20 +246,40 @@
|
||||
"configurePreset": "linux-gcc-12"
|
||||
},
|
||||
{
|
||||
"name": "macos-arm64-debug",
|
||||
"name": "macos-arm64-debug-san",
|
||||
"configuration": "Debug",
|
||||
"configurePreset": "macos-arm64-san"
|
||||
},
|
||||
{
|
||||
"name": "macos-arm64-debug-san-no-exceptions",
|
||||
"configuration": "Debug",
|
||||
"configurePreset": "macos-arm64-san-no-exceptions"
|
||||
},
|
||||
{
|
||||
"name": "macos-arm64-debug-san-no-rtti",
|
||||
"configuration": "Debug",
|
||||
"configurePreset": "macos-arm64-san-no-rtti"
|
||||
},
|
||||
{
|
||||
"name": "macos-arm64-release",
|
||||
"configuration": "Release",
|
||||
"configurePreset": "macos-arm64"
|
||||
},
|
||||
{
|
||||
"name": "macos-x64-debug",
|
||||
"name": "macos-x64-debug-san",
|
||||
"configuration": "Debug",
|
||||
"configurePreset": "macos-x64-san"
|
||||
},
|
||||
{
|
||||
"name": "macos-x64-debug-san-no-exceptions",
|
||||
"configuration": "Debug",
|
||||
"configurePreset": "macos-x64-san-no-exceptions"
|
||||
},
|
||||
{
|
||||
"name": "macos-x64-debug-san-no-rtti",
|
||||
"configuration": "Debug",
|
||||
"configurePreset": "macos-x64-san-no-rtti"
|
||||
},
|
||||
{
|
||||
"name": "macos-x64-release",
|
||||
"configuration": "Release",
|
||||
|
||||
@@ -44,6 +44,8 @@ add_subdirectory(external/meta.hpp)
|
||||
target_link_libraries(your_project_target PUBLIC meta.hpp::meta.hpp)
|
||||
```
|
||||
|
||||
Or just use the single-header version of the library, which you can find [here](develop/singles/headers/meta.hpp).
|
||||
|
||||
## Manuals
|
||||
|
||||
- [Class](develop/manuals/meta_manuals/class_manual.cpp)
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
option(BUILD_WITH_COVERAGE "Build with coverage" OFF)
|
||||
option(BUILD_WITH_SANITIZERS "Build with sanitizers" OFF)
|
||||
option(BUILD_WITH_NO_EXCEPTIONS "Build with no exceptions" OFF)
|
||||
option(BUILD_WITH_NO_RTTI "Build with no RTTI" OFF)
|
||||
|
||||
enable_testing()
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMake")
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
include(DisableExceptions)
|
||||
include(DisableRTTI)
|
||||
include(EnableASan)
|
||||
include(EnableGCov)
|
||||
include(EnableUBSan)
|
||||
|
||||
5
develop/cmake/DisableExceptions.cmake
Normal file
5
develop/cmake/DisableExceptions.cmake
Normal file
@@ -0,0 +1,5 @@
|
||||
add_library(${PROJECT_NAME}.disable_exceptions INTERFACE)
|
||||
add_library(${PROJECT_NAME}::disable_exceptions ALIAS ${PROJECT_NAME}.disable_exceptions)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}.disable_exceptions INTERFACE
|
||||
-fno-exceptions)
|
||||
5
develop/cmake/DisableRTTI.cmake
Normal file
5
develop/cmake/DisableRTTI.cmake
Normal file
@@ -0,0 +1,5 @@
|
||||
add_library(${PROJECT_NAME}.disable_rtti INTERFACE)
|
||||
add_library(${PROJECT_NAME}::disable_rtti ALIAS ${PROJECT_NAME}.disable_rtti)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}.disable_rtti INTERFACE
|
||||
-fno-rtti)
|
||||
@@ -31,3 +31,16 @@ if(BUILD_WITH_SANITIZERS)
|
||||
meta.hpp::enable_asan
|
||||
meta.hpp::enable_ubsan)
|
||||
endif()
|
||||
|
||||
if(BUILD_WITH_NO_EXCEPTIONS)
|
||||
target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE
|
||||
meta.hpp::disable_exceptions)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}.setup_targets INTERFACE
|
||||
DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS)
|
||||
endif()
|
||||
|
||||
if(BUILD_WITH_NO_RTTI)
|
||||
target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE
|
||||
meta.hpp::disable_rtti)
|
||||
endif()
|
||||
|
||||
@@ -39,6 +39,16 @@
|
||||
# define META_HPP_NO_RTTI
|
||||
#endif
|
||||
|
||||
#if defined(META_HPP_NO_EXCEPTIONS)
|
||||
# define META_HPP_TRY if ( true )
|
||||
# define META_HPP_CATCH(e) if ( false )
|
||||
# define META_HPP_RETHROW() std::abort()
|
||||
#else
|
||||
# define META_HPP_TRY try
|
||||
# define META_HPP_CATCH(e) catch(e)
|
||||
# define META_HPP_RETHROW() throw
|
||||
#endif
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename Enum >
|
||||
@@ -833,7 +843,7 @@ namespace meta_hpp
|
||||
namespace detail
|
||||
{
|
||||
inline void throw_exception_with [[noreturn]] (const char* what) {
|
||||
#ifndef META_HPP_NO_EXCEPTIONS
|
||||
#if !defined(META_HPP_NO_EXCEPTIONS)
|
||||
throw ::meta_hpp::exception(what);
|
||||
#else
|
||||
(void)what;
|
||||
@@ -3221,8 +3231,13 @@ namespace meta_hpp::detail
|
||||
std::call_once(init_flag, [this, &type_data](){
|
||||
const locker lock;
|
||||
type_by_id_.emplace(type_data.id, any_type{&type_data});
|
||||
#ifndef META_HPP_NO_RTTI
|
||||
type_by_rtti_.emplace(typeid(Type), any_type{&type_data});
|
||||
#if !defined(META_HPP_NO_RTTI)
|
||||
META_HPP_TRY {
|
||||
type_by_rtti_.emplace(typeid(Type), any_type{&type_data});
|
||||
} META_HPP_CATCH(...) {
|
||||
type_by_id_.erase(type_data.id);
|
||||
META_HPP_RETHROW();
|
||||
}
|
||||
#endif
|
||||
});
|
||||
}
|
||||
@@ -3325,9 +3340,9 @@ namespace meta_hpp
|
||||
|
||||
// base_
|
||||
|
||||
template < detail::class_kind Base >
|
||||
template < detail::class_kind... Bases >
|
||||
class_bind& base_()
|
||||
requires detail::class_bind_base_kind<Class, Base>;
|
||||
requires (... && detail::class_bind_base_kind<Class, Bases>);
|
||||
|
||||
// constructor_
|
||||
|
||||
@@ -3755,7 +3770,7 @@ namespace meta_hpp
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] any_type resolve_polymorphic_type(T&& v) noexcept {
|
||||
#ifndef META_HPP_NO_RTTI
|
||||
#if !defined(META_HPP_NO_RTTI)
|
||||
using namespace detail;
|
||||
type_registry& registry = type_registry::instance();
|
||||
return registry.get_type_by_rtti(typeid(v));
|
||||
@@ -3809,21 +3824,28 @@ namespace meta_hpp
|
||||
//
|
||||
|
||||
template < detail::class_kind Class >
|
||||
template < detail::class_kind Base >
|
||||
template < detail::class_kind... Bases >
|
||||
class_bind<Class>& class_bind<Class>::base_()
|
||||
requires detail::class_bind_base_kind<Class, Base>
|
||||
requires (... && detail::class_bind_base_kind<Class, Bases>)
|
||||
{
|
||||
const class_type base_type = resolve_type<Base>();
|
||||
if ( data_->bases.contains(base_type) ) {
|
||||
return *this;
|
||||
}
|
||||
([this]<detail::class_kind Base>(std::in_place_type_t<Base>) {
|
||||
const class_type base_type = resolve_type<Base>();
|
||||
|
||||
data_->bases.emplace(base_type);
|
||||
data_->bases_info.emplace(base_type, detail::class_type_data::base_info{
|
||||
.upcast = +[](void* derived) -> void* {
|
||||
return static_cast<Base*>(static_cast<Class*>(derived));
|
||||
if ( auto&& [_, success] = data_->bases.emplace(base_type); !success ) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
META_HPP_TRY {
|
||||
data_->bases_info.emplace(base_type, detail::class_type_data::base_info{
|
||||
.upcast = +[](void* derived) -> void* {
|
||||
return static_cast<Base*>(static_cast<Class*>(derived));
|
||||
}
|
||||
});
|
||||
} META_HPP_CATCH(...) {
|
||||
data_->bases.erase(base_type);
|
||||
META_HPP_RETHROW();
|
||||
}
|
||||
}(std::in_place_type<Bases>), ...);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -5309,18 +5331,13 @@ namespace meta_hpp::detail
|
||||
using ct = constructor_traits<Class, Args...>;
|
||||
using ct_argument_types = typename ct::argument_types;
|
||||
|
||||
argument_list arguments;
|
||||
arguments.reserve(ct::arity);
|
||||
|
||||
[&arguments]<std::size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
return []<std::size_t... Is>(std::index_sequence<Is...>){
|
||||
[[maybe_unused]] const auto make_argument = []<std::size_t I>(std::index_sequence<I>){
|
||||
using P = type_list_at_t<I, ct_argument_types>;
|
||||
return argument{argument_state::make<P>(I, metadata_map{})};
|
||||
};
|
||||
(arguments.push_back(make_argument(std::index_sequence<Is>{})), ...);
|
||||
return argument_list{make_argument(std::index_sequence<Is>{})...};
|
||||
}(std::make_index_sequence<ct::arity>());
|
||||
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5831,18 +5848,13 @@ namespace meta_hpp::detail
|
||||
using ft = function_traits<Function>;
|
||||
using ft_argument_types = typename ft::argument_types;
|
||||
|
||||
argument_list arguments;
|
||||
arguments.reserve(ft::arity);
|
||||
|
||||
[&arguments]<std::size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
return []<std::size_t... Is>(std::index_sequence<Is...>){
|
||||
[[maybe_unused]] const auto make_argument = []<std::size_t I>(std::index_sequence<I>){
|
||||
using P = type_list_at_t<I, ft_argument_types>;
|
||||
return argument{argument_state::make<P>(I, metadata_map{})};
|
||||
};
|
||||
(arguments.push_back(make_argument(std::index_sequence<Is>{})), ...);
|
||||
return argument_list{make_argument(std::index_sequence<Is>{})...};
|
||||
}(std::make_index_sequence<ft::arity>());
|
||||
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6609,18 +6621,13 @@ namespace meta_hpp::detail
|
||||
using mt = method_traits<Method>;
|
||||
using mt_argument_types = typename mt::argument_types;
|
||||
|
||||
argument_list arguments;
|
||||
arguments.reserve(mt::arity);
|
||||
|
||||
[&arguments]<std::size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
return []<std::size_t... Is>(std::index_sequence<Is...>){
|
||||
[[maybe_unused]] const auto make_argument = []<std::size_t I>(std::index_sequence<I>){
|
||||
using P = type_list_at_t<I, mt_argument_types>;
|
||||
return argument{argument_state::make<P>(I, metadata_map{})};
|
||||
};
|
||||
(arguments.push_back(make_argument(std::index_sequence<Is>{})), ...);
|
||||
return argument_list{make_argument(std::index_sequence<Is>{})...};
|
||||
}(std::make_index_sequence<mt::arity>());
|
||||
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,6 @@ TEST_CASE("meta/meta_base/fixed_function") {
|
||||
s = std::make_unique<int>(10)
|
||||
](){};
|
||||
fixed_function ff = std::move(f);
|
||||
CHECK_NOTHROW(ff());
|
||||
ff();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,9 +330,11 @@ TEST_CASE("meta/meta_features/diamond") {
|
||||
CHECK(meta::resolve_type(cd) == meta::resolve_type<C>());
|
||||
CHECK(meta::resolve_type(dd) == meta::resolve_type<D>());
|
||||
|
||||
#if !defined(META_HPP_NO_RTTI)
|
||||
CHECK(meta::resolve_polymorphic_type(ad) == meta::resolve_type<D>());
|
||||
CHECK(meta::resolve_polymorphic_type(bd) == meta::resolve_type<D>());
|
||||
CHECK(meta::resolve_polymorphic_type(cd) == meta::resolve_type<D>());
|
||||
CHECK(meta::resolve_polymorphic_type(dd) == meta::resolve_type<D>());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,20 +136,20 @@ TEST_CASE("meta/meta_states/member") {
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_NOTHROW(vm.set(v, 10)); CHECK(vm.get(v) == 10);
|
||||
CHECK_NOTHROW(vm.set(&v, 100)); CHECK(vm.get(v) == 100);
|
||||
vm.set(v, 10); CHECK(vm.get(v) == 10);
|
||||
vm.set(&v, 100); CHECK(vm.get(v) == 100);
|
||||
CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 100);
|
||||
CHECK_THROWS(vm.set(&std::as_const(v), 11)); CHECK(vm.get(v) == 100);
|
||||
|
||||
CHECK_NOTHROW(vm.set(std::move(v), 12)); CHECK(vm.get(v) == 12);
|
||||
vm.set(std::move(v), 12); CHECK(vm.get(v) == 12);
|
||||
CHECK_THROWS(vm.set(std::move(std::as_const(v)), 13)); CHECK(vm.get(v) == 12);
|
||||
|
||||
CHECK_NOTHROW(vm(v, 13)); CHECK(vm(v) == 13);
|
||||
CHECK_NOTHROW(vm(&v, 130)); CHECK(vm(v) == 130);
|
||||
vm(v, 13); CHECK(vm(v) == 13);
|
||||
vm(&v, 130); CHECK(vm(v) == 130);
|
||||
CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v) == 130);
|
||||
CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v) == 130);
|
||||
|
||||
CHECK_NOTHROW(vm(std::move(v), 15)); CHECK(vm(v) == 15);
|
||||
vm(std::move(v), 15); CHECK(vm(v) == 15);
|
||||
CHECK_THROWS(vm(std::move(std::as_const(v)), 16)); CHECK(vm(v) == 15);
|
||||
|
||||
CHECK_THROWS(vm.set(v2, 17));
|
||||
|
||||
@@ -84,8 +84,8 @@ TEST_CASE("meta/meta_states/variable") {
|
||||
CHECK_FALSE(vm.is_settable_with<const float&>());
|
||||
CHECK_FALSE(vm.is_settable_with(1.0));
|
||||
|
||||
CHECK_NOTHROW(vm.set(10)); CHECK(vm.get() == 10);
|
||||
CHECK_NOTHROW(vm(11)); CHECK(vm() == 11);
|
||||
vm.set(10); CHECK(vm.get() == 10);
|
||||
vm(11); CHECK(vm() == 11);
|
||||
}
|
||||
|
||||
SUBCASE("const int") {
|
||||
@@ -132,8 +132,8 @@ TEST_CASE("meta/meta_states/variable") {
|
||||
CHECK_FALSE(vm.is_settable_with<const float&>());
|
||||
CHECK_FALSE(vm.is_settable_with(1.0));
|
||||
|
||||
CHECK_NOTHROW(vm.set(20)); CHECK(vm.get() == 20);
|
||||
CHECK_NOTHROW(vm(21)); CHECK(vm() == 21);
|
||||
vm.set(20); CHECK(vm.get() == 20);
|
||||
vm(21); CHECK(vm() == 21);
|
||||
}
|
||||
|
||||
SUBCASE("const ref int") {
|
||||
@@ -169,7 +169,7 @@ TEST_CASE("meta/meta_states/variable") {
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(11);
|
||||
CHECK_NOTHROW(vm.set(std::move(nv)));
|
||||
vm.set(std::move(nv));
|
||||
CHECK(*clazz_1::unique_int_variable == 11);
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ TEST_CASE("meta/meta_states/variable") {
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(13);
|
||||
CHECK_NOTHROW(vm.set(std::move(nv)));
|
||||
vm.set(std::move(nv));
|
||||
CHECK(*clazz_1::unique_int_variable == 13);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ TEST_CASE("meta/meta_types/class_type") {
|
||||
|
||||
meta::class_<base_clazz_1>()
|
||||
.constructor_<int>()
|
||||
.base_<>()
|
||||
.member_("base_member_1", &base_clazz_1::base_member_1)
|
||||
.method_("base_method_1", &base_clazz_1::base_method_1)
|
||||
.function_("base_function_1", &base_clazz_1::base_function_1)
|
||||
@@ -81,8 +82,7 @@ TEST_CASE("meta/meta_types/class_type") {
|
||||
|
||||
meta::class_<derived_clazz>()
|
||||
.constructor_<int, float>()
|
||||
.base_<base_clazz_1>()
|
||||
.base_<base_clazz_2>()
|
||||
.base_<base_clazz_1, base_clazz_2>()
|
||||
.member_("derived_member", &derived_clazz::derived_member)
|
||||
.method_("derived_method", &derived_clazz::derived_method)
|
||||
.function_("derived_function", &derived_clazz::derived_function)
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace
|
||||
switch ( i ) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
default: throw std::out_of_range("ivec2::at");
|
||||
default: std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -143,10 +143,10 @@ TEST_CASE("meta/meta_utilities/arg5/cast") {
|
||||
static_assert(std::is_invocable_v<void(A* const), decltype(LV())>);
|
||||
static_assert(std::is_invocable_v<void(const A* const), decltype(LV())>);
|
||||
|
||||
CHECK_NOTHROW([](A*){}(LV()));
|
||||
CHECK_NOTHROW([](const A*){}(LV()));
|
||||
CHECK_NOTHROW([](A* const){}(LV()));
|
||||
CHECK_NOTHROW([](const A* const){}(LV()));
|
||||
[](A*){}(LV());
|
||||
[](const A*){}(LV());
|
||||
[](A* const){}(LV());
|
||||
[](const A* const){}(LV());
|
||||
|
||||
CHECK(uarg(LV()).cast<A*>() == static_cast<A*>(src));
|
||||
CHECK(uarg(LV()).cast<const A*>() == static_cast<const A*>(src));
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace
|
||||
if ( std::is_invocable_v<decltype(function_ptr), decltype(FromValue)> ) {\
|
||||
CHECK(uarg{FromValue}.can_cast_to<ToType>());\
|
||||
CHECK(uarg_base{type_list<decltype(FromValue)>{}}.can_cast_to<ToType>());\
|
||||
CHECK_NOTHROW(std::ignore = uarg{FromValue}.cast<ToType>());\
|
||||
std::ignore = uarg{FromValue}.cast<ToType>();\
|
||||
\
|
||||
CHECK(f_state.is_invocable_with<decltype(FromValue)>());\
|
||||
CHECK(f_state.invoke(FromValue) == 1);\
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace
|
||||
if ( std::is_invocable_v<decltype(method_ptr), decltype(Inst)> ) {\
|
||||
CHECK(uinst{Inst}.can_cast_to<clazz Qualifiers>());\
|
||||
CHECK(uinst_base{type_list<decltype(Inst)>{}}.can_cast_to<clazz Qualifiers>());\
|
||||
CHECK_NOTHROW(std::ignore = uinst{Inst}.cast<clazz Qualifiers>());\
|
||||
std::ignore = uinst{Inst}.cast<clazz Qualifiers>();\
|
||||
\
|
||||
CHECK(m_state.is_invocable_with<decltype(Inst)>());\
|
||||
CHECK(m_state.invoke(Inst) == 1);\
|
||||
|
||||
@@ -379,7 +379,7 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
|
||||
SUBCASE("ostream") {
|
||||
std::stringstream str_stream;
|
||||
CHECK_NOTHROW(str_stream << meta::uvalue{21} << " " << meta::uvalue{42});
|
||||
str_stream << meta::uvalue{21} << " " << meta::uvalue{42};
|
||||
CHECK_THROWS((str_stream << meta::uvalue{ivec2{1,2}}));
|
||||
REQUIRE(str_stream.str() == "21 42");
|
||||
}
|
||||
@@ -391,9 +391,9 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK_THROWS(str_stream >> v);
|
||||
|
||||
v = meta::uvalue{0};
|
||||
CHECK_NOTHROW(str_stream >> v);
|
||||
str_stream >> v;
|
||||
CHECK(v == 21);
|
||||
CHECK_NOTHROW(str_stream >> v);
|
||||
str_stream >> v;
|
||||
CHECK(v == 42);
|
||||
}
|
||||
|
||||
@@ -436,10 +436,10 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
{
|
||||
int i{42};
|
||||
|
||||
void* p1 = &i;
|
||||
const void* p2 = &i;
|
||||
void* const& p3 = &i;
|
||||
const void* const& p4 = &i;
|
||||
[[maybe_unused]] void* p1 = &i;
|
||||
[[maybe_unused]] const void* p2 = &i;
|
||||
[[maybe_unused]] void* const& p3 = &i;
|
||||
[[maybe_unused]] const void* const& p4 = &i;
|
||||
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p1));
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p2));
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace meta_hpp
|
||||
namespace detail
|
||||
{
|
||||
inline void throw_exception_with [[noreturn]] (const char* what) {
|
||||
#ifndef META_HPP_NO_EXCEPTIONS
|
||||
#if !defined(META_HPP_NO_EXCEPTIONS)
|
||||
throw ::meta_hpp::exception(what);
|
||||
#else
|
||||
(void)what;
|
||||
|
||||
@@ -41,3 +41,13 @@
|
||||
#if !defined(__cpp_rtti)
|
||||
# define META_HPP_NO_RTTI
|
||||
#endif
|
||||
|
||||
#if defined(META_HPP_NO_EXCEPTIONS)
|
||||
# define META_HPP_TRY if ( true )
|
||||
# define META_HPP_CATCH(e) if ( false )
|
||||
# define META_HPP_RETHROW() std::abort()
|
||||
#else
|
||||
# define META_HPP_TRY try
|
||||
# define META_HPP_CATCH(e) catch(e)
|
||||
# define META_HPP_RETHROW() throw
|
||||
#endif
|
||||
|
||||
@@ -104,9 +104,9 @@ namespace meta_hpp
|
||||
|
||||
// base_
|
||||
|
||||
template < detail::class_kind Base >
|
||||
template < detail::class_kind... Bases >
|
||||
class_bind& base_()
|
||||
requires detail::class_bind_base_kind<Class, Base>;
|
||||
requires (... && detail::class_bind_base_kind<Class, Bases>);
|
||||
|
||||
// constructor_
|
||||
|
||||
|
||||
@@ -29,21 +29,28 @@ namespace meta_hpp
|
||||
//
|
||||
|
||||
template < detail::class_kind Class >
|
||||
template < detail::class_kind Base >
|
||||
template < detail::class_kind... Bases >
|
||||
class_bind<Class>& class_bind<Class>::base_()
|
||||
requires detail::class_bind_base_kind<Class, Base>
|
||||
requires (... && detail::class_bind_base_kind<Class, Bases>)
|
||||
{
|
||||
const class_type base_type = resolve_type<Base>();
|
||||
if ( data_->bases.contains(base_type) ) {
|
||||
return *this;
|
||||
}
|
||||
([this]<detail::class_kind Base>(std::in_place_type_t<Base>) {
|
||||
const class_type base_type = resolve_type<Base>();
|
||||
|
||||
data_->bases.emplace(base_type);
|
||||
data_->bases_info.emplace(base_type, detail::class_type_data::base_info{
|
||||
.upcast = +[](void* derived) -> void* {
|
||||
return static_cast<Base*>(static_cast<Class*>(derived));
|
||||
if ( auto&& [_, success] = data_->bases.emplace(base_type); !success ) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
META_HPP_TRY {
|
||||
data_->bases_info.emplace(base_type, detail::class_type_data::base_info{
|
||||
.upcast = +[](void* derived) -> void* {
|
||||
return static_cast<Base*>(static_cast<Class*>(derived));
|
||||
}
|
||||
});
|
||||
} META_HPP_CATCH(...) {
|
||||
data_->bases.erase(base_type);
|
||||
META_HPP_RETHROW();
|
||||
}
|
||||
}(std::in_place_type<Bases>), ...);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -221,8 +221,13 @@ namespace meta_hpp::detail
|
||||
std::call_once(init_flag, [this, &type_data](){
|
||||
const locker lock;
|
||||
type_by_id_.emplace(type_data.id, any_type{&type_data});
|
||||
#ifndef META_HPP_NO_RTTI
|
||||
type_by_rtti_.emplace(typeid(Type), any_type{&type_data});
|
||||
#if !defined(META_HPP_NO_RTTI)
|
||||
META_HPP_TRY {
|
||||
type_by_rtti_.emplace(typeid(Type), any_type{&type_data});
|
||||
} META_HPP_CATCH(...) {
|
||||
type_by_id_.erase(type_data.id);
|
||||
META_HPP_RETHROW();
|
||||
}
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace meta_hpp
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] any_type resolve_polymorphic_type(T&& v) noexcept {
|
||||
#ifndef META_HPP_NO_RTTI
|
||||
#if !defined(META_HPP_NO_RTTI)
|
||||
using namespace detail;
|
||||
type_registry& registry = type_registry::instance();
|
||||
return registry.get_type_by_rtti(typeid(v));
|
||||
|
||||
@@ -115,18 +115,13 @@ namespace meta_hpp::detail
|
||||
using ct = constructor_traits<Class, Args...>;
|
||||
using ct_argument_types = typename ct::argument_types;
|
||||
|
||||
argument_list arguments;
|
||||
arguments.reserve(ct::arity);
|
||||
|
||||
[&arguments]<std::size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
return []<std::size_t... Is>(std::index_sequence<Is...>){
|
||||
[[maybe_unused]] const auto make_argument = []<std::size_t I>(std::index_sequence<I>){
|
||||
using P = type_list_at_t<I, ct_argument_types>;
|
||||
return argument{argument_state::make<P>(I, metadata_map{})};
|
||||
};
|
||||
(arguments.push_back(make_argument(std::index_sequence<Is>{})), ...);
|
||||
return argument_list{make_argument(std::index_sequence<Is>{})...};
|
||||
}(std::make_index_sequence<ct::arity>());
|
||||
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,18 +98,13 @@ namespace meta_hpp::detail
|
||||
using ft = function_traits<Function>;
|
||||
using ft_argument_types = typename ft::argument_types;
|
||||
|
||||
argument_list arguments;
|
||||
arguments.reserve(ft::arity);
|
||||
|
||||
[&arguments]<std::size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
return []<std::size_t... Is>(std::index_sequence<Is...>){
|
||||
[[maybe_unused]] const auto make_argument = []<std::size_t I>(std::index_sequence<I>){
|
||||
using P = type_list_at_t<I, ft_argument_types>;
|
||||
return argument{argument_state::make<P>(I, metadata_map{})};
|
||||
};
|
||||
(arguments.push_back(make_argument(std::index_sequence<Is>{})), ...);
|
||||
return argument_list{make_argument(std::index_sequence<Is>{})...};
|
||||
}(std::make_index_sequence<ft::arity>());
|
||||
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,18 +109,13 @@ namespace meta_hpp::detail
|
||||
using mt = method_traits<Method>;
|
||||
using mt_argument_types = typename mt::argument_types;
|
||||
|
||||
argument_list arguments;
|
||||
arguments.reserve(mt::arity);
|
||||
|
||||
[&arguments]<std::size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
return []<std::size_t... Is>(std::index_sequence<Is...>){
|
||||
[[maybe_unused]] const auto make_argument = []<std::size_t I>(std::index_sequence<I>){
|
||||
using P = type_list_at_t<I, mt_argument_types>;
|
||||
return argument{argument_state::make<P>(I, metadata_map{})};
|
||||
};
|
||||
(arguments.push_back(make_argument(std::index_sequence<Is>{})), ...);
|
||||
return argument_list{make_argument(std::index_sequence<Is>{})...};
|
||||
}(std::make_index_sequence<mt::arity>());
|
||||
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user