- fennec::variant & fennec::generic, TODO: Test
This commit is contained in:
@@ -19,13 +19,19 @@
|
||||
#ifndef FENNEC_LANG_DETAIL_TYPE_SEQUENCES_H
|
||||
#define FENNEC_LANG_DETAIL_TYPE_SEQUENCES_H
|
||||
|
||||
#include <fennec/math/common.h>
|
||||
#include <fennec/lang/type_transforms.h>
|
||||
|
||||
namespace fennec::detail
|
||||
{
|
||||
template<typename...TypesT> struct _type_sequence {};
|
||||
|
||||
template<typename FirstT, typename... RestT> struct _first_element : type_identity<FirstT> {};
|
||||
|
||||
|
||||
|
||||
// fennec::nth_element =================================================================================================
|
||||
|
||||
template<size_t n, size_t i, typename...TypesT> struct _nth_element;
|
||||
|
||||
template<size_t n, size_t i> struct _nth_element<n, i> : type_identity<void> {};
|
||||
@@ -35,6 +41,56 @@ namespace fennec::detail
|
||||
n == i, HeadT,
|
||||
typename _nth_element<n, i + 1, RestT...>::type
|
||||
> {};
|
||||
|
||||
|
||||
|
||||
// fennec::max_element_size ============================================================================================
|
||||
|
||||
template<size_t, typename...> struct _max_element_size;
|
||||
|
||||
template<size_t M, typename HeadT>
|
||||
struct _max_element_size<M, HeadT>
|
||||
: integral_constant<size_t, fennec::max(M, sizeof(HeadT))> {
|
||||
};
|
||||
|
||||
template<size_t M, typename HeadT, typename...RestT>
|
||||
struct _max_element_size<M, HeadT, RestT...>
|
||||
: _max_element_size<fennec::max(M, sizeof(HeadT)), RestT...> {
|
||||
};
|
||||
|
||||
|
||||
|
||||
// fennec::find_element ================================================================================================
|
||||
|
||||
template<size_t N, typename, typename...> struct _find_element;
|
||||
|
||||
template<size_t N, typename FindT, typename HeadT>
|
||||
struct _find_element<N, FindT, HeadT> : integral_constant<size_t, is_same_v<FindT, HeadT> ? N : N + 1> {};
|
||||
|
||||
template<size_t N, typename FindT, typename HeadT, typename...RestT> requires(is_same_v<FindT, HeadT>)
|
||||
struct _find_element<N, FindT, HeadT, RestT...>
|
||||
: conditional_t<is_same_v<FindT, HeadT>, integral_constant<size_t, N>, _find_element<N + 1, FindT, RestT...>> {};
|
||||
|
||||
|
||||
// fennec::search_element ==============================================================================================
|
||||
|
||||
template<template<typename> typename, typename...> struct _search_element;
|
||||
|
||||
template<template<typename> typename SearchT> struct _search_element<SearchT> : type_identity<void> {};
|
||||
|
||||
template<template<typename> typename SearchT, typename HeadT, typename...RestT> requires(SearchT<HeadT>{})
|
||||
struct _search_element<SearchT, HeadT, RestT...>
|
||||
: conditional_t<SearchT<HeadT>{}, type_identity<HeadT>, _search_element<SearchT, RestT...>> {
|
||||
};
|
||||
|
||||
template<template<typename, typename...> typename, typename, typename...> struct _search_element_args;
|
||||
|
||||
template<template<typename, typename...> typename SearchT, typename...ArgsT>
|
||||
struct _search_element_args<SearchT, _type_sequence<ArgsT...>> : type_identity<void> {};
|
||||
|
||||
template<template<typename, typename...> typename SearchT, typename HeadT, typename...RestT, typename...ArgsT>
|
||||
struct _search_element_args<SearchT, _type_sequence<ArgsT...>, HeadT, RestT...>
|
||||
: conditional_t<SearchT<HeadT, ArgsT...>{}, type_identity<HeadT>, _search_element_args<SearchT, _type_sequence<ArgsT...>, RestT...>> {};
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_DETAIL_TYPE_SEQUENCES_H
|
||||
|
||||
@@ -63,9 +63,19 @@ namespace fennec::detail
|
||||
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> struct _is_pointer : false_type {};
|
||||
template<typename T> struct _is_pointer<T*> : true_type {};
|
||||
|
||||
template<typename> struct _is_reference : false_type {};
|
||||
template<typename T> struct _is_reference<T&> : true_type {};
|
||||
template<typename T> struct _is_reference<T&&> : true_type {};
|
||||
|
||||
template<typename> struct _is_lvalue_reference : false_type {};
|
||||
template<typename T> struct _is_lvalue_reference<T&> : true_type {};
|
||||
|
||||
template<typename> struct _is_rvalue_reference : false_type {};
|
||||
template<typename T> struct _is_rvalue_reference<T&&> : true_type {};
|
||||
|
||||
template<typename T> struct _is_complete {
|
||||
template<typename U>
|
||||
static auto test(U*) -> bool_constant<sizeof(U) == sizeof(U)>;
|
||||
|
||||
@@ -213,6 +213,14 @@
|
||||
# define FENNEC_HAS_BUILTIN_IS_ENUM 0
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics.
|
||||
#if __has_builtin(__is_union)
|
||||
# define FENNEC_HAS_BUILTIN_IS_UNION 1
|
||||
# define FENNEC_BUILTIN_IS_UNION(arg) __is_union(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_UNION 0
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_final)
|
||||
# define FENNEC_HAS_BUILTIN_IS_FINAL 1
|
||||
@@ -221,12 +229,20 @@
|
||||
# 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)
|
||||
// Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_function)
|
||||
# define FENNEC_HAS_BUILTIN_IS_FUNCTION 1
|
||||
# define FENNEC_BUILTIN_IS_FUNCTION(arg) __is_function(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_FUNDAMENTAL 0
|
||||
# define FENNEC_HAS_BUILTIN_IS_FUNCTION 0
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_object)
|
||||
# define FENNEC_HAS_BUILTIN_IS_OBJECT 1
|
||||
# define FENNEC_BUILTIN_IS_OBJECT(arg) __is_object(arg)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_FUNCTION 0
|
||||
#endif
|
||||
|
||||
// Inconsistent without intrinsics
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
/// - \subpage fennec_lang_conditional_types
|
||||
/// - \subpage fennec_lang_numeric_transforms
|
||||
/// - \subpage fennec_lang_metasequences
|
||||
/// - \subpage fennec_lang_type_identity
|
||||
/// - \subpage fennec_lang_type_sequences
|
||||
/// - \subpage fennec_lang_type_traits
|
||||
/// - \subpage fennec_lang_type_transforms
|
||||
|
||||
@@ -51,6 +51,12 @@
|
||||
/// \ref fennec::replace_first_element "typename replace_first_element<ClassT, SubT, OriginT, RestT...>::type"<br>
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// \copydoc fennec::replace_first_element
|
||||
///
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// \ref fennec::is_unique "is_unique<TypesT...>::value"<br>
|
||||
/// \ref fennec::is_unique_v "is_unique_v<TypesT...>"
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// \copydoc fennec::is_unique
|
||||
/// </table>
|
||||
///
|
||||
|
||||
@@ -59,6 +65,12 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
|
||||
template<typename...TypesT> struct type_sequence {};
|
||||
|
||||
|
||||
// fennec::first_element ===============================================================================================
|
||||
|
||||
///
|
||||
/// \brief Get the first element of a template parameter pack
|
||||
/// \tparam TypesT the Parameter Pack
|
||||
@@ -69,8 +81,20 @@ template<typename...TypesT> struct first_element : detail::_first_element<TypesT
|
||||
template<typename...TypesT> using first_element_t = typename first_element<TypesT...>::type;
|
||||
|
||||
|
||||
|
||||
// fennec::nth_element =================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Gets the type of the nth element of the type sequence `TypesT...`
|
||||
/// \tparam n The index in the type sequence
|
||||
/// \tparam TypesT The type sequence
|
||||
template<size_t n, typename...TypesT> struct nth_element : detail::_nth_element<n, 0, TypesT...> {};
|
||||
|
||||
template<size_t n, typename...TypesT> using nth_element_t = nth_element<n, TypesT...>::type;
|
||||
|
||||
|
||||
|
||||
// fennec::replace_first_element =======================================================================================
|
||||
|
||||
///
|
||||
/// \brief Take a Template with a Pack `ClassT<ArgsT...>` and replace the first `ArgT` of `ArgsT...` with `SubT`
|
||||
@@ -84,6 +108,99 @@ template<
|
||||
struct replace_first_element<ClassT<OriginT, RestT...>, SubT> // Specialization
|
||||
{ using type = ClassT<SubT, RestT...>; }; // Definition
|
||||
|
||||
|
||||
|
||||
// fennec::max_element_size ============================================================================================
|
||||
|
||||
///
|
||||
/// \brief Gets the max value of the size of each type in the sequence, i.e. `max(sizeof(Ts)...)`
|
||||
/// \tparam Ts The type sequence to check
|
||||
template<typename...Ts> struct max_element_size : detail::_max_element_size<0, Ts...> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `max_element_size<Ts...>::value`
|
||||
/// \tparam Ts The type sequence to check
|
||||
template<typename...Ts> constexpr size_t max_element_size_v = max_element_size<Ts...>::value;
|
||||
|
||||
|
||||
|
||||
// fennec::find_element ================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Finds the index of `T` in `Ts`, if `T` is not found, results in `sizeof...(Ts)`
|
||||
/// \tparam T The type to find
|
||||
/// \tparam Ts The type sequence to check
|
||||
template<typename T, typename...Ts> struct find_element : detail::_find_element<0, T, Ts...> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `find_element<T, Ts...>::value`
|
||||
/// \tparam T The type to find
|
||||
/// \tparam Ts The type sequence to check
|
||||
template<typename T, typename...Ts> constexpr size_t find_element_v = find_element<T, Ts...>::value;
|
||||
|
||||
|
||||
|
||||
// fennec::search_element ==============================================================================================
|
||||
|
||||
|
||||
///
|
||||
/// \brief Find the first element in `TypesT...` that satisfies `SearchT<T>`
|
||||
/// \tparam SearchT A type that satisfies `template<typename>` and contains `static constexpr bool value;` to use for searching
|
||||
/// \tparam TypesT The type sequence to search
|
||||
template<template<typename> typename SearchT, typename...TypesT> struct search_element : detail::_search_element<SearchT, TypesT...> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `search_element_t<T, Ts...>::type`
|
||||
/// \tparam SearchT A type that satisfies `template<typename>` and contains `static constexpr bool value;` to use for searching
|
||||
/// \tparam TypesT The type sequence to search
|
||||
template<template<typename> typename SearchT, typename...TypesT> using search_element_t = search_element<SearchT, TypesT...>::type;
|
||||
|
||||
|
||||
template<template<typename, typename...> typename, typename, typename...> struct search_element_args;
|
||||
|
||||
template<template<typename, typename...> typename SearchT, typename...TypesT, typename...ArgsT>
|
||||
struct search_element_args<SearchT, type_sequence<ArgsT...>, TypesT...>
|
||||
: detail::_search_element_args<SearchT, detail::_type_sequence<ArgsT...>, TypesT...> {
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// fennec::contains_element ============================================================================================
|
||||
|
||||
///
|
||||
/// \brief Checks if the type sequence `Ts...` contains `T`
|
||||
/// \tparam T The type to find
|
||||
/// \tparam Ts The type sequence to check
|
||||
template<typename T, typename...Ts> struct contains_element : bool_constant<(is_same_v<T, Ts> or ...)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `contains_element_v<T, Ts...>::value`
|
||||
/// \tparam T The type to find
|
||||
/// \tparam Ts The type sequence to check
|
||||
template<typename T, typename...Ts> constexpr bool contains_element_v = contains_element<T, Ts...>::value;
|
||||
|
||||
|
||||
|
||||
// fennec::is_unique ===================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Checks if all types in a type sequence are unique
|
||||
/// \tparam Ts The type sequence to check
|
||||
template<typename...Ts> struct is_unique : false_type {};
|
||||
|
||||
// Single type case
|
||||
template<typename T> struct is_unique<T> : true_type {};
|
||||
|
||||
// Recursion case
|
||||
template<typename T, typename...Ts> requires(not is_same_v<T, Ts> && ...)
|
||||
struct is_unique<T, Ts...> : is_unique<Ts...> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_unique<Ts...>::value`
|
||||
/// \tparam Ts The type sequence to check
|
||||
template<typename...Ts> constexpr bool is_unique_v = is_unique<Ts...>::value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -360,7 +360,7 @@
|
||||
/// \ref fennec::is_nothrow_move_constructible "is_nothrow_move_constructible<ClassT, ArgsT...>::value"<br>
|
||||
/// \ref fennec::is_nothrow_move_constructible_v "is_nothrow_move_constructible_v<ClassT, ArgsT...>"
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// \movedetails fennec::is_move_constructible
|
||||
/// \copydetails fennec::is_move_constructible
|
||||
///
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// \ref fennec::is_assignable "is_assignable<ClassT, ArgsT...>::value"<br>
|
||||
@@ -390,7 +390,7 @@
|
||||
/// \ref fennec::is_nothrow_move_assignable "is_nothrow_move_assignable<ClassT, ArgsT...>::value"<br>
|
||||
/// \ref fennec::is_nothrow_move_assignable_v "is_nothrow_move_assignable_v<ClassT, ArgsT...>"
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// \movedetails fennec::is_move_assignable
|
||||
/// \copydetails fennec::is_move_assignable
|
||||
///
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// \ref fennec::is_destructible "is_destructible<ClassT, ArgsT...>::value"<br>
|
||||
@@ -446,7 +446,7 @@ constexpr inline bool is_constant_evaluated() noexcept {
|
||||
// fennec::is_void =====================================================================================================
|
||||
|
||||
///
|
||||
/// \brief check if \p T is of type void
|
||||
/// \brief Check if \p T is of type void
|
||||
///
|
||||
/// \details Stores a boolean value in `is_void::value`, representing whether the provided type is of base type void.
|
||||
/// \tparam T type to check
|
||||
@@ -454,7 +454,7 @@ template<typename T> struct is_void
|
||||
: detail::_is_void<remove_cvr_t<T>>{};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_void<T>::value```
|
||||
/// \brief Shorthand for ```is_void<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_void_v = is_void<T>::value;
|
||||
|
||||
@@ -463,7 +463,7 @@ template<typename T> constexpr bool_t is_void_v = is_void<T>::value;
|
||||
// fennec::is_null_pointer =============================================================================================
|
||||
|
||||
///
|
||||
/// \brief check if \p T is of type nullptr_t
|
||||
/// \brief Check if \p T is of type nullptr_t
|
||||
///
|
||||
/// \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
|
||||
@@ -471,7 +471,7 @@ template<typename T> struct is_null_pointer
|
||||
: detail::_is_null_pointer<remove_cvr_t<T>>{};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_null_pointer<T>::value```
|
||||
/// \brief Shorthand for ```is_null_pointer<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_null_pointer_v = is_null_pointer<T>::value;
|
||||
|
||||
@@ -482,7 +482,7 @@ template<typename T> constexpr bool_t is_null_pointer_v = is_null_pointer<T>::va
|
||||
#ifdef FENNEC_BUILTIN_IS_ARRAY
|
||||
|
||||
///
|
||||
/// \brief check if \p T is of an array type
|
||||
/// \brief Check if \p T is of an array type
|
||||
/// \tparam T type to check
|
||||
template<typename T> struct is_array
|
||||
: bool_constant<FENNEC_BUILTIN_IS_ARRAY(T)> {};
|
||||
@@ -490,7 +490,7 @@ template<typename T> struct is_array
|
||||
#else
|
||||
|
||||
///
|
||||
/// \brief check if \p T is of an array type
|
||||
/// \brief Check if \p T is of an array type
|
||||
/// \tparam T type to check
|
||||
template<typename T> struct is_array
|
||||
: false_type {};
|
||||
@@ -506,25 +506,72 @@ template<typename T> struct is_array<T[]>
|
||||
#endif
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_array<T>::value```
|
||||
/// \brief Shorthand for ```is_array<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_array_v = is_array<T>::value;
|
||||
|
||||
|
||||
|
||||
// fennec::is_enum ====================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if \p T is an enum
|
||||
/// \tparam T type to check
|
||||
template<typename T> struct is_enum
|
||||
: bool_constant<FENNEC_BUILTIN_IS_ENUM(T)> {};
|
||||
|
||||
///
|
||||
/// \brief Check if \p T is a class
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr size_t is_enum_v = is_enum<T>::value;
|
||||
|
||||
|
||||
|
||||
// fennec::is_union ====================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if \p T is a union
|
||||
/// \tparam T type to check
|
||||
template<typename T> struct is_union
|
||||
: bool_constant<FENNEC_BUILTIN_IS_UNION(T)> {};
|
||||
|
||||
///
|
||||
/// \brief Check if \p T is a class
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr size_t is_union_v = is_union<T>::value;
|
||||
|
||||
|
||||
|
||||
// fennec::is_class ====================================================================================================
|
||||
|
||||
///
|
||||
/// \brief check if \p T is a class
|
||||
/// \brief Check if \p T is a class
|
||||
/// \tparam T type to check
|
||||
template<typename T> struct is_class
|
||||
: bool_constant<FENNEC_BUILTIN_IS_CLASS(T)> {};
|
||||
|
||||
///
|
||||
/// \brief check if \p T is a class
|
||||
/// \brief Check if \p T is a class
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr size_t is_class_v = is_class<T>::value;
|
||||
|
||||
|
||||
|
||||
// fennec::is_function ====================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if \p T is a class
|
||||
/// \tparam T type to check
|
||||
template<typename T> struct is_function
|
||||
: bool_constant<FENNEC_BUILTIN_IS_FUNCTION(T)> {};
|
||||
|
||||
///
|
||||
/// \brief Check if \p T is a class
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr size_t is_function_v = is_function<T>::value;
|
||||
|
||||
|
||||
|
||||
// Integral Types ======================================================================================================
|
||||
|
||||
|
||||
@@ -532,7 +579,7 @@ template<typename T> constexpr size_t is_class_v = is_class<T>::value;
|
||||
// fennec::is_bool =====================================================================================================
|
||||
|
||||
///
|
||||
/// \brief check if \p T is of type 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
|
||||
@@ -540,12 +587,16 @@ template<typename T> struct is_bool
|
||||
: detail::_is_bool<remove_cvr_t<T>>{};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_bool<T>::value```
|
||||
/// \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
|
||||
/// \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
|
||||
@@ -553,13 +604,17 @@ template<typename T> struct is_integral
|
||||
: detail::_is_integral<remove_cvr_t<T>> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_integral<T>::value```
|
||||
/// \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_signed =================================================================================================
|
||||
|
||||
|
||||
///
|
||||
/// \brief check if \p T is of a signed integral
|
||||
/// \brief Check if \p T is of a signed integral
|
||||
///
|
||||
/// \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
|
||||
@@ -567,13 +622,17 @@ template<typename T> struct is_signed
|
||||
: detail::_is_signed<remove_cvr_t<T>> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_signed<T>::value```
|
||||
/// \brief Shorthand for ```is_signed<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_signed_v = is_signed<T>::value;
|
||||
|
||||
|
||||
|
||||
// fennec::is_unsigned =================================================================================================
|
||||
|
||||
|
||||
///
|
||||
/// \brief check if \p T is of an unsigned integral
|
||||
/// \brief Check if \p T is of an unsigned integral
|
||||
///
|
||||
/// \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
|
||||
@@ -581,7 +640,7 @@ template<typename T> struct is_unsigned
|
||||
: detail::_is_unsigned<remove_cvr_t<T>> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_unsigned<T>::value```
|
||||
/// \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;
|
||||
|
||||
@@ -590,15 +649,15 @@ 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
|
||||
/// \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`.
|
||||
/// \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```
|
||||
/// \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> {};
|
||||
|
||||
@@ -606,24 +665,69 @@ 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
|
||||
/// \brief Check if \p T is of a pointer type
|
||||
///
|
||||
/// \details Checks if type `T` is a floating point type and store it in `is_same::value`.
|
||||
/// \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_floating_point<T>::value```
|
||||
/// \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
|
||||
/// \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
|
||||
@@ -631,21 +735,38 @@ 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```
|
||||
/// \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
|
||||
/// \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```
|
||||
/// \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;
|
||||
|
||||
@@ -653,7 +774,7 @@ template<typename T> constexpr bool_t is_fundamental_v = is_fundamental<T>::valu
|
||||
// fennec::is_same =====================================================================================================
|
||||
|
||||
///
|
||||
/// \brief check if the two types are identical
|
||||
/// \brief Check if the two types are identical
|
||||
///
|
||||
/// \details Checks if `T0` and `T1` are identical and store it in `is_same::value`
|
||||
/// \tparam T0 first type to check
|
||||
@@ -664,7 +785,7 @@ template<typename T0, typename T1> struct is_same : false_type {};
|
||||
template<typename T> struct is_same<T, T> : true_type {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_same<T0, T1>::value```
|
||||
/// \brief Shorthand for ```is_same<T0, T1>::value```
|
||||
/// \tparam T0 first type to check
|
||||
/// \tparam T1 second type to check
|
||||
template<typename T0, typename T1> constexpr bool_t is_same_v = is_same<T0, T1> {};
|
||||
@@ -672,63 +793,63 @@ template<typename T0, typename T1> constexpr bool_t is_same_v = is_same<T0, T1>
|
||||
// fennec::is_complete ==============================================================================================
|
||||
|
||||
///
|
||||
/// \brief check if type `T` 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`
|
||||
/// \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
|
||||
/// \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`
|
||||
/// \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
|
||||
/// \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`
|
||||
/// \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
|
||||
/// \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`
|
||||
/// \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 ==============================================================================================
|
||||
|
||||
///
|
||||
/// \brief check if type `T0` can be converted `T1`
|
||||
/// \brief Check if type `T0` can be converted `T1`
|
||||
///
|
||||
/// \details Checks if `TypeT0`
|
||||
/// \tparam FromT First type
|
||||
@@ -737,7 +858,7 @@ template<typename FromT, typename ToT> struct is_convertible
|
||||
: bool_constant<FENNEC_BUILTIN_IS_CONVERTIBLE(FromT, ToT)> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `can_convert<TypeT0, TypeT1>::value`
|
||||
/// \brief Shorthand for `can_convert<TypeT0, TypeT1>::value`
|
||||
/// \param FromT First type
|
||||
/// \param ToT Second type
|
||||
template<typename FromT, typename ToT> constexpr bool_t is_convertible_v = is_convertible<FromT, ToT>{};
|
||||
@@ -779,7 +900,7 @@ template<typename ClassT> struct is_default_constructible
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_default_constructible<ClassT>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_default_constructible_v = is_default_constructible<ClassT>{};
|
||||
template<typename ClassT> constexpr bool_t is_default_constructible_v = is_default_constructible<ClassT>{};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -213,6 +213,8 @@ namespace fennec
|
||||
|
||||
using bool_t = bool; ///< \brief A conditional type
|
||||
|
||||
using byte_t = unsigned char; ///< \brief A type capable of holding a single byte
|
||||
|
||||
using char_t = char; ///< \brief A type capable of holding an ascii value
|
||||
using schar_t = signed char; ///< \brief A type with the size of a char, capable of holding a signed 8-bit integer
|
||||
using uchar_t = unsigned char; ///< \brief A type with the size of a char, capable of holding an unsigned 8-bit integer
|
||||
|
||||
Reference in New Issue
Block a user