- Started setting up a thread safe window manager

- Created thread & atomic structures
This commit is contained in:
2025-12-17 01:11:28 -05:00
parent 520a0e1363
commit aee4e340dd
41 changed files with 2179 additions and 428 deletions

View File

@@ -0,0 +1,45 @@
// =====================================================================================================================
// 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 _function.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_LANG_DETAIL_FUNCTION_H
#define FENNEC_LANG_DETAIL_FUNCTION_H
#include <fennec/lang/utility.h>
namespace fennec::detail
{
}
#endif // FENNEC_LANG_DETAIL_FUNCTION_H

View File

@@ -55,6 +55,12 @@ namespace fennec::detail
template<> struct _is_integral<llong_t> : true_type {};
template<> struct _is_integral<ullong_t> : true_type {};
template<typename> struct _is_const : false_type {};
template<typename T> struct _is_const<const T> : true_type {};
template<typename> struct _is_volatile : false_type {};
template<typename T> struct _is_volatile<volatile T> : true_type {};
// Most unsigned types will underflow `-1` to the types maximum value
template<typename TypeT> struct _is_signed : bool_constant<TypeT(-1) < TypeT(0)> {};
template<typename TypeT> struct _is_unsigned : bool_constant<TypeT(-1) >= TypeT(0)> {};

View File

