Просмотр исходного кода

entt: there is a reason why an allocator concept does not exist...

skypjack 3 недель назад
Родитель
Сommit
f93d28981f

+ 9 - 7
src/entt/container/dense_map.hpp

@@ -17,7 +17,6 @@
 #include "../config/config.h"
 #include "../core/bit.hpp"
 #include "../core/compressed_pair.hpp"
-#include "../core/concepts.hpp"
 #include "../core/iterator.hpp"
 #include "../core/memory.hpp"
 #include "../core/type_traits.hpp"
@@ -40,16 +39,18 @@ struct dense_map_node final {
         : next{pos},
           element{std::forward<Args>(args)...} {}
 
-    template<typename... Args>
-    dense_map_node(std::allocator_arg_t, const allocator_like auto &allocator, const std::size_t pos, Args &&...args)
+    template<typename Allocator, typename... Args>
+    dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
         : next{pos},
           element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
 
-    dense_map_node(std::allocator_arg_t, const allocator_like auto &allocator, const dense_map_node &other)
+    template<typename Allocator>
+    dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
         : next{other.next},
           element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
 
-    dense_map_node(std::allocator_arg_t, const allocator_like auto &allocator, dense_map_node &&other)
+    template<typename Allocator>
+    dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
         : next{other.next},
           element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
 
@@ -227,8 +228,9 @@ private:
  * @tparam Type Mapped type of the associative container.
  * @tparam Hash Type of function to use to hash the keys.
  * @tparam KeyEqual Type of function to use to compare the keys for equality.
+ * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Key, typename Type, typename Hash, typename KeyEqual, allocator_like Allocator>
+template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
 class dense_map {
     static constexpr float default_threshold = 0.875f;
     static constexpr std::size_t minimum_capacity = 8u;
@@ -1015,7 +1017,7 @@ private:
 /*! @cond ENTT_INTERNAL */
 namespace std {
 
-template<typename Key, typename Value, entt::allocator_like Allocator>
+template<typename Key, typename Value, typename Allocator>
 struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
     : std::true_type {};
 

+ 2 - 1
src/entt/container/dense_set.hpp

@@ -190,8 +190,9 @@ private:
  * @tparam Type Value type of the associative container.
  * @tparam Hash Type of function to use to hash the values.
  * @tparam KeyEqual Type of function to use to compare the values for equality.
+ * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Type, typename Hash, typename KeyEqual, allocator_like Allocator>
+template<typename Type, typename Hash, typename KeyEqual, typename Allocator>
 class dense_set {
     static constexpr float default_threshold = 0.875f;
     static constexpr std::size_t minimum_capacity = 8u;

+ 2 - 3
src/entt/container/fwd.hpp

@@ -5,7 +5,6 @@
 #include <memory>
 #include <utility>
 #include <vector>
-#include "../core/concepts.hpp"
 
 namespace entt {
 
@@ -14,14 +13,14 @@ template<
     typename Type,
     typename = std::hash<Key>,
     typename = std::equal_to<>,
-    allocator_like = std::allocator<std::pair<const Key, Type>>>
+    typename = std::allocator<std::pair<const Key, Type>>>
 class dense_map;
 
 template<
     typename Type,
     typename = std::hash<Type>,
     typename = std::equal_to<>,
-    allocator_like = std::allocator<Type>>
+    typename = std::allocator<Type>>
 class dense_set;
 
 template<typename...>

+ 4 - 2
src/entt/container/table.hpp

@@ -170,9 +170,11 @@ public:
 
     /**
      * @brief Constructs the underlying containers using a given allocator.
+     * @tparam Allocator Type of allocator.
      * @param allocator A valid allocator.
      */
-    explicit basic_table(const allocator_like auto &allocator)
+    template<typename Allocator>
+    explicit basic_table(const Allocator &allocator)
         : payload{Container{allocator}...} {}
 
     /**
@@ -422,7 +424,7 @@ private:
 /*! @cond ENTT_INTERNAL */
 namespace std {
 
-template<typename... Container, entt::allocator_like Allocator>
+template<typename... Container, typename Allocator>
 struct uses_allocator<entt::basic_table<Container...>, Allocator>
     : std::bool_constant<(std::uses_allocator_v<Container, Allocator> && ...)> {};
 

+ 0 - 11
src/entt/core/concepts.hpp

@@ -1,7 +1,6 @@
 #ifndef ENTT_CORE_CONCEPTS_HPP
 #define ENTT_CORE_CONCEPTS_HPP
 
-#include <concepts>
 #include <type_traits>
 
 namespace entt {
@@ -13,16 +12,6 @@ namespace entt {
 template<typename Type>
 concept cvref_unqualified = std::is_same_v<std::remove_cvref_t<Type>, Type>;
 
-/**
- * @brief Specifies that a type is likely an allocator type.
- * @tparam Type Type to check.
- */
-template<typename Type>
-concept allocator_like = requires(Type alloc, typename Type::value_type *value) {
-    { alloc.allocate(0) } -> std::same_as<decltype(value)>;
-    { alloc.deallocate(value, 0) } -> std::same_as<void>;
-};
-
 } // namespace entt
 
 #endif

+ 25 - 22
src/entt/core/memory.hpp

@@ -7,7 +7,6 @@
 #include <type_traits>
 #include <utility>
 #include "../config/config.h"
-#include "../core/concepts.hpp"
 #include "../stl/memory.hpp"
 
 namespace entt {
@@ -18,7 +17,7 @@ namespace entt {
  * @param lhs A valid allocator.
  * @param rhs Another valid allocator.
  */
-template<allocator_like Allocator>
+template<typename Allocator>
 constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
     if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
         lhs = rhs;
@@ -31,7 +30,7 @@ constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator
  * @param lhs A valid allocator.
  * @param rhs Another valid allocator.
  */
-template<allocator_like Allocator>
+template<typename Allocator>
 constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
     if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
         lhs = std::move(rhs);
@@ -44,7 +43,7 @@ constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator
  * @param lhs A valid allocator.
  * @param rhs Another valid allocator.
  */
-template<allocator_like Allocator>
+template<typename Allocator>
 constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
     if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
         using std::swap;
@@ -58,7 +57,7 @@ constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[ma
  * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<allocator_like Allocator>
+template<typename Allocator>
 struct allocation_deleter: private Allocator {
     /*! @brief Allocator type. */
     using allocator_type = Allocator;
@@ -92,7 +91,7 @@ struct allocation_deleter: private Allocator {
  * @param args Parameters to use to construct the object.
  * @return A properly initialized unique pointer with a custom deleter.
  */
-template<typename Type, allocator_like Allocator, typename... Args>
+template<typename Type, typename Allocator, typename... Args>
 constexpr auto allocate_unique(Allocator &allocator, Args &&...args) {
     static_assert(!std::is_array_v<Type>, "Array types are not supported");
 
@@ -118,7 +117,7 @@ namespace internal {
 
 template<typename Type>
 struct uses_allocator_construction {
-    template<allocator_like Allocator, typename... Params>
+    template<typename Allocator, typename... Params>
     static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
         if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
             return std::forward_as_tuple(std::forward<Params>(params)...);
@@ -139,30 +138,31 @@ template<typename Type, typename Other>
 struct uses_allocator_construction<std::pair<Type, Other>> {
     using type = std::pair<Type, Other>;
 
-    template<typename First, typename Second>
-    static constexpr auto args(const allocator_like auto &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
+    template<typename Allocator, typename First, typename Second>
+    static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
         return std::make_tuple(
             std::piecewise_construct,
             std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
             std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
     }
 
-    static constexpr auto args(const allocator_like auto &allocator) noexcept {
+    template<typename Allocator>
+    static constexpr auto args(const Allocator &allocator) noexcept {
         return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
     }
 
-    template<typename First, typename Second>
-    static constexpr auto args(const allocator_like auto &allocator, First &&first, Second &&second) noexcept {
+    template<typename Allocator, typename First, typename Second>
+    static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
         return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
     }
 
-    template<typename First, typename Second>
-    static constexpr auto args(const allocator_like auto &allocator, const std::pair<First, Second> &value) noexcept {
+    template<typename Allocator, typename First, typename Second>
+    static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
         return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
     }
 
-    template<typename First, typename Second>
-    static constexpr auto args(const allocator_like auto &allocator, std::pair<First, Second> &&value) noexcept {
+    template<typename Allocator, typename First, typename Second>
+    static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
         return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
     }
 };
@@ -177,13 +177,14 @@ struct uses_allocator_construction<std::pair<Type, Other>> {
  * create an object of a given type by means of uses-allocator construction.
  *
  * @tparam Type Type to return arguments for.
+ * @tparam Allocator Type of allocator used to manage memory and elements.
  * @tparam Args Types of arguments to use to construct the object.
  * @param allocator The allocator to use.
  * @param args Parameters to use to construct the object.
  * @return The arguments needed to create an object of the given type.
  */
-template<typename Type, typename... Args>
-constexpr auto uses_allocator_construction_args(const allocator_like auto &allocator, Args &&...args) noexcept {
+template<typename Type, typename Allocator, typename... Args>
+constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
     return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
 }
 
@@ -194,13 +195,14 @@ constexpr auto uses_allocator_construction_args(const allocator_like auto &alloc
  * means of uses-allocator construction.
  *
  * @tparam Type Type of object to create.
+ * @tparam Allocator Type of allocator used to manage memory and elements.
  * @tparam Args Types of arguments to use to construct the object.
  * @param allocator The allocator to use.
  * @param args Parameters to use to construct the object.
  * @return A newly created object of the given type.
  */
-template<typename Type, typename... Args>
-constexpr Type make_obj_using_allocator(const allocator_like auto &allocator, Args &&...args) {
+template<typename Type, typename Allocator, typename... Args>
+constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
     return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
 }
 
@@ -211,14 +213,15 @@ constexpr Type make_obj_using_allocator(const allocator_like auto &allocator, Ar
  * means of uses-allocator construction at an uninitialized memory location.
  *
  * @tparam Type Type of object to create.
+ * @tparam Allocator Type of allocator used to manage memory and elements.
  * @tparam Args Types of arguments to use to construct the object.
  * @param value Memory location in which to place the object.
  * @param allocator The allocator to use.
  * @param args Parameters to use to construct the object.
  * @return A pointer to the newly created object of the given type.
  */
-template<typename Type, typename... Args>
-constexpr Type *uninitialized_construct_using_allocator(Type *value, const allocator_like auto &allocator, Args &&...args) {
+template<typename Type, typename Allocator, typename... Args>
+constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
     return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
 }
 

+ 7 - 7
src/entt/entity/fwd.hpp

@@ -47,10 +47,10 @@ enum class deletion_policy : std::uint8_t {
 template<cvref_unqualified Type, entity_like Entity = entity>
 struct component_traits;
 
-template<entity_like Entity = entity, allocator_like = std::allocator<Entity>>
+template<entity_like Entity = entity, typename = std::allocator<Entity>>
 class basic_sparse_set;
 
-template<typename Type, entity_like = entity, allocator_like = std::allocator<Type>>
+template<typename Type, entity_like = entity, typename = std::allocator<Type>>
 class basic_storage;
 
 template<typename, typename>
@@ -59,13 +59,13 @@ class basic_sigh_mixin;
 template<typename, typename>
 class basic_reactive_mixin;
 
-template<entity_like Entity = entity, allocator_like = std::allocator<Entity>>
+template<entity_like Entity = entity, typename = std::allocator<Entity>>
 class basic_registry;
 
 template<typename, typename>
 class basic_view;
 
-template<typename Type, allocator_like = std::allocator<Type *>>
+template<typename Type, typename = std::allocator<Type *>>
 class basic_runtime_view;
 
 template<typename, typename, typename>
@@ -241,7 +241,7 @@ struct type_list_transform<owned_t<Type...>, Op> {
  * @tparam Entity A valid entity type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Type, entity_like Entity = entity, allocator_like Allocator = std::allocator<Type>>
+template<typename Type, entity_like Entity = entity, typename Allocator = std::allocator<Type>>
 struct storage_type {
     /*! @brief Type-to-storage conversion result. */
     using type = ENTT_STORAGE(sigh_mixin, basic_storage<Type, Entity, Allocator>);
@@ -255,7 +255,7 @@ struct reactive final {};
  * @tparam Entity A valid entity type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<entity_like Entity, allocator_like Allocator>
+template<entity_like Entity, typename Allocator>
 struct storage_type<reactive, Entity, Allocator> {
     /*! @brief Type-to-storage conversion result. */
     using type = ENTT_STORAGE(reactive_mixin, basic_storage<reactive, Entity, Allocator>);
@@ -274,7 +274,7 @@ using storage_type_t = storage_type<Args...>::type;
  * @tparam Entity A valid entity type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Type, entity_like Entity = entity, allocator_like Allocator = std::allocator<std::remove_const_t<Type>>>
+template<typename Type, entity_like Entity = entity, typename Allocator = std::allocator<std::remove_const_t<Type>>>
 struct storage_for {
     /*! @brief Type-to-storage conversion result. */
     using type = constness_as_t<storage_type_t<std::remove_const_t<Type>, Entity, Allocator>, Type>;

+ 2 - 3
src/entt/entity/group.hpp

@@ -10,7 +10,6 @@
 #include <utility>
 #include "../config/config.h"
 #include "../core/algorithm.hpp"
-#include "../core/concepts.hpp"
 #include "../core/fwd.hpp"
 #include "../core/iterator.hpp"
 #include "../core/type_info.hpp"
@@ -206,8 +205,8 @@ class group_handler<Type, 0u, Get, Exclude> final: public group_descriptor {
 public:
     using common_type = Type;
 
-    template<typename... GType, typename... EType>
-    group_handler(const allocator_like auto &allocator, std::tuple<GType &...> gpool, std::tuple<EType &...> epool)
+    template<typename Allocator, typename... GType, typename... EType>
+    group_handler(const Allocator &allocator, std::tuple<GType &...> gpool, std::tuple<EType &...> epool)
         : pools{std::apply([](auto &&...cpool) { return std::array<common_type *, Get>{&cpool...}; }, gpool)},
           filter{std::apply([](auto &&...cpool) { return std::array<common_type *, Exclude>{&cpool...}; }, epool)},
           elem{allocator} {

+ 2 - 2
src/entt/entity/registry.hpp

@@ -131,7 +131,7 @@ private:
     It it;
 };
 
-template<allocator_like Allocator>
+template<typename Allocator>
 class registry_context {
     using alloc_traits = std::allocator_traits<Allocator>;
     using allocator_type = alloc_traits::template rebind_alloc<std::pair<const id_type, basic_any<0u>>>;
@@ -210,7 +210,7 @@ private:
  * @tparam Entity A valid entity type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<entity_like Entity, allocator_like Allocator>
+template<entity_like Entity, typename Allocator>
 class basic_registry {
     using base_type = basic_sparse_set<Entity, Allocator>;
     using alloc_traits = std::allocator_traits<Allocator>;

+ 1 - 2
src/entt/entity/runtime_view.hpp

@@ -6,7 +6,6 @@
 #include <iterator>
 #include <utility>
 #include <vector>
-#include "../core/concepts.hpp"
 #include "entity.hpp"
 #include "fwd.hpp"
 
@@ -116,7 +115,7 @@ private:
  * @tparam Type Common base type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Type, allocator_like Allocator>
+template<typename Type, typename Allocator>
 class basic_runtime_view {
     using alloc_traits = std::allocator_traits<Allocator>;
     static_assert(std::is_same_v<typename alloc_traits::value_type, Type *>, "Invalid value type");

+ 1 - 2
src/entt/entity/sparse_set.hpp

@@ -13,7 +13,6 @@
 #include "../core/algorithm.hpp"
 #include "../core/any.hpp"
 #include "../core/bit.hpp"
-#include "../core/concepts.hpp"
 #include "../core/type_info.hpp"
 #include "../stl/iterator.hpp"
 #include "entity.hpp"
@@ -137,7 +136,7 @@ private:
  * @tparam Entity A valid entity type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<entity_like Entity, allocator_like Allocator>
+template<entity_like Entity, typename Allocator>
 class basic_sparse_set {
     using alloc_traits = std::allocator_traits<Allocator>;
     static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>, "Invalid value type");

+ 3 - 4
src/entt/entity/storage.hpp

@@ -12,7 +12,6 @@
 #include <vector>
 #include "../config/config.h"
 #include "../core/bit.hpp"
-#include "../core/concepts.hpp"
 #include "../core/iterator.hpp"
 #include "../core/memory.hpp"
 #include "../core/type_info.hpp"
@@ -207,7 +206,7 @@ private:
  * @tparam Entity A valid entity type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Type, entity_like Entity, allocator_like Allocator>
+template<typename Type, entity_like Entity, typename Allocator>
 class basic_storage: public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
     using alloc_traits = std::allocator_traits<Allocator>;
     static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
@@ -766,7 +765,7 @@ private:
 };
 
 /*! @copydoc basic_storage */
-template<typename Type, entity_like Entity, allocator_like Allocator>
+template<typename Type, entity_like Entity, typename Allocator>
 requires (component_traits<Type, Entity>::page_size == 0u)
 class basic_storage<Type, Entity, Allocator>
     : public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
@@ -951,7 +950,7 @@ public:
  * @tparam Entity A valid entity type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<entity_like Entity, allocator_like Allocator>
+template<entity_like Entity, typename Allocator>
 class basic_storage<Entity, Entity, Allocator>
     : public basic_sparse_set<Entity, Allocator> {
     using alloc_traits = std::allocator_traits<Allocator>;

+ 1 - 2
src/entt/graph/adjacency_matrix.hpp

@@ -9,7 +9,6 @@
 #include <utility>
 #include <vector>
 #include "../config/config.h"
-#include "../core/concepts.hpp"
 #include "../core/iterator.hpp"
 #include "fwd.hpp"
 
@@ -85,7 +84,7 @@ private:
  * @tparam Category Either a directed or undirected category tag.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<std::derived_from<directed_tag> Category, allocator_like Allocator>
+template<std::derived_from<directed_tag> Category, typename Allocator>
 class adjacency_matrix {
     using alloc_traits = std::allocator_traits<Allocator>;
     static_assert(std::is_same_v<typename alloc_traits::value_type, std::size_t>, "Invalid value type");

+ 1 - 2
src/entt/graph/flow.hpp

@@ -14,7 +14,6 @@
 #include "../container/dense_map.hpp"
 #include "../container/dense_set.hpp"
 #include "../core/compressed_pair.hpp"
-#include "../core/concepts.hpp"
 #include "../core/fwd.hpp"
 #include "../core/iterator.hpp"
 #include "../stl/functional.hpp"
@@ -28,7 +27,7 @@ namespace entt {
  * @brief Utility class for creating task graphs.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<allocator_like Allocator>
+template<typename Allocator>
 class basic_flow {
     using alloc_traits = std::allocator_traits<Allocator>;
     static_assert(std::is_same_v<typename alloc_traits::value_type, id_type>, "Invalid value type");

+ 2 - 3
src/entt/graph/fwd.hpp

@@ -4,7 +4,6 @@
 #include <concepts>
 #include <cstddef>
 #include <memory>
-#include "../core/concepts.hpp"
 #include "../core/fwd.hpp"
 
 namespace entt {
@@ -15,10 +14,10 @@ struct directed_tag {};
 /*! @brief Directed graph category tag. */
 struct undirected_tag: directed_tag {};
 
-template<std::derived_from<directed_tag>, allocator_like = std::allocator<std::size_t>>
+template<std::derived_from<directed_tag>, typename = std::allocator<std::size_t>>
 class adjacency_matrix;
 
-template<allocator_like = std::allocator<id_type>>
+template<typename = std::allocator<id_type>>
 class basic_flow;
 
 /*! @brief Alias declaration for the most common use case. */

+ 3 - 3
src/entt/locator/locator.hpp

@@ -5,7 +5,6 @@
 #include <memory>
 #include <utility>
 #include "../config/config.h"
-#include "../core/concepts.hpp"
 
 namespace entt {
 
@@ -109,14 +108,15 @@ public:
     /**
      * @brief Sets or replaces a service using a given allocator.
      * @tparam Type Service type.
+     * @tparam Allocator Type of allocator used to manage memory and elements.
      * @tparam Args Types of arguments to use to construct the service.
      * @param alloc The allocator to use.
      * @param args Parameters to use to construct the service.
      * @return A reference to a valid service.
      */
-    template<std::derived_from<Service> Type = Service, typename... Args>
+    template<std::derived_from<Service> Type = Service, typename Allocator, typename... Args>
     requires std::constructible_from<Type, Args...>
-    static Service &emplace(std::allocator_arg_t, allocator_like auto alloc, Args &&...args) {
+    static Service &emplace(std::allocator_arg_t, Allocator alloc, Args &&...args) {
         service = std::allocate_shared<Type>(alloc, std::forward<Args>(args)...);
         return *service;
     }

+ 2 - 3
src/entt/process/fwd.hpp

@@ -3,17 +3,16 @@
 
 #include <cstdint>
 #include <memory>
-#include "../core/concepts.hpp"
 
 namespace entt {
 
-template<typename, allocator_like = std::allocator<void>>
+template<typename, typename = std::allocator<void>>
 class basic_process;
 
 /*! @brief Alias declaration for the most common use case. */
 using process = basic_process<std::uint32_t>;
 
-template<typename, allocator_like = std::allocator<void>>
+template<typename, typename = std::allocator<void>>
 class basic_scheduler;
 
 /*! @brief Alias declaration for the most common use case. */

+ 3 - 4
src/entt/process/process.hpp

@@ -6,7 +6,6 @@
 #include <type_traits>
 #include <utility>
 #include "../core/compressed_pair.hpp"
-#include "../core/concepts.hpp"
 #include "../core/type_traits.hpp"
 #include "fwd.hpp"
 
@@ -15,7 +14,7 @@ namespace entt {
 /*! @cond ENTT_INTERNAL */
 namespace internal {
 
-template<typename, typename, allocator_like>
+template<typename, typename, typename>
 struct process_adaptor;
 
 } // namespace internal
@@ -69,7 +68,7 @@ struct process_adaptor;
  * @tparam Delta Type to use to provide elapsed time.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Delta, allocator_like Allocator>
+template<typename Delta, typename Allocator>
 class basic_process: public std::enable_shared_from_this<basic_process<Delta, Allocator>> {
     enum class state : std::uint8_t {
         idle = 0,
@@ -291,7 +290,7 @@ private:
 /*! @cond ENTT_INTERNAL */
 namespace internal {
 
-template<typename Delta, typename Func, allocator_like Allocator>
+template<typename Delta, typename Func, typename Allocator>
 struct process_adaptor: public basic_process<Delta, Allocator> {
     using allocator_type = Allocator;
     using base_type = basic_process<Delta, Allocator>;

+ 1 - 2
src/entt/process/scheduler.hpp

@@ -8,7 +8,6 @@
 #include <vector>
 #include "../config/config.h"
 #include "../core/compressed_pair.hpp"
-#include "../core/concepts.hpp"
 #include "fwd.hpp"
 #include "process.hpp"
 
@@ -33,7 +32,7 @@ namespace entt {
  * @tparam Delta Type to use to provide elapsed time.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Delta, allocator_like Allocator>
+template<typename Delta, typename Allocator>
 class basic_scheduler {
     using base_type = basic_process<Delta, Allocator>;
     using alloc_traits = std::allocator_traits<Allocator>;

+ 1 - 2
src/entt/resource/cache.hpp

@@ -12,7 +12,6 @@
 #include <utility>
 #include "../container/dense_map.hpp"
 #include "../core/compressed_pair.hpp"
-#include "../core/concepts.hpp"
 #include "../core/fwd.hpp"
 #include "../core/iterator.hpp"
 #include "../stl/functional.hpp"
@@ -124,7 +123,7 @@ private:
  * @tparam Loader Type of loader used to create the resources.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Type, typename Loader, allocator_like Allocator>
+template<typename Type, typename Loader, typename Allocator>
 class resource_cache {
     using alloc_traits = std::allocator_traits<Allocator>;
     static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");

+ 1 - 2
src/entt/resource/fwd.hpp

@@ -2,14 +2,13 @@
 #define ENTT_RESOURCE_FWD_HPP
 
 #include <memory>
-#include "../core/concepts.hpp"
 
 namespace entt {
 
 template<typename>
 struct resource_loader;
 
-template<typename Type, typename = resource_loader<Type>, allocator_like = std::allocator<Type>>
+template<typename Type, typename = resource_loader<Type>, typename = std::allocator<Type>>
 class resource_cache;
 
 template<typename>

+ 2 - 2
src/entt/signal/dispatcher.hpp

@@ -29,7 +29,7 @@ struct basic_dispatcher_handler {
     [[nodiscard]] virtual std::size_t size() const noexcept = 0;
 };
 
-template<cvref_unqualified Type, allocator_like Allocator>
+template<cvref_unqualified Type, typename Allocator>
 class dispatcher_handler final: public basic_dispatcher_handler {
     using alloc_traits = std::allocator_traits<Allocator>;
     using signal_type = sigh<void(Type &), Allocator>;
@@ -102,7 +102,7 @@ private:
  *
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<allocator_like Allocator>
+template<typename Allocator>
 class basic_dispatcher {
     template<typename Type>
     using handler_type = internal::dispatcher_handler<Type, Allocator>;

+ 1 - 2
src/entt/signal/emitter.hpp

@@ -6,7 +6,6 @@
 #include <utility>
 #include "../container/dense_map.hpp"
 #include "../core/compressed_pair.hpp"
-#include "../core/concepts.hpp"
 #include "../core/fwd.hpp"
 #include "../core/type_info.hpp"
 #include "../stl/functional.hpp"
@@ -33,7 +32,7 @@ namespace entt {
  * @tparam Derived Emitter type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Derived, allocator_like Allocator>
+template<typename Derived, typename Allocator>
 class emitter {
     using key_type = id_type;
     using mapped_type = std::function<void(void *)>;

+ 3 - 4
src/entt/signal/fwd.hpp

@@ -2,17 +2,16 @@
 #define ENTT_SIGNAL_FWD_HPP
 
 #include <memory>
-#include "../core/concepts.hpp"
 
 namespace entt {
 
 template<typename>
 class delegate;
 
-template<allocator_like = std::allocator<void>>
+template<typename = std::allocator<void>>
 class basic_dispatcher;
 
-template<typename, allocator_like = std::allocator<void>>
+template<typename, typename = std::allocator<void>>
 class emitter;
 
 class connection;
@@ -22,7 +21,7 @@ struct scoped_connection;
 template<typename>
 class sink;
 
-template<typename Type, allocator_like = std::allocator<void>>
+template<typename Type, typename = std::allocator<void>>
 class sigh;
 
 /*! @brief Alias declaration for the most common use case. */

+ 4 - 5
src/entt/signal/sigh.hpp

@@ -6,7 +6,6 @@
 #include <type_traits>
 #include <utility>
 #include <vector>
-#include "../core/concepts.hpp"
 #include "delegate.hpp"
 #include "fwd.hpp"
 
@@ -32,7 +31,7 @@ class sink;
  * @tparam Type A valid function type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Type, allocator_like Allocator>
+template<typename Type, typename Allocator>
 class sigh;
 
 /**
@@ -51,7 +50,7 @@ class sigh;
  * @tparam Args Types of arguments of a function type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Ret, typename... Args, allocator_like Allocator>
+template<typename Ret, typename... Args, typename Allocator>
 class sigh<Ret(Args...), Allocator> {
     friend class sink<sigh<Ret(Args...), Allocator>>;
 
@@ -355,7 +354,7 @@ private:
  * @tparam Args Types of arguments of a function type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Ret, typename... Args, allocator_like Allocator>
+template<typename Ret, typename... Args, typename Allocator>
 class sink<sigh<Ret(Args...), Allocator>> {
     using signal_type = sigh<Ret(Args...), Allocator>;
     using delegate_type = signal_type::delegate_type;
@@ -566,7 +565,7 @@ private:
  * @tparam Args Types of arguments of a function type.
  * @tparam Allocator Type of allocator used to manage memory and elements.
  */
-template<typename Ret, typename... Args, allocator_like Allocator>
+template<typename Ret, typename... Args, typename Allocator>
 sink(sigh<Ret(Args...), Allocator> &) -> sink<sigh<Ret(Args...), Allocator>>;
 
 } // namespace entt

+ 5 - 6
src/entt/tools/davey.hpp

@@ -6,7 +6,6 @@
 #include <sstream>
 #include <string>
 #include <imgui.h>
-#include "../core/concepts.hpp"
 #include "../entity/mixin.hpp"
 #include "../entity/registry.hpp"
 #include "../entity/sparse_set.hpp"
@@ -134,7 +133,7 @@ static void present_element(const meta_any &obj, OnEntity on_entity) {
     }
 }
 
-template<entity_like Entity, allocator_like Allocator>
+template<entity_like Entity, typename Allocator>
 static void present_storage(const meta_ctx &ctx, const basic_sparse_set<Entity, Allocator> &storage) {
     if(auto type = resolve(ctx, storage.info()); type) {
         for(auto entt: storage) {
@@ -235,7 +234,7 @@ static void present_view(const meta_ctx &ctx, const basic_view<get_t<Get...>, ex
  * @param ctx The context from which to search for meta types.
  * @param storage An instance of the storage type.
  */
-template<typename Type, entity_like Entity, allocator_like Allocator>
+template<typename Type, entity_like Entity, typename Allocator>
 void davey(const meta_ctx &ctx, const basic_storage<Type, Entity, Allocator> &storage) {
     internal::present_storage(ctx, storage);
 }
@@ -247,7 +246,7 @@ void davey(const meta_ctx &ctx, const basic_storage<Type, Entity, Allocator> &st
  * @tparam Allocator Storage allocator type.
  * @param storage An instance of the storage type.
  */
-template<typename Type, entity_like Entity, allocator_like Allocator>
+template<typename Type, entity_like Entity, typename Allocator>
 void davey(const basic_storage<Type, Entity, Allocator> &storage) {
     davey(locator<meta_ctx>::value_or(), storage);
 }
@@ -282,7 +281,7 @@ void davey(const basic_view<get_t<Get...>, exclude_t<Exclude...>> &view) {
  * @param ctx The context from which to search for meta types.
  * @param registry An instance of the registry type.
  */
-template<entity_like Entity, allocator_like Allocator>
+template<entity_like Entity, typename Allocator>
 void davey(const meta_ctx &ctx, const basic_registry<Entity, Allocator> &registry) {
     ImGui::BeginTabBar("#tabs");
 
@@ -326,7 +325,7 @@ void davey(const meta_ctx &ctx, const basic_registry<Entity, Allocator> &registr
  * @tparam Allocator Registry allocator type.
  * @param registry An instance of the registry type.
  */
-template<entity_like Entity, allocator_like Allocator>
+template<entity_like Entity, typename Allocator>
 void davey(const basic_registry<Entity, Allocator> &registry) {
     davey(locator<meta_ctx>::value_or(), registry);
 }

+ 0 - 7
test/entt/core/concepts.cpp

@@ -12,10 +12,3 @@ TEST(Concepts, CVRefUnqualified) {
     ASSERT_FALSE(entt::cvref_unqualified<const std::shared_ptr<int>>);
     ASSERT_FALSE(entt::cvref_unqualified<std::shared_ptr<int> &>);
 }
-
-TEST(Concepts, AllocatorLike) {
-    ASSERT_FALSE(entt::allocator_like<int>);
-    ASSERT_TRUE(entt::allocator_like<std::allocator<int>>);
-    ASSERT_FALSE(entt::allocator_like<std::shared_ptr<int>>);
-    ASSERT_TRUE(entt::allocator_like<std::allocator<std::allocator<int>>>);
-}