From 6f09c3f7fe9c2adf56c44e0ab5f2062e344e04ed Mon Sep 17 00:00:00 2001 From: Medusa Slockbower Date: Sat, 29 Nov 2025 23:43:18 -0500 Subject: [PATCH] - Bug fixing for RTTI - Fixes for declval + separated into own file - is_iterable - fixes for doxygen generation --- CMakeLists.txt | 15 +- doxy/Doxyfile.in | 3 +- include/fennec/containers/array.h | 6 +- include/fennec/containers/detail/_tuple.h | 4 +- include/fennec/containers/dynarray.h | 17 +- include/fennec/containers/initializer_list.h | 57 ++ include/fennec/containers/tuple.h | 4 +- include/fennec/langcpp/declval.h | 48 ++ include/fennec/langcpp/detail/_declval.h | 46 ++ include/fennec/langcpp/detail/_type_traits.h | 26 +- include/fennec/langcpp/lang.h | 2 +- include/fennec/langcpp/metaprogramming.h | 2 +- .../{const_sequences.h => metasequences.h} | 118 ++-- include/fennec/langcpp/ranges.h | 72 +++ include/fennec/langcpp/type_traits.h | 21 +- include/fennec/langcpp/type_transforms.h | 9 +- include/fennec/langcpp/types.h | 2 - include/fennec/langcpp/utility.h | 1 - include/fennec/math/common.h | 526 ++++++++---------- include/fennec/math/detail/_fwd.h | 4 +- include/fennec/math/detail/_types.h | 6 +- include/fennec/math/exponential.h | 100 ++-- include/fennec/math/ext/common.h | 2 + include/fennec/math/ext/quaternion.h | 10 +- include/fennec/math/ext/trigonometric.h | 4 +- include/fennec/math/geometric.h | 6 +- include/fennec/math/swizzle.h | 6 +- include/fennec/math/trigonometric.h | 151 ++--- include/fennec/math/vector.h | 2 +- include/fennec/memory/common.h | 4 + include/fennec/renderers/opengl/lib/texture.h | 5 + include/fennec/rtti/type.h | 21 + include/fennec/rtti/type_data.h | 6 +- include/fennec/scene/node2d.h | 2 +- include/fennec/scene/scene_node.h | 2 +- test/tests/test_rtti.h | 2 + 36 files changed, 762 insertions(+), 550 deletions(-) create mode 100644 include/fennec/containers/initializer_list.h create mode 100644 include/fennec/langcpp/declval.h create mode 100644 include/fennec/langcpp/detail/_declval.h rename include/fennec/langcpp/{const_sequences.h => metasequences.h} (50%) create mode 100644 include/fennec/langcpp/ranges.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ebcc99..b03c0f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/doxy/Doxyfile.in b/doxy/Doxyfile.in index 105b202..59e8f87 100644 --- a/doxy/Doxyfile.in +++ b/doxy/Doxyfile.in @@ -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 diff --git a/include/fennec/containers/array.h b/include/fennec/containers/array.h index 1a00dd3..01bb610 100644 --- a/include/fennec/containers/array.h +++ b/include/fennec/containers/array.h @@ -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{}); + return array::_compare(lhs, rhs, make_index_metasequence{}); } /// /// \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{}); + return not array::_compare(lhs, rhs, make_index_metasequence{}); } /// @} @@ -217,7 +217,7 @@ public: private: template - static bool _compare(const array& lhs, const array& rhs, const_index_sequence) { + static bool _compare(const array& lhs, const array& rhs, index_metasequence) { return ((lhs[i] == rhs[i]) && ...); } }; diff --git a/include/fennec/containers/detail/_tuple.h b/include/fennec/containers/detail/_tuple.h index 4cc96e7..80d25bc 100644 --- a/include/fennec/containers/detail/_tuple.h +++ b/include/fennec/containers/detail/_tuple.h @@ -18,7 +18,7 @@ #ifndef FENNEC_CONTAINERS_DETAIL_TUPLE_H #define FENNEC_CONTAINERS_DETAIL_TUPLE_H -#include +#include #include namespace fennec::detail @@ -43,7 +43,7 @@ template struct _tuple; template -struct _tuple, TypesT...> : _tuple_leaf... +struct _tuple, TypesT...> : _tuple_leaf... { template constexpr _tuple(ArgsT&&... args) diff --git a/include/fennec/containers/dynarray.h b/include/fennec/containers/dynarray.h index 6839c95..518b9f8 100644 --- a/include/fennec/containers/dynarray.h +++ b/include/fennec/containers/dynarray.h @@ -31,7 +31,7 @@ #ifndef FENNEC_CONTAINERS_DYNARRAY_H #define FENNEC_CONTAINERS_DYNARRAY_H -#include +#include #include #include #include @@ -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 constexpr dynarray(const dynarray& conv) : _alloc(conv.size()) @@ -211,7 +214,11 @@ public: } } - constexpr dynarray(std::initializer_list 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 l, const alloc_t& alloc = alloc_t()) : _alloc(l.size(), alloc) , _size(l.size()) { size_t i = 0; diff --git a/include/fennec/containers/initializer_list.h b/include/fennec/containers/initializer_list.h new file mode 100644 index 0000000..23c4365 --- /dev/null +++ b/include/fennec/containers/initializer_list.h @@ -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 . +// ===================================================================================================================== + +/// +/// \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 + +namespace fennec +{ + +using std::initializer_list; + +template +constexpr const T* begin(initializer_list inls) noexcept { + return inls.begin(); +} + +template +constexpr const T* end(initializer_list inls) noexcept { + return inls.end(); +} + +} + +#endif // FENNEC_CONTAINERS_INITIALIZER_LIST_H \ No newline at end of file diff --git a/include/fennec/containers/tuple.h b/include/fennec/containers/tuple.h index 1cf3f84..9316bf0 100644 --- a/include/fennec/containers/tuple.h +++ b/include/fennec/containers/tuple.h @@ -76,9 +76,9 @@ constexpr const typename tuple::template elem_t& get(const tuple -struct tuple : public detail::_tuple, TypesT...> +struct tuple : public detail::_tuple, TypesT...> { - using base_t = detail::_tuple, TypesT...>; + using base_t = detail::_tuple, TypesT...>; template using elem_t = typename nth_element::type; diff --git a/include/fennec/langcpp/declval.h b/include/fennec/langcpp/declval.h new file mode 100644 index 0000000..853a39a --- /dev/null +++ b/include/fennec/langcpp/declval.h @@ -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 . +// ===================================================================================================================== + +/// +/// \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 + +namespace fennec +{ + +// fennec::declval ===================================================================================================== + +template auto declval() noexcept -> decltype(detail::_declval(0)) { + static_assert(detail::_declval_protector{}, "declval must not be used"); + return detail::_declval(0); +} + +} + +#endif // FENNEC_LANGCPP_DECLVAL_H \ No newline at end of file diff --git a/include/fennec/langcpp/detail/_declval.h b/include/fennec/langcpp/detail/_declval.h new file mode 100644 index 0000000..c54b0c5 --- /dev/null +++ b/include/fennec/langcpp/detail/_declval.h @@ -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 . +// ===================================================================================================================== + +/// +/// \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 + +namespace fennec::detail +{ + +template U _declval(int); +template T _declval(long); + +template struct _declval_protector : bool_constant {}; + +} + +#endif // FENNEC_LANGCPP_DETAIL_DECLVAL_H \ No newline at end of file diff --git a/include/fennec/langcpp/detail/_type_traits.h b/include/fennec/langcpp/detail/_type_traits.h index 853754a..c51fdb3 100644 --- a/include/fennec/langcpp/detail/_type_traits.h +++ b/include/fennec/langcpp/detail/_type_traits.h @@ -19,7 +19,9 @@ #ifndef FENNEC_LANG_DETAIL_TYPE_TRAITS_H #define FENNEC_LANG_DETAIL_TYPE_TRAITS_H +#include #include +#include namespace fennec::detail { @@ -64,11 +66,6 @@ namespace fennec::detail template struct _is_pointer : false_type {}; template struct _is_pointer : true_type {}; - template U _declval(int); - template T _declval(long); - - template struct _declval_protector : bool_constant {}; - template struct _is_complete { template static auto test(U*) -> bool_constant; @@ -77,19 +74,34 @@ namespace fennec::detail }; template struct _is_destructible { - template().~T())> + template().~T())> static auto test(int) -> true_type; + template static auto test(...) -> false_type; using type = decltype(test(0)); }; template struct _is_nothrow_destructible { - template().~T()))> + template().~T()))> static auto test(int) -> true_type; + template static auto test(...) -> false_type; using type = decltype(test(0)); }; + // https://stackoverflow.com/questions/13830158/how-to-write-a-trait-which-checks-whether-a-type-is-iterable + template + auto _is_iterable(int) -> decltype( + fennec::begin(declval()) != fennec::end(declval()), + void(), + ++declval()))&>(), + void(*fennec::begin(declval())), + true_type{} + ); + + template + auto _is_iterable(...) -> false_type; + } #endif // FENNEC_LANG_DETAIL_TYPE_TRAITS_H diff --git a/include/fennec/langcpp/lang.h b/include/fennec/langcpp/lang.h index 436e3b1..46ce15c 100644 --- a/include/fennec/langcpp/lang.h +++ b/include/fennec/langcpp/lang.h @@ -17,7 +17,7 @@ // ===================================================================================================================== /// -/// \file langcpp.h +/// \file lang.h /// \brief \ref fennec_lang /// /// diff --git a/include/fennec/langcpp/metaprogramming.h b/include/fennec/langcpp/metaprogramming.h index fa5fe35..82890a1 100644 --- a/include/fennec/langcpp/metaprogramming.h +++ b/include/fennec/langcpp/metaprogramming.h @@ -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 diff --git a/include/fennec/langcpp/const_sequences.h b/include/fennec/langcpp/metasequences.h similarity index 50% rename from include/fennec/langcpp/const_sequences.h rename to include/fennec/langcpp/metasequences.h index a118146..07cfe92 100644 --- a/include/fennec/langcpp/const_sequences.h +++ b/include/fennec/langcpp/metasequences.h @@ -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 \endcode +/// \code #include \endcode /// -/// +///
///
Syntax /// Description /// ///

