diff --git a/develop/cmake/SetupTargets.cmake b/develop/cmake/SetupTargets.cmake index 5348cdb..4e6eca0 100644 --- a/develop/cmake/SetupTargets.cmake +++ b/develop/cmake/SetupTargets.cmake @@ -30,3 +30,6 @@ target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE meta.hpp::disable_exceptions> $<$: meta.hpp::disable_rtti>) + +target_compile_definitions(${PROJECT_NAME}.setup_targets INTERFACE + $<$:META_HPP_SANITIZERS>) diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index 882d773..bb116b6 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -52,6 +52,12 @@ # define META_HPP_ASSERT(...) assert(__VA_ARGS__) // NOLINT #endif +#if defined(META_HPP_SANITIZERS) +# define META_HPP_DEV_ASSERT(...) META_HPP_ASSERT(__VA_ARGS__) +#else +# define META_HPP_DEV_ASSERT(...) (void)0 +#endif + #if !defined(META_HPP_PP_CAT) # define META_HPP_PP_CAT(x, y) META_HPP_PP_CAT_I(x, y) # define META_HPP_PP_CAT_I(x, y) x##y @@ -634,15 +640,15 @@ namespace meta_hpp::detail static vtable_t table{ .call{[](const fixed_function& self, Args... args) -> R { - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(self); const Fp& src = *buffer_cast(self.buffer_); return std::invoke(src, std::forward(args)...); }}, .move{[](fixed_function& from, fixed_function& to) noexcept { - META_HPP_ASSERT(!to); - META_HPP_ASSERT(from); + META_HPP_DEV_ASSERT(!to); + META_HPP_DEV_ASSERT(from); Fp& src = *buffer_cast(from.buffer_); std::construct_at(buffer_cast(to.buffer_), std::move(src)); @@ -653,7 +659,7 @@ namespace meta_hpp::detail }}, .destroy{[](fixed_function& self) { - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(self); Fp& src = *buffer_cast(self.buffer_); std::destroy_at(&src); @@ -666,7 +672,7 @@ namespace meta_hpp::detail template < typename F, typename Fp = std::decay_t > static void construct(fixed_function& dst, F&& fun) { - META_HPP_ASSERT(!dst); + META_HPP_DEV_ASSERT(!dst); static_assert(sizeof(Fp) <= sizeof(buffer_t)); static_assert(alignof(buffer_t) % alignof(Fp) == 0); @@ -6000,7 +6006,7 @@ namespace meta_hpp::detail { template < pointer_kind To > [[nodiscard]] decltype(auto) uarg::cast(type_registry& registry) const { - META_HPP_ASSERT(can_cast_to(registry) && "bad argument cast"); + META_HPP_DEV_ASSERT(can_cast_to(registry) && "bad argument cast"); using to_raw_type = std::remove_cv_t; @@ -6036,7 +6042,7 @@ namespace meta_hpp::detail template < non_pointer_kind To > [[nodiscard]] decltype(auto) uarg::cast(type_registry& registry) const { - META_HPP_ASSERT(can_cast_to(registry) && "bad argument cast"); + META_HPP_DEV_ASSERT(can_cast_to(registry) && "bad argument cast"); using to_raw_type_cv = std::remove_reference_t; using to_raw_type = std::remove_cv_t; @@ -6089,18 +6095,11 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < typename ArgTypeList, typename F > - auto call_with_uargs(type_registry& registry, std::span args, F&& f) { - META_HPP_ASSERT(args.size() == type_list_arity_v); - return [ args, ®istry, &f ](std::index_sequence) { - return f(args[Is].cast>(registry)...); - } - (std::make_index_sequence>()); - } - template < typename ArgTypeList > bool can_cast_all_uargs(type_registry& registry, std::span args) { - META_HPP_ASSERT(args.size() == type_list_arity_v); + if ( args.size() != type_list_arity_v ) { + return false; + } return [ args, ®istry ](std::index_sequence) { return (... && args[Is].can_cast_to>(registry)); } @@ -6109,12 +6108,23 @@ namespace meta_hpp::detail template < typename ArgTypeList > bool can_cast_all_uargs(type_registry& registry, std::span args) { - META_HPP_ASSERT(args.size() == type_list_arity_v); + if ( args.size() != type_list_arity_v ) { + return false; + } return [ args, ®istry ](std::index_sequence) { return (... && args[Is].can_cast_to>(registry)); } (std::make_index_sequence>()); } + + template < typename ArgTypeList, typename F > + auto unchecked_call_with_uargs(type_registry& registry, std::span args, F&& f) { + META_HPP_DEV_ASSERT(args.size() == type_list_arity_v); + return [ args, ®istry, &f ](std::index_sequence) { + return f(args[Is].cast>(registry)...); + } + (std::make_index_sequence>()); + } } namespace meta_hpp::detail @@ -6185,7 +6195,7 @@ namespace meta_hpp::detail && "an attempt to call a function with incorrect argument types" ); - return call_with_uargs(registry, args, [function_ptr](auto&&... all_args) { + return unchecked_call_with_uargs(registry, args, [function_ptr](auto&&... all_args) { if constexpr ( std::is_void_v ) { function_ptr(META_HPP_FWD(all_args)...); return uvalue{}; @@ -6503,7 +6513,7 @@ namespace meta_hpp::detail { template < inst_class_ref_kind Q > decltype(auto) uinst::cast(type_registry& registry) const { - META_HPP_ASSERT(can_cast_to(registry) && "bad instance cast"); + META_HPP_DEV_ASSERT(can_cast_to(registry) && "bad instance cast"); using inst_class_cv = std::remove_reference_t; using inst_class = std::remove_cv_t; @@ -6961,7 +6971,7 @@ namespace meta_hpp::detail && "an attempt to call a method with incorrect argument types" ); - return call_with_uargs(registry, args, [method_ptr, &inst, ®istry](auto&&... all_args) { + return unchecked_call_with_uargs(registry, args, [method_ptr, &inst, ®istry](auto&&... all_args) { if constexpr ( std::is_void_v ) { (inst.cast(registry).*method_ptr)(META_HPP_FWD(all_args)...); return uvalue{}; @@ -7352,7 +7362,7 @@ namespace meta_hpp::detail && "an attempt to call a constructor with incorrect argument types" ); - return call_with_uargs(registry, args, [](auto&&... all_args) -> uvalue { + return unchecked_call_with_uargs(registry, args, [](auto&&... all_args) -> uvalue { if constexpr ( as_object ) { return make_uvalue(META_HPP_FWD(all_args)...); } @@ -7383,7 +7393,7 @@ namespace meta_hpp::detail && "an attempt to call a constructor with incorrect argument types" ); - return call_with_uargs(registry, args, [mem](auto&&... all_args) { + return unchecked_call_with_uargs(registry, args, [mem](auto&&... all_args) { return std::construct_at(static_cast(mem), META_HPP_FWD(all_args)...); }); } @@ -8870,7 +8880,7 @@ namespace meta_hpp template < typename T, typename... Args, typename Tp = std::decay_t > static Tp& do_ctor(uvalue& dst, Args&&... args) { - META_HPP_ASSERT(!dst); + META_HPP_DEV_ASSERT(!dst); if constexpr ( in_internal_v ) { std::construct_at(storage_cast(dst.storage_), std::forward(args)...); @@ -8888,7 +8898,7 @@ namespace meta_hpp } static void do_move(uvalue&& self, uvalue& to) noexcept { - META_HPP_ASSERT(!to); + META_HPP_DEV_ASSERT(!to); auto&& [tag, vtable] = unpack_vtag(self); @@ -8907,7 +8917,7 @@ namespace meta_hpp } static void do_copy(const uvalue& self, uvalue& to) noexcept { - META_HPP_ASSERT(!to); + META_HPP_DEV_ASSERT(!to); auto&& [tag, vtable] = unpack_vtag(self); @@ -8969,8 +8979,8 @@ namespace meta_hpp .type = resolve_type(), .move{[](uvalue&& self, uvalue& to) noexcept { - META_HPP_ASSERT(!to); - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(!to); + META_HPP_DEV_ASSERT(self); Tp* src = storage_cast(self.storage_); @@ -8985,8 +8995,8 @@ namespace meta_hpp }}, .copy{[](const uvalue& self, uvalue& to) { - META_HPP_ASSERT(!to); - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(!to); + META_HPP_DEV_ASSERT(self); const Tp* src = storage_cast(self.storage_); @@ -9000,7 +9010,7 @@ namespace meta_hpp }}, .reset{[](uvalue& self) noexcept { - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(self); Tp* src = storage_cast(self.storage_); diff --git a/headers/meta.hpp/meta_base/base.hpp b/headers/meta.hpp/meta_base/base.hpp index 5cae5f2..f07e52d 100644 --- a/headers/meta.hpp/meta_base/base.hpp +++ b/headers/meta.hpp/meta_base/base.hpp @@ -53,6 +53,12 @@ # define META_HPP_ASSERT(...) assert(__VA_ARGS__) // NOLINT #endif +#if defined(META_HPP_SANITIZERS) +# define META_HPP_DEV_ASSERT(...) META_HPP_ASSERT(__VA_ARGS__) +#else +# define META_HPP_DEV_ASSERT(...) (void)0 +#endif + #if !defined(META_HPP_PP_CAT) # define META_HPP_PP_CAT(x, y) META_HPP_PP_CAT_I(x, y) # define META_HPP_PP_CAT_I(x, y) x##y diff --git a/headers/meta.hpp/meta_base/fixed_function.hpp b/headers/meta.hpp/meta_base/fixed_function.hpp index a39275f..47c0727 100644 --- a/headers/meta.hpp/meta_base/fixed_function.hpp +++ b/headers/meta.hpp/meta_base/fixed_function.hpp @@ -126,15 +126,15 @@ namespace meta_hpp::detail static vtable_t table{ .call{[](const fixed_function& self, Args... args) -> R { - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(self); const Fp& src = *buffer_cast(self.buffer_); return std::invoke(src, std::forward(args)...); }}, .move{[](fixed_function& from, fixed_function& to) noexcept { - META_HPP_ASSERT(!to); - META_HPP_ASSERT(from); + META_HPP_DEV_ASSERT(!to); + META_HPP_DEV_ASSERT(from); Fp& src = *buffer_cast(from.buffer_); std::construct_at(buffer_cast(to.buffer_), std::move(src)); @@ -145,7 +145,7 @@ namespace meta_hpp::detail }}, .destroy{[](fixed_function& self) { - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(self); Fp& src = *buffer_cast(self.buffer_); std::destroy_at(&src); @@ -158,7 +158,7 @@ namespace meta_hpp::detail template < typename F, typename Fp = std::decay_t > static void construct(fixed_function& dst, F&& fun) { - META_HPP_ASSERT(!dst); + META_HPP_DEV_ASSERT(!dst); static_assert(sizeof(Fp) <= sizeof(buffer_t)); static_assert(alignof(buffer_t) % alignof(Fp) == 0); diff --git a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp index d772f28..72dbffa 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp @@ -244,7 +244,7 @@ namespace meta_hpp::detail { template < pointer_kind To > [[nodiscard]] decltype(auto) uarg::cast(type_registry& registry) const { - META_HPP_ASSERT(can_cast_to(registry) && "bad argument cast"); + META_HPP_DEV_ASSERT(can_cast_to(registry) && "bad argument cast"); using to_raw_type = std::remove_cv_t; @@ -280,7 +280,7 @@ namespace meta_hpp::detail template < non_pointer_kind To > [[nodiscard]] decltype(auto) uarg::cast(type_registry& registry) const { - META_HPP_ASSERT(can_cast_to(registry) && "bad argument cast"); + META_HPP_DEV_ASSERT(can_cast_to(registry) && "bad argument cast"); using to_raw_type_cv = std::remove_reference_t; using to_raw_type = std::remove_cv_t; @@ -333,18 +333,11 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < typename ArgTypeList, typename F > - auto call_with_uargs(type_registry& registry, std::span args, F&& f) { - META_HPP_ASSERT(args.size() == type_list_arity_v); - return [ args, ®istry, &f ](std::index_sequence) { - return f(args[Is].cast>(registry)...); - } - (std::make_index_sequence>()); - } - template < typename ArgTypeList > bool can_cast_all_uargs(type_registry& registry, std::span args) { - META_HPP_ASSERT(args.size() == type_list_arity_v); + if ( args.size() != type_list_arity_v ) { + return false; + } return [ args, ®istry ](std::index_sequence) { return (... && args[Is].can_cast_to>(registry)); } @@ -353,10 +346,21 @@ namespace meta_hpp::detail template < typename ArgTypeList > bool can_cast_all_uargs(type_registry& registry, std::span args) { - META_HPP_ASSERT(args.size() == type_list_arity_v); + if ( args.size() != type_list_arity_v ) { + return false; + } return [ args, ®istry ](std::index_sequence) { return (... && args[Is].can_cast_to>(registry)); } (std::make_index_sequence>()); } + + template < typename ArgTypeList, typename F > + auto unchecked_call_with_uargs(type_registry& registry, std::span args, F&& f) { + META_HPP_DEV_ASSERT(args.size() == type_list_arity_v); + return [ args, ®istry, &f ](std::index_sequence) { + return f(args[Is].cast>(registry)...); + } + (std::make_index_sequence>()); + } } diff --git a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp index 89475f4..c20e7d6 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp @@ -183,7 +183,7 @@ namespace meta_hpp::detail { template < inst_class_ref_kind Q > decltype(auto) uinst::cast(type_registry& registry) const { - META_HPP_ASSERT(can_cast_to(registry) && "bad instance cast"); + META_HPP_DEV_ASSERT(can_cast_to(registry) && "bad instance cast"); using inst_class_cv = std::remove_reference_t; using inst_class = std::remove_cv_t; diff --git a/headers/meta.hpp/meta_states/constructor.hpp b/headers/meta.hpp/meta_states/constructor.hpp index 42d9890..99bead5 100644 --- a/headers/meta.hpp/meta_states/constructor.hpp +++ b/headers/meta.hpp/meta_states/constructor.hpp @@ -43,7 +43,7 @@ namespace meta_hpp::detail && "an attempt to call a constructor with incorrect argument types" ); - return call_with_uargs(registry, args, [](auto&&... all_args) -> uvalue { + return unchecked_call_with_uargs(registry, args, [](auto&&... all_args) -> uvalue { if constexpr ( as_object ) { return make_uvalue(META_HPP_FWD(all_args)...); } @@ -74,7 +74,7 @@ namespace meta_hpp::detail && "an attempt to call a constructor with incorrect argument types" ); - return call_with_uargs(registry, args, [mem](auto&&... all_args) { + return unchecked_call_with_uargs(registry, args, [mem](auto&&... all_args) { return std::construct_at(static_cast(mem), META_HPP_FWD(all_args)...); }); } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 7408383..92dc4dd 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -45,7 +45,7 @@ namespace meta_hpp::detail && "an attempt to call a function with incorrect argument types" ); - return call_with_uargs(registry, args, [function_ptr](auto&&... all_args) { + return unchecked_call_with_uargs(registry, args, [function_ptr](auto&&... all_args) { if constexpr ( std::is_void_v ) { function_ptr(META_HPP_FWD(all_args)...); return uvalue{}; diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index e9e385d..685e20b 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -52,7 +52,7 @@ namespace meta_hpp::detail && "an attempt to call a method with incorrect argument types" ); - return call_with_uargs(registry, args, [method_ptr, &inst, ®istry](auto&&... all_args) { + return unchecked_call_with_uargs(registry, args, [method_ptr, &inst, ®istry](auto&&... all_args) { if constexpr ( std::is_void_v ) { (inst.cast(registry).*method_ptr)(META_HPP_FWD(all_args)...); return uvalue{}; diff --git a/headers/meta.hpp/meta_uvalue/uvalue.hpp b/headers/meta.hpp/meta_uvalue/uvalue.hpp index 4ee0bf6..0232a82 100644 --- a/headers/meta.hpp/meta_uvalue/uvalue.hpp +++ b/headers/meta.hpp/meta_uvalue/uvalue.hpp @@ -73,7 +73,7 @@ namespace meta_hpp template < typename T, typename... Args, typename Tp = std::decay_t > static Tp& do_ctor(uvalue& dst, Args&&... args) { - META_HPP_ASSERT(!dst); + META_HPP_DEV_ASSERT(!dst); if constexpr ( in_internal_v ) { std::construct_at(storage_cast(dst.storage_), std::forward(args)...); @@ -91,7 +91,7 @@ namespace meta_hpp } static void do_move(uvalue&& self, uvalue& to) noexcept { - META_HPP_ASSERT(!to); + META_HPP_DEV_ASSERT(!to); auto&& [tag, vtable] = unpack_vtag(self); @@ -110,7 +110,7 @@ namespace meta_hpp } static void do_copy(const uvalue& self, uvalue& to) noexcept { - META_HPP_ASSERT(!to); + META_HPP_DEV_ASSERT(!to); auto&& [tag, vtable] = unpack_vtag(self); @@ -172,8 +172,8 @@ namespace meta_hpp .type = resolve_type(), .move{[](uvalue&& self, uvalue& to) noexcept { - META_HPP_ASSERT(!to); - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(!to); + META_HPP_DEV_ASSERT(self); Tp* src = storage_cast(self.storage_); @@ -188,8 +188,8 @@ namespace meta_hpp }}, .copy{[](const uvalue& self, uvalue& to) { - META_HPP_ASSERT(!to); - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(!to); + META_HPP_DEV_ASSERT(self); const Tp* src = storage_cast(self.storage_); @@ -203,7 +203,7 @@ namespace meta_hpp }}, .reset{[](uvalue& self) noexcept { - META_HPP_ASSERT(self); + META_HPP_DEV_ASSERT(self); Tp* src = storage_cast(self.storage_);