- Added More Documentation

This commit is contained in:
Medusa Slockbower 2025-06-17 19:45:33 -04:00
parent 079b0b27ee
commit 9d35daa494
28 changed files with 1852 additions and 190 deletions

View File

@ -88,6 +88,7 @@ add_library(fennec STATIC
include/fennec/math/detail/__vector_traits.h include/fennec/math/detail/__vector_traits.h
include/fennec/lang/lang.h include/fennec/lang/lang.h
include/fennec/lang/detail/__bits.h include/fennec/lang/detail/__bits.h
include/fennec/lang/integer.h
) )
# add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled # add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled

View File

@ -32,7 +32,7 @@ This file serves as a general planning document for engine structure, systems, p
Implementations of core engine systems should strive to be `O(1)` in implementations, Implementations of core engine systems should strive to be `O(1)` in implementations,
both in terms of runtime and memory performance. This is obviously not a realistic goal, both in terms of runtime and memory performance. This is obviously not a realistic goal,
so rather than the entire engine striving to be `O(1)` we should more specifically look so rather than the goal requiring the entire engine to be `O(1)`, we should more specifically look
at achieving `O(1)` performance on hot paths. at achieving `O(1)` performance on hot paths.
Functions should be highly verbose, and in debug mode any bugprone or erroneous behaviour should throw Functions should be highly verbose, and in debug mode any bugprone or erroneous behaviour should throw
@ -98,7 +98,7 @@ All containers of the [C++ Standard Library](https://cppreference.com/w/cpp/cont
Here are essential data-structures not specified in the C++ stdlib: Here are essential data-structures not specified in the C++ stdlib:
- Graph → AI `graph` - Graph → AI `graph`
- Necessary for 2D and 3D navigation. - Necessary for 2D and 3D navigation.
- Rooted Directed Tree `rd_tree` - Rooted Directed Tree → Scene `rd_tree`
- Defines the scene structure. - Defines the scene structure.
@ -165,6 +165,8 @@ fennec should be able to use Doxygen and LaTeX externally. Consider including bi
This will be the core of the engine. This will be the core of the engine.
- Event System - Event System
- Most events will fire at the start of the next tick, especially those related to physics and input.
- Events for graphics or audio should propagate immediately.
- Core Engine Loop - Core Engine Loop
- System Manager - System Manager
- Ticks vs. Frames - Ticks vs. Frames
@ -172,9 +174,6 @@ This will be the core of the engine.
The following systems are not essential to the core engine, but are instead major systems that should be defined The following systems are not essential to the core engine, but are instead major systems that should be defined
in their operation order: in their operation order:
**3D Systems will apply *before* their 2D Variants**
### Tick ### Tick
- **Update** - **Update**
- Events - Events
@ -187,10 +186,10 @@ in their operation order:
- Apply Velocities (Updates Position and Rotation) - Apply Velocities (Updates Position and Rotation)
- Constraint Resolution - Constraint Resolution
- Collision Detection - Collision Detection
- Collision Resolution (Adjust for Clipping) - Collision Resolution
- Soft Bodies resolve before Rigid Bodies
- Collision Response - Collision Response
- Calculate Forces - Calculate Forces & Velocities
- Queue events for next tick
### Frame ### Frame

266
doxy/DoxyLayout.xml Normal file
View File

@ -0,0 +1,266 @@
<?xml version="1.0" encoding="UTF-8"?>
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.9.8 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type=""
<tab type="topics" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro="">
<tab type="modulelist" visible="yes" title="" intro=""/>
<tab type="modulemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="concepts" visible="yes" title="">
</tab>
<tab type="interfaces" visible="yes" title="">
<tab type="interfacelist" visible="yes" title="" intro=""/>
<tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="interfacehierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="structs" visible="yes" title="">
<tab type="structlist" visible="yes" title="" intro=""/>
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
</tab>
<tab type="exceptions" visible="yes" title="">
<tab type="exceptionlist" visible="yes" title="" intro=""/>
<tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="yes"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<concepts visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a concept page -->
<concept>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<definition visible="yes" title=""/>
<detaileddescription title=""/>
<authorsection visible="yes"/>
</concept>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="yes"/>
<includedbygraph visible="yes"/>
<sourcelink visible="yes"/>
<memberdecl>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="yes"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<modules visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a C++20 module page -->
<module>
<briefdescription visible="yes"/>
<exportedmodules visible="yes"/>
<memberdecl>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<enums title=""/>
<typedefs title=""/>
<functions title=""/>
<variables title=""/>
<membergroups title=""/>
</memberdecl>
<detaileddescription title=""/>
<memberdecl>
<files visible="yes"/>
</memberdecl>
</module>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

View File

@ -34,9 +34,11 @@
/// ///
/// \page fennec_lang_bit_manipulation Bit Manipulation /// \page fennec_lang_bit_manipulation Bit Manipulation
/// ///
/// \code #include <fennec/lang/bits.h> \endcode
///
/// This header contains definitions for manipulating the bits of a provided object or pointer. /// This header contains definitions for manipulating the bits of a provided object or pointer.
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_common_sign_functions"> /// <table width="100%" class="fieldtable" id="table_fennec_lang_bits">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// ///

View File

@ -35,21 +35,32 @@
/// ///
/// \page fennec_lang_conditional_types Conditional Types /// \page fennec_lang_conditional_types Conditional Types
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_common_sign_functions"> /// \code #include <fennec/lang/conditional_types.h> \endcode
///
/// This header contains various compile-time functions for conditionally setting types, detecting types, or
/// conditionally enabling functions. <br><br>
///
/// <table width="100%" class="fieldtable" id="table_fennec_lang_conditional_types">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::conditional "conditional<bool_t B, TrueT, FalseT>::type"<br> /// \ref fennec::conditional "typename conditional<bool_t B, TrueT, FalseT>::type"<br>
/// \ref fennec::conditional_t "conditional_t<bool_t B, TrueT, FalseT>" /// \ref fennec::conditional_t "conditional_t<bool_t B, TrueT, FalseT>"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::conditional /// \copydetails fennec::conditional
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::detect "detect<DefaultT, DetectT<...>, ArgsT...>::type"<br> /// \ref fennec::detect "typename detect<DefaultT, DetectT<...>, ArgsT...>::type"<br>
/// \ref fennec::detect_t "detect_t<DefaultT, DetectT<...>, ArgsT...>" /// \ref fennec::detect_t "detect_t<DefaultT, DetectT<...>, ArgsT...>"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::detect /// \copydetails fennec::detect
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::enable_if "typename enable_if<bool_t B, TypeT>::type"<br>
/// \ref fennec::enable_if_t "enable_if_t<bool_t B, TypeT>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::enable_if
/// </table> /// </table>
/// ///
/// ///
@ -126,9 +137,35 @@ struct detect<DefaultT, DetectT, ArgsT...>
using type = DetectT<ArgsT...>; using type = DetectT<ArgsT...>;
static constexpr bool is_detected = true; static constexpr bool is_detected = true;
};
// fennec::enable_if =================================================================================================== // fennec::enable_if ===================================================================================================
};
///
/// \brief Leverage SFINAE to conditionally enable a function or class at compile-time
///
/// \details If `B` is `true`, define a public member type `type`. Otherwise, there is no member. <br>
/// **Example Usage**
/// \code{.cpp}
/// template<typename TypeT,
/// enable_if_t<is_integral_v<TypeT>, bool> = true>
/// TypeT conditional_func() { return 0; }
/// \endcode
///
/// \tparam B A boolean value
/// \tparam T The type to conditionally define
template<bool_t B, typename T = void>
struct enable_if {};
///
/// \brief Shorthand for ```typename enable_if<B, T>::type```
template<bool_t B, typename T = void>
using enable_if_t = typename enable_if<B, T>::type;
// true case
template<typename T>
struct enable_if<true, T> { using type = T; };
} }

View File

@ -31,6 +31,37 @@
#ifndef FENNEC_LANG_CONSTANTS_H #ifndef FENNEC_LANG_CONSTANTS_H
#define FENNEC_LANG_CONSTANTS_H #define FENNEC_LANG_CONSTANTS_H
///
///
/// \page fennec_lang_constants Constants
///
/// \brief This header is part of the metaprogramming library. It defines structures for constant values,
/// used during compile time.
///
/// \code #include <fennec/lang/constants.h> \endcode
///
/// <table width="100%" class="fieldtable" id="table_fennec_lang_constants">
/// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::integral_constant "integral_constant<IntT, IntT ValueV>::type"<br>
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::integral_constant
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::bool_constant "bool_constant<bool_t ValueV>::type"<br>
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::bool_constant
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::bool_constant "bool_constant<bool_t ValueV>::type"<br>
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::bool_constant
///
/// </table>
///
#include <fennec/lang/types.h> #include <fennec/lang/types.h>
namespace fennec namespace fennec
@ -39,19 +70,19 @@ namespace fennec
/// ///
/// \brief metaprogramming integral constant /// \brief metaprogramming integral constant
/// ///
/// \details /// \details A metaprogramming integral constant
/// \tparam T type of the constant /// \tparam IntT type of the constant
/// \tparam V value of the constant /// \tparam ValueV value of the constant
template<typename T, T V> struct integral_constant template<typename IntT, IntT ValueV> struct integral_constant
{ {
/// ///
/// \brief value of the constant /// \brief value of the constant
inline static constexpr T value = V; inline static constexpr IntT value = ValueV;
/// ///
/// \brief cast operator to allow for braced initialization /// \brief cast operator to allow for braced initialization
/// \returns the value of the constant /// \returns the value of the constant
constexpr operator T() const noexcept { return V; } constexpr operator IntT() const noexcept { return value; }
}; };
@ -59,10 +90,10 @@ template<typename T, T V> struct integral_constant
/// \brief metaprogramming boolean constant /// \brief metaprogramming boolean constant
/// ///
/// \details /// \details
/// \tparam V value of the constant /// \tparam ValueV value of the constant
template<bool_t V> template<bool_t ValueV>
struct bool_constant struct bool_constant
: integral_constant<bool_t, V> {}; : integral_constant<bool_t, ValueV> {};
/// ///

View File