-/// \ref fennec::sequence "sequence"
+/// \ref fennec::metasequence "metasequence"
///
-/// \copydetails fennec::sequence +/// \copydetails fennec::metasequence /// ///

-/// \ref fennec::integer_sequence "integer_sequence"
-/// \ref fennec::make_integer_sequence "typename make_integer_sequence::type"
-/// \ref fennec::make_integer_sequence_t "make_integer_sequence_t" +/// \ref fennec::integer_metasequence "integer_metasequence"
+/// \ref fennec::make_integer_metasequence "typename make_integer_metasequence::type"
+/// \ref fennec::make_integer_metasequence_t "make_integer_metasequence_t" ///
-/// \copydetails fennec::integer_sequence +/// \copydetails fennec::integer_metasequence /// ///

-/// \ref fennec::index_sequence "index_sequence"
-/// \ref fennec::make_index_sequence "typename make_index_sequence::type"
-/// \ref fennec::make_index_sequence_t "make_index_sequence_t" +/// \ref fennec::index_metasequence "index_metasequence"
+/// \ref fennec::make_index_metasequence "typename make_index_metasequence::type"
+/// \ref fennec::make_index_metasequence_t "make_index_metasequence_t" ///
-/// \copydetails fennec::index_sequence +/// \copydetails fennec::index_metasequence /// ///

