Fixes for MSVC

This commit is contained in:
2025-07-02 14:19:05 -07:00
parent 9010650ceb
commit 9ea63478e5
22 changed files with 468 additions and 285 deletions

View File

@@ -163,7 +163,7 @@ if(DOXYGEN_FOUND)
# Target for cleaning docs # Target for cleaning docs
add_custom_target(fennecdocs-clean ALL add_custom_target(fennecdocs-clean ALL
COMMAND rm -r "${PROJECT_SOURCE_DIR}/docs/" COMMAND ${CMAKE_COMMAND} -E remove -f "${PROJECT_SOURCE_DIR}/docs/"
COMMENT "Cleaning Doxygen Documentation" COMMENT "Cleaning Doxygen Documentation"
VERBATIM) VERBATIM)
else() else()

View File

@@ -68,7 +68,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If # entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used. # left blank the current directory will be used.
OUTPUT_DIRECTORY = /home/medusa/Documents/Work/Personal/fennec/docs OUTPUT_DIRECTORY = C:/Users/msloc/Documents/Work/Personal/fennec/docs
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 # If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096
# sub-directories (in 2 levels) under the output directory of each output format # sub-directories (in 2 levels) under the output directory of each output format
@@ -815,7 +815,7 @@ FILE_VERSION_FILTER =
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty. # tag is left empty.
LAYOUT_FILE = /home/medusa/Documents/Work/Personal/fennec/doxy/DoxyLayout.xml LAYOUT_FILE = C:/Users/msloc/Documents/Work/Personal/fennec/doxy/DoxyLayout.xml
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing # The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib # the reference definitions. This must be a list of .bib files. The .bib
@@ -943,9 +943,9 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = "/home/medusa/Documents/Work/Personal/fennec/include/" \ INPUT = "C:/Users/msloc/Documents/Work/Personal/fennec/include/" \
"/home/medusa/Documents/Work/Personal/fennec/source/" \ "C:/Users/msloc/Documents/Work/Personal/fennec/source/" \
"/home/medusa/Documents/Work/Personal/fennec/README.md" "C:/Users/msloc/Documents/Work/Personal/fennec/README.md"
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -1079,7 +1079,7 @@ EXCLUDE_SYMBOLS =
# that contain example code fragments that are included (see the \include # that contain example code fragments that are included (see the \include
# command). # command).
EXAMPLE_PATH = "/home/medusa/Documents/Work/Personal/fennec" EXAMPLE_PATH = "C:/Users/msloc/Documents/Work/Personal/fennec"
# If the value of the EXAMPLE_PATH tag contains directories, you can use the # If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
@@ -1160,7 +1160,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub # (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output. # and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE = "/home/medusa/Documents/Work/Personal/fennec/README.md" USE_MDFILE_AS_MAINPAGE = "C:/Users/msloc/Documents/Work/Personal/fennec/README.md"
# The Fortran standard specifies that for fixed formatted Fortran code all # The Fortran standard specifies that for fixed formatted Fortran code all
# characters from position 72 are to be considered as comment. A common # characters from position 72 are to be considered as comment. A common
@@ -1359,7 +1359,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation. # of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER = /home/medusa/Documents/Work/Personal/fennec/doxy/header.html HTML_HEADER = C:/Users/msloc/Documents/Work/Personal/fennec/doxy/header.html
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard # generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1369,7 +1369,7 @@ HTML_HEADER = /home/medusa/Documents/Work/Personal/fennec/doxy/header
# that doxygen normally uses. # that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FOOTER = /home/medusa/Documents/Work/Personal/fennec/doxy/footer.html HTML_FOOTER = C:/Users/msloc/Documents/Work/Personal/fennec/doxy/footer.html
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of # sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1381,7 +1381,7 @@ HTML_FOOTER = /home/medusa/Documents/Work/Personal/fennec/doxy/footer
# obsolete. # obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_STYLESHEET = /home/medusa/Documents/Work/Personal/fennec/doxy/style.css HTML_STYLESHEET = C:/Users/msloc/Documents/Work/Personal/fennec/doxy/style.css
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# cascading style sheets that are included after the standard style sheets # cascading style sheets that are included after the standard style sheets
@@ -1399,10 +1399,10 @@ HTML_STYLESHEET = /home/medusa/Documents/Work/Personal/fennec/doxy/style.
# documentation. # documentation.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET = /home/medusa/Documents/Work/Personal/fennec/doxy/doxygen-awesome.css \ HTML_EXTRA_STYLESHEET = C:/Users/msloc/Documents/Work/Personal/fennec/doxy/doxygen-awesome.css \
/home/medusa/Documents/Work/Personal/fennec/doxy/doxygen-awesome-sidebar-only.css \ C:/Users/msloc/Documents/Work/Personal/fennec/doxy/doxygen-awesome-sidebar-only.css \
/home/medusa/Documents/Work/Personal/fennec/doxy/doxygen-awesome-sidebar-only-darkmode-toggle.css \ C:/Users/msloc/Documents/Work/Personal/fennec/doxy/doxygen-awesome-sidebar-only-darkmode-toggle.css \
/home/medusa/Documents/Work/Personal/fennec/doxy/custom.css C:/Users/msloc/Documents/Work/Personal/fennec/doxy/custom.css
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note # other source files which should be copied to the HTML output directory. Note
@@ -1412,7 +1412,7 @@ HTML_EXTRA_STYLESHEET = /home/medusa/Documents/Work/Personal/fennec/doxy/doxyge
# files will be copied as-is; there are no commands or markers available. # files will be copied as-is; there are no commands or markers available.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_FILES = "/home/medusa/Documents/Work/Personal/fennec/doxy/doxygen-awesome-darkmode-toggle.js" HTML_EXTRA_FILES = "C:/Users/msloc/Documents/Work/Personal/fennec/doxy/doxygen-awesome-darkmode-toggle.js"
# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output # The HTML_COLORSTYLE tag can be used to specify if the generated HTML output
# should be rendered with a dark or light theme. # should be rendered with a dark or light theme.

View File

