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

memory: make_obj_using_allocator utility (waiting for C++20)

Michele Caini 4 лет назад
Родитель
Сommit
5cf0ba079f
2 измененных файлов с 38 добавлено и 5 удалено
  1. 25 3
      src/entt/core/memory.hpp
  2. 13 2
      test/entt/core/memory.cpp

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

@@ -164,10 +164,14 @@ auto allocate_unique(Allocator &allocator, Args &&...args) {
 }
 
 /**
- * @brief Uses-allocator construction utility.
+ * @brief Uses-allocator construction utility (waiting for C++20).
  *
- * Primarily intended for internal use. Unlike the standard version (waiting for
- * C++20), this utility does not differentiate between pair and non-pair types.
+ * Primarily intended for internal use. Prepares the argument list needed to
+ * create an object of a given type by means of uses-allocator construction.
+ *
+ * @warning
+ * Unlike the standard implementation, this utility does not differentiate
+ * between pair and non-pair types.
  *
  * @tparam Type Type to return arguments for.
  * @tparam Allocator Type of allocator used to manage memory and elements.
@@ -192,6 +196,24 @@ constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args
     }
 }
 
+/**
+ * @brief Uses-allocator construction utility (waiting for C++20).
+ *
+ * Primarily intended for internal use. Creates an object of a given type by
+ * 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 Allocator, typename... Args>
+constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
+    return std::make_from_tuple<Type>(uses_allocator_construction_args<Type>(allocator, std::forward<Args>(args)...));
+}
+
 } // namespace entt
 
 #endif

+ 13 - 2
test/entt/core/memory.cpp

@@ -138,10 +138,21 @@ TEST(UsesAllocatorConstructionArgs, LeadingAllocatorConvetion) {
 }
 
 TEST(UsesAllocatorConstructionArgs, TrailingAllocatorConvetion) {
-    const auto args = entt::uses_allocator_construction_args<std::vector<int>>(std::allocator<int>{}, 42);
+    const auto args = entt::uses_allocator_construction_args<std::vector<int>>(std::allocator<int>{}, 42u);
 
     static_assert(std::tuple_size_v<decltype(args)> == 2u);
-    static_assert(std::is_same_v<decltype(args), const std::tuple<int &&, const std::allocator<int> &>>);
+    static_assert(std::is_same_v<decltype(args), const std::tuple<unsigned int &&, const std::allocator<int> &>>);
 
     ASSERT_EQ(std::get<0>(args), 42);
 }
+
+TEST(MakeObjUsingAllocator, Functionalities) {
+    test::throwing_allocator<int>::trigger_on_allocate = true;
+
+    ASSERT_THROW((entt::make_obj_using_allocator<std::vector<int, test::throwing_allocator<int>>>(test::throwing_allocator<int>{}, 42u)), test::throwing_allocator<int>::exception_type);
+
+    const auto vec = entt::make_obj_using_allocator<std::vector<int>>(std::allocator<int>{}, 42u);
+
+    ASSERT_FALSE(vec.empty());
+    ASSERT_EQ(vec.size(), 42u);
+}