-/// \ref fennec::concat_sequence "typename concat_sequence::type"
-/// \ref fennec::concat_sequence_t "concat_sequence_t"
+/// \ref fennec::concat_metasequence "typename concat_metasequence::type"
+/// \ref fennec::concat_metasequence_t "concat_metasequence_t"
///
-/// \copydetails fennec::concat_sequence +/// \copydetails fennec::concat_metasequence /// ///
/// @@ -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 -/// constexpr TypeT summation(sequence) +/// constexpr TypeT summation(metasequence) /// { /// return (Values + ...); /// } /// \endcode /// \tparam ValueT type of the values /// \tparam Values sequence values -template struct const_sequence +template 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 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``` /// \tparam Values sequence values template requires(is_integral_v) -struct const_integer_sequence : const_sequence +struct integer_metasequence : metasequence { /// \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 /// -/// \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``` -/// \tparam N size of the sequence to generate -template struct make_integer_sequence; +/// \tparam N size of the metasequence to generate +template struct make_integer_metasequence; /// /// \brief shorthand for ```typename make_integer_sequence::type``` -template using make_integer_sequence_t = typename make_integer_sequence::type; +template using make_integer_metasequence_t = typename make_integer_metasequence::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 struct const_index_sequence : const_integer_sequence +template struct index_metasequence : integer_metasequence { /// \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 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``` /// \tparam N size of the sequence to generate -template struct make_index_sequence; +template struct make_index_metasequence; /// -/// \brief shorthand for ```typename make_index_sequence::type``` -template using make_index_sequence_t = typename make_index_sequence::type; +/// \brief shorthand for ```typename make_index_metasequence::type``` +template using make_index_metasequence_t = typename make_index_metasequence::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 struct concat_sequence; +template struct concat_metasequence; /// -/// \brief shorthand for ```typename concat_sequence::type``` -template using concat_sequence_t - = typename concat_sequence::type; +/// \brief shorthand for ```typename concat_metasequence::type``` +template using concat_metasequence_t + = typename concat_metasequence::type; // Internal ============================================================================================================ // Implementation for Generating an integer_sequence -template struct make_integer_sequence : concat_sequence_t, make_integer_sequence_t>{}; +template struct make_integer_metasequence : concat_metasequence_t, make_integer_metasequence_t>{}; // Base Case of N=0 -template struct make_integer_sequence : const_integer_sequence {}; +template struct make_integer_metasequence : integer_metasequence {}; // Base Case of N=1 -template struct make_integer_sequence : const_integer_sequence{}; +template struct make_integer_metasequence : integer_metasequence{}; // Implementation for Generating an index_sequence -template struct make_index_sequence : concat_sequence_t, make_index_sequence_t>{}; +template struct make_index_metasequence : concat_metasequence_t, make_index_metasequence_t>{}; // 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 -struct concat_sequence, const_integer_sequence> - : const_integer_sequence{}; +struct concat_metasequence, integer_metasequence> + : integer_metasequence{}; // Specialization for index sequences template -struct concat_sequence, const_index_sequence> - : const_index_sequence{}; +struct concat_metasequence, index_metasequence> + : index_metasequence{}; diff --git a/include/fennec/langcpp/ranges.h b/include/fennec/langcpp/ranges.h new file mode 100644 index 0000000..acfad56 --- /dev/null +++ b/include/fennec/langcpp/ranges.h @@ -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 . +// ===================================================================================================================== + +/// +/// \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 + +namespace fennec +{ + +template +inline constexpr auto begin(ContainerT& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()) { + return c.begin(); +} + +template +inline constexpr auto begin(const ContainerT& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()) { + return c.begin(); +} + +template +inline constexpr T* begin(T (&arr)[N]) noexcept { + return arr; +} + + +template +inline constexpr auto end(ContainerT& c) noexcept(noexcept(c.end())) -> decltype(c.end()) { + return c.end(); +} + +template +inline constexpr auto end(const ContainerT& c) noexcept(noexcept(c.end())) -> decltype(c.end()) { + return c.end(); +} + +template +inline constexpr T* end(T (&arr)[N]) noexcept { + return arr + N; +} + +} + +#endif // FENNEC_LANGCPP_RANGES_H \ No newline at end of file diff --git a/include/fennec/langcpp/type_traits.h b/include/fennec/langcpp/type_traits.h index b6519cc..42e3f3f 100644 --- a/include/fennec/langcpp/type_traits.h +++ b/include/fennec/langcpp/type_traits.h @@ -434,13 +434,6 @@ namespace fennec { -// fennec::declval ===================================================================================================== - -template auto declval() noexcept -> decltype(detail::_declval(0)) { - static_assert(detail::_declval_protector{}, "declval must not be used"); - return detail::_declval(0); -} - constexpr inline bool is_constant_evaluated() noexcept { if consteval { return true; @@ -690,6 +683,20 @@ template struct is_complete : detail::_is_complete::type {}; /// \tparam T type to check template constexpr bool_t is_complete_v = is_complete{}; +// fennec::is_complete ============================================================================================== + +/// +/// \brief check if type `T` is iterable +/// +/// \details Checks if `T` +/// \tparam T type to check +template struct is_iterable : decltype(detail::_is_iterable(0)) {}; + +/// +/// \brief shorthand for `is_iterable::value` +/// \tparam T type to check +template constexpr bool_t is_iterable_v = is_iterable{}; + // fennec::is_convertible ============================================================================================== /// diff --git a/include/fennec/langcpp/type_transforms.h b/include/fennec/langcpp/type_transforms.h index 7f9cab2..eac2757 100644 --- a/include/fennec/langcpp/type_transforms.h +++ b/include/fennec/langcpp/type_transforms.h @@ -31,6 +31,7 @@ #ifndef FENNEC_LANG_TYPE_TRANSFORMS_H #define FENNEC_LANG_TYPE_TRANSFORMS_H +#include #include #include #include @@ -161,10 +162,10 @@ template using remove_pointer_t = typename remove_pointer::type; /// \details removes all pointers from the provided type such that `T*`, `T**`, etc. becomes `T` /// \tparam T Resultant Type template struct strip_pointers : conditional_t< - detail::_is_pointer::value, - strip_pointers>, - type_identity - > {}; + detail::_is_pointer::value, + strip_pointers>, + type_identity + > {}; template using strip_pointers_t = strip_pointers::type; diff --git a/include/fennec/langcpp/types.h b/include/fennec/langcpp/types.h index d8f0520..726e42a 100644 --- a/include/fennec/langcpp/types.h +++ b/include/fennec/langcpp/types.h @@ -203,8 +203,6 @@ #include -#include - namespace fennec { // Basic Types ========================================================================================================= diff --git a/include/fennec/langcpp/utility.h b/include/fennec/langcpp/utility.h index 1743881..487c39f 100644 --- a/include/fennec/langcpp/utility.h +++ b/include/fennec/langcpp/utility.h @@ -123,7 +123,6 @@ constexpr void swap(T& x, T& y) noexcept { /// \param x first value /// \param y second value template constexpr void swap(T& x, T& y) noexcept { - #if FENNEC_COMPILER_GCC #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" diff --git a/include/fennec/math/common.h b/include/fennec/math/common.h index 2f68d99..23c4515 100644 --- a/include/fennec/math/common.h +++ b/include/fennec/math/common.h @@ -44,81 +44,81 @@ /// /// /// -/// \section section_sign_functions Sign +/// \section fennec_math_common_section_sign_functions Sign Functions /// /// ///
Syntax /// Description ///

-/// \ref fennec::abs(fennec::genType) "genIType abs(genIType x)"
-/// \ref fennec::abs(fennec::genType) "genFType abs(genFType x)"
-/// \ref fennec::abs(fennec::genType) "genDType abs(genDType x)" +/// \ref fennec::abs "genIType abs(genIType x)"
+/// \ref fennec::abs "genFType abs(genFType x)"
+/// \ref fennec::abs "genDType abs(genDType x)" ///
-/// \copydetails fennec::abs(fennec::genType) +/// \copydetails fennec::abs /// /// ///

-/// \ref fennec::sign(fennec::genType) "genIType sign(genIType x)"
-/// \ref fennec::sign(fennec::genType) "genFType sign(genFType x)"
-/// \ref fennec::sign(fennec::genType) "genDType sign(genDType x)" +/// \ref fennec::sign "genIType sign(genIType x)"
+/// \ref fennec::sign "genFType sign(genFType x)"
+/// \ref fennec::sign "genDType sign(genDType x)" ///
-/// \copydetails fennec::sign(fennec::genType) +/// \copydetails fennec::sign /// ///
/// /// -/// \section section_rounding_functions Rounding +/// \section fennec_math_common_section_rounding_functions Rounding Functions /// /// ///
Syntax /// Description ///

-/// \ref fennec::floor(fennec::genType) "genFType floor(genFType x)"
-/// \ref fennec::floor(fennec::genType) "genDType floor(genDType x)" +/// \ref fennec::floor "genFType floor(genFType x)"
+/// \ref fennec::floor "genDType floor(genDType x)" ///
-/// \copydetails fennec::floor(fennec::genType) +/// \copydetails fennec::floor /// /// ///

-/// \ref fennec::ceil(fennec::genType) "genFType ceil(genFType x)"
-/// \ref fennec::ceil(fennec::genType) "genDType ceil(genDType x)" +/// \ref fennec::ceil "genFType ceil(genFType x)"
+/// \ref fennec::ceil "genDType ceil(genDType x)" ///
-/// \copydetails fennec::ceil(fennec::genType) +/// \copydetails fennec::ceil /// /// ///

-/// \ref fennec::round(fennec::genType) "genFType round(genFType x)"
-/// \ref fennec::round(fennec::genType) "genDType round(genDType x)" +/// \ref fennec::round "genFType round(genFType x)"
+/// \ref fennec::round "genDType round(genDType x)" ///
-/// \copydetails fennec::round(fennec::genType) +/// \copydetails fennec::round /// /// ///

-/// \ref fennec::roundEven(fennec::genType) "genFType roundEven(genFType x)"
-/// \ref fennec::roundEven(fennec::genType) "genDType roundEven(genDType x)" +/// \ref fennec::roundEven "genFType roundEven(genFType x)"
+/// \ref fennec::roundEven "genDType roundEven(genDType x)" ///
-/// \copydetails fennec::roundEven(fennec::genType) +/// \copydetails fennec::roundEven /// /// ///

