#pragma once #include #include namespace Math { static const long double e = 2.71828182845904523536; static const long double Pi = 3.14159265358979323846; } #if defined(PLATFORM_WINDOWS) #if defined(NALL_HEADER_ONLY) #include #endif #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if !defined(PLATFORM_WINDOWS) #include #include #include #include #include #include #include #include #include #include #include #endif #if defined(ARCHITECTURE_X86) || defined(ARCHITECTURE_AMD64) #include #undef _serialize #endif #if !defined(__has_builtin) #define __has_builtin(x) 0 #endif #if defined(PLATFORM_WINDOWS) #define dllexport __declspec(dllexport) #define MSG_NOSIGNAL 0 #define PATH_MAX 260 typedef void* HANDLE; inline auto access(const char* path, int amode) -> int { return _waccess(nall::utf16_t(path), amode); } inline auto getcwd(char* buf, size_t size) -> char* { wchar_t wpath[PATH_MAX] = L""; if(!_wgetcwd(wpath, size)) return nullptr; strcpy(buf, nall::utf8_t(wpath)); return buf; } inline auto mkdir(const char* path, int mode) -> int { return _wmkdir(nall::utf16_t(path)); } inline auto poll(struct pollfd fds[], unsigned long nfds, int timeout) -> int; inline auto putenv(const char* value) -> int { return _wputenv(nall::utf16_t(value)); } inline auto realpath(const char* file_name, char* resolved_name) -> char* { wchar_t wfile_name[PATH_MAX] = L""; if(!_wfullpath(wfile_name, nall::utf16_t(file_name), PATH_MAX)) return nullptr; strcpy(resolved_name, nall::utf8_t(wfile_name)); return resolved_name; } inline auto rename(const char* oldname, const char* newname) -> int { return _wrename(nall::utf16_t(oldname), nall::utf16_t(newname)); } namespace nall { //network functions take void*, not char*. this allows them to be used without casting auto recv(int socket, void* buffer, size_t length, int flags) -> ssize_t; auto send(int socket, const void* buffer, size_t length, int flags) -> ssize_t; auto setsockopt(int socket, int level, int option_name, const void* option_value, int option_len) -> int; auto usleep(unsigned int us) -> int; } #else #define dllexport #endif #undef bswap16 #undef bswap32 #undef bswap64 #undef bswap128 #undef likely #undef unlikely #if defined(COMPILER_CLANG) || defined(COMPILER_GCC) #define bswap16(value) __builtin_bswap16(value) #define bswap32(value) __builtin_bswap32(value) #define bswap64(value) __builtin_bswap64(value) #if defined(__SIZEOF_INT128__) inline auto bswap128(u128 value) -> u128 { #if defined(__SSSE3__) static const __m128i shuffle = _mm_setr_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); return reinterpret_cast(_mm_shuffle_epi8(reinterpret_cast<__m128i>(value), shuffle)); #else return (u128)__builtin_bswap64(value) << 64 | __builtin_bswap64(value >> 64); #endif } #endif #define likely(expression) __builtin_expect(bool(expression), true) #define unlikely(expression) __builtin_expect(bool(expression), false) #elif defined(COMPILER_MICROSOFT) #define bswap16(value) _byteswap_ushort(value) #define bswap32(value) _byteswap_ulong(value) #define bswap64(value) _byteswap_uint64(value) #define likely(expression) expression #define unlikely(expression) expression #else inline auto bswap16(u16 value) -> u16 { return value << 8 | value >> 8; } inline auto bswap32(u32 value) -> u32 { return (u32)bswap16(value) << 16 | bswap16(value >> 16); } inline auto bswap64(u64 value) -> u64 { return (u64)bswap32(value) << 32 | bswap32(value >> 32); } #if defined(__SIZEOF_INT128__) inline auto bswap128(u128 value) -> u128 { return (u128)bswap64(value) << 64 | bswap64(value >> 64); } #endif #define likely(expression) expression #define unlikely(expression) expression #endif namespace nall { //notify the processor/operating system that this thread is currently awaiting an event (eg a spinloop) //calling this function aims to avoid consuming 100% CPU resources on the active thread during spinloops inline auto spinloop() -> void { #if defined(ARCHITECTURE_X86) || defined(ARCHITECTURE_AMD64) #if defined(COMPILER_CLANG) || defined(COMPILER_GCC) __builtin_ia32_pause(); return; #elif defined(COMPILER_MICROSOFT) _mm_pause(); return; #endif #endif usleep(1); } } #if defined(PLATFORM_MACOS) && !defined(MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 #endif #if defined(COMPILER_CLANG) || defined(COMPILER_GCC) #define no_optimize __attribute__((optnone)) #define noinline __attribute__((noinline)) #define alwaysinline inline __attribute__((always_inline)) #elif defined(COMPILER_MICROSOFT) #define no_optimize #define noinline __declspec(noinline) #define alwaysinline inline __forceinline #else #define no_optimize #define noinline #define alwaysinline inline #endif //P0627: [[unreachable]] -- impossible to simulate with identical syntax, must omit brackets ... #if defined(COMPILER_CLANG) || defined(COMPILER_GCC) #define unreachable __builtin_unreachable() #elif defined(COMPILER_MICROSOFT) #define unreachable __assume(0) #else #define unreachable throw #endif #if defined(COMPILER_GCC) #undef _serialize #endif #define export $export #define register $register #if defined(NALL_HEADER_ONLY) #include #endif