314 lines
36 KiB
HTML
314 lines
36 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
|
<meta name="generator" content="Doxygen 1.8.20"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
<title>EnTT: Crash Course: core functionalities</title>
|
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="jquery.js"></script>
|
|
<script type="text/javascript" src="dynsections.js"></script>
|
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
|
<script type="text/javascript" src="search/search.js"></script>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
|
</head>
|
|
<body>
|
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
<div id="titlearea">
|
|
<table cellspacing="0" cellpadding="0">
|
|
<tbody>
|
|
<tr style="height: 56px;">
|
|
<td id="projectalign" style="padding-left: 0.5em;">
|
|
<div id="projectname">EnTT
|
|
 <span id="projectnumber">3.5.2</span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<!-- end header part -->
|
|
<!-- Generated by Doxygen 1.8.20 -->
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
|
/* @license-end */
|
|
</script>
|
|
<script type="text/javascript" src="menudata.js"></script>
|
|
<script type="text/javascript" src="menu.js"></script>
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
|
$(function() {
|
|
initMenu('',true,false,'search.php','Search');
|
|
$(document).ready(function() { init_search(); });
|
|
});
|
|
/* @license-end */</script>
|
|
<div id="main-nav"></div>
|
|
<!-- window showing the filter options -->
|
|
<div id="MSearchSelectWindow"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
|
</div>
|
|
|
|
<!-- iframe showing the search results (closed by default) -->
|
|
<div id="MSearchResultsWindow">
|
|
<iframe src="javascript:void(0)" frameborder="0"
|
|
name="MSearchResults" id="MSearchResults">
|
|
</iframe>
|
|
</div>
|
|
|
|
</div><!-- top -->
|
|
<div class="PageDoc"><div class="header">
|
|
<div class="headertitle">
|
|
<div class="title">Crash Course: core functionalities </div> </div>
|
|
</div><!--header-->
|
|
<div class="contents">
|
|
<div class="textblock"><h1><a class="anchor" id="autotoc_md13"></a>
|
|
Introduction</h1>
|
|
<p><code>EnTT</code> comes with a bunch of core functionalities mostly used by the other parts of the library itself.<br />
|
|
Hardly users will include these features in their code, but it's worth describing what <code>EnTT</code> offers so as not to reinvent the wheel in case of need.</p>
|
|
<h1><a class="anchor" id="autotoc_md14"></a>
|
|
Unique sequential identifiers</h1>
|
|
<p>Sometimes it's useful to be able to give unique, sequential numeric identifiers to types either at compile-time or runtime.<br />
|
|
There are plenty of different solutions for this out there and I could have used one of them. However, I decided to spend my time to define a couple of tools that fully embraces what the modern C++ has to offer.</p>
|
|
<h2><a class="anchor" id="autotoc_md15"></a>
|
|
Compile-time generator</h2>
|
|
<p>To generate sequential numeric identifiers at compile-time, <code>EnTT</code> offers the <code>identifier</code> class template:</p>
|
|
<div class="fragment"><div class="line"><span class="comment">// defines the identifiers for the given types</span></div>
|
|
<div class="line"><span class="keyword">using</span> <span class="keywordtype">id</span> = <a class="code" href="classentt_1_1identifier.html">entt::identifier<a_type, another_type></a>;</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="comment">// ...</span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keywordflow">switch</span>(a_type_identifier) {</div>
|
|
<div class="line"><span class="keywordflow">case</span> id::type<a_type>:</div>
|
|
<div class="line"> <span class="comment">// ...</span></div>
|
|
<div class="line"> <span class="keywordflow">break</span>;</div>
|
|
<div class="line"><span class="keywordflow">case</span> id::type<another_type>:</div>
|
|
<div class="line"> <span class="comment">// ...</span></div>
|
|
<div class="line"> <span class="keywordflow">break</span>;</div>
|
|
<div class="line"><span class="keywordflow">default</span>:</div>
|
|
<div class="line"> <span class="comment">// ...</span></div>
|
|
<div class="line">}</div>
|
|
</div><!-- fragment --><p>This is all what this class template has to offer: a <code>type</code> inline variable that contains a numeric identifier for the given type. It can be used in any context where constant expressions are required.</p>
|
|
<p>As long as the list remains unchanged, identifiers are also guaranteed to be stable across different runs. In case they have been used in a production environment and a type has to be removed, one can just use a placeholder to left the other identifiers unchanged:</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">template</span><<span class="keyword">typename</span>> <span class="keyword">struct </span>ignore_type {};</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keyword">using</span> <span class="keywordtype">id</span> = <a class="code" href="classentt_1_1identifier.html">entt::identifier</a><</div>
|
|
<div class="line"> a_type_still_valid,</div>
|
|
<div class="line"> ignore_type<a_type_no_longer_valid>,</div>
|
|
<div class="line"> another_type_still_valid</div>
|
|
<div class="line">>;</div>
|
|
</div><!-- fragment --><p>Perhaps a bit ugly to see in a codebase but it gets the job done at least.</p>
|
|
<h2><a class="anchor" id="autotoc_md16"></a>
|
|
Runtime generator</h2>
|
|
<p>To generate sequential numeric identifiers at runtime, <code>EnTT</code> offers the <code>family</code> class template:</p>
|
|
<div class="fragment"><div class="line"><span class="comment">// defines a custom generator</span></div>
|
|
<div class="line"><span class="keyword">using</span> <span class="keywordtype">id</span> = <a class="code" href="classentt_1_1family.html">entt::family<struct my_tag></a>;</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="comment">// ...</span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> a_type_id = id::type<a_type>;</div>
|
|
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> another_type_id = id::type<another_type>;</div>
|
|
</div><!-- fragment --><p>This is all what a <em>family</em> has to offer: a <code>type</code> inline variable that contains a numeric identifier for the given type.<br />
|
|
The generator is customizable, so as to get different <em>sequences</em> for different purposes if needed.</p>
|
|
<p>Please, note that identifiers aren't guaranteed to be stable across different runs. Indeed it mostly depends on the flow of execution.</p>
|
|
<h1><a class="anchor" id="autotoc_md17"></a>
|
|
Hashed strings</h1>
|
|
<p>A hashed string is a zero overhead unique identifier. Users can use human-readable identifiers in the codebase while using their numeric counterparts at runtime, thus without affecting performance.<br />
|
|
The class has an implicit <code>constexpr</code> constructor that chews a bunch of characters. Once created, all what one can do with it is getting back the original string or converting it into a number.<br />
|
|
The good part is that a hashed string can be used wherever a constant expression is required and no <em>string-to-number</em> conversion will take place at runtime if used carefully.</p>
|
|
<p>Example of use:</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">auto</span> load(<a class="code" href="classentt_1_1basic__hashed__string.html#a1631b1f6ecd56a451366eeb228a6ffb9">entt::hashed_string::hash_type</a> resource) {</div>
|
|
<div class="line"> <span class="comment">// uses the numeric representation of the resource to load and return it</span></div>
|
|
<div class="line">}</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keyword">auto</span> resource = load(<a class="code" href="classentt_1_1basic__hashed__string.html">entt::hashed_string</a>{<span class="stringliteral">"gui/background"</span>});</div>
|
|
</div><!-- fragment --><p>There is also a <em>user defined literal</em> dedicated to hashed strings to make them more user-friendly:</p>
|
|
<div class="fragment"><div class="line">constexpr <span class="keyword">auto</span> str = <span class="stringliteral">"text"</span>_hs;</div>
|
|
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md18"></a>
|
|
Wide characters</h2>
|
|
<p>The hashed string has a design that is close to that of an <code>std::basic_string</code>. It means that <code>hashed_string</code> is nothing more than an alias for <code>basic_hashed_string<char></code>. For those who want to use the C++ type for wide character representation, there exists also the alias <code>hashed_wstring</code> for <code>basic_hashed_string<wchar_t></code>.<br />
|
|
In this case, the user defined literal to use to create hashed strings on the fly is <code>_hws</code>:</p>
|
|
<div class="fragment"><div class="line">constexpr <span class="keyword">auto</span> str = <span class="stringliteral">"text"</span>_hws;</div>
|
|
</div><!-- fragment --><p>Note that the hash type of the <code>hashed_wstring</code> is the same of its counterpart.</p>
|
|
<h2><a class="anchor" id="autotoc_md19"></a>
|
|
Conflicts</h2>
|
|
<p>The hashed string class uses internally FNV-1a to compute the numeric counterpart of a string. Because of the <em>pigeonhole principle</em>, conflicts are possible. This is a fact.<br />
|
|
There is no silver bullet to solve the problem of conflicts when dealing with hashing functions. In this case, the best solution seemed to be to give up. That's all.<br />
|
|
After all, human-readable unique identifiers aren't something strictly defined and over which users have not the control. Choosing a slightly different identifier is probably the best solution to make the conflict disappear in this case.</p>
|
|
<h1><a class="anchor" id="autotoc_md20"></a>
|
|
Monostate</h1>
|
|
<p>The monostate pattern is often presented as an alternative to a singleton based configuration system. This is exactly its purpose in <code>EnTT</code>. Moreover, this implementation is thread safe by design (hopefully).<br />
|
|
Keys are represented by hashed strings, values are basic types like <code>int</code>s or <code>bool</code>s. Values of different types can be associated to each key, even more than one at a time. Because of this, users must pay attention to use the same type both during an assignment and when they try to read back their data. Otherwise, they will probably incur in unexpected results.</p>
|
|
<p>Example of use:</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="structentt_1_1monostate.html">entt::monostate</a><<a class="code" href="classentt_1_1basic__hashed__string.html">entt::hashed_string</a>{<span class="stringliteral">"mykey"</span>}>{} = <span class="keyword">true</span>;</div>
|
|
<div class="line"><a class="code" href="structentt_1_1monostate.html">entt::monostate</a><<span class="stringliteral">"mykey"</span>_hs>{} = 42;</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="comment">// ...</span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keyword">const</span> <span class="keywordtype">bool</span> b = <a class="code" href="structentt_1_1monostate.html">entt::monostate</a><<span class="stringliteral">"mykey"</span>_hs>{};</div>
|
|
<div class="line"><span class="keyword">const</span> <span class="keywordtype">int</span> i = <a class="code" href="structentt_1_1monostate.html">entt::monostate</a><<a class="code" href="classentt_1_1basic__hashed__string.html">entt::hashed_string</a>{<span class="stringliteral">"mykey"</span>}>{};</div>
|
|
</div><!-- fragment --><h1><a class="anchor" id="autotoc_md21"></a>
|
|
Type support</h1>
|
|
<p><code>EnTT</code> provides some basic information about types of all kinds.<br />
|
|
It also offers additional features that are not yet available in the standard library or that will never be.</p>
|
|
<h2><a class="anchor" id="autotoc_md22"></a>
|
|
Type info</h2>
|
|
<p>This class template isn't a drop-in replacement for <code>std::type_info</code> but can provide similar information which are not implementation defined and don't require to enable RTTI.<br />
|
|
Therefore, they can sometimes be even more reliable than those obtained otherwise.</p>
|
|
<p>Currently, there are a couple of information available:</p>
|
|
<ul>
|
|
<li>The numeric identifier associated with a given type:</li>
|
|
</ul>
|
|
<div class="fragment"><div class="line"><span class="keyword">auto</span> <span class="keywordtype">id</span> = <a class="code" href="structentt_1_1type__info.html#aefa2a63e4b4f41dbb783718bdc8c5a76">entt::type_info<my_type>::id</a>();</div>
|
|
</div><!-- fragment --><p>In general, the <code>id</code> function is also <code>constexpr</code> but this isn't guaranteed for all compilers and platforms (although it's valid with the most well-known and popular ones).</p>
|
|
<p>This function <b>can</b> use non-standard features of the language for its own purposes. This makes it possible to provide compile-time identifiers that remain stable across different runs.<br />
|
|
In all cases, users can prevent the library from using these features by means of the <code>ENTT_STANDARD_CPP</code> definition. In this case, there is no guarantee that identifiers remain stable across executions. Moreover, they are generated at runtime and are no longer a compile-time thing.</p>
|
|
<ul>
|
|
<li>The <em>name</em> associated with a given type:</li>
|
|
</ul>
|
|
<div class="fragment"><div class="line"><span class="keyword">auto</span> name = <a class="code" href="structentt_1_1type__info.html#a77b9e5dd77357b99e2ebfb8d0a8b2efc">entt::type_info<my_type>::name</a>();</div>
|
|
</div><!-- fragment --><p>The name associated with a type is extracted from some information generally made available by the compiler in use. Therefore, it may differ depending on the compiler and may be empty in the event that this information isn't available.<br />
|
|
For example, given the following class:</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">struct </span>my_type { <span class="comment">/* ... */</span> };</div>
|
|
</div><!-- fragment --><p>The name is <code>my_type</code> when compiled with GCC or CLang and <code>struct my_type</code> when MSVC is in use.<br />
|
|
Most of the time the name is also retrieved at compile-time and is therefore always returned through an <code>std::string_view</code>. Users can easily access it and modify it as needed, for example by removing the word <code>struct</code> to standardize the result. <code>EnTT</code> won't do this for obvious reasons, since it requires copying and creating a new string potentially at runtime.</p>
|
|
<p>This function <b>can</b> use non-standard features of the language for its own purposes. As for the numeric identifier, users can prevent the library from using non-standard features by means of the <code>ENTT_STANDARD_CPP</code> definition. In this case, the name will be empty by default.</p>
|
|
<p>An external type system can also be used if needed. In fact, <code>type_info</code> can be specialized by type and is also <em>sfinae-friendly</em> in order to allow more refined specializations such as:</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">template</span><<span class="keyword">typename</span> Type></div>
|
|
<div class="line"><span class="keyword">struct </span><a class="code" href="structentt_1_1type__info.html">entt::type_info</a><Type, std::enable_if_t<has_custom_data_v<Type>>> {</div>
|
|
<div class="line"> <span class="keyword">static</span> constexpr <a class="code" href="namespaceentt.html#a13e040e7b38a8f86d1ab2f096f37b627">entt::id_type</a> <a class="code" href="structentt_1_1type__info.html#aefa2a63e4b4f41dbb783718bdc8c5a76">id</a>() ENTT_NOEXCEPT {</div>
|
|
<div class="line"> <span class="keywordflow">return</span> Type::custom_id();</div>
|
|
<div class="line"> }</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> <span class="keyword">static</span> constexpr std::string_view <a class="code" href="structentt_1_1type__info.html#a77b9e5dd77357b99e2ebfb8d0a8b2efc">name</a>() ENTT_NOEXCEPT {</div>
|
|
<div class="line"> <span class="keywordflow">return</span> Type::custom_name();</div>
|
|
<div class="line"> }</div>
|
|
<div class="line">};</div>
|
|
</div><!-- fragment --><p>Note that this class template and its specializations are widely used within <code>EnTT</code>. It also plays a very important role in making <code>EnTT</code> work transparently across boundaries in many cases.<br />
|
|
Please refer to the dedicated section for more details.</p>
|
|
<h3><a class="anchor" id="autotoc_md23"></a>
|
|
Almost unique identifiers</h3>
|
|
<p>Since the default non-standard, compile-time implementation makes use of hashed strings, it may happen that two types are assigned the same numeric identifier.<br />
|
|
In fact, although this is quite rare, it's not entirely excluded.</p>
|
|
<p>Another case where two types are assigned the same identifier is when classes from different contexts (for example two or more libraries loaded at runtime) have the same fully qualified name.<br />
|
|
If the types have the same name and belong to the same namespace then their identifiers <em>could</em> be identical (they won't necessarily be the same though).</p>
|
|
<p>Fortunately, there are several easy ways to deal with this:</p>
|
|
<ul>
|
|
<li>The most trivial one is to define the <code>ENTT_STANDARD_CPP</code> macro. Runtime identifiers don't suffer from the same problem in fact. However, this solution doesn't work well with a plugin system, where the libraries aren't linked.</li>
|
|
<li>Another possibility is to specialize the <code>type_info</code> class for one of the conflicting types, in order to assign it a custom identifier. This is probably the easiest solution that also preserves the feature of the tool.</li>
|
|
<li>A fully customized identifier generation policy (based for example on enum classes or preprocessing steps) may represent yet another option.</li>
|
|
</ul>
|
|
<p>These are just some examples of possible approaches to the problem but there are many others. As already mentioned above, since users have full control over their types, this problem is in any case easy to solve and should not worry too much.<br />
|
|
In all likelihood, it will never happen to run into a conflict anyway.</p>
|
|
<h2><a class="anchor" id="autotoc_md24"></a>
|
|
Type index</h2>
|
|
<p>Types in <code>EnTT</code> are assigned also unique, sequential <em>indexes</em> generated at runtime:</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">auto</span> index = <a class="code" href="structentt_1_1type__index.html#ac1a87730c605024e3fb6426fc633380e">entt::type_index<my_type>::value</a>();</div>
|
|
</div><!-- fragment --><p>This value may differ from the numeric identifier of a type and isn't guaranteed to be stable across different runs. However, it can be very useful as index in associative and unordered associative containers or for positional accesses in a vector or an array.</p>
|
|
<p>So as not to conflict with the other tools available, the <code>family</code> class isn't used to generate these indexes. Therefore, the numeric identifiers returned by the two tools may differ.<br />
|
|
On the other hand, this leaves users with full powers over the <code>family</code> class and therefore the generation of custom runtime sequences of indices for their own purposes, if necessary.</p>
|
|
<p>An external generator can also be used if needed. In fact, <code>type_index</code> can be specialized by type and is also <em>sfinae-friendly</em> in order to allow more refined specializations such as:</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">template</span><<span class="keyword">typename</span> Type></div>
|
|
<div class="line"><span class="keyword">struct </span><a class="code" href="structentt_1_1type__index.html">entt::type_index</a><Type, std::void_d<decltype(Type::index())>> {</div>
|
|
<div class="line"> <span class="keyword">static</span> <a class="code" href="namespaceentt.html#a13e040e7b38a8f86d1ab2f096f37b627">entt::id_type</a> <a class="code" href="structentt_1_1type__index.html#ac1a87730c605024e3fb6426fc633380e">value</a>() ENTT_NOEXCEPT {</div>
|
|
<div class="line"> <span class="keywordflow">return</span> Type::index();</div>
|
|
<div class="line"> }</div>
|
|
<div class="line">};</div>
|
|
</div><!-- fragment --><p>Note that indexes <b>must</b> still be generated sequentially in this case.<br />
|
|
The tool is widely used within <code>EnTT</code>. Generating indices not sequentially would break an assumption and would likely lead to undesired behaviors.</p>
|
|
<h2><a class="anchor" id="autotoc_md25"></a>
|
|
Type traits</h2>
|
|
<p>A handful of utilities and traits not present in the standard template library but which can be useful in everyday life.<br />
|
|
This list <b>is not</b> exhaustive and contains only some of the most useful classes. Refer to the inline documentation for more information on the features offered by this module.</p>
|
|
<h3><a class="anchor" id="autotoc_md26"></a>
|
|
Member class type</h3>
|
|
<p>The <code>auto</code> template parameter introduced with C++17 made it possible to simplify many class templates and template functions but also made the class type opaque when members are passed as template arguments.<br />
|
|
The purpose of this utility is to extract the class type in a few lines of code:</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">template</span><<span class="keyword">typename</span> Member></div>
|
|
<div class="line"><span class="keyword">using</span> clazz = <a class="code" href="namespaceentt.html#a49f19d031690e5ebfffd6c7a4f6bd364">entt::member_class_t<Member></a>;</div>
|
|
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md27"></a>
|
|
Integral constant</h3>
|
|
<p>Since <code>std::integral_constant</code> may be annoying because of its form that requires to specify both a type and a value of that type, there is a more user-friendly shortcut for the creation of integral constants.<br />
|
|
This shortcut is the alias template <code><a class="el" href="namespaceentt.html#a0d9fd5898acf13553bbcf14b99159f4d" title="Wraps a static constant.">entt::integral_constant</a></code>:</p>
|
|
<div class="fragment"><div class="line">constexpr <span class="keyword">auto</span> constant = <a class="code" href="namespaceentt.html#a0d9fd5898acf13553bbcf14b99159f4d">entt::integral_constant<42></a>;</div>
|
|
</div><!-- fragment --><p>Among the other uses, when combined with a hashed string it helps to define tags as human-readable <em>names</em> where actual types would be required otherwise:</p>
|
|
<div class="fragment"><div class="line">constexpr <span class="keyword">auto</span> enemy_tag = <a class="code" href="namespaceentt.html#a0d9fd5898acf13553bbcf14b99159f4d">entt::integral_constant</a><<span class="stringliteral">"enemy"</span>_hs>;</div>
|
|
<div class="line"><a class="code" href="namespaceentt.html#a292643317d1dbb13e45824f757bd1086">registry</a>.emplace<enemy_tag>(<a class="code" href="namespaceentt.html#a0b54e231d069e8a231e14b223388808a">entity</a>);</div>
|
|
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md28"></a>
|
|
Tag</h3>
|
|
<p>Since <code>id_type</code> is very important and widely used in <code>EnTT</code>, there is a more user-friendly shortcut for the creation of integral constants based on it.<br />
|
|
This shortcut is the alias template <code><a class="el" href="namespaceentt.html#a9f7bb8c357f08a01ad9c8dab0ea40c1c" title="Alias template to ease the creation of named values.">entt::tag</a></code>.</p>
|
|
<p>If used in combination with hashed strings, it helps to use human-readable names where types would be required otherwise. As an example:</p>
|
|
<div class="fragment"><div class="line"><a class="code" href="namespaceentt.html#a292643317d1dbb13e45824f757bd1086">registry</a>.emplace<<a class="code" href="namespaceentt.html#a9f7bb8c357f08a01ad9c8dab0ea40c1c">entt::tag</a><<span class="stringliteral">"enemy"</span>_hs>>(<a class="code" href="namespaceentt.html#a0b54e231d069e8a231e14b223388808a">entity</a>);</div>
|
|
</div><!-- fragment --><p>However, this isn't the only permitted use. Literally any value convertible to <code>id_type</code> is a good candidate, such as the named constants of an unscoped enum.</p>
|
|
<h1><a class="anchor" id="autotoc_md29"></a>
|
|
Utilities</h1>
|
|
<p>It's not possible to escape the temptation to add utilities of some kind to a library. In fact, <code>EnTT</code> also provides a handful of tools to simplify the life of developers:</p>
|
|
<ul>
|
|
<li><code><a class="el" href="structentt_1_1identity.html" title="Identity function object (waiting for C++20).">entt::identity</a></code>: 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 <em>do nothing</em> function in template programming.</li>
|
|
<li><code><a class="el" href="namespaceentt.html#ac5131df9ce458a6884c43595f501f916" title="Constant utility to disambiguate overloaded members of a class.">entt::overload</a></code>: a tool to disambiguate different overloads from their function type. It works with both free and member functions.<br />
|
|
Consider the following definition:</li>
|
|
</ul>
|
|
<div class="fragment"><div class="line"><span class="keyword">struct </span>clazz {</div>
|
|
<div class="line"> <span class="keywordtype">void</span> bar(<span class="keywordtype">int</span>) {}</div>
|
|
<div class="line"> <span class="keywordtype">void</span> bar() {}</div>
|
|
<div class="line">};</div>
|
|
</div><!-- fragment --><p>This utility can be used to get the <em>right</em> overload as:</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">auto</span> *member = entt::overload<void(int)>(&clazz::bar);</div>
|
|
</div><!-- fragment --><p>The line above is literally equivalent to:</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">auto</span> *member = <span class="keyword">static_cast<</span><span class="keywordtype">void</span>(clazz:: *)(<span class="keywordtype">int</span>)<span class="keyword">></span>(&clazz::bar);</div>
|
|
</div><!-- fragment --><p>Just easier to read and shorter to type.</p>
|
|
<ul>
|
|
<li><code><a class="el" href="structentt_1_1overloaded.html" title="Helper type for visitors.">entt::overloaded</a></code>: a small class template used to create a new type with an overloaded <code>operator()</code> from a bunch of lambdas or functors.<br />
|
|
As an example:</li>
|
|
</ul>
|
|
<div class="fragment"><div class="line"><a class="code" href="structentt_1_1overloaded.html">entt::overloaded</a> func{</div>
|
|
<div class="line"> [](<span class="keywordtype">int</span> value) { <span class="comment">/* ... */</span> },</div>
|
|
<div class="line"> [](<span class="keywordtype">char</span> value) { <span class="comment">/* ... */</span> }</div>
|
|
<div class="line">};</div>
|
|
<div class="line"> </div>
|
|
<div class="line">func(42);</div>
|
|
<div class="line">func(<span class="charliteral">'c'</span>);</div>
|
|
</div><!-- fragment --><p>Rather useful when doing metaprogramming and having to pass to a function a callable object that supports multiple types at once.</p>
|
|
<ul>
|
|
<li><code><a class="el" href="structentt_1_1y__combinator.html" title="Basic implementation of a y-combinator.">entt::y_combinator</a></code>: this is a C++ implementation of <b>the</b> <em>y-combinator</em>. If it's not clear what it is, there is probably no need for this utility.<br />
|
|
Below is a small example to show its use:</li>
|
|
</ul>
|
|
<div class="fragment"><div class="line"><a class="code" href="structentt_1_1y__combinator.html">entt::y_combinator</a> gauss([](<span class="keyword">const</span> <span class="keyword">auto</span> &<span class="keyword">self</span>, <span class="keyword">auto</span> value) -> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> {</div>
|
|
<div class="line"> <span class="keywordflow">return</span> value ? (value + <span class="keyword">self</span>(value-1u)) : 0;</div>
|
|
<div class="line">});</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> result = gauss(3u);</div>
|
|
</div><!-- fragment --><p>Maybe convoluted at a first glance but certainly effective. Unfortunately, the language doesn't make it possible to do much better.</p>
|
|
<p>This is a rundown of the (actually few) utilities made available by <code>EnTT</code>. The list will probably grow over time but the size of each will remain rather small, as has been the case so far. </p>
|
|
</div></div><!-- contents -->
|
|
</div><!-- PageDoc -->
|
|
<div class="ttc" id="anamespaceentt_html_a292643317d1dbb13e45824f757bd1086"><div class="ttname"><a href="namespaceentt.html#a292643317d1dbb13e45824f757bd1086">entt::registry</a></div><div class="ttdeci">basic_registry< entity > registry</div><div class="ttdoc">Alias declaration for the most common use case.</div><div class="ttdef"><b>Definition:</b> <a href="entity_2fwd_8hpp_source.html#l00056">fwd.hpp:56</a></div></div>
|
|
<div class="ttc" id="astructentt_1_1type__index_html_ac1a87730c605024e3fb6426fc633380e"><div class="ttname"><a href="structentt_1_1type__index.html#ac1a87730c605024e3fb6426fc633380e">entt::type_index::value</a></div><div class="ttdeci">static id_type value() noexcept</div><div class="ttdoc">Returns the sequential identifier of a given type.</div><div class="ttdef"><b>Definition:</b> <a href="type__info_8hpp_source.html#l00064">type_info.hpp:64</a></div></div>
|
|
<div class="ttc" id="anamespaceentt_html_a13e040e7b38a8f86d1ab2f096f37b627"><div class="ttname"><a href="namespaceentt.html#a13e040e7b38a8f86d1ab2f096f37b627">entt::id_type</a></div><div class="ttdeci">std::uint32_t id_type</div><div class="ttdoc">Alias declaration for type identifiers.</div><div class="ttdef"><b>Definition:</b> <a href="core_2fwd_8hpp_source.html#l00012">fwd.hpp:12</a></div></div>
|
|
<div class="ttc" id="anamespaceentt_html_a0d9fd5898acf13553bbcf14b99159f4d"><div class="ttname"><a href="namespaceentt.html#a0d9fd5898acf13553bbcf14b99159f4d">entt::integral_constant</a></div><div class="ttdeci">std::integral_constant< decltype(Value), Value > integral_constant</div><div class="ttdoc">Wraps a static constant.</div><div class="ttdef"><b>Definition:</b> <a href="core_2type__traits_8hpp_source.html#l00038">type_traits.hpp:38</a></div></div>
|
|
<div class="ttc" id="astructentt_1_1monostate_html"><div class="ttname"><a href="structentt_1_1monostate.html">entt::monostate</a></div><div class="ttdoc">Minimal implementation of the monostate pattern.</div><div class="ttdef"><b>Definition:</b> <a href="monostate_8hpp_source.html#l00024">monostate.hpp:24</a></div></div>
|
|
<div class="ttc" id="astructentt_1_1type__info_html"><div class="ttname"><a href="structentt_1_1type__info.html">entt::type_info</a></div><div class="ttdoc">Type info.</div><div class="ttdef"><b>Definition:</b> <a href="type__info_8hpp_source.html#l00098">type_info.hpp:98</a></div></div>
|
|
<div class="ttc" id="aclassentt_1_1basic__hashed__string_html"><div class="ttname"><a href="classentt_1_1basic__hashed__string.html">entt::basic_hashed_string</a></div><div class="ttdoc">Zero overhead unique identifier.</div><div class="ttdef"><b>Definition:</b> <a href="hashed__string_8hpp_source.html#l00064">hashed_string.hpp:64</a></div></div>
|
|
<div class="ttc" id="astructentt_1_1y__combinator_html"><div class="ttname"><a href="structentt_1_1y__combinator.html">entt::y_combinator</a></div><div class="ttdoc">Basic implementation of a y-combinator.</div><div class="ttdef"><b>Definition:</b> <a href="core_2utility_8hpp_source.html#l00071">utility.hpp:71</a></div></div>
|
|
<div class="ttc" id="astructentt_1_1type__info_html_aefa2a63e4b4f41dbb783718bdc8c5a76"><div class="ttname"><a href="structentt_1_1type__info.html#aefa2a63e4b4f41dbb783718bdc8c5a76">entt::type_info::id</a></div><div class="ttdeci">static id_type id() noexcept</div><div class="ttdoc">Returns the numeric representation of a given type.</div><div class="ttdef"><b>Definition:</b> <a href="type__info_8hpp_source.html#l00114">type_info.hpp:114</a></div></div>
|
|
<div class="ttc" id="anamespaceentt_html_a9f7bb8c357f08a01ad9c8dab0ea40c1c"><div class="ttname"><a href="namespaceentt.html#a9f7bb8c357f08a01ad9c8dab0ea40c1c">entt::tag</a></div><div class="ttdeci">integral_constant< Value > tag</div><div class="ttdoc">Alias template to ease the creation of named values.</div><div class="ttdef"><b>Definition:</b> <a href="core_2type__traits_8hpp_source.html#l00046">type_traits.hpp:46</a></div></div>
|
|
<div class="ttc" id="aclassentt_1_1identifier_html"><div class="ttname"><a href="classentt_1_1identifier.html">entt::identifier</a></div><div class="ttdoc">Types identifiers.</div><div class="ttdef"><b>Definition:</b> <a href="ident_8hpp_source.html#l00044">ident.hpp:44</a></div></div>
|
|
<div class="ttc" id="astructentt_1_1overloaded_html"><div class="ttname"><a href="structentt_1_1overloaded.html">entt::overloaded</a></div><div class="ttdoc">Helper type for visitors.</div><div class="ttdef"><b>Definition:</b> <a href="core_2utility_8hpp_source.html#l00053">utility.hpp:53</a></div></div>
|
|
<div class="ttc" id="aclassentt_1_1family_html"><div class="ttname"><a href="classentt_1_1family.html">entt::family</a></div><div class="ttdoc">Dynamic identifier generator.</div><div class="ttdef"><b>Definition:</b> <a href="family_8hpp_source.html#l00020">family.hpp:20</a></div></div>
|
|
<div class="ttc" id="aclassentt_1_1basic__hashed__string_html_a1631b1f6ecd56a451366eeb228a6ffb9"><div class="ttname"><a href="classentt_1_1basic__hashed__string.html#a1631b1f6ecd56a451366eeb228a6ffb9">entt::basic_hashed_string::hash_type</a></div><div class="ttdeci">id_type hash_type</div><div class="ttdoc">Unsigned integer type.</div><div class="ttdef"><b>Definition:</b> <a href="hashed__string_8hpp_source.html#l00088">hashed_string.hpp:88</a></div></div>
|
|
<div class="ttc" id="anamespaceentt_html_a0b54e231d069e8a231e14b223388808a"><div class="ttname"><a href="namespaceentt.html#a0b54e231d069e8a231e14b223388808a">entt::entity</a></div><div class="ttdeci">entity</div><div class="ttdoc">Default entity identifier.</div><div class="ttdef"><b>Definition:</b> <a href="entity_2fwd_8hpp_source.html#l00052">fwd.hpp:52</a></div></div>
|
|
<div class="ttc" id="astructentt_1_1type__index_html"><div class="ttname"><a href="structentt_1_1type__index.html">entt::type_index</a></div><div class="ttdoc">Type index.</div><div class="ttdef"><b>Definition:</b> <a href="type__info_8hpp_source.html#l00059">type_info.hpp:59</a></div></div>
|
|
<div class="ttc" id="astructentt_1_1type__info_html_a77b9e5dd77357b99e2ebfb8d0a8b2efc"><div class="ttname"><a href="structentt_1_1type__info.html#a77b9e5dd77357b99e2ebfb8d0a8b2efc">entt::type_info::name</a></div><div class="ttdeci">static constexpr std::string_view name() noexcept</div><div class="ttdoc">Returns the name of a given type.</div><div class="ttdef"><b>Definition:</b> <a href="type__info_8hpp_source.html#l00134">type_info.hpp:134</a></div></div>
|
|
<div class="ttc" id="anamespaceentt_html_a49f19d031690e5ebfffd6c7a4f6bd364"><div class="ttname"><a href="namespaceentt.html#a49f19d031690e5ebfffd6c7a4f6bd364">entt::member_class_t</a></div><div class="ttdeci">typename member_class< Member >::type member_class_t</div><div class="ttdoc">Helper type.</div><div class="ttdef"><b>Definition:</b> <a href="core_2type__traits_8hpp_source.html#l00256">type_traits.hpp:256</a></div></div>
|
|
<!-- start footer part -->
|
|
<hr class="footer"/><address class="footer"><small>
|
|
Generated by <a href="http://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.8.20
|
|
</small></address>
|
|
</body>
|
|
</html>
|