@ -0,0 +1,146 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file integer.h
/// \brief metaprogramming integer type info
///
///
/// \details this file is automatically generated for the current build environment
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_LANG_INTEGER_H
#define FENNEC_LANG_INTEGER_H
#undef WCHAR_MIN
#undef WCHAR_MAX
#define CHAR_IS_SIGNED true
#define CHAR_ROUNDS 0x0
#define CHAR_RADIX_DIG 0x7
#define CHAR_DIG 0x2
#define CHAR_DECIMAL_DIG 0x0
#define CHAR_RADIX 0x2
#define CHAR_TRAPS 0xtrue
#define CHAR_MIN 0xffffff80
#define CHAR_MAX 0x7f
#define WCHAR_IS_SIGNED true
#define WCHAR_ROUNDS 0x0
#define WCHAR_RADIX_DIG 0x1f
#define WCHAR_DIG 0x9
#define WCHAR_DECIMAL_DIG 0x0
#define WCHAR_RADIX 0x2
#define WCHAR_TRAPS 0xtrue
#define WCHAR_MIN 0x80000000
#define WCHAR_MAX 0x7fffffff
#define SCHAR_ROUNDS 0x0
#define SCHAR_RADIX_DIG 0x7
#define SCHAR_DIG 0x2
#define SCHAR_DECIMAL_DIG 0x0
#define SCHAR_RADIX 0x2
#define SCHAR_TRAPS 0xtrue
#define SCHAR_MIN 0xffffff80
#define SCHAR_MAX 0x7f
#define UCHAR_ROUNDS 0x0
#define UCHAR_RADIX_DIG 0x8
#define UCHAR_DIG 0x2
#define UCHAR_DECIMAL_DIG 0x0
#define UCHAR_RADIX 0x2
#define UCHAR_TRAPS 0xtrue
#define UCHAR_MIN 0x0
#define UCHAR_MAX 0xff
#define SHORT_ROUNDS 0x0
#define SHORT_RADIX_DIG 0xf
#define SHORT_DIG 0x4
#define SHORT_DECIMAL_DIG 0x0
#define SHORT_RADIX 0x2
#define SHORT_TRAPS 0xtrue
#define SHORT_MIN 0x8000
#define SHORT_MAX 0x7fff
#define USHORT_ROUNDS 0x0
#define USHORT_RADIX_DIG 0x10
#define USHORT_DIG 0x4
#define USHORT_DECIMAL_DIG 0x0
#define USHORT_RADIX 0x2
#define USHORT_TRAPS 0xtrue
#define USHORT_MIN 0x0
#define USHORT_MAX 0xffff
#define INT_ROUNDS 0x0
#define INT_RADIX_DIG 0x1f
#define INT_DIG 0x9
#define INT_DECIMAL_DIG 0x0
#define INT_RADIX 0x2
#define INT_TRAPS 0xtrue
#define INT_MIN 0x80000000
#define INT_MAX 0x7fffffff
#define UINT_ROUNDS 0x0
#define UINT_RADIX_DIG 0x20
#define UINT_DIG 0x9
#define UINT_DECIMAL_DIG 0x0
#define UINT_RADIX 0x2
#define UINT_TRAPS 0xtrue
#define UINT_MIN 0x0
#define UINT_MAX 0xffffffff
#define LONG_ROUNDS 0x0
#define LONG_RADIX_DIG 0x3f
#define LONG_DIG 0x12
#define LONG_DECIMAL_DIG 0x0
#define LONG_RADIX 0x2
#define LONG_TRAPS 0xtrue
#define LONG_MIN 0x8000000000000000
#define LONG_MAX 0x7fffffffffffffff
#define ULONG_ROUNDS 0x0
#define ULONG_RADIX_DIG 0x40
#define ULONG_DIG 0x13
#define ULONG_DECIMAL_DIG 0x0
#define ULONG_RADIX 0x2
#define ULONG_TRAPS 0xtrue
#define ULONG_MIN 0x0
#define ULONG_MAX 0xffffffffffffffff
#define LLONG_ROUNDS 0x0
#define LLONG_RADIX_DIG 0x3f
#define LLONG_DIG 0x12
#define LLONG_DECIMAL_DIG 0x0
#define LLONG_RADIX 0x2
#define LLONG_TRAPS 0xtrue
#define LLONG_MIN 0x8000000000000000
#define LLONG_MAX 0x7fffffffffffffff
#define ULLONG_ROUNDS 0x0
#define ULLONG_RADIX_DIG 0x40
#define ULLONG_DIG 0x13
#define ULLONG_DECIMAL_DIG 0x0
#define ULLONG_RADIX 0x2
#define ULLONG_TRAPS 0xtrue
#define ULLONG_MIN 0x0
#define ULLONG_MAX 0xffffffffffffffff
#endif // FENNEC_LANG_INTEGER_H

View File

@ -16,10 +16,89 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
///
/// \file intrinsics.h
/// \brief This header contains definitions for compiler intrinsics necessary for implementing functions of the
/// C++ stdlib.
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_LANG_INTRINSICS_H #ifndef FENNEC_LANG_INTRINSICS_H
#define FENNEC_LANG_INTRINSICS_H #define FENNEC_LANG_INTRINSICS_H
///
/// \page fennec_lang_intrinsics Intrinsics
///
/// \brief This header contains definitions for compiler intrinsics necessary for implementing functions of the
/// C++ stdlib.
///
///
/// <table width="100%" class="fieldtable" id="table_fennec_lang_intrinsics">
/// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// `FENNEC_HAS_BUILTIN_BIT_CAST` <br>
/// `Y FENNEC_BUILTIN_BIT_CAST(X)`
/// <td width="50%" style="vertical-align: top">
/// An intrinsic for doing a bitwise cast without using `reinterpret_cast`.
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// `FENNEC_HAS_BUILTIN_ADDRESSOF` <br>
/// `Y FENNEC_BUILTIN_ADDRESSOF(X)`
/// <td width="50%" style="vertical-align: top">
/// Obtains the true address of an object in circumstances where `operator&` is overloaded.
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// `FENNEC_HAS_BUILTIN_IS_CONVERTIBLE` <br>
/// `B FENNEC_BUILTIN_IS_CONVERTIBLE(X, Y)`
/// <td width="50%" style="vertical-align: top">
/// Checks if type `X` can be converted to type `Y`.
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// `FENNEC_HAS_BUILTIN_IS_EMPTY` <br>
/// `B FENNEC_BUILTIN_IS_EMPTY(X)`
/// <td width="50%" style="vertical-align: top">
/// Checks if type `X` stores no data.
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// `FENNEC_HAS_BUILTIN_IS_POLYMORPHIC` <br>
/// `B FENNEC_BUILTIN_IS_POLYMORPHIC(X)`
/// <td width="50%" style="vertical-align: top">
/// Checks if type `X` is polymorphic, this is for classes only thus checks only for subtyping
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// `FENNEC_HAS_BUILTIN_IS_FINAL` <br>
/// `B FENNEC_BUILTIN_IS_FINAL(X)`
/// <td width="50%" style="vertical-align: top">
/// Checks if type `X` is final, meaning a function or class cannot be derived from.
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// `FENNEC_HAS_BUILTIN_IS_ABSTRACT` <br>
/// `B FENNEC_BUILTIN_IS_ABSTRACT(X)`
/// <td width="50%" style="vertical-align: top">
/// Opposite of `FENNEC_BUILTIN_IS_FINAL`, checks if abstract, meaning `X` has at least one pure virtual function.
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// `FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT` <br>
/// `B FENNEC_BUILTIN_IS_STANDARD_LAYOUT(X)`
/// <td width="50%" style="vertical-align: top">
/// Checks if `X` has a standard layout, here is [full criteria](https://www.cppreference.com/w/cpp/language/classes.html#Standard-layout_class)
/// for this trait
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// `FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE` <br>
/// `B FENNEC_BUILTIN_IS_CONSTRUCTIBLE(X, ...)`
/// <td width="50%" style="vertical-align: top">
/// Checks if type `X` is constructible with args `...`, such that `X::X(...)` exists.
///
/// </table>
///
///
// Most major compilers support __has_builtin, notably GCC, MINGW, CLANG, and MSVC // Most major compilers support __has_builtin, notably GCC, MINGW, CLANG, and MSVC
#if defined(__has_builtin) #if defined(__has_builtin)
@ -45,10 +124,10 @@
// 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_CAN_CONVERT 1 # define FENNEC_HAS_BUILTIN_IS_CONVERTIBLE 1
# define FENNEC_BUILTIN_CAN_CONVERT(arg0, arg1) __is_convertible(arg0, arg1) # define FENNEC_BUILTIN_IS_CONVERTIBLE(arg0, arg1) __is_convertible(arg0, arg1)
#else #else
# define FENNEC_HAS_BUILTIN_CAN_CONVERT 0 # define FENNEC_HAS_BUILTIN_IS_CONVERTIBLE 0
#endif #endif
// Inconsistent without intrinsics. // Inconsistent without intrinsics.

View File

@ -37,7 +37,10 @@
/// This library implements the parts of the C++ stdlib that relate to built-in types and metaprogramming. /// This library implements the parts of the C++ stdlib that relate to built-in types and metaprogramming.
/// ///
/// - \subpage fennec_lang_bit_manipulation /// - \subpage fennec_lang_bit_manipulation
/// - \subpage fennec_lang_intrinsics
/// - \subpage fennec_lang_limits
/// - \subpage fennec_lang_metaprogramming /// - \subpage fennec_lang_metaprogramming
/// - \subpage fennec_lang_types
/// ///
/// ///
@ -45,11 +48,12 @@
/// \page fennec_lang_metaprogramming Metaprogramming /// \page fennec_lang_metaprogramming Metaprogramming
/// ///
/// Metaprogramming is a method of obtaining information about the structure of the code at compile time. /// Metaprogramming is a method of obtaining information about the structure of the code at compile time.
/// This includes getting traits of types, such as with \ref fennec::numeric_limits. You may even programmatically /// This includes getting traits of types, such as with \ref fennec::numeric_limits. You may even
/// enable functions based on the info of the types that the function uses. /// \ref fennec_lang_conditional_types "programmatically enable" functions based on the info of the types that the function uses.
/// ///
/// - \subpage fennec_lang_constants
/// - \subpage fennec_lang_conditional_types /// - \subpage fennec_lang_conditional_types
/// /// - \subpage fennec_lang_numeric_transforms
/// ///
/// ///

View File