@@ -20,9 +20,39 @@
#define FENNEC_LANG_DETAIL_TYPE_TRANSFORMS_H
#include <fennec/lang/types.h>
#include <fennec/lang/detail/_type_traits.h>
namespace fennec::detail
{
template<typename TypeT> struct _add_pointer : type_identity<TypeT*> {};
template<typename TypeT> struct _remove_pointer : type_identity<TypeT> {};
template<typename TypeT> struct _remove_pointer<TypeT*> : type_identity<TypeT> {};
template<typename TypeT> struct _add_const : type_identity<const TypeT> {};
template<typename TypeT> struct _remove_const : type_identity<TypeT> {};
template<typename TypeT> struct _remove_const<const TypeT> : type_identity<TypeT> {};
template<typename TypeT> struct _add_volatile : type_identity<volatile TypeT> {};
template<typename TypeT> struct _remove_volatile : type_identity<TypeT> {};
template<typename TypeT> struct _remove_volatile<volatile TypeT> : type_identity<TypeT> {};
template<typename TypeT> struct _add_cv : _add_const<typename _add_volatile<TypeT>::type> {};
template<typename TypeT> struct _remove_cv : type_identity<TypeT> {};
template<typename TypeT> struct _remove_cv<const TypeT> : type_identity<TypeT> {};
template<typename TypeT> struct _remove_cv<volatile TypeT> : type_identity<TypeT> {};
template<typename TypeT> struct _remove_cv<const volatile TypeT> : type_identity<TypeT> {};
template<typename TypeT>
struct _decay : conditional<_is_const<const TypeT>{}, _remove_cv<TypeT>, _add_pointer<TypeT>> {};
template<typename TypeT> requires requires { typename TypeT::element_t; }
struct _decay<TypeT> : type_identity<typename TypeT::decay_t> {};
template<typename TypeT, size_t N>
struct _decay<TypeT[N]> : type_identity<TypeT*> {};
template<typename TypeT>
struct _decay<TypeT[]> : type_identity<TypeT*> {};
template<typename _Tp, typename = void>
struct _add_lvalue_reference {

View File

@@ -0,0 +1,87 @@
// =====================================================================================================================
// 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 function.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_LANG_FUNCTION_H
#define FENNEC_LANG_FUNCTION_H
#include <fennec/lang/types.h>
#include <fennec/lang/assert.h>
#include <fennec/lang/utility.h>
#include <fennec/lang/detail/_function.h>
namespace fennec
{
template<typename> class function;
template<typename ReturnT, typename...ArgsT>
class function<ReturnT(ArgsT...)> {
public:
constexpr function() noexcept = default;
constexpr ~function() = default;
constexpr function(const function&) noexcept = default;
constexpr function( function&&) noexcept = default;
constexpr function(ReturnT (*func)(ArgsT...))
: call(func) {
}
constexpr function(nullptr_t) noexcept : function() {}
constexpr function& operator=(const function&) = default;
constexpr function& operator=(function&&) = default;
constexpr function& operator=(nullptr_t) {
call = nullptr;
return *this;
}
constexpr function& operator=(ReturnT (*func)(ArgsT...)) {
call = func;
return *this;
}
constexpr operator bool() const noexcept { return call != nullptr; }
ReturnT operator()(ArgsT...args) const noexcept {
assertf(call != nullptr, "Attempted to call a null function object!");
return call(fennec::forward<ArgsT>(args)...);
}
private:
ReturnT (*call)(ArgsT&&...) { nullptr };
};
}
#endif // FENNEC_LANG_FUNCTION_H

View File

@@ -21,6 +21,7 @@
#include <fennec/lang/types.h>
#include <fennec/lang/type_traits.h>
#include <fennec/lang/bits.h>
namespace fennec
{

View File

@@ -176,6 +176,27 @@
# define FENNEC_HAS_BUILTIN_IS_CLASS
#endif
#if __has_builtin(__is_member_pointer)
# define FENNEC_HAS_BUILTIN_IS_MEMBER_POINTER 1
# define FENNEC_BUILTIN_IS_MEMBER_POINTER(arg) __is_member_pointer(arg)
#else
# define FENNEC_HAS_BUILTIN_IS_MEMBER_POINTER 0
#endif
#if __has_builtin(__is_member_function_pointer)
# define FENNEC_HAS_BUILTIN_IS_MEMBER_FUNCTION_POINTER 1
# define FENNEC_BUILTIN_IS_MEMBER_FUNCTION_POINTER(arg) __is_member_function_pointer(arg)
#else
# define FENNEC_HAS_BUILTIN_IS_MEMBER_FUNCTION_POINTER 0
#endif
#if __has_builtin(__is_member_object_pointer)
# define FENNEC_HAS_BUILTIN_IS_MEMBER_OBJECT_POINTER 1
# define FENNEC_BUILTIN_IS_MEMBER_OBJECT_POINTER(arg) __is_member_object_pointer(arg)
#else
# define FENNEC_HAS_BUILTIN_IS_MEMBER_OBJECT_POINTER 0
#endif
// CONSTRUCTORS ========================================================================================================
@@ -214,6 +235,38 @@
# define FENNEC_HAS_BUILTIN_IS_ASSIGNABLE 0
#endif
// Inconsistent without intrinsics
#if __has_builtin(__is_trivial)
# define FENNEC_HAS_BUILTIN_IS_TRIVIAL 1
# define FENNEC_BUILTIN_IS_TRIVIAL(a) __is_trivial(a)
#else
# define FENNEC_HAS_BUILTIN_IS_TRIVIAL 0
#endif
// Difficult and Inconsistent without intrinsics
#if __has_builtin(__is_trivially_copyable)
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_COPYABLE 1
# define FENNEC_BUILTIN_IS_TRIVIALLY_COPYABLE(a) __is_trivially_copyable(a)
#else
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_COPYABLE 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
// Impossible without instrinsics
#if __has_builtin(__has_unique_object_representations)
# define FENNEC_HAS_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS 1
# define FENNEC_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS(arg) __has_unique_object_representations(arg)
#else
# define FENNEC_HAS_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS 0
#endif
// Type Traits
// can_convert is also very difficult to implement without intrinsics
@@ -264,6 +317,22 @@
# define FENNEC_HAS_BUILTIN_IS_FINAL 0
#endif
// Inconsistent without intrinsics
#if __has_builtin(__is_aggregate)
# define FENNEC_HAS_BUILTIN_IS_AGGREGATE 1
# define FENNEC_BUILTIN_IS_AGGREGATE(arg) __is_aggregate(arg)
#else
# define FENNEC_HAS_BUILTIN_IS_AGGREGATE 0
#endif
// Inconsistent without intrinsics
#if __has_builtin(__builtin_is_implicit_lifetime)
# define FENNEC_HAS_BUILTIN_IS_IMPLICIT_LIFETIME 1
# define FENNEC_BUILTIN_IS_IMPLICIT_LIFETIME(arg) __builtin_is_implicit_lifetime(arg)
#else
# define FENNEC_HAS_BUILTIN_IS_IMPLICIT_LIFETIME 0
#endif
// Inconsistent without intrinsics
#if __has_builtin(__is_function)
# define FENNEC_HAS_BUILTIN_IS_FUNCTION 1
@@ -288,14 +357,6 @@
# 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

View File

@@ -147,18 +147,18 @@
/// <th style="vertical-align: top">Description
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::is_fundamental "is_fundamental<TypeT>::value"<br>
/// \ref fennec::is_fundamental_v "is_fundamental_v<TypeT>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::is_fundamental
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::is_arithmetic "is_arithmetic<TypeT>::value"<br>
/// \ref fennec::is_arithmetic_v "is_arithmetic_v<TypeT>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::is_arithmetic
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::is_fundamental "is_fundamental<TypeT>::value"<br>
/// \ref fennec::is_fundamental_v "is_fundamental_v<TypeT>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::is_fundamental
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::is_scalar "is_scalar<TypeT>::value"<br>
/// \ref fennec::is_scalar_v "is_scalar_v<TypeT>"
/// <td width="50%" style="vertical-align: top">
@@ -271,12 +271,6 @@
/// \copydetails fennec::is_aggregate
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::is_implicit_lifetime "is_implicit_lifetime<TypeT>::value"<br>
/// \ref fennec::is_implicit_lifetime_v "is_implicit_lifetime_v<TypeT>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::is_implicit_lifetime
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::is_signed "is_signed<TypeT>::value"<br>
/// \ref fennec::is_signed_v "is_signed_v<TypeT>"
/// <td width="50%" style="vertical-align: top">
@@ -451,7 +445,7 @@ constexpr inline bool is_constant_evaluated() noexcept {
/// \details Stores a boolean value in `is_void::value`, representing whether the provided type is of base type void.
/// \tparam T type to check
template<typename T> struct is_void
: detail::_is_void<remove_cvr_t<T>>{};
: detail::_is_void<remove_cvref_t<T>>{};
///
/// \brief Shorthand for ```is_void<T>::value```
@@ -468,7 +462,7 @@ template<typename T> constexpr bool_t is_void_v = is_void<T>::value;
/// \details Stores a boolean value in `is_null_pointer::value`, representing whether the provided type is of base type nullptr_t.
/// \tparam T type to check
template<typename T> struct is_null_pointer
: detail::_is_null_pointer<remove_cvr_t<T>>{};
: detail::_is_null_pointer<remove_cvref_t<T>>{};
///
/// \brief Shorthand for ```is_null_pointer<T>::value```
@@ -477,6 +471,57 @@ template<typename T> constexpr bool_t is_null_pointer_v = is_null_pointer<T>::va
// fennec::is_bool =====================================================================================================
///
/// \brief Check if \p T is of type bool
///
/// \details Stores a boolean value in `is_bool::value`, representing whether the provided type is of base type bool.
/// \tparam T type to check
template<typename T> struct is_bool
: detail::_is_bool<remove_cvref_t<T>>{};
///
/// \brief Shorthand for ```is_bool<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_bool_v = is_bool<T>::value;
// fennec::is_integral =================================================================================================
///
/// \brief Check if \p T is of an integral
///
/// \details Stores a boolean value in `is_integral::value`, representing whether the provided type is of a base integer type.
/// \tparam T type to check
template<typename T> struct is_integral
: detail::_is_integral<remove_cvref_t<T>> {};
///
/// \brief Shorthand for ```is_integral<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_integral_v = is_integral<T>::value;
// fennec::is_floating_point ===========================================================================================
///
/// \brief Check if \p T is of a floating point type
///
/// \details Stores a boolean value in `is_floating_point::value`, representing whether the provided type is of a base floating point type.
/// \tparam T type to check
template<typename T> struct is_floating_point
: detail::_is_floating_point<remove_cvref_t<T>>{};
///
/// \brief Shorthand for ```is_floating_point<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_floating_point_v = is_floating_point<T> {};
// fennec::is_array ====================================================================================================
#ifdef FENNEC_BUILTIN_IS_ARRAY
@@ -557,7 +602,7 @@ template<typename T> constexpr size_t is_class_v = is_class<T>::value;
// fennec::is_function ====================================================================================================
// fennec::is_function =================================================================================================
///
/// \brief Check if \p T is a class
@@ -572,41 +617,363 @@ template<typename T> constexpr size_t is_function_v = is_function<T>::value;
// Integral Types ======================================================================================================
// fennec::is_bool =====================================================================================================
// fennec::is_pointer ==================================================================================================
///
/// \brief Check if \p T is of type bool
/// \brief Check if \p T is of a pointer type
///
/// \details Stores a boolean value in `is_bool::value`, representing whether the provided type is of base type bool.
/// \details Stores a boolean value in `is_pointer::value`, representing whether the provided type is of a base pointer type.
/// \tparam T type to check
template<typename T> struct is_bool
: detail::_is_bool<remove_cvr_t<T>>{};
template<typename T> struct is_pointer
: detail::_is_pointer<remove_cvref_t<T>>{};
///
/// \brief Shorthand for ```is_bool<T>::value```
/// \brief Shorthand for ```is_pointer<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_bool_v = is_bool<T>::value;
template<typename T> constexpr bool_t is_pointer_v = is_pointer<T> {};
// fennec::is_integral =================================================================================================
// fennec::is_lvalue_reference =========================================================================================
///
/// \brief Check if \p T is of an integral
/// \brief Check if \p T is of a floating point type
///
/// \details Stores a boolean value in `is_integral::value`, representing whether the provided type is of a base integer type.
/// \details Checks if type `T` is a floating point type and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_integral
: detail::_is_integral<remove_cvr_t<T>> {};
template<typename T> struct is_lvalue_reference
: detail::_is_lvalue_reference<T>{};
///
/// \brief Shorthand for ```is_integral<T>::value```
/// \brief Shorthand for ```is_floating_point<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_integral_v = is_integral<T>::value;
template<typename T> constexpr bool_t is_lvalue_reference_v = is_lvalue_reference<T> {};
// fennec::is_rvalue_reference =========================================================================================
///
/// \brief Check if \p T is of a floating point type
///
/// \details Checks if type `T` is a floating point type and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_rvalue_reference
: detail::_is_rvalue_reference<T>{};
///
/// \brief Shorthand for ```is_floating_point<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_rvalue_reference_v = is_rvalue_reference<T> {};
// fennec::is_member_function_pointer ==================================================================================
///
/// \brief Check if \p T is a pointer to a member function
///
/// \details Checks if type `T` is pointer to a member function and store it in `is_member_function_pointer::value`.
/// \tparam T type to check
template<typename T> struct is_member_function_pointer
: bool_constant<FENNEC_BUILTIN_IS_MEMBER_FUNCTION_POINTER(T)> {};
///
/// \brief Shorthand for ```is_member_function_pointer<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_member_function_pointer_v = is_member_function_pointer<T> {};
// fennec::is_member_object_pointer ====================================================================================
///
/// \brief Check if \p T is a pointer to a member object
///
/// \details Checks if type `T` is pointer to a member object and store it in `is_member_object_pointer::value`.
/// \tparam T type to check
template<typename T> struct is_member_object_pointer
: bool_constant<FENNEC_BUILTIN_IS_MEMBER_OBJECT_POINTER(T)> {};
///
/// \brief Shorthand for ```is_member_object_pointer<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_member_object_pointer_v = is_member_object_pointer<T> {};
// fennec::is_arithmetic ===============================================================================================
///
/// \brief Check if \p T is an arithmetic type
///
/// \details Checks if type `T` is a built-in type with arithmetic operators and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_arithmetic
: bool_constant<is_integral_v<T> or is_floating_point_v<T>>{};
///
/// \brief Shorthand for ```is_arithmetic<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_arithmetic_v = is_arithmetic<T>::value;
// fennec::is_fundamental ==============================================================================================
///
/// \brief Check if \p T is a fundamental type, i.e. arithmetic, void, or nullptr_t
/// \tparam T type to check
template<typename T> struct is_fundamental
: bool_constant<is_arithmetic_v<T> or is_void_v<T> or is_null_pointer_v<T>>{};
///
/// \brief Shorthand for ```is_fundamental<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_fundamental_v = is_fundamental<T>::value;
// fennec::is_scalar ===================================================================================================
///
/// \brief Check if \p T is an arithmetic type
///
/// \details Checks if type `T` is a built-in type with arithmetic operators and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_scalar
: bool_constant<is_arithmetic_v<T> or is_enum_v<T> or is_pointer_v<T>>{};
///
/// \brief Shorthand for ```is_scalar<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_scalar_v = is_scalar<T>::value;
// fennec::is_object ===================================================================================================
///
/// \brief Check if \p T is an object
///
/// \details Checks if type `T` is an object and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_object : bool_constant<FENNEC_BUILTIN_IS_OBJECT(T)> {};
///
/// \brief Shorthand for ```is_object<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_object_v = is_object<T>::value;
// fennec::is_compound =================================================================================================
///
/// \brief Check if \p T is a object compound type
///
/// \details Checks if type `T` is an object and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_compound : bool_constant<not is_fundamental_v<T>> {};
///
/// \brief Shorthand for ```is_compound<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_compound_v = is_compound<T>::value;
// fennec::is_reference ================================================================================================
///
/// \brief Check if \p T is of a floating point type
///
/// \details Checks if type `T` is a floating point type and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_reference
: detail::_is_reference<T>{};
///
/// \brief Shorthand for ```is_floating_point<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_reference_v = is_reference<T> {};
// fennec::is_member_pointer ===========================================================================================
///
/// \brief Check if \p T is a pointer to a member
///
/// \details Checks if type `T` is pointer to a member and store it in `is_member_function_pointer::value`.
/// \tparam T type to check
template<typename T> struct is_member_pointer
: bool_constant<FENNEC_BUILTIN_IS_MEMBER_POINTER(T)> {};
///
/// \brief Shorthand for ```is_member_function_pointer<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_member_pointer_v = is_member_pointer<T> {};
// fennec::is_trivial ==================================================================================================
///
/// \brief Check if type `T` is trivial
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_trivial : bool_constant<FENNEC_BUILTIN_IS_TRIVIAL(T)> {};
///
/// \brief Shorthand for `is_trivial<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_trivial_v = is_trivial<T>{};
// fennec::is_trivially_copyable =======================================================================================
///
/// \brief Check if type `T` is trivially_copyable
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_trivially_copyable : bool_constant<FENNEC_BUILTIN_IS_TRIVIALLY_COPYABLE(T)> {};
///
/// \brief Shorthand for `is_trivially_copyable<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_trivially_copyable_v = is_trivially_copyable<T>{};
// fennec::is_standard_layout ==========================================================================================
///
/// \brief Check if type `T` is standard_layout
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_standard_layout : bool_constant<FENNEC_BUILTIN_IS_STANDARD_LAYOUT(T)> {};
///
/// \brief Shorthand for `is_standard_layout<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_standard_layout_v = is_standard_layout<T>{};
// fennec::has_unique_object_representations ===========================================================================
///
/// \brief Check if type `T` has unique object representations
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct has_unique_object_representations
: bool_constant<FENNEC_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS(remove_cv_t<T>)> {};
///
/// \brief Shorthand for `has_unique_object_representations<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t has_unique_object_representations_v = has_unique_object_representations<T>{};
// fennec::is_empty ====================================================================================================
///
/// \brief Check if type `T` is empty
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_empty : bool_constant<FENNEC_BUILTIN_IS_EMPTY(T)> {};
///
/// \brief Shorthand for `is_empty<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_empty_v = is_empty<T>{};
// fennec::is_polymorphic ==============================================================================================
///
/// \brief Check if type `T` is polymorphic
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_polymorphic : bool_constant<FENNEC_BUILTIN_IS_POLYMORPHIC(T)> {};
///
/// \brief Shorthand for `is_polymorphic<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_polymorphic_v = is_polymorphic<T>{};
// fennec::is_abstract =================================================================================================
///
/// \brief Check if type `T` is abstract
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_abstract : bool_constant<FENNEC_BUILTIN_IS_ABSTRACT(T)> {};
///
/// \brief Shorthand for `is_abstract<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_abstract_v = is_abstract<T>{};
// fennec::is_complete =================================================================================================
///
/// \brief Check if type `T` is complete
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_complete : detail::_is_complete<T>::type {};
///
/// \brief Shorthand for `is_complete<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_complete_v = is_complete<T>{};
// fennec::is_final =================================================================================================
///
/// \brief Check if type `T` is final
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_final : bool_constant<FENNEC_BUILTIN_IS_FINAL(T)> {};
///
/// \brief Shorthand for `is_final<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_final_v = is_final<T>{};
// fennec::is_aggregate =================================================================================================
///
/// \brief Check if type `T` is aggregate
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_aggregate : bool_constant<FENNEC_BUILTIN_IS_AGGREGATE(T)> {};
///
/// \brief Shorthand for `is_aggregate<T>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_aggregate_v = is_aggregate<T>{};
@@ -619,7 +986,7 @@ template<typename T> constexpr bool_t is_integral_v = is_integral<T>::value;
/// \details Checks if type `T` is a signed type i.e. `T(-1) < T(0)` and stores it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_signed
: detail::_is_signed<remove_cvr_t<T>> {};
: detail::_is_signed<remove_cvref_t<T>> {};
///
/// \brief Shorthand for ```is_signed<T>::value```
@@ -637,138 +1004,12 @@ template<typename T> constexpr bool_t is_signed_v = is_signed<T>::value;
/// \details Checks if type `T` is an unsigned type i.e. `T(-1) > T(0)` and stores it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_unsigned
: detail::_is_unsigned<remove_cvr_t<T>> {};
: detail::_is_unsigned<remove_cvref_t<T>> {};
///
/// \brief Shorthand for ```is_unsigned<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_unsigned_v = is_unsigned<T>::value;
// Floating Point Types ================================================================================================
///
/// \brief Check if \p T is of a floating point type
///
/// \details Stores a boolean value in `is_floating_point::value`, representing whether the provided type is of a base floating point type.
/// \tparam T type to check
template<typename T> struct is_floating_point
: detail::_is_floating_point<remove_cvr_t<T>>{};
///
/// \brief Shorthand for ```is_floating_point<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_floating_point_v = is_floating_point<T> {};
// Pointer Types =======================================================================================================
///
/// \brief Check if \p T is of a pointer type
///
/// \details Stores a boolean value in `is_pointer::value`, representing whether the provided type is of a base pointer type.
/// \tparam T type to check
template<typename T> struct is_pointer
: detail::_is_pointer<remove_cvr_t<T>>{};
///
/// \brief Shorthand for ```is_pointer<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_pointer_v = is_pointer<T> {};
// Reference Types =======================================================================================================
///
/// \brief Check if \p T is of a floating point type
///
/// \details Checks if type `T` is a floating point type and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_reference
: detail::_is_reference<T>{};
///
/// \brief Shorthand for ```is_floating_point<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_reference_v = is_reference<T> {};
///
/// \brief Check if \p T is of a floating point type
///
/// \details Checks if type `T` is a floating point type and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_lvalue_reference
: detail::_is_lvalue_reference<T>{};
///
/// \brief Shorthand for ```is_floating_point<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_lvalue_reference_v = is_lvalue_reference<T> {};
///
/// \brief Check if \p T is of a floating point type
///
/// \details Checks if type `T` is a floating point type and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_rvalue_reference
: detail::_is_rvalue_reference<T>{};
///
/// \brief Shorthand for ```is_floating_point<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_rvalue_reference_v = is_rvalue_reference<T> {};
// Arithmetic Types ====================================================================================================
///
/// \brief Check if \p T is an arithmetic type
///
/// \details Checks if type `T` is a built-in type with arithmetic operators and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_arithmetic
: bool_constant<is_integral_v<T> or is_floating_point_v<T>>{};
///
/// \brief Shorthand for ```is_arithmetic<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_arithmetic_v = is_arithmetic<T>::value;
// Arithmetic Types ====================================================================================================
///
/// \brief Check if \p T is an arithmetic type
///
/// \details Checks if type `T` is a built-in type with arithmetic operators and store it in `is_same::value`.
/// \tparam T type to check
template<typename T> struct is_scalar
: bool_constant<is_arithmetic_v<T> or is_enum_v<T> or is_pointer_v<T>>{};
///
/// \brief Shorthand for ```is_scalar<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_scalar_v = is_scalar<T>::value;
// fennec::is_fundamental ==============================================================================================
///
/// \brief Check if \p T is a fundamental type, i.e. arithmetic, void, or nullptr_t
/// \tparam T type to check
template<typename T> struct is_fundamental
: bool_constant<is_arithmetic_v<T> || is_void_v<T> || is_null_pointer_v<T>>{};
///
/// \brief Shorthand for ```is_fundamental<T>::value```
/// \tparam T type to check
template<typename T> constexpr bool_t is_fundamental_v = is_fundamental<T>::value;
template<typename T> constexpr bool_t is_unsigned_v = is_unsigned<T>::value;
// fennec::is_same =====================================================================================================
@@ -791,7 +1032,7 @@ template<typename T> struct is_same<T, T> : true_type {};
template<typename T0, typename T1> constexpr bool_t is_same_v = is_same<T0, T1> {};
// fennec::is_base_of =====================================================================================================
// fennec::is_base_of ==================================================================================================
///
/// \brief Check if `Derived` has a base type of `Base`
@@ -809,61 +1050,7 @@ template<typename Base, typename Derived> struct is_base_of : bool_constant<
/// \tparam Derived derived type to check
template<typename Base, typename Derived> constexpr bool_t is_base_of_v = is_base_of<Base, Derived> {};
// fennec::is_complete ==============================================================================================
///
/// \brief Check if type `T` is complete
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_complete : detail::_is_complete<T>::type {};
///
/// \brief Shorthand for `is_complete<TypeT0, TypeT1>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_complete_v = is_complete<T>{};
// fennec::is_iterable ==============================================================================================
///
/// \brief Check if type `T` is iterable
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_iterable : decltype(detail::_is_iterable<T>(0)) {};
///
/// \brief Shorthand for `is_iterable<TypeT0, TypeT1>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_iterable_v = is_iterable<T>{};
// fennec::is_indexable ==============================================================================================
///
/// \brief Check if type `T` is indexable
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_indexable : decltype(detail::_is_indexable<T>(0)) {};
///
/// \brief Shorthand for `is_indexable<TypeT0, TypeT1>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_indexable_v = is_indexable<T>{};
// fennec::is_mappable ==============================================================================================
///
/// \brief Check if type `T` is mappable
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_mappable : decltype(detail::_is_mappable<T>(0)) {};
///
/// \brief Shorthand for `is_mappable<TypeT0, TypeT1>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_mappable_v = is_mappable<T>{};
// fennec::is_convertible ==============================================================================================
@@ -883,6 +1070,7 @@ template<typename FromT, typename ToT> struct is_convertible
template<typename FromT, typename ToT> constexpr bool_t is_convertible_v = is_convertible<FromT, ToT>{};
// fennec::is_constructible ============================================================================================
///
@@ -899,6 +1087,8 @@ template<typename ClassT, typename...ArgsT> constexpr bool_t is_constructible_v
// fennec::is_trivially_constructible ==================================================================================
///
/// \brief Check if `ClassT` is trivially constructible
/// \tparam ClassT The class type to test
@@ -911,6 +1101,8 @@ template<typename ClassT> constexpr bool_t is_trivially_constructible_v = is_tri
// fennec::is_default_constructible ====================================================================================
///
/// \brief Check if `ClassT` is default constructible
/// \tparam ClassT The class type to test
@@ -923,6 +1115,8 @@ template<typename ClassT> constexpr bool_t is_default_constructible_v = is_defau
// fennec::is_copy_constructible =======================================================================================
///
/// \brief Check if `ClassT` is copy constructible
/// \tparam ClassT The class type to test
@@ -935,8 +1129,10 @@ template<typename ClassT, typename...ArgsT> constexpr bool_t is_copy_constructib
// fennec::is_move_constructible =======================================================================================
///
/// \brief Check if `ClassT` is copy constructible
/// \brief Check if `ClassT` is move constructible
/// \tparam ClassT The class type to test
template<typename ClassT> struct is_move_constructible
: bool_constant<FENNEC_BUILTIN_IS_CONSTRUCTIBLE(ClassT, add_rvalue_reference_t<ClassT>)> {};
@@ -946,42 +1142,6 @@ template<typename ClassT> struct is_move_constructible
template<typename ClassT, typename...ArgsT> constexpr bool_t is_move_constructible_v = is_move_constructible<ClassT>{};
// fennec::is_destructible ===================================================================================
///
/// \brief Check if `ClassT` is destructible
/// \tparam ClassT The class type to test
template<typename ClassT> struct is_destructible
: detail::_is_destructible<ClassT>::type {};
///
/// \brief Shorthand for `is_destructible<ClassT, ArgsT...>::value`
template<typename ClassT> constexpr bool_t is_destructible_v = is_destructible<ClassT>{};
///
/// \brief Check if `ClassT` is trivially destructible
/// \tparam ClassT The class type to test
template<typename ClassT> struct is_trivially_destructible
: bool_constant<FENNEC_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE(ClassT)> {};
///
/// \brief Shorthand for `is_trivially_destructible<ClassT, ArgsT...>::value`
template<typename ClassT> constexpr bool_t is_trivially_destructible_v = is_trivially_destructible<ClassT>{};
///
/// \brief Check if `ClassT` is nothrow destructible
/// \tparam ClassT The class type to test
template<typename ClassT> struct is_nothrow_destructible
: detail::_is_nothrow_destructible<ClassT>::type {};
///
/// \brief Shorthand for `is_nothrow_destructible<ClassT, ArgsT...>::value`
template<typename ClassT> constexpr bool_t is_nothrow_destructible_v = is_nothrow_destructible<ClassT>{};
// fennec::is_assignable ===============================================================================================
@@ -998,6 +1158,7 @@ template<typename ClassAT, typename ClassBT> struct is_assignable
template<typename ClassT, typename...ArgsT> constexpr bool_t is_assignable_v = is_assignable<ClassT, ArgsT...>{};
// fennec::is_copy_assignable ==========================================================================================
///
@@ -1011,6 +1172,7 @@ template<typename ClassT> struct is_copy_assignable
template<typename ClassT> constexpr bool_t is_copy_assignable_v = is_copy_assignable<ClassT>{};
// fennec::is_move_assignable ==========================================================================================
///
@@ -1024,6 +1186,96 @@ template<typename ClassT> struct is_move_assignable
template<typename ClassT> constexpr bool_t is_move_assignable_v = is_move_assignable<ClassT>{};
// fennec::is_destructible =============================================================================================
///
/// \brief Check if `ClassT` is destructible
/// \tparam ClassT The class type to test
template<typename ClassT> struct is_destructible
: detail::_is_destructible<ClassT>::type {};
///
/// \brief Shorthand for `is_destructible<ClassT, ArgsT...>::value`
template<typename ClassT> constexpr bool_t is_destructible_v = is_destructible<ClassT>{};
// fennec::is_trivially_destructible ===================================================================================
///
/// \brief Check if `ClassT` is trivially destructible
/// \tparam ClassT The class type to test
template<typename ClassT> struct is_trivially_destructible
: bool_constant<FENNEC_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE(ClassT)> {};
///
/// \brief Shorthand for `is_trivially_destructible<ClassT, ArgsT...>::value`
template<typename ClassT> constexpr bool_t is_trivially_destructible_v = is_trivially_destructible<ClassT>{};
// fennec::is_nothrow_destructible =====================================================================================
///
/// \brief Check if `ClassT` is nothrow destructible
/// \tparam ClassT The class type to test
template<typename ClassT> struct is_nothrow_destructible
: detail::_is_nothrow_destructible<ClassT>::type {};
///
/// \brief Shorthand for `is_nothrow_destructible<ClassT, ArgsT...>::value`
template<typename ClassT> constexpr bool_t is_nothrow_destructible_v = is_nothrow_destructible<ClassT>{};
// fennec::is_iterable =================================================================================================
///
/// \brief Check if type `T` is iterable
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_iterable : decltype(detail::_is_iterable<T>(0)) {};
///
/// \brief Shorthand for `is_iterable<TypeT0, TypeT1>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_iterable_v = is_iterable<T>{};
// fennec::is_indexable ================================================================================================
///
/// \brief Check if type `T` is indexable
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_indexable : decltype(detail::_is_indexable<T>(0)) {};
///
/// \brief Shorthand for `is_indexable<TypeT0, TypeT1>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_indexable_v = is_indexable<T>{};
// fennec::is_mappable =================================================================================================
///
/// \brief Check if type `T` is mappable
///
/// \details Checks if `T`
/// \tparam T type to check
template<typename T> struct is_mappable : decltype(detail::_is_mappable<T>(0)) {};
///
/// \brief Shorthand for `is_mappable<TypeT0, TypeT1>::value`
/// \tparam T type to check
template<typename T> constexpr bool_t is_mappable_v = is_mappable<T>{};
}
#endif // FENNEC_LANG_TYPE_TRAITS_H

View File

@@ -127,6 +127,12 @@
namespace fennec
{
// Decay Conversions ===================================================================================================
template<typename T> struct decay : detail::_decay<T> {};
template<typename T> using decay_t = typename decay<T>::type;
// Pointer Conversions =================================================================================================
///
@@ -134,7 +140,7 @@ namespace fennec
///
/// \details adds a pointer to the provided type such that `T` becomes `T*`
/// \tparam T Resultant Type
template<typename T> struct add_pointer : type_identity<T*>{};
template<typename T> struct add_pointer : detail::_add_pointer<T>{};
///
/// \brief shorthand for `typename add_pointer<T>::type`
@@ -146,10 +152,7 @@ template<typename T> using add_pointer_t = typename add_pointer<T>::type;
///
/// \details removes a pointer from the provided type such that `T*` becomes `T`
/// \tparam T Resultant Type
template<typename T> struct remove_pointer : type_identity<T> {};
// specialization for T*
template<typename T> struct remove_pointer<T*> : type_identity<T> {};
template<typename T> struct remove_pointer : detail::_remove_pointer<T> {};
///
/// \brief shorthand for `typename remove_pointer<T>::type`
@@ -235,30 +238,24 @@ template<typename T> using add_rvalue_reference_t = typename add_rvalue_referen
///
/// \details adds const qualification to the provided type such that `T` becomes `const T`
/// \tparam T Reference Type
template<typename T> struct add_const : type_identity<const T> {};
template<typename T> struct add_const : detail::_add_const<T> {};
///
/// \brief shorthand for `typename add_const<T>::type`
template<typename T> using add_const_t = typename add_const<T>::type;
// specialization for const types
template<typename T> struct add_const<const T> : type_identity<const 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`
/// \tparam T Reference Type
template<typename T> struct remove_const : type_identity<T> {};
template<typename T> struct remove_const : detail::_remove_const<T> {};
///
/// \brief shorthand for `typename remove_const<T>::type`
template<typename T> using remove_const_t = typename remove_const<T>::type;
// specialization for const types
template<typename T> struct remove_const<const T> : type_identity<T> {};
///
@@ -266,30 +263,24 @@ template<typename T> struct remove_const<const T> : type_identity<T> {};
///
/// \details removes references from the provided type such that `T` becomes `volatile T`
/// \tparam T Reference Type
template<typename T> struct add_volatile : type_identity<volatile T> {};
template<typename T> struct add_volatile : detail::_add_volatile<T> {};
///
/// \brief shorthand for `typename add_volatile<T>::type`
template<typename T> using add_volatile_t = typename add_volatile<T>::type;
// specialization for volatile types
template<typename T> struct add_volatile<volatile T> : type_identity<volatile 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`
/// \tparam T Reference Type
template<typename T> struct remove_volatile : type_identity<T> {};
template<typename T> struct remove_volatile : detail::_remove_volatile<T> {};
///
/// \brief shorthand for `typename remove_volatile<T>::type`
template<typename T> using remove_volatile_t = typename remove_volatile<T>::type;
// specialization for volatile types
template<typename T> struct remove_volatile<volatile T> : type_identity<T> {};
///
@@ -298,21 +289,12 @@ template<typename T> struct remove_volatile<volatile T> : type_identity<T> {};
/// \details removes references from the provided type such that `T`, `const T`, and `volatile T` become
/// `const volatile T`
/// \tparam T Reference Type
template<typename T> struct add_cv : type_identity<const volatile T> {};
template<typename T> struct add_cv : detail::_add_cv<T> {};
///
/// \brief shorthand for `typename add_cv<T>::type`
template<typename T> using add_cv_t = typename add_cv<T>::type;
// specialization for const types
template<typename T> struct add_cv<const T> : type_identity<const volatile T> {};
// specialization for volatile types
template<typename T> struct add_cv<volatile T> : type_identity<const volatile T> {};
// specialization for const volatile types
template<typename T> struct add_cv<const volatile T> : type_identity<const volatile T> {};
///
@@ -321,16 +303,7 @@ template<typename T> struct add_cv<const volatile T> : type_identity<const volat
/// \details removes const and volatile from the provided type such that `const T`, `volatile T`, and
/// `const volatile T` become `T`
/// \tparam T Reference Type
template<typename T> struct remove_cv : type_identity<T> {};
// specialization for const types
template<typename T> struct remove_cv<const T> : type_identity<T> {};
// specialization for volatile types
template<typename T> struct remove_cv<volatile T> : type_identity<T> {};
// specialization for const volatile types
template<typename T> struct remove_cv<const volatile T> : type_identity<T> {};
template<typename T> struct remove_cv : detail::_remove_cv<T> {};
///
/// \brief shorthand for `typename remove_cv<T>::type`
@@ -343,11 +316,11 @@ template<typename T> using remove_cv_t = typename remove_cv<T>::type;
///
/// \details adds references and const volatile qualifiers to the provided type.
/// \tparam T Reference Type
template<typename T> struct add_cvr : type_identity<add_reference_t<add_cv_t<T>>> {};
template<typename T> struct add_cvref : type_identity<add_reference_t<add_cv_t<T>>> {};
///
/// \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_cvref_t = typename add_cvref<T>::type;
@@ -356,12 +329,12 @@ template<typename T> using add_cvr_t = typename add_cvr<T>::type;
///
/// \details removes const and volatile from the provided type such that
/// \tparam T Reference Type
template<typename T> struct remove_cvr : type_identity<remove_cv_t<remove_reference_t<T>>> {};
template<typename T> struct remove_cvref : type_identity<remove_cv_t<remove_reference_t<T>>> {};
///
/// \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_cvref_t = typename remove_cvref<T>::type;
@@ -370,12 +343,12 @@ template<typename T> using remove_cvr_t = typename remove_cvr<T>::type;
///
/// \details removes const and volatile from the provided type such that
/// \tparam T Reference Type
template<typename T> struct remove_cvrp : type_identity<remove_cv_t<remove_reference_t<strip_pointers_t<T>>>> {};
template<typename T> struct remove_cvrefptr : type_identity<remove_cv_t<remove_reference_t<strip_pointers_t<T>>>> {};
///
/// \brief shorthand for `typename remove_cvrp_t<T>::type`
template<typename T> using remove_cvrp_t = typename remove_cvrp<T>::type;
template<typename T> using remove_cvrefptr_t = typename remove_cvrefptr<T>::type;
}