From 7ca615a1c1bfe77942fa2c4b13f0a186f8b15a1d Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 2 Mar 2018 08:45:47 +0100 Subject: [PATCH] sfinaed construct in sparse set to favor emplace_back with arguments when possible (#48) --- src/entt/entity/sparse_set.hpp | 40 +++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/entt/entity/sparse_set.hpp b/src/entt/entity/sparse_set.hpp index 196faa118..b334dba34 100644 --- a/src/entt/entity/sparse_set.hpp +++ b/src/entt/entity/sparse_set.hpp @@ -501,6 +501,12 @@ public: /** * @brief Assigns an entity to a sparse set and constructs its object. * + * @note + * _Sfinae'd_ function.
+ * This version is used for types that can be constructed in place directly. + * It doesn't work well with aggregates because of the placement new usually + * performed under the hood during an _emplace back_. + * * @warning * Attempting to use an entity that already belongs to the sparse set * results in undefined behavior.
@@ -513,10 +519,38 @@ public: * @return The object associated to the entity. */ template - object_type & construct(entity_type entity, Args&&... args) { + std::enable_if_t::value, object_type &> + construct(entity_type entity, Args&&... args) { underlying_type::construct(entity); - // emplace_back doesn't work well with PODs because of its placement new - instances.push_back(object_type{ std::forward(args)... }); + instances.emplace_back(std::forward(args)...); + return instances.back(); + } + + /** + * @brief Assigns an entity to a sparse set and constructs its object. + * + * @note + * _Sfinae'd_ function.
+ * Fallback for aggregates and types in general that do not work well with a + * placement new as performed usually under the hood during an + * _emplace back_. + * + * @warning + * Attempting to use an entity that already belongs to the sparse set + * results in undefined behavior.
+ * An assertion will abort the execution at runtime in debug mode if the + * sparse set already contains the given entity. + * + * @tparam Args Types of arguments to use to construct the object. + * @param entity A valid entity identifier. + * @param args Parameters to use to construct an object for the entity. + * @return The object associated to the entity. + */ + template + std::enable_if_t::value, object_type &> + construct(entity_type entity, Args&&... args) { + underlying_type::construct(entity); + instances.emplace_back(Type{ std::forward(args)... }); return instances.back(); }