Flecs v4.1
A fast entity component system (ECS) for C & C++
Loading...
Searching...
No Matches
utils.hpp
Go to the documentation of this file.
1
9// Macros so that C++ new calls can allocate using ecs_os_api memory allocation functions.
10// Rationale:
11// - Using macros here instead of a templated function because clients might override
12// ecs_os_malloc to contain extra debug info like source tracking location. Using a
13// template function in that scenario would collapse all source locations into said
14// function vs. the actual call site.
15// - FLECS_PLACEMENT_NEW(): exists to remove any naked new calls and make it easy to identify any
16// regressions by grepping for new/delete.
17
18#define FLECS_PLACEMENT_NEW(_ptr, _type) ::new(flecs::_::placement_new_tag, _ptr) _type
19#define FLECS_NEW(_type) FLECS_PLACEMENT_NEW(ecs_os_malloc(sizeof(_type)), _type)
20#define FLECS_DELETE(_ptr) \
21 do { \
22 if (_ptr) { \
23 flecs::_::destruct_obj(_ptr); \
24 ecs_os_free(_ptr); \
25 } \
26 } while (false)
27
28/* Faster (compile-time) alternatives to std::move / std::forward. From:
29 * https://www.foonathan.net/2020/09/move-forward/
30 */
31
32#define FLECS_MOV(...) \
33 static_cast<flecs::remove_reference_t<decltype(__VA_ARGS__)>&&>(__VA_ARGS__)
34
35#define FLECS_FWD(...) \
36 static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)
37
38namespace flecs
39{
40
41namespace _
42{
43
45struct placement_new_tag_t{};
47constexpr placement_new_tag_t placement_new_tag{};
49template<class Ty> inline void destruct_obj(Ty* _ptr) { _ptr->~Ty(); }
51template<class Ty> inline void free_obj(void* _ptr) {
52 if (_ptr) {
53 destruct_obj(static_cast<Ty*>(_ptr));
54 ecs_os_free(_ptr);
55 }
56}
57
58} // namespace _
59
60} // namespace flecs
61
62// Allows overriding flecs_static_assert, which is useful when testing.
63#ifndef flecs_static_assert
64#define flecs_static_assert(cond, str) static_assert(cond, str)
65#endif
66
67inline void* operator new(size_t, flecs::_::placement_new_tag_t, void* _ptr) noexcept { return _ptr; }
68inline void operator delete(void*, flecs::_::placement_new_tag_t, void*) noexcept { }
69
70namespace flecs
71{
72
74template <bool> struct condition;
75
77template <> struct condition<false> {
79 template <typename T, typename F> using type = F;
80};
81
83template <> struct condition<true> {
85 template <typename T, typename F> using type = T;
86};
87
88using std::conditional_t;
89using std::decay_t;
90using std::enable_if_t;
91using std::remove_pointer_t;
92using std::remove_reference_t;
93using std::underlying_type_t;
94using std::is_base_of;
95using std::is_empty;
96using std::is_const;
97using std::is_pointer;
98using std::is_reference;
99using std::is_volatile;
100using std::is_same;
101using std::is_enum;
102using std::is_trivially_constructible;
103using std::is_trivially_move_assignable;
104using std::is_trivially_copy_assignable;
105using std::is_trivially_copy_constructible;
106using std::is_trivially_move_constructible;
107using std::is_trivially_copyable;
108using std::is_move_assignable;
109using std::is_move_constructible;
110using std::is_copy_constructible;
111using std::is_trivially_destructible;
112using std::is_empty_v;
113using std::is_const_v;
114using std::is_pointer_v;
115using std::is_reference_v;
116using std::is_volatile_v;
117using std::is_same_v;
118using std::is_enum_v;
119using std::is_base_of_v;
120using std::is_trivially_constructible_v;
121using std::is_trivially_destructible_v;
122using std::is_trivially_copyable_v;
123using std::is_trivially_move_constructible_v;
124using std::is_trivially_copy_constructible_v;
125using std::is_trivially_move_assignable_v;
126using std::is_trivially_copy_assignable_v;
127using std::is_default_constructible_v;
128using std::is_move_constructible_v;
129using std::is_copy_constructible_v;
130using std::is_move_assignable_v;
131using std::is_copy_assignable_v;
132using std::is_destructible_v;
133
135template <typename T>
136using is_const_p = is_const< remove_pointer_t<T> >;
137
139template<class Src, class Dst>
140using transcribe_const_t = conditional_t<is_const<Src>::value, Dst const, Dst>;
141
143template<class Src, class Dst>
144using transcribe_volatile_t = conditional_t<is_volatile<Src>::value, Dst volatile, Dst>;
145
147template<class Src, class Dst>
149
151template<class Src, class Dst>
152using transcribe_pointer_t = conditional_t<is_pointer<Src>::value, Dst*, Dst>;
153
155template<class Src, class Dst>
157
158
167template <bool V>
168using if_t = enable_if_t<V, int>;
169
171template <bool V>
172using if_not_t = enable_if_t<false == V, int>;
173
174namespace _
175{
176
178template <class... T>
179struct always_false {
180 static const bool value = false;
181};
182
183} // namespace _
184
185} // namespace flecs
186
187#include "array.hpp"
188#include "string.hpp"
189#include "enum.hpp"
190#include "stringstream.hpp"
191#include "function_traits.hpp"
192
193namespace flecs {
194namespace _ {
195
197#if defined(__GNUC__) || defined(_WIN32)
198template <typename T>
199inline const char* type_name() {
200 static const size_t len = ECS_FUNC_TYPE_LEN(const char*, type_name, ECS_FUNC_NAME);
201 static char result[len + 1] = {};
202 static const size_t front_len = ECS_FUNC_NAME_FRONT(const char*, type_name);
203 static const char* cppTypeName = ecs_cpp_get_type_name(result, ECS_FUNC_NAME, len, front_len);
204 return cppTypeName;
205}
206#else
207#error "implicit component registration not supported"
208#endif
209
210}
211}
Array class.
Compile-time enum reflection utilities.
Compile-time utilities to inspect properties of functions.
String utility that doesn't implicitly allocate memory.
Wrapper around ecs_strbuf_t that provides a simple stringstream-like API.
F type
Select the second type.
Definition utils.hpp:79
T type
Select the first type.
Definition utils.hpp:85
Compile-time conditional type selector (faster alternative to std::conditional).
Definition utils.hpp:74
enable_if_t< false==V, int > if_not_t
Convenience enable_if alias for negated conditions.
Definition utils.hpp:172
enable_if_t< V, int > if_t
Convenience enable_if alias using int as default type.
Definition utils.hpp:168
conditional_t< is_volatile< Src >::value, Dst volatile, Dst > transcribe_volatile_t
Apply volatile from source type to destination type.
Definition utils.hpp:144
transcribe_cv_t< Src, transcribe_pointer_t< Src, Dst > > transcribe_cvp_t
Apply const, volatile, and pointer from source type to destination type.
Definition utils.hpp:156
is_const< remove_pointer_t< T > > is_const_p
Determine constness even if T is a pointer type.
Definition utils.hpp:136
conditional_t< is_const< Src >::value, Dst const, Dst > transcribe_const_t
Apply const from source type to destination type.
Definition utils.hpp:140
conditional_t< is_pointer< Src >::value, Dst *, Dst > transcribe_pointer_t
Apply pointer from source type to destination type.
Definition utils.hpp:152
transcribe_const_t< Src, transcribe_volatile_t< Src, Dst > > transcribe_cv_t
Apply const and volatile from source type to destination type.
Definition utils.hpp:148