diff --git a/src/entt/core/algorithm.hpp b/src/entt/core/algorithm.hpp index f9ba2abd8..c44a7d65b 100644 --- a/src/entt/core/algorithm.hpp +++ b/src/entt/core/algorithm.hpp @@ -80,7 +80,7 @@ struct insertion_sort { */ template struct radix_sort { - static_assert((N % Bit) == 0); + static_assert((N % Bit) == 0, "The maximum number of bits to sort must be a multiple of the number of bits processed per pass"); /** * @brief Sorts the elements in a range. diff --git a/src/entt/core/ident.hpp b/src/entt/core/ident.hpp index f146d2ff9..984ad2a01 100644 --- a/src/entt/core/ident.hpp +++ b/src/entt/core/ident.hpp @@ -46,7 +46,7 @@ class identifier { template static constexpr id_type get(std::index_sequence) { - static_assert(std::disjunction_v...>); + static_assert(std::disjunction_v...>, "Invalid type"); return (0 + ... + (std::is_same_v> ? id_type(Indexes) : id_type{})); } diff --git a/src/entt/core/type_traits.hpp b/src/entt/core/type_traits.hpp index 496a613a6..f3c4bb835 100644 --- a/src/entt/core/type_traits.hpp +++ b/src/entt/core/type_traits.hpp @@ -193,7 +193,7 @@ inline constexpr auto is_equality_comparable_v = is_equality_comparable::v */ template class member_class { - static_assert(std::is_member_pointer_v); + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); template static Class * clazz(Ret(Class:: *)(Args...)); diff --git a/src/entt/entity/group.hpp b/src/entt/entity/group.hpp index 56301519b..9107550fe 100644 --- a/src/entt/entity/group.hpp +++ b/src/entt/entity/group.hpp @@ -385,7 +385,7 @@ public: template void sort(Compare compare, Sort algo = Sort{}, Args &&... args) { if constexpr(sizeof...(Component) == 0) { - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v, "Invalid comparison function"); handler->sort(handler->begin(), handler->end(), std::move(compare), std::move(algo), std::forward(args)...); } else if constexpr(sizeof...(Component) == 1) { handler->sort(handler->begin(), handler->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) { @@ -812,7 +812,7 @@ public: auto *cpool = std::get<0>(pools); if constexpr(sizeof...(Component) == 0) { - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v, "Invalid comparison function"); cpool->sort(cpool->end()-*length, cpool->end(), std::move(compare), std::move(algo), std::forward(args)...); } else if constexpr(sizeof...(Component) == 1) { cpool->sort(cpool->end()-*length, cpool->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) { diff --git a/src/entt/entity/helper.hpp b/src/entt/entity/helper.hpp index 3a88346b5..49bfb0c7f 100644 --- a/src/entt/entity/helper.hpp +++ b/src/entt/entity/helper.hpp @@ -122,7 +122,7 @@ as_group(const basic_registry &) ENTT_NOEXCEPT -> as_group */ template void invoke(basic_registry ®, const Entity entt) { - static_assert(std::is_member_function_pointer_v); + static_assert(std::is_member_function_pointer_v, "Invalid pointer to non-static member function"); delegate &, const Entity)> func; func.template connect(reg.template get>(entt)); func(reg, entt); diff --git a/src/entt/entity/observer.hpp b/src/entt/entity/observer.hpp index 961effae9..e9e3ba73b 100644 --- a/src/entt/entity/observer.hpp +++ b/src/entt/entity/observer.hpp @@ -257,7 +257,7 @@ class basic_observer { template void connect(basic_registry ®, std::index_sequence) { - static_assert(sizeof...(Matcher) < std::numeric_limits::digits); + static_assert(sizeof...(Matcher) < std::numeric_limits::digits, "Too many matchers"); (matcher_handler::template connect(*this, reg), ...); release = &basic_observer::disconnect; } @@ -408,8 +408,6 @@ public: */ template void each(Func func) const { - static_assert(std::is_invocable_v); - for(const auto entity: *this) { func(entity); } diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index f9ce83e4e..267957825 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -45,7 +45,7 @@ class basic_registry { template struct pool_handler final: storage { - static_assert(std::is_same_v>); + static_assert(std::is_same_v>, "Invalid component type"); std::size_t super{}; auto on_construct() ENTT_NOEXCEPT { @@ -129,12 +129,11 @@ class basic_registry { template struct group_handler, get_t, Owned...> { - static_assert(std::conjunction_v>..., std::is_same>..., std::is_same>...>); + static_assert(std::conjunction_v>..., std::is_same>..., std::is_same>...>, "One or more component types are invalid"); std::conditional_t, std::size_t> current{}; template void maybe_valid_if(basic_registry &owner, const Entity entt) { - static_assert(std::disjunction_v>..., std::is_same>..., std::is_same>...>); [[maybe_unused]] const auto cpools = std::forward_as_tuple(owner.assure()...); const auto is_valid = ((std::is_same_v || std::get &>(cpools).contains(entt)) && ...) @@ -182,7 +181,6 @@ class basic_registry { template const pool_handler & assure() const { - static_assert(std::is_same_v>); const sparse_set *cpool; if constexpr(has_type_index_v) { @@ -674,7 +672,7 @@ public: */ template void insert(EIt first, EIt last, CIt from, CIt to) { - static_assert(std::is_constructible_v::value_type>); + static_assert(std::is_constructible_v::value_type>, "Invalid value type"); ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); })); assure().insert(*this, first, last, from, to); } @@ -1035,8 +1033,6 @@ public: */ template void each(Func func) const { - static_assert(std::is_invocable_v); - if(destroyed == null) { for(auto pos = entities.size(); pos; --pos) { func(entities[pos-1]); @@ -1078,8 +1074,6 @@ public: */ template void orphans(Func func) const { - static_assert(std::is_invocable_v); - each([this, &func](const auto entity) { if(orphan(entity)) { func(entity); @@ -1296,14 +1290,14 @@ public: */ template entt::basic_view, Component...> view(exclude_t = {}) const { - static_assert(sizeof...(Component) > 0); + static_assert(sizeof...(Component) > 0, "Exclusion-only views are not supported"); return { assure>()..., assure()... }; } /*! @copydoc view */ template entt::basic_view, Component...> view(exclude_t = {}) { - static_assert(sizeof...(Component) > 0); + static_assert(sizeof...(Component) > 0, "Exclusion-only views are not supported"); return { assure>()..., assure()... }; } @@ -1347,8 +1341,8 @@ public: */ template entt::basic_group, get_t, Owned...> group(get_t, exclude_t = {}) { - static_assert(sizeof...(Owned) + sizeof...(Get) > 0); - static_assert(sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude) > 1); + static_assert(sizeof...(Owned) + sizeof...(Get) > 0, "Exclusion-only views are not supported"); + static_assert(sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude) > 1, "Single component groups are not allowed"); using handler_type = group_handler, get_t...>, std::decay_t...>; @@ -1443,7 +1437,7 @@ public: */ template entt::basic_group, get_t, Owned...> group(get_t, exclude_t = {}) const { - static_assert(std::conjunction_v..., std::is_const...>); + static_assert(std::conjunction_v..., std::is_const...>, "Invalid non-const type"); return const_cast(this)->group(entt::get, exclude); } @@ -1472,7 +1466,7 @@ public: */ template entt::basic_group, get_t<>, Owned...> group(exclude_t = {}) const { - static_assert(std::conjunction_v...>); + static_assert(std::conjunction_v...>, "Invalid non-const type"); return const_cast(this)->group(exclude); } diff --git a/src/entt/entity/snapshot.hpp b/src/entt/entity/snapshot.hpp index 33c790a2e..b46925273 100644 --- a/src/entt/entity/snapshot.hpp +++ b/src/entt/entity/snapshot.hpp @@ -336,7 +336,7 @@ class basic_continuous_loader { } else if constexpr(std::is_same_v) { other.emplace(map(pair.first), std::move(pair.second)); } else { - static_assert(std::is_same_v); + static_assert(std::is_same_v, "Neither the key nor the value are of entity type"); other.emplace(std::move(pair.first), map(pair.second)); } } @@ -348,7 +348,7 @@ class basic_continuous_loader { auto update(char, Container &container) -> decltype(typename Container::value_type{}, void()) { // vector like container - static_assert(std::is_same_v); + static_assert(std::is_same_v, "Invalid value type"); for(auto &&entt: container) { entt = map(entt); diff --git a/src/entt/entity/sparse_set.hpp b/src/entt/entity/sparse_set.hpp index cf8e770fb..721247455 100644 --- a/src/entt/entity/sparse_set.hpp +++ b/src/entt/entity/sparse_set.hpp @@ -41,7 +41,7 @@ namespace entt { */ template class sparse_set { - static_assert(ENTT_PAGE_SIZE && ((ENTT_PAGE_SIZE & (ENTT_PAGE_SIZE - 1)) == 0)); + static_assert(ENTT_PAGE_SIZE && ((ENTT_PAGE_SIZE & (ENTT_PAGE_SIZE - 1)) == 0), "ENTT_PAGE_SIZE must be a power of two"); static constexpr auto entt_per_page = ENTT_PAGE_SIZE / sizeof(Entity); using traits_type = entt_traits>; diff --git a/src/entt/entity/storage.hpp b/src/entt/entity/storage.hpp index 2c3bdb7a4..e2155f32c 100644 --- a/src/entt/entity/storage.hpp +++ b/src/entt/entity/storage.hpp @@ -46,8 +46,7 @@ namespace entt { */ template> class storage: public sparse_set { - static_assert(std::is_move_constructible_v); - static_assert(std::is_move_assignable_v); + static_assert(std::is_move_constructible_v && std::is_move_assignable_v, "The managed type must be at least move constructible and assignable"); using underlying_type = sparse_set; using traits_type = entt_traits>; diff --git a/src/entt/entity/view.hpp b/src/entt/entity/view.hpp index 20cb27eeb..9180cf051 100644 --- a/src/entt/entity/view.hpp +++ b/src/entt/entity/view.hpp @@ -405,7 +405,7 @@ public: ENTT_ASSERT(contains(entt)); if constexpr(sizeof...(Comp) == 0) { - static_assert(sizeof...(Component) == 1); + static_assert(sizeof...(Component) == 1, "Invalid component type"); return (std::get *>(pools)->get(entt), ...); } else if constexpr(sizeof...(Comp) == 1) { return (std::get *>(pools)->get(entt), ...); @@ -672,7 +672,7 @@ public: */ template decltype(auto) get(const entity_type entt) const { - static_assert(std::is_same_v); + static_assert(std::is_same_v, "Invalid component type"); ENTT_ASSERT(contains(entt)); return pool->get(entt); } diff --git a/src/entt/meta/factory.hpp b/src/entt/meta/factory.hpp index 4dac226c0..e51d5ffec 100644 --- a/src/entt/meta/factory.hpp +++ b/src/entt/meta/factory.hpp @@ -96,7 +96,7 @@ bool setter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any index, if constexpr(std::is_function_v>> || std::is_member_function_pointer_v) { using helper_type = meta_function_helper_t; using data_type = std::tuple_element_t, typename helper_type::args_type>; - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v, "Invalid function or member function"); auto * const clazz = instance.try_cast(); auto * const direct = value.try_cast(); @@ -106,7 +106,7 @@ bool setter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any index, } } else if constexpr(std::is_member_object_pointer_v) { using data_type = std::remove_cv_t().*Data)>>; - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v, "Invalid data member"); auto * const clazz = instance.try_cast(); if constexpr(std::is_array_v) { @@ -127,7 +127,7 @@ bool setter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any index, } } } else { - static_assert(std::is_pointer_v); + static_assert(std::is_pointer_v, "Invalid pointer to data type"); using data_type = std::remove_cv_t>; if constexpr(std::is_array_v) { @@ -162,18 +162,18 @@ meta_any getter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any in } else if constexpr(std::is_same_v) { return meta_any{std::ref(std::forward(value))}; } else { - static_assert(std::is_same_v); + static_assert(std::is_same_v, "Policy not supported"); return meta_any{std::forward(value)}; } }; if constexpr(std::is_function_v>> || std::is_member_function_pointer_v) { - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v, "Invalid function or member function"); auto * const clazz = instance.try_cast(); return clazz ? dispatch(std::invoke(Data, *clazz)) : meta_any{}; } else if constexpr(std::is_member_object_pointer_v) { using data_type = std::remove_cv_t().*Data)>>; - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v, "Invalid data member"); auto * const clazz = instance.try_cast(); if constexpr(std::is_array_v) { @@ -183,7 +183,7 @@ meta_any getter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any in return clazz ? dispatch(std::invoke(Data, clazz)) : meta_any{}; } } else { - static_assert(std::is_pointer_v>); + static_assert(std::is_pointer_v>, "Invalid pointer to data type"); if constexpr(std::is_array_v>) { auto * const idx = index.try_cast(); @@ -206,7 +206,7 @@ meta_any invoke([[maybe_unused]] meta_any instance, meta_any *args, std::index_s } else if constexpr(std::is_same_v) { return meta_any{std::ref(std::invoke(Candidate, *params...))}; } else { - static_assert(std::is_same_v); + static_assert(std::is_same_v, "Policy not supported"); return meta_any{std::invoke(Candidate, *params...)}; } }; @@ -402,7 +402,6 @@ public: return meta_factory{&node->prop}; } - /*! @copydoc type */ /** * @brief Assigns a meta base to a meta type. * @@ -413,7 +412,7 @@ public: */ template auto base() ENTT_NOEXCEPT { - static_assert(std::is_base_of_v); + static_assert(std::is_base_of_v, "Invalid base type"); auto * const type = internal::meta_info::resolve(); static internal::meta_base_node node{ @@ -443,7 +442,7 @@ public: */ template auto conv() ENTT_NOEXCEPT { - static_assert(std::is_convertible_v); + static_assert(std::is_convertible_v, "Could not convert to the required type"); auto * const type = internal::meta_info::resolve(); static internal::meta_conv_node node{ @@ -511,7 +510,7 @@ public: template auto ctor() ENTT_NOEXCEPT { using helper_type = internal::meta_function_helper_t; - static_assert(std::is_same_v); + static_assert(std::is_same_v, "The function doesn't return an object of the required type"); auto * const type = internal::meta_info::resolve(); static internal::meta_ctor_node node{ @@ -583,7 +582,7 @@ public: */ template auto dtor() ENTT_NOEXCEPT { - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v, "The function doesn't accept an object of the type provided"); auto * const type = internal::meta_info::resolve(); static internal::meta_dtor_node node{ @@ -620,7 +619,7 @@ public: internal::meta_data_node *curr = nullptr; if constexpr(std::is_same_v) { - static_assert(std::is_same_v); + static_assert(std::is_same_v, "Policy not supported"); static internal::meta_data_node node{ {}, @@ -652,7 +651,6 @@ public: curr = &node; } else { - static_assert(std::is_pointer_v>); using data_type = std::remove_pointer_t>; static internal::meta_data_node node{ @@ -702,7 +700,7 @@ public: template auto data(const id_type id) ENTT_NOEXCEPT { using underlying_type = std::invoke_result_t; - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v, "Invalid setter and/or getter"); auto * const type = internal::meta_info::resolve(); static internal::meta_data_node node{ diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 718d84565..b4d82a0f4 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -222,7 +222,7 @@ struct ENTT_API meta_context { template struct ENTT_API meta_node { - static_assert(std::is_same_v>>); + static_assert(std::is_same_v>>, "Invalid type"); static meta_type_node * resolve() ENTT_NOEXCEPT { static meta_type_node node{ @@ -670,7 +670,7 @@ struct meta_handle { if constexpr(std::is_same_v>, meta_any>) { any = *value; } else { - static_assert(std::is_lvalue_reference_v); + static_assert(std::is_lvalue_reference_v, "Lvalue reference required"); any = std::ref(value); } } diff --git a/src/entt/process/process.hpp b/src/entt/process/process.hpp index 93add6e9a..1ff4a6901 100644 --- a/src/entt/process/process.hpp +++ b/src/entt/process/process.hpp @@ -169,7 +169,7 @@ public: /*! @brief Default destructor. */ virtual ~process() { - static_assert(std::is_base_of_v); + static_assert(std::is_base_of_v, "Incorrect use of the class template"); } /** diff --git a/src/entt/process/scheduler.hpp b/src/entt/process/scheduler.hpp index 4c35c38de..32a079353 100644 --- a/src/entt/process/scheduler.hpp +++ b/src/entt/process/scheduler.hpp @@ -63,7 +63,7 @@ class scheduler { template continuation then(Args &&... args) { - static_assert(std::is_base_of_v, Proc>); + static_assert(std::is_base_of_v, Proc>, "Invalid process type"); auto proc = typename process_handler::instance_type{new Proc{std::forward(args)...}, &scheduler::deleter}; handler->next.reset(new process_handler{std::move(proc), &scheduler::update, &scheduler::abort, nullptr}); handler = handler->next.get(); @@ -175,7 +175,7 @@ public: */ template auto attach(Args &&... args) { - static_assert(std::is_base_of_v, Proc>); + static_assert(std::is_base_of_v, Proc>, "Invalid process type"); auto proc = typename process_handler::instance_type{new Proc{std::forward(args)...}, &scheduler::deleter}; process_handler handler{std::move(proc), &scheduler::update, &scheduler::abort, nullptr}; // forces the process to exit the uninitialized state diff --git a/src/entt/resource/cache.hpp b/src/entt/resource/cache.hpp index 4ddf91baf..49240bd10 100644 --- a/src/entt/resource/cache.hpp +++ b/src/entt/resource/cache.hpp @@ -92,7 +92,7 @@ struct cache { */ template entt::handle load(const id_type id, Args &&... args) { - static_assert(std::is_base_of_v, Loader>); + static_assert(std::is_base_of_v, Loader>, "Invalid loader type"); entt::handle resource{}; if(auto it = resources.find(id); it == resources.cend()) { diff --git a/src/entt/signal/dispatcher.hpp b/src/entt/signal/dispatcher.hpp index 2d93c4469..1c9cbb0aa 100644 --- a/src/entt/signal/dispatcher.hpp +++ b/src/entt/signal/dispatcher.hpp @@ -84,7 +84,7 @@ class dispatcher { template pool_handler & assure() { - static_assert(std::is_same_v>); + static_assert(std::is_same_v>, "Invalid event type"); if constexpr(has_type_index_v) { const auto index = type_index::value(); diff --git a/src/entt/signal/emitter.hpp b/src/entt/signal/emitter.hpp index 9075bac38..f412a0c76 100644 --- a/src/entt/signal/emitter.hpp +++ b/src/entt/signal/emitter.hpp @@ -126,7 +126,7 @@ class emitter { template const pool_handler & assure() const { - static_assert(std::is_same_v>); + static_assert(std::is_same_v>, "Invalid event type"); if constexpr(has_type_index_v) { const auto index = type_index::value(); @@ -187,7 +187,7 @@ public: /*! @brief Default destructor. */ virtual ~emitter() { - static_assert(std::is_base_of_v, Derived>); + static_assert(std::is_base_of_v, Derived>, "Incorrect use of the class template"); } /*! @brief Default move constructor. */