You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

181 lines
5.2 KiB

/**
* Copyright (c) 2018 Niklas Rosenstein
* MIT licensed.
*/
#pragma once
/**
* This macro can be explicitly defined to enable/disable debug
* functionality. Otherwise it will fall back on enabled when
* either `DEBUG` or `_DEBUG` is defined.
*/
#if !defined(NR_DEBUG)
#if defined(DEBUG) || defined(_DEBUG)
#define NR_DEBUG 1
#else
#define NR_DEBUG 0
#endif
#endif
/**
* This macro allows you to create an enclosed scope that can be
* exited with a `break` or `continue` statement.
*
* NR_SCOPE {
* // ...
* if (some_condition()) {
* break;
* }
* // ...
* }
*/
#define NR_SCOPE \
for (bool __nr_break=false; !__nr_break; __nr_break=true)
/**
* This macro allows you to create an enclosed scope that can be
* exited with a `break` or `continue` statement and that will
* only be entered if the #condition evaluates to true.
*
* NR_IF (some_condition()) {
* // do stuff
* if (!some_other_condition()) break;
* // do stuff
* }
*
* Note that you can not use else-if or else-clauses with this macro.
*/
#define NR_IF(condition) \
for (bool __nr_break=false; !__nr_break && (condition); __nr_break=true)
/**
* Use this macro to define a global variable or a static class
* member in a compilation unit instead of writing the actual type
* of the member again.
*
* extern int x;
* NR_DECL(x) = 42;
*
* class Foo { static int y; };
* NR_DECL(Foo::y) = 0;
*/
#define NR_DECL(member) decltype(member) member
/**
* @macro NR_INLINE_PRAGMA(...)
* @macro NR_INLINE_PRAGMA_CLANG(...)
* @macro NR_INLINE_PRAGMA_GCC(...)
* @macro NR_INLINE_PRAGMA_MSVC(...)
*
* Generate an inline pragma expression that can be used inside macro
* definitions. The macros with the respective compiler name will only
* evaluate to the pragma instruction if the source is compiled with the
* respective compiler.
*/
#if defined(__llvm__) || defined(__clang__) || defined(__GNUC__)
#define NR_INLINE_PRAGMA(...) _Pragma(#__VA_ARGS__)
#if defined(__llvm__) || defined(__clang__)
#define NR_INLINE_PRAGMA_CLANG(...) NR_INLINE_PRAGMA(__VA_ARGS__)
#elif defined(__GNUC__)
#define NR_INLINE_PRAGMA_GCC(...) NR_INLINE_PRAGMA(__VA_ARGS__)
#else
#error "unexpected error"
#endif
#elif defined(_MSC_VER)
#define NR_INLINE_PRAGMA(...) __pragma(__VA_ARGS__)
#define NR_INLINE_PRAGMA_MSVC(...) NR_INLINE_PRAGMA(__VA_ARGS__)
#else
#error "compiler could not be detected"
#endif
#ifndef NR_INLINE_PRAGMA_CLANG
#define NR_INLINE_PRAGMA_CLANG(...)
#endif
#ifndef NR_INLINE_PRAGMA_GCC
#define NR_INLINE_PRAGMA_GCC(...)
#endif
#ifndef NR_INLINE_PRAGMA_MSVC
#define NR_INLINE_PRAGMA_MSVC(...)
#endif
/**
* @macro NR_PLATFORM
* @macro NR_PLATFORM_WINDOWS
* @macro NR_PLATFORM_WINDOWS_64
* @macro NR_PLATFORM_MACOS
* @macro NR_PLATFORM_MACOS_IPHONE
* @macro NR_PLATFORM_MACOS_IPHONE_SIMULATOR
* @macro NR_PLATFORM_LINUX
* @macro NR_PLATFORM_UNIX
* @macro NR_PLATFORM_POSIX
*
* One of these macros is defined depending on the platform that is currently
* compiled for. Some of these macros can be defined both at the same time.
* The only exception is #NR_PLATFORM which is a string identifying the generic
* platorm name.
*/
#if defined(_WIN32)
#define NR_PLATFORM_WINDOWS
#if defined(_WIN64)
#define NR_PLATFORM "windows-x64"
#define NR_PLATFORM_WINDOWS_64
#else
#define NR_PLATFORM "windows-x86"
#endif
#elif defined(__APPLE__)
#define NR_PLATFORM_UNIX
#define NR_PLATFORM_MACOS
#include "TargetConditionals.h"
#if TARGET_IPHONE_SIMULATOR
#define NR_PLATFORM "macos-iphone-simulator"
#define NR_PLATFORM_MACOS_IPHONE
#define NR_PLATFORM_MACOS_IPHONE_SIMULATOR
#elif TARGET_OS_IPHONE
#define NR_PLATFORM "macos-iphone"
#define NR_PLATFORM_MACOS_IPHONE
#elif TARGET_OS_MAC
// Some other kind of Mac OS
#define NR_PLATFORM "macos"
#endif
#elif defined(__linux__) && __linux__
#define NR_PLATFORM "linux"
#define NR_PLATFORM_UNIX
#define NR_PLATFORM_LINUX
#elif defined(__unix__) && __unix__
#define NR_PLATFORM "unix"
#define NR_PLATFORM_UNIX
#elif defined(_POSIX_VERSION)
#define NR_PLATFORM "posix"
#define NR_PLATFORM_POSIX
#elif !defined(NR_PLATFORM)
#warning "Unable to identify this platform, macro NR_PLATFORM stays undefined."
#endif
/**
* @macro NR_CURRENT_FUNCTION
*
* Copied from `BOOST_CURRENT_FUNCTION`.
*/
#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
# define NR_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__DMC__) && (__DMC__ >= 0x810)
# define NR_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__FUNCSIG__)
# define NR_CURRENT_FUNCTION __FUNCSIG__
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
# define NR_CURRENT_FUNCTION __FUNCTION__
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
# define NR_CURRENT_FUNCTION __FUNC__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
# define NR_CURRENT_FUNCTION __func__
#elif defined(__cplusplus) && (__cplusplus >= 201103)
# define NR_CURRENT_FUNCTION __func__
#else
# define NR_CURRENT_FUNCTION "(unknown)"
#endif