@@ -45,8 +45,6 @@ namespace fennec
/// \details /// \details
/// \tparam ValueT value type /// \tparam ValueT value type
/// \tparam ElemV number of elements /// \tparam ElemV number of elements
///
///
template<typename ValueT, size_t ElemV> template<typename ValueT, size_t ElemV>
struct array struct array
{ {

View File

@@ -19,6 +19,10 @@
#ifndef FENNEC_LANG_ASSERT_H #ifndef FENNEC_LANG_ASSERT_H
#define FENNEC_LANG_ASSERT_H #define FENNEC_LANG_ASSERT_H
#if _MSC_VER
#define __PRETTY_FUNCTION__ __FUNCSIG__
#endif
using assert_handler = void (*)(const char *, const char *, int , const char *); using assert_handler = void (*)(const char *, const char *, int , const char *);
extern void __assert_impl(const char* expression, const char* file, int line, const char* function); extern void __assert_impl(const char* expression, const char* file, int line, const char* function);

View File

@@ -19,9 +19,18 @@
#ifndef FENNEC_LANG_DETAIL_INT_H #ifndef FENNEC_LANG_DETAIL_INT_H
#define FENNEC_LANG_DETAIL_INT_H #define FENNEC_LANG_DETAIL_INT_H
#if _MSC_VER
#pragma warning(push)
#pragma warning(disable:4117)
#endif
#pragma push_macro("__cplusplus") #pragma push_macro("__cplusplus")
#undef __cplusplus #undef __cplusplus
#include <stdint.h> #include <stdint.h>
#pragma pop_macro("__cplusplus") #pragma pop_macro("__cplusplus")
#if _MSC_VER
#pragma warning(pop)
#endif
#endif // FENNEC_LANG_DETAIL_INT_H #endif // FENNEC_LANG_DETAIL_INT_H

View File

@@ -19,6 +19,11 @@
#ifndef FENNEC_LANG_DETAIL_STDLIB_H #ifndef FENNEC_LANG_DETAIL_STDLIB_H
#define FENNEC_LANG_DETAIL_STDLIB_H #define FENNEC_LANG_DETAIL_STDLIB_H
#if _MSC_VER
#pragma warning(push)
#pragma warning(disable:4117)
#endif
#pragma push_macro("__cplusplus") #pragma push_macro("__cplusplus")
#undef __cplusplus #undef __cplusplus
extern "C" { extern "C" {
@@ -26,4 +31,8 @@ extern "C" {
} }
#pragma pop_macro("__cplusplus") #pragma pop_macro("__cplusplus")
#if _MSC_VER
#pragma warning(pop)
#endif
#endif // FENNEC_LANG_DETAIL_STDLIB_H #endif // FENNEC_LANG_DETAIL_STDLIB_H

View File

@@ -32,6 +32,32 @@
#include <fennec/lang/bits.h> #include <fennec/lang/bits.h>
#undef FLT_HAS_INFINITY
#undef FLT_HAS_QUIET_NAN
#undef FLT_HAS_SIGNALING_NAN
#undef FLT_HAS_DENORM
#undef FLT_HAS_DENORM_LOSS
#undef FLT_ROUNDS
#undef FLT_IS_IEC559
#undef FLT_MANT_DIG
#undef FLT_DIG
#undef FLT_DECIMAL_DIG
#undef FLT_RADIX
#undef FLT_MIN_EXP
#undef FLT_MAX_EXP
#undef FLT_MIN_10_EXP
#undef FLT_MAX_10_EXP
#undef FLT_TRAPS
#undef FLT_TINYNESS_BEFORE
#undef FLT_MIN
#undef FLT_MAX
#undef FLT_EPSILON
#undef FLT_INF
#undef FLT_QUIET_NAN
#undef FLT_SIGNALING_NAN
#undef FLT_DENORM_MIN
#undef FLT_ROUND_ERR
#define FLT_HAS_INFINITY 1 #define FLT_HAS_INFINITY 1
#define FLT_HAS_QUIET_NAN 1 #define FLT_HAS_QUIET_NAN 1
#define FLT_HAS_SIGNALING_NAN 1 #define FLT_HAS_SIGNALING_NAN 1
@@ -54,10 +80,36 @@
#define FLT_EPSILON fennec::bit_cast<float>(0x34000000) #define FLT_EPSILON fennec::bit_cast<float>(0x34000000)
#define FLT_INF fennec::bit_cast<float>(0x7f800000) #define FLT_INF fennec::bit_cast<float>(0x7f800000)
#define FLT_QUIET_NAN fennec::bit_cast<float>(0x7fc00000) #define FLT_QUIET_NAN fennec::bit_cast<float>(0x7fc00000)
#define FLT_SIGNALING_NAN fennec::bit_cast<float>(0x7fa00000) #define FLT_SIGNALING_NAN fennec::bit_cast<float>(0x7fc00001)
#define FLT_DENORM_MIN fennec::bit_cast<float>(0x1) #define FLT_DENORM_MIN fennec::bit_cast<float>(0x1)
#define FLT_ROUND_ERR fennec::bit_cast<float>(0x3f000000) #define FLT_ROUND_ERR fennec::bit_cast<float>(0x3f000000)
#undef DBL_HAS_INFINITY
#undef DBL_HAS_QUIET_NAN
#undef DBL_HAS_SIGNALING_NAN
#undef DBL_HAS_DENORM
#undef DBL_HAS_DENORM_LOSS
#undef DBL_ROUNDS
#undef DBL_IS_IEC559
#undef DBL_MANT_DIG
#undef DBL_DIG
#undef DBL_DECIMAL_DIG
#undef DBL_RADIX
#undef DBL_MIN_EXP
#undef DBL_MAX_EXP
#undef DBL_MIN_10_EXP
#undef DBL_MAX_10_EXP
#undef DBL_TRAPS
#undef DBL_TINYNESS_BEFORE
#undef DBL_MIN
#undef DBL_MAX
#undef DBL_EPSILON
#undef DBL_INF
#undef DBL_QUIET_NAN
#undef DBL_SIGNALING_NAN
#undef DBL_DENORM_MIN
#undef DBL_ROUND_ERR
#define DBL_HAS_INFINITY 1 #define DBL_HAS_INFINITY 1
#define DBL_HAS_QUIET_NAN 1 #define DBL_HAS_QUIET_NAN 1
#define DBL_HAS_SIGNALING_NAN 1 #define DBL_HAS_SIGNALING_NAN 1
@@ -80,7 +132,7 @@
#define DBL_EPSILON fennec::bit_cast<double>(0x3cb0000000000000ll) #define DBL_EPSILON fennec::bit_cast<double>(0x3cb0000000000000ll)
#define DBL_INF fennec::bit_cast<double>(0x7ff0000000000000ll) #define DBL_INF fennec::bit_cast<double>(0x7ff0000000000000ll)
#define DBL_QUIET_NAN fennec::bit_cast<double>(0x7ff8000000000000ll) #define DBL_QUIET_NAN fennec::bit_cast<double>(0x7ff8000000000000ll)
#define DBL_SIGNALING_NAN fennec::bit_cast<double>(0x7ff4000000000000ll) #define DBL_SIGNALING_NAN fennec::bit_cast<double>(0x7ff0000000000001ll)
#define DBL_DENORM_MIN fennec::bit_cast<double>(0x1ll) #define DBL_DENORM_MIN fennec::bit_cast<double>(0x1ll)
#define DBL_ROUND_ERR fennec::bit_cast<double>(0x3fe0000000000000ll) #define DBL_ROUND_ERR fennec::bit_cast<double>(0x3fe0000000000000ll)

View File

@@ -57,27 +57,27 @@
#define CHAR_DIG 0x2 #define CHAR_DIG 0x2
#define CHAR_DECIMAL_DIG 0x0 #define CHAR_DECIMAL_DIG 0x0
#define CHAR_RADIX 0x2 #define CHAR_RADIX 0x2
#define CHAR_TRAPS 0xtrue #define CHAR_TRAPS 0xfalse
#define CHAR_MIN 0xffffff80 #define CHAR_MIN 0x80
#define CHAR_MAX 0x7f #define CHAR_MAX 0x7f
#define WCHAR_IS_SIGNED true #define WCHAR_IS_SIGNED false
#define WCHAR_ROUNDS 0x0 #define WCHAR_ROUNDS 0x0
#define WCHAR_RADIX_DIG 0x1f #define WCHAR_RADIX_DIG 0x10
#define WCHAR_DIG 0x9 #define WCHAR_DIG 0x4
#define WCHAR_DECIMAL_DIG 0x0 #define WCHAR_DECIMAL_DIG 0x0
#define WCHAR_RADIX 0x2 #define WCHAR_RADIX 0x2
#define WCHAR_TRAPS 0xtrue #define WCHAR_TRAPS 0xfalse
#define WCHAR_MIN 0x80000000 #define WCHAR_MIN 0x0
#define WCHAR_MAX 0x7fffffff #define WCHAR_MAX 0xffff
#define SCHAR_ROUNDS 0x0 #define SCHAR_ROUNDS 0x0
#define SCHAR_RADIX_DIG 0x7 #define SCHAR_RADIX_DIG 0x7
#define SCHAR_DIG 0x2 #define SCHAR_DIG 0x2
#define SCHAR_DECIMAL_DIG 0x0 #define SCHAR_DECIMAL_DIG 0x0
#define SCHAR_RADIX 0x2 #define SCHAR_RADIX 0x2
#define SCHAR_TRAPS 0xtrue #define SCHAR_TRAPS 0xfalse
#define SCHAR_MIN 0xffffff80 #define SCHAR_MIN 0x80
#define SCHAR_MAX 0x7f #define SCHAR_MAX 0x7f
#define UCHAR_ROUNDS 0x0 #define UCHAR_ROUNDS 0x0
@@ -85,7 +85,7 @@
#define UCHAR_DIG 0x2 #define UCHAR_DIG 0x2
#define UCHAR_DECIMAL_DIG 0x0 #define UCHAR_DECIMAL_DIG 0x0
#define UCHAR_RADIX 0x2 #define UCHAR_RADIX 0x2
#define UCHAR_TRAPS 0xtrue #define UCHAR_TRAPS 0xfalse
#define UCHAR_MIN 0x0 #define UCHAR_MIN 0x0
#define UCHAR_MAX 0xff #define UCHAR_MAX 0xff
@@ -94,7 +94,7 @@
#define SHORT_DIG 0x4 #define SHORT_DIG 0x4
#define SHORT_DECIMAL_DIG 0x0 #define SHORT_DECIMAL_DIG 0x0
#define SHORT_RADIX 0x2 #define SHORT_RADIX 0x2
#define SHORT_TRAPS 0xtrue #define SHORT_TRAPS 0xfalse
#define SHORT_MIN 0x8000 #define SHORT_MIN 0x8000
#define SHORT_MAX 0x7fff #define SHORT_MAX 0x7fff
@@ -103,7 +103,7 @@
#define USHORT_DIG 0x4 #define USHORT_DIG 0x4
#define USHORT_DECIMAL_DIG 0x0 #define USHORT_DECIMAL_DIG 0x0
#define USHORT_RADIX 0x2 #define USHORT_RADIX 0x2
#define USHORT_TRAPS 0xtrue #define USHORT_TRAPS 0xfalse
#define USHORT_MIN 0x0 #define USHORT_MIN 0x0
#define USHORT_MAX 0xffff #define USHORT_MAX 0xffff
@@ -112,7 +112,7 @@
#define INT_DIG 0x9 #define INT_DIG 0x9
#define INT_DECIMAL_DIG 0x0 #define INT_DECIMAL_DIG 0x0
#define INT_RADIX 0x2 #define INT_RADIX 0x2
#define INT_TRAPS 0xtrue #define INT_TRAPS 0xfalse
#define INT_MIN 0x80000000 #define INT_MIN 0x80000000
#define INT_MAX 0x7fffffff #define INT_MAX 0x7fffffff
@@ -121,34 +121,34 @@
#define UINT_DIG 0x9 #define UINT_DIG 0x9
#define UINT_DECIMAL_DIG 0x0 #define UINT_DECIMAL_DIG 0x0
#define UINT_RADIX 0x2 #define UINT_RADIX 0x2
#define UINT_TRAPS 0xtrue #define UINT_TRAPS 0xfalse
#define UINT_MIN 0x0 #define UINT_MIN 0x0
#define UINT_MAX 0xffffffff #define UINT_MAX 0xffffffff
#define LONG_ROUNDS 0x0 #define LONG_ROUNDS 0x0
#define LONG_RADIX_DIG 0x3f #define LONG_RADIX_DIG 0x1f
#define LONG_DIG 0x12 #define LONG_DIG 0x9
#define LONG_DECIMAL_DIG 0x0 #define LONG_DECIMAL_DIG 0x0
#define LONG_RADIX 0x2 #define LONG_RADIX 0x2
#define LONG_TRAPS 0xtrue #define LONG_TRAPS 0xfalse
#define LONG_MIN 0x8000000000000000 #define LONG_MIN 0x80000000
#define LONG_MAX 0x7fffffffffffffff #define LONG_MAX 0x7fffffff
#define ULONG_ROUNDS 0x0 #define ULONG_ROUNDS 0x0
#define ULONG_RADIX_DIG 0x40 #define ULONG_RADIX_DIG 0x20
#define ULONG_DIG 0x13 #define ULONG_DIG 0x9
#define ULONG_DECIMAL_DIG 0x0 #define ULONG_DECIMAL_DIG 0x0
#define ULONG_RADIX 0x2 #define ULONG_RADIX 0x2
#define ULONG_TRAPS 0xtrue #define ULONG_TRAPS 0xfalse
#define ULONG_MIN 0x0 #define ULONG_MIN 0x0
#define ULONG_MAX 0xffffffffffffffff #define ULONG_MAX 0xffffffff
#define LLONG_ROUNDS 0x0 #define LLONG_ROUNDS 0x0
#define LLONG_RADIX_DIG 0x3f #define LLONG_RADIX_DIG 0x3f
#define LLONG_DIG 0x12 #define LLONG_DIG 0x12
#define LLONG_DECIMAL_DIG 0x0 #define LLONG_DECIMAL_DIG 0x0
#define LLONG_RADIX 0x2 #define LLONG_RADIX 0x2
#define LLONG_TRAPS 0xtrue #define LLONG_TRAPS 0xfalse
#define LLONG_MIN 0x8000000000000000 #define LLONG_MIN 0x8000000000000000
#define LLONG_MAX 0x7fffffffffffffff #define LLONG_MAX 0x7fffffffffffffff
@@ -157,7 +157,7 @@
#define ULLONG_DIG 0x13 #define ULLONG_DIG 0x13
#define ULLONG_DECIMAL_DIG 0x0 #define ULLONG_DECIMAL_DIG 0x0
#define ULLONG_RADIX 0x2 #define ULLONG_RADIX 0x2
#define ULLONG_TRAPS 0xtrue #define ULLONG_TRAPS 0xfalse
#define ULLONG_MIN 0x0 #define ULLONG_MIN 0x0
#define ULLONG_MAX 0xffffffffffffffff #define ULLONG_MAX 0xffffffffffffffff

View File

@@ -99,18 +99,9 @@
/// ///
// Most major compilers support __has_builtin, notably GCC, MINGW, CLANG, and MSVC // Most major compilers support __has_builtin, notably GCC, MINGW, and CLANG
#if defined(__has_builtin) #if defined(__has_builtin)
// bitcast is slightly more efficient for build times than using memcpy
#if __has_builtin(__builtin_bit_cast)
# define FENNEC_HAS_BUILTIN_BIT_CAST 1
# define FENNEC_BUILTIN_BIT_CAST(type, arg) __builtin_bit_cast(type, arg)
#else
# define FENNEC_HAS_BUILTIN_BIT_CAST 0
#endif
// addressof is very difficult to implement without intrinsics. // addressof is very difficult to implement without intrinsics.
#if __has_builtin(__builtin_addressof) #if __has_builtin(__builtin_addressof)
# define FENNEC_HAS_BUILTIN_ADDRESSOF 1 # define FENNEC_HAS_BUILTIN_ADDRESSOF 1
@@ -119,9 +110,31 @@
# define FENNEC_HAS_BUILTIN_ADDRESSOF 0 # define FENNEC_HAS_BUILTIN_ADDRESSOF 0
#endif #endif
// bitcast is slightly more efficient for build times than using memcpy
#if __has_builtin(__builtin_bit_cast)
# define FENNEC_HAS_BUILTIN_BIT_CAST 1
# define FENNEC_BUILTIN_BIT_CAST(type, arg) __builtin_bit_cast(type, arg)
#else
# define FENNEC_HAS_BUILTIN_BIT_CAST 0
#endif
// Inconsistent without intrinsics
#if __has_builtin(__is_abstract)
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 1
# define FENNEC_BUILTIN_IS_ABSTRACT(arg) __is_abstract(arg)
#else
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 0
#endif
// Difficult and Inconsistent without intrinsics
#if __has_builtin(__is_constructible)
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 1
# define FENNEC_BUILTIN_IS_CONSTRUCTIBLE(type, ...) __is_constructible(type, __VA_ARGS__)
#else
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 0
#endif
// Type Traits // Type Traits
// can_convert is also very difficult to implement without intrinsics // can_convert is also very difficult to implement without intrinsics
#if __has_builtin(__is_convertible) #if __has_builtin(__is_convertible)
# define FENNEC_HAS_BUILTIN_IS_CONVERTIBLE 1 # define FENNEC_HAS_BUILTIN_IS_CONVERTIBLE 1
@@ -136,6 +149,14 @@
# define FENNEC_BUILTIN_IS_EMPTY(arg) __is_empty(arg) # define FENNEC_BUILTIN_IS_EMPTY(arg) __is_empty(arg)
#else #else
# define FENNEC_HAS_BUILTIN_IS_EMPTY 0 # define FENNEC_HAS_BUILTIN_IS_EMPTY 0
// Inconsistent without intrinsics
#if __has_builtin(__is_final)
# define FENNEC_HAS_BUILTIN_IS_FINAL 1
# define FENNEC_BUILTIN_IS_FINAL(arg) __is_final(arg)
#else
# define FENNEC_HAS_BUILTIN_IS_FINAL 0
#endif
#endif #endif
// Inconsistent without intrinsics // Inconsistent without intrinsics
@@ -146,22 +167,6 @@
# define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 0 # define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 0
#endif #endif
// Inconsistent without intrinsics
#if __has_builtin(__is_final)
# define FENNEC_HAS_BUILTIN_IS_FINAL 1
# define FENNEC_BUILTIN_IS_FINAL(arg) __is_final(arg)
#else
# define FENNEC_HAS_BUILTIN_IS_FINAL 0
#endif
// Inconsistent without intrinsics
#if __has_builtin(__is_abstract)
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 1
# define FENNEC_BUILTIN_IS_ABSTRACT(arg) __is_abstract(arg)
#else
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 0
#endif
// Impossible without instrinsics // Impossible without instrinsics
#if __has_builtin(__is_standard_layout) #if __has_builtin(__is_standard_layout)
# define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 1 # define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 1
@@ -170,20 +175,40 @@
# define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 0 # define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 0
#endif #endif
// Difficult and Inconsistent without intrinsics
#if __has_builtin(__is_constructible)
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 1
# define FENNEC_BUILTIN_IS_CONSTRUCTIBLE(type, ...) __is_constructible(type, __VA_ARGS__)
#else
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 0
#endif
// For compilers without or differently named builtins // For compilers without or differently named builtins
#else #else
// TODO: More compiler support // TODO: More compiler support
#if _MSC_VER
# define FENNEC_HAS_BUILTIN_ADDRESS_OF 1
# define FENNEC_BUILTIN_ADDRESS_OF(arg) __builtin_addressof(arg)
# define FENNEC_HAS_BUILTIN_BIT_CAST 1
# define FENNEC_BUILTIN_BIT_CAST(type, arg) __builtin_bit_cast(type, arg)
# define FENNEC_HAS_BUILTIN_IS_CONVERTIBLE 1
# define FENNEC_BUILTIN_IS_CONVERTIBLE(arg0, arg1) __is_convertible_to(arg0, arg1)
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 1
# define FENNEC_BUILTIN_IS_CONSTRUCTIBLE(...) __is_constructible(__VA_ARGS__)
# define FENNEC_HAS_BUILTIN_IS_EMPTY 1
# define FENNEC_BUILTIN_IS_EMPTY(arg) __is_empty(arg)
# define FENNEC_HAS_BUILTIN_IS_FINAL 1
# define FENNEC_BUILTIN_IS_FINAL(arg) __is_final(arg)
# define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 1
# define FENNEC_BUILTIN_IS_POLYMORPHIC(arg) __is_polymorphic(arg)
# define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 1
# define FENNEC_BUILTIN_IS_STANDARD_LAYOUT(arg) __is_standard_layout(arg)
#endif
#endif #endif
#endif // FENNEC_LANG_INTRINSICS_H #endif // FENNEC_LANG_INTRINSICS_H

View File

@@ -365,15 +365,15 @@ template<> struct numeric_limits<char>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return CHAR_MIN; } static constexpr char min() { return static_cast<char>(CHAR_MIN); }
static constexpr double max() { return CHAR_MAX; } static constexpr char max() { return CHAR_MAX; }
static constexpr double lowest() { return 1; } static constexpr char lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr char epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr char round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr char infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr char quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr char signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr char denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -403,15 +403,15 @@ template<> struct numeric_limits<signed char>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return SCHAR_MIN; } static constexpr signed char min() { return static_cast<signed char>(SCHAR_MIN); }
static constexpr double max() { return SCHAR_MAX; } static constexpr signed char max() { return SCHAR_MAX; }
static constexpr double lowest() { return 1; } static constexpr signed char lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr signed char epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr signed char round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr signed char infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr signed char quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr signed char signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr signed char denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -441,15 +441,15 @@ template<> struct numeric_limits<unsigned char>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return UCHAR_MIN; } static constexpr unsigned char min() { return UCHAR_MIN; }
static constexpr double max() { return UCHAR_MAX; } static constexpr unsigned char max() { return UCHAR_MAX; }
static constexpr double lowest() { return 1; } static constexpr unsigned char lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr unsigned char epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr unsigned char round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr unsigned char infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr unsigned char quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr unsigned char signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr unsigned char denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -479,15 +479,15 @@ template<> struct numeric_limits<short>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return SHORT_MIN; } static constexpr short min() { return static_cast<short>(SHORT_MIN); }
static constexpr double max() { return SHORT_MAX; } static constexpr short max() { return SHORT_MAX; }
static constexpr double lowest() { return 1; } static constexpr short lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr short epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr short round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr short infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr short quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr short signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr short denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -517,15 +517,15 @@ template<> struct numeric_limits<unsigned short>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return USHORT_MIN; } static constexpr unsigned short min() { return USHORT_MIN; }
static constexpr double max() { return USHORT_MAX; } static constexpr unsigned short max() { return USHORT_MAX; }
static constexpr double lowest() { return 1; } static constexpr unsigned short lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr unsigned short epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr unsigned short round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr unsigned short infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr unsigned short quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr unsigned short signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr unsigned short denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -555,15 +555,15 @@ template<> struct numeric_limits<int>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return INT_MIN; } static constexpr int min() { return INT_MIN; }
static constexpr double max() { return INT_MAX; } static constexpr int max() { return INT_MAX; }
static constexpr double lowest() { return 1; } static constexpr int lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr int epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr int round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr int infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr int quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr int signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr int denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -593,15 +593,15 @@ template<> struct numeric_limits<unsigned int>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return UINT_MIN; } static constexpr unsigned int min() { return UINT_MIN; }
static constexpr double max() { return UINT_MAX; } static constexpr unsigned int max() { return UINT_MAX; }
static constexpr double lowest() { return 1; } static constexpr unsigned int lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr unsigned int epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr unsigned int round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr unsigned int infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr unsigned int quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr unsigned int signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr unsigned int denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -631,15 +631,15 @@ template<> struct numeric_limits<long int>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return LONG_MIN; } static constexpr long int min() { return LONG_MIN; }
static constexpr double max() { return LONG_MAX; } static constexpr long int max() { return LONG_MAX; }
static constexpr double lowest() { return 1; } static constexpr long int lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr long int epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr long int round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr long int infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr long int quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr long int signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr long int denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -669,15 +669,15 @@ template<> struct numeric_limits<unsigned long int>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return ULONG_MIN; } static constexpr unsigned long min() { return ULONG_MIN; }
static constexpr double max() { return ULONG_MAX; } static constexpr unsigned long max() { return ULONG_MAX; }
static constexpr double lowest() { return 1; } static constexpr unsigned long lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr unsigned long epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr unsigned long round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr unsigned long infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr unsigned long quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr unsigned long signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr unsigned long denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -707,15 +707,15 @@ template<> struct numeric_limits<long long>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return LLONG_MIN; } static constexpr long long min() { return LLONG_MIN; }
static constexpr double max() { return LLONG_MAX; } static constexpr long long max() { return LLONG_MAX; }
static constexpr double lowest() { return 1; } static constexpr long long lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr long long epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr long long round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr long long infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr long long quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr long long signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr long long denorm_min() { return 0; }
}; };
// Overload for the builtin signed char type // Overload for the builtin signed char type
@@ -745,15 +745,15 @@ template<> struct numeric_limits<unsigned long long>
static constexpr int max_exponent = 0; static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0; static constexpr int max_exponent10 = 0;
static constexpr double min() { return ULLONG_MIN; } static constexpr unsigned long long min() { return ULLONG_MIN; }
static constexpr double max() { return ULLONG_MAX; } static constexpr unsigned long long max() { return ULLONG_MAX; }
static constexpr double lowest() { return 1; } static constexpr unsigned long long lowest() { return 1; }
static constexpr double epsilon() { return 1; } static constexpr unsigned long long epsilon() { return 1; }
static constexpr double round_error() { return 0; } static constexpr unsigned long long round_error() { return 0; }
static constexpr double infinity() { return 0; } static constexpr unsigned long long infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; } static constexpr unsigned long long quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; } static constexpr unsigned long long signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; } static constexpr unsigned long long denorm_min() { return 0; }
}; };
} }