@ -16,14 +16,198 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
///
/// \file limits.h
/// \brief contains the limits of builtin data types to C++
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_LANG_LIMITS_H #ifndef FENNEC_LANG_LIMITS_H
#define FENNEC_LANG_LIMITS_H #define FENNEC_LANG_LIMITS_H
///
/// \page fennec_lang_limits Limits
///
/// \brief This header defines fennec::numeric_limits which contains info regarding the limits of numeric types including
/// floats and integers. There are overloads for all builtin types, and overloads for other types are included in
/// their own header.
///
/// \code{.cpp}#include <fennec/lang/limits.h>\endcode
///
/// \section fennec_lang_limits_numeric_limits Numeric Limits
/// <table width="100%" class="fieldtable" id="table_fennec_lang_limits">
/// <tr><th style="vertical-align: top">Member
/// <th style="vertical-align: top">Description
///
/// <tr><th colspan=2 style="text-align: center;">Traits
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::is_specialized "is_specialized"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::is_specialized
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::is_signed "is_signed"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::is_signed
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::is_integer "is_integer"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::is_integer
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::is_exact "is_exact"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::is_exact
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::has_infinity "has_infinity"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::has_infinity
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::has_quiet_nan "has_quiet_nan"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::has_quiet_nan
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::has_signaling_nan "has_signaling_nan"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::has_signaling_nan
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::is_iec559 "is_iec559"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::is_iec559
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::is_bounded "is_bounded"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::is_bounded
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::is_modulo "is_modulo"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::is_modulo
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::tinyness_before "tinyness_before"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::tinyness_before
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::traps "traps"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::traps
///
/// <tr><th colspan=2 style="text-align: center;">Binary
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::radix "radix"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::radix
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::digits "digits"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::digits
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::digits10 "digits10"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::digits10
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::max_digits10 "max_digits10"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::max_digits10
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::min_exponent "min_exponent"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::min_exponent
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::min_exponent10 "min_exponent10"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::min_exponent10
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::max_exponent "max_exponent"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::max_exponent
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::max_exponent10 "max_exponent10"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::max_exponent10
///
/// <tr><th colspan=2 style="text-align: center;">Limits
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::min "min()"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::min
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::max "max()"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::max
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::lowest "lowest()"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::lowest
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::epsilon "epsilon()"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::epsilon
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::round_error "round_error()"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::round_error
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::infinity "infinity()"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::infinity
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::quiet_NaN "quiet_NaN()"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::quiet_NaN
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::signaling_NaN "signaling_NaN()"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::signaling_NaN
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::numeric_limits::denorm_min "denorm_min()"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::numeric_limits::denorm_min
///
/// </table>
///
///
#include <cmath> #include <cmath>
#include <fennec/lang/types.h> #include <fennec/lang/types.h>
#include <fennec/lang/type_traits.h> #include <fennec/lang/type_traits.h>
#include <fennec/lang/integer.h>
#include <fennec/lang/float.h>
namespace fennec namespace fennec
{ {
@ -51,6 +235,8 @@ template<typename TypeT> struct numeric_limits
static constexpr bool has_infinity = false; ///< Check if TypeT can hold a value representing infinity static constexpr bool has_infinity = false; ///< Check if TypeT can hold a value representing infinity
static constexpr bool has_quiet_nan = false; ///< Check if TypeT can hold a non-signaling nan static constexpr bool has_quiet_nan = false; ///< Check if TypeT can hold a non-signaling nan
static constexpr bool has_signaling_nan = false; ///< Check if TypeT can hold a signaling nan static constexpr bool has_signaling_nan = false; ///< Check if TypeT can hold a signaling nan
static constexpr bool has_denorm = false; ///< Check if TypeT denormalizes
static constexpr bool has_denorm_loss = false; ///< Check if TypeT has precision loss when denormalized
static constexpr bool is_iec559 = false; ///< Check if a TypeT representing a float is IEC 559 or IEEE 754 static constexpr bool is_iec559 = false; ///< Check if a TypeT representing a float is IEC 559 or IEEE 754
static constexpr bool is_bounded = false; ///< Check if TypeT represents a finite set of values static constexpr bool is_bounded = false; ///< Check if TypeT represents a finite set of values
static constexpr bool is_modulo = false; ///< Check if TypeT can handle modulo arithmetic static constexpr bool is_modulo = false; ///< Check if TypeT can handle modulo arithmetic
@ -69,9 +255,9 @@ template<typename TypeT> struct numeric_limits
static constexpr float_round_style rounding_style = round_indeterminate; ///< The rounding style of TypeT static constexpr float_round_style rounding_style = round_indeterminate; ///< The rounding style of TypeT
// This is very poorly named and defined in the C++ Standard so these functions differ // This is very poorly named and defined in the C++ Standard so these functions differ
static constexpr TypeT min() { return TypeT(); } ///< The minimum finite value of TypeT static constexpr TypeT min() { return TypeT(); } ///< Returns the minimum finite value of TypeT
static constexpr TypeT max() { return TypeT(); } ///< The maximum finite value of TypeT static constexpr TypeT max() { return TypeT(); } ///< Returns the maximum finite value of TypeT
static constexpr TypeT lowest() { return TypeT(); } ///< The smallest positive value of TypeT static constexpr TypeT lowest() { return TypeT(); } ///< Returns the smallest positive value of TypeT
static constexpr TypeT epsilon() { return TypeT(); } ///< Returns the difference between 1.0 and the next representable value static constexpr TypeT epsilon() { return TypeT(); } ///< Returns the difference between 1.0 and the next representable value
static constexpr TypeT round_error() { return TypeT(); } ///< Returns the max rounding error of TypeT static constexpr TypeT round_error() { return TypeT(); } ///< Returns the max rounding error of TypeT
static constexpr TypeT infinity() { return TypeT(); } ///< Returns a value of TypeT holding a positive infinity static constexpr TypeT infinity() { return TypeT(); } ///< Returns a value of TypeT holding a positive infinity
@ -80,6 +266,8 @@ template<typename TypeT> struct numeric_limits
static constexpr TypeT denorm_min() { return TypeT(); } ///< Returns a value of TypeT holding the smallest positive subnormal static constexpr TypeT denorm_min() { return TypeT(); } ///< Returns a value of TypeT holding the smallest positive subnormal
}; };
// Overload definitions for basic types
// Overload for the builtin floating point type // Overload for the builtin floating point type
template<> struct numeric_limits<float> template<> struct numeric_limits<float>
{ {
@ -107,9 +295,9 @@ template<> struct numeric_limits<float>
static constexpr int max_exponent = FLT_MAX_EXP; static constexpr int max_exponent = FLT_MAX_EXP;
static constexpr int max_exponent10 = FLT_MAX_10_EXP; static constexpr int max_exponent10 = FLT_MAX_10_EXP;
static constexpr double min() { return FLT_MIN; } static constexpr double min() { return -FLT_MAX; }
static constexpr double max() { return FLT_MAX; } static constexpr double max() { return FLT_MAX; }
static constexpr double lowest() { return -FLT_MAX; } static constexpr double lowest() { return FLT_MIN; }
static constexpr double epsilon() { return FLT_EPSILON; } static constexpr double epsilon() { return FLT_EPSILON; }
static constexpr double round_error() { return FLT_ROUND_ERR; } static constexpr double round_error() { return FLT_ROUND_ERR; }
static constexpr double infinity() { return FLT_INF; } static constexpr double infinity() { return FLT_INF; }
@ -145,9 +333,9 @@ template<> struct numeric_limits<double>
static constexpr int max_exponent = DBL_MAX_EXP; static constexpr int max_exponent = DBL_MAX_EXP;
static constexpr int max_exponent10 = DBL_MAX_10_EXP; static constexpr int max_exponent10 = DBL_MAX_10_EXP;
static constexpr double min() { return DBL_MIN; } static constexpr double min() { return -DBL_MAX; }
static constexpr double max() { return DBL_MAX; } static constexpr double max() { return DBL_MAX; }
static constexpr double lowest() { return -DBL_MAX; } static constexpr double lowest() { return DBL_MIN; }
static constexpr double epsilon() { return DBL_EPSILON; } static constexpr double epsilon() { return DBL_EPSILON; }
static constexpr double round_error() { return DBL_ROUND_ERR; } static constexpr double round_error() { return DBL_ROUND_ERR; }
static constexpr double infinity() { return DBL_INF; } static constexpr double infinity() { return DBL_INF; }
@ -156,6 +344,424 @@ template<> struct numeric_limits<double>
static constexpr double denorm_min() { return DBL_DENORM_MIN; } static constexpr double denorm_min() { return DBL_DENORM_MIN; }
}; };
// Overload for the builtin char type
template<> struct numeric_limits<char>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = CHAR_IS_SIGNED;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = CHAR_RADIX_DIG;
static constexpr int digits10 = CHAR_DIG;
static constexpr int max_digits10 = CHAR_DECIMAL_DIG;
static constexpr int radix = CHAR_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return CHAR_MIN; }
static constexpr double max() { return CHAR_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<signed char>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = SCHAR_RADIX_DIG;
static constexpr int digits10 = SCHAR_DIG;
static constexpr int max_digits10 = SCHAR_DECIMAL_DIG;
static constexpr int radix = SCHAR_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return SCHAR_MIN; }
static constexpr double max() { return SCHAR_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<unsigned char>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = UCHAR_RADIX_DIG;
static constexpr int digits10 = UCHAR_DIG;
static constexpr int max_digits10 = UCHAR_DECIMAL_DIG;
static constexpr int radix = UCHAR_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return UCHAR_MIN; }
static constexpr double max() { return UCHAR_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<short>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = SHORT_RADIX_DIG;
static constexpr int digits10 = SHORT_DIG;
static constexpr int max_digits10 = SHORT_DECIMAL_DIG;
static constexpr int radix = SHORT_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return SHORT_MIN; }
static constexpr double max() { return SHORT_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<unsigned short>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = USHORT_RADIX_DIG;
static constexpr int digits10 = USHORT_DIG;
static constexpr int max_digits10 = USHORT_DECIMAL_DIG;
static constexpr int radix = USHORT_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return USHORT_MIN; }
static constexpr double max() { return USHORT_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<int>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = INT_RADIX_DIG;
static constexpr int digits10 = INT_DIG;
static constexpr int max_digits10 = INT_DECIMAL_DIG;
static constexpr int radix = INT_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return INT_MIN; }
static constexpr double max() { return INT_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<unsigned int>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = UINT_RADIX_DIG;
static constexpr int digits10 = UINT_DIG;
static constexpr int max_digits10 = UINT_DECIMAL_DIG;
static constexpr int radix = UINT_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return UINT_MIN; }
static constexpr double max() { return UINT_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<long int>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = LONG_RADIX_DIG;
static constexpr int digits10 = LONG_DIG;
static constexpr int max_digits10 = LONG_DECIMAL_DIG;
static constexpr int radix = LONG_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return LONG_MIN; }
static constexpr double max() { return LONG_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<unsigned long int>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = ULONG_RADIX_DIG;
static constexpr int digits10 = ULONG_DIG;
static constexpr int max_digits10 = ULONG_DECIMAL_DIG;
static constexpr int radix = ULONG_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return ULONG_MIN; }
static constexpr double max() { return ULONG_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<long long>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = LLONG_RADIX_DIG;
static constexpr int digits10 = LLONG_DIG;
static constexpr int max_digits10 = LLONG_DECIMAL_DIG;
static constexpr int radix = LLONG_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return LLONG_MIN; }
static constexpr double max() { return LLONG_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
// Overload for the builtin signed char type
template<> struct numeric_limits<unsigned long long>
{
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_nan = false;
static constexpr bool has_signaling_nan = false;
static constexpr bool has_denorm = false;
static constexpr bool has_denorm_loss = false;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr bool tinyness_before = false;
static constexpr bool traps = true;
static constexpr int digits = ULLONG_RADIX_DIG;
static constexpr int digits10 = ULLONG_DIG;
static constexpr int max_digits10 = ULLONG_DECIMAL_DIG;
static constexpr int radix = ULLONG_RADIX;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr double min() { return ULLONG_MIN; }
static constexpr double max() { return ULLONG_MAX; }
static constexpr double lowest() { return 1; }
static constexpr double epsilon() { return 1; }
static constexpr double round_error() { return 0; }
static constexpr double infinity() { return 0; }
static constexpr double quiet_NaN() { return 0; }
static constexpr double signaling_NaN() { return 0; }
static constexpr double denorm_min() { return 0; }
};
} }
#endif // FENNEC_LANG_LIMITS_H #endif // FENNEC_LANG_LIMITS_H

