From 2a86acfc50c0884786b71897178e4eec1d4fbb26 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Tue, 14 Apr 2020 18:29:43 +0200 Subject: [PATCH] doc: updated documentation for the core part --- TODO | 2 +- docs/md/core.md | 72 ++++++++++++++++++++++++++++++++++++++ test/entt/core/utility.cpp | 22 ++++++------ 3 files changed, 84 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index d91f3a0b9..9c967872d 100644 --- a/TODO +++ b/TODO @@ -12,7 +12,7 @@ * can we write a bool conv func for entt::entity that silently compares it to null? * reset... reset everywhere... * is it possible to make 0 the entity null? -* document undocumented parts (entt::overload and a few others) +* update documentation for meta, it contains less than half of the actual feature * any-of rule for views/groups (eg entity has A and any of B/C/D) - get -> all, exclude -> none diff --git a/docs/md/core.md b/docs/md/core.md index ee0fe0e1c..730b6e25d 100644 --- a/docs/md/core.md +++ b/docs/md/core.md @@ -21,6 +21,7 @@ * [Member class type](#member-class-type) * [Integral constant](#integral-constant) * [Tag](#tag) +* [Utilities](#utilities) @@ -358,3 +359,74 @@ registry.assign>(entity); However, this isn't the only permitted use. Literally any value convertible to `id_type` is a good candidate, such as the named constants of an unscoped enum. + +# Utilities + +It's not possible to escape the temptation to add utilities of some kind to a +library. In fact, `EnTT` also provides a handful of tools to simplify the +life of developers: + +* `entt::identity`: the identity function object that will be available with + C++20. It returns its argument unchanged and nothing more. It's useful as a + sort of _do nothing_ function in template programming. + +* `entt::overload`: a tool to disambiguate different overloads from their + function type. It works with both free and member functions.
+ Consider the following definition: + + ```cpp + struct clazz { + void bar(int) {} + void bar() {} + }; + ``` + + This utility can be used to get the _right_ overload as: + + ```cpp + auto *member = entt::overload(&clazz::bar); + ``` + + The line above is literally equivalent to: + + ```cpp + auto *member = static_cast(&clazz::bar); + ``` + + Just easier to read and shorter to type. + +* `entt::overloaded`: a small class template used to create a new type with an + overloaded `operator()` from a bunch of lambdas or functors.
+ As an example: + + ```cpp + entt::overloaded func{ + [](int value) { /* ... */ }, + [](char value) { /* ... */ } + }; + + func(42); + func('c'); + ``` + + Rather useful when doing metaprogramming and having to pass to a function a + callable object that supports multiple types at once. + +* `entt::y_combinator`: this is a C++ implementation of **the** _y-combinator_. + If it's not clear what it is, there is probably no need for this utility.
+ Below is a small example to show its use: + + ```cpp + entt::y_combinator gauss([](const auto &self, auto value) -> unsigned int { + return value ? (value + self(value-1u)) : 0; + }); + + const auto result = gauss(3u); + ``` + + Maybe convoluted at a first glance but certainly effective. Unfortunately, + the language doesn't make it possible to do much better. + +This is a rundown of the (actually few) utilities made available by `EnTT`. The +list will probably grow over time but the size of each will remain rather small, +as has been the case so far. diff --git a/test/entt/core/utility.cpp b/test/entt/core/utility.cpp index 97023ea72..412e0b91d 100644 --- a/test/entt/core/utility.cpp +++ b/test/entt/core/utility.cpp @@ -2,7 +2,7 @@ #include #include -struct Functions { +struct functions { static void foo(int) {} static void foo() {} @@ -19,19 +19,19 @@ TEST(Utility, Identity) { } TEST(Utility, Overload) { - ASSERT_EQ(entt::overload(&Functions::foo), static_cast(&Functions::foo)); - ASSERT_EQ(entt::overload(&Functions::foo), static_cast(&Functions::foo)); + ASSERT_EQ(entt::overload(&functions::foo), static_cast(&functions::foo)); + ASSERT_EQ(entt::overload(&functions::foo), static_cast(&functions::foo)); - ASSERT_EQ(entt::overload(&Functions::bar), static_cast(&Functions::bar)); - ASSERT_EQ(entt::overload(&Functions::bar), static_cast(&Functions::bar)); + ASSERT_EQ(entt::overload(&functions::bar), static_cast(&functions::bar)); + ASSERT_EQ(entt::overload(&functions::bar), static_cast(&functions::bar)); - Functions instance; + functions instance; - ASSERT_NO_THROW(entt::overload(&Functions::foo)(0)); - ASSERT_NO_THROW(entt::overload(&Functions::foo)()); + ASSERT_NO_THROW(entt::overload(&functions::foo)(0)); + ASSERT_NO_THROW(entt::overload(&functions::foo)()); - ASSERT_NO_THROW((instance.*entt::overload(&Functions::bar))(0)); - ASSERT_NO_THROW((instance.*entt::overload(&Functions::bar))()); + ASSERT_NO_THROW((instance.*entt::overload(&functions::bar))(0)); + ASSERT_NO_THROW((instance.*entt::overload(&functions::bar))()); } TEST(Utility, Overloaded) { @@ -51,7 +51,7 @@ TEST(Utility, Overloaded) { } TEST(Utility, YCombinator) { - entt::y_combinator gauss([](auto &&self, unsigned int value) -> unsigned int { + entt::y_combinator gauss([](const auto &self, auto value) -> unsigned int { return value ? (value + self(value-1u)) : 0; });