-/// \ref fennec::trunc(fennec::genType) "genFType trunc(genFType x)"
-/// \ref fennec::trunc(fennec::genType) "genDType trunc(genDType x)" +/// \ref fennec::trunc "genFType trunc(genFType x)"
+/// \ref fennec::trunc "genDType trunc(genDType x)" ///
-/// \copydetails fennec::trunc(fennec::genType) +/// \copydetails fennec::trunc /// ///
/// /// -/// \section section_decimal_functions Decimal-Point +/// \section fennec_math_common_section_decimal_functions Decimal-Point Functions /// /// ///
Syntax /// Description ///

-/// \ref fennec::fract(fennec::genType) "genFType fract(genFType x)"
-/// \ref fennec::fract(fennec::genType) "genDType fract(genDType x)" +/// \ref fennec::fract "genFType fract(genFType x)"
+/// \ref fennec::fract "genDType fract(genDType x)" ///
-/// \copydetails fennec::fract(fennec::genType) +/// \copydetails fennec::fract /// ///

/// \ref fennec::mod "genFType mod(genFType x, float y)"
@@ -129,59 +129,59 @@ /// \copydetails fennec::mod /// ///

-/// \ref fennec::modf(fennec::genType, fennec::genType&) "genFType modf(genFType x, out genFType i)"
-/// \ref fennec::modf(fennec::genType, fennec::genType&) "genDType modf(genDType x, out genDType i)" +/// \ref fennec::modf "genFType modf(genFType x, out genFType i)"
+/// \ref fennec::modf "genDType modf(genDType x, out genDType i)" ///
-/// \copydetails fennec::modf(fennec::genType, fennec::genType&) +/// \copydetails fennec::modf /// ///

-/// \ref fennec::isnan(fennec::genType) "genBType isnan(genFType x)"
-/// \ref fennec::isnan(fennec::genType) "genBType isnan(genDType x)" +/// \ref fennec::isnan "genBType isnan(genFType x)"
+/// \ref fennec::isnan "genBType isnan(genDType x)" ///
-/// \copydetails fennec::isnan(fennec::genType) +/// \copydetails fennec::isnan /// ///

-/// \ref fennec::isinf(fennec::genType) "genBType isinf(genFType x)"
-/// \ref fennec::isinf(fennec::genType) "genBType isinf(genDType x)" +/// \ref fennec::isinf "genBType isinf(genFType x)"
+/// \ref fennec::isinf "genBType isinf(genDType x)" ///
-/// \copydetails fennec::isinf(fennec::genType) +/// \copydetails fennec::isinf /// ///

-/// \ref fennec::frexp(fennec::genType, fennec::genIType&) "genFType frexp(genFType x, out genIType exp)"
-/// \ref fennec::frexp(fennec::genType, fennec::genIType&) "genDType frexp(genDType x, out genIType exp)" +/// \ref fennec::frexp "genFType frexp(genFType x, out genIType exp)"
+/// \ref fennec::frexp "genDType frexp(genDType x, out genIType exp)" ///
-/// \copydetails fennec::frexp(fennec::genType, fennec::genIType&) +/// \copydetails fennec::frexp /// ///

-/// \ref fennec::ldexp(fennec::genType, fennec::genIType) "genFType ldexp(genFType x, genIType exp)"
-/// \ref fennec::ldexp(fennec::genType, fennec::genIType) "genDType ldexp(genDType x, genIType exp)" +/// \ref fennec::ldexp "genFType ldexp(genFType x, genIType exp)"
+/// \ref fennec::ldexp "genDType ldexp(genDType x, genIType exp)" ///
-/// \copydetails fennec::ldexp(fennec::genType, fennec::genIType) +/// \copydetails fennec::ldexp /// ///
/// /// -/// \section section_bit_conversion_functions Bit Conversion +/// \section fennec_math_common_section_bit_functions Bit Conversion /// /// ///
Syntax /// Description ///

-/// \ref fennec::floatBitsToInt(fennec::genType) "genIType floatBitsToInt(genType value)"
-/// \ref fennec::floatBitsToUint(fennec::genType) "genUType floatBitsToUint(genType value)" +/// \ref fennec::floatBitsToInt "genIType floatBitsToInt(genType value)"
+/// \ref fennec::floatBitsToUint "genUType floatBitsToUint(genType value)" ///
-/// \copydetails fennec::floatBitsToUint(fennec::genType) +/// \copydetails fennec::floatBitsToUint /// ///

-/// \ref fennec::intBitsToFloat(fennec::genIType) "genFType intBitsToFloat(genIType value)"
-/// \ref fennec::uintBitsToFloat(fennec::genUType) "genFType uintBitsToFloat(genUType value)" +/// \ref fennec::intBitsToFloat "genFType intBitsToFloat(genIType value)"
+/// \ref fennec::uintBitsToFloat "genFType uintBitsToFloat(genUType value)" ///
-/// \copydetails fennec::uintBitsToFloat(fennec::genType) +/// \copydetails fennec::uintBitsToFloat /// ///
/// /// -/// \section section_comparison_functions Comparison +/// \section fennec_math_common_section_comparison_functions Comparison Functions /// /// ///
Syntax @@ -226,7 +226,7 @@ ///
/// /// -/// \section section_curve_functions Curves +/// \section fennec_math_common_section_curve_functions Curve Functions /// /// ///
Syntax @@ -256,11 +256,11 @@ /// \copydetails fennec::mix /// ///

