- Separated Platform and Compiler Dependent Behaviour into CMake scripts
- Implemented Basic Platform Interfaces
- Implemented partial Linux platform and Wayland Display.
- Implemented Dependencies for the above
- map
- set
- optional
- pair
TODO: threading
This commit is contained in:
@@ -46,7 +46,12 @@
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// assert(expr, desc)
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// Make an assertion with expression `expr` and provide a description `desc`.
|
||||
/// Make an assertion with expression `expr` and provide a description `desc`. Only halts in debug mode.
|
||||
///
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// assertf(expr, desc)
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// Make an assertion with expression `expr` and provide a description `desc`. Always halts.
|
||||
///
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// assertd(expr, desc)
|
||||
@@ -65,15 +70,20 @@
|
||||
|
||||
using assert_handler = void (*)(const char *, const char *, int , const char *);
|
||||
|
||||
void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* desc);
|
||||
void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* desc, bool halt);
|
||||
|
||||
// flagged unlikely to optimize branch prediction
|
||||
#define assert(expression, description) \
|
||||
if(not(expression)) [[unlikely]] { \
|
||||
__assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description); \
|
||||
__assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, not FENNEC_RELEASE); \
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define assertf(expression, description) \
|
||||
if(not(expression)) [[unlikely]] { \
|
||||
__assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, true); \
|
||||
}
|
||||
|
||||
#if FENNEC_RELEASE
|
||||
#define assertd(expression, description) (0)
|
||||
#else
|
||||
#define assertd(expression, description) assert(expression, description)
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#ifndef FENNEC_LANG_CONDITIONAL_TYPES_H
|
||||
#define FENNEC_LANG_CONDITIONAL_TYPES_H
|
||||
|
||||
#include <fennec/lang/type_identity.h>
|
||||
|
||||
///
|
||||
/// \page fennec_lang_conditional_types Conditional Types
|
||||
///
|
||||
@@ -64,8 +66,6 @@
|
||||
///
|
||||
///
|
||||
|
||||
#include <fennec/lang/type_transforms.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
@@ -92,12 +92,12 @@ using conditional_t
|
||||
|
||||
// specialization of fennec::conditional for `true` case
|
||||
template<typename T, typename F>
|
||||
struct conditional<true, T, F> : type_transform<T>{};
|
||||
struct conditional<true, T, F> : type_identity<T>{};
|
||||
|
||||
|
||||
// specialization of fennec::conditional for `false` case
|
||||
template<typename T, typename F>
|
||||
struct conditional<false, T, F> : type_transform<F>{};
|
||||
struct conditional<false, T, F> : type_identity<F>{};
|
||||
|
||||
|
||||
// fennec::detect ======================================================================================================
|
||||
|
||||
@@ -28,34 +28,34 @@ namespace fennec
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename> struct __make_unsigned : type_transform<undefined_t> {};
|
||||
template<typename> struct __make_unsigned : type_identity<undefined_t> {};
|
||||
|
||||
template<> struct __make_unsigned<char_t> : type_transform<uchar_t> {};
|
||||
template<> struct __make_unsigned<uchar_t> : type_transform<uchar_t> {};
|
||||
template<> struct __make_unsigned<schar_t> : type_transform<uchar_t> {};
|
||||
template<> struct __make_unsigned<short_t> : type_transform<ushort_t> {};
|
||||
template<> struct __make_unsigned<ushort_t> : type_transform<ushort_t> {};
|
||||
template<> struct __make_unsigned<uint_t> : type_transform<uint_t> {};
|
||||
template<> struct __make_unsigned<int_t> : type_transform<uint_t> {};
|
||||
template<> struct __make_unsigned<long_t> : type_transform<ulong_t> {};
|
||||
template<> struct __make_unsigned<ulong_t> : type_transform<ulong_t> {};
|
||||
template<> struct __make_unsigned<llong_t> : type_transform<ullong_t> {};
|
||||
template<> struct __make_unsigned<ullong_t> : type_transform<ullong_t> {};
|
||||
template<> struct __make_unsigned<char_t> : type_identity<uchar_t> {};
|
||||
template<> struct __make_unsigned<uchar_t> : type_identity<uchar_t> {};
|
||||
template<> struct __make_unsigned<schar_t> : type_identity<uchar_t> {};
|
||||
template<> struct __make_unsigned<short_t> : type_identity<ushort_t> {};
|
||||
template<> struct __make_unsigned<ushort_t> : type_identity<ushort_t> {};
|
||||
template<> struct __make_unsigned<uint_t> : type_identity<uint_t> {};
|
||||
template<> struct __make_unsigned<int_t> : type_identity<uint_t> {};
|
||||
template<> struct __make_unsigned<long_t> : type_identity<ulong_t> {};
|
||||
template<> struct __make_unsigned<ulong_t> : type_identity<ulong_t> {};
|
||||
template<> struct __make_unsigned<llong_t> : type_identity<ullong_t> {};
|
||||
template<> struct __make_unsigned<ullong_t> : type_identity<ullong_t> {};
|
||||
|
||||
|
||||
template<typename> struct __make_signed : type_transform<undefined_t> {};
|
||||
template<typename> struct __make_signed : type_identity<undefined_t> {};
|
||||
|
||||
template<> struct __make_signed<char_t> : type_transform<schar_t> {};
|
||||
template<> struct __make_signed<uchar_t> : type_transform<schar_t> {};
|
||||
template<> struct __make_signed<schar_t> : type_transform<schar_t> {};
|
||||
template<> struct __make_signed<short_t> : type_transform<short_t> {};
|
||||
template<> struct __make_signed<ushort_t> : type_transform<short_t> {};
|
||||
template<> struct __make_signed<uint_t> : type_transform<int_t> {};
|
||||
template<> struct __make_signed<int_t> : type_transform<int_t> {};
|
||||
template<> struct __make_signed<long_t> : type_transform<long_t> {};
|
||||
template<> struct __make_signed<ulong_t> : type_transform<long_t> {};
|
||||
template<> struct __make_signed<llong_t> : type_transform<llong_t> {};
|
||||
template<> struct __make_signed<ullong_t> : type_transform<llong_t> {};
|
||||
template<> struct __make_signed<char_t> : type_identity<schar_t> {};
|
||||
template<> struct __make_signed<uchar_t> : type_identity<schar_t> {};
|
||||
template<> struct __make_signed<schar_t> : type_identity<schar_t> {};
|
||||
template<> struct __make_signed<short_t> : type_identity<short_t> {};
|
||||
template<> struct __make_signed<ushort_t> : type_identity<short_t> {};
|
||||
template<> struct __make_signed<uint_t> : type_identity<int_t> {};
|
||||
template<> struct __make_signed<int_t> : type_identity<int_t> {};
|
||||
template<> struct __make_signed<long_t> : type_identity<long_t> {};
|
||||
template<> struct __make_signed<ulong_t> : type_identity<long_t> {};
|
||||
template<> struct __make_signed<llong_t> : type_identity<llong_t> {};
|
||||
template<> struct __make_signed<ullong_t> : type_identity<llong_t> {};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace fennec
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename FirstT, typename... RestT> struct __first_element : type_transform<FirstT>{};
|
||||
template<typename FirstT, typename... RestT> struct __first_element : type_identity<FirstT>{};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ template<typename> struct __is_floating_point : false_type {};
|
||||
template<> struct __is_floating_point<float_t> : true_type {};
|
||||
template<> struct __is_floating_point<double_t> : true_type {};
|
||||
|
||||
template<typename> struct __is_pointer : false_type {};
|
||||
template<typename T> struct __is_pointer<T*> : true_type {};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
55
include/fennec/lang/detail/__type_transforms.h
Normal file
55
include/fennec/lang/detail/__type_transforms.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// =====================================================================================================================
|
||||
// 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_LANG_DETAIL_TYPE_TRANSFORMS_H
|
||||
#define FENNEC_LANG_DETAIL_TYPE_TRANSFORMS_H
|
||||
|
||||
#include <fennec/lang/types.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename _Tp, typename = void>
|
||||
struct __add_lvalue_reference {
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __add_lvalue_reference<_Tp, void_t<_Tp&>> {
|
||||
using type = _Tp&;
|
||||
};
|
||||
|
||||
|
||||
template<typename _Tp, typename = void>
|
||||
struct __add_rvalue_reference {
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __add_rvalue_reference<_Tp, void_t<_Tp&&>> {
|
||||
using type = _Tp&&;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_DETAIL_TYPE_TRANSFORMS_H
|
||||
89
include/fennec/lang/hashing.h
Normal file
89
include/fennec/lang/hashing.h
Normal file
@@ -0,0 +1,89 @@
|
||||
// =====================================================================================================================
|
||||
// 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_LANG_HASHING_H
|
||||
#define FENNEC_LANG_HASHING_H
|
||||
|
||||
#include <fennec/lang/types.h>
|
||||
#include <fennec/lang/type_traits.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
/// \brief Struct for hashing types, there is no default hashing function
|
||||
/// \tparam Key The type to hash
|
||||
template<typename Key> struct hash;
|
||||
|
||||
// Murmur3 Hash for 64-bit ints
|
||||
template<>
|
||||
struct hash<uint64_t> {
|
||||
using type_t = uint64_t;
|
||||
constexpr size_t operator()(uint64_t x) const {
|
||||
// Murmur3
|
||||
x ^= x >> 33U;
|
||||
x *= 0xff51afd7ed558ccd;
|
||||
x ^= x >> 33U;
|
||||
x *= 0xc4ceb9fe1a85ec53;
|
||||
x ^= x >> 33U;
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
// Wrapper for casting ints
|
||||
template<typename IntT>
|
||||
requires is_integral_v<IntT>
|
||||
struct hash<IntT> : hash<uint64_t> {
|
||||
using type_t = IntT;
|
||||
};
|
||||
|
||||
// Wrapper for pointers
|
||||
template<typename PtrT>
|
||||
requires is_pointer_v<PtrT>
|
||||
struct hash<PtrT> : hash<uintptr_t> {
|
||||
};
|
||||
|
||||
// Float
|
||||
template<>
|
||||
struct hash<float> : hash<uint32_t> {
|
||||
constexpr size_t operator()(float x) const {
|
||||
return hash<uint32_t>::operator()(bit_cast<uint32_t>(x));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<double> : hash<uint64_t> {
|
||||
constexpr size_t operator()(double x) const {
|
||||
return hash<uint64_t>::operator()(bit_cast<uint64_t>(x));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// \brief Pairs two hashes
|
||||
/// \param x first hash
|
||||
/// \param y second hash
|
||||
/// \returns a pairing of the two hashes
|
||||
constexpr size_t pair_hash(size_t x, size_t y) {
|
||||
// Szudzik Pairing
|
||||
return (x >= y ? (x * x) + x + y : (y * y) + x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_HASHING_H
|
||||
@@ -142,14 +142,44 @@
|
||||
# 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_ARGS__)
|
||||
# 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)
|
||||
|
||||
57
include/fennec/lang/type_identity.h
Normal file
57
include/fennec/lang/type_identity.h
Normal file
@@ -0,0 +1,57 @@
|
||||
// =====================================================================================================================
|
||||
// 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_LANG_TYPE_IDENTITY_H
|
||||
#define FENNEC_LANG_TYPE_IDENTITY_H
|
||||
|
||||
///
|
||||
/// \page fennec_lang_type_identity Type Identity
|
||||
///
|
||||
/// \brief Part of the fennec metaprogramming library. This header defines structures for copying types with different traits
|
||||
/// or rather, transform them, at compile time.
|
||||
///
|
||||
/// \code #include <fennec/lang/type_identity.h> \endcode
|
||||
///
|
||||
///
|
||||
/// <table width="100%" class="fieldtable" id="table_fennec_lang_type_identity">
|
||||
/// <tr><th style="vertical-align: top">Syntax
|
||||
/// <th style="vertical-align: top">Description
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// \ref fennec::type_identity "type_identity<TypeT>::type"<br>
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// \copydetails fennec::type_identity
|
||||
/// </table>
|
||||
///
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
/// \brief Base Class for Type Transformations
|
||||
///
|
||||
/// \details resembles a transformation from one type to T, the result is stored in the member type_transform::type
|
||||
/// \tparam T Resultant Type
|
||||
template<typename T> struct type_identity {
|
||||
|
||||
/// \brief the type to transform into
|
||||
using type = T;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_TYPE_IDENTITY_H
|
||||
@@ -272,6 +272,22 @@ template<typename T> struct is_floating_point
|
||||
template<typename T> constexpr bool_t is_floating_point_v = is_floating_point<T> {};
|
||||
|
||||
|
||||
// Pointer 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_pointer
|
||||
: detail::__is_pointer<remove_cvr_t<T>>{};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_floating_point<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_pointer_v = is_pointer<T> {};
|
||||
|
||||
|
||||
|
||||
// Arithmetic Types ====================================================================================================
|
||||
|
||||
@@ -339,7 +355,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 ===============================================================================================
|
||||
// fennec::is_constructible ============================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` can be constructed with `ArgsT,` i.e. `ClassT(ArgsT...)`.
|
||||
@@ -354,7 +370,106 @@ template<typename ClassT, typename...ArgsT> struct is_constructible
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_constructible_v = is_constructible<ClassT, ArgsT...>{};
|
||||
|
||||
|
||||
// fennec::
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is default constructible
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_default_constructible
|
||||
: bool_constant<FENNEC_BUILTIN_IS_CONSTRUCTIBLE(ClassT,)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_default_constructible<ClassT>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_default_constructible_v = is_default_constructible<ClassT>{};
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is copy constructible
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_copy_constructible
|
||||
: bool_constant<FENNEC_BUILTIN_IS_CONSTRUCTIBLE(ClassT, add_lvalue_reference_t<const ClassT>)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_copy_constructible<ClassT>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_copy_constructible_v = is_copy_constructible<ClassT>{};
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is copy 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>)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_copy_constructible<ClassT>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_move_constructible_v = is_move_constructible<ClassT>{};
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is trivially constructible
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_trivially_constructible
|
||||
: bool_constant<FENNEC_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE(ClassT)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_trivially_constructible<ClassT, ArgsT...>::value`
|
||||
template<typename ClassT> constexpr bool_t is_trivially_constructible_v = is_trivially_constructible<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_assignable ===============================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` can be constructed with `ArgsT,` i.e. `ClassT(ArgsT...)`.
|
||||
/// This may be read as "is `ClassT` constructible with `ArgsT`"
|
||||
/// \tparam ClassAT The class type to test
|
||||
/// \tparam ClassBT The arguments for the specific constructor
|
||||
template<typename ClassAT, typename ClassBT> struct is_assignable
|
||||
: bool_constant<FENNEC_BUILTIN_IS_ASSIGNABLE(ClassAT, ClassBT)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_constructible<ClassT, ArgsT...>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_assignable_v = is_assignable<ClassT, ArgsT...>{};
|
||||
|
||||
|
||||
// fennec::is_copy_assignable ==========================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is copy assignable
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_copy_assignable
|
||||
: bool_constant<FENNEC_BUILTIN_IS_ASSIGNABLE(add_lvalue_reference_t<ClassT>, add_lvalue_reference_t<const ClassT>)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_copy_assignable<ClassT>::value`
|
||||
template<typename ClassT> constexpr bool_t is_copy_assignable_v = is_copy_assignable<ClassT>{};
|
||||
|
||||
|
||||
// fennec::is_move_assignable ==========================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is move assignable
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_move_assignable
|
||||
: bool_constant<FENNEC_BUILTIN_IS_ASSIGNABLE(add_lvalue_reference_t<ClassT>, add_rvalue_reference_t<ClassT>)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_move_assignable<ClassT>::value`
|
||||
template<typename ClassT> constexpr bool_t is_move_assignable_v = is_move_assignable<ClassT>{};
|
||||
|
||||
//
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#ifndef FENNEC_LANG_TYPE_TRANSFORMS_H
|
||||
#define FENNEC_LANG_TYPE_TRANSFORMS_H
|
||||
|
||||
#include <fennec/lang/type_identity.h>
|
||||
#include <fennec/lang/detail/__type_transforms.h>
|
||||
|
||||
///
|
||||
/// \page fennec_lang_type_transforms Type Transforms
|
||||
///
|
||||
@@ -44,11 +47,6 @@
|
||||
/// <tr><th style="vertical-align: top">Syntax
|
||||
/// <th style="vertical-align: top">Description
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// \ref fennec::type_transform "type_transform<TypeT>::type"<br>
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// \copydetails fennec::type_transform
|
||||
///
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// \ref fennec::add_pointer "add_pointer<TypeT>::type"<br>
|
||||
/// \ref fennec::add_pointer_t "add_pointer_t<TypeT>"
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
@@ -127,22 +125,6 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
// fennec::type_transform ==============================================================================================
|
||||
|
||||
///
|
||||
/// \brief Base Class for Type Transformations
|
||||
///
|
||||
/// \details resembles a transformation from one type to T, the result is stored in the member type_transform::type
|
||||
/// \tparam T Resultant Type
|
||||
template<typename T> struct type_transform {
|
||||
|
||||
///
|
||||
/// \brief the type to transform into
|
||||
using type = T;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Pointer Conversions =================================================================================================
|
||||
|
||||
///
|
||||
@@ -150,7 +132,7 @@ template<typename T> struct type_transform {
|
||||
///
|
||||
/// \details adds a pointer to the provided type such that `T` becomes `T*`
|
||||
/// \tparam T Resultant Type
|
||||
template<typename T> struct add_pointer : type_transform<T*>{};
|
||||
template<typename T> struct add_pointer : type_identity<T*>{};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename add_pointer<T>::type`
|
||||
@@ -162,10 +144,10 @@ 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_transform<T> {};
|
||||
template<typename T> struct remove_pointer : type_identity<T> {};
|
||||
|
||||
// specialization for T*
|
||||
template<typename T> struct remove_pointer<T*> : type_transform<T> {};
|
||||
template<typename T> struct remove_pointer<T*> : type_identity<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_pointer<T>::type`
|
||||
@@ -180,7 +162,7 @@ template<typename T> using remove_pointer_t = typename remove_pointer<T>::type;
|
||||
///
|
||||
/// \details adds a pointer to the provided type such that `T` becomes `T&`
|
||||
/// \tparam T Resultant Type
|
||||
template<typename T> struct add_reference : type_transform<T&> {};
|
||||
template<typename T> struct add_reference : type_identity<T&> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename add_reference<T>::type`
|
||||
@@ -192,19 +174,43 @@ template<typename T> using add_reference_t = typename add_reference<T>::type;
|
||||
///
|
||||
/// \details removes references from the provided type such that `T&` and `T&&` become `T`
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct remove_reference : type_transform<T> {};
|
||||
template<typename T> struct remove_reference : type_identity<T> {};
|
||||
|
||||
// specialization for `T&`
|
||||
template<typename T> struct remove_reference<T&> : type_transform<T> {};
|
||||
template<typename T> struct remove_reference<T&> : type_identity<T> {};
|
||||
|
||||
// specialization for `T&&`
|
||||
template<typename T> struct remove_reference<T&&> : type_transform<T> {};
|
||||
template<typename T> struct remove_reference<T&&> : type_identity<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_reference<T>::type`
|
||||
template<typename T> using remove_reference_t = typename remove_reference<T>::type;
|
||||
|
||||
|
||||
///
|
||||
/// \brief add a lvalue reference to \p T
|
||||
///
|
||||
/// \details adds a lvalue reference to the provided type such that 'T' becomes 'T&'
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct add_lvalue_reference : detail::__add_lvalue_reference<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_reference<T>::type`
|
||||
template<typename T> using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
|
||||
|
||||
|
||||
///
|
||||
/// \brief add a rvalue reference to \p T
|
||||
///
|
||||
/// \details adds a rvalue reference to the provided type such that 'T' becomes 'T&&'
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct add_rvalue_reference : detail::__add_rvalue_reference<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_reference<T>::type`
|
||||
template<typename T> using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
|
||||
|
||||
|
||||
|
||||
// Const & Volatile Conversions ========================================================================================
|
||||
|
||||
@@ -213,14 +219,14 @@ template<typename T> using remove_reference_t = typename remove_reference<T>::t
|
||||
///
|
||||
/// \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_transform<const T> {};
|
||||
template<typename T> struct add_const : type_identity<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_transform<const T> {};
|
||||
template<typename T> struct add_const<const T> : type_identity<const T> {};
|
||||
|
||||
|
||||
///
|
||||
@@ -228,14 +234,14 @@ template<typename T> struct add_const<const T> : type_transform<const 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_transform<T> {};
|
||||
template<typename T> struct remove_const : type_identity<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_transform<T> {};
|
||||
template<typename T> struct remove_const<const T> : type_identity<T> {};
|
||||
|
||||
|
||||
|
||||
@@ -244,14 +250,14 @@ template<typename T> struct remove_const<const T> : type_transform<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_transform<volatile T> {};
|
||||
template<typename T> struct add_volatile : type_identity<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_transform<volatile T> {};
|
||||
template<typename T> struct add_volatile<volatile T> : type_identity<volatile T> {};
|
||||
|
||||
|
||||
///
|
||||
@@ -259,14 +265,14 @@ template<typename T> struct add_volatile<volatile T> : type_transform<volatile 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_transform<T> {};
|
||||
template<typename T> struct remove_volatile : type_identity<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_transform<T> {};
|
||||
template<typename T> struct remove_volatile<volatile T> : type_identity<T> {};
|
||||
|
||||
|
||||
|
||||
@@ -276,20 +282,20 @@ template<typename T> struct remove_volatile<volatile T> : type_transform<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_transform<const volatile T> {};
|
||||
template<typename T> struct add_cv : type_identity<const volatile 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_transform<const volatile T> {};
|
||||
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_transform<const volatile T> {};
|
||||
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_transform<const volatile T> {};
|
||||
template<typename T> struct add_cv<const volatile T> : type_identity<const volatile T> {};
|
||||
|
||||
|
||||
|
||||
@@ -299,16 +305,16 @@ template<typename T> struct add_cv<const volatile T> : type_transform<const vola
|
||||
/// \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_transform<T> {};
|
||||
template<typename T> struct remove_cv : type_identity<T> {};
|
||||
|
||||
// specialization for const types
|
||||
template<typename T> struct remove_cv<const T> : type_transform<T> {};
|
||||
template<typename T> struct remove_cv<const T> : type_identity<T> {};
|
||||
|
||||
// specialization for volatile types
|
||||
template<typename T> struct remove_cv<volatile T> : type_transform<T> {};
|
||||
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_transform<T> {};
|
||||
template<typename T> struct remove_cv<const volatile T> : type_identity<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_cv<T>::type`
|
||||
@@ -321,7 +327,7 @@ 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_transform<add_reference_t<add_cv_t<T>>> {};
|
||||
template<typename T> struct add_cvr : type_identity<add_reference_t<add_cv_t<T>>> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename add_cvr<T>::type`
|
||||
@@ -334,7 +340,7 @@ 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_transform<remove_cv_t<remove_reference_t<T>>> {};
|
||||
template<typename T> struct remove_cvr : type_identity<remove_cv_t<remove_reference_t<T>>> {};
|
||||
|
||||
|
||||
///
|
||||
|
||||
@@ -242,7 +242,6 @@ namespace fennec
|
||||
/// \name Special Types
|
||||
/// @{
|
||||
|
||||
|
||||
using nullptr_t = decltype(nullptr); ///< \brief Null Pointer Type
|
||||
using intptr_t = intptr_t; ///< \brief Signed Integer Capable of Holding a Pointer to void
|
||||
using uintptr_t = uintptr_t; ///< \brief Unsigned Integer Capable of Holding a Pointer to void
|
||||
@@ -251,6 +250,7 @@ namespace fennec
|
||||
using size_t = size_t; ///< \brief Unsigned Integer Type Returned By `sizeof`, `sizeof...`, and `alignof`
|
||||
using ptrdiff_t = __PTRDIFF_TYPE__; ///< \brief Signed Integer Type Returned by the Subtraction of two Pointers
|
||||
|
||||
|
||||
class undefined_t; ///< \brief undefined class for SFINAE
|
||||
template<typename...> using void_t = void; ///< \brief Void type used for SFINAE
|
||||
|
||||
@@ -263,15 +263,15 @@ namespace fennec
|
||||
/// \name Sized Integer Types
|
||||
/// @{
|
||||
|
||||
using int8_t = schar_t; ///< \brief Signed 8-bit integer
|
||||
using int16_t = short_t; ///< \brief Signed 16-bit integer
|
||||
using int32_t = conditional_t<sizeof(int_t) == 4, int_t, long_t>; ///< \brief Signed 32-bit integer
|
||||
using int64_t = llong_t; ///< \brief Signed 64-bit integer
|
||||
using int8_t = schar_t; ///< \brief Signed 8-bit integer
|
||||
using int16_t = short_t; ///< \brief Signed 16-bit integer
|
||||
using int32_t = conditional_t<sizeof(int_t) == 4, int_t, long_t>; ///< \brief Signed 32-bit integer
|
||||
using int64_t = conditional_t<sizeof(long_t) == 8, long_t, llong_t>; ///< \brief Signed 64-bit integer
|
||||
|
||||
using uint8_t = uchar_t; ///< \brief Unsigned 8-bit integer
|
||||
using uint16_t = ushort_t; ///< \brief Unsigned 16-bit integer
|
||||
using uint32_t = conditional_t<sizeof(uint_t) == 4, uint_t, ulong_t>; ///< \brief Unsigned 32-bit integer
|
||||
using uint64_t = ullong_t; ///< \brief Unsigned 64-bit integer
|
||||
using uint8_t = uchar_t; ///< \brief Unsigned 8-bit integer
|
||||
using uint16_t = ushort_t; ///< \brief Unsigned 16-bit integer
|
||||
using uint32_t = conditional_t<sizeof(uint_t) == 4, uint_t, ulong_t>; ///< \brief Unsigned 32-bit integer
|
||||
using uint64_t = conditional_t<sizeof(ulong_t) == 8, ulong_t, ullong_t>; ///< \brief Unsigned 64-bit integer
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
///
|
||||
|
||||
#include <fennec/lang/type_transforms.h>
|
||||
#include <fennec/lang/type_traits.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
@@ -104,6 +105,29 @@ template<typename T> constexpr const remove_reference_t<T>& copy(T&& x) noexcept
|
||||
return x;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Swaps x and y
|
||||
/// \tparam T the fundamental type
|
||||
/// \param x first value
|
||||
/// \param y second value
|
||||
template<typename T> requires is_fundamental_v<T>
|
||||
constexpr void swap(T& x, T& y) noexcept {
|
||||
T a = x;
|
||||
x = y;
|
||||
y = a;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Swaps x and y without invoking destructor
|
||||
/// \tparam T the type
|
||||
/// \param x first value
|
||||
/// \param y second value
|
||||
template<typename T> constexpr void swap(T& x, T& y) noexcept {
|
||||
T a = fennec::move(x);
|
||||
x = fennec::move(y);
|
||||
y = fennec::move(a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_UTILITY_H
|
||||
|
||||
Reference in New Issue
Block a user