Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
utility.h
Go to the documentation of this file.
1#pragma once
2
3#include "Utility/traits.h"
4
5#include <Common/assertion.h>
6#include <Common/exceptions.h>
7
8#include <bit>
9#include <concepts>
10#include <cstddef>
11#include <cstring>
12#include <limits>
13#include <string>
14#include <string_view>
15#include <type_traits>
16#include <utility>
17#include <variant>
18#include <version>
19
23#define PH_DECLARE_RULE_OF_5_MEMBERS_NO_DTOR(ClassType)\
24 ClassType();\
25 ClassType(const ClassType& other);\
26 ClassType(ClassType&& other) noexcept;\
27 ClassType& operator = (const ClassType& rhs);\
28 ClassType& operator = (ClassType&& rhs) noexcept
29
33#define PH_DEFINE_RULE_OF_5_MEMBERS_NO_DTOR(ClassType)\
34 ClassType::ClassType() = default;\
35 ClassType::ClassType(const ClassType& other) = default;\
36 ClassType::ClassType(ClassType&& other) noexcept = default;\
37 ClassType& ClassType::operator = (const ClassType& rhs) = default;\
38 ClassType& ClassType::operator = (ClassType&& rhs) noexcept = default
39
43#define PH_DEFINE_INLINE_RULE_OF_5_MEMBERS_NO_DTOR(ClassType)\
44 inline ClassType() = default;\
45 inline ClassType(const ClassType& other) = default;\
46 inline ClassType(ClassType&& other) noexcept = default;\
47 inline ClassType& operator = (const ClassType& rhs) = default;\
48 inline ClassType& operator = (ClassType&& rhs) noexcept = default
49
52#define PH_DECLARE_RULE_OF_5_MEMBERS(ClassType)\
53 PH_DECLARE_RULE_OF_5_MEMBERS_NO_DTOR(ClassType);\
54 ~ClassType()
55
58#define PH_DEFINE_RULE_OF_5_MEMBERS(ClassType)\
59 PH_DEFINE_RULE_OF_5_MEMBERS_NO_DTOR(ClassType);\
60 ClassType::~ClassType() = default
61
64#define PH_DEFINE_INLINE_RULE_OF_5_MEMBERS(ClassType)\
65 PH_DEFINE_INLINE_RULE_OF_5_MEMBERS_NO_DTOR(ClassType);\
66 inline ~ClassType() = default
67
68namespace ph
69{
70
77template<typename T>
78inline T* ptr_access(T* const ptr)
79{
80 return ptr;
81}
82
83template<typename T>
84inline T* ptr_access(T& ref)
85{
86 return &ref;
87}
88
93template<typename T>
94inline T* ptr_access(T&& ref) = delete;
95
96template<typename T>
97inline T& ref_access(T& ref)
98{
99 return ref;
100}
101
102template<typename T>
103inline T& ref_access(T* const ptr)
104{
105 PH_ASSERT(ptr);
106 return *ptr;
107}
108
112inline void ref_access(std::nullptr_t /* ptr */) = delete;
113
118template<typename T>
119inline T& ref_access(T&& ref) = delete;
121
125template<typename Target, typename Source>
126inline Target bitwise_cast(const Source& source)
127{
128 static_assert(std::is_trivially_copyable_v<Source>);
129 static_assert(std::is_trivially_copyable_v<Target>);
130
131 static_assert(sizeof(Source) == sizeof(Target),
132 "Source and Target must have the same size");
133
134 if constexpr(std::is_same_v<Source, Target>)
135 {
136 return source;
137 }
138 else
139 {
140#if __cpp_lib_bit_cast
141 return std::bit_cast<Target>(source);
142#else
143 Target target;
144 std::memcpy(&target, &source, sizeof(Source));
145 return target;
146#endif
147 }
148}
149
153inline consteval bool is_big_endian()
154{
155#if __cpp_lib_endian
156 return std::endian::native == std::endian::big;
157#else
158 static_assert(sizeof(int) > sizeof(char));
159
160 constexpr int i = 0x07;
161 return reinterpret_cast<const char*>(&i)[0] != '\x07';
162#endif
163}
164
165template<CEnum EnumType>
166inline constexpr auto enum_to_value(const EnumType enumValue)
167{
168 using ValueType = std::underlying_type_t<EnumType>;
169 return static_cast<ValueType>(enumValue);
170}
171
172template<CEnum EnumType>
173inline std::string enum_to_string(const EnumType enumValue)
174{
175 return std::to_string(enum_to_value(enumValue));
176}
177
178template<CEnumWithSizeInfo EnumType>
179inline constexpr auto enum_size()
180{
181 return enum_to_value(EnumType::SIZE);
182}
183
184template<typename T, T VALUE>
186{};
187
216template<typename T>
217inline constexpr T& mutable_cast(const T& value) noexcept
218{
219 return const_cast<T&>(value);
220}
221
222template<typename T>
223inline constexpr T* mutable_cast(const T* value) noexcept
224{
225 return const_cast<T*>(value);
226}
227
228template<typename T>
229inline constexpr T* mutable_cast(T* value) noexcept
230{
231 return value;
232}
233
234template<typename T>
235inline void mutable_cast(const T&&) = delete;
237
238template<typename TypeInVariant, typename VariantType, std::size_t D_INDEX = 0>
239inline constexpr std::size_t variant_index_of() noexcept
240{
241 if constexpr(D_INDEX == std::variant_size_v<VariantType>)
242 {
243 static_assert(D_INDEX < std::variant_size_v<VariantType>,
244 "`TypeInVariant` must be one of the types in variant.");
245 }
246 else if constexpr(std::is_same_v<std::variant_alternative_t<D_INDEX, VariantType>, TypeInVariant>)
247 {
248 return D_INDEX;
249 }
250 else
251 {
252 return variant_index_of<TypeInVariant, VariantType, D_INDEX + 1>();
253 }
254}
255
256template<typename TypeInVariant, typename InVariantType>
257inline constexpr std::size_t variant_index_of(const InVariantType& /* variant */) noexcept
258{
259 using VariantType = std::remove_cvref_t<InVariantType>;
260
261 return variant_index_of<TypeInVariant, VariantType>();
262}
263
264}// end namespace ph
The root for all renderer implementations.
Definition EEngineProject.h:6
constexpr auto enum_size()
Definition utility.h:179
T & ref_access(T &ref)
Definition utility.h:97
std::string enum_to_string(const EnumType enumValue)
Definition utility.h:173
consteval bool is_big_endian()
Definition utility.h:153
Target bitwise_cast(const Source &source)
Definition utility.h:126
T * ptr_access(T *const ptr)
Access a target's member consistently using . or -> operators. Note that these functions treat smart ...
Definition utility.h:78
constexpr auto enum_to_value(const EnumType enumValue)
Definition utility.h:166
Definition utility.h:186