View File

@ -30,6 +30,31 @@
#ifndef FENNEC_LANG_NUMERIC_TRANSFORMS_H #ifndef FENNEC_LANG_NUMERIC_TRANSFORMS_H
#define FENNEC_LANG_NUMERIC_TRANSFORMS_H #define FENNEC_LANG_NUMERIC_TRANSFORMS_H
///
/// \page fennec_lang_numeric_transforms Numeric Transforms
///
/// \code #include <fennec/lang/numeric_transforms.h> \endcode
///
/// This header contains various compile-time functions for changing the characteristics of a provided type
///
/// <table width="100%" class="fieldtable" id="table_fennec_lang_numeric_transforms">
/// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::make_signed "typename make_signed<TypeT>::type"<br>
/// \ref fennec::make_signed_t "make_signed_t<TypeT>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::make_signed
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::make_unsigned "typename make_unsigned<TypeT>::type"<br>
/// \ref fennec::make_unsigned_t "make_unsigned_t<TypeT>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::make_unsigned
///
/// </table>
#include <fennec/lang/type_transforms.h> #include <fennec/lang/type_transforms.h>
#include <fennec/lang/detail/__numeric_transforms.h> #include <fennec/lang/detail/__numeric_transforms.h>
@ -41,12 +66,20 @@ namespace fennec
/// \tparam TypeT the integral type to transform /// \tparam TypeT the integral type to transform
template<typename TypeT> struct make_signed : detail::__make_signed<remove_cv_t<TypeT>> {}; template<typename TypeT> struct make_signed : detail::__make_signed<remove_cv_t<TypeT>> {};
///
/// \brief Shorthand for `typename make_signed<TypeT>::type`
template<typename TypeT> using make_signed_t = typename make_signed<TypeT>::type;
/// ///
/// \brief Get the corresponding unsigned integral type of TypeT /// \brief Get the corresponding unsigned integral type of TypeT
/// \tparam TypeT the integral type to transform /// \tparam TypeT the integral type to transform
template<typename TypeT> struct make_unsigned : detail::__make_unsigned<remove_cv_t<TypeT>> {}; template<typename TypeT> struct make_unsigned : detail::__make_unsigned<remove_cv_t<TypeT>> {};
///
/// \brief Shorthand for `typename make_unsigned<TypeT>::type`
template<typename TypeT> using make_unsigned_t = typename make_unsigned<TypeT>::type;
} }
#endif // FENNEC_LANG_NUMERIC_TRANSFORMS_H #endif // FENNEC_LANG_NUMERIC_TRANSFORMS_H

View File

@ -198,7 +198,7 @@ template<typename T0, typename T1> constexpr bool_t is_same_v
/// \tparam T0 First type /// \tparam T0 First type
/// \tparam T1 Second type /// \tparam T1 Second type
template<typename T0, typename T1> struct can_convert template<typename T0, typename T1> struct can_convert
: bool_constant<FENNEC_BUILTIN_CAN_CONVERT(T0, T1)> {}; : bool_constant<FENNEC_BUILTIN_IS_CONVERTIBLE(T0, T1)> {};
/// ///
/// \brief shorthand /// \brief shorthand

View File