View File

@@ -153,15 +153,15 @@
/// \copybrief fennec::int64_t /// \copybrief fennec::int64_t
/// ///
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> ///// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::float32_t "float32_t"</tt> ///// <tt>\ref fennec::float32_t "float32_t"</tt>
/// <td width="50%" style="vertical-align: top"> ///// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::float32_t ///// \copybrief fennec::float32_t
/// /////
/// <tr><td width="50%" style="vertical-align: top"> <br> ///// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::float64_t "float64_t"</tt> ///// <tt>\ref fennec::float64_t "float64_t"</tt>
/// <td width="50%" style="vertical-align: top"> ///// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::float64_t ///// \copybrief fennec::float64_t
/// ///
/// ///
/// <tr><th colspan=2 style="text-align: center;">Special Types /// <tr><th colspan=2 style="text-align: center;">Special Types
@@ -253,10 +253,10 @@ namespace fennec
using nullptr_t = decltype(nullptr); ///< \brief Null Pointer Type using nullptr_t = decltype(nullptr); ///< \brief Null Pointer Type
using intptr_t = intptr_t; ///< \brief Signed Integer Capable of Holding a Pointer to void using intptr_t = intptr_t; ///< \brief Signed Integer Capable of Holding a Pointer to void
using uintptr_t = uintptr_t; ///< \brief Unsigned Integer Capable of Holding a Pointer to void using uintptr_t = uintptr_t; ///< \brief Unsigned Integer Capable of Holding a Pointer to void
using intmax_t = __INTMAX_TYPE__; ///< \brief Maximum Width Signed Integer Type using intmax_t = intmax_t; ///< \brief Maximum Width Signed Integer Type
using uintmax_t = __UINTMAX_TYPE__; ///< \brief Maximum Width Unsigned Integer Type using uintmax_t = uintmax_t; ///< \brief Maximum Width Unsigned Integer Type
using size_t = __SIZE_TYPE__; ///< \brief Unsigned Integer Type Returned By `sizeof`, `sizeof...`, and `alignof` using size_t = size_t; ///< \brief Unsigned Integer Type Returned By `sizeof`, `sizeof...`, and `alignof`
using ptrdiff_t = __PTRDIFF_TYPE__; ///< \brief Signed Integer Type Returned by the Subtraction of two Pointers using ptrdiff_t = ptrdiff_t; ///< \brief Signed Integer Type Returned by the Subtraction of two Pointers
class undefined_t; ///< \brief undefined class for SFINAE class undefined_t; ///< \brief undefined class for SFINAE
template<typename...> using void_t = void; ///< \brief Void type used for SFINAE template<typename...> using void_t = void; ///< \brief Void type used for SFINAE
@@ -293,9 +293,9 @@ namespace fennec
/// \name Sized Floating-Point Types /// \name Sized Floating-Point Types
/// @{ /// @{
using float16_t = _Float16; ///< \brief A half-precision floating-point scalar //using float16_t = _Float16; ///< \brief A half-precision floating-point scalar
using float32_t = _Float32; ///< \brief A single-precision floating-point scalar //using float32_t = _Float32; ///< \brief A single-precision floating-point scalar
using float64_t = _Float64; ///< \brief A double-precision floating-point scalar //using float64_t = _Float64; ///< \brief A double-precision floating-point scalar
/// @} /// @}

