neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
neolib.hpp
Go to the documentation of this file.
1/*
2 * neolib.hpp
3 *
4 * Copyright (c) 2007 Leigh Johnston.
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * * Neither the name of Leigh Johnston nor the names of any
20 * other contributors to this software may be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#pragma once
38
39#include <type_traits>
40#include <cstdint>
41#include <utility>
42#include <variant>
43#include <optional>
44#include <chrono>
45#include <stdexcept>
46#include <string>
47
48#include <neolib/neolib_export.hpp>
49
50#ifdef NDEBUG
51constexpr bool ndebug = true;
52#else
53constexpr bool ndebug = false;
54#endif
55
56#define STRING2(x) #x
57#define STRING(x) STRING2(x)
58
59#define TODO_MSG __FILE__ "(" STRING(__LINE__) "): TODO"
60#ifdef _MSC_VER
61#define TODO \
62 _Pragma("message (TODO_MSG)") \
63 throw std::logic_error(std::string{ TODO_MSG });
64#else
65#define TODO \
66 throw std::logic_error(std::string{ TODO_MSG });
67#endif
68
69#define rvalue_cast static_cast
70
71#define GENERATE_HAS_MEMBER_TYPE(Type) \
72 \
73template <class T, bool OK = std::is_class_v<T>> \
74class HasMemberType_##Type \
75{ \
76public: \
77 static constexpr bool RESULT = false; \
78}; \
79 \
80template <class T> \
81class HasMemberType_##Type<T, true> \
82{ \
83private: \
84 using Yes = char[2]; \
85 using No = char[1]; \
86 \
87 struct Fallback { struct Type { }; }; \
88 struct Derived : T, Fallback { }; \
89 \
90 template < class U > \
91 static No& test ( typename U::Type* ); \
92 template < typename U > \
93 static Yes& test ( U* ); \
94 \
95public: \
96 static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
97}; \
98 \
99template < class T > \
100struct has_member_type_##Type \
101: public std::integral_constant<bool, HasMemberType_##Type<T>::RESULT> \
102{ };
103
104GENERATE_HAS_MEMBER_TYPE(abstract_type)
105
106namespace neolib
107{
108 struct sfinae {};
109
110 template <typename T>
111 using to_const_reference_t = const std::remove_reference_t<T>&;
112 template <typename T>
114 {
115 return const_cast<to_const_reference_t<T>>(object);
116 }
117
118 template <typename T, typename... Ts>
120
121 template <typename T, typename... Ts>
122 struct variadic_index<T, T, Ts...> : std::integral_constant<std::size_t, 0> {};
123
124 template <typename T, typename Tail, typename... Ts>
125 struct variadic_index<T, Tail, Ts...> : std::integral_constant<std::size_t, 1 + variadic_index<T, Ts...>::value> {};
126
127 template <typename T, typename... Ts>
128 constexpr std::size_t index_of_v = variadic_index<T, Ts...>::value;
129
130 template <typename T1, typename T2>
131 class pair;
132
133 namespace detail
134 {
135 template <typename T>
136 struct is_pair { static constexpr bool value = false; };
137 template <typename T1, typename T2>
138 struct is_pair<std::pair<T1, T2>> { static constexpr bool value = true; };
139 template <typename T1, typename T2>
140 struct is_pair<const std::pair<T1, T2>> { static constexpr bool value = true; };
141 template <typename T>
142 constexpr bool is_pair_v = is_pair<T>::value;
143
144 template <typename T>
145 constexpr bool abstract_class_possible_v = std::is_class_v<T> && has_member_type_abstract_type<T>::value;
146
147 template <typename T, typename AT, typename = sfinae>
149 template <typename T, typename AT>
150 struct correct_const<T, AT, typename std::enable_if_t<!std::is_const_v<T>, sfinae>> { typedef AT type; };
151 template <typename T, typename AT>
152 struct correct_const<T, AT, typename std::enable_if_t<std::is_const_v<T>, sfinae>> { typedef const AT type; };
153
154 template <typename T, typename AT>
156
157 template <typename, typename = sfinae>
158 struct abstract_type : std::false_type {};
159 template <typename T>
160 struct abstract_type<T, typename std::enable_if_t<abstract_class_possible_v<T>, sfinae>> : std::true_type { typedef correct_const_t<T, typename T::abstract_type> type; };
161 template <typename T>
162 struct abstract_type<T, typename std::enable_if_t<std::is_arithmetic_v<T>, sfinae>> : std::true_type { typedef correct_const_t<T, T> type; };
163 template <typename T>
164 struct abstract_type<T, typename std::enable_if_t<std::is_enum_v<T>, sfinae>> : std::true_type { typedef correct_const_t<T, T> type; };
165 template <typename T>
166 struct abstract_type<T, typename std::enable_if_t<std::is_pointer_v<T>, sfinae>> : std::true_type { typedef correct_const_t<T, T> type; };
167 template <typename T1, typename T2>
168 struct abstract_type<std::pair<T1, pair<T1, T2>>> : std::false_type { typedef typename abstract_type<pair<T1, T2>>::type type; };
169 template <typename T1, typename T2>
170 struct abstract_type<const std::pair<T1, pair<T1, T2>>> : std::false_type { typedef typename abstract_type<const pair<T1, T2>>::type type; };
171 template <>
172 struct abstract_type<std::monostate> : std::true_type { typedef std::monostate type; };
173 template <typename Rep, typename Period>
174 struct abstract_type<std::chrono::duration<Rep, Period>> : std::true_type { typedef std::chrono::duration<Rep, Period> type; };
175 }
176
177 template <typename T>
179
180 template <typename T, typename = std::enable_if_t<detail::abstract_type<T>::value, sfinae>>
181 inline const abstract_t<T>& to_abstract(const T& aArgument)
182 {
183 return static_cast<const abstract_t<T>&>(aArgument);
184 }
185
186 template <typename T, typename = std::enable_if_t<detail::abstract_type<T>::value, sfinae>>
187 inline abstract_t<T>& to_abstract(T& aArgument)
188 {
189 return static_cast<abstract_t<T>&>(aArgument);
190 }
191
192 template <typename T1, typename T2>
193 inline const abstract_t<pair<T1, T2>>& to_abstract(const std::pair<T1, pair<T1, T2>>& aArgument)
194 {
195 return static_cast<const abstract_t<pair<T1, T2>>&>(aArgument.second);
196 }
197
198 template <typename T1, typename T2>
199 inline abstract_t<neolib::pair<T1, T2>>& to_abstract(std::pair<T1, pair<T1, T2>>& aArgument)
200 {
201 return static_cast<abstract_t<pair<T1, T2>>&>(aArgument.second);
202 }
203
204 namespace detail
205 {
206 template <typename T, typename = sfinae>
208 template <typename T>
209 struct abstract_return_type<T, std::enable_if_t<std::is_scalar_v<T>, sfinae>> { typedef std::remove_const_t<T> type; };
210 }
211
212 template <typename T>
214
215 template <typename T>
216 using cache = std::optional<T>;
217
218 inline constexpr auto invalid = std::nullopt;
219
220 template <typename T>
221 inline void clear_cache(cache<T>& aCachedVariable)
222 {
223 aCachedVariable = invalid;
224 }
225}
226
227#ifdef NEOLIB_HOSTED_ENVIRONMENT
228
229// SIMD support
230#ifndef NO_SIMD
231#ifndef USE_AVX_DYNAMIC
232#define USE_AVX
233#endif
234#ifndef USE_EMM_DYNAMIC
235#define USE_EMM
236#endif
237#endif
238
239#define USING_BOOST
240#define BOOST_BIND_GLOBAL_PLACEHOLDERS
241#define _SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING
242
243#ifdef _WIN32
245#endif
246
247#ifdef USING_BOOST
248#ifndef API
249#include <boost/dll.hpp>
250#define API extern "C" BOOST_SYMBOL_EXPORT
251#endif
252#endif
253
254#endif // NEOLIB_HOSTED_ENVIRONMENT
typename correct_const< T, AT >::type correct_const_t
Definition neolib.hpp:155
constexpr bool is_pair_v
Definition neolib.hpp:142
constexpr bool abstract_class_possible_v
Definition neolib.hpp:145
typename detail::abstract_type< T >::type abstract_t
Definition neolib.hpp:178
typename detail::abstract_return_type< T >::type abstract_return_t
Definition neolib.hpp:213
std::optional< T > cache
Definition neolib.hpp:216
const abstract_t< T > & to_abstract(const T &aArgument)
Definition neolib.hpp:181
constexpr std::size_t index_of_v
Definition neolib.hpp:128
constexpr auto invalid
Definition neolib.hpp:218
to_const_reference_t< T > to_const(T &&object)
Definition neolib.hpp:113
void clear_cache(cache< T > &aCachedVariable)
Definition neolib.hpp:221
const std::remove_reference_t< T > & to_const_reference_t
Definition neolib.hpp:111
Definition plf_hive.h:79
constexpr bool ndebug
Definition neolib.hpp:53
#define GENERATE_HAS_MEMBER_TYPE(Type)
Definition neolib.hpp:71
static constexpr bool value
Definition neolib.hpp:136