diff --git a/CMakeLists.txt b/CMakeLists.txt index 07a2c96..ae5cb68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,7 +136,7 @@ fennec_add_sources( include/fennec/containers/detail/_tuple.h - # lang ================================================================================================================= +# lang ================================================================================================================= include/fennec/lang/lang.h include/fennec/lang/metaprogramming.h @@ -145,6 +145,7 @@ fennec_add_sources( include/fennec/lang/constants.h include/fennec/lang/conditional_types.h include/fennec/lang/declval.h + include/fennec/lang/function.h include/fennec/lang/hashing.h include/fennec/lang/intrinsics.h include/fennec/lang/limits.h @@ -165,6 +166,7 @@ fennec_add_sources( include/fennec/lang/detail/_bits.h include/fennec/lang/detail/_declval.h + include/fennec/lang/detail/_function.h include/fennec/lang/detail/_int.h include/fennec/lang/detail/_numeric_transforms.h include/fennec/lang/detail/_stdlib.h @@ -173,7 +175,7 @@ fennec_add_sources( include/fennec/lang/detail/_type_sequences.h - # RTTI ================================================================================================================= +# RTTI ================================================================================================================= include/fennec/rtti/typeid.h include/fennec/rtti/type_data.h include/fennec/rtti/type.h @@ -190,7 +192,7 @@ fennec_add_sources( include/fennec/rtti/detail/_type_name.h - # MEMORY =============================================================================================================== +# MEMORY =============================================================================================================== include/fennec/memory/new.h source/memory/new.cpp include/fennec/memory/allocator.h @@ -202,11 +204,11 @@ fennec_add_sources( include/fennec/memory/detail/_ptr_traits.h - # DEBUG ================================================================================================================ +# DEBUG ================================================================================================================ source/debug/assert_impl.cpp - # MATH ================================================================================================================= +# MATH ================================================================================================================= include/fennec/math/math.h include/fennec/math/scalar.h @@ -243,7 +245,16 @@ fennec_add_sources( - # string =============================================================================================================== +# threading ============================================================================================================ + + include/fennec/threading/atomic.h + include/fennec/threading/thread.h + + include/fennec/threading/detail/_thread.h + + + +# string =============================================================================================================== include/fennec/string/locale.h include/fennec/string/cstring.h include/fennec/string/string.h @@ -252,7 +263,7 @@ fennec_add_sources( - # format =============================================================================================================== +# format =============================================================================================================== include/fennec/format/format.h include/fennec/format/format_arg.h include/fennec/format/formatter.h @@ -264,26 +275,26 @@ fennec_add_sources( - # filesystem =========================================================================================================== +# filesystem =========================================================================================================== include/fennec/filesystem/file.h source/filesystem/file.cpp include/fennec/filesystem/path.h source/filesystem/path.cpp - # interpret ============================================================================================================ +# interpret ============================================================================================================ include/fennec/interpret/tokenizer.h - # PLATFORM ============================================================================================================= +# PLATFORM ============================================================================================================= include/fennec/platform/interface/fwd.h include/fennec/platform/interface/display_server.h include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp include/fennec/platform/interface/window.h source/platform/interface/window.cpp + include/fennec/platform/window_manager.h source/platform/window_manager.cpp - # GRAPHICS ============================================================================================================= +# GRAPHICS ============================================================================================================= - include/fennec/gfx3d/mesh_instance.h ) # add the test suite as a sub-project @@ -291,14 +302,6 @@ add_subdirectory(test) add_library(fennec STATIC ${FENNEC_SOURCES} - include/fennec/platform/window_manager.h - include/fennec/platform/window_manager.cpp - include/fennec/platform/window_manager.h - include/fennec/lang/function.h - include/fennec/threading/thread.h - include/fennec/threading/detail/_thread.h - include/fennec/lang/detail/_function.h - include/fennec/threading/atomic.h ) diff --git a/include/fennec/containers/list.h b/include/fennec/containers/list.h index 1b39e50..a7bac0b 100644 --- a/include/fennec/containers/list.h +++ b/include/fennec/containers/list.h @@ -424,17 +424,17 @@ public: /// /// \brief C++ Iterator Specification `end()` - /// \returns An iterator for the end of the list - constexpr iterator end() { - return iterator(this, npos); - } - - /// /// \returns A const iterator for the first element in the list constexpr const_iterator begin() const { return const_iterator(this, _root); } + /// + /// \returns An iterator for the end of the list + constexpr iterator end() { + return iterator(this, npos); + } + /// /// \brief Const C++ Iterator Specification `end()` /// \returns A const iterator for the end of the list diff --git a/include/fennec/containers/set.h b/include/fennec/containers/set.h index dc2cc47..e69fd7f 100644 --- a/include/fennec/containers/set.h +++ b/include/fennec/containers/set.h @@ -362,6 +362,7 @@ public: /// @{ /// + /// \brief C++ Iterator Specification `begin()` /// \returns An iterator for all elements of the set in no particular order constexpr iterator begin() const { iterator it(this, 0); @@ -372,6 +373,7 @@ public: } /// + /// \brief C++ Iterator Specification `end()` /// \returns An iterator representing the end of the set constexpr iterator end() const { return iterator(this, npos); diff --git a/include/fennec/gfx3d/mesh_instance.h b/include/fennec/gfx3d/mesh_instance.h deleted file mode 100644 index 03041a4..0000000 --- a/include/fennec/gfx3d/mesh_instance.h +++ /dev/null @@ -1,47 +0,0 @@ -// ===================================================================================================================== -// 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 mesh_instance.h -/// \brief -/// -/// -/// \details -/// \author Medusa Slockbower -/// -/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) -/// -/// - -#ifndef FENNEC_GFX3D_MESH_INSTANCE_H -#define FENNEC_GFX3D_MESH_INSTANCE_H -#include - -namespace fennec -{ - -class mesh_instance : component { -public: - - -private: -}; - -} - -#endif // FENNEC_GFX3D_MESH_INSTANCE_H \ No newline at end of file diff --git a/include/fennec/interpret/tokenizer.h b/include/fennec/interpret/tokenizer.h index a5b50a1..c7f1bd8 100644 --- a/include/fennec/interpret/tokenizer.h +++ b/include/fennec/interpret/tokenizer.h @@ -55,7 +55,8 @@ namespace fennec { - +/// +/// \brief Escape Sequence Specification struct escape_sequence { virtual size_t operator[](const string& str, size_t i) = 0; }; diff --git a/include/fennec/lang/assert.h b/include/fennec/lang/assert.h index 1ff98df..5152d61 100644 --- a/include/fennec/lang/assert.h +++ b/include/fennec/lang/assert.h @@ -68,21 +68,32 @@ #define __PRETTY_FUNCTION__ __FUNCSIG__ #endif -using assert_handler = void (*)(const char *, const char *, int , const char *); - +#ifndef FENNEC_DOXYGEN void _assert_impl(const char* expression, const char* file, int line, const char* function, const char* desc, bool halt); +#endif -// flagged unlikely to optimize branch prediction +/// +/// \brief base assert function, halts only in debug mode +/// \param expression the expression to validate +/// \param description the description of the assertion #define assert(expression, description) \ if(not(expression)) [[unlikely]] { \ _assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, not FENNEC_RELEASE); \ } +/// +/// \brief fail assert function, always halts +/// \param expression the expression to validate +/// \param description the description of the assertion #define assertf(expression, description) \ if(not(expression)) [[unlikely]] { \ _assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, true); \ } +/// +/// \brief debug assert function, only defined in debug mode +/// \param expression the expression to validate +/// \param description the description of the assertion #if FENNEC_RELEASE #define assertd(expression, description) #else diff --git a/include/fennec/lang/compare.h b/include/fennec/lang/compare.h index 649d864..f4d1c51 100644 --- a/include/fennec/lang/compare.h +++ b/include/fennec/lang/compare.h @@ -26,27 +26,58 @@ namespace fennec // equality ============================================================================================================ +/// +/// \brief Struct to test equality of two values +/// \tparam T0 The first type +/// \tparam T1 The second type template struct equality; +/// +/// \brief Implementations for two types that have a common equality operator \f$==\f$ +/// \tparam T0 The first type +/// \tparam T1 The second type template requires has_equals_v struct equality { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if equal, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { return x == y; } }; +/// +/// \brief Implementations for two types that have a common less operator \f$<\f$ +/// \tparam T0 The first type +/// \tparam T1 The second type template requires(not has_equals_v and has_less_v and has_less_v) struct equality { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if equal, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { return not(x < y) and not(y < x); } }; +/// +/// \brief Implementations for two types that have a common greater operator \f$>\f$ +/// \tparam T0 The first type +/// \tparam T1 The second type template requires(not(has_equals_v) and(not has_less_v or not has_less_v) and(has_greater_v and has_greater_v)) struct equality { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if equal, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { return not(x > y) and not(y > x); } @@ -55,24 +86,72 @@ struct equality { // inequality ========================================================================================================== +/// +/// \brief Struct to test inequality of two values +/// \tparam T0 The first type +/// \tparam T1 The second type template struct inequality; +/// +/// \brief Implementations for two types that have a common inequality operator \f$\neq\f$ +/// \tparam T0 The first type +/// \tparam T1 The second type template requires has_nequals_v struct inequality { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if not equal, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { return x != y; } }; + +/// +/// \brief Implementations for two types that have a common equality operator \f$==\f$ +/// \tparam T0 The first type +/// \tparam T1 The second type +template requires has_equals_v +struct inequality { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if not equal, \f$false\f$ otherwise + constexpr bool operator()(const T0& x, const T1& y) const { + return not (x == y); + } +}; + +/// +/// \brief Implementations for two types that have a common less operator \f$<\f$ +/// \tparam T0 The first type +/// \tparam T1 The second type template requires has_less_v and has_less_v struct inequality { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if not equal, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { return (x < y) or (y < x); } }; +/// +/// \brief Implementations for two types that have a common greater operator \f$>\f$ +/// \tparam T0 The first type +/// \tparam T1 The second type template requires has_greater_v and has_greater_v struct inequality { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if not equal, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { return (x > y) or (y > x); } @@ -81,8 +160,17 @@ struct inequality { // less ================================================================================================================ +/// +/// \brief Struct to test if a value of type `T0` is less than a value of type `T1` +/// \tparam T0 The first type +/// \tparam T1 The second type template requires has_less_v struct less { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if less, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { return x < y; } @@ -91,30 +179,57 @@ struct less { // less_equal ========================================================================================================== +/// +/// \brief Struct to test if a value of type `T0` is less than or equal to a value of type `T1` +/// \tparam T0 The first type +/// \tparam T1 The second type template requires has_less_equals_v struct less_equals { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if less than or equal, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { return x <= y; } }; -// less ================================================================================================================ +// greater ============================================================================================================= +/// +/// \brief Struct to test if a value of type `T0` is greater than a value of type `T1` +/// \tparam T0 The first type +/// \tparam T1 The second type template requires has_greater_v struct greater { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if greater, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { - return x < y; + return x > y; } }; // less_equal ========================================================================================================== +/// +/// \brief Struct to test if a value of type `T0` is greater than or equal to a value of type `T1` +/// \tparam T0 The first type +/// \tparam T1 The second type template requires has_greater_equals_v struct greater_equals { + /// + /// \brief operator to test the two values + /// \param x the value of type \f$T0\f$ + /// \param y the value of type \f$T1\f$ + /// \returns \f$true\f$ if greater than or equal, \f$false\f$ otherwise constexpr bool operator()(const T0& x, const T1& y) const { - return x <= y; + return x >= y; } }; diff --git a/include/fennec/lang/conditional_types.h b/include/fennec/lang/conditional_types.h index b37dfa8..baa9cc5 100644 --- a/include/fennec/lang/conditional_types.h +++ b/include/fennec/lang/conditional_types.h @@ -89,7 +89,7 @@ template using conditional_t = typename conditional::type; - +#ifndef FENNEC_DOXYGEN // specialization of fennec::conditional for \f$true\f$ case template struct conditional : type_identity{}; @@ -98,7 +98,7 @@ struct conditional : type_identity{}; // specialization of fennec::conditional for \f$false\f$ case template struct conditional : type_identity{}; - +#endif // fennec::detect ====================================================================================================== @@ -113,8 +113,8 @@ struct conditional : type_identity{}; template typename DetectT, typename...ArgsT> struct detect { - using type = DefaultT; - static constexpr bool is_detected = false; + using type = DefaultT; //!< the detected type + static constexpr bool is_detected = false; //!< whether it was detected }; /// @@ -123,6 +123,7 @@ template typename DetectT, typename...A using detect_t = typename detect::type; +#ifndef FENNEC_DOXYGEN // true case template typename DetectT, typename...ArgsT> requires requires { typename DetectT; } @@ -131,6 +132,7 @@ struct detect using type = DetectT; static constexpr bool is_detected = true; }; +#endif // fennec::enable_if =================================================================================================== @@ -156,9 +158,11 @@ struct enable_if {}; template using enable_if_t = typename enable_if::type; +#ifndef FENNEC_DOXYGEN // true case template struct enable_if { using type = T; }; +#endif } diff --git a/include/fennec/lang/declval.h b/include/fennec/lang/declval.h index 7c1f840..fbcee61 100644 --- a/include/fennec/lang/declval.h +++ b/include/fennec/lang/declval.h @@ -28,8 +28,8 @@ /// /// -#ifndef FENNEC_LANGCPP_DECLVAL_H -#define FENNEC_LANGCPP_DECLVAL_H +#ifndef FENNEC_LANG_DECLVAL_H +#define FENNEC_LANG_DECLVAL_H #include @@ -38,6 +38,10 @@ namespace fennec // fennec::declval ===================================================================================================== +/// +/// \brief Metaprogramming helper for testing values of type T +/// \tparam T the type +/// \returns a metavalue of type \f$T\f$ template auto declval() noexcept -> decltype(detail::_declval(0)) { static_assert(detail::_declval_protector{}, "declval must not be used"); return detail::_declval(0); @@ -45,4 +49,4 @@ template auto declval() noexcept -> decltype(detail::_declval(0)) } -#endif // FENNEC_LANGCPP_DECLVAL_H \ No newline at end of file +#endif // FENNEC_LANG_DECLVAL_H \ No newline at end of file diff --git a/include/fennec/lang/function.h b/include/fennec/lang/function.h index 6cf4ffb..b2447b9 100644 --- a/include/fennec/lang/function.h +++ b/include/fennec/lang/function.h @@ -40,39 +40,86 @@ namespace fennec { - +/// +/// \brief a class capable of holding a function or non-capturing lambda template class function; +/// +/// \brief a class capable of holding a function or non-capturing lambda +/// \tparam ReturnT The return type of the function +/// \tparam ArgsT The argument types of the function template class function { public: + /// + /// \brief default constructor constexpr function() noexcept = default; + + /// + /// \brief destructor constexpr ~function() = default; - constexpr function(const function&) noexcept = default; - constexpr function( function&&) noexcept = default; + /// + /// \brief copy constructor + /// \param func the function to copy + constexpr function(const function& func) noexcept = default; + /// + /// \brief move constructor + /// \param func the function to take ownership of + constexpr function(function&& func) noexcept = default; + + /// + /// \brief function constructor + /// \param func the function to capture constexpr function(ReturnT (*func)(ArgsT...)) : call(func) { } + /// + /// \brief null constructor constexpr function(nullptr_t) noexcept : function() {} - constexpr function& operator=(const function&) = default; - constexpr function& operator=(function&&) = default; + /// + /// \brief copy assignment + /// \param func the function to copy + /// \returns a reference to self + constexpr function& operator=(const function& func) = default; + /// + /// \brief move assignment + /// \param func the function to capture + /// \returns a reference to self + constexpr function& operator=(function&& func) = default; + + /// + /// \brief null assignment + /// \returns a reference to self constexpr function& operator=(nullptr_t) { call = nullptr; return *this; } + /// + /// \brief function assignment + /// \param func the function to capture + /// \returns a reference to self constexpr function& operator=(ReturnT (*func)(ArgsT...)) { call = func; return *this; } - constexpr operator bool() const noexcept { return call != nullptr; } + /// + /// \brief implicit bool check + /// \returns \f$true\f$ if a function is captured, \f$false\f$ otherwise + constexpr operator bool() const noexcept { + return call != nullptr; + } + /// + /// \brief function call operator + /// \param args the arguments to call the function with + /// \returns the result of the function call ReturnT operator()(ArgsT...args) const noexcept { assertf(call != nullptr, "Attempted to call a null function object!"); return call(fennec::forward(args)...); diff --git a/include/fennec/lang/hashing.h b/include/fennec/lang/hashing.h index 6a115ae..0700e98 100644 --- a/include/fennec/lang/hashing.h +++ b/include/fennec/lang/hashing.h @@ -31,10 +31,13 @@ namespace fennec /// \tparam Key The type to hash template struct hash; -// Murmur3 Hash for 64-bit ints +/// \brief Murmur3 Hash for 64-bit ints template<> struct hash { - using type_t = uint64_t; + using type_t = uint64_t; //!< the type of the hash + /// \brief hash operator + /// \param x the value to hash + /// \returns an integer hash for the value constexpr size_t operator()(uint64_t x) const { // Murmur3 x ^= x >> 33U; @@ -46,16 +49,22 @@ struct hash { } }; -// Wrapper for casting ints +/// \brief Hashing for integer types +/// \tparam IntT the integer type template requires is_integral_v struct hash : hash { - using type_t = IntT; + using type_t = IntT; //!< the type of the hash }; -// Wrapper for pointers +/// \brief Hashing for pointer types +/// \tparam PtrT The base type template struct hash : hash { + using type_t = PtrT*; //!< the type of the hash + /// \brief hash operator + /// \param ptr the pointer to hash + /// \returns an integer hash for the value constexpr size_t operator()(PtrT* ptr) const { return hash::operator()((uintptr_t)(const void*)ptr); } @@ -64,6 +73,10 @@ struct hash : hash { // Float template<> struct hash : hash { + using type_t = float; //!< the type of the hash + /// \brief hash operator + /// \param x the value to hash + /// \returns an integer hash for the value constexpr size_t operator()(float x) const { return hash::operator()(bit_cast(x)); } @@ -71,6 +84,10 @@ struct hash : hash { template<> struct hash : hash { + using type_t = double; //!< the type of the hash + /// \brief hash operator + /// \param x the value to hash + /// \returns an integer hash for the value constexpr size_t operator()(double x) const { return hash::operator()(bit_cast(x)); } diff --git a/include/fennec/lang/ranges.h b/include/fennec/lang/ranges.h index 7a644c9..65f7380 100644 --- a/include/fennec/lang/ranges.h +++ b/include/fennec/lang/ranges.h @@ -28,40 +28,72 @@ /// /// -#ifndef FENNEC_LANGCPP_RANGES_H -#define FENNEC_LANGCPP_RANGES_H +#ifndef FENNEC_LANG_RANGES_H +#define FENNEC_LANG_RANGES_H #include namespace fennec { +/// +/// \brief C++ Iterator Specification `begin()` +/// \tparam ContainerT the container type +/// \param c the container to iterate on +/// \returns an iterator at the start of the container template inline constexpr auto begin(ContainerT& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()) { return c.begin(); } +/// +/// \brief C++ Iterator Specification `begin()` +/// \tparam ContainerT the container type +/// \param c the container to iterate on +/// \returns an iterator at the start of the container template inline constexpr auto begin(const ContainerT& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()) { return c.begin(); } +/// +/// \brief C++ Iterator Specification `begin()` +/// \tparam T the element type +/// \tparam N the bounds of the array +/// \param arr a bounded array to iterate on +/// \returns an iterator at the start of the array template inline constexpr T* begin(T (&arr)[N]) noexcept { return arr; } +/// +/// \brief C++ Iterator Specification `end()` +/// \tparam ContainerT the container type +/// \param c the container to iterate on +/// \returns an iterator at the end of the container template inline constexpr auto end(ContainerT& c) noexcept(noexcept(c.end())) -> decltype(c.end()) { return c.end(); } +/// +/// \brief C++ Iterator Specification `end()` +/// \tparam ContainerT the container type +/// \param c the container to iterate on +/// \returns an iterator at the end of the container template inline constexpr auto end(const ContainerT& c) noexcept(noexcept(c.end())) -> decltype(c.end()) { return c.end(); } +/// +/// \brief C++ Iterator Specification `end()` +/// \tparam T the element type +/// \tparam N the bounds of the array +/// \param arr a bounded array to iterate on +/// \returns an iterator at the end of the array template inline constexpr T* end(T (&arr)[N]) noexcept { return arr + N; @@ -69,4 +101,4 @@ inline constexpr T* end(T (&arr)[N]) noexcept { } -#endif // FENNEC_LANGCPP_RANGES_H \ No newline at end of file +#endif // FENNEC_LANG_RANGES_H \ No newline at end of file diff --git a/include/fennec/lang/static_constructor.h b/include/fennec/lang/static_constructor.h index c444cd8..5b908e3 100644 --- a/include/fennec/lang/static_constructor.h +++ b/include/fennec/lang/static_constructor.h @@ -19,12 +19,17 @@ #ifndef FENNEC_LANG_STARTUP_H #define FENNEC_LANG_STARTUP_H -// Helper for running a function before main() +/// +/// \brief Macro for running a function before main +/// \param f the name of the function #define FENNEC_PRIVATE_STATIC_CONSTRUCTOR(f) \ inline static void f(void); \ struct f##_t_ { inline f##_t_(void) { f(); } }; inline static f##_t_ f##_; \ inline static void f(void) +/// +/// \brief Macro for running a function before main in a class scope +/// \param f the name of the function #define FENNEC_CLASS_STATIC_CONSTRUCTOR(f) \ struct f##_t_ { inline f##_t_(void) { f(); } }; inline static f##_t_ f##_; \ inline static void f(void) diff --git a/include/fennec/lang/type_operators.h b/include/fennec/lang/type_operators.h index 95b9306..40d67af 100644 --- a/include/fennec/lang/type_operators.h +++ b/include/fennec/lang/type_operators.h @@ -26,26 +26,38 @@ namespace fennec // has_equals ========================================================================================================== +/// +/// \brief Checks if a type has a defined equality operator +/// \tparam T0 The first type +/// \tparam T1 The second type template struct has_equals { +private: // Use SFINAE to check for the operator template static auto test(U*) -> decltype(declval() == declval()); template static auto test(...) -> false_type; - static constexpr bool value = is_same_v(0))>; +public: + static constexpr bool value = is_same_v(0))>; //!< The result of the check }; template constexpr bool has_equals_v = has_equals::value; // has_nequals ========================================================================================================= +/// +/// \brief Checks if a type has a defined inequality operator +/// \tparam T0 The first type +/// \tparam T1 The second type template struct has_nequals { +private: // Use SFINAE to check for the operator template static auto test(U*) -> decltype(declval() != declval()); template static auto test(...) -> false_type; - static constexpr bool value = is_same_v(0))>; +public: + static constexpr bool value = is_same_v(0))>; //!< The result of the check }; template constexpr bool has_nequals_v = has_nequals::value; @@ -53,13 +65,19 @@ template constexpr bool has_nequals_v = has_nequa // has_less ============================================================================================================ +/// +/// \brief Checks if a type has a defined less operator +/// \tparam T0 The first type +/// \tparam T1 The second type template struct has_less { +private: // Use SFINAE to check for the operator template static auto test(U*) -> decltype(declval() < declval()); template static auto test(...) -> false_type; - static constexpr bool value = is_same_v(0))>; +public: + static constexpr bool value = is_same_v(0))>; //!< The result of the check }; template constexpr bool has_less_v = has_less::value; @@ -67,13 +85,19 @@ template constexpr bool has_less_v = has_less struct has_less_equals { +private: // Use SFINAE to check for the operator template static auto test(U*) -> decltype(declval() <= declval()); template static auto test(...) -> false_type; - static constexpr bool value = is_same_v(0))>; +public: + static constexpr bool value = is_same_v(0))>; //!< The result of the check }; template constexpr bool has_less_equals_v = has_less_equals::value; @@ -81,13 +105,19 @@ template constexpr bool has_less_equals_v = has_l // has_greater ========================================================================================================= +/// +/// \brief Checks if a type has a defined greater operator +/// \tparam T0 The first type +/// \tparam T1 The second type template struct has_greater { +private: // Use SFINAE to check for the operator template static auto test(U*) -> decltype(declval() > declval()); template static auto test(...) -> false_type; - static constexpr bool value = is_same_v(0))>; +public: + static constexpr bool value = is_same_v(0))>; //!< The result of the check }; template constexpr bool has_greater_v = has_greater::value; @@ -95,13 +125,19 @@ template constexpr bool has_greater_v = has_great // has_greater_equals ================================================================================================== +/// +/// \brief Checks if a type has a defined greater equals operator +/// \tparam T0 The first type +/// \tparam T1 The second type template struct has_greater_equals { +private: // Use SFINAE to check for the operator template static auto test(U*) -> decltype(declval() >= declval()); template static auto test(...) -> false_type; - static constexpr bool value = is_same_v(0))>; +public: + static constexpr bool value = is_same_v(0))>; //!< The result of the check }; template constexpr bool has_greater_equals_v = has_greater_equals::value; diff --git a/include/fennec/lang/type_sequences.h b/include/fennec/lang/type_sequences.h index 4ea1576..25a69c7 100644 --- a/include/fennec/lang/type_sequences.h +++ b/include/fennec/lang/type_sequences.h @@ -77,7 +77,8 @@ template struct type_sequence {}; template struct first_element : detail::_first_element {}; /// -/// \brief alias for first_element::type +/// \brief alias for `first_element::type` +/// \tparam TypesT the Parameter Pack template using first_element_t = typename first_element::type; @@ -90,6 +91,10 @@ template using first_element_t = typename first_element struct nth_element : detail::_nth_element {}; +/// +/// \brief alias for nth_element::type +/// \tparam n The index in the type sequence +/// \tparam TypesT the Parameter Pack template using nth_element_t = nth_element::type; @@ -100,6 +105,7 @@ template using nth_element_t = nth_element` and replace the first \f$ArgT\f$ of `ArgsT...` with \f$SubT\f$ template struct replace_first_element { }; +#ifndef FENNEC_DOXYGEN // Implementation template< template class ClassT // The Base Template @@ -107,6 +113,7 @@ template< , typename... RestT> // The Rest of the Parameter Pack struct replace_first_element, SubT> // Specialization { using type = ClassT; }; // Definition +#endif @@ -155,9 +162,13 @@ template typename SearchT, typename...TypesT> struct search_e /// \tparam TypesT The type sequence to search template typename SearchT, typename...TypesT> using search_element_t = search_element::type; - template typename, typename, typename...> struct search_element_args; +/// +/// \brief Find the first element `T` in `TypesT...` that satisfies `SearchT` +/// \tparam SearchT A type that satisfies `template` and contains `static constexpr bool value;` to use for searching +/// \tparam TypesT The type sequence to search +/// \tparam ArgsT The arguments for the search template typename SearchT, typename...TypesT, typename...ArgsT> struct search_element_args, TypesT...> : detail::_search_element_args, TypesT...> { @@ -187,14 +198,16 @@ template constexpr bool contains_element_v = contains /// /// \brief Checks if all types in a type sequence are unique /// \tparam Ts The type sequence to check -template struct is_unique : false_type {}; +template struct is_unique : false_type {}; +#ifndef FENNEC_DOXYGEN // Single type case template struct is_unique : true_type {}; // Recursion case template requires(not is_same_v && ...) struct is_unique : is_unique {}; +#endif /// /// \brief Shorthand for `is_unique::value` diff --git a/include/fennec/lang/type_traits.h b/include/fennec/lang/type_traits.h index efacf4a..51cfd83 100644 --- a/include/fennec/lang/type_traits.h +++ b/include/fennec/lang/type_traits.h @@ -434,6 +434,9 @@ namespace fennec { +/// +/// \brief metaprogramming helper for determining if a function is consteval +/// \returns \f$true\f$ if under `consteval`, \f$false\f$ otherwise constexpr inline bool is_constant_evaluated() noexcept { if consteval { return true; @@ -1147,12 +1150,14 @@ template struct is_scoped_enum template struct is_scoped_enum : false_type {}; +#ifndef FENNEC_DOXYGEN // true case template requires __is_enum(T) and requires(remove_cv_t test) { test = test; } // fails if incomplete struct is_scoped_enum : bool_constant { }; +#endif #endif diff --git a/include/fennec/lang/type_transforms.h b/include/fennec/lang/type_transforms.h index be8d43d..1962633 100644 --- a/include/fennec/lang/type_transforms.h +++ b/include/fennec/lang/type_transforms.h @@ -129,8 +129,14 @@ namespace fennec // Decay Conversions =================================================================================================== +/// +/// \brief decays a type into its most basic form +/// \tparam T the type to decay template struct decay : detail::_decay {}; +/// +/// \brief shorthand for `typename decay::type` +/// \tparam T the type to decay template using decay_t = typename decay::type; // Pointer Conversions ================================================================================================= @@ -170,6 +176,8 @@ template struct strip_pointers : conditional_t< type_identity > {}; +/// +/// \brief shorthand for `typename strip_pointers::type` template using strip_pointers_t = strip_pointers::type; diff --git a/include/fennec/lang/utility.h b/include/fennec/lang/utility.h index af12dbe..4d013c4 100644 --- a/include/fennec/lang/utility.h +++ b/include/fennec/lang/utility.h @@ -76,10 +76,12 @@ template constexpr T&& forward(remove_reference_t& x) noexcept { return static_cast(x); } +#ifndef FENNEC_DOXYGEN // specialization for T&& template constexpr T&& forward(remove_reference_t&& x) noexcept { return static_cast(x); } +#endif /// diff --git a/include/fennec/math/common.h b/include/fennec/math/common.h index a9927d5..579007d 100644 --- a/include/fennec/math/common.h +++ b/include/fennec/math/common.h @@ -826,6 +826,7 @@ constexpr genType mix(genType x, genType y, genBType a) { // Internal ============================================================================================================ +#ifndef FENNEC_DOXYGEN template constexpr vector sign(const vector& x) { return vector(fennec::sign(x[i]) ...); @@ -1011,6 +1012,7 @@ template requires(is_b constexpr vector mix(const vector& x, const vector& y, const vector& a) { return genDType((a[i] ? y[i] : x[i])...); } +#endif // FENNEC_DOXYGEN /// @} diff --git a/include/fennec/math/exponential.h b/include/fennec/math/exponential.h index 35e8886..c807ff7 100644 --- a/include/fennec/math/exponential.h +++ b/include/fennec/math/exponential.h @@ -196,6 +196,7 @@ template constexpr genType inversesqrt(genType x) { // Internal ============================================================================================================ +#ifndef FENNEC_DOXYGEN template constexpr vector pow(const vector & x, const vector & y) { return vector(fennec::pow(x[i], y[i]) ...); @@ -225,6 +226,7 @@ template constexpr vector inversesqrt(const vector& x) { return vector(fennec::inversesqrt(x[i]) ...); } +#endif // FENNEC_DOXYGEN } diff --git a/include/fennec/math/ext/quaternion.h b/include/fennec/math/ext/quaternion.h index 1bae3e5..badc167 100644 --- a/include/fennec/math/ext/quaternion.h +++ b/include/fennec/math/ext/quaternion.h @@ -77,18 +77,20 @@ constexpr qua reciprocal(const qua& q) { return ~q / fennec::sqnorm(q); } - +/// +/// \brief quaternion structure type +/// \tparam ScalarT the base scalar type template struct quaternion : detail::vector_base_type { public: // Typedefs ============================================================================================================ - using base_type = detail::vector_base_type; - using scalar_t = ScalarT; - using quat_t = quaternion; - using vec3_t = vec; - using vec4_t = vec; + using base_type = detail::vector_base_type; //!< base vector_storage type + using scalar_t = ScalarT; //!< scalar type + using quat_t = quaternion; //!< quaternion type + using vec3_t = vec; //!< scalar equivalent vec3 type + using vec4_t = vec; //!< scalar equivalent vec4 type using base_type::data; using base_type::x, base_type::y, base_type::z, base_type::w; @@ -158,6 +160,7 @@ public: /// /// \brief Copy Assignment Operator /// \param q The quaternion to copy + /// \returns a reference to self constexpr quat_t& operator=(const quat_t& q) { data = q.data; return *this; @@ -166,6 +169,7 @@ public: /// /// \brief Move Assignment Operator /// \param q The quaternion to move + /// \returns a reference to self constexpr quat_t& operator=(quat_t&& q) noexcept { data = q.data; return *this; @@ -282,6 +286,11 @@ public: // Quaternion Vector Arithmetic Operators ============================================================================== + /// + /// \brief Quaternion-Vector Multiplication Operator + /// \param q the quaternion + /// \param v the vector + /// \returns the linear algebraic product of \f$q\f$ and \f$v\f$ 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); @@ -289,21 +298,41 @@ public: return v + (uv*q.w + uuv) * scalar_t(2); } + /// + /// \brief Vector-Quaternion Multiplication Operator + /// \param v the vector + /// \param q the quaternion + /// \returns the linear algebraic product of \f$v\f$ and \f$q\f$ constexpr friend vec3_t operator*(const vec3_t& v, const quat_t& q) { return fennec::reciprocal(q) * v; } + /// + /// \brief Quaternion-Vector Multiplication Operator + /// \param q the quaternion + /// \param v the vector + /// \returns the linear algebraic product of \f$q\f$ and \f$v\f$ constexpr friend vec4_t operator*(const quat_t& q, const vec4_t& v) { return vec4_t(q * v.xyz, v.w); } + /// + /// \brief Vector-Quaternion Multiplication Operator + /// \param v the vector + /// \param q the quaternion + /// \returns the linear algebraic product of \f$v\f$ and \f$q\f$ constexpr friend vec4_t operator*(const vec4_t& v, const quat_t& q) { return fennec::reciprocal(q) * v; } -// Quaternion Quaternion Arithmetic Operators ========================================================================== +// Quaternion-Quaternion Arithmetic Operators ========================================================================== + /// + /// \brief Quaternion-Quaternion Addition Operator + /// \param lhs the left hand side + /// \param rhs the right hand side + /// \returns the component-wise sum of \f$lhs\f$ and \f$rhs\f$ constexpr friend quat_t operator+(const quat_t& lhs, const quat_t& rhs) { return quat_t( lhs.w + rhs.w, @@ -313,6 +342,11 @@ public: ); } + /// + /// \brief Quaternion-Quaternion Subtraction Operator + /// \param lhs the left hand side + /// \param rhs the right hand side + /// \returns the component-wise difference of \f$lhs\f$ and \f$rhs\f$ constexpr friend quat_t operator-(const quat_t& lhs, const quat_t& rhs) { return quat_t( lhs.w - rhs.w, @@ -322,6 +356,11 @@ public: ); } + /// + /// \brief Quaternion-Quaternion Multiplication Operator + /// \param lhs the left hand side + /// \param rhs the right hand side + /// \returns the linear algebraic product of \f$lhs\f$ and \f$rhs\f$ constexpr friend quat_t operator*(const quat_t& lhs, const quat_t& rhs) { return quat_t( lhs.w*rhs.w - lhs.x*rhs.x - lhs.y*rhs.y - lhs.z * rhs.z, @@ -334,6 +373,11 @@ public: // Quaternion Quaternion Arithmetic Assignment Operators =============================================================== + /// + /// \brief Quaternion-Quaternion Addition Assignment Operator + /// \param lhs the left hand side + /// \param rhs the right hand side + /// \returns the component-wise sum of \f$lhs\f$ and \f$rhs\f$ stored in \f$lhs\f$ constexpr friend quat_t& operator+=(quat_t& lhs, const quat_t& rhs) { lhs.w += rhs.w; lhs.x += rhs.x; @@ -342,6 +386,11 @@ public: return lhs; } + /// + /// \brief Quaternion-Quaternion Subtraction Assignment Operator + /// \param lhs the left hand side + /// \param rhs the right hand side + /// \returns the component-wise difference of \f$lhs\f$ and \f$rhs\f$ stored in \f$lhs\f$ constexpr friend quat_t& operator-=(quat_t& lhs, const quat_t& rhs) { lhs.w -= rhs.w; lhs.x -= rhs.x; @@ -350,6 +399,11 @@ public: return lhs; } + /// + /// \brief Quaternion-Quaternion Multiplication Assignment Operator + /// \param lhs the left hand side + /// \param rhs the right hand side + /// \returns the linear algebraic product of \f$lhs\f$ and \f$rhs\f$ stored in \f$lhs\f$ constexpr friend quat_t& operator*=(quat_t& lhs, const quat_t& rhs) { return lhs = lhs * rhs; } diff --git a/include/fennec/math/ext/rect.h b/include/fennec/math/ext/rect.h index ebb041a..5841e18 100644 --- a/include/fennec/math/ext/rect.h +++ b/include/fennec/math/ext/rect.h @@ -37,15 +37,19 @@ namespace fennec { +/// +/// \brief a math structure representing the bounds of a rectangle +/// \tparam ScalarT the scalar type template struct rectangle { - tvec2 position, size; + tvec2 position; //!< the cartesian position of the box + tvec2 size; //!< the cartesian size of the box }; -using rect = rectangle; -using irect = rectangle; -using urect = rectangle; -using drect = rectangle; +using rect = rectangle; //!< a floating point rectangle +using irect = rectangle; //!< an integer rectangle +using urect = rectangle; //!< an unsigned integer rectangle +using drect = rectangle; //!< a double-precision floating point rectangle } diff --git a/include/fennec/math/matrix.h b/include/fennec/math/matrix.h index 522563c..406e6e4 100644 --- a/include/fennec/math/matrix.h +++ b/include/fennec/math/matrix.h @@ -160,8 +160,7 @@ constexpr mat transpose(const matrix constexpr scalar determinant(const matrix&) noexcept { @@ -169,6 +168,9 @@ constexpr scalar determinant(const matrix&) noexcept { return 0; } +/// +/// \brief Returns the determinant of \f$m\f$. +/// \returns \f$m^{-1}\f$ template constexpr matrix inverse(const matrix&) noexcept { static_assert(false, "implementation undefined"); @@ -176,10 +178,10 @@ constexpr matrix inverse(const matrix requires(is_scalar_v) struct matrix { @@ -260,6 +262,10 @@ struct matrix : data{ mat.data } { } + /// + /// \brief scalar conversion operator + /// \tparam OScalarT the scalar type of the other matrix + /// \param mat the matrix to convert template constexpr matrix(const matrix& mat) : matrix() { @@ -270,6 +276,10 @@ struct matrix } } + /// + /// \brief scalar conversion operator + /// \tparam OScalarT the scalar type of the other matrix + /// \param mat the matrix to convert template constexpr matrix(matrix&& mat) noexcept : matrix() { @@ -645,6 +655,7 @@ struct matrix /// \brief performs a linear algebraic matrix multiplication /// \param lhs the rows to multiply with /// \param rhs the columns to multiply with + /// \returns a matrix with the result of the multiplication template requires(columns == ORowsV) constexpr friend matrix operator*(const matrix_t& lhs, const matrix& rhs) { return matrix( @@ -652,6 +663,10 @@ struct matrix ); } + /// + /// \brief performs a linear algebraic matrix multiplication assignment + /// \param rhs the columns to multiply with + /// \returns a reference to self template requires(columns == ORowsV) constexpr matrix& operator*=(const matrix& rhs) { return *this = *this * rhs; @@ -665,13 +680,15 @@ struct matrix public: + /// + /// \param mat the matrix to transpose + /// \returns \f$m^T\f$ static constexpr matrix_t transpose(const transpose_t& mat) { return matrix_t(fennec::row(mat, ColIndicesV)...); } private: - // ReSharper disable once CppMemberFunctionMayBeStatic template constexpr void _construct() { // base case, does nothing, this will get optimized away diff --git a/include/fennec/math/scalar.h b/include/fennec/math/scalar.h index b51968f..9107966 100644 --- a/include/fennec/math/scalar.h +++ b/include/fennec/math/scalar.h @@ -65,10 +65,10 @@ namespace fennec { -using byte = uint8_t; -using ubyte = uint8_t; -using ushort = uint16_t; -using uint = uint32_t; +using byte = uint8_t; //!< a single byte type +using ubyte = uint8_t; //!< a single unsigned byte type +using ushort = uint16_t; //!< an unsigned short type +using uint = uint32_t; //!< an unsigned int type } diff --git a/include/fennec/math/vector.h b/include/fennec/math/vector.h index 73b95ae..c90695d 100644 --- a/include/fennec/math/vector.h +++ b/include/fennec/math/vector.h @@ -338,6 +338,9 @@ struct vector : detail::vector_base_type vector::_construct<0>(args...); } + /// + /// \brief initializer list constructor + /// \param init the initializer list constexpr vector(initializer_list init) { size_t i = 0; for (ScalarT x : init) { @@ -345,6 +348,9 @@ struct vector : detail::vector_base_type } } + /// + /// \brief initializer list conversion constructor + /// \param init the initializer list template constexpr vector(initializer_list init) { size_t i = 0; diff --git a/include/fennec/math/vector_base.h b/include/fennec/math/vector_base.h index 4c92624..6d7a5fc 100644 --- a/include/fennec/math/vector_base.h +++ b/include/fennec/math/vector_base.h @@ -60,7 +60,7 @@ struct vector_base_type_helper /// \tparam IndicesV Indices of the vector to pull from template struct SwizzleGen { - // \brief generated swizzle type + /// \brief generated swizzle type using type = swizzle; }; @@ -68,7 +68,7 @@ struct vector_base_type_helper /// \tparam IndicesV Indices of the vector to pull from template struct SwizzleGen { - // \brief decayed scalar type + /// \brief decayed scalar type using type = ScalarT; }; diff --git a/include/fennec/math/vector_storage.h b/include/fennec/math/vector_storage.h index 8e3de31..a9355fa 100644 --- a/include/fennec/math/vector_storage.h +++ b/include/fennec/math/vector_storage.h @@ -46,7 +46,7 @@ namespace fennec::detail template