@ -55,24 +55,21 @@ template<typename T> struct type_transform {
// Pointer Conversions ================================================================================================= // Pointer Conversions =================================================================================================
/// ///
/// \struct fennec::add_pointer
/// \brief adds a pointer level to \p T /// \brief adds a pointer level to \p T
/// ///
/// \details adds a pointer to the provided type such that ```T``` becomes ```T*``` /// \details adds a pointer to the provided type such that `T` becomes `T*`
/// \tparam T Resultant Type /// \tparam T Resultant Type
template<typename T> struct add_pointer : type_transform<T*>{}; template<typename T> struct add_pointer : type_transform<T*>{};
/// ///
/// \typedef fennec::add_pointer_t /// \brief shorthand for `typename add_pointer<T>::type`
/// \brief shorthand for ```typename add_pointer<T>::type```
template<typename T> using add_pointer_t = typename add_pointer<T>::type; template<typename T> using add_pointer_t = typename add_pointer<T>::type;
/// ///
/// \struct fennec::remove_pointer
/// \brief removes a pointer level from \p T /// \brief removes a pointer level from \p T
/// ///
/// \details removes a pointer from the provided type such that ```T*``` becomes ```T``` /// \details removes a pointer from the provided type such that `T*` becomes `T`
/// \tparam T Resultant Type /// \tparam T Resultant Type
template<typename T> struct remove_pointer : type_transform<T> {}; template<typename T> struct remove_pointer : type_transform<T> {};
@ -80,8 +77,7 @@ template<typename T> struct remove_pointer : type_transform<T> {};
template<typename T> struct remove_pointer<T*> : type_transform<T> {}; template<typename T> struct remove_pointer<T*> : type_transform<T> {};
/// ///
/// \typedef fennec::remove_pointer_t /// \brief shorthand for `typename remove_pointer<T>::type`
/// \brief shorthand for ```typename remove_pointer<T>::type```
template<typename T> using remove_pointer_t = typename remove_pointer<T>::type; template<typename T> using remove_pointer_t = typename remove_pointer<T>::type;
@ -89,36 +85,32 @@ template<typename T> using remove_pointer_t = typename remove_pointer<T>::type;
// Reference Conversions =============================================================================================== // Reference Conversions ===============================================================================================
/// ///
/// \struct fennec::add_reference
/// \brief add a reference to \p T /// \brief add a reference to \p T
/// ///
/// \details adds a pointer to the provided type such that ```T``` becomes ```T&``` /// \details adds a pointer to the provided type such that `T` becomes `T&`
/// \tparam T Resultant Type /// \tparam T Resultant Type
template<typename T> struct add_reference : type_transform<T&> {}; template<typename T> struct add_reference : type_transform<T&> {};
/// ///
/// \typedef fennec::add_reference_t /// \brief shorthand for `typename add_reference<T>::type`
/// \brief shorthand for ```typename add_reference<T>::type```
template<typename T> using add_reference_t = typename add_reference<T>::type; template<typename T> using add_reference_t = typename add_reference<T>::type;
/// ///
/// \struct fennec::remove_reference
/// \brief remove a reference from \p T /// \brief remove a reference from \p T
/// ///
/// \details removes references from the provided type such that ```T&``` and ```T&&``` become ```T``` /// \details removes references from the provided type such that `T&` and `T&&` become `T`
/// \tparam T Reference Type /// \tparam T Reference Type
template<typename T> struct remove_reference : type_transform<T> {}; template<typename T> struct remove_reference : type_transform<T> {};
// specialization for ```T&``` // specialization for `T&`
template<typename T> struct remove_reference<T&> : type_transform<T> {}; template<typename T> struct remove_reference<T&> : type_transform<T> {};
// specialization for ```T&&``` // specialization for `T&&`
template<typename T> struct remove_reference<T&&> : type_transform<T> {}; template<typename T> struct remove_reference<T&&> : type_transform<T> {};
/// ///
/// \typedef fennec::remove_reference_t /// \brief shorthand for `typename remove_reference<T>::type`
/// \brief shorthand for ```typename remove_reference<T>::type```
template<typename T> using remove_reference_t = typename remove_reference<T>::type; template<typename T> using remove_reference_t = typename remove_reference<T>::type;
@ -126,16 +118,14 @@ template<typename T> using remove_reference_t = typename remove_reference<T>::t
// Const & Volatile Conversions ======================================================================================== // Const & Volatile Conversions ========================================================================================
/// ///
/// \struct fennec::add_const
/// \brief add the const qualifier to the provided type \p T /// \brief add the const qualifier to the provided type \p T
/// ///
/// \details adds const qualification to the provided type such that ```T``` becomes ```const T``` /// \details adds const qualification to the provided type such that `T` becomes `const T`
/// \tparam T Reference Type /// \tparam T Reference Type
template<typename T> struct add_const : type_transform<const T> {}; template<typename T> struct add_const : type_transform<const T> {};
/// ///
/// \typedef fennec::add_const_t /// \brief shorthand for `typename add_const<T>::type`
/// \brief shorthand for ```typename add_const<T>::type```
template<typename T> using add_const_t = typename add_const<T>::type; template<typename T> using add_const_t = typename add_const<T>::type;
// specialization for const types // specialization for const types
@ -143,16 +133,14 @@ template<typename T> struct add_const<const T> : type_transform<const T> {};
/// ///
/// \struct fennec::remove_const
/// \brief remove the const qualifier from the provided type \p T /// \brief remove the const qualifier from the provided type \p T
/// ///
/// \details removes const qualification from the provided type such that ```const T``` becomes ```T``` /// \details removes const qualification from the provided type such that `const T` becomes `T`
/// \tparam T Reference Type /// \tparam T Reference Type
template<typename T> struct remove_const : type_transform<T> {}; template<typename T> struct remove_const : type_transform<T> {};
/// ///
/// \typedef fennec::remove_const_t /// \brief shorthand for `typename remove_const<T>::type`
/// \brief shorthand for ```typename remove_const<T>::type```
template<typename T> using remove_const_t = typename remove_const<T>::type; template<typename T> using remove_const_t = typename remove_const<T>::type;
// specialization for const types // specialization for const types
@ -161,16 +149,14 @@ template<typename T> struct remove_const<const T> : type_transform<T> {};
/// ///
/// \struct fennec::add_volatile
/// \brief add the volatile qualifier to the provided type \p T /// \brief add the volatile qualifier to the provided type \p T
/// ///
/// \details removes references from the provided type such that ```T``` becomes ```volatile T``` /// \details removes references from the provided type such that `T` becomes `volatile T`
/// \tparam T Reference Type /// \tparam T Reference Type
template<typename T> struct add_volatile : type_transform<volatile T> {}; template<typename T> struct add_volatile : type_transform<volatile T> {};
/// ///
/// \typedef fennec::add_volatile_t /// \brief shorthand for `typename add_volatile<T>::type`
/// \brief shorthand for ```typename add_volatile<T>::type```
template<typename T> using add_volatile_t = typename add_volatile<T>::type; template<typename T> using add_volatile_t = typename add_volatile<T>::type;
// specialization for volatile types // specialization for volatile types
@ -178,16 +164,14 @@ template<typename T> struct add_volatile<volatile T> : type_transform<volatile T
/// ///
/// \struct fennec::remove_volatile
/// \brief remove the volatile qualifier from the provided type \p T /// \brief remove the volatile qualifier from the provided type \p T
/// ///
/// \details removes references from the provided type such that ```volatile T``` becomes ```T``` /// \details removes references from the provided type such that `volatile T` becomes `T`
/// \tparam T Reference Type /// \tparam T Reference Type
template<typename T> struct remove_volatile : type_transform<T> {}; template<typename T> struct remove_volatile : type_transform<T> {};
/// ///
/// \typedef fennec::remove_volatile_t /// \brief shorthand for `typename remove_volatile<T>::type`
/// \brief shorthand for ```typename remove_volatile<T>::type```
template<typename T> using remove_volatile_t = typename remove_volatile<T>::type; template<typename T> using remove_volatile_t = typename remove_volatile<T>::type;
// specialization for volatile types // specialization for volatile types
@ -196,17 +180,15 @@ template<typename T> struct remove_volatile<volatile T> : type_transform<T> {};
/// ///
/// \struct fennec::add_cv
/// \brief remove the volatile qualifier from the provided type \p T /// \brief remove the volatile qualifier from the provided type \p T
/// ///
/// \details removes references from the provided type such that ```T```, ```const T```, and ```volatile T``` become /// \details removes references from the provided type such that `T`, `const T`, and `volatile T` become
/// ```const volatile T``` /// `const volatile T`
/// \tparam T Reference Type /// \tparam T Reference Type
template<typename T> struct add_cv : type_transform<const volatile T> {}; template<typename T> struct add_cv : type_transform<const volatile T> {};
/// ///
/// \typedef fennec::add_cv_t /// \brief shorthand for `typename add_cv<T>::type`
/// \brief shorthand for ```typename add_cv<T>::type```
template<typename T> using add_cv_t = typename add_cv<T>::type; template<typename T> using add_cv_t = typename add_cv<T>::type;
// specialization for const types // specialization for const types
@ -220,12 +202,11 @@ template<typename T> struct add_cv<const volatile T> : type_transform<const vola
///
/// ///
/// \brief remove the const and volatile qualifiers from the provided type \p T /// \brief remove the const and volatile qualifiers from the provided type \p T
/// ///
/// \details removes const and volatile from the provided type such that ```const T```, ```volatile T```, and /// \details removes const and volatile from the provided type such that `const T`, `volatile T`, and
/// ```const volatile T``` become ```T``` /// `const volatile T` become `T`
/// \tparam T Reference Type /// \tparam T Reference Type
template<typename T> struct remove_cv : type_transform<T> {}; template<typename T> struct remove_cv : type_transform<T> {};
@ -239,12 +220,11 @@ template<typename T> struct remove_cv<volatile T> : type_transform<T> {};
template<typename T> struct remove_cv<const volatile T> : type_transform<T> {}; template<typename T> struct remove_cv<const volatile T> : type_transform<T> {};
/// ///
/// \brief shorthand for ```typename remove_cv<T>::type``` /// \brief shorthand for `typename remove_cv<T>::type`
template<typename T> using remove_cv_t = typename remove_cv<T>::type; template<typename T> using remove_cv_t = typename remove_cv<T>::type;
///
/// ///
/// \brief add a reference and the const volatile qualifiers from the provided type \p T /// \brief add a reference and the const volatile qualifiers from the provided type \p T
/// ///
@ -253,12 +233,11 @@ template<typename T> using remove_cv_t = typename remove_cv<T>::type;
template<typename T> struct add_cvr : type_transform<add_reference_t<add_cv_t<T>>> {}; template<typename T> struct add_cvr : type_transform<add_reference_t<add_cv_t<T>>> {};
/// ///
/// \brief shorthand for ```typename add_cvr<T>::type``` /// \brief shorthand for `typename add_cvr<T>::type`
template<typename T> using add_cvr_t = typename add_cvr<T>::type; template<typename T> using add_cvr_t = typename add_cvr<T>::type;
///
/// ///
/// \brief removes references as well as the const and volatile qualifiers from the provided type \p T /// \brief removes references as well as the const and volatile qualifiers from the provided type \p T
/// ///
@ -268,7 +247,7 @@ template<typename T> struct remove_cvr : type_transform<remove_cv_t<remove_refer
/// ///
/// \brief shorthand for ```typename remove_cvr<T>::type``` /// \brief shorthand for `typename remove_cvr<T>::type`
template<typename T> using remove_cvr_t = typename remove_cvr<T>::type; template<typename T> using remove_cvr_t = typename remove_cvr<T>::type;
} }

View File

@ -31,6 +31,190 @@
#ifndef FENNEC_LANG_TYPES_H #ifndef FENNEC_LANG_TYPES_H
#define FENNEC_LANG_TYPES_H #define FENNEC_LANG_TYPES_H
///
/// \page fennec_lang_types Types
///
/// \brief This header contains definitions for built-in types.
///
/// <table width="100%" class="fieldtable" id="table_fennec_lang_types">
/// <tr><th style="vertical-align: top">Member
/// <th style="vertical-align: top">Description
///
/// <tr><th colspan=2 style="text-align: center;">Basic Types
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::bool_t "bool_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::bool_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::char_t "char_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::char_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::schar_t "schar_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::schar_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::uchar_t "uchar_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::uchar_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::short_t "short_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::short_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::ushort_t "ushort_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::ushort_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::int_t "int_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::int_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::uint_t "uint_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::uint_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::long_t "long_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::long_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::ulong_t "ulong_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::ulong_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::llong_t "llong_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::llong_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::ullong_t "ullong_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::ullong_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::float_t "float_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::float_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::double_t "double_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::double_t
///
/// <tr><th colspan=2 style="text-align: center;">Sized Arithmetic Types
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::int8_t "int8_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::int8_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::int16_t "int16_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::int16_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::int32_t "int32_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::int32_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::int64_t "int64_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::int64_t
///
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::uint8_t "uint8_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::uint8_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::uint16_t "uint16_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::uint16_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::uint32_t "uint32_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::uint32_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::uint64_t "uint64_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::int64_t
///
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::float32_t "float32_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::float32_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::float64_t "float64_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::float64_t
///
///
/// <tr><th colspan=2 style="text-align: center;">Special Types
///
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::nullptr_t "nullptr_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::nullptr_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::intptr_t "intptr_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::intptr_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::uintptr_t "uintptr_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::uintptr_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::intmax_t "intmax_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::intmax_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::uintmax_t "uintmax_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::uintmax_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::size_t "size_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::size_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::ptrdiff_t "ptrdiff_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::ptrdiff_t
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// <tt>\ref fennec::void_t "void_t"</tt>
/// <td width="50%" style="vertical-align: top">
/// \copybrief fennec::void_t
///
///
/// </table>
///
///
#include <cstdint> #include <cstdint>
namespace fennec namespace fennec

View File

@ -40,6 +40,8 @@
/// ///
/// \brief The Common Functions defined in the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). /// \brief The Common Functions defined in the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf).
/// ///
/// \code #include <fennec/math/common.h> \endcode
///
/// ///
/// ///
/// \section section_sign_functions Sign /// \section section_sign_functions Sign

View File

@ -41,10 +41,12 @@
/// ///
/// \brief The Exponential Functions defined in the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). /// \brief The Exponential Functions defined in the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf).
/// ///
/// \code #include <fennec/math/exponential.h> \endcode
///
/// ///
/// \section Exponential Functions /// \section Exponential Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_curve_functions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_exponential_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// ///

View File

@ -43,6 +43,8 @@
/// ///
/// \brief The Geometric Functions defined in the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). /// \brief The Geometric Functions defined in the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf).
/// ///
/// \code #include <fennec/math/geometric.h> \endcode
///
/// ///
/// \section Geometric Functions /// \section Geometric Functions
/// ///

View File

