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

This commit is contained in:
Michele Caini
2022-02-21 16:31:36 +01:00
parent e08b1f82ce
commit 5cf0ba079f
2 changed files with 38 additions and 5 deletions

View File

@@ -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

View File

@@ -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);
}