Explorar el Código

any: doc + test for configurable sbo

Michele Caini hace 5 años
padre
commit
1aec7f71b8
Se han modificado 3 ficheros con 36 adiciones y 2 borrados
  1. 20 0
      docs/md/core.md
  2. 2 2
      src/entt/entity/registry.hpp
  3. 14 0
      test/entt/core/any.cpp

+ 20 - 0
docs/md/core.md

@@ -14,6 +14,7 @@
   * [Conflicts](#conflicts)
 * [Monostate](#monostate)
 * [Any as in any type](#any-as-in-any-type)
+  * [Small buffer optimization](#small-buffer-optimization)
 * [Type support](#type-support)
   * [Type info](#type-info)
     * [Almost unique identifiers](#almost-unique-identifiers)
@@ -312,6 +313,25 @@ The only difference is that, in the case of `EnTT`, these won't raise exceptions
 but will only trigger an assert in debug mode, otherwise resulting in undefined
 behavior in case of misuse in release mode.
 
+## Small buffer optimization
+
+The `any` class uses a technique called _small buffer optimization_ to reduce
+the number of allocations where possible.<br/>
+The default reserved size for an instance of `any` is `sizeof(double[2])`.
+However, this is also configurable if needed. In fact, `any` is defined as an
+alias for `basic_any<Len>`, where `Len` is just the size above.<br/>
+Users can easily use a custom size or define their own alias:
+
+```cpp
+using my_any = entt::basic_any<sizeof(double[4])>;
+```
+
+This feature, in addition to allowing the choice of a size that best suits the
+needs of an application, also reserves the possibility of forcing dynamic
+creation of objects during construction.<br/>
+In fact, if the size is 0, `any` will avoid the use of any optimization, in fact
+always dynamically allocating objects (except for aliasing cases).
+
 # Type support
 
 `EnTT` provides some basic information about types of all kinds.<br/>

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

@@ -1520,7 +1520,7 @@ public:
     template<typename Type, typename... Args>
     Type & set(Args &&... args) {
         unset<Type>();
-        vars.push_back(any{std::in_place_type<Type>, std::forward<Args>(args)...});
+        vars.emplace_back(std::in_place_type<Type>, std::forward<Args>(args)...);
         return any_cast<Type &>(vars.back());
     }
 
@@ -1621,7 +1621,7 @@ public:
     }
 
 private:
-    std::vector<any> vars{};
+    std::vector<basic_any<0u>> vars{};
     std::vector<pool_data> pools{};
     std::vector<group_data> groups{};
     std::vector<entity_type> entities{};

+ 14 - 0
test/entt/core/any.cpp

@@ -870,3 +870,17 @@ TEST(Any, CopyMoveReference) {
     test(std::ref(value));
     test(std::cref(value));
 }
+
+TEST(Any, SBOVsForcedDynamic) {
+    entt::any sbo{42};
+    const auto sbo_ptr = sbo.data();
+    entt::any sbo_copy = std::move(sbo);
+
+    ASSERT_NE(sbo_ptr, sbo_copy.data());
+
+    entt::basic_any<0u> dyn{42};
+    const auto dyn_ptr = dyn.data();
+    entt::any dyn_copy = std::move(dyn);
+
+    ASSERT_NE(dyn_ptr, dyn_copy.data());
+}