@ -41,18 +41,26 @@
/// ///
/// \page fennec_math Math Library /// \page fennec_math Math Library
/// ///
/// \brief The fennec Math Library.
/// Includes various types and functions related to mathematics, predominantly linear algebra.
///
/// \code #include <fennec/math/math.h> \endcode
///
/// The \ref fennec Math Library is composed of the modules listed in below. /// The \ref fennec Math Library is composed of the modules listed in below.
/// The overarching goal of this math library is to implement the math types and functions of the /// The overarching goal of this math library is to implement the math types and functions of the
/// [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). /// [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf).
/// ///
/// The data types are influenced by the GLM and CxxSwizzle implementations. The resulting structures were optimized
/// to decrease compilation times and allow the compiler to more easily optimize the resulting binary code.
///
/// - \subpage fennec_math_topics "Topics" /// - \subpage fennec_math_topics "Topics"
/// - \ref fennec_math_set_theory /// - \ref fennec_math_set_theory
/// - \ref fennec_math_swizzle
/// - \subpage fennec_math_data_types "Data Types" /// - \subpage fennec_math_data_types "Data Types"
/// - \ref fennec_math_scalar /// - \ref fennec_math_scalar
/// - \ref fennec_math_vector /// - \ref fennec_math_vector
/// - \ref fennec_math_matrix /// - \ref fennec_math_matrix
/// - \subpage fennec_math_functions "Functions" /// - \subpage fennec_math_functions "Functions"
/// - \ref fennec_math_set_theory
/// - \ref fennec_math_common /// - \ref fennec_math_common
/// - \ref fennec_math_exponential /// - \ref fennec_math_exponential
/// - \ref fennec_math_geometric /// - \ref fennec_math_geometric
@ -64,6 +72,7 @@
/// ///
/// \page fennec_math_topics Topics /// \page fennec_math_topics Topics
/// - \subpage fennec_math_set_theory /// - \subpage fennec_math_set_theory
/// - \subpage fennec_math_swizzle
/// ///
/// ///
@ -75,7 +84,6 @@
/// ///
/// \page fennec_math_functions Functions /// \page fennec_math_functions Functions
/// - \subpage fennec_math_set_theory
/// - \subpage fennec_math_common /// - \subpage fennec_math_common
/// - \subpage fennec_math_exponential /// - \subpage fennec_math_exponential
/// - \subpage fennec_math_geometric /// - \subpage fennec_math_geometric
@ -88,9 +96,9 @@
/// ///
/// \page fennec_math_set_theory Set Theory /// \page fennec_math_set_theory Set Theory
/// ///
/// Binary Mathematics, like most branches of Mathematics, is built, foundationally, upon Set Theory. Set Theory is /// Binary Mathematics, like most branches of Mathematics, is built upon Set Theory. Set Theory is
/// the branch of Mathematics that studies Sets. Sets contain a collection of elements which may be numbers, or other /// the branch of Mathematics that studies Sets. Sets contain a collection of elements which may be numbers, as well as other
/// mathematical values and structures. /// mathematical structures, types, or values.
/// ///
/// Set definitions for all mathematical structures in the \ref fennec_math "Fennec Math Library" are present in /// Set definitions for all mathematical structures in the \ref fennec_math "Fennec Math Library" are present in
/// their respective pages. /// their respective pages.

View File

@ -28,17 +28,20 @@
/// ///
/// ///
/// #ifndef FENNEC_MATH_MATRIX_H
#define FENNEC_MATH_MATRIX_H
/// ///
/// ///
/// \page fennec_math_matrix Matrices /// \page fennec_math_matrix Matrices
/// ///
/// \brief The fennec Matrix Math Module
///
/// \code #include <fennec/math/matrix.h> \endcode
///
/// ///
/// ///
/// ///
#ifndef FENNEC_MATH_MATRIX_H
#define FENNEC_MATH_MATRIX_H
#include <fennec/math/detail/__fwd.h> #include <fennec/math/detail/__fwd.h>

View File

@ -38,7 +38,9 @@
/// ///
/// \brief The Relational Functions defined in the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). /// \brief The Relational Functions defined in the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf).
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_curve_functions"> /// \code #include <fennec/math/relational.h> \endcode
///
/// <table width="100%" class="fieldtable" id="table_fennec_math_relational_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// ///

View File

@ -39,6 +39,10 @@
/// \page fennec_math_scalar Scalars /// \page fennec_math_scalar Scalars
/// \anchor scalar /// \anchor scalar
/// ///
/// \brief The base scalar types of the fennec Math Library
///
/// \code #include <fennec/math/scalar.h> \endcode
///
/// The \ref fennec Library considers any type that passes ```is_arithmetic<T>``` to be a \ref scalar "Scalar." Bools are /// The \ref fennec Library considers any type that passes ```is_arithmetic<T>``` to be a \ref scalar "Scalar." Bools are
/// supported as a logical type. /// supported as a logical type.
/// ///

View File

@ -31,6 +31,16 @@
#ifndef FENNEC_MATH_SWIZZLE_H #ifndef FENNEC_MATH_SWIZZLE_H
#define FENNEC_MATH_SWIZZLE_H #define FENNEC_MATH_SWIZZLE_H
///
///
/// \page fennec_math_swizzle Swizzling
///
/// \brief A submodule of the fennec Vector Math Module, used for "swizzling" vectors.
///
/// \code #include <fennec/math/swizzle.h> \endcode
///
///
#include <fennec/lang/sequences.h> #include <fennec/lang/sequences.h>
#include <fennec/math/swizzle_storage.h> #include <fennec/math/swizzle_storage.h>

View File

@ -36,7 +36,9 @@
/// ///
/// \page fennec_math_trigonometric Trigonometry /// \page fennec_math_trigonometric Trigonometry
/// ///
/// \brief The fennec Trigonometry Module /// \brief The Trigonometric Functions defined in the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf).
///
/// \code #include <fennec/math/trigonometric.h> \endcode
/// ///
/// ///
/// ///
@ -62,7 +64,7 @@
/// ///
/// \section section_fennec_trigonometric_functions Trigonometric Functions /// \section section_fennec_trigonometric_functions Trigonometric Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_trigonometry_angle_conversions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_trigonometry_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// ///
@ -103,7 +105,7 @@
/// ///
/// \section section_fennec_hyperbolic_functions Hyperbolic Functions /// \section section_fennec_hyperbolic_functions Hyperbolic Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_trigonometry_angle_conversions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_trigonometry_hyperbolic">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// ///

View File

@ -38,11 +38,12 @@
/// ///
/// \brief The fennec Vector Math Module /// \brief The fennec Vector Math Module
/// ///
/// \code #include <fennec/math/vector.h> \endcode
///
/// ///
/// \section vector_types Types /// \section vector_types Types
/// ///
/// <table> /// <table width="100%" class="fieldtable" id="table_fennec_math_vector_types">
/// <caption id="table_fennec_math_vector_types"></caption>
/// <tr><th>Type <th>Corresponding Type <th>Brief /// <tr><th>Type <th>Corresponding Type <th>Brief
/// <tr><th colspan=3 style="text-align: center;">Floats /// <tr><th colspan=3 style="text-align: center;">Floats
/// <tr><td>```vec2``` <td>\ref fennec::vec2 <td>\copybrief fennec::vec2 /// <tr><td>```vec2``` <td>\ref fennec::vec2 <td>\copybrief fennec::vec2

View File

