MT Core (C++)
Core library for replacing C++ standard in project usage
Loading...
Searching...
No Matches
core/mtcore/core.hpp
Go to the documentation of this file.
1/*
2
3Copyright 2025 Matthew Tolman
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16
17*/
18
23
28
29#pragma once
30
31#ifndef MTCORE_CORE_HPP
32#define MTCORE_CORE_HPP
33
34#include <cerrno>
35#ifndef MTCORE_NO_STACKTRACE
36#include <cpptrace/cpptrace.hpp>
37#endif
38
39#include <cstdarg>
40#include <cstdint>
41#include <cstdio>
42#include <cstdlib>
43#include <cstring>
44#include <iostream>
45
46#if defined __linux__ || defined __EMSCRIPTEN__
48using Environ = char **;
49#else
51using Environ = const char **;
52#endif
53
54// NOLINTBEGIN
59typedef float f32;
64typedef double f64;
69typedef long double f80;
74typedef int8_t i8;
79typedef int16_t i16;
84typedef int32_t i32;
89typedef int64_t i64;
94typedef uint8_t u8;
99typedef uint16_t u16;
104typedef uint32_t u32;
109typedef uint64_t u64;
114typedef uintptr_t uptr;
119typedef wchar_t wchar;
120
121#ifndef EXIT_MAX
126#define EXIT_MAX 255
127#endif
128
129#ifndef EXIT_ABORT
134#define EXIT_ABORT EXIT_MAX
135#endif
136
137typedef int ThreeWayCompare;
138// NOLINTEND
139
140#ifndef mt_print_cur_stacktrace
141#ifndef MTCORE_NO_STACKTRACE
146#define mt_print_cur_stacktrace(...) \
147 (void) fprintf(stderr, __VA_ARGS__); \
148 (void) fflush(stderr); \
149 cpptrace::stacktrace::current(1).print(std::cerr);
150#else
151#define mt_print_cur_stacktrace(...) \
152 (void) fprintf(stderr, __VA_ARGS__); \
153 (void) fflush(stderr);
154#endif
155#endif
156
157#ifndef mt_print_stacktrace
158#ifndef MTCORE_NO_STACKTRACE
163#define mt_print_stacktrace(TRACE, ...) \
164 (void) fprintf(stderr, __VA_ARGS__); \
165 (void) fflush(stderr); \
166 (TRACE).print(std::cerr);
167#else
168#define mt_print_stacktrace(TRACE, ...) \
169 (void) fprintf(stderr, __VA_ARGS__); \
170 (void) fflush(stderr);
171#endif
172#endif
173
174#ifndef NDEBUG
180#define not_implemented() unreachable("NOT IMPLEMENTED")
181#else
188#define not_implemented() \
189 unreachable("NOT IMPLEMENTED"); \
190 static_assert(false, "CODE NOT IMPLEMENTED");
191#endif
192
193#ifndef print_debug
194#ifndef NDEBUG
199#define print_debug(fmt, ...) (void) fprintf(stderr, "\nDEBUG AT %s:%d! " fmt "\n", __FILE__, __LINE__, __VA_ARGS__)
200#else
206#define print_debug(fmt, ...)
207#endif
208#endif
209
216#define ensure(check, ...) \
217 if (!(check)) { \
218 mt_print_cur_stacktrace("\nCONDITION FAILED!\n\t" \
219 "CONDITION: %s\n\t" \
220 "MESSAGE: %s\n\t" \
221 "WHERE: %s:%d\n\t" \
222 "ERRNO: " \
223 "%d\n\tERRNO DESC: %s\n", \
224 #check, #__VA_ARGS__, __FILE__, __LINE__, errno, strerror(errno)); \
225 abort(); \
226 }
227
228#if defined(_MSC_VER) && !defined(__clang__) // MSVC
232#define unreachable(...) \
233 mt_print_cur_stacktrace("\n\nUNREACHABLE!\n\t" \
234 "MESSAGE: %s\n\t" \
235 "WHERE: %s:%d\n\t" \
236 "ERRNO: " \
237 "%d\n\tERRNO DESC: %s\n", \
238 #__VA_ARGS__, __FILE__, __LINE__, errno, strerror(errno)); \
239 __assume(false); \
240 abort();
241#else // GCC, Clang
246#define unreachable(...) \
247 mt_print_cur_stacktrace("\nUNREACHABLE!\n\t" \
248 "MESSAGE: %s\n\t" \
249 "WHERE: %s:%d\n\t" \
250 "ERRNO: " \
251 "%d\n\tERRNO DESC: %s\n", \
252 #__VA_ARGS__, __FILE__, __LINE__, errno, strerror(errno)); \
253 __builtin_unreachable(); \
254 abort();
255#endif
256
257#ifndef NDEBUG
262#define mtcore_warn_trace(...) \
263 mt_print_cur_stacktrace("\nWARNING!\n\t" \
264 "MESSAGE: %s\n\t" \
265 "WHERE: %s:%d\n", \
266 #__VA_ARGS__, __FILE__, __LINE__);
267
271#define mtcore_warn(...) \
272 fprintf(stderr, \
273 "\nWARNING!\n\t" \
274 "MESSAGE: %s\n\t" \
275 "WHERE: %s:%d\n", \
276 #__VA_ARGS__, __FILE__, __LINE__); \
277 (void) fflush(stderr);
278#else
284#define mtcore_warn(...)
290#define mtcore_warn_trace(...)
291#endif
292
293namespace mtcore {
301
305 template<typename... Ts>
306 struct overload : Ts... {
307 using Ts::operator()...;
308 };
309
310 template<class... Ts>
311 overload(Ts...) -> overload<Ts...>;
312
313 namespace defer_impl {
314 // Struct that will be used for operator overloading
315 // we're using our own struct so that we don't have to worry about overloading
316 // collisions with other code
317 struct DeferrerBuilder {};
318
319 // The deferrer struct uses RAII to delay calling a callable
320 // We intentionally don't define any custom constructors or make them explicit
321 template<class F>
322 struct Deferrer {
323 F f;
324
325 ~Deferrer() { f(); }
326 };
327
328 // We define a custom operator that takes a builder type and our function
329 // callable type so we can generate a deferrable
330 // without the use of parenthesis
331 // When we combine this with our macro, we will be able to create a block of
332 // code which turns into a deferred lambda
333 template<class F>
334 Deferrer<F> operator+(DeferrerBuilder, F f) {
335 return {f};
336 }
337 } // namespace defer_impl
338
339#define DEFER_(LINE) zz_defer##LINE
340#define DEFER(LINE) DEFER_(LINE)
341
342 // NOLINTBEGIN
357#define mtdefer auto DEFER(__LINE__) = mtcore::defer_impl::DeferrerBuilder{} + [&]()
358 // NOLINTEND
359} // namespace mtcore
360
361#endif // MTCORE_CORE_HPP
const char ** Environ
Environment variable typedef.
int ThreeWayCompare
CollectionAddNoAllocationError
Errors when adding elements to collections when no allocation is allowed.
uint64_t u64
Alias for 64-bit unsigned ints.
int32_t i32
Alias for 32-bit ints.
wchar_t wchar
Alias for ints the same size as a wide character.
float f32
Alias for 32-bit floats.
int64_t i64
Alias for 64-bit ints.
uint8_t u8
Alias for 8-bit unsigned ints.
uintptr_t uptr
Alias for ints the same size as a pointer.
double f64
Alias for 64-bit floats.
long double f80
Alias for 80-bit floats.
uint16_t u16
Alias for 16-bit unsigned ints.
int16_t i16
Alias for 16-bit ints.
int8_t i8
Alias for 8-bit ints.
uint32_t u32
Alias for 32-bit unsigned ints.
Core library for C++ with Zig-related functionality.
overload(Ts...) -> overload< Ts... >
Visit overload pattern for std::variant.