-/// \ref fennec::mix(fennec::genBType, fennec::genBType, fennec::genBType) "mix(genBType x, genBType y, genBType a)"
-/// \ref fennec::mix(fennec::genType, fennec::genType, fennec::genBType) "mix(genIType x, genIType y, genBType a)"
-/// \ref fennec::mix(fennec::genType, fennec::genType, fennec::genBType) "mix(genUType x, genUType y, genBType a)"
-/// \ref fennec::mix(fennec::genType, fennec::genType, fennec::genBType) "mix(genFType x, genFType y, genBType a)"
-/// \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)"
+/// \ref fennec::mix "mix(genIType x, genIType y, genBType a)"
+/// \ref fennec::mix "mix(genUType x, genUType y, genBType a)"
+/// \ref fennec::mix "mix(genFType x, genFType y, genBType a)"
+/// \ref fennec::mix "mix(genDType x, genDType y, genBType a)" ///
/// \copydetails fennec::mix /// @@ -308,14 +308,6 @@ constexpr genType sign(genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector sign(const vector& x) { - return vector(fennec::sign(x[i]) ...); -} - - // Absolute Value ====================================================================================================== /// @@ -331,14 +323,6 @@ constexpr genType abs(genType x) { return x * fennec::sign(x); } - -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector abs(const vector& x) { - return vector(fennec::abs(x[i]) ...); -} - /// @} @@ -366,14 +350,6 @@ constexpr genType floor(genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector floor(const vector& x) { - return vector(fennec::floor(x[i]) ...); -} - - // Ceil ================================================================================================================ @@ -391,14 +367,6 @@ constexpr genType ceil(genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector ceil(const vector& x) { - return vector(fennec::ceil(x[i]) ...); -} - - // Round =============================================================================================================== @@ -416,14 +384,6 @@ template constexpr genType round(genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector round(const vector& x) { - return vector(fennec::round(x[i]) ...); -} - - // Trunc =============================================================================================================== @@ -441,14 +401,6 @@ constexpr genType trunc(genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector trunc(const vector& x) { - return vector(fennec::trunc(x[i]) ...); -} - - // Round Even ========================================================================================================== @@ -486,13 +438,6 @@ constexpr genType roundEven(genType x) { //return i + static_cast(up); } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector roundEven(const vector& x) { - return vector(fennec::roundEven(x[i]) ...); -} - /// @} @@ -519,14 +464,6 @@ constexpr genType fract(genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector fract(const vector& x) { - return vector(fennec::fract(x[i]) ...); -} - - // Mod ================================================================================================================= /// @@ -544,19 +481,6 @@ constexpr genType mod(genType x, genType y) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector mod(const vector& x, genType y) { - return x - y * fennec::floor(x / y); -} - -template -constexpr vector mod(const vector& x, const vector& y) { - return x - y * fennec::floor(x / y); -} - - // ModF ================================================================================================================ /// @@ -574,14 +498,6 @@ constexpr genType modf(genType x, genType& i) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector modf(const vector& x, vector& I) { - I = fennec::floor(x); return fennec::fract(x); -} - - // Is NaN ============================================================================================================== /// @@ -603,14 +519,6 @@ constexpr genBType isnan(genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template requires(is_bool_v) -constexpr vector isnan(const vector& x) { - return vector(fennec::isnan(x[i]) ...); -} - - // Is Inf ============================================================================================================== /// @@ -627,19 +535,11 @@ constexpr genBType isinf(genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template requires(is_bool_v) -constexpr vector isinf(const vector& x) { - return vector(fennec::isinf(x[i]) ...); -} - - // Bit Conversion ====================================================================================================== /// -/// \copydetails fennec::floatBitsToUint(fennec::genFType) +/// \copydetails fennec::floatBitsToUint template requires(is_floating_point_v and is_integral_v and is_signed_v and sizeof(genType) == sizeof(genIType)) constexpr genIType floatBitsToInt(genType x) { return fennec::bit_cast(x); @@ -669,7 +569,7 @@ constexpr genUType floatBitsToUint(genType x) { /// -/// \copydetails fennec::uintBitsToFloat(fennec::genUType) +/// \copydetails fennec::uintBitsToFloat template requires(is_floating_point_v and is_integral_v and is_signed_v and sizeof(genType) == sizeof(genIType)) constexpr genType intBitsToFloat(genIType x) { return fennec::bit_cast(x); @@ -696,29 +596,6 @@ constexpr genType uintBitsToFloat(genUType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template requires(is_floating_point_v and is_integral_v and is_signed_v and sizeof(genType) == sizeof(genIType)) -constexpr vector floatBitsToInt(const vector& x) { - return vector(fennec::bit_cast(x[i])...); -} - -template requires(is_floating_point_v and is_integral_v and is_unsigned_v and sizeof(genType) == sizeof(genUType)) -constexpr vector floatBitsToUint(const vector& x) { - return vector(fennec::bit_cast(x[i])...); -} - -template requires(is_floating_point_v and is_integral_v and is_signed_v and sizeof(genType) == sizeof(genIType)) -constexpr vector intBitsToFloat(const vector& x) { - return vector(fennec::bit_cast(x[i]) ...); -} - -template requires(is_floating_point_v and is_integral_v and is_unsigned_v and sizeof(genType) == sizeof(genUType)) -constexpr vector uintBitsToFloat(const vector& x) { - return vector(fennec::bit_cast(x[i]) ...); -} - - // fma ================================================================================================================= @@ -738,14 +615,6 @@ constexpr genType fma(genType a, genType b, genType c) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector fma(const vector& a, const vector& b, const vector& c) { - return vector(fennec::fma(a[i], b[i], c[i]) ...); -} - - // frexp =============================================================================================================== @@ -769,14 +638,6 @@ constexpr genType frexp(genType x, genIType& exp) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template requires(is_integral_v) -constexpr vector frexp(const vector& x, vector& exp) { - return vector(fennec::frexp(x[i], exp[i])...); -} - - // ldexp =============================================================================================================== @@ -802,14 +663,6 @@ constexpr genType ldexp(genType x, genIType exp) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template requires(is_integral_v) -constexpr vector ldexp(const vector& x, const vector& exp) { - return vector(fennec::ldexp(x[i], exp[i])...); -} - - /// @} @@ -837,24 +690,6 @@ constexpr genType min(genType x, genType y) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector min(genType x, const vector& y) { - return vector(fennec::min(x, y[i]) ...); -} - -template -constexpr vector min(const vector& x, genType y) { - return vector(fennec::min(x[i], y) ...); -} - -template -constexpr vector min(const vector& x, const vector& y) { - return vector(fennec::min(x[i], y[i]) ...); -} - - // Max ================================================================================================================= /// @@ -872,24 +707,6 @@ constexpr genType max(genType x, genType y) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector max(genType x, const vector& y) { - return vector(fennec::max(x, y[i]) ...); -} - -template -constexpr vector max(const vector& x, genType y) { - return vector(fennec::max(x[i], y) ...); -} - -template -constexpr vector max(const vector& x, const vector& y) { - return vector(fennec::max(x[i], y[i]) ...); -} - - // Clamp =============================================================================================================== /// @@ -908,19 +725,6 @@ constexpr genType clamp(genType x, genType minVal, genType maxVal) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector clamp(const vector& x, genType minVal, genType maxVal) { - return vector(fennec::min(fennec::max(x[i], minVal), maxVal)...); -} - -template -constexpr vector clamp(const vector& x, const vector& minVal, const vector& maxVal) { - return vector(fennec::min(fennec::max(x[i], minVal[i]), maxVal[i])...); -} - - /// @} @@ -948,19 +752,6 @@ constexpr genType step(genType edge, genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template requires(is_floating_point_v) -constexpr vector step(genType edge, const vector& x) { - return vector(fennec::step(edge, x[i]) ...); -} - -template requires(is_floating_point_v) -constexpr vector step(const vector& edge, const vector& x) { - return vector(fennec::step(edge[i], x[i]) ...); -} - - // Smoothstep ========================================================================================================== /// @@ -989,19 +780,6 @@ constexpr genType smoothstep(genType edge0, genType edge1, genType x) { } -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template requires(is_floating_point_v) -constexpr vector smoothstep(genType edge0, genType edge1, const vector& x) { - return vector(fennec::smoothstep(edge0, edge1, x[i]) ...); -} - -template requires(is_floating_point_v) -constexpr vector smoothstep(const vector& edge0, const vector& edge1, const vector& x) { - return vector(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 requires(is_floating_point_v) -constexpr vector mix(const vector& x, const vector& y, genType a) { - return x * (genType(1.0) - a) + y * a; -} - -template requires(is_floating_point_v) -constexpr vector mix(const vector& x, const vector& y, const vector& 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 +constexpr vector sign(const vector& x) { + return vector(fennec::sign(x[i]) ...); +} + +template +constexpr vector abs(const vector& x) { + return vector(fennec::abs(x[i]) ...); +} + +template +constexpr vector floor(const vector& x) { + return vector(fennec::floor(x[i]) ...); +} + +template +constexpr vector ceil(const vector& x) { + return vector(fennec::ceil(x[i]) ...); +} + +template +constexpr vector round(const vector& x) { + return vector(fennec::round(x[i]) ...); +} + +template +constexpr vector trunc(const vector& x) { + return vector(fennec::trunc(x[i]) ...); +} + +template +constexpr vector roundEven(const vector& x) { + return vector(fennec::roundEven(x[i]) ...); +} + +template +constexpr vector fract(const vector& x) { + return vector(fennec::fract(x[i]) ...); +} + +template +constexpr vector mod(const vector& x, genType y) { + return x - y * fennec::floor(x / y); +} + +template +constexpr vector mod(const vector& x, const vector& y) { + return x - y * fennec::floor(x / y); +} + +template +constexpr vector modf(const vector& x, vector& I) { + I = fennec::floor(x); return fennec::fract(x); +} + +template requires(is_bool_v) +constexpr vector isnan(const vector& x) { + return vector(fennec::isnan(x[i]) ...); +} + +template requires(is_bool_v) +constexpr vector isinf(const vector& x) { + return vector(fennec::isinf(x[i]) ...); +} + +template requires(is_floating_point_v and is_integral_v and is_signed_v and sizeof(genType) == sizeof(genIType)) +constexpr vector floatBitsToInt(const vector& x) { + return vector(fennec::bit_cast(x[i])...); +} + +template requires(is_floating_point_v and is_integral_v and is_unsigned_v and sizeof(genType) == sizeof(genUType)) +constexpr vector floatBitsToUint(const vector& x) { + return vector(fennec::bit_cast(x[i])...); +} + +template requires(is_floating_point_v and is_integral_v and is_signed_v and sizeof(genType) == sizeof(genIType)) +constexpr vector intBitsToFloat(const vector& x) { + return vector(fennec::bit_cast(x[i]) ...); +} + +template requires(is_floating_point_v and is_integral_v and is_unsigned_v and sizeof(genType) == sizeof(genUType)) +constexpr vector uintBitsToFloat(const vector& x) { + return vector(fennec::bit_cast(x[i]) ...); +} + +template +constexpr vector fma(const vector& a, const vector& b, const vector& c) { + return vector(fennec::fma(a[i], b[i], c[i]) ...); +} + +template requires(is_integral_v) +constexpr vector frexp(const vector& x, vector& exp) { + return vector(fennec::frexp(x[i], exp[i])...); +} + +template requires(is_integral_v) +constexpr vector ldexp(const vector& x, const vector& exp) { + return vector(fennec::ldexp(x[i], exp[i])...); +} + +template +constexpr vector min(genType x, const vector& y) { + return vector(fennec::min(x, y[i]) ...); +} + +template +constexpr vector min(const vector& x, genType y) { + return vector(fennec::min(x[i], y) ...); +} + +template +constexpr vector min(const vector& x, const vector& y) { + return vector(fennec::min(x[i], y[i]) ...); +} + +template +constexpr vector max(genType x, const vector& y) { + return vector(fennec::max(x, y[i]) ...); +} + +template +constexpr vector max(const vector& x, genType y) { + return vector(fennec::max(x[i], y) ...); +} + +template +constexpr vector max(const vector& x, const vector& y) { + return vector(fennec::max(x[i], y[i]) ...); +} + +template +constexpr vector clamp(const vector& x, genType minVal, genType maxVal) { + return vector(fennec::min(fennec::max(x[i], minVal), maxVal)...); +} + +template +constexpr vector clamp(const vector& x, const vector& minVal, const vector& maxVal) { + return vector(fennec::min(fennec::max(x[i], minVal[i]), maxVal[i])...); +} + +template requires(is_floating_point_v) +constexpr vector step(genType edge, const vector& x) { + return vector(fennec::step(edge, x[i]) ...); +} + +template requires(is_floating_point_v) +constexpr vector step(const vector& edge, const vector& x) { + return vector(fennec::step(edge[i], x[i]) ...); +} + +template requires(is_floating_point_v) +constexpr vector smoothstep(genType edge0, genType edge1, const vector& x) { + return vector(fennec::smoothstep(edge0, edge1, x[i]) ...); +} + +template requires(is_floating_point_v) +constexpr vector smoothstep(const vector& edge0, const vector& edge1, const vector& x) { + return vector(fennec::smoothstep(edge0[i], edge1[i], x[i]) ...); +} + +template requires(is_floating_point_v) +constexpr vector mix(const vector& x, const vector& y, genType a) { + return x * (genType(1.0) - a) + y * a; +} + +template requires(is_floating_point_v) +constexpr vector mix(const vector& x, const vector& y, const vector& a) { + return x * (genType(1.0) - a) + y * a; +} template requires(is_bool_v and is_floating_point_v) constexpr vector mix(const vector& x, const vector& y, genBType a) { diff --git a/include/fennec/math/detail/_fwd.h b/include/fennec/math/detail/_fwd.h index 3da4535..3176846 100644 --- a/include/fennec/math/detail/_fwd.h +++ b/include/fennec/math/detail/_fwd.h @@ -29,10 +29,10 @@ template struct matrix; // // Simplified interface for creating sized vectors or matrices template using vec - = decltype(detail::_gen_vector(make_index_sequence{})); // Gets the type returned by this function + = decltype(detail::_gen_vector(make_index_metasequence{})); // Gets the type returned by this function template using mat - = decltype(detail::_gen_matrix(make_index_sequence{})); // Gets the type returned by this function + = decltype(detail::_gen_matrix(make_index_metasequence{})); // Gets the type returned by this function } diff --git a/include/fennec/math/detail/_types.h b/include/fennec/math/detail/_types.h index 7a15da3..febf4ec 100644 --- a/include/fennec/math/detail/_types.h +++ b/include/fennec/math/detail/_types.h @@ -19,7 +19,7 @@ #ifndef FENNEC_MATH_DETAIL_TYPES_H #define FENNEC_MATH_DETAIL_TYPES_H -#include +#include namespace fennec { @@ -28,11 +28,11 @@ namespace detail { template typename VectorT, typename ScalarT, size_t...IndicesV> -VectorT _gen_vector(const_index_sequence); // Helper for substituting a size N with sequence of integers +VectorT _gen_vector(index_metasequence); // Helper for substituting a size N with sequence of integers template typename MatrixT, typename ScalarT, size_t RowsV, size_t...IndicesV> -MatrixT _gen_matrix(const_index_sequence); // Helper for substituting a size Columns with sequence of integers +MatrixT _gen_matrix(index_metasequence); // Helper for substituting a size Columns with sequence of integers } diff --git a/include/fennec/math/exponential.h b/include/fennec/math/exponential.h index 34cc95a..35e8886 100644 --- a/include/fennec/math/exponential.h +++ b/include/fennec/math/exponential.h @@ -42,45 +42,45 @@ /// \code #include \endcode /// /// -/// \section Exponential Functions +/// \section fennec_math_exponential_section_functions Exponential Functions /// /// ///
Syntax /// Description ///