@ -4,7 +4,8 @@ project(fennec-metaprogramming)
set(CMAKE_CXX_STANDARD 26) set(CMAKE_CXX_STANDARD 26)
add_executable(fennec-metaprogramming main.cpp add_executable(fennec-metaprogramming main.cpp
float.h) float.h
integer.h)
add_custom_command( add_custom_command(
OUTPUT .metaprogramming OUTPUT .metaprogramming
COMMAND fennec-metaprogramming COMMAND fennec-metaprogramming

View File

@ -9,115 +9,115 @@
inline void float_h() inline void float_h()
{ {
std::ofstream flt("float.h"); std::ofstream out("float.h");
flt << "// =====================================================================================================================" << std::endl; out << "// =====================================================================================================================" << std::endl;
flt << "// fennec, a free and open source game engine" << std::endl; out << "// fennec, a free and open source game engine" << std::endl;
flt << "// Copyright © 2025 Medusa Slockbower" << std::endl; out << "// Copyright © 2025 Medusa Slockbower" << std::endl;
flt << "//" << std::endl; out << "//" << std::endl;
flt << "// This program is free software: you can redistribute it and/or modify" << std::endl; out << "// This program is free software: you can redistribute it and/or modify" << std::endl;
flt << "// it under the terms of the GNU General Public License as published by" << std::endl; out << "// it under the terms of the GNU General Public License as published by" << std::endl;
flt << "// the Free Software Foundation, either version 3 of the License, or" << std::endl; out << "// the Free Software Foundation, either version 3 of the License, or" << std::endl;
flt << "// (at your option) any later version." << std::endl; out << "// (at your option) any later version." << std::endl;
flt << "//" << std::endl; out << "//" << std::endl;
flt << "// This program is distributed in the hope that it will be useful," << std::endl; out << "// This program is distributed in the hope that it will be useful," << std::endl;
flt << "// but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl; out << "// but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl;
flt << "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl; out << "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl;
flt << "// GNU General Public License for more details." << std::endl; out << "// GNU General Public License for more details." << std::endl;
flt << "//" << std::endl; out << "//" << std::endl;
flt << "// You should have received a copy of the GNU General Public License" << std::endl; out << "// You should have received a copy of the GNU General Public License" << std::endl;
flt << "// along with this program. If not, see <https://www.gnu.org/licenses/>." << std::endl; out << "// along with this program. If not, see <https://www.gnu.org/licenses/>." << std::endl;
flt << "// =====================================================================================================================" << std::endl; out << "// =====================================================================================================================" << std::endl;
flt << "" << std::endl; out << "" << std::endl;
flt << "///" << std::endl; out << "///" << std::endl;
flt << "/// \\file float.h" << std::endl; out << "/// \\file float.h" << std::endl;
flt << "/// \\brief metaprogramming floating point type info" << std::endl; out << "/// \\brief metaprogramming floating point type info" << std::endl;
flt << "///" << std::endl; out << "///" << std::endl;
flt << "///" << std::endl; out << "///" << std::endl;
flt << "/// \\details this file is automatically generated for the current build environment" << std::endl; out << "/// \\details this file is automatically generated for the current build environment" << std::endl;
flt << "///" << std::endl; out << "///" << std::endl;
flt << "/// \\copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))" << std::endl; out << "/// \\copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))" << std::endl;
flt << "///" << std::endl; out << "///" << std::endl;
flt << "///" << std::endl; out << "///" << std::endl;
flt << "" << std::endl; out << "" << std::endl;
flt << "#ifndef FENNEC_LANG_FLOAT_H" << std::endl; out << "#ifndef FENNEC_LANG_FLOAT_H" << std::endl;
flt << "#define FENNEC_LANG_FLOAT_H" << std::endl; out << "#define FENNEC_LANG_FLOAT_H" << std::endl;
flt << "" << std::endl; out << "" << std::endl;
flt << "#include <fennec/lang/bits.h>" << std::endl; out << "#include <fennec/lang/bits.h>" << std::endl;
flt << "" << std::endl; out << "" << std::endl;
// 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.
flt << "#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;
flt << "#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;
flt << "#define FLT_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits<float>::has_signaling_NaN << std::endl; out << "#define FLT_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits<float>::has_signaling_NaN << std::endl;
flt << "#define FLT_HAS_DENORM " << std::dec << std::numeric_limits<float>::has_denorm << std::endl; out << "#define FLT_HAS_DENORM " << std::dec << std::numeric_limits<float>::has_denorm << std::endl;
flt << "#define FLT_HAS_DENORM_LOSS " << std::dec << std::numeric_limits<float>::has_denorm_loss << std::endl; out << "#define FLT_HAS_DENORM_LOSS " << std::dec << std::numeric_limits<float>::has_denorm_loss << std::endl;
flt << "#define FLT_ROUNDS " << std::dec << std::numeric_limits<float>::round_style << std::endl; out << "#define FLT_ROUNDS " << std::dec << std::numeric_limits<float>::round_style << std::endl;
flt << "#define FLT_IS_IEC559 " << std::dec << std::numeric_limits<float>::is_iec559 << std::endl; out << "#define FLT_IS_IEC559 " << std::dec << std::numeric_limits<float>::is_iec559 << std::endl;
flt << "#define FLT_MANT_DIG " << std::dec << std::numeric_limits<float>::digits << std::endl; out << "#define FLT_MANT_DIG " << std::dec << std::numeric_limits<float>::digits << std::endl;
flt << "#define FLT_DIG " << std::dec << std::numeric_limits<float>::digits10 << std::endl; out << "#define FLT_DIG " << std::dec << std::numeric_limits<float>::digits10 << std::endl;
flt << "#define FLT_DECIMAL_DIG " << std::dec << std::numeric_limits<float>::max_digits10 << std::endl; out << "#define FLT_DECIMAL_DIG " << std::dec << std::numeric_limits<float>::max_digits10 << std::endl;
flt << "#define FLT_RADIX " << std::dec << std::numeric_limits<float>::radix << std::endl; out << "#define FLT_RADIX " << std::dec << std::numeric_limits<float>::radix << std::endl;
flt << "#define FLT_MIN_EXP " << std::dec << std::numeric_limits<float>::min_exponent << std::endl; out << "#define FLT_MIN_EXP " << std::dec << std::numeric_limits<float>::min_exponent << std::endl;
flt << "#define FLT_MAX_EXP " << std::dec << std::numeric_limits<float>::max_exponent << std::endl; out << "#define FLT_MAX_EXP " << std::dec << std::numeric_limits<float>::max_exponent << std::endl;
flt << "#define FLT_MIN_10_EXP " << std::dec << std::numeric_limits<float>::min_exponent10 << std::endl; out << "#define FLT_MIN_10_EXP " << std::dec << std::numeric_limits<float>::min_exponent10 << std::endl;
flt << "#define FLT_MAX_10_EXP " << std::dec << std::numeric_limits<float>::max_exponent10 << std::endl; out << "#define FLT_MAX_10_EXP " << std::dec << std::numeric_limits<float>::max_exponent10 << std::endl;
flt << "#define FLT_TRAPS " << std::dec << std::numeric_limits<float>::traps << std::endl; out << "#define FLT_TRAPS " << std::dec << std::numeric_limits<float>::traps << std::endl;
flt << "#define FLT_TINYNESS_BEFORE " << std::dec << std::numeric_limits<float>::tinyness_before << std::endl; out << "#define FLT_TINYNESS_BEFORE " << std::dec << std::numeric_limits<float>::tinyness_before << std::endl;
flt << "#define FLT_MIN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::min() ) << ")" << std::endl; out << "#define FLT_MIN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::min() ) << ")" << std::endl;
flt << "#define FLT_MAX " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::max() ) << ")" << std::endl; out << "#define FLT_MAX " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::max() ) << ")" << std::endl;
flt << "#define FLT_EPSILON " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::epsilon() ) << ")" << std::endl; out << "#define FLT_EPSILON " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::epsilon() ) << ")" << std::endl;
flt << "#define FLT_INF " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::infinity() ) << ")" << std::endl; out << "#define FLT_INF " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::infinity() ) << ")" << std::endl;
flt << "#define FLT_QUIET_NAN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::quiet_NaN() ) << ")" << std::endl; out << "#define FLT_QUIET_NAN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::quiet_NaN() ) << ")" << std::endl;
flt << "#define FLT_SIGNALING_NAN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::signaling_NaN()) << ")" << std::endl; out << "#define FLT_SIGNALING_NAN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::signaling_NaN()) << ")" << std::endl;
flt << "#define FLT_DENORM_MIN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::denorm_min() ) << ")" << std::endl; out << "#define FLT_DENORM_MIN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::denorm_min() ) << ")" << std::endl;
flt << "#define FLT_ROUND_ERR " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::round_error() ) << ")" << std::endl; out << "#define FLT_ROUND_ERR " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::round_error() ) << ")" << std::endl;
flt << "" << std::endl; out << "" << std::endl;
flt << "#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;
flt << "#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;
flt << "#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;
flt << "#define DBL_HAS_DENORM " << std::dec << std::numeric_limits<double>::has_denorm << std::endl; out << "#define DBL_HAS_DENORM " << std::dec << std::numeric_limits<double>::has_denorm << std::endl;
flt << "#define DBL_HAS_DENORM_LOSS " << std::dec << std::numeric_limits<double>::has_denorm_loss << std::endl; out << "#define DBL_HAS_DENORM_LOSS " << std::dec << std::numeric_limits<double>::has_denorm_loss << std::endl;
flt << "#define DBL_ROUNDS " << std::dec << std::numeric_limits<double>::round_style << std::endl; out << "#define DBL_ROUNDS " << std::dec << std::numeric_limits<double>::round_style << std::endl;
flt << "#define DBL_IS_IEC559 " << std::dec << std::numeric_limits<double>::is_iec559 << std::endl; out << "#define DBL_IS_IEC559 " << std::dec << std::numeric_limits<double>::is_iec559 << std::endl;
flt << "#define DBL_MANT_DIG " << std::dec << std::numeric_limits<double>::digits << std::endl; out << "#define DBL_MANT_DIG " << std::dec << std::numeric_limits<double>::digits << std::endl;
flt << "#define DBL_DIG " << std::dec << std::numeric_limits<double>::digits10 << std::endl; out << "#define DBL_DIG " << std::dec << std::numeric_limits<double>::digits10 << std::endl;
flt << "#define DBL_DECIMAL_DIG " << std::dec << std::numeric_limits<double>::max_digits10 << std::endl; out << "#define DBL_DECIMAL_DIG " << std::dec << std::numeric_limits<double>::max_digits10 << std::endl;
flt << "#define DBL_RADIX " << std::dec << std::numeric_limits<double>::radix << std::endl; out << "#define DBL_RADIX " << std::dec << std::numeric_limits<double>::radix << std::endl;
flt << "#define DBL_MIN_EXP " << std::dec << std::numeric_limits<double>::min_exponent << std::endl; out << "#define DBL_MIN_EXP " << std::dec << std::numeric_limits<double>::min_exponent << std::endl;
flt << "#define DBL_MAX_EXP " << std::dec << std::numeric_limits<double>::max_exponent << std::endl; out << "#define DBL_MAX_EXP " << std::dec << std::numeric_limits<double>::max_exponent << std::endl;
flt << "#define DBL_MIN_10_EXP " << std::dec << std::numeric_limits<double>::min_exponent10 << std::endl; out << "#define DBL_MIN_10_EXP " << std::dec << std::numeric_limits<double>::min_exponent10 << std::endl;
flt << "#define DBL_MAX_10_EXP " << std::dec << std::numeric_limits<double>::max_exponent10 << std::endl; out << "#define DBL_MAX_10_EXP " << std::dec << std::numeric_limits<double>::max_exponent10 << std::endl;
flt << "#define DBL_TRAPS " << std::dec << std::numeric_limits<double>::traps << std::endl; out << "#define DBL_TRAPS " << std::dec << std::numeric_limits<double>::traps << std::endl;
flt << "#define DBL_TINYNESS_BEFORE " << std::dec << std::numeric_limits<double>::tinyness_before << std::endl; out << "#define DBL_TINYNESS_BEFORE " << std::dec << std::numeric_limits<double>::tinyness_before << std::endl;
flt << "#define DBL_MIN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::min() ) << "l)" << std::endl; out << "#define DBL_MIN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::min() ) << "l)" << std::endl;
flt << "#define DBL_MAX " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::max() ) << "l)" << std::endl; out << "#define DBL_MAX " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::max() ) << "l)" << std::endl;
flt << "#define DBL_EPSILON " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::epsilon() ) << "l)" << std::endl; out << "#define DBL_EPSILON " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::epsilon() ) << "l)" << std::endl;
flt << "#define DBL_INF " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::infinity() ) << "l)" << std::endl; out << "#define DBL_INF " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::infinity() ) << "l)" << std::endl;
flt << "#define DBL_QUIET_NAN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::quiet_NaN() ) << "l)" << std::endl; out << "#define DBL_QUIET_NAN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::quiet_NaN() ) << "l)" << std::endl;
flt << "#define DBL_SIGNALING_NAN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::signaling_NaN()) << "l)" << std::endl; out << "#define DBL_SIGNALING_NAN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::signaling_NaN()) << "l)" << std::endl;
flt << "#define DBL_DENORM_MIN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::denorm_min() ) << "l)" << std::endl; out << "#define DBL_DENORM_MIN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::denorm_min() ) << "l)" << std::endl;
flt << "#define DBL_ROUND_ERR " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::round_error() ) << "l)" << std::endl; out << "#define DBL_ROUND_ERR " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::round_error() ) << "l)" << std::endl;
flt << "" << std::endl; out << "" << std::endl;
flt << "#endif // FENNEC_LANG_FLOAT_H" << std::endl; out << "#endif // FENNEC_LANG_FLOAT_H" << std::endl;
flt.close(); out.close();
return 0; return;
} }
#endif //FLOAT_H #endif //FLOAT_H

253
metaprogramming/integer.h Normal file
View File

