- Bug fixing for RTTI

- Fixes for declval + separated into own file
 - is_iterable
 - fixes for doxygen generation
This commit is contained in:
2025-11-29 23:43:18 -05:00
parent fe8c3a4602
commit 6f09c3f7fe
36 changed files with 762 additions and 550 deletions

View File

@@ -114,6 +114,7 @@ add_library(fennec STATIC
include/fennec/containers/deque.h include/fennec/containers/deque.h
include/fennec/containers/dynarray.h include/fennec/containers/dynarray.h
include/fennec/containers/graph.h include/fennec/containers/graph.h
include/fennec/containers/initializer_list.h
include/fennec/containers/list.h include/fennec/containers/list.h
include/fennec/containers/map.h include/fennec/containers/map.h
include/fennec/containers/object_pool.h include/fennec/containers/object_pool.h
@@ -142,7 +143,7 @@ add_library(fennec STATIC
include/fennec/langcpp/intrinsics.h include/fennec/langcpp/intrinsics.h
include/fennec/langcpp/limits.h include/fennec/langcpp/limits.h
include/fennec/langcpp/numeric_transforms.h include/fennec/langcpp/numeric_transforms.h
include/fennec/langcpp/const_sequences.h include/fennec/langcpp/metasequences.h
include/fennec/langcpp/startup.h include/fennec/langcpp/startup.h
include/fennec/langcpp/type_identity.h include/fennec/langcpp/type_identity.h
include/fennec/langcpp/type_operators.h include/fennec/langcpp/type_operators.h
@@ -168,6 +169,10 @@ add_library(fennec STATIC
# RTTI ================================================================================================================= # RTTI =================================================================================================================
include/fennec/rtti/typeid.h include/fennec/rtti/typeid.h
include/fennec/rtti/type_data.h include/fennec/rtti/type_data.h
include/fennec/rtti/type.h
include/fennec/rtti/enable.h
include/fennec/rtti/forward.h
include/fennec/rtti/typelist.h
include/fennec/rtti/detail/_typeid.h include/fennec/rtti/detail/_typeid.h
@@ -217,7 +222,6 @@ add_library(fennec STATIC
include/fennec/math/ext/primes.h include/fennec/math/ext/primes.h
include/fennec/math/ext/quaternion.h include/fennec/math/ext/quaternion.h
include/fennec/math/ext/transform.h include/fennec/math/ext/transform.h
include/fennec/math/ext/trigonometric.h
include/fennec/math/detail/_fwd.h include/fennec/math/detail/_fwd.h
@@ -258,10 +262,9 @@ add_library(fennec STATIC
# EXTRA SOURCES ======================================================================================================== # EXTRA SOURCES ========================================================================================================
${FENNEC_EXTRA_SOURCES} ${FENNEC_EXTRA_SOURCES}
include/fennec/rtti/type.h include/fennec/langcpp/ranges.h
include/fennec/rtti/enable.h include/fennec/langcpp/declval.h
include/fennec/rtti/forward.h include/fennec/langcpp/detail/_declval.h
include/fennec/rtti/typelist.h
) )
add_dependencies(fennec metaprogramming fennec-dependencies) add_dependencies(fennec metaprogramming fennec-dependencies)

View File

@@ -2435,8 +2435,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = "FENNEC_SCALAR_TEMPLATE=" \ PREDEFINED = "FENNEC_DOXYGEN="
"FENNEC_VECTOR_TEMPLATE="
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The # tag can be used to specify a list of macro names that should be expanded. The

View File

@@ -166,13 +166,13 @@ public:
/// ///
/// \brief Checks if all elements in the arrays are equal /// \brief Checks if all elements in the arrays are equal
friend constexpr bool_t operator==(const array& lhs, const array& rhs) { friend constexpr bool_t operator==(const array& lhs, const array& rhs) {
return array::_compare(lhs, rhs, make_index_sequence<ElemV>{}); return array::_compare(lhs, rhs, make_index_metasequence<ElemV>{});
} }
/// ///
/// \brief Checks if any element in the arrays is not equal /// \brief Checks if any element in the arrays is not equal
friend constexpr bool_t operator!=(const array& lhs, const array& rhs) { friend constexpr bool_t operator!=(const array& lhs, const array& rhs) {
return not array::_compare(lhs, rhs, make_index_sequence<ElemV>{}); return not array::_compare(lhs, rhs, make_index_metasequence<ElemV>{});
} }
/// @} /// @}
@@ -217,7 +217,7 @@ public:
private: private:
template<size_t...i> template<size_t...i>
static bool _compare(const array& lhs, const array& rhs, const_index_sequence<i...>) { static bool _compare(const array& lhs, const array& rhs, index_metasequence<i...>) {
return ((lhs[i] == rhs[i]) && ...); return ((lhs[i] == rhs[i]) && ...);
} }
}; };

View File

@@ -18,7 +18,7 @@
#ifndef FENNEC_CONTAINERS_DETAIL_TUPLE_H #ifndef FENNEC_CONTAINERS_DETAIL_TUPLE_H
#define FENNEC_CONTAINERS_DETAIL_TUPLE_H #define FENNEC_CONTAINERS_DETAIL_TUPLE_H
#include <fennec/langcpp/const_sequences.h> #include <fennec/langcpp/metasequences.h>
#include <fennec/langcpp/utility.h> #include <fennec/langcpp/utility.h>
namespace fennec::detail namespace fennec::detail
@@ -43,7 +43,7 @@ template <typename, typename...>
struct _tuple; struct _tuple;
template <size_t...IndicesV, typename...TypesT> template <size_t...IndicesV, typename...TypesT>
struct _tuple<const_index_sequence<IndicesV...>, TypesT...> : _tuple_leaf<IndicesV, TypesT>... struct _tuple<index_metasequence<IndicesV...>, TypesT...> : _tuple_leaf<IndicesV, TypesT>...
{ {
template <typename...ArgsT> template <typename...ArgsT>
constexpr _tuple(ArgsT&&... args) constexpr _tuple(ArgsT&&... args)

View File

@@ -31,7 +31,7 @@
#ifndef FENNEC_CONTAINERS_DYNARRAY_H #ifndef FENNEC_CONTAINERS_DYNARRAY_H
#define FENNEC_CONTAINERS_DYNARRAY_H #define FENNEC_CONTAINERS_DYNARRAY_H
#include <initializer_list> #include <fennec/containers/initializer_list.h>
#include <fennec/langcpp/utility.h> #include <fennec/langcpp/utility.h>
#include <fennec/memory/allocator.h> #include <fennec/memory/allocator.h>
#include <fennec/memory/new.h> #include <fennec/memory/new.h>
@@ -157,9 +157,7 @@ public:
// This constructor should not be invokable since moving is a single object operation and will cause undefined // This constructor should not be invokable since moving is a single object operation and will cause undefined
// behaviour when moving to multiple elements // behaviour when moving to multiple elements
constexpr dynarray(size_t n, TypeT&& val) constexpr dynarray(size_t n, TypeT&& val) = delete;
: dynarray(n, fennec::copy(val)) {
};
/// ///
/// \brief Emplace Constructor /// \brief Emplace Constructor
@@ -201,6 +199,11 @@ public:
} }
} }
///
/// \brief Conversion Constructor, copies elements of conv as this `value_t`
/// \tparam OTypeT The other value type
/// \tparam OAlloc The other allocator type
/// \param conv The dynarray to convert
template<typename OTypeT, class OAlloc> template<typename OTypeT, class OAlloc>
constexpr dynarray(const dynarray<OTypeT, OAlloc>& conv) constexpr dynarray(const dynarray<OTypeT, OAlloc>& conv)
: _alloc(conv.size()) : _alloc(conv.size())
@@ -211,7 +214,11 @@ public:
} }
} }
constexpr dynarray(std::initializer_list<value_t> l, const alloc_t& alloc = alloc_t()) ///
/// \brief Initializer List Constructor
/// \param l List of elements to initialize with
/// \param alloc An allocator object to copy
constexpr dynarray(initializer_list<value_t> l, const alloc_t& alloc = alloc_t())
: _alloc(l.size(), alloc) : _alloc(l.size(), alloc)
, _size(l.size()) { , _size(l.size()) {
size_t i = 0; size_t i = 0;

View 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/>.
// =====================================================================================================================
///
/// \file initializer_list.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_CONTAINERS_INITIALIZER_LIST_H
#define FENNEC_CONTAINERS_INITIALIZER_LIST_H
// Since initializer lists are completely intertwined with the compiler, and this is part of the c++ standard
// (specifically standard, and not the standard template library) we need to use std::initializer_list.
// We can at least alias it for proper naming conventions.
#include <initializer_list>
namespace fennec
{
using std::initializer_list;
template<typename T>
constexpr const T* begin(initializer_list<T> inls) noexcept {
return inls.begin();
}
template<typename T>
constexpr const T* end(initializer_list<T> inls) noexcept {
return inls.end();
}
}
#endif // FENNEC_CONTAINERS_INITIALIZER_LIST_H

View File

@@ -76,9 +76,9 @@ constexpr const typename tuple<TypesT...>::template elem_t<i>& get(const tuple<T
template<typename ...TypesT> template<typename ...TypesT>
struct tuple : public detail::_tuple<make_index_sequence_t<sizeof...(TypesT)>, TypesT...> struct tuple : public detail::_tuple<make_index_metasequence_t<sizeof...(TypesT)>, TypesT...>
{ {
using base_t = detail::_tuple<make_index_sequence_t<sizeof...(TypesT)>, TypesT...>; using base_t = detail::_tuple<make_index_metasequence_t<sizeof...(TypesT)>, TypesT...>;
template<size_t i> template<size_t i>
using elem_t = typename nth_element<i, TypesT...>::type; using elem_t = typename nth_element<i, TypesT...>::type;

View File

@@ -0,0 +1,48 @@
// =====================================================================================================================
// 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 declval.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_LANGCPP_DECLVAL_H
#define FENNEC_LANGCPP_DECLVAL_H
#include <fennec/langcpp/detail/_declval.h>
namespace fennec
{
// fennec::declval =====================================================================================================
template<typename T> auto declval() noexcept -> decltype(detail::_declval<T>(0)) {
static_assert(detail::_declval_protector<T>{}, "declval must not be used");
return detail::_declval<T>(0);
}
}
#endif // FENNEC_LANGCPP_DECLVAL_H

View File

@@ -0,0 +1,46 @@
// =====================================================================================================================
// 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 _declval.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_LANGCPP_DETAIL_DECLVAL_H
#define FENNEC_LANGCPP_DETAIL_DECLVAL_H
#include <fennec/langcpp/constants.h>
namespace fennec::detail
{
template<typename T, typename U = T&&> U _declval(int);
template<typename T> T _declval(long);
template<typename T> struct _declval_protector : bool_constant<false> {};
}
#endif // FENNEC_LANGCPP_DETAIL_DECLVAL_H

View File

@@ -19,7 +19,9 @@
#ifndef FENNEC_LANG_DETAIL_TYPE_TRAITS_H #ifndef FENNEC_LANG_DETAIL_TYPE_TRAITS_H
#define FENNEC_LANG_DETAIL_TYPE_TRAITS_H #define FENNEC_LANG_DETAIL_TYPE_TRAITS_H
#include <fennec/langcpp/ranges.h>
#include <fennec/langcpp/constants.h> #include <fennec/langcpp/constants.h>
#include <fennec/langcpp/declval.h>
namespace fennec::detail namespace fennec::detail
{ {
@@ -64,11 +66,6 @@ namespace fennec::detail
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 T> struct _is_pointer<T*> : true_type {};
template<typename T, typename U = T&&> U _declval(int);
template<typename T> T _declval(long);
template<typename T> struct _declval_protector : bool_constant<false> {};
template<typename T> struct _is_complete { template<typename T> struct _is_complete {
template<typename U> template<typename U>
static auto test(U*) -> bool_constant<sizeof(U) == sizeof(U)>; static auto test(U*) -> bool_constant<sizeof(U) == sizeof(U)>;
@@ -77,19 +74,34 @@ namespace fennec::detail
}; };
template<typename T> struct _is_destructible { template<typename T> struct _is_destructible {
template<typename U, typename = decltype(_declval<T&>().~T())> template<typename U, typename = decltype(declval<T&>().~T())>
static auto test(int) -> true_type; static auto test(int) -> true_type;
template<typename>
static auto test(...) -> false_type; static auto test(...) -> false_type;
using type = decltype(test<T>(0)); using type = decltype(test<T>(0));
}; };
template<typename T> struct _is_nothrow_destructible { template<typename T> struct _is_nothrow_destructible {
template<typename U, typename = decltype(noexcept(_declval<T&>().~T()))> template<typename U, typename = decltype(noexcept(declval<T&>().~T()))>
static auto test(int) -> true_type; static auto test(int) -> true_type;
template<typename>
static auto test(...) -> false_type; static auto test(...) -> false_type;
using type = decltype(test<T>(0)); using type = decltype(test<T>(0));
}; };
// https://stackoverflow.com/questions/13830158/how-to-write-a-trait-which-checks-whether-a-type-is-iterable
template<typename T>
auto _is_iterable(int) -> decltype(
fennec::begin(declval<T&>()) != fennec::end(declval<T&>()),
void(),
++declval<decltype(fennec::begin(declval<T&>()))&>(),
void(*fennec::begin(declval<T&>())),
true_type{}
);
template<typename T>
auto _is_iterable(...) -> false_type;
} }
#endif // FENNEC_LANG_DETAIL_TYPE_TRAITS_H #endif // FENNEC_LANG_DETAIL_TYPE_TRAITS_H

View File

@@ -17,7 +17,7 @@
// ===================================================================================================================== // =====================================================================================================================
/// ///
/// \file langcpp.h /// \file lang.h
/// \brief \ref fennec_lang /// \brief \ref fennec_lang
/// ///
/// ///

View File

@@ -42,7 +42,7 @@
/// - \subpage fennec_lang_constants /// - \subpage fennec_lang_constants
/// - \subpage fennec_lang_conditional_types /// - \subpage fennec_lang_conditional_types
/// - \subpage fennec_lang_numeric_transforms /// - \subpage fennec_lang_numeric_transforms
/// - \subpage fennec_lang_sequences /// - \subpage fennec_lang_metasequences
/// - \subpage fennec_lang_type_sequences /// - \subpage fennec_lang_type_sequences
/// - \subpage fennec_lang_type_traits /// - \subpage fennec_lang_type_traits
/// - \subpage fennec_lang_type_transforms /// - \subpage fennec_lang_type_transforms

View File

@@ -17,8 +17,8 @@
// ===================================================================================================================== // =====================================================================================================================
/// ///
/// \file sequences.h /// \file metasequences.h
/// \brief \ref fennec_lang_sequences /// \brief \ref fennec_lang_metasequences
/// ///
/// ///
/// \details /// \details
@@ -32,40 +32,40 @@
#define FENNEC_LANG_SEQUENCES_H #define FENNEC_LANG_SEQUENCES_H
/// ///
/// \page fennec_lang_sequences Sequences /// \page fennec_lang_metasequences Metasequences
/// ///
/// \brief This header is part of the metaprogramming library. It defines structures for sequences of values, used during compile time. /// \brief This header is part of the metaprogramming library. It defines structures for metasequences of values, used during compile time.
/// ///
/// \code #include <fennec/langcpp/sequences.h> \endcode /// \code #include <fennec/langcpp/metasequences.h> \endcode
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_lang_sequences"> /// <table width="100%" class="fieldtable" id="table_fennec_lang_metasequences">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::sequence "sequence<ValueT, Values...>"<br> /// \ref fennec::metasequence "metasequence<ValueT, Values...>"<br>
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::sequence /// \copydetails fennec::metasequence
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::integer_sequence "integer_sequence<IntT, Values...>"<br> /// \ref fennec::integer_metasequence "integer_metasequence<IntT, Values...>"<br>
/// \ref fennec::make_integer_sequence "typename make_integer_sequence<IntT, N>::type"<br> /// \ref fennec::make_integer_metasequence "typename make_integer_metasequence<IntT, N>::type"<br>
/// \ref fennec::make_integer_sequence_t "make_integer_sequence_t<IntT, N>" /// \ref fennec::make_integer_metasequence_t "make_integer_metasequence_t<IntT, N>"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::integer_sequence /// \copydetails fennec::integer_metasequence
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::index_sequence "index_sequence<Indices...>"<br> /// \ref fennec::index_metasequence "index_metasequence<Indices...>"<br>
/// \ref fennec::make_index_sequence "typename make_index_sequence<N>::type"<br> /// \ref fennec::make_index_metasequence "typename make_index_metasequence<N>::type"<br>
/// \ref fennec::make_index_sequence_t "make_index_sequence_t<N>" /// \ref fennec::make_index_metasequence_t "make_index_metasequence_t<N>"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::index_sequence /// \copydetails fennec::index_metasequence
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::concat_sequence "typename concat_sequence<SequenceT0, SequenceT1>::type"<br> /// \ref fennec::concat_metasequence "typename concat_metasequence<metasequenceT0, metasequenceT1>::type"<br>
/// \ref fennec::concat_sequence_t "concat_sequence_t<SequenceT0, SequenceT1>"<br> /// \ref fennec::concat_metasequence_t "concat_metasequence_t<metasequenceT0, metasequenceT1>"<br>
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::concat_sequence /// \copydetails fennec::concat_metasequence
/// ///
/// </table> /// </table>
/// ///
@@ -75,7 +75,7 @@
namespace fennec namespace fennec
{ {
// fennec::sequence ==================================================================================================== // fennec::metasequence ====================================================================================================
/// ///
/// \brief metaprogramming sequence /// \brief metaprogramming sequence
@@ -84,20 +84,20 @@ namespace fennec
/// You can access the parameter pack in another template function, i.e. /// You can access the parameter pack in another template function, i.e.
/// \code{cpp} /// \code{cpp}
/// template<typename TypeT, TypeT...Values> /// template<typename TypeT, TypeT...Values>
/// constexpr TypeT summation(sequence<TypeT, Values...>) /// constexpr TypeT summation(metasequence<TypeT, Values...>)
/// { /// {
/// return (Values + ...); /// return (Values + ...);
/// } /// }
/// \endcode /// \endcode
/// \tparam ValueT type of the values /// \tparam ValueT type of the values
/// \tparam Values sequence values /// \tparam Values sequence values
template<typename ValueT, ValueT...Values> struct const_sequence template<typename ValueT, ValueT...Values> struct metasequence
{ {
/// \brief type of the sequence /// \brief type of the metasequence
using value_type = ValueT; using value_type = ValueT;
/// \brief self-referential type /// \brief self-referential type
using type = const_sequence; using type = metasequence;
/// ///
/// \brief returns the number of elements /// \brief returns the number of elements
@@ -110,22 +110,22 @@ template<typename ValueT, ValueT...Values> struct const_sequence
// fennec::integer_sequence ============================================================================================ // fennec::integer_metasequence ============================================================================================
/// ///
/// \brief metaprogramming integral sequence /// \brief metaprogramming integral metasequence
/// ///
/// \details A `fennec::sequence` specialized integer types. /// \details A `fennec::metasequence` specialized integer types.
/// \tparam IntT type of the values, must satisfy ```fennec::is_integral<T>``` /// \tparam IntT type of the values, must satisfy ```fennec::is_integral<T>```
/// \tparam Values sequence values /// \tparam Values sequence values
template<typename IntT, IntT...Values> requires(is_integral_v<IntT>) template<typename IntT, IntT...Values> requires(is_integral_v<IntT>)
struct const_integer_sequence : const_sequence<IntT, Values...> struct integer_metasequence : metasequence<IntT, Values...>
{ {
/// \brief type of the sequence /// \brief type of the sequence
using value_type = IntT; using value_type = IntT;
/// \brief self-referential type /// \brief self-referential type
using type = const_integer_sequence; using type = integer_metasequence;
/// ///
/// \brief returns the number of elements /// \brief returns the number of elements
@@ -138,33 +138,33 @@ struct const_integer_sequence : const_sequence<IntT, Values...>
/// ///
/// \brief generate a fennec::integer_sequence \f$\left[\,0\,\ldots\,N\,\right)\f$ /// \brief generate a fennec::integer_metasequence \f$\left[\,0\,\ldots\,N\,\right)\f$
/// ///
/// \details /// \details
/// \tparam IntT type of the values, must satisfy ```fennec::is_integral<T>``` /// \tparam IntT type of the values, must satisfy ```fennec::is_integral<T>```
/// \tparam N size of the sequence to generate /// \tparam N size of the metasequence to generate
template<typename IntT, size_t N> struct make_integer_sequence; template<typename IntT, size_t N> struct make_integer_metasequence;
/// ///
/// \brief shorthand for ```typename make_integer_sequence<T, N>::type``` /// \brief shorthand for ```typename make_integer_sequence<T, N>::type```
template<typename IntT, size_t N> using make_integer_sequence_t = typename make_integer_sequence<IntT, N>::type; template<typename IntT, size_t N> using make_integer_metasequence_t = typename make_integer_metasequence<IntT, N>::type;
// fennec::index_sequence ============================================================================================== // fennec::index_metasequence ==============================================================================================
/// ///
/// \brief metaprogramming integral sequence /// \brief metaprogramming integral metasequence
/// ///
/// \details A `fennec::integer_sequence` specialized for sequences of `size_t` indices. /// \details A `fennec::integer_metasequence` specialized for sequences of `size_t` indices.
/// \tparam Indices sequence values /// \tparam Indices sequence values
template<size_t...Indices> struct const_index_sequence : const_integer_sequence<size_t, Indices...> template<size_t...Indices> struct index_metasequence : integer_metasequence<size_t, Indices...>
{ {
/// \brief type of the sequence /// \brief type of the sequence
using value_type = size_t; using value_type = size_t;
/// \brief self-referential type /// \brief self-referential type
using type = const_index_sequence; using type = index_metasequence;
/// ///
/// \brief returns the number of elements /// \brief returns the number of elements
@@ -177,67 +177,67 @@ template<size_t...Indices> struct const_index_sequence : const_integer_sequence<
/// ///
/// \brief generate a fennec::index_sequence \f$\left[\,0\,\ldots\,N\,\right)\f$ /// \brief generate a fennec::index_metasequence \f$\left[\,0\,\ldots\,N\,\right)\f$
/// ///
/// \details /// \details
/// \tparam T type of the values, must satisfy ```fennec::is_integral<T>``` /// \tparam T type of the values, must satisfy ```fennec::is_integral<T>```
/// \tparam N size of the sequence to generate /// \tparam N size of the sequence to generate
template<size_t N> struct make_index_sequence; template<size_t N> struct make_index_metasequence;
/// ///
/// \brief shorthand for ```typename make_index_sequence<N>::type``` /// \brief shorthand for ```typename make_index_metasequence<N>::type```
template<size_t N> using make_index_sequence_t = typename make_index_sequence<N>::type; template<size_t N> using make_index_metasequence_t = typename make_index_metasequence<N>::type;
// fennec::concat_sequence ============================================================================================= // fennec::concat_metasequence =============================================================================================
/// ///
/// \brief concatenate two sequences /// \brief concatenate two metasequences
/// ///
/// \details A tool for concatenating two `fennec::sequence` types. /// \details A tool for concatenating two `fennec::metasequence` types.
/// \tparam SequenceT0 lhs /// \tparam SequenceT0 lhs
/// \tparam SequenceT1 rhs /// \tparam SequenceT1 rhs
template<typename SequenceT0, typename SequenceT1> struct concat_sequence; template<typename SequenceT0, typename SequenceT1> struct concat_metasequence;
/// ///
/// \brief shorthand for ```typename concat_sequence<SequenceT0, SequenceT1>::type``` /// \brief shorthand for ```typename concat_metasequence<SequenceT0, SequenceT1>::type```
template<typename SequenceT0, typename SequenceT1> using concat_sequence_t template<typename SequenceT0, typename SequenceT1> using concat_metasequence_t
= typename concat_sequence<SequenceT0, SequenceT1>::type; = typename concat_metasequence<SequenceT0, SequenceT1>::type;
// Internal ============================================================================================================ // Internal ============================================================================================================
// Implementation for Generating an integer_sequence // Implementation for Generating an integer_sequence
template<typename T, size_t N> struct make_integer_sequence : concat_sequence_t<make_integer_sequence_t<T, N / 2>, make_integer_sequence_t<T, N - N / 2>>{}; template<typename T, size_t N> struct make_integer_metasequence : concat_metasequence_t<make_integer_metasequence_t<T, N / 2>, make_integer_metasequence_t<T, N - N / 2>>{};
// Base Case of N=0 // Base Case of N=0
template<typename T> struct make_integer_sequence<T, 0> : const_integer_sequence<T> {}; template<typename T> struct make_integer_metasequence<T, 0> : integer_metasequence<T> {};
// Base Case of N=1 // Base Case of N=1
template<typename T> struct make_integer_sequence<T, 1> : const_integer_sequence<T, 0>{}; template<typename T> struct make_integer_metasequence<T, 1> : integer_metasequence<T, 0>{};
// Implementation for Generating an index_sequence // Implementation for Generating an index_sequence
template<size_t N> struct make_index_sequence : concat_sequence_t<make_index_sequence_t<N / 2>, make_index_sequence_t<N - N / 2>>{}; template<size_t N> struct make_index_metasequence : concat_metasequence_t<make_index_metasequence_t<N / 2>, make_index_metasequence_t<N - N / 2>>{};
// Base Case of N=0 // Base Case of N=0
template<> struct make_index_sequence<0> : const_index_sequence<> {}; template<> struct make_index_metasequence<0> : index_metasequence<> {};
// Base Case of N=1 // Base Case of N=1
template<> struct make_index_sequence<1> : const_index_sequence<0>{}; template<> struct make_index_metasequence<1> : index_metasequence<0>{};
// Specialization for integer sequences // Specialization for integer sequences
template<typename T, T...SequenceV0, T...SequenceV1> template<typename T, T...SequenceV0, T...SequenceV1>
struct concat_sequence<const_integer_sequence<T, SequenceV0...>, const_integer_sequence<T, SequenceV1...>> struct concat_metasequence<integer_metasequence<T, SequenceV0...>, integer_metasequence<T, SequenceV1...>>
: const_integer_sequence<T, SequenceV0..., (sizeof...(SequenceV0) + SequenceV1)...>{}; : integer_metasequence<T, SequenceV0..., (sizeof...(SequenceV0) + SequenceV1)...>{};
// Specialization for index sequences // Specialization for index sequences
template<size_t...SequenceV0, size_t...SequenceV1> template<size_t...SequenceV0, size_t...SequenceV1>
struct concat_sequence<const_index_sequence<SequenceV0...>, const_index_sequence<SequenceV1...>> struct concat_metasequence<index_metasequence<SequenceV0...>, index_metasequence<SequenceV1...>>
: const_index_sequence<SequenceV0..., (sizeof...(SequenceV0) + SequenceV1)...>{}; : index_metasequence<SequenceV0..., (sizeof...(SequenceV0) + SequenceV1)...>{};

View File

@@ -0,0 +1,72 @@
// =====================================================================================================================
// 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 ranges.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_LANGCPP_RANGES_H
#define FENNEC_LANGCPP_RANGES_H
#include <fennec/langcpp/types.h>
namespace fennec
{
template<typename ContainerT>
inline constexpr auto begin(ContainerT& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()) {
return c.begin();
}
template<typename ContainerT>
inline constexpr auto begin(const ContainerT& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()) {
return c.begin();
}
template<typename T, size_t N>
inline constexpr T* begin(T (&arr)[N]) noexcept {
return arr;
}
template<typename ContainerT>
inline constexpr auto end(ContainerT& c) noexcept(noexcept(c.end())) -> decltype(c.end()) {
return c.end();
}
template<typename ContainerT>
inline constexpr auto end(const ContainerT& c) noexcept(noexcept(c.end())) -> decltype(c.end()) {
return c.end();
}
template<typename T, size_t N>
inline constexpr T* end(T (&arr)[N]) noexcept {
return arr + N;
}
}
#endif // FENNEC_LANGCPP_RANGES_H

View File

@@ -434,13 +434,6 @@
namespace fennec namespace fennec
{ {
// fennec::declval =====================================================================================================
template<typename T> auto declval() noexcept -> decltype(detail::_declval<T>(0)) {
static_assert(detail::_declval_protector<T>{}, "declval must not be used");
return detail::_declval<T>(0);
}
constexpr inline bool is_constant_evaluated() noexcept { constexpr inline bool is_constant_evaluated() noexcept {
if consteval { if consteval {
return true; return true;
@@ -690,6 +683,20 @@ template<typename T> struct is_complete : detail::_is_complete<T>::type {};
/// \tparam T type to check /// \tparam T type to check
template<typename T> constexpr bool_t is_complete_v = is_complete<T>{}; template<typename T> constexpr bool_t is_complete_v = is_complete<T>{};
// fennec::is_complete ==============================================================================================
///
/// \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_convertible ============================================================================================== // fennec::is_convertible ==============================================================================================
/// ///

View File

@@ -31,6 +31,7 @@
#ifndef FENNEC_LANG_TYPE_TRANSFORMS_H #ifndef FENNEC_LANG_TYPE_TRANSFORMS_H
#define FENNEC_LANG_TYPE_TRANSFORMS_H #define FENNEC_LANG_TYPE_TRANSFORMS_H
#include <fennec/langcpp/conditional_types.h>
#include <fennec/langcpp/type_identity.h> #include <fennec/langcpp/type_identity.h>
#include <fennec/langcpp/detail/_type_traits.h> #include <fennec/langcpp/detail/_type_traits.h>
#include <fennec/langcpp/detail/_type_transforms.h> #include <fennec/langcpp/detail/_type_transforms.h>

View File

@@ -203,8 +203,6 @@
#include <fennec/langcpp/detail/_int.h> #include <fennec/langcpp/detail/_int.h>
#include <fennec/langcpp/conditional_types.h>
namespace fennec namespace fennec
{ {
// Basic Types ========================================================================================================= // Basic Types =========================================================================================================

View File

@@ -123,7 +123,6 @@ constexpr void swap(T& x, T& y) noexcept {
/// \param x first value /// \param x first value
/// \param y second value /// \param y second value
template<typename T> constexpr void swap(T& x, T& y) noexcept { template<typename T> constexpr void swap(T& x, T& y) noexcept {
#if FENNEC_COMPILER_GCC #if FENNEC_COMPILER_GCC
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"

View File

@@ -44,81 +44,81 @@
/// ///
/// ///
/// ///
/// \section section_sign_functions Sign /// \section fennec_math_common_section_sign_functions Sign Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_common_sign_functions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_common_sign_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::abs(fennec::genType) "genIType abs(genIType x)" <br> /// \ref fennec::abs "genIType abs(genIType x)" <br>
/// \ref fennec::abs(fennec::genType) "genFType abs(genFType x)" <br> /// \ref fennec::abs "genFType abs(genFType x)" <br>
/// \ref fennec::abs(fennec::genType) "genDType abs(genDType x)" /// \ref fennec::abs "genDType abs(genDType x)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::abs(fennec::genType) /// \copydetails fennec::abs
/// ///
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::sign(fennec::genType) "genIType sign(genIType x)" <br> /// \ref fennec::sign "genIType sign(genIType x)" <br>
/// \ref fennec::sign(fennec::genType) "genFType sign(genFType x)" <br> /// \ref fennec::sign "genFType sign(genFType x)" <br>
/// \ref fennec::sign(fennec::genType) "genDType sign(genDType x)" /// \ref fennec::sign "genDType sign(genDType x)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::sign(fennec::genType) /// \copydetails fennec::sign
/// ///
/// </table> /// </table>
/// ///
/// ///
/// \section section_rounding_functions Rounding /// \section fennec_math_common_section_rounding_functions Rounding Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_common_rounding_functions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_common_rounding_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::floor(fennec::genType) "genFType floor(genFType x)" <br> /// \ref fennec::floor "genFType floor(genFType x)" <br>
/// \ref fennec::floor(fennec::genType) "genDType floor(genDType x)" /// \ref fennec::floor "genDType floor(genDType x)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::floor(fennec::genType) /// \copydetails fennec::floor
/// ///
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::ceil(fennec::genType) "genFType ceil(genFType x)" <br> /// \ref fennec::ceil "genFType ceil(genFType x)" <br>
/// \ref fennec::ceil(fennec::genType) "genDType ceil(genDType x)" /// \ref fennec::ceil "genDType ceil(genDType x)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::ceil(fennec::genType) /// \copydetails fennec::ceil
/// ///
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::round(fennec::genType) "genFType round(genFType x)" <br> /// \ref fennec::round "genFType round(genFType x)" <br>
/// \ref fennec::round(fennec::genType) "genDType round(genDType x)" /// \ref fennec::round "genDType round(genDType x)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::round(fennec::genType) /// \copydetails fennec::round
/// ///
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::roundEven(fennec::genType) "genFType roundEven(genFType x)" <br> /// \ref fennec::roundEven "genFType roundEven(genFType x)" <br>
/// \ref fennec::roundEven(fennec::genType) "genDType roundEven(genDType x)" /// \ref fennec::roundEven "genDType roundEven(genDType x)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::roundEven(fennec::genType) /// \copydetails fennec::roundEven
/// ///
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::trunc(fennec::genType) "genFType trunc(genFType x)" <br> /// \ref fennec::trunc "genFType trunc(genFType x)" <br>
/// \ref fennec::trunc(fennec::genType) "genDType trunc(genDType x)" /// \ref fennec::trunc "genDType trunc(genDType x)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::trunc(fennec::genType) /// \copydetails fennec::trunc
/// ///
/// </table> /// </table>
/// ///
/// ///
/// \section section_decimal_functions Decimal-Point /// \section fennec_math_common_section_decimal_functions Decimal-Point Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_common_decimal_functions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_common_decimal_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::fract(fennec::genType) "genFType fract(genFType x)" <br> /// \ref fennec::fract "genFType fract(genFType x)" <br>
/// \ref fennec::fract(fennec::genType) "genDType fract(genDType x)" /// \ref fennec::fract "genDType fract(genDType x)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::fract(fennec::genType) /// \copydetails fennec::fract
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::mod "genFType mod(genFType x, float y)" <br> /// \ref fennec::mod "genFType mod(genFType x, float y)" <br>
@@ -129,59 +129,59 @@
/// \copydetails fennec::mod /// \copydetails fennec::mod
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::modf(fennec::genType, fennec::genType&) "genFType modf(genFType x, out genFType i)" <br> /// \ref fennec::modf "genFType modf(genFType x, out genFType i)" <br>
/// \ref fennec::modf(fennec::genType, fennec::genType&) "genDType modf(genDType x, out genDType i)" /// \ref fennec::modf "genDType modf(genDType x, out genDType i)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::modf(fennec::genType, fennec::genType&) /// \copydetails fennec::modf
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::isnan(fennec::genType) "genBType isnan(genFType x)" <br> /// \ref fennec::isnan "genBType isnan(genFType x)" <br>
/// \ref fennec::isnan(fennec::genType) "genBType isnan(genDType x)" /// \ref fennec::isnan "genBType isnan(genDType x)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::isnan(fennec::genType) /// \copydetails fennec::isnan
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::isinf(fennec::genType) "genBType isinf(genFType x)" <br> /// \ref fennec::isinf "genBType isinf(genFType x)" <br>
/// \ref fennec::isinf(fennec::genType) "genBType isinf(genDType x)" /// \ref fennec::isinf "genBType isinf(genDType x)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::isinf(fennec::genType) /// \copydetails fennec::isinf
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::frexp(fennec::genType, fennec::genIType&) "genFType frexp(genFType x, out genIType exp)" <br> /// \ref fennec::frexp "genFType frexp(genFType x, out genIType exp)" <br>
/// \ref fennec::frexp(fennec::genType, fennec::genIType&) "genDType frexp(genDType x, out genIType exp)" /// \ref fennec::frexp "genDType frexp(genDType x, out genIType exp)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::frexp(fennec::genType, fennec::genIType&) /// \copydetails fennec::frexp
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::ldexp(fennec::genType, fennec::genIType) "genFType ldexp(genFType x, genIType exp)" <br> /// \ref fennec::ldexp "genFType ldexp(genFType x, genIType exp)" <br>
/// \ref fennec::ldexp(fennec::genType, fennec::genIType) "genDType ldexp(genDType x, genIType exp)" /// \ref fennec::ldexp "genDType ldexp(genDType x, genIType exp)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::ldexp(fennec::genType, fennec::genIType) /// \copydetails fennec::ldexp
/// ///
/// </table> /// </table>
/// ///
/// ///
/// \section section_bit_conversion_functions Bit Conversion /// \section fennec_math_common_section_bit_functions Bit Conversion
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_common_bit_conversions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_common_bit_conversions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::floatBitsToInt(fennec::genType) "genIType floatBitsToInt(genType value)" <br> /// \ref fennec::floatBitsToInt "genIType floatBitsToInt(genType value)" <br>
/// \ref fennec::floatBitsToUint(fennec::genType) "genUType floatBitsToUint(genType value)" /// \ref fennec::floatBitsToUint "genUType floatBitsToUint(genType value)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::floatBitsToUint(fennec::genType) /// \copydetails fennec::floatBitsToUint
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::intBitsToFloat(fennec::genIType) "genFType intBitsToFloat(genIType value)" <br> /// \ref fennec::intBitsToFloat "genFType intBitsToFloat(genIType value)" <br>
/// \ref fennec::uintBitsToFloat(fennec::genUType) "genFType uintBitsToFloat(genUType value)" /// \ref fennec::uintBitsToFloat "genFType uintBitsToFloat(genUType value)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::uintBitsToFloat(fennec::genType) /// \copydetails fennec::uintBitsToFloat
/// ///
/// </table> /// </table>
/// ///
/// ///
/// \section section_comparison_functions Comparison /// \section fennec_math_common_section_comparison_functions Comparison Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_common_comparison_functions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_common_comparison_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
@@ -226,7 +226,7 @@
/// </table> /// </table>
/// ///
/// ///
/// \section section_curve_functions Curves /// \section fennec_math_common_section_curve_functions Curve Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_curve_functions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_curve_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
@@ -256,11 +256,11 @@
/// \copydetails fennec::mix /// \copydetails fennec::mix
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::mix(fennec::genBType, fennec::genBType, fennec::genBType) "mix(genBType x, genBType y, genBType a)" <br> /// \ref fennec::mix "mix(genBType x, genBType y, genBType a)" <br>
/// \ref fennec::mix(fennec::genType, fennec::genType, fennec::genBType) "mix(genIType x, genIType y, genBType a)" <br> /// \ref fennec::mix "mix(genIType x, genIType y, genBType a)" <br>
/// \ref fennec::mix(fennec::genType, fennec::genType, fennec::genBType) "mix(genUType x, genUType y, genBType a)" <br> /// \ref fennec::mix "mix(genUType x, genUType y, genBType a)" <br>
/// \ref fennec::mix(fennec::genType, fennec::genType, fennec::genBType) "mix(genFType x, genFType y, genBType a)" <br> /// \ref fennec::mix "mix(genFType x, genFType y, genBType a)" <br>
/// \ref fennec::mix(fennec::genType, fennec::genType, fennec::genBType) "mix(genDType x, genDType y, genBType a)" /// \ref fennec::mix "mix(genDType x, genDType y, genBType a)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::mix /// \copydetails fennec::mix
/// ///
@@ -308,14 +308,6 @@ constexpr genType sign(genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> sign(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::sign(x[i]) ...);
}
// Absolute Value ====================================================================================================== // Absolute Value ======================================================================================================
/// ///
@@ -331,14 +323,6 @@ constexpr genType abs(genType x) {
return x * fennec::sign(x); return x * fennec::sign(x);
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> abs(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::abs(x[i]) ...);
}
/// @} /// @}
@@ -366,14 +350,6 @@ constexpr genType floor(genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> floor(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::floor(x[i]) ...);
}
// Ceil ================================================================================================================ // Ceil ================================================================================================================
@@ -391,14 +367,6 @@ constexpr genType ceil(genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> ceil(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::ceil(x[i]) ...);
}
// Round =============================================================================================================== // Round ===============================================================================================================
@@ -416,14 +384,6 @@ template<typename genType> constexpr genType round(genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> round(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::round(x[i]) ...);
}
// Trunc =============================================================================================================== // Trunc ===============================================================================================================
@@ -441,14 +401,6 @@ constexpr genType trunc(genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> trunc(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::trunc(x[i]) ...);
}
// Round Even ========================================================================================================== // Round Even ==========================================================================================================
@@ -486,13 +438,6 @@ constexpr genType roundEven(genType x) {
//return i + static_cast<genType>(up); //return i + static_cast<genType>(up);
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> roundEven(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::roundEven(x[i]) ...);
}
/// @} /// @}
@@ -519,14 +464,6 @@ constexpr genType fract(genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> fract(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::fract(x[i]) ...);
}
// Mod ================================================================================================================= // Mod =================================================================================================================
/// ///
@@ -544,19 +481,6 @@ constexpr genType mod(genType x, genType y) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> mod(const vector<genType, i...>& x, genType y) {
return x - y * fennec::floor(x / y);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> mod(const vector<genType, i...>& x, const vector<genType, i...>& y) {
return x - y * fennec::floor(x / y);
}
// ModF ================================================================================================================ // ModF ================================================================================================================
/// ///
@@ -574,14 +498,6 @@ constexpr genType modf(genType x, genType& i) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> modf(const vector<genType, i...>& x, vector<genType, i...>& I) {
I = fennec::floor(x); return fennec::fract(x);
}
// Is NaN ============================================================================================================== // Is NaN ==============================================================================================================
/// ///
@@ -603,14 +519,6 @@ constexpr genBType isnan(genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, typename genBType = bool_t, size_t...i> requires(is_bool_v<genBType>)
constexpr vector<genBType, i...> isnan(const vector<genType, i...>& x) {
return vector<genBType, i...>(fennec::isnan(x[i]) ...);
}
// Is Inf ============================================================================================================== // Is Inf ==============================================================================================================
/// ///
@@ -627,19 +535,11 @@ constexpr genBType isinf(genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, typename genBType = bool_t, size_t...i> requires(is_bool_v<genBType>)
constexpr vector<genBType, i...> isinf(const vector<genType, i...>& x) {
return vector<genBType, i...>(fennec::isinf(x[i]) ...);
}
// Bit Conversion ====================================================================================================== // Bit Conversion ======================================================================================================
/// ///
/// \copydetails fennec::floatBitsToUint(fennec::genFType) /// \copydetails fennec::floatBitsToUint
template<typename genType, typename genIType = int_t> requires(is_floating_point_v<genType> and is_integral_v<genIType> and is_signed_v<genIType> and sizeof(genType) == sizeof(genIType)) template<typename genType, typename genIType = int_t> requires(is_floating_point_v<genType> and is_integral_v<genIType> and is_signed_v<genIType> and sizeof(genType) == sizeof(genIType))
constexpr genIType floatBitsToInt(genType x) { constexpr genIType floatBitsToInt(genType x) {
return fennec::bit_cast<genIType>(x); return fennec::bit_cast<genIType>(x);
@@ -669,7 +569,7 @@ constexpr genUType floatBitsToUint(genType x) {
/// ///
/// \copydetails fennec::uintBitsToFloat(fennec::genUType) /// \copydetails fennec::uintBitsToFloat
template<typename genType = float_t, typename genIType = int_t> requires(is_floating_point_v<genType> and is_integral_v<genIType> and is_signed_v<genIType> and sizeof(genType) == sizeof(genIType)) template<typename genType = float_t, typename genIType = int_t> requires(is_floating_point_v<genType> and is_integral_v<genIType> and is_signed_v<genIType> and sizeof(genType) == sizeof(genIType))
constexpr genType intBitsToFloat(genIType x) { constexpr genType intBitsToFloat(genIType x) {
return fennec::bit_cast<genType>(x); return fennec::bit_cast<genType>(x);
@@ -696,29 +596,6 @@ constexpr genType uintBitsToFloat(genUType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType = float_t, typename genIType = int_t, size_t...i> requires(is_floating_point_v<genType> and is_integral_v<genIType> and is_signed_v<genIType> and sizeof(genType) == sizeof(genIType))
constexpr vector<genIType, i...> floatBitsToInt(const vector<genType, i...>& x) {
return vector<genIType, i...>(fennec::bit_cast<genIType>(x[i])...);
}
template<typename genType = float_t, typename genUType = uint_t, size_t...i> requires(is_floating_point_v<genType> and is_integral_v<genUType> and is_unsigned_v<genUType> and sizeof(genType) == sizeof(genUType))
constexpr vector<genUType, i...> floatBitsToUint(const vector<genType, i...>& x) {
return vector<genUType, i...>(fennec::bit_cast<genUType>(x[i])...);
}
template<typename genType = float_t, typename genIType = int_t, size_t...i> requires(is_floating_point_v<genType> and is_integral_v<genIType> and is_signed_v<genIType> and sizeof(genType) == sizeof(genIType))
constexpr vector<genType, i...> intBitsToFloat(const vector<genIType, i...>& x) {
return vector<genType, i...>(fennec::bit_cast<genType>(x[i]) ...);
}
template<typename genType = float_t, typename genUType = uint_t, size_t...i> requires(is_floating_point_v<genType> and is_integral_v<genUType> and is_unsigned_v<genUType> and sizeof(genType) == sizeof(genUType))
constexpr vector<genType, i...> uintBitsToFloat(const vector<genUType, i...>& x) {
return vector<genType, i...>(fennec::bit_cast<genType>(x[i]) ...);
}
// fma ================================================================================================================= // fma =================================================================================================================
@@ -738,14 +615,6 @@ constexpr genType fma(genType a, genType b, genType c) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> fma(const vector<genType, i...>& a, const vector<genType, i...>& b, const vector<genType, i...>& c) {
return vector<genType, i...>(fennec::fma(a[i], b[i], c[i]) ...);
}
// frexp =============================================================================================================== // frexp ===============================================================================================================
@@ -769,14 +638,6 @@ constexpr genType frexp(genType x, genIType& exp) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, typename genIType = int_t, size_t...i> requires(is_integral_v<genIType>)
constexpr vector<genType, i...> frexp(const vector<genType, i...>& x, vector<genIType, i...>& exp) {
return vector<genType, i...>(fennec::frexp(x[i], exp[i])...);
}
// ldexp =============================================================================================================== // ldexp ===============================================================================================================
@@ -802,14 +663,6 @@ constexpr genType ldexp(genType x, genIType exp) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, typename genIType = int_t, size_t...i> requires(is_integral_v<genIType>)
constexpr vector<genType, i...> ldexp(const vector<genType, i...>& x, const vector<genIType, i...>& exp) {
return vector<genType, i...>(fennec::ldexp(x[i], exp[i])...);
}
/// @} /// @}
@@ -837,24 +690,6 @@ constexpr genType min(genType x, genType y) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> min(genType x, const vector<genType, i...>& y) {
return vector<genType, i...>(fennec::min(x, y[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> min(const vector<genType, i...>& x, genType y) {
return vector<genType, i...>(fennec::min(x[i], y) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> min(const vector<genType, i...>& x, const vector<genType, i...>& y) {
return vector<genType, i...>(fennec::min(x[i], y[i]) ...);
}
// Max ================================================================================================================= // Max =================================================================================================================
/// ///
@@ -872,24 +707,6 @@ constexpr genType max(genType x, genType y) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> max(genType x, const vector<genType, i...>& y) {
return vector<genType, i...>(fennec::max(x, y[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> max(const vector<genType, i...>& x, genType y) {
return vector<genType, i...>(fennec::max(x[i], y) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> max(const vector<genType, i...>& x, const vector<genType, i...>& y) {
return vector<genType, i...>(fennec::max(x[i], y[i]) ...);
}
// Clamp =============================================================================================================== // Clamp ===============================================================================================================
/// ///
@@ -908,19 +725,6 @@ constexpr genType clamp(genType x, genType minVal, genType maxVal) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> clamp(const vector<genType, i...>& x, genType minVal, genType maxVal) {
return vector<genType, i...>(fennec::min(fennec::max(x[i], minVal), maxVal)...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> clamp(const vector<genType, i...>& x, const vector<genType, i...>& minVal, const vector<genType, i...>& maxVal) {
return vector<genType, i...>(fennec::min(fennec::max(x[i], minVal[i]), maxVal[i])...);
}
/// @} /// @}
@@ -948,19 +752,6 @@ constexpr genType step(genType edge, genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> step(genType edge, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::step(edge, x[i]) ...);
}
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> step(const vector<genType, i...>& edge, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::step(edge[i], x[i]) ...);
}
// Smoothstep ========================================================================================================== // Smoothstep ==========================================================================================================
/// ///
@@ -989,19 +780,6 @@ constexpr genType smoothstep(genType edge0, genType edge1, genType x) {
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> smoothstep(genType edge0, genType edge1, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::smoothstep(edge0, edge1, x[i]) ...);
}
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> smoothstep(const vector<genType, i...>& edge0, const vector<genType, i...>& edge1, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::smoothstep(edge0[i], edge1[i], x[i]) ...);
}
// Mix ================================================================================================================= // Mix =================================================================================================================
/// ///
@@ -1022,18 +800,6 @@ constexpr genType mix(genType x, genType y, genType a) {
return x * (genType(1.0) - a) + y * a; return x * (genType(1.0) - a) + y * a;
} }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, genType a) {
return x * (genType(1.0) - a) + y * a;
}
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, const vector<genType, i...>& a) {
return x * (genType(1.0) - a) + y * a;
}
// Mix (Bool) ========================================================================================================== // Mix (Bool) ==========================================================================================================
@@ -1058,7 +824,177 @@ constexpr genType mix(genType x, genType y, genBType a) {
} }
// Vector Specializations ---------------------------------------------------------------------------------------------- // Internal ============================================================================================================
template<typename genType, size_t...i>
constexpr vector<genType, i...> sign(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::sign(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> abs(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::abs(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> floor(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::floor(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> ceil(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::ceil(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> round(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::round(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> trunc(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::trunc(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> roundEven(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::roundEven(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> fract(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::fract(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> mod(const vector<genType, i...>& x, genType y) {
return x - y * fennec::floor(x / y);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> mod(const vector<genType, i...>& x, const vector<genType, i...>& y) {
return x - y * fennec::floor(x / y);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> modf(const vector<genType, i...>& x, vector<genType, i...>& I) {
I = fennec::floor(x); return fennec::fract(x);
}
template<typename genType, typename genBType = bool_t, size_t...i> requires(is_bool_v<genBType>)
constexpr vector<genBType, i...> isnan(const vector<genType, i...>& x) {
return vector<genBType, i...>(fennec::isnan(x[i]) ...);
}
template<typename genType, typename genBType = bool_t, size_t...i> requires(is_bool_v<genBType>)
constexpr vector<genBType, i...> isinf(const vector<genType, i...>& x) {
return vector<genBType, i...>(fennec::isinf(x[i]) ...);
}
template<typename genType = float_t, typename genIType = int_t, size_t...i> requires(is_floating_point_v<genType> and is_integral_v<genIType> and is_signed_v<genIType> and sizeof(genType) == sizeof(genIType))
constexpr vector<genIType, i...> floatBitsToInt(const vector<genType, i...>& x) {
return vector<genIType, i...>(fennec::bit_cast<genIType>(x[i])...);
}
template<typename genType = float_t, typename genUType = uint_t, size_t...i> requires(is_floating_point_v<genType> and is_integral_v<genUType> and is_unsigned_v<genUType> and sizeof(genType) == sizeof(genUType))
constexpr vector<genUType, i...> floatBitsToUint(const vector<genType, i...>& x) {
return vector<genUType, i...>(fennec::bit_cast<genUType>(x[i])...);
}
template<typename genType = float_t, typename genIType = int_t, size_t...i> requires(is_floating_point_v<genType> and is_integral_v<genIType> and is_signed_v<genIType> and sizeof(genType) == sizeof(genIType))
constexpr vector<genType, i...> intBitsToFloat(const vector<genIType, i...>& x) {
return vector<genType, i...>(fennec::bit_cast<genType>(x[i]) ...);
}
template<typename genType = float_t, typename genUType = uint_t, size_t...i> requires(is_floating_point_v<genType> and is_integral_v<genUType> and is_unsigned_v<genUType> and sizeof(genType) == sizeof(genUType))
constexpr vector<genType, i...> uintBitsToFloat(const vector<genUType, i...>& x) {
return vector<genType, i...>(fennec::bit_cast<genType>(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> fma(const vector<genType, i...>& a, const vector<genType, i...>& b, const vector<genType, i...>& c) {
return vector<genType, i...>(fennec::fma(a[i], b[i], c[i]) ...);
}
template<typename genType, typename genIType = int_t, size_t...i> requires(is_integral_v<genIType>)
constexpr vector<genType, i...> frexp(const vector<genType, i...>& x, vector<genIType, i...>& exp) {
return vector<genType, i...>(fennec::frexp(x[i], exp[i])...);
}
template<typename genType, typename genIType = int_t, size_t...i> requires(is_integral_v<genIType>)
constexpr vector<genType, i...> ldexp(const vector<genType, i...>& x, const vector<genIType, i...>& exp) {
return vector<genType, i...>(fennec::ldexp(x[i], exp[i])...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> min(genType x, const vector<genType, i...>& y) {
return vector<genType, i...>(fennec::min(x, y[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> min(const vector<genType, i...>& x, genType y) {
return vector<genType, i...>(fennec::min(x[i], y) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> min(const vector<genType, i...>& x, const vector<genType, i...>& y) {
return vector<genType, i...>(fennec::min(x[i], y[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> max(genType x, const vector<genType, i...>& y) {
return vector<genType, i...>(fennec::max(x, y[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> max(const vector<genType, i...>& x, genType y) {
return vector<genType, i...>(fennec::max(x[i], y) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> max(const vector<genType, i...>& x, const vector<genType, i...>& y) {
return vector<genType, i...>(fennec::max(x[i], y[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> clamp(const vector<genType, i...>& x, genType minVal, genType maxVal) {
return vector<genType, i...>(fennec::min(fennec::max(x[i], minVal), maxVal)...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> clamp(const vector<genType, i...>& x, const vector<genType, i...>& minVal, const vector<genType, i...>& maxVal) {
return vector<genType, i...>(fennec::min(fennec::max(x[i], minVal[i]), maxVal[i])...);
}
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> step(genType edge, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::step(edge, x[i]) ...);
}
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> step(const vector<genType, i...>& edge, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::step(edge[i], x[i]) ...);
}
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> smoothstep(genType edge0, genType edge1, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::smoothstep(edge0, edge1, x[i]) ...);
}
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> smoothstep(const vector<genType, i...>& edge0, const vector<genType, i...>& edge1, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::smoothstep(edge0[i], edge1[i], x[i]) ...);
}
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, genType a) {
return x * (genType(1.0) - a) + y * a;
}
template<typename genType, size_t...i> requires(is_floating_point_v<genType>)
constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, const vector<genType, i...>& a) {
return x * (genType(1.0) - a) + y * a;
}
template<typename genType, typename genBType = bool_t, size_t...i> requires(is_bool_v<genBType> and is_floating_point_v<genType>) template<typename genType, typename genBType = bool_t, size_t...i> requires(is_bool_v<genBType> and is_floating_point_v<genType>)
constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, genBType a) { constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, genBType a) {

View File

@@ -29,10 +29,10 @@ template<typename ScalarT, size_t RowsV, size_t...ColIndicesV> struct matrix; //
// Simplified interface for creating sized vectors or matrices // Simplified interface for creating sized vectors or matrices
template<typename ScalarT, size_t SizeV> using vec template<typename ScalarT, size_t SizeV> using vec
= decltype(detail::_gen_vector<vector, ScalarT>(make_index_sequence<SizeV>{})); // Gets the type returned by this function = decltype(detail::_gen_vector<vector, ScalarT>(make_index_metasequence<SizeV>{})); // Gets the type returned by this function
template<typename ScalarT, size_t ColsV, size_t RowsV> using mat template<typename ScalarT, size_t ColsV, size_t RowsV> using mat
= decltype(detail::_gen_matrix<matrix, ScalarT, RowsV>(make_index_sequence<ColsV>{})); // Gets the type returned by this function = decltype(detail::_gen_matrix<matrix, ScalarT, RowsV>(make_index_metasequence<ColsV>{})); // Gets the type returned by this function
} }

View File

@@ -19,7 +19,7 @@
#ifndef FENNEC_MATH_DETAIL_TYPES_H #ifndef FENNEC_MATH_DETAIL_TYPES_H
#define FENNEC_MATH_DETAIL_TYPES_H #define FENNEC_MATH_DETAIL_TYPES_H
#include <fennec/langcpp/const_sequences.h> #include <fennec/langcpp/metasequences.h>
namespace fennec namespace fennec
{ {
@@ -28,11 +28,11 @@ namespace detail
{ {
template<template<typename, size_t...> typename VectorT, typename ScalarT, size_t...IndicesV> template<template<typename, size_t...> typename VectorT, typename ScalarT, size_t...IndicesV>
VectorT<ScalarT, IndicesV...> _gen_vector(const_index_sequence<IndicesV...>); // Helper for substituting a size N with sequence of integers VectorT<ScalarT, IndicesV...> _gen_vector(index_metasequence<IndicesV...>); // Helper for substituting a size N with sequence of integers
template<template<typename, size_t...> typename MatrixT, typename ScalarT, size_t RowsV, size_t...IndicesV> template<template<typename, size_t...> typename MatrixT, typename ScalarT, size_t RowsV, size_t...IndicesV>
MatrixT<ScalarT, RowsV, IndicesV...> _gen_matrix(const_index_sequence<IndicesV...>); // Helper for substituting a size Columns with sequence of integers MatrixT<ScalarT, RowsV, IndicesV...> _gen_matrix(index_metasequence<IndicesV...>); // Helper for substituting a size Columns with sequence of integers
} }

View File

@@ -42,45 +42,45 @@
/// \code #include <fennec/math/exponential.h> \endcode /// \code #include <fennec/math/exponential.h> \endcode
/// ///
/// ///
/// \section Exponential Functions /// \section fennec_math_exponential_section_functions Exponential Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_exponential_functions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_exponential_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description /// <th style="vertical-align: top">Description
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::pow(fennec::genType, fennec::genType) "genFType pow(genFType x, genFType y)" /// \ref fennec::pow "genFType pow(genFType x, genFType y)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::pow(fennec::genType, fennec::genType) /// \copydetails fennec::pow
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::exp(fennec::genType)"genFType exp(genFType x)" /// \ref fennec::exp"genFType exp(genFType x)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::exp(fennec::genType) /// \copydetails fennec::exp
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::exp2(fennec::genType) "genFType exp2(genFType x)" /// \ref fennec::exp2 "genFType exp2(genFType x)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::exp2(fennec::genType) /// \copydetails fennec::exp2
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::log(fennec::genType) "genFType log(genFType x)" /// \ref fennec::log "genFType log(genFType x)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::log(fennec::genType) /// \copydetails fennec::log
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::log2(fennec::genType) "genFType log2(genFType x)" /// \ref fennec::log2 "genFType log2(genFType x)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::log2(fennec::genType) /// \copydetails fennec::log2
/// ///
/// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br> /// <tr><td width="50%" style="vertical-align: top" class="odd_c"> <br>
/// \ref fennec::sqrt(fennec::genType) "genFType sqrt(genFType x)" /// \ref fennec::sqrt "genFType sqrt(genFType x)"
/// <td width="50%" style="vertical-align: top" class="odd_c"> /// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::sqrt(fennec::genType) /// \copydetails fennec::sqrt
/// ///
/// <tr><td width="50%" style="vertical-align: top"> <br> /// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::inversesqrt(fennec::genType) "genFType inversesqrt(genFType x)" /// \ref fennec::inversesqrt "genFType inversesqrt(genFType x)"
/// <td width="50%" style="vertical-align: top"> /// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::inversesqrt(fennec::genType) /// \copydetails fennec::inversesqrt
/// ///
/// </table> /// </table>
/// ///
@@ -110,14 +110,6 @@ constexpr genType pow(genType x, genType y) {
} }
// Vector Specialization -----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> pow(const vector<genType, i...> & x, const vector<genType, i...> & y) {
return vector<genType, i...>(fennec::pow(x[i], y[i]) ...);
}
// exp ================================================================================================================= // exp =================================================================================================================
/// ///
@@ -132,13 +124,6 @@ constexpr genType exp(genType x) {
} }
// Vector Specialization -----------------------------------------------------------------------------------------------
template<typename genType, size_t...i> constexpr vector<genType, i...> exp(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::exp(x[i]) ...);
}
// exp2 ================================================================================================================ // exp2 ================================================================================================================
/// ///
@@ -152,13 +137,6 @@ template<typename genType> constexpr genType exp2(genType x) {
} }
// Vector Specialization -----------------------------------------------------------------------------------------------
template<typename genType, size_t...i> constexpr vector<genType, i...> exp2(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::exp2(x[i]) ...);
}
// log ================================================================================================================= // log =================================================================================================================
/// ///
@@ -173,13 +151,6 @@ template<typename genType> constexpr genType log(genType x) {
} }
// Vector Specialization -----------------------------------------------------------------------------------------------
template<typename genType, size_t...i> constexpr genType log(const vector<genType, i...>& x) {
return vector<genType, i...>(log(x[i]) ...);
}
// log2 ================================================================================================================ // log2 ================================================================================================================
/// ///
@@ -195,13 +166,6 @@ template<typename genType> constexpr genType log2(genType x) {
} }
// Vector Specialization -----------------------------------------------------------------------------------------------
template<typename genType, size_t...i> constexpr genType log2(const vector<genType, i...>& x) {
return vector<genType, i...>(log2(x[i]) ...);
}
// sqrt ================================================================================================================ // sqrt ================================================================================================================
/// ///
@@ -216,13 +180,6 @@ template<typename genType> constexpr genType sqrt(genType x) {
} }
// Vector Specialization -----------------------------------------------------------------------------------------------
template<typename genType, size_t...i> constexpr genType sqrt(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::sqrt(x[i]) ...);
}
// inversesqrt ========================================================================================================= // inversesqrt =========================================================================================================
/// ///
@@ -237,7 +194,32 @@ template<typename genType> constexpr genType inversesqrt(genType x) {
} }
// Vector Specialization ----------------------------------------------------------------------------------------------- // Internal ============================================================================================================
template<typename genType, size_t...i>
constexpr vector<genType, i...> pow(const vector<genType, i...> & x, const vector<genType, i...> & y) {
return vector<genType, i...>(fennec::pow(x[i], y[i]) ...);
}
template<typename genType, size_t...i> constexpr vector<genType, i...> exp(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::exp(x[i]) ...);
}
template<typename genType, size_t...i> constexpr vector<genType, i...> exp2(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::exp2(x[i]) ...);
}
template<typename genType, size_t...i> constexpr genType log(const vector<genType, i...>& x) {
return vector<genType, i...>(log(x[i]) ...);
}
template<typename genType, size_t...i> constexpr genType log2(const vector<genType, i...>& x) {
return vector<genType, i...>(log2(x[i]) ...);
}
template<typename genType, size_t...i> constexpr genType sqrt(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::sqrt(x[i]) ...);
}
template<typename genType, size_t...i> template<typename genType, size_t...i>
constexpr vector<genType, i...> inversesqrt(const vector<genType, i...>& x) { constexpr vector<genType, i...> inversesqrt(const vector<genType, i...>& x) {

View File

@@ -21,7 +21,9 @@
#include <fennec/langcpp/limits.h> #include <fennec/langcpp/limits.h>
#include <fennec/math/common.h>
#include <fennec/math/trigonometric.h> #include <fennec/math/trigonometric.h>
#include <fennec/math/ext/quaternion.h> #include <fennec/math/ext/quaternion.h>
namespace fennec namespace fennec

View File

@@ -19,6 +19,7 @@
#ifndef FENNEC_MATH_EXT_QUATERNION_H #ifndef FENNEC_MATH_EXT_QUATERNION_H
#define FENNEC_MATH_EXT_QUATERNION_H #define FENNEC_MATH_EXT_QUATERNION_H
#include <fennec/math/geometric.h>
#include <fennec/math/vector_base.h> #include <fennec/math/vector_base.h>
namespace fennec namespace fennec
@@ -31,15 +32,13 @@ template<typename genType> using qua = quaternion<genType>;
using quat = qua<float>; using quat = qua<float>;
using dquat = qua<double>; using dquat = qua<double>;
///
/// \brief Dot Function #ifndef FENNEC_DOXYGEN
/// \param x the first quaternion
/// \param y the second quaternion
/// \returns The sum of component products.
template<typename genType> template<typename genType>
constexpr genType dot(const qua<genType>& x, const qua<genType>& y) { constexpr genType dot(const qua<genType>& x, const qua<genType>& y) {
return x.w*y.w + x.x*y.x + x.y*y.y + x.z*y.z; return x.w*y.w + x.x*y.x + x.y*y.y + x.z*y.z;
} }
#endif
/// ///
/// \brief Square Norm Function /// \brief Square Norm Function
@@ -283,7 +282,6 @@ public:
// Quaternion Vector Arithmetic Operators ============================================================================== // Quaternion Vector Arithmetic Operators ==============================================================================
/// \brief
constexpr friend vec3_t operator*(const quat_t& q, const vec3_t& v) { constexpr friend vec3_t operator*(const quat_t& q, const vec3_t& v) {
const vec3_t u = q.xyz; const vec3_t u = q.xyz;
const vec3_t uv = fennec::cross(u, v); const vec3_t uv = fennec::cross(u, v);

View File

@@ -19,7 +19,6 @@
#ifndef FENNEC_MATH_EXT_TRIGONOMETRIC_H #ifndef FENNEC_MATH_EXT_TRIGONOMETRIC_H
#define FENNEC_MATH_EXT_TRIGONOMETRIC_H #define FENNEC_MATH_EXT_TRIGONOMETRIC_H
#include <fennec/math/trigonometric.h>
#include <fennec/math/ext/quaternion.h> #include <fennec/math/ext/quaternion.h>
namespace fennec namespace fennec
@@ -27,6 +26,7 @@ namespace fennec
// Angle Conversions =================================================================================================== // Angle Conversions ===================================================================================================
#ifndef FENNEC_DOXYGEN
template<typename genType> template<typename genType>
constexpr qua<genType> radians(const qua<genType>& degrees) { constexpr qua<genType> radians(const qua<genType>& degrees) {
return qua<genType>(degrees * 0.01745329251994329576923690768489); return qua<genType>(degrees * 0.01745329251994329576923690768489);
@@ -37,7 +37,6 @@ constexpr qua<genType> degrees(const qua<genType>& radians) {
return qua<genType>(radians * 57.29577951308232087679815481410517); return qua<genType>(radians * 57.29577951308232087679815481410517);
} }
// Trigonometric Functions ============================================================================================= // Trigonometric Functions =============================================================================================
template<typename genType> template<typename genType>
@@ -162,6 +161,7 @@ constexpr qua<genType> atanh(const qua<genType>& x) {
fennec::atanh(x.z) fennec::atanh(x.z)
); );
} }
#endif
} }

View File

@@ -43,7 +43,7 @@
/// \code #include <fennec/math/geometric.h> \endcode /// \code #include <fennec/math/geometric.h> \endcode
/// ///
/// ///
/// \section Geometric Functions /// \section fennec_math_geometric_section_functions Geometric Functions
/// ///
/// <table width="100%" class="fieldtable" id="table_fennec_math_geometric_functions"> /// <table width="100%" class="fieldtable" id="table_fennec_math_geometric_functions">
/// <tr><th style="vertical-align: top">Syntax /// <tr><th style="vertical-align: top">Syntax
@@ -118,7 +118,7 @@ namespace fennec
// dot ----------------------------------------------------------------------------------------------------------------- // dot -----------------------------------------------------------------------------------------------------------------
/// ///
/// \brief Returns the dot product of \f$x\f$ and \f$y\f$, i.e., \f$x_0 \cdot y_0 + x_0 \cdot y_0 + \ldots\f$ /// \brief Returns the dot product of \f$x\f$ and \f$y\f$, i.e., \f$x_0 \cdot y_0 + x_1 \cdot y_1 + \ldots\f$
/// ///
/// \returns the dot product of \f$x\f$ and \f$y\f$, i.e., \f$x_0 \cdot y_0 + x_0 \cdot y_0 + \ldots\f$ <br><br> /// \returns the dot product of \f$x\f$ and \f$y\f$, i.e., \f$x_0 \cdot y_0 + x_0 \cdot y_0 + \ldots\f$ <br><br>
/// \details we can represent this in linear algebra as the following, <br><br> /// \details we can represent this in linear algebra as the following, <br><br>

View File

@@ -41,7 +41,7 @@
/// ///
/// ///
#include <fennec/langcpp/const_sequences.h> #include <fennec/langcpp/metasequences.h>
#include <fennec/math/swizzle_storage.h> #include <fennec/math/swizzle_storage.h>
@@ -79,7 +79,7 @@ public:
/// \return The Value of the Swizzle as a Vector /// \return The Value of the Swizzle as a Vector
constexpr VectorT decay() const { constexpr VectorT decay() const {
VectorT res; VectorT res;
return decay_impl(res, make_index_sequence<size>{}); return decay_impl(res, make_index_metasequence<size>{});
} }
/// ///
@@ -93,7 +93,7 @@ public:
private: private:
template<size_t...VecIndicesV> template<size_t...VecIndicesV>
constexpr VectorT& decay_impl(VectorT& vec, const_index_sequence<VecIndicesV...>) { constexpr VectorT& decay_impl(VectorT& vec, index_metasequence<VecIndicesV...>) {
return ((vec[VecIndicesV] = this->data[IndicesV]), ..., vec); return ((vec[VecIndicesV] = this->data[IndicesV]), ..., vec);
} }
}; };

View File

@@ -145,6 +145,8 @@
/// ///
#include <fennec/math/detail/_math.h> #include <fennec/math/detail/_math.h>
#include <fennec/math/vector.h>
#include <fennec/langcpp/types.h>
namespace fennec namespace fennec
{ {
@@ -167,11 +169,6 @@ constexpr genType radians(genType degrees) {
return genType(degrees * 0.01745329251994329576923690768489); return genType(degrees * 0.01745329251994329576923690768489);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> radians(const vector<genType, i...>& degrees) {
return vector<genType, i...>(degrees * 0.01745329251994329576923690768489);
}
/// ///
/// \brief Converts \f$radians\f$ to \f$degrees\f$, i.e., \f$radians\cdot\frac{\pi}{180}\f$ /// \brief Converts \f$radians\f$ to \f$degrees\f$, i.e., \f$radians\cdot\frac{\pi}{180}\f$
@@ -186,11 +183,6 @@ constexpr genType degrees(genType radians) {
return genType(radians * 57.29577951308232087679815481410517); return genType(radians * 57.29577951308232087679815481410517);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> degrees(const vector<genType, i...>& radians) {
return genType(radians * 57.29577951308232087679815481410517);
}
/// @} /// @}
@@ -213,11 +205,6 @@ constexpr genType sin(genType x) {
return ::sin(x); return ::sin(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> sin(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::sin(x[i]) ...);
}
/// ///
/// \brief The Standard Trigonometric Cosine /// \brief The Standard Trigonometric Cosine
@@ -232,11 +219,6 @@ constexpr genType cos(genType x) {
return ::cos(x); return ::cos(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> cos(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::cos(x[i]) ...);
}
/// ///
/// \brief The Standard Trigonometric Tangent /// \brief The Standard Trigonometric Tangent
@@ -251,11 +233,6 @@ constexpr genType tan(genType x) {
return ::tan(x); return ::tan(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> tan(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::tan(x[i]) ...);
}
/// @} /// @}
@@ -277,11 +254,6 @@ constexpr genType asin(genType x) {
return ::asin(x); return ::asin(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> asin(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::asin(x[i]) ...);
}
/// ///
/// \brief Arc Cosine. Returns an angle \f$\theta\f$ whose cosine is /a x. /// \brief Arc Cosine. Returns an angle \f$\theta\f$ whose cosine is /a x.
@@ -297,11 +269,6 @@ constexpr genType acos(genType x) {
return ::acos(x); return ::acos(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> acos(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::acos(x[i]) ...);
}
/// ///
/// \brief Arc Tangent. Returns an angle \f$\theta\f$ whose tangent is /a y_over_x. /// \brief Arc Tangent. Returns an angle \f$\theta\f$ whose tangent is /a y_over_x.
@@ -317,11 +284,6 @@ constexpr genType atan(genType y_over_x) {
return ::atan(y_over_x); return ::atan(y_over_x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> atan(const vector<genType, i...>& y_over_x) {
return vector<genType, i...>(fennec::atan(y_over_x[i]) ...);
}
/// ///
/// \brief Arc Tangent. Returns an angle whose tangent is \f$\frac{y}{x}\f$. /// \brief Arc Tangent. Returns an angle whose tangent is \f$\frac{y}{x}\f$.
@@ -338,11 +300,6 @@ constexpr genType atan(genType y, genType x) {
return ::atan2(y, x); return ::atan2(y, x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> atan(const vector<genType, i...>& y, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::atan(y[i], x[i]) ...);
}
/// @} /// @}
@@ -364,11 +321,6 @@ constexpr genType sinh(genType x) {
return ::sinh(x); return ::sinh(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> sinh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::sinh(x[i]) ...);
}
/// ///
/// \brief Returns the Hyperbolic Cosine Function, \f$\frac{{e}^{x}+{e}^{-x}}{2}\f$ /// \brief Returns the Hyperbolic Cosine Function, \f$\frac{{e}^{x}+{e}^{-x}}{2}\f$
@@ -381,11 +333,6 @@ constexpr genType cosh(genType x) {
return ::cosh(x); return ::cosh(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> cosh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::cosh(x[i]) ...);
}
/// ///
/// \brief Returns the Hyperbolic Tangent Function, \f$\frac{\text{sinh}(x)}{\text{cosh}(x)}\f$ /// \brief Returns the Hyperbolic Tangent Function, \f$\frac{\text{sinh}(x)}{\text{cosh}(x)}\f$
@@ -398,10 +345,6 @@ constexpr genType tanh(genType x) {
return ::tanh(x); return ::tanh(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> tanh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::tanh(x[i]) ...);
}
/// @} /// @}
@@ -421,11 +364,6 @@ constexpr genType asinh(genType x) {
return ::asinh(x); return ::asinh(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> asinh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::asinh(x[i]) ...);
}
/// ///
/// \brief The Inverse Hyperbolic Cosine Function /// \brief The Inverse Hyperbolic Cosine Function
@@ -439,11 +377,6 @@ constexpr genType acosh(genType x) {
return ::acosh(x); return ::acosh(x);
} }
template<typename genType, size_t...i>
constexpr vector<genType, i...> acosh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::acosh(x[i]) ...);
}
/// ///
/// \brief The Inverse Hyperbolic Tangent Function /// \brief The Inverse Hyperbolic Tangent Function
@@ -457,12 +390,88 @@ constexpr genType atanh(genType x) {
return ::atanh(x); return ::atanh(x);
} }
/// @}
// Internal ============================================================================================================
#ifndef FENNEC_DOXYGEN
template<typename genType, size_t...i>
constexpr vector<genType, i...> radians(const vector<genType, i...>& degrees) {
return vector<genType, i...>(degrees * 0.01745329251994329576923690768489);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> degrees(const vector<genType, i...>& radians) {
return genType(radians * 57.29577951308232087679815481410517);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> sin(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::sin(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> cos(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::cos(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> tan(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::tan(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> asin(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::asin(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> acos(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::acos(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> atan(const vector<genType, i...>& y_over_x) {
return vector<genType, i...>(fennec::atan(y_over_x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> atan(const vector<genType, i...>& y, const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::atan(y[i], x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> sinh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::sinh(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> cosh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::cosh(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> tanh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::tanh(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> asinh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::asinh(x[i]) ...);
}
template<typename genType, size_t...i>
constexpr vector<genType, i...> acosh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::acosh(x[i]) ...);
}
template<typename genType, size_t...i> template<typename genType, size_t...i>
constexpr vector<genType, i...> atanh(const vector<genType, i...>& x) { constexpr vector<genType, i...> atanh(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::atanh(x[i]) ...); return vector<genType, i...>(fennec::atanh(x[i]) ...);
} }
#endif
/// @}

View File

@@ -120,7 +120,7 @@ namespace fennec
/// \tparam ScalarT The type of the Components /// \tparam ScalarT The type of the Components
/// \tparam SizeV The number of Components /// \tparam SizeV The number of Components
template<typename ScalarT, size_t SizeV> template<typename ScalarT, size_t SizeV>
using vec = decltype(detail::_gen_vector<vector, ScalarT>(make_index_sequence<SizeV>{})); using vec = decltype(detail::_gen_vector<vector, ScalarT>(make_index_metasequence<SizeV>{}));
/// ///

View File

@@ -73,6 +73,8 @@ using ::wmemcmp;
/// \param rhs The second object, interpreted as an array of bytes /// \param rhs The second object, interpreted as an array of bytes
/// \param n0 The size, in bytes, of lhs /// \param n0 The size, in bytes, of lhs
/// \param n1 The size, in bytes, of rhs /// \param n1 The size, in bytes, of rhs
/// \returns \f$0\f$ if the first \f$min(n0, n1)\f$ bytes of \f$lhs\f$ and \f$rhs\f$ are equivalent. Otherwise, returns \f$1\f$
/// for the first byte \f$b\f$ where \f$lhs[b] > \f$ rhs[b]\f$, and \f$-1\f$ for \f$
constexpr int memcmp_s(const void* lhs, size_t n0, const void* rhs, size_t n1) { constexpr int memcmp_s(const void* lhs, size_t n0, const void* rhs, size_t n1) {
return memcmp(lhs, rhs, n0 < n1 ? n0 : n1); return memcmp(lhs, rhs, n0 < n1 ? n0 : n1);
} }
@@ -98,6 +100,7 @@ using ::wmemcpy;
/// \param src The source object, interpreted as an array of bytes /// \param src The source object, interpreted as an array of bytes
/// \param n0 The size, in bytes, of dst /// \param n0 The size, in bytes, of dst
/// \param n1 The size, in bytes, of src /// \param n1 The size, in bytes, of src
/// \returns \f$dst\f$
constexpr void* memcpy_s(void* dst, size_t n0, const void* src, size_t n1) { constexpr void* memcpy_s(void* dst, size_t n0, const void* src, size_t n1) {
return memcpy(dst, src, n0 < n1 ? n0 : n1); return memcpy(dst, src, n0 < n1 ? n0 : n1);
} }
@@ -117,6 +120,7 @@ using ::wmemmove;
/// \param src The source object, interpreted as an array of bytes /// \param src The source object, interpreted as an array of bytes
/// \param n0 The size, in bytes, of dst /// \param n0 The size, in bytes, of dst
/// \param n1 The size, in bytes, of src /// \param n1 The size, in bytes, of src
/// \returns \f$dst\f$
constexpr void* memmove_s(void* dst, size_t n0, const void* src, size_t n1) { constexpr void* memmove_s(void* dst, size_t n0, const void* src, size_t n1) {
return memmove(dst, src, n0 < n1 ? n0 : n1); return memmove(dst, src, n0 < n1 ? n0 : n1);
} }

View File

@@ -115,6 +115,7 @@ public:
/// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound. /// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound.
/// \param component The type of each component /// \param component The type of each component
/// \param layout The layout of components in each pixel /// \param layout The layout of components in each pixel
/// \param size The size of the image data in bytes, for compressed pixel formats
texture(GLsizei width, GLint mips, texture(GLsizei width, GLint mips,
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_1d void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_1d
: _handle(NULL) : _handle(NULL)
@@ -141,6 +142,7 @@ public:
/// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound. /// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound.
/// \param component The type of each component /// \param component The type of each component
/// \param layout The layout of components in each pixel /// \param layout The layout of components in each pixel
/// \param size The size of the image data in bytes, for compressed pixel formats
texture(GLsizei width, GLsizei height, GLint mips, texture(GLsizei width, GLsizei height, GLint mips,
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_2d and not cubemap void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_2d and not cubemap
: _handle(NULL) : _handle(NULL)
@@ -167,6 +169,7 @@ public:
/// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound. /// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound.
/// \param component The type of each component /// \param component The type of each component
/// \param layout The layout of components in each pixel /// \param layout The layout of components in each pixel
/// \param size The size of the image data in bytes, for compressed pixel formats
texture(GLsizei width, GLsizei height, GLsizei depth, GLsizei mips, texture(GLsizei width, GLsizei height, GLsizei depth, GLsizei mips,
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_3d and not cubemap void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_3d and not cubemap
: _handle(NULL) : _handle(NULL)
@@ -230,6 +233,7 @@ public:
/// \param faces An array of pointers to textures containing pixel data for each face /// \param faces An array of pointers to textures containing pixel data for each face
/// \param component The component type of the data /// \param component The component type of the data
/// \param layout The layout of the components in the pixel /// \param layout The layout of the components in the pixel
/// \param size The size of the image data in bytes, for compressed pixel formats
texture(GLsizei size, GLsizei mips, texture(GLsizei size, GLsizei mips,
const void* faces[6], GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires is_2d and cubemap const void* faces[6], GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires is_2d and cubemap
: _handle(NULL) : _handle(NULL)
@@ -258,6 +262,7 @@ public:
/// \param data A pointer to a buffer containing image data /// \param data A pointer to a buffer containing image data
/// \param component The component type of the data /// \param component The component type of the data
/// \param layout The layout of the components in the pixel /// \param layout The layout of the components in the pixel
/// \param size The size of the image data in bytes, for compressed pixel formats
/// ///
/// \details Requires OES_texture_cube_map_array /// \details Requires OES_texture_cube_map_array
texture(GLsizei size, GLsizei depth, GLsizei mips, texture(GLsizei size, GLsizei depth, GLsizei mips,

View File

@@ -39,22 +39,38 @@ namespace fennec
struct type { struct type {
///
/// \returns A const-qualified reference to a string containing the name of the type
const string& name() const { const string& name() const {
return _data->name; return _data->name;
} }
///
/// \returns An integer value containing the unique universal identifier for the type
uint64_t id() const { uint64_t id() const {
return _data->uuid; return _data->uuid;
} }
///
/// \returns A dynarray of all the super (base) types of the type
dynarray<type> supertypes() const { dynarray<type> supertypes() const {
return _data->supers; return _data->supers;
} }
///
/// \returns A dynarray of all the sub (child) types of the type
dynarray<type> subtypes() const { dynarray<type> subtypes() const {
return _data->subs; return _data->subs;
} }
bool is_iterable() const {
return _data->is_iterable;
}
///
/// \brief Type Equality Operator
/// \param c The type to check against
/// \returns True if the types are identical, false otherwise.
bool operator==(const type& c) const { bool operator==(const type& c) const {
return _data == c._data; return _data == c._data;
} }
@@ -66,6 +82,11 @@ struct type {
template<typename TypeT> template<typename TypeT>
static type get() { return type(static_cast<TypeT*>(nullptr)); } static type get() { return type(static_cast<TypeT*>(nullptr)); }
///
/// \brief Get the type info of the provided object.
/// \tparam TypeT The type, automatically deduced
/// \param t A pointer to an object
/// \returns The type info of the provided type
template<typename TypeT> template<typename TypeT>
static type get_from_instance(TypeT* t) { return type(t); } static type get_from_instance(TypeT* t) { return type(t); }

View File

@@ -49,6 +49,8 @@ struct type_data {
type_data* raw_type; type_data* raw_type;
dynarray<type_data*> supers; dynarray<type_data*> supers;
dynarray<type_data*> subs; dynarray<type_data*> subs;
bool is_iterable;
}; };
struct type_storage { struct type_storage {
@@ -71,7 +73,9 @@ private:
.raw_type = typeuuid<raw_t>() == typeuuid<T>() ? nullptr : type_storage::get_data<raw_t>(), .raw_type = typeuuid<raw_t>() == typeuuid<T>() ? nullptr : type_storage::get_data<raw_t>(),
.supers = type_storage::get_data(supers_t{}), .supers = type_storage::get_data(supers_t{}),
.subs = {} .subs = {},
.is_iterable = is_iterable_v<T>
}); });
for (type_data* t : res->supers) { for (type_data* t : res->supers) {

View File

@@ -17,7 +17,7 @@
// ===================================================================================================================== // =====================================================================================================================
/// ///
/// \file transform2d.h /// \file node2d.h
/// \brief /// \brief
/// ///
/// ///

View File

@@ -17,7 +17,7 @@
// ===================================================================================================================== // =====================================================================================================================
/// ///
/// \file node.h /// \file scene_node.h
/// \brief /// \brief
/// ///
/// ///

View File

@@ -60,6 +60,8 @@ inline void fennec_test_rtti() {
fennec_test_run(type::get<rtti_test_sub>().supertypes()[0].name(), string(detail::type_name<rtti_test_base>())); fennec_test_run(type::get<rtti_test_sub>().supertypes()[0].name(), string(detail::type_name<rtti_test_base>()));
fennec_test_run(type::get<rtti_test_base>().subtypes()[0].name(), string(detail::type_name<rtti_test_sub>())); fennec_test_run(type::get<rtti_test_base>().subtypes()[0].name(), string(detail::type_name<rtti_test_sub>()));
fennec_test_run(type::get<dynarray<int>>().is_iterable(), true);
} }
} }