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

View File

@@ -2435,8 +2435,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = "FENNEC_SCALAR_TEMPLATE=" \
"FENNEC_VECTOR_TEMPLATE="
PREDEFINED = "FENNEC_DOXYGEN="
# 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

View File

@@ -166,13 +166,13 @@ public:
///
/// \brief Checks if all elements in the arrays are equal
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
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:
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]) && ...);
}
};

View File

@@ -18,7 +18,7 @@
#ifndef 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>
namespace fennec::detail
@@ -43,7 +43,7 @@ template <typename, typename...>
struct _tuple;
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>
constexpr _tuple(ArgsT&&... args)

View File

@@ -31,7 +31,7 @@
#ifndef 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/memory/allocator.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
// behaviour when moving to multiple elements
constexpr dynarray(size_t n, TypeT&& val)
: dynarray(n, fennec::copy(val)) {
};
constexpr dynarray(size_t n, TypeT&& val) = delete;
///
/// \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>
constexpr dynarray(const dynarray<OTypeT, OAlloc>& conv)
: _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)
, _size(l.size()) {
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>
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>
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
#define FENNEC_LANG_DETAIL_TYPE_TRAITS_H
#include <fennec/langcpp/ranges.h>
#include <fennec/langcpp/constants.h>
#include <fennec/langcpp/declval.h>
namespace fennec::detail
{
@@ -64,11 +66,6 @@ namespace fennec::detail
template<typename> struct _is_pointer : false_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 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 U, typename = decltype(_declval<T&>().~T())>
template<typename U, typename = decltype(declval<T&>().~T())>
static auto test(int) -> true_type;
template<typename>
static auto test(...) -> false_type;
using type = decltype(test<T>(0));
};
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;
template<typename>
static auto test(...) -> false_type;
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

View File

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

View File

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

View File

@@ -17,8 +17,8 @@
// =====================================================================================================================
///
/// \file sequences.h
/// \brief \ref fennec_lang_sequences
/// \file metasequences.h
/// \brief \ref fennec_lang_metasequences
///
///
/// \details
@@ -32,40 +32,40 @@
#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
/// <th style="vertical-align: top">Description
///
/// <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">
/// \copydetails fennec::sequence
/// \copydetails fennec::metasequence
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::integer_sequence "integer_sequence<IntT, Values...>"<br>
/// \ref fennec::make_integer_sequence "typename make_integer_sequence<IntT, N>::type"<br>
/// \ref fennec::make_integer_sequence_t "make_integer_sequence_t<IntT, N>"
/// \ref fennec::integer_metasequence "integer_metasequence<IntT, Values...>"<br>
/// \ref fennec::make_integer_metasequence "typename make_integer_metasequence<IntT, N>::type"<br>
/// \ref fennec::make_integer_metasequence_t "make_integer_metasequence_t<IntT, N>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::integer_sequence
/// \copydetails fennec::integer_metasequence
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::index_sequence "index_sequence<Indices...>"<br>
/// \ref fennec::make_index_sequence "typename make_index_sequence<N>::type"<br>
/// \ref fennec::make_index_sequence_t "make_index_sequence_t<N>"
/// \ref fennec::index_metasequence "index_metasequence<Indices...>"<br>
/// \ref fennec::make_index_metasequence "typename make_index_metasequence<N>::type"<br>
/// \ref fennec::make_index_metasequence_t "make_index_metasequence_t<N>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::index_sequence
/// \copydetails fennec::index_metasequence
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::concat_sequence "typename concat_sequence<SequenceT0, SequenceT1>::type"<br>
/// \ref fennec::concat_sequence_t "concat_sequence_t<SequenceT0, SequenceT1>"<br>
/// \ref fennec::concat_metasequence "typename concat_metasequence<metasequenceT0, metasequenceT1>::type"<br>
/// \ref fennec::concat_metasequence_t "concat_metasequence_t<metasequenceT0, metasequenceT1>"<br>
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::concat_sequence
/// \copydetails fennec::concat_metasequence
///
/// </table>
///
@@ -75,7 +75,7 @@
namespace fennec
{
// fennec::sequence ====================================================================================================
// fennec::metasequence ====================================================================================================
///
/// \brief metaprogramming sequence
@@ -84,20 +84,20 @@ namespace fennec
/// You can access the parameter pack in another template function, i.e.
/// \code{cpp}
/// template<typename TypeT, TypeT...Values>
/// constexpr TypeT summation(sequence<TypeT, Values...>)
/// constexpr TypeT summation(metasequence<TypeT, Values...>)
/// {
/// return (Values + ...);
/// }
/// \endcode
/// \tparam ValueT type of the 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;
/// \brief self-referential type
using type = const_sequence;
using type = metasequence;
///
/// \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 Values sequence values
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
using value_type = IntT;
/// \brief self-referential type
using type = const_integer_sequence;
using type = integer_metasequence;
///
/// \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
/// \tparam IntT type of the values, must satisfy ```fennec::is_integral<T>```
/// \tparam N size of the sequence to generate
template<typename IntT, size_t N> struct make_integer_sequence;
/// \tparam N size of the metasequence to generate
template<typename IntT, size_t N> struct make_integer_metasequence;
///
/// \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
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
using value_type = size_t;
/// \brief self-referential type
using type = const_index_sequence;
using type = index_metasequence;
///
/// \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
/// \tparam T type of the values, must satisfy ```fennec::is_integral<T>```
/// \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```
template<size_t N> using make_index_sequence_t = typename make_index_sequence<N>::type;
/// \brief shorthand for ```typename make_index_metasequence<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 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```
template<typename SequenceT0, typename SequenceT1> using concat_sequence_t
= typename concat_sequence<SequenceT0, SequenceT1>::type;
/// \brief shorthand for ```typename concat_metasequence<SequenceT0, SequenceT1>::type```
template<typename SequenceT0, typename SequenceT1> using concat_metasequence_t
= typename concat_metasequence<SequenceT0, SequenceT1>::type;
// Internal ============================================================================================================
// 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
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
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
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
template<> struct make_index_sequence<0> : const_index_sequence<> {};
template<> struct make_index_metasequence<0> : index_metasequence<> {};
// 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
template<typename T, T...SequenceV0, T...SequenceV1>
struct concat_sequence<const_integer_sequence<T, SequenceV0...>, const_integer_sequence<T, SequenceV1...>>
: const_integer_sequence<T, SequenceV0..., (sizeof...(SequenceV0) + SequenceV1)...>{};
struct concat_metasequence<integer_metasequence<T, SequenceV0...>, integer_metasequence<T, SequenceV1...>>
: integer_metasequence<T, SequenceV0..., (sizeof...(SequenceV0) + SequenceV1)...>{};
// Specialization for index sequences
template<size_t...SequenceV0, size_t...SequenceV1>
struct concat_sequence<const_index_sequence<SequenceV0...>, const_index_sequence<SequenceV1...>>
: const_index_sequence<SequenceV0..., (sizeof...(SequenceV0) + SequenceV1)...>{};
struct concat_metasequence<index_metasequence<SequenceV0...>, index_metasequence<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
{
// 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 {
if consteval {
return true;
@@ -690,6 +683,20 @@ template<typename T> struct is_complete : detail::_is_complete<T>::type {};
/// \tparam T type to check
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 ==============================================================================================
///

View File

@@ -31,6 +31,7 @@
#ifndef 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/detail/_type_traits.h>
#include <fennec/langcpp/detail/_type_transforms.h>

View File

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

View File

@@ -123,7 +123,6 @@ constexpr void swap(T& x, T& y) noexcept {
/// \param x first value
/// \param y second value
template<typename T> constexpr void swap(T& x, T& y) noexcept {
#if FENNEC_COMPILER_GCC
#pragma GCC diagnostic push
#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">
/// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::abs(fennec::genType) "genIType abs(genIType x)" <br>
/// \ref fennec::abs(fennec::genType) "genFType abs(genFType x)" <br>
/// \ref fennec::abs(fennec::genType) "genDType abs(genDType x)"
/// \ref fennec::abs "genIType abs(genIType x)" <br>
/// \ref fennec::abs "genFType abs(genFType x)" <br>
/// \ref fennec::abs "genDType abs(genDType x)"
/// <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>
/// \ref fennec::sign(fennec::genType) "genIType sign(genIType x)" <br>
/// \ref fennec::sign(fennec::genType) "genFType sign(genFType x)" <br>
/// \ref fennec::sign(fennec::genType) "genDType sign(genDType x)"
/// \ref fennec::sign "genIType sign(genIType x)" <br>
/// \ref fennec::sign "genFType sign(genFType x)" <br>
/// \ref fennec::sign "genDType sign(genDType x)"
/// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::sign(fennec::genType)
/// \copydetails fennec::sign
///
/// </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">
/// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::floor(fennec::genType) "genFType floor(genFType x)" <br>
/// \ref fennec::floor(fennec::genType) "genDType floor(genDType x)"
/// \ref fennec::floor "genFType floor(genFType x)" <br>
/// \ref fennec::floor "genDType floor(genDType x)"
/// <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>
/// \ref fennec::ceil(fennec::genType) "genFType ceil(genFType x)" <br>
/// \ref fennec::ceil(fennec::genType) "genDType ceil(genDType x)"
/// \ref fennec::ceil "genFType ceil(genFType x)" <br>
/// \ref fennec::ceil "genDType ceil(genDType x)"
/// <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>
/// \ref fennec::round(fennec::genType) "genFType round(genFType x)" <br>
/// \ref fennec::round(fennec::genType) "genDType round(genDType x)"
/// \ref fennec::round "genFType round(genFType x)" <br>
/// \ref fennec::round "genDType round(genDType x)"
/// <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>
/// \ref fennec::roundEven(fennec::genType) "genFType roundEven(genFType x)" <br>
/// \ref fennec::roundEven(fennec::genType) "genDType roundEven(genDType x)"
/// \ref fennec::roundEven "genFType roundEven(genFType x)" <br>
/// \ref fennec::roundEven "genDType roundEven(genDType x)"
/// <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>
/// \ref fennec::trunc(fennec::genType) "genFType trunc(genFType x)" <br>
/// \ref fennec::trunc(fennec::genType) "genDType trunc(genDType x)"
/// \ref fennec::trunc "genFType trunc(genFType x)" <br>
/// \ref fennec::trunc "genDType trunc(genDType x)"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::trunc(fennec::genType)
/// \copydetails fennec::trunc
///
/// </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">
/// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::fract(fennec::genType) "genFType fract(genFType x)" <br>
/// \ref fennec::fract(fennec::genType) "genDType fract(genDType x)"
/// \ref fennec::fract "genFType fract(genFType x)" <br>
/// \ref fennec::fract "genDType fract(genDType x)"
/// <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>
/// \ref fennec::mod "genFType mod(genFType x, float y)" <br>
@@ -129,59 +129,59 @@
/// \copydetails fennec::mod
///
/// <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(fennec::genType, fennec::genType&) "genDType modf(genDType x, out genDType i)"
/// \ref fennec::modf "genFType modf(genFType x, out genFType i)" <br>
/// \ref fennec::modf "genDType modf(genDType x, out genDType i)"
/// <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>
/// \ref fennec::isnan(fennec::genType) "genBType isnan(genFType x)" <br>
/// \ref fennec::isnan(fennec::genType) "genBType isnan(genDType x)"
/// \ref fennec::isnan "genBType isnan(genFType x)" <br>
/// \ref fennec::isnan "genBType isnan(genDType x)"
/// <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>
/// \ref fennec::isinf(fennec::genType) "genBType isinf(genFType x)" <br>
/// \ref fennec::isinf(fennec::genType) "genBType isinf(genDType x)"
/// \ref fennec::isinf "genBType isinf(genFType x)" <br>
/// \ref fennec::isinf "genBType isinf(genDType x)"
/// <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>
/// \ref fennec::frexp(fennec::genType, fennec::genIType&) "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 "genFType frexp(genFType x, out genIType exp)" <br>
/// \ref fennec::frexp "genDType frexp(genDType x, out genIType exp)"
/// <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>
/// \ref fennec::ldexp(fennec::genType, fennec::genIType) "genFType ldexp(genFType x, genIType exp)" <br>
/// \ref fennec::ldexp(fennec::genType, fennec::genIType) "genDType ldexp(genDType x, genIType exp)"
/// \ref fennec::ldexp "genFType ldexp(genFType x, genIType exp)" <br>
/// \ref fennec::ldexp "genDType ldexp(genDType x, genIType exp)"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::ldexp(fennec::genType, fennec::genIType)
/// \copydetails fennec::ldexp
///
/// </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">
/// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::floatBitsToInt(fennec::genType) "genIType floatBitsToInt(genType value)" <br>
/// \ref fennec::floatBitsToUint(fennec::genType) "genUType floatBitsToUint(genType value)"
/// \ref fennec::floatBitsToInt "genIType floatBitsToInt(genType value)" <br>
/// \ref fennec::floatBitsToUint "genUType floatBitsToUint(genType value)"
/// <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>
/// \ref fennec::intBitsToFloat(fennec::genIType) "genFType intBitsToFloat(genIType value)" <br>
/// \ref fennec::uintBitsToFloat(fennec::genUType) "genFType uintBitsToFloat(genUType value)"
/// \ref fennec::intBitsToFloat "genFType intBitsToFloat(genIType value)" <br>
/// \ref fennec::uintBitsToFloat "genFType uintBitsToFloat(genUType value)"
/// <td width="50%" style="vertical-align: top" class="odd_c">
/// \copydetails fennec::uintBitsToFloat(fennec::genType)
/// \copydetails fennec::uintBitsToFloat
///
/// </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">
/// <tr><th style="vertical-align: top">Syntax
@@ -226,7 +226,7 @@
/// </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">
/// <tr><th style="vertical-align: top">Syntax
@@ -256,11 +256,11 @@
/// \copydetails fennec::mix
///
/// <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(fennec::genType, fennec::genType, fennec::genBType) "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(fennec::genType, fennec::genType, fennec::genBType) "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(genBType x, genBType y, genBType a)" <br>
/// \ref fennec::mix "mix(genIType x, genIType y, genBType a)" <br>
/// \ref fennec::mix "mix(genUType x, genUType y, genBType a)" <br>
/// \ref fennec::mix "mix(genFType x, genFType y, genBType a)" <br>
/// \ref fennec::mix "mix(genDType x, genDType y, genBType a)"
/// <td width="50%" style="vertical-align: top" class="odd_c">
/// \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 ======================================================================================================
///
@@ -331,14 +323,6 @@ constexpr genType abs(genType 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 ================================================================================================================
@@ -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 ===============================================================================================================
@@ -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 ===============================================================================================================
@@ -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 ==========================================================================================================
@@ -486,13 +438,6 @@ constexpr genType roundEven(genType x) {
//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 =================================================================================================================
///
@@ -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 ================================================================================================================
///
@@ -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 ==============================================================================================================
///
@@ -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 ==============================================================================================================
///
@@ -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 ======================================================================================================
///
/// \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))
constexpr genIType floatBitsToInt(genType 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))
constexpr genType intBitsToFloat(genIType 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 =================================================================================================================
@@ -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 ===============================================================================================================
@@ -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 ===============================================================================================================
@@ -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 =================================================================================================================
///
@@ -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 ===============================================================================================================
///
@@ -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 ==========================================================================================================
///
@@ -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 =================================================================================================================
///
@@ -1022,18 +800,6 @@ constexpr genType mix(genType x, genType y, genType 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) ==========================================================================================================
@@ -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>)
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
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
= 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
#define FENNEC_MATH_DETAIL_TYPES_H
#include <fennec/langcpp/const_sequences.h>
#include <fennec/langcpp/metasequences.h>
namespace fennec
{
@@ -28,11 +28,11 @@ namespace detail
{
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>
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
///
///
/// \section Exponential Functions
/// \section fennec_math_exponential_section_functions Exponential Functions
///
/// <table width="100%" class="fieldtable" id="table_fennec_math_exponential_functions">
/// <tr><th style="vertical-align: top">Syntax
/// <th style="vertical-align: top">Description
/// <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">
/// \copydetails fennec::pow(fennec::genType, fennec::genType)
/// \copydetails fennec::pow
///
/// <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">
/// \copydetails fennec::exp(fennec::genType)
/// \copydetails fennec::exp
///
/// <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">
/// \copydetails fennec::exp2(fennec::genType)
/// \copydetails fennec::exp2
///
/// <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">
/// \copydetails fennec::log(fennec::genType)
/// \copydetails fennec::log
///
/// <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">
/// \copydetails fennec::log2(fennec::genType)
/// \copydetails fennec::log2
///
/// <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">
/// \copydetails fennec::sqrt(fennec::genType)
/// \copydetails fennec::sqrt
///
/// <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">
/// \copydetails fennec::inversesqrt(fennec::genType)
/// \copydetails fennec::inversesqrt
///
/// </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 =================================================================================================================
///
@@ -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 ================================================================================================================
///
@@ -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 =================================================================================================================
///
@@ -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 ================================================================================================================
///
@@ -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 ================================================================================================================
///
@@ -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 =========================================================================================================
///
@@ -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>
constexpr vector<genType, i...> inversesqrt(const vector<genType, i...>& x) {

View File

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

View File

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

View File

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

View File

@@ -43,7 +43,7 @@
/// \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">
/// <tr><th style="vertical-align: top">Syntax
@@ -118,7 +118,7 @@ namespace fennec
// 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>
/// \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>
@@ -79,7 +79,7 @@ public:
/// \return The Value of the Swizzle as a Vector
constexpr VectorT decay() const {
VectorT res;
return decay_impl(res, make_index_sequence<size>{});
return decay_impl(res, make_index_metasequence<size>{});
}
///
@@ -93,7 +93,7 @@ public:
private:
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);
}
};

View File

@@ -145,6 +145,8 @@
///
#include <fennec/math/detail/_math.h>
#include <fennec/math/vector.h>
#include <fennec/langcpp/types.h>
namespace fennec
{
@@ -167,11 +169,6 @@ constexpr genType radians(genType degrees) {
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$
@@ -186,11 +183,6 @@ constexpr genType degrees(genType radians) {
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);
}
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
@@ -232,11 +219,6 @@ constexpr genType cos(genType 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
@@ -251,11 +233,6 @@ constexpr genType tan(genType 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);
}
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.
@@ -297,11 +269,6 @@ constexpr genType acos(genType 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.
@@ -317,11 +284,6 @@ constexpr genType atan(genType 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$.
@@ -338,11 +300,6 @@ constexpr genType atan(genType y, genType 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);
}
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$
@@ -381,11 +333,6 @@ constexpr genType cosh(genType 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$
@@ -398,10 +345,6 @@ constexpr genType tanh(genType 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);
}
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
@@ -439,11 +377,6 @@ constexpr genType acosh(genType 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
@@ -457,12 +390,88 @@ constexpr genType atanh(genType 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>
constexpr vector<genType, i...> atanh(const vector<genType, i...>& x) {
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 SizeV The number of Components
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 n0 The size, in bytes, of lhs
/// \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) {
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 n0 The size, in bytes, of dst
/// \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) {
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 n0 The size, in bytes, of dst
/// \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) {
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 component The type of each component
/// \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,
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_1d
: _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 component The type of each component
/// \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,
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_2d and not cubemap
: _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 component The type of each component
/// \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,
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_3d and not cubemap
: _handle(NULL)
@@ -230,6 +233,7 @@ public:
/// \param faces An array of pointers to textures containing pixel data for each face
/// \param component The component type of the data
/// \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,
const void* faces[6], GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires is_2d and cubemap
: _handle(NULL)
@@ -258,6 +262,7 @@ public:
/// \param data A pointer to a buffer containing image data
/// \param component The component type of the data
/// \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
texture(GLsizei size, GLsizei depth, GLsizei mips,

View File

@@ -39,22 +39,38 @@ namespace fennec
struct type {
///
/// \returns A const-qualified reference to a string containing the name of the type
const string& name() const {
return _data->name;
}
///
/// \returns An integer value containing the unique universal identifier for the type
uint64_t id() const {
return _data->uuid;
}
///
/// \returns A dynarray of all the super (base) types of the type
dynarray<type> supertypes() const {
return _data->supers;
}
///
/// \returns A dynarray of all the sub (child) types of the type
dynarray<type> subtypes() const {
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 {
return _data == c._data;
}
@@ -66,6 +82,11 @@ struct type {
template<typename TypeT>
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>
static type get_from_instance(TypeT* t) { return type(t); }

View File

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

View File

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

View File

@@ -17,7 +17,7 @@
// =====================================================================================================================
///
/// \file node.h
/// \file scene_node.h
/// \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_base>().subtypes()[0].name(), string(detail::type_name<rtti_test_sub>()));
fennec_test_run(type::get<dynarray<int>>().is_iterable(), true);
}
}