@ -0,0 +1,253 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#ifndef FENNEC_METAPROGRAMMING_INTEGER_H
#define FENNEC_METAPROGRAMMING_INTEGER_H
#include <fstream>
inline void integer_h()
{
std::ofstream out("integer.h");
out << "// =====================================================================================================================" << std::endl;
out << "// fennec, a free and open source game engine" << std::endl;
out << "// Copyright © 2025 Medusa Slockbower" << std::endl;
out << "//" << std::endl;
out << "// This program is free software: you can redistribute it and/or modify" << std::endl;
out << "// it under the terms of the GNU General Public License as published by" << std::endl;
out << "// the Free Software Foundation, either version 3 of the License, or" << std::endl;
out << "// (at your option) any later version." << std::endl;
out << "//" << std::endl;
out << "// This program is distributed in the hope that it will be useful," << std::endl;
out << "// but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl;
out << "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl;
out << "// GNU General Public License for more details." << std::endl;
out << "//" << std::endl;
out << "// You should have received a copy of the GNU General Public License" << std::endl;
out << "// along with this program. If not, see <https://www.gnu.org/licenses/>." << std::endl;
out << "// =====================================================================================================================" << std::endl;
out << "" << std::endl;
out << "///" << std::endl;
out << "/// \\file integer.h" << std::endl;
out << "/// \\brief metaprogramming integer type info" << std::endl;
out << "///" << std::endl;
out << "///" << std::endl;
out << "/// \\details this file is automatically generated for the current build environment" << std::endl;
out << "///" << std::endl;
out << "/// \\copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))" << std::endl;
out << "///" << std::endl;
out << "///" << std::endl;
out << "" << std::endl;
out << "#ifndef FENNEC_LANG_INTEGER_H" << std::endl;
out << "#define FENNEC_LANG_INTEGER_H" << std::endl;
out << "" << std::endl;
out << "#undef WCHAR_MIN" << std::endl;
out << "#undef WCHAR_MAX" << std::endl;
out << "" << std::endl;
// 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;
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_MAX " << "0x" << std::hex << (int)std::numeric_limits<char>::max() << std::endl;
}
else {
out << "#define CHAR_ROUNDS " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::round_style << std::endl;
out << "#define CHAR_RADIX_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::digits << 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_MAX " << "0x" << std::hex << (unsigned int)std::numeric_limits<char>::max() << std::endl;
}
out << "" << 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_MAX " << "0x" << std::hex << (int)std::numeric_limits<wchar_t>::max() << std::endl;
}
else {
out << "#define WCHAR_ROUNDS " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::round_style << std::endl;
out << "#define WCHAR_RADIX_DIG " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::digits << 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_MAX " << "0x" << std::hex << (unsigned int)std::numeric_limits<wchar_t>::max() << std::endl;
}
out << "" << std::endl;
out << "#define SCHAR_ROUNDS " << "0x" << std::hex << (int)std::numeric_limits<signed char>::round_style << std::endl;
out << "#define SCHAR_RADIX_DIG " << "0x" << std::hex << (int)std::numeric_limits<signed char>::digits << std::endl;
out << "#define SCHAR_DIG " << "0x" << std::hex << (int)std::numeric_limits<signed char>::digits10 << std::endl;
out << "#define SCHAR_DECIMAL_DIG " << "0x" << std::hex << (int)std::numeric_limits<signed char>::max_digits10 << 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_MIN " << "0x" << std::hex << (int)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 << "" << std::endl;
out << "#define UCHAR_ROUNDS " << "0x" << std::hex << (unsigned int)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_DIG " << "0x" << std::hex << (unsigned int)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_RADIX " << "0x" << std::hex << (unsigned int)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_MIN " << "0x" << std::hex << (unsigned int)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 << "" << std::endl;
out << "#define SHORT_ROUNDS " << "0x" << std::hex << std::numeric_limits<short>::round_style << std::endl;
out << "#define SHORT_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<short>::digits << std::endl;
out << "#define SHORT_DIG " << "0x" << std::hex << std::numeric_limits<short>::digits10 << std::endl;
out << "#define SHORT_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<short>::max_digits10 << std::endl;
out << "#define SHORT_RADIX " << "0x" << std::hex << std::numeric_limits<short>::radix << std::endl;
out << "#define SHORT_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<short>::traps << std::endl;
out << "#define SHORT_MIN " << "0x" << std::hex << std::numeric_limits<short>::min() << std::endl;
out << "#define SHORT_MAX " << "0x" << std::hex << std::numeric_limits<short>::max() << std::endl;
out << "" << std::endl;
out << "#define USHORT_ROUNDS " << "0x" << std::hex << std::numeric_limits<unsigned short>::round_style << std::endl;
out << "#define USHORT_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<unsigned short>::digits << std::endl;
out << "#define USHORT_DIG " << "0x" << std::hex << std::numeric_limits<unsigned short>::digits10 << std::endl;
out << "#define USHORT_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<unsigned short>::max_digits10 << std::endl;
out << "#define USHORT_RADIX " << "0x" << std::hex << std::numeric_limits<unsigned short>::radix << std::endl;
out << "#define USHORT_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<unsigned short>::traps << std::endl;
out << "#define USHORT_MIN " << "0x" << std::hex << std::numeric_limits<unsigned short>::min() << std::endl;
out << "#define USHORT_MAX " << "0x" << std::hex << std::numeric_limits<unsigned short>::max() << std::endl;
out << "" << std::endl;
out << "#define INT_ROUNDS " << "0x" << std::hex << std::numeric_limits<int>::round_style << std::endl;
out << "#define INT_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<int>::digits << std::endl;
out << "#define INT_DIG " << "0x" << std::hex << std::numeric_limits<int>::digits10 << std::endl;
out << "#define INT_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<int>::max_digits10 << std::endl;
out << "#define INT_RADIX " << "0x" << std::hex << std::numeric_limits<int>::radix << std::endl;
out << "#define INT_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<int>::traps << std::endl;
out << "#define INT_MIN " << "0x" << std::hex << std::numeric_limits<int>::min() << std::endl;
out << "#define INT_MAX " << "0x" << std::hex << std::numeric_limits<int>::max() << std::endl;
out << "" << std::endl;
out << "#define UINT_ROUNDS " << "0x" << std::hex << std::numeric_limits<unsigned int>::round_style << std::endl;
out << "#define UINT_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<unsigned int>::digits << std::endl;
out << "#define UINT_DIG " << "0x" << std::hex << std::numeric_limits<unsigned int>::digits10 << std::endl;
out << "#define UINT_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<unsigned int>::max_digits10 << std::endl;
out << "#define UINT_RADIX " << "0x" << std::hex << std::numeric_limits<unsigned int>::radix << std::endl;
out << "#define UINT_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<unsigned int>::traps << std::endl;
out << "#define UINT_MIN " << "0x" << std::hex << std::numeric_limits<unsigned int>::min() << std::endl;
out << "#define UINT_MAX " << "0x" << std::hex << std::numeric_limits<unsigned int>::max() << std::endl;
out << "" << std::endl;
out << "#define LONG_ROUNDS " << "0x" << std::hex << std::numeric_limits<long int>::round_style << std::endl;
out << "#define LONG_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<long int>::digits << std::endl;
out << "#define LONG_DIG " << "0x" << std::hex << std::numeric_limits<long int>::digits10 << std::endl;
out << "#define LONG_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<long int>::max_digits10 << std::endl;
out << "#define LONG_RADIX " << "0x" << std::hex << std::numeric_limits<long int>::radix << std::endl;
out << "#define LONG_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<long int>::traps << std::endl;
out << "#define LONG_MIN " << "0x" << std::hex << std::numeric_limits<long int>::min() << std::endl;
out << "#define LONG_MAX " << "0x" << std::hex << std::numeric_limits<long int>::max() << std::endl;
out << "" << std::endl;
out << "#define ULONG_ROUNDS " << "0x" << std::hex << std::numeric_limits<unsigned long int>::round_style << std::endl;
out << "#define ULONG_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<unsigned long int>::digits << std::endl;
out << "#define ULONG_DIG " << "0x" << std::hex << std::numeric_limits<unsigned long int>::digits10 << std::endl;
out << "#define ULONG_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<unsigned long int>::max_digits10 << std::endl;
out << "#define ULONG_RADIX " << "0x" << std::hex << std::numeric_limits<unsigned long int>::radix << std::endl;
out << "#define ULONG_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<unsigned long int>::traps << std::endl;
out << "#define ULONG_MIN " << "0x" << std::hex << std::numeric_limits<unsigned long int>::min() << std::endl;
out << "#define ULONG_MAX " << "0x" << std::hex << std::numeric_limits<unsigned long int>::max() << std::endl;
out << "" << std::endl;
out << "#define LLONG_ROUNDS " << "0x" << std::hex << std::numeric_limits<long long>::round_style << std::endl;
out << "#define LLONG_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<long long>::digits << std::endl;
out << "#define LLONG_DIG " << "0x" << std::hex << std::numeric_limits<long long>::digits10 << std::endl;
out << "#define LLONG_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<long long>::max_digits10 << std::endl;
out << "#define LLONG_RADIX " << "0x" << std::hex << std::numeric_limits<long long>::radix << std::endl;
out << "#define LLONG_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<long long>::traps << std::endl;
out << "#define LLONG_MIN " << "0x" << std::hex << std::numeric_limits<long long>::min() << std::endl;
out << "#define LLONG_MAX " << "0x" << std::hex << std::numeric_limits<long long>::max() << std::endl;
out << "" << std::endl;
out << "#define ULLONG_ROUNDS " << "0x" << std::hex << std::numeric_limits<unsigned long long>::round_style << std::endl;
out << "#define ULLONG_RADIX_DIG " << "0x" << std::hex << std::numeric_limits<unsigned long long>::digits << std::endl;
out << "#define ULLONG_DIG " << "0x" << std::hex << std::numeric_limits<unsigned long long>::digits10 << std::endl;
out << "#define ULLONG_DECIMAL_DIG " << "0x" << std::hex << std::numeric_limits<unsigned long long>::max_digits10 << std::endl;
out << "#define ULLONG_RADIX " << "0x" << std::hex << std::numeric_limits<unsigned long long>::radix << std::endl;
out << "#define ULLONG_TRAPS " << "0x" << std::boolalpha << std::numeric_limits<unsigned long long>::traps << std::endl;
out << "#define ULLONG_MIN " << "0x" << std::hex << std::numeric_limits<unsigned long long>::min() << std::endl;
out << "#define ULLONG_MAX " << "0x" << std::hex << std::numeric_limits<unsigned long long>::max() << std::endl;
out << "" << std::endl;
out << "#endif // FENNEC_LANG_INTEGER_H" << std::endl;
out.close();
return;
}
#endif // FENNEC_METAPROGRAMMING_INTEGER_H

View File

@ -19,6 +19,11 @@
#include <fstream> #include <fstream>
#include <cmath> #include <cmath>
#include "float.h"
#include "integer.h"
int main(int, const char**) int main(int, const char**)
{ {
float_h();
integer_h();
} }