- Basic RTTI type data with inheritance.
This commit is contained in:
@@ -1,284 +0,0 @@
|
||||
// =====================================================================================================================
|
||||
// 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 intrinsics.h
|
||||
/// \brief \ref fennec_lang_intrinsics
|
||||
///
|
||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||
///
|
||||
///
|
||||
|
||||
#ifndef 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.
|
||||
///
|
||||
/// \code{.cpp}#include <fennec/lang/intrinsics.h>\endcode
|
||||
///
|
||||
///
|
||||
/// <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, and CLANG
|
||||
#if defined(__has_builtin)
|
||||
|
||||
// addressof is very difficult to implement without intrinsics.
|
||||
#if __has_builtin(__builtin_addressof)
|
||||
# define FENNEC_HAS_BUILTIN_ADDRESSOF 1
|
||||
# define FENNEC_BUILTIN_ADDRESSOF(arg) __builtin_addressof(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_ADDRESSOF 0
|
||||
#endif
|
||||
|
||||
// bitcast is slightly more efficient for build times than using memcpy
|
||||
#if __has_builtin(__builtin_bit_cast)
|
||||
# define FENNEC_HAS_BUILTIN_BIT_CAST 1
|
||||
# define FENNEC_BUILTIN_BIT_CAST(type, arg) __builtin_bit_cast(type, arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_BIT_CAST 0
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_abstract)
|
||||
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 1
|
||||
# define FENNEC_BUILTIN_IS_ABSTRACT(arg) __is_abstract(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 0
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_array)
|
||||
# define FENNEC_HAS_BUILTIN_IS_ARRAY 1
|
||||
# define FENNEC_BUILTIN_IS_ARRAY(arg) __is_array(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_ARRAY
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_class)
|
||||
# define FENNEC_HAS_BUILTIN_IS_CLASS 1
|
||||
# define FENNEC_BUILTIN_IS_CLASS(arg) __is_class(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_CLASS
|
||||
#endif
|
||||
|
||||
// CONSTRUCTORS ========================================================================================================
|
||||
|
||||
// Difficult and Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_constructible)
|
||||
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 1
|
||||
# define FENNEC_BUILTIN_IS_CONSTRUCTIBLE(type, ...) __is_constructible(type __VA_OPT__(,) __VA_ARGS__)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 0
|
||||
#endif
|
||||
|
||||
// Difficult and Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_trivially_constructible)
|
||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 1
|
||||
# define FENNEC_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE(type) __is_trivially_constructible(type)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 0
|
||||
#endif
|
||||
|
||||
// Difficult and Inconsistent without intrinsics
|
||||
#if __has_builtin(__has_trivial_destructor)
|
||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 1
|
||||
# define FENNEC_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE(type) __has_trivial_destructor(type)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 0
|
||||
#endif
|
||||
|
||||
|
||||
// ASSIGNMENTS =========================================================================================================
|
||||
|
||||
// Difficult and Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_assignable)
|
||||
# define FENNEC_HAS_BUILTIN_IS_ASSIGNABLE 1
|
||||
# define FENNEC_BUILTIN_IS_ASSIGNABLE(a, b) __is_assignable(a, b)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_ASSIGNABLE 0
|
||||
#endif
|
||||
|
||||
|
||||
// Type Traits
|
||||
// can_convert is also very difficult to implement without intrinsics
|
||||
#if __has_builtin(__is_convertible)
|
||||
# define FENNEC_HAS_BUILTIN_IS_CONVERTIBLE 1
|
||||
# define FENNEC_BUILTIN_IS_CONVERTIBLE(arg0, arg1) __is_convertible(arg0, arg1)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_CONVERTIBLE 0
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics.
|
||||
#if __has_builtin(__is_empty)
|
||||
# define FENNEC_HAS_BUILTIN_IS_EMPTY 1
|
||||
# define FENNEC_BUILTIN_IS_EMPTY(arg) __is_empty(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_EMPTY 0
|
||||
|
||||
// Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_final)
|
||||
# define FENNEC_HAS_BUILTIN_IS_FINAL 1
|
||||
# define FENNEC_BUILTIN_IS_FINAL(arg) __is_final(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_FINAL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics.
|
||||
#if __has_builtin(__is_enum)
|
||||
# define FENNEC_HAS_BUILTIN_IS_ENUM 1
|
||||
# define FENNEC_BUILTIN_IS_ENUM(arg) __is_enum(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_ENUM 0
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_final)
|
||||
# define FENNEC_HAS_BUILTIN_IS_FINAL 1
|
||||
# define FENNEC_BUILTIN_IS_FINAL(arg) __is_final(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_FINAL 0
|
||||
#endif
|
||||
|
||||
// Inconsistent with dynamic intrinsics, requires a massive table for static intrinsics
|
||||
#if __has_builtin(__is_fundamental)
|
||||
# define FENNEC_HAS_BUILTIN_IS_FUNDAMENTAL 1
|
||||
# define FENNEC_BUILTIN_IS_FUNDAMENTAL(arg) __is_fundamental(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_FUNDAMENTAL 0
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_polymorphic)
|
||||
# define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 1
|
||||
# define FENNEC_BUILTIN_IS_POLYMORPHIC(arg) __is_polymorphic(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 0
|
||||
#endif
|
||||
|
||||
// Impossible without instrinsics
|
||||
#if __has_builtin(__is_standard_layout)
|
||||
# define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 1
|
||||
# define FENNEC_BUILTIN_IS_STANDARD_LAYOUT(arg) __is_standard_layout(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 0
|
||||
#endif
|
||||
|
||||
|
||||
// For compilers without or differently named builtins
|
||||
#else
|
||||
|
||||
// TODO: More compiler support
|
||||
|
||||
#if FENNEC_COMPILER_MSVC
|
||||
|
||||
# define FENNEC_HAS_BUILTIN_ADDRESS_OF 1
|
||||
# define FENNEC_BUILTIN_ADDRESS_OF(arg) __builtin_addressof(arg)
|
||||
|
||||
# define FENNEC_HAS_BUILTIN_BIT_CAST 1
|
||||
# define FENNEC_BUILTIN_BIT_CAST(type, arg) __builtin_bit_cast(type, arg)
|
||||
|
||||
# define FENNEC_HAS_BUILTIN_IS_CONVERTIBLE 1
|
||||
# define FENNEC_BUILTIN_IS_CONVERTIBLE(arg0, arg1) __is_convertible_to(arg0, arg1)
|
||||
|
||||
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 1
|
||||
# define FENNEC_BUILTIN_IS_CONSTRUCTIBLE(...) __is_constructible(__VA_ARGS__)
|
||||
|
||||
# define FENNEC_HAS_BUILTIN_IS_EMPTY 1
|
||||
# define FENNEC_BUILTIN_IS_EMPTY(arg) __is_empty(arg)
|
||||
|
||||
# define FENNEC_HAS_BUILTIN_IS_FINAL 1
|
||||
# define FENNEC_BUILTIN_IS_FINAL(arg) __is_final(arg)
|
||||
|
||||
# define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 1
|
||||
# define FENNEC_BUILTIN_IS_POLYMORPHIC(arg) __is_polymorphic(arg)
|
||||
|
||||
# define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 1
|
||||
# define FENNEC_BUILTIN_IS_STANDARD_LAYOUT(arg) __is_standard_layout(arg)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // FENNEC_LANG_INTRINSICS_H
|
||||
Reference in New Issue
Block a user