View File

@@ -273,6 +273,11 @@
#include <fennec/math/vector.h> #include <fennec/math/vector.h>
#if _MSC_VER
#define isnanf(x) isnan(x)
#define isinff(x) isinf(x)
#endif
namespace fennec namespace fennec
{ {
@@ -408,31 +413,6 @@ constexpr vector<genType, i...> round(const vector<genType, i...>& x)
// Round Even ==========================================================================================================
///
/// \brief Returns a value equal to the nearest integer. In C++, a fractional part of \f$0.5\f$ will always
/// round to the nearest even integer.
///
/// \returns a value equal to the nearest integer.<br> <br>
/// \details In C++, a fractional part of \f$0.5\f$ will always round to the nearest even integer.<br> <br>
/// We can express this as,<br> <br>
/// \f$\text{roundEven}() = \begin{cases}\lfloor{x}\rfloor + \text{mod}(\lfloor{x}\rfloor, 2.0) & \text{fract}(x) = 0.5, \\ \text{round}(x) \end{cases}\f$<br> <br>
///
/// \param x input value
template<typename genType>
constexpr genType roundEven(genType x)
{ return ::roundeven(x); }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> roundEven(const vector<genType, i...>& x)
{ return vector<genType, i...>(fennec::roundEven(x[i]) ...); }
// Trunc =============================================================================================================== // Trunc ===============================================================================================================
/// ///
@@ -454,6 +434,40 @@ template<typename genType, size_t...i>
constexpr vector<genType, i...> trunc(const vector<genType, i...>& x) constexpr vector<genType, i...> trunc(const vector<genType, i...>& x)
{ return vector<genType, i...>(fennec::trunc(x[i]) ...); } { return vector<genType, i...>(fennec::trunc(x[i]) ...); }
// Round Even ==========================================================================================================
///
/// \brief Returns a value equal to the nearest integer. In C++, a fractional part of \f$0.5\f$ will always
/// round to the nearest even integer.
///
/// \returns a value equal to the nearest integer.<br> <br>
/// \details In C++, a fractional part of \f$0.5\f$ will always round to the nearest even integer.<br> <br>
/// We can express this as,<br> <br>
/// \f$\text{roundEven}() = \begin{cases}\lfloor{x}\rfloor + \text{mod}(\lfloor{x}\rfloor, 2.0) & \text{fract}(x) = 0.5, \\ \text{round}(x) \end{cases}\f$<br> <br>
///
/// \param x input value
template<typename genType>
constexpr genType roundEven(genType x)
{
const float e = numeric_limits<genType>::epsilon();
float f = x - fennec::floor(x);
if (fennec::abs(f - genType(0.5)) > e)
return fennec::round(x);
float i = fennec::floor(x);
float r = i / 2;
bool up = r - fennec::floor(r) > e;
return i + static_cast<genType>(up);
}
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> roundEven(const vector<genType, i...>& x)
{ return vector<genType, i...>(fennec::roundEven(x[i]) ...); }
/// @} /// @}
@@ -678,7 +692,7 @@ constexpr vector<genType, i...> uintBitsToFloat(const vector<genUType, i...>& x)
/// \param c the addend /// \param c the addend
template<typename genType> template<typename genType>
constexpr genType fma(genType a, genType b, genType c) constexpr genType fma(genType a, genType b, genType c)
{ return ::fma(a, b, c); } { return genType(::fma(a, b, c)); }
// Vector Specializations ---------------------------------------------------------------------------------------------- // Vector Specializations ----------------------------------------------------------------------------------------------
@@ -941,17 +955,17 @@ constexpr vector<genType, i...> smoothstep(const vector<genType, i...>& edge0, c
/// \param a Interpolant /// \param a Interpolant
template<typename genType> requires(is_floating_point_v<genType>) template<typename genType> requires(is_floating_point_v<genType>)
constexpr genType mix(genType x, genType y, genType a) constexpr genType mix(genType x, genType y, genType a)
{ return x * (1.0 - a) + y * a; } { return x * (genType(1.0) - a) + y * a; }
// Vector Specializations ---------------------------------------------------------------------------------------------- // Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i> requires(is_floating_point_v<genType>) template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, genType a) constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, genType a)
{ return x * (1.0 - a) + y * a; } { return x * (genType(1.0) - a) + y * a; }
template<typename genType, size_t...i> requires(is_floating_point_v<genType>) template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, const vector<genType, i...>& a) constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, const vector<genType, i...>& a)
{ return x * (1.0 - a) + y * a; } { return x * (genType(1.0) - a) + y * a; }
// Mix (Bool) ========================================================================================================== // Mix (Bool) ==========================================================================================================

View File

@@ -19,11 +19,20 @@
#ifndef FENNEC_MATH_DETAIL_MATH_H #ifndef FENNEC_MATH_DETAIL_MATH_H
#define FENNEC_MATH_DETAIL_MATH_H #define FENNEC_MATH_DETAIL_MATH_H
#if _MSC_VER
#pragma warning(push)
#pragma warning(disable:4117)
#endif
#pragma push_macro("__cplusplus") #pragma push_macro("__cplusplus")
#undef __cplusplus #undef __cplusplus
#include <math.h> #include <math.h>
#pragma pop_macro("__cplusplus") #pragma pop_macro("__cplusplus")
#if _MSC_VER
#pragma warning(pop)
#endif
#undef div #undef div
#undef acos #undef acos
#undef asin #undef asin

View File

@@ -114,7 +114,7 @@ constexpr matrix<scalar, rows, cols...> inverse(const matrix<scalar, rows, cols.
// Should check for 0 determinant // Should check for 0 determinant
scalar invdet = (s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0); scalar invdet = (s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0);
invdet = invdet ? 1.0 / invdet : 0; // this will get reduced to cmov, div still happens invdet = invdet ? scalar(1.0) / invdet : scalar(0); // this will get reduced to cmov, div still happens
matrix<scalar, rows, cols...> i( matrix<scalar, rows, cols...> i(
( m[1][1] * c5 - m[1][2] * c4 + m[1][3] * c3) * invdet ( m[1][1] * c5 - m[1][2] * c4 + m[1][3] * c3) * invdet

View File

@@ -529,6 +529,12 @@
/// ///
/// </table> /// </table>
/// ///
///
#if _MSC_VER
#pragma warning(push)
#pragma warning(disable:4305)
#endif
namespace fennec namespace fennec
{ {
@@ -682,4 +688,8 @@ template<typename genType> constexpr genType log_phi() { return
} }
#if _MSC_VER
#pragma warning(pop)
#endif
#endif // FENNEC_MATH_EXT_CONSTANTS_H #endif // FENNEC_MATH_EXT_CONSTANTS_H

View File

@@ -252,7 +252,7 @@ constexpr vector<genType, i...> faceforward(const vector<genType, i...>& N, cons
/// \param N the surface orientation /// \param N the surface orientation
template<typename genType, size_t...i> template<typename genType, size_t...i>
constexpr vector<genType, i...> reflect(const vector<genType, i...>& I, const vector<genType, i...>& N) constexpr vector<genType, i...> reflect(const vector<genType, i...>& I, const vector<genType, i...>& N)
{ return I - 2.0 * fennec::dot(N, I) * N; } { return I - genType(2.0) * fennec::dot(N, I) * N; }
// refract ------------------------------------------------------------------------------------------------------------- // refract -------------------------------------------------------------------------------------------------------------
@@ -272,7 +272,7 @@ template<typename genType, size_t...i>
constexpr vector<genType, i...> refract(const vector<genType, i...>& I, const vector<genType, i...>& N, genType eta) constexpr vector<genType, i...> refract(const vector<genType, i...>& I, const vector<genType, i...>& N, genType eta)
{ {
genType ndi = fennec::dot(N, I); genType ndi = fennec::dot(N, I);
genType k = 1.0 - eta * eta * (1.0 - ndi * ndi); genType k = genType(1.0) - eta * eta * (genType(1.0) - ndi * ndi);
if (k < 0) return vector<genType, i...>(0); if (k < 0) return vector<genType, i...>(0);
return eta * I - N * (eta * ndi + fennec::sqrt(k)); return eta * I - N * (eta * ndi + fennec::sqrt(k));
} }

View File

@@ -164,11 +164,11 @@ namespace fennec
/// \param degrees the angle \f$\theta\f$ in \f$degrees\f$ /// \param degrees the angle \f$\theta\f$ in \f$degrees\f$
template<typename genType> template<typename genType>
constexpr genType radians(genType degrees) constexpr genType radians(genType degrees)
{ return degrees * 0.01745329251994329576923690768489; } { return genType(degrees * 0.01745329251994329576923690768489); }
template<typename genType, size_t...i> template<typename genType, size_t...i>
constexpr vector<genType, i...> radians(const vector<genType, i...>& degrees) constexpr vector<genType, i...> radians(const vector<genType, i...>& degrees)
{ return degrees * 0.01745329251994329576923690768489; } { return genType(degrees * 0.01745329251994329576923690768489); }
/// ///
@@ -181,11 +181,11 @@ constexpr vector<genType, i...> radians(const vector<genType, i...>& degrees)
/// \param radians the angle \f$\theta\f$ in \f$radians\f$ /// \param radians the angle \f$\theta\f$ in \f$radians\f$
template<typename genType> template<typename genType>
constexpr genType degrees(genType radians) constexpr genType degrees(genType radians)
{ return radians * 57.29577951308232087679815481410517; } { return genType(radians * 57.29577951308232087679815481410517); }
template<typename genType, size_t...i> template<typename genType, size_t...i>
constexpr vector<genType, i...> degrees(const vector<genType, i...>& radians) constexpr vector<genType, i...> degrees(const vector<genType, i...>& radians)
{ return radians * 57.29577951308232087679815481410517; } { return genType(radians * 57.29577951308232087679815481410517); }
/// @} /// @}

View File

@@ -20,8 +20,15 @@
#ifndef FENNEC_MATH_VECTOR_STORAGE_H #ifndef FENNEC_MATH_VECTOR_STORAGE_H
#define FENNEC_MATH_VECTOR_STORAGE_H #define FENNEC_MATH_VECTOR_STORAGE_H
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic" #pragma GCC diagnostic ignored "-Wpedantic"
#endif
#if _MSC_VER
#pragma warning(push)
#pragma warning(disable:4201)
#endif
namespace fennec namespace fennec
{ {
@@ -604,6 +611,12 @@ struct vector_storage<4, SwizzleGenT, DataT>
} }
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
#if _MSC_VER
#pragma warning(pop)
#endif
#endif // FENNEC_MATH_VECTOR_STORAGE_H #endif // FENNEC_MATH_VECTOR_STORAGE_H

View File

@@ -93,6 +93,9 @@ template<typename T> constexpr size_t component_count_v = component_count<T>::va
/// \tparam Ts types to accumulate the count of /// \tparam Ts types to accumulate the count of
template<typename...Ts> struct total_component_count : integral_constant<size_t, (component_count_v<Ts> + ...)>{}; template<typename...Ts> struct total_component_count : integral_constant<size_t, (component_count_v<Ts> + ...)>{};
// Override for empty list
template<> struct total_component_count<> : integral_constant<size_t, 0>{};
/// ///
/// \brief shorthand for ```component_count<T>::value``` /// \brief shorthand for ```component_count<T>::value```
/// \tparam Ts types to accumulate the count of /// \tparam Ts types to accumulate the count of

View File

@@ -19,6 +19,7 @@
#ifndef FENNEC_METAPROGRAMMING_FLOAT_H #ifndef FENNEC_METAPROGRAMMING_FLOAT_H
#define FENNEC_METAPROGRAMMING_FLOAT_H #define FENNEC_METAPROGRAMMING_FLOAT_H
#include <bit>
#include <iosfwd> #include <iosfwd>
inline void float_h() inline void float_h()
@@ -67,7 +68,35 @@ inline void float_h()
out << "" << std::endl; out << "" << std::endl;
// TODO: Fix this to generate info without using the c++stdlib for platforms without this available. // MAYBE TODO: Generate info without C++ STDLIB to compile natively on platforms without support
out << "#undef FLT_HAS_INFINITY" << std::endl;
out << "#undef FLT_HAS_QUIET_NAN" << std::endl;
out << "#undef FLT_HAS_SIGNALING_NAN" << std::endl;
out << "#undef FLT_HAS_DENORM" << std::endl;
out << "#undef FLT_HAS_DENORM_LOSS" << std::endl;
out << "#undef FLT_ROUNDS" << std::endl;
out << "#undef FLT_IS_IEC559" << std::endl;
out << "#undef FLT_MANT_DIG" << std::endl;
out << "#undef FLT_DIG" << std::endl;
out << "#undef FLT_DECIMAL_DIG" << std::endl;
out << "#undef FLT_RADIX" << std::endl;
out << "#undef FLT_MIN_EXP" << std::endl;
out << "#undef FLT_MAX_EXP" << std::endl;
out << "#undef FLT_MIN_10_EXP" << std::endl;
out << "#undef FLT_MAX_10_EXP" << std::endl;
out << "#undef FLT_TRAPS" << std::endl;
out << "#undef FLT_TINYNESS_BEFORE" << std::endl;
out << "#undef FLT_MIN" << std::endl;
out << "#undef FLT_MAX" << std::endl;
out << "#undef FLT_EPSILON" << std::endl;
out << "#undef FLT_INF" << std::endl;
out << "#undef FLT_QUIET_NAN" << std::endl;
out << "#undef FLT_SIGNALING_NAN" << std::endl;
out << "#undef FLT_DENORM_MIN" << std::endl;
out << "#undef FLT_ROUND_ERR" << std::endl;
out << "" << std::endl;
out << "#define FLT_HAS_INFINITY " << std::dec << std::numeric_limits<float>::has_infinity << std::endl; out << "#define FLT_HAS_INFINITY " << std::dec << std::numeric_limits<float>::has_infinity << std::endl;
out << "#define FLT_HAS_QUIET_NAN " << std::dec << std::numeric_limits<float>::has_quiet_NaN << std::endl; out << "#define FLT_HAS_QUIET_NAN " << std::dec << std::numeric_limits<float>::has_quiet_NaN << std::endl;
@@ -98,6 +127,34 @@ inline void float_h()
out << "" << std::endl; out << "" << std::endl;
out << "#undef DBL_HAS_INFINITY" << std::endl;
out << "#undef DBL_HAS_QUIET_NAN" << std::endl;
out << "#undef DBL_HAS_SIGNALING_NAN" << std::endl;
out << "#undef DBL_HAS_DENORM" << std::endl;
out << "#undef DBL_HAS_DENORM_LOSS" << std::endl;
out << "#undef DBL_ROUNDS" << std::endl;
out << "#undef DBL_IS_IEC559" << std::endl;
out << "#undef DBL_MANT_DIG" << std::endl;
out << "#undef DBL_DIG" << std::endl;
out << "#undef DBL_DECIMAL_DIG" << std::endl;
out << "#undef DBL_RADIX" << std::endl;
out << "#undef DBL_MIN_EXP" << std::endl;
out << "#undef DBL_MAX_EXP" << std::endl;
out << "#undef DBL_MIN_10_EXP" << std::endl;
out << "#undef DBL_MAX_10_EXP" << std::endl;
out << "#undef DBL_TRAPS" << std::endl;
out << "#undef DBL_TINYNESS_BEFORE" << std::endl;
out << "#undef DBL_MIN" << std::endl;
out << "#undef DBL_MAX" << std::endl;
out << "#undef DBL_EPSILON" << std::endl;
out << "#undef DBL_INF" << std::endl;
out << "#undef DBL_QUIET_NAN" << std::endl;
out << "#undef DBL_SIGNALING_NAN" << std::endl;
out << "#undef DBL_DENORM_MIN" << std::endl;
out << "#undef DBL_ROUND_ERR" << std::endl;
out << "" << std::endl;
out << "#define DBL_HAS_INFINITY " << std::dec << std::numeric_limits<double>::has_infinity << std::endl; out << "#define DBL_HAS_INFINITY " << std::dec << std::numeric_limits<double>::has_infinity << std::endl;
out << "#define DBL_HAS_QUIET_NAN " << std::dec << std::numeric_limits<double>::has_quiet_NaN << std::endl; out << "#define DBL_HAS_QUIET_NAN " << std::dec << std::numeric_limits<double>::has_quiet_NaN << std::endl;
out << "#define DBL_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits<double>::has_signaling_NaN << std::endl; out << "#define DBL_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits<double>::has_signaling_NaN << std::endl;

View File

@@ -90,54 +90,30 @@ inline void integer_h()
// TODO: Fix this to generate info without using the c++stdlib for platforms without this available. // TODO: Fix this to generate info without using the c++stdlib for platforms without this available.
out << "#define CHAR_IS_SIGNED " << std::boolalpha << std::numeric_limits<char>::is_signed << std::endl; out << "#define CHAR_IS_SIGNED " << std::boolalpha << std::numeric_limits<char>::is_signed << std::endl;
if(std::numeric_limits<char>::is_signed) {
out << "#define CHAR_ROUNDS " << "0x" << std::hex << (int)std::numeric_limits<char>::round_style << std::endl;
out << "#define CHAR_RADIX_DIG " << "0x" << std::hex << (int)std::numeric_limits<char>::digits << std::endl;
out << "#define CHAR_DIG " << "0x" << std::hex << (int)std::numeric_limits<char>::digits10 << std::endl;
out << "#define CHAR_DECIMAL_DIG " << "0x" << std::hex << (int)std::numeric_limits<char>::max_digits10 << std::endl;
out << "#define CHAR_RADIX " << "0x" << std::hex << (int)std::numeric_limits<char>::radix << std::endl;
out << "#define CHAR_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<char>::traps << std::endl;
out << "#define CHAR_MIN " << "0x" << std::hex << (int)std::numeric_limits<char>::min() << std::endl; out << "#define CHAR_ROUNDS " << "0x" << std::hex << (int)std::numeric_limits<char>::round_style << std::endl;
out << "#define CHAR_MAX " << "0x" << std::hex << (int)std::numeric_limits<char>::max() << std::endl; out << "#define CHAR_RADIX_DIG " << "0x" << std::hex << (int)std::numeric_limits<char>::digits << std::endl;
} out << "#define CHAR_DIG " << "0x" << std::hex << (int)std::numeric_limits<char>::digits10 << std::endl;
else { out << "#define CHAR_DECIMAL_DIG " << "0x" << std::hex << (int)std::numeric_limits<char>::max_digits10 << std::endl;
out << "#define CHAR_ROUNDS " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::round_style << std::endl; out << "#define CHAR_RADIX " << "0x" << std::hex << (int)std::numeric_limits<char>::radix << std::endl;
out << "#define CHAR_RADIX_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::digits << std::endl; out << "#define CHAR_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<char>::traps << std::endl;
out << "#define CHAR_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::digits10 << std::endl;
out << "#define CHAR_DECIMAL_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::max_digits10 << std::endl;
out << "#define CHAR_RADIX " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::radix << std::endl;
out << "#define CHAR_TRAPS " << "0x" << std::boolalpha << (unsigned int)std::numeric_limits<char>::traps << std::endl;
out << "#define CHAR_MIN " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::min() << std::endl; out << "#define CHAR_MIN " << "0x" << std::hex << (0xFF & +std::numeric_limits<char>::min()) << std::endl;
out << "#define CHAR_MAX " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::max() << std::endl; out << "#define CHAR_MAX " << "0x" << std::hex << (0xFF & +std::numeric_limits<char>::max()) << std::endl;
}
out << "" << std::endl; out << "" << std::endl;
out << "#define WCHAR_IS_SIGNED " << std::boolalpha << std::numeric_limits<wchar_t>::is_signed << std::endl; out << "#define WCHAR_IS_SIGNED " << std::boolalpha << std::numeric_limits<wchar_t>::is_signed << std::endl;
if(std::numeric_limits<wchar_t>::is_signed) {
out << "#define WCHAR_ROUNDS " << "0x" << std::hex << (int)std::numeric_limits<wchar_t>::round_style << std::endl;
out << "#define WCHAR_RADIX_DIG " << "0x" << std::hex << (int)std::numeric_limits<wchar_t>::digits << std::endl;
out << "#define WCHAR_DIG " << "0x" << std::hex << (int)std::numeric_limits<wchar_t>::digits10 << std::endl;
out << "#define WCHAR_DECIMAL_DIG " << "0x" << std::hex << (int)std::numeric_limits<wchar_t>::max_digits10 << std::endl;
out << "#define WCHAR_RADIX " << "0x" << std::hex << (int)std::numeric_limits<wchar_t>::radix << std::endl;
out << "#define WCHAR_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<wchar_t>::traps << std::endl;
out << "#define WCHAR_MIN " << "0x" << std::hex << (int)std::numeric_limits<wchar_t>::min() << std::endl; out << "#define WCHAR_ROUNDS " << "0x" << std::hex << std::numeric_limits<wchar_t>::round_style << std::endl;
out << "#define WCHAR_MAX " << "0x" << std::hex << (int)std::numeric_limits<wchar_t>::max() << std::endl; out << "#define WCHAR_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<wchar_t>::digits << std::endl;
} out << "#define WCHAR_DIG " << "0x" << std::hex << std::numeric_limits<wchar_t>::digits10 << std::endl;
else { out << "#define WCHAR_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<wchar_t>::max_digits10 << std::endl;
out << "#define WCHAR_ROUNDS " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::round_style << std::endl; out << "#define WCHAR_RADIX " << "0x" << std::hex << std::numeric_limits<wchar_t>::radix << std::endl;
out << "#define WCHAR_RADIX_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::digits << std::endl; out << "#define WCHAR_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<wchar_t>::traps << std::endl;
out << "#define WCHAR_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::digits10 << std::endl;
out << "#define WCHAR_DECIMAL_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::max_digits10 << std::endl;
out << "#define WCHAR_RADIX " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::radix << std::endl;
out << "#define WCHAR_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<wchar_t>::traps << std::endl;
out << "#define WCHAR_MIN " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::min() << std::endl; out << "#define WCHAR_MIN " << "0x" << std::hex << +std::numeric_limits<wchar_t>::min() << std::endl;
out << "#define WCHAR_MAX " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::max() << std::endl; out << "#define WCHAR_MAX " << "0x" << std::hex << +std::numeric_limits<wchar_t>::max() << std::endl;
}
out << "" << std::endl; out << "" << std::endl;
@@ -148,20 +124,20 @@ inline void integer_h()
out << "#define SCHAR_RADIX " << "0x" << std::hex << (int)std::numeric_limits<signed char>::radix << std::endl; out << "#define SCHAR_RADIX " << "0x" << std::hex << (int)std::numeric_limits<signed char>::radix << std::endl;
out << "#define SCHAR_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<signed char>::traps << std::endl; out << "#define SCHAR_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<signed char>::traps << std::endl;
out << "#define SCHAR_MIN " << "0x" << std::hex << (int)std::numeric_limits<signed char>::min() << std::endl; out << "#define SCHAR_MIN " << "0x" << std::hex << (0xFF & +std::numeric_limits<signed char>::min()) << std::endl;
out << "#define SCHAR_MAX " << "0x" << std::hex << (int)std::numeric_limits<signed char>::max() << std::endl; out << "#define SCHAR_MAX " << "0x" << std::hex << (0xFF & +std::numeric_limits<signed char>::max()) << std::endl;
out << "" << std::endl; out << "" << std::endl;
out << "#define UCHAR_ROUNDS " << "0x" << std::hex << (unsigned int)std::numeric_limits<unsigned char>::round_style << std::endl; out << "#define UCHAR_ROUNDS " << "0x" << std::hex << std::numeric_limits<unsigned char>::round_style << std::endl;
out << "#define UCHAR_RADIX_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<unsigned char>::digits << std::endl; out << "#define UCHAR_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<unsigned char>::digits << std::endl;
out << "#define UCHAR_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<unsigned char>::digits10 << std::endl; out << "#define UCHAR_DIG " << "0x" << std::hex << std::numeric_limits<unsigned char>::digits10 << std::endl;
out << "#define UCHAR_DECIMAL_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<unsigned char>::max_digits10 << std::endl; out << "#define UCHAR_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<unsigned char>::max_digits10 << std::endl;
out << "#define UCHAR_RADIX " << "0x" << std::hex << (unsigned int)std::numeric_limits<unsigned char>::radix << std::endl; out << "#define UCHAR_RADIX " << "0x" << std::hex << std::numeric_limits<unsigned char>::radix << std::endl;
out << "#define UCHAR_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<unsigned char>::traps << std::endl; out << "#define UCHAR_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<unsigned char>::traps << std::endl;
out << "#define UCHAR_MIN " << "0x" << std::hex << (unsigned int)std::numeric_limits<unsigned char>::min() << std::endl; out << "#define UCHAR_MIN " << "0x" << std::hex << (0xFF & +std::numeric_limits<unsigned char>::min()) << std::endl;
out << "#define UCHAR_MAX " << "0x" << std::hex << (unsigned int)std::numeric_limits<unsigned char>::max() << std::endl; out << "#define UCHAR_MAX " << "0x" << std::hex << (0xFF & +std::numeric_limits<unsigned char>::max()) << std::endl;
out << "" << std::endl; out << "" << std::endl;

View File

@@ -72,13 +72,17 @@ inline void __fennec_test_run(const std::string& expression, const ResultT resul
if constexpr(is_arithmetic_v<ResultT>) if constexpr(is_arithmetic_v<ResultT>)
{ {
passed = result == expected; passed = result == expected;
passed |= fennec::abs(expected - result) <= numeric_limits<ResultT>::epsilon();
if constexpr(not is_bool_v<ResultT>)
passed |= fennec::abs(expected - result) <= numeric_limits<ResultT>::epsilon();
} }
// Check non-boolean vector values // Check non-boolean vector values
else if constexpr(is_vector_v<ResultT> && not(is_bool_v<typename ResultT::scalar_t>)) else if constexpr(is_vector_v<ResultT>)
{ {
passed = result == expected; passed = result == expected;
passed |= fennec::all(fennec::lessThanEqual(fennec::abs(expected - result), ResultT(numeric_limits<typename ResultT::scalar_t>::epsilon())));
if constexpr(not is_bool_v<typename ResultT::scalar_t>)
passed |= fennec::all(fennec::lessThanEqual(fennec::abs(expected - result), ResultT(numeric_limits<typename ResultT::scalar_t>::epsilon())));
} }
// Base Case, simple comparison // Base Case, simple comparison
else else