-/// \ref fennec::pow(fennec::genType, fennec::genType) "genFType pow(genFType x, genFType y)" +/// \ref fennec::pow "genFType pow(genFType x, genFType y)" ///
-/// \copydetails fennec::pow(fennec::genType, fennec::genType) +/// \copydetails fennec::pow /// ///

-/// \ref fennec::exp(fennec::genType)"genFType exp(genFType x)" +/// \ref fennec::exp"genFType exp(genFType x)" ///
-/// \copydetails fennec::exp(fennec::genType) +/// \copydetails fennec::exp /// ///

-/// \ref fennec::exp2(fennec::genType) "genFType exp2(genFType x)" +/// \ref fennec::exp2 "genFType exp2(genFType x)" ///
-/// \copydetails fennec::exp2(fennec::genType) +/// \copydetails fennec::exp2 /// ///

-/// \ref fennec::log(fennec::genType) "genFType log(genFType x)" +/// \ref fennec::log "genFType log(genFType x)" ///
-/// \copydetails fennec::log(fennec::genType) +/// \copydetails fennec::log /// ///

-/// \ref fennec::log2(fennec::genType) "genFType log2(genFType x)" +/// \ref fennec::log2 "genFType log2(genFType x)" ///
-/// \copydetails fennec::log2(fennec::genType) +/// \copydetails fennec::log2 /// ///

-/// \ref fennec::sqrt(fennec::genType) "genFType sqrt(genFType x)" +/// \ref fennec::sqrt "genFType sqrt(genFType x)" ///
-/// \copydetails fennec::sqrt(fennec::genType) +/// \copydetails fennec::sqrt /// ///

-/// \ref fennec::inversesqrt(fennec::genType) "genFType inversesqrt(genFType x)" +/// \ref fennec::inversesqrt "genFType inversesqrt(genFType x)" ///
-/// \copydetails fennec::inversesqrt(fennec::genType) +/// \copydetails fennec::inversesqrt /// ///
/// @@ -110,14 +110,6 @@ constexpr genType pow(genType x, genType y) { } -// Vector Specialization ----------------------------------------------------------------------------------------------- - -template -constexpr vector pow(const vector & x, const vector & y) { - return vector(fennec::pow(x[i], y[i]) ...); -} - - // exp ================================================================================================================= /// @@ -132,13 +124,6 @@ constexpr genType exp(genType x) { } -// Vector Specialization ----------------------------------------------------------------------------------------------- - -template constexpr vector exp(const vector& x) { - return vector(fennec::exp(x[i]) ...); -} - - // exp2 ================================================================================================================ /// @@ -152,13 +137,6 @@ template constexpr genType exp2(genType x) { } -// Vector Specialization ----------------------------------------------------------------------------------------------- - -template constexpr vector exp2(const vector& x) { - return vector(fennec::exp2(x[i]) ...); -} - - // log ================================================================================================================= /// @@ -173,13 +151,6 @@ template constexpr genType log(genType x) { } -// Vector Specialization ----------------------------------------------------------------------------------------------- - -template constexpr genType log(const vector& x) { - return vector(log(x[i]) ...); -} - - // log2 ================================================================================================================ /// @@ -195,13 +166,6 @@ template constexpr genType log2(genType x) { } -// Vector Specialization ----------------------------------------------------------------------------------------------- - -template constexpr genType log2(const vector& x) { - return vector(log2(x[i]) ...); -} - - // sqrt ================================================================================================================ /// @@ -216,13 +180,6 @@ template constexpr genType sqrt(genType x) { } -// Vector Specialization ----------------------------------------------------------------------------------------------- - -template constexpr genType sqrt(const vector& x) { - return vector(fennec::sqrt(x[i]) ...); -} - - // inversesqrt ========================================================================================================= /// @@ -237,7 +194,32 @@ template constexpr genType inversesqrt(genType x) { } -// Vector Specialization ----------------------------------------------------------------------------------------------- +// Internal ============================================================================================================ + +template +constexpr vector pow(const vector & x, const vector & y) { + return vector(fennec::pow(x[i], y[i]) ...); +} + +template constexpr vector exp(const vector& x) { + return vector(fennec::exp(x[i]) ...); +} + +template constexpr vector exp2(const vector& x) { + return vector(fennec::exp2(x[i]) ...); +} + +template constexpr genType log(const vector& x) { + return vector(log(x[i]) ...); +} + +template constexpr genType log2(const vector& x) { + return vector(log2(x[i]) ...); +} + +template constexpr genType sqrt(const vector& x) { + return vector(fennec::sqrt(x[i]) ...); +} template constexpr vector inversesqrt(const vector& x) { diff --git a/include/fennec/math/ext/common.h b/include/fennec/math/ext/common.h index 18b02fd..4dd4881 100644 --- a/include/fennec/math/ext/common.h +++ b/include/fennec/math/ext/common.h @@ -21,7 +21,9 @@ #include +#include #include + #include namespace fennec diff --git a/include/fennec/math/ext/quaternion.h b/include/fennec/math/ext/quaternion.h index 5d275aa..f1ea368 100644 --- a/include/fennec/math/ext/quaternion.h +++ b/include/fennec/math/ext/quaternion.h @@ -19,6 +19,7 @@ #ifndef FENNEC_MATH_EXT_QUATERNION_H #define FENNEC_MATH_EXT_QUATERNION_H +#include #include namespace fennec @@ -31,15 +32,13 @@ template using qua = quaternion; using quat = qua; using dquat = qua; -/// -/// \brief Dot Function -/// \param x the first quaternion -/// \param y the second quaternion -/// \returns The sum of component products. + +#ifndef FENNEC_DOXYGEN template constexpr genType dot(const qua& x, const qua& 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); diff --git a/include/fennec/math/ext/trigonometric.h b/include/fennec/math/ext/trigonometric.h index b1db987..4c3e18b 100644 --- a/include/fennec/math/ext/trigonometric.h +++ b/include/fennec/math/ext/trigonometric.h @@ -19,7 +19,6 @@ #ifndef FENNEC_MATH_EXT_TRIGONOMETRIC_H #define FENNEC_MATH_EXT_TRIGONOMETRIC_H -#include #include namespace fennec @@ -27,6 +26,7 @@ namespace fennec // Angle Conversions =================================================================================================== +#ifndef FENNEC_DOXYGEN template constexpr qua radians(const qua& degrees) { return qua(degrees * 0.01745329251994329576923690768489); @@ -37,7 +37,6 @@ constexpr qua degrees(const qua& radians) { return qua(radians * 57.29577951308232087679815481410517); } - // Trigonometric Functions ============================================================================================= template @@ -162,6 +161,7 @@ constexpr qua atanh(const qua& x) { fennec::atanh(x.z) ); } +#endif } diff --git a/include/fennec/math/geometric.h b/include/fennec/math/geometric.h index 67fcdc1..5da59b0 100644 --- a/include/fennec/math/geometric.h +++ b/include/fennec/math/geometric.h @@ -43,13 +43,13 @@ /// \code #include \endcode /// /// -/// \section Geometric Functions +/// \section fennec_math_geometric_section_functions Geometric Functions /// /// ///
Syntax /// Description ///

-/// \ref fennec::dot "float dot(genFType x, genFType y)"
+/// \ref fennec::dot "float dot(genFType x, genFType y)"
/// \ref fennec::dot "double dot(genDType x, genDType x)" ///
/// \copydoc fennec::dot @@ -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$

/// \details we can represent this in linear algebra as the following,

diff --git a/include/fennec/math/swizzle.h b/include/fennec/math/swizzle.h index 5d9ab43..fe41ee1 100644 --- a/include/fennec/math/swizzle.h +++ b/include/fennec/math/swizzle.h @@ -41,7 +41,7 @@ /// /// -#include +#include #include @@ -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{}); + return decay_impl(res, make_index_metasequence{}); } /// @@ -93,7 +93,7 @@ public: private: template - constexpr VectorT& decay_impl(VectorT& vec, const_index_sequence) { + constexpr VectorT& decay_impl(VectorT& vec, index_metasequence) { return ((vec[VecIndicesV] = this->data[IndicesV]), ..., vec); } }; diff --git a/include/fennec/math/trigonometric.h b/include/fennec/math/trigonometric.h index d0bc588..e7bbe51 100644 --- a/include/fennec/math/trigonometric.h +++ b/include/fennec/math/trigonometric.h @@ -145,6 +145,8 @@ /// #include +#include +#include namespace fennec { @@ -167,11 +169,6 @@ constexpr genType radians(genType degrees) { return genType(degrees * 0.01745329251994329576923690768489); } -template -constexpr vector radians(const vector& degrees) { - return vector(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 -constexpr vector degrees(const vector& radians) { - return genType(radians * 57.29577951308232087679815481410517); -} - /// @} @@ -213,11 +205,6 @@ constexpr genType sin(genType x) { return ::sin(x); } -template -constexpr vector sin(const vector& x) { - return vector(fennec::sin(x[i]) ...); -} - /// /// \brief The Standard Trigonometric Cosine @@ -232,11 +219,6 @@ constexpr genType cos(genType x) { return ::cos(x); } -template -constexpr vector cos(const vector& x) { - return vector(fennec::cos(x[i]) ...); -} - /// /// \brief The Standard Trigonometric Tangent @@ -251,11 +233,6 @@ constexpr genType tan(genType x) { return ::tan(x); } -template -constexpr vector tan(const vector& x) { - return vector(fennec::tan(x[i]) ...); -} - /// @} @@ -277,11 +254,6 @@ constexpr genType asin(genType x) { return ::asin(x); } -template -constexpr vector asin(const vector& x) { - return vector(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 -constexpr vector acos(const vector& x) { - return vector(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 -constexpr vector atan(const vector& y_over_x) { - return vector(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 -constexpr vector atan(const vector& y, const vector& x) { - return vector(fennec::atan(y[i], x[i]) ...); -} - /// @} @@ -364,11 +321,6 @@ constexpr genType sinh(genType x) { return ::sinh(x); } -template -constexpr vector sinh(const vector& x) { - return vector(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 -constexpr vector cosh(const vector& x) { - return vector(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 -constexpr vector tanh(const vector& x) { - return vector(fennec::tanh(x[i]) ...); -} /// @} @@ -421,11 +364,6 @@ constexpr genType asinh(genType x) { return ::asinh(x); } -template -constexpr vector asinh(const vector& x) { - return vector(fennec::asinh(x[i]) ...); -} - /// /// \brief The Inverse Hyperbolic Cosine Function @@ -439,11 +377,6 @@ constexpr genType acosh(genType x) { return ::acosh(x); } -template -constexpr vector acosh(const vector& x) { - return vector(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 +constexpr vector radians(const vector& degrees) { + return vector(degrees * 0.01745329251994329576923690768489); +} + +template +constexpr vector degrees(const vector& radians) { + return genType(radians * 57.29577951308232087679815481410517); +} + +template +constexpr vector sin(const vector& x) { + return vector(fennec::sin(x[i]) ...); +} + +template +constexpr vector cos(const vector& x) { + return vector(fennec::cos(x[i]) ...); +} + +template +constexpr vector tan(const vector& x) { + return vector(fennec::tan(x[i]) ...); +} + +template +constexpr vector asin(const vector& x) { + return vector(fennec::asin(x[i]) ...); +} + +template +constexpr vector acos(const vector& x) { + return vector(fennec::acos(x[i]) ...); +} + +template +constexpr vector atan(const vector& y_over_x) { + return vector(fennec::atan(y_over_x[i]) ...); +} + +template +constexpr vector atan(const vector& y, const vector& x) { + return vector(fennec::atan(y[i], x[i]) ...); +} + +template +constexpr vector sinh(const vector& x) { + return vector(fennec::sinh(x[i]) ...); +} + +template +constexpr vector cosh(const vector& x) { + return vector(fennec::cosh(x[i]) ...); +} + +template +constexpr vector tanh(const vector& x) { + return vector(fennec::tanh(x[i]) ...); +} + +template +constexpr vector asinh(const vector& x) { + return vector(fennec::asinh(x[i]) ...); +} + +template +constexpr vector acosh(const vector& x) { + return vector(fennec::acosh(x[i]) ...); +} + template constexpr vector atanh(const vector& x) { return vector(fennec::atanh(x[i]) ...); } - -/// @} +#endif diff --git a/include/fennec/math/vector.h b/include/fennec/math/vector.h index 80919c2..cb525bf 100644 --- a/include/fennec/math/vector.h +++ b/include/fennec/math/vector.h @@ -120,7 +120,7 @@ namespace fennec /// \tparam ScalarT The type of the Components /// \tparam SizeV The number of Components template -using vec = decltype(detail::_gen_vector(make_index_sequence{})); +using vec = decltype(detail::_gen_vector(make_index_metasequence{})); /// diff --git a/include/fennec/memory/common.h b/include/fennec/memory/common.h index c503550..6e14465 100644 --- a/include/fennec/memory/common.h +++ b/include/fennec/memory/common.h @@ -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); } diff --git a/include/fennec/renderers/opengl/lib/texture.h b/include/fennec/renderers/opengl/lib/texture.h index f13acbe..30f5ae2 100644 --- a/include/fennec/renderers/opengl/lib/texture.h +++ b/include/fennec/renderers/opengl/lib/texture.h @@ -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, diff --git a/include/fennec/rtti/type.h b/include/fennec/rtti/type.h index 78d5806..13ea31e 100644 --- a/include/fennec/rtti/type.h +++ b/include/fennec/rtti/type.h @@ -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 supertypes() const { return _data->supers; } + /// + /// \returns A dynarray of all the sub (child) types of the type dynarray 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 static type get() { return type(static_cast(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 static type get_from_instance(TypeT* t) { return type(t); } diff --git a/include/fennec/rtti/type_data.h b/include/fennec/rtti/type_data.h index 2d6d98f..9a1acf7 100644 --- a/include/fennec/rtti/type_data.h +++ b/include/fennec/rtti/type_data.h @@ -49,6 +49,8 @@ struct type_data { type_data* raw_type; dynarray supers; dynarray subs; + + bool is_iterable; }; struct type_storage { @@ -71,7 +73,9 @@ private: .raw_type = typeuuid() == typeuuid() ? nullptr : type_storage::get_data(), .supers = type_storage::get_data(supers_t{}), - .subs = {} + .subs = {}, + + .is_iterable = is_iterable_v }); for (type_data* t : res->supers) { diff --git a/include/fennec/scene/node2d.h b/include/fennec/scene/node2d.h index 2e52908..635b5fe 100644 --- a/include/fennec/scene/node2d.h +++ b/include/fennec/scene/node2d.h @@ -17,7 +17,7 @@ // ===================================================================================================================== /// -/// \file transform2d.h +/// \file node2d.h /// \brief /// /// diff --git a/include/fennec/scene/scene_node.h b/include/fennec/scene/scene_node.h index 1b00985..89e0e1a 100644 --- a/include/fennec/scene/scene_node.h +++ b/include/fennec/scene/scene_node.h @@ -17,7 +17,7 @@ // ===================================================================================================================== /// -/// \file node.h +/// \file scene_node.h /// \brief /// /// diff --git a/test/tests/test_rtti.h b/test/tests/test_rtti.h index 3d20aad..32a2d73 100644 --- a/test/tests/test_rtti.h +++ b/test/tests/test_rtti.h @@ -60,6 +60,8 @@ inline void fennec_test_rtti() { fennec_test_run(type::get().supertypes()[0].name(), string(detail::type_name())); fennec_test_run(type::get().subtypes()[0].name(), string(detail::type_name())); + fennec_test_run(type::get>().is_iterable(), true); + } }