diff --git a/doxy/Doxyfile.in b/doxy/Doxyfile.in index 76c4fe4..b0d91a6 100644 --- a/doxy/Doxyfile.in +++ b/doxy/Doxyfile.in @@ -582,7 +582,7 @@ RESOLVE_UNNAMED_PARAMS = YES # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. -HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set @@ -591,7 +591,7 @@ HIDE_UNDOC_MEMBERS = YES # if EXTRACT_ALL is enabled. # The default value is: NO. -HIDE_UNDOC_CLASSES = YES +HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # declarations. If set to NO, these declarations will be included in the @@ -701,7 +701,7 @@ SORT_BRIEF_DOCS = NO # detailed member documentation. # The default value is: NO. -SORT_MEMBERS_CTORS_1ST = NO +SORT_MEMBERS_CTORS_1ST = YES # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will diff --git a/include/fennec/containers/bintree.h b/include/fennec/containers/bintree.h index b103abf..2476b2d 100644 --- a/include/fennec/containers/bintree.h +++ b/include/fennec/containers/bintree.h @@ -385,8 +385,9 @@ public: /// /// \brief Perform a Tree Rotation at `i` in the specified direction - /// \param i The root node for the rotation + /// \param sub The root node for the rotation /// \param dir The direction to rotate, `true` for right, `false` for left + /// \returns the new root constexpr size_t rotate(size_t sub, bool dir) { if (sub == npos) { return npos; @@ -504,6 +505,8 @@ public: } } + /// + /// \brief Traverser pattern for breadth-first traversal struct breadth_first { list visit; size_t head; @@ -540,6 +543,8 @@ public: } }; + /// + /// \brief Traverser pattern for pre-order traversal struct pre_order { list visit; size_t head; @@ -577,6 +582,8 @@ public: } }; + /// + /// \brief Traverser pattern for in-order traversal struct in_order { list visit; size_t head; @@ -614,6 +621,8 @@ public: } }; + /// + /// \brief Traverser pattern for post-order traversal struct post_order { list visit; size_t head; diff --git a/include/fennec/containers/containers.h b/include/fennec/containers/containers.h index 6dcb13c..6b1459d 100644 --- a/include/fennec/containers/containers.h +++ b/include/fennec/containers/containers.h @@ -44,24 +44,24 @@ /// /// | Symbol | Implemented | Passed | /// |:----------------------------------------------------------------------------|:-----------:|:------:| -/// | \ref fennec::any "fennec::any" | ⛔ | ⛔ | -/// | \ref fennec::array "fennec::array" | ✅ | ✅ | -/// | \ref fennec::bitset "fennec::bitset" | ⛔ | ⛔ | -/// | \ref fennec::deque "fennec::deque" | ⛔ | ⛔ | +/// | \ref fennec::generic "fennec::generic" `std::any` | 🚧 | 🚧 | +/// | \ref fennec::array "fennec::array" | ✅ | ✅ | +/// | \ref fennec::bitfield "fennec::bitfield" `std::bitset` | 🚧 | 🚧 | +/// | \ref fennec::deque "fennec::deque" | 🚧 | 🚧 | /// | \ref fennec::dynarray "fennec::dynarray" `std::vector` | 🚧 | 🚧 | -/// | \ref fennec::list "fennec::list" | ✅ | ✅ | -/// | \ref fennec::map "fennec::map" `std::unordered_map` | ✅ | ✅ | -/// | \ref fennec::map_sequence "fennec::map_sequence" `std::map` | ⛔ | ⛔ | -/// | \ref fennec::multiset "fennec::multiset" `std::unordered_multiset` | ⛔ | ⛔ | -/// | \ref fennec::multisequence "fennec::multisequence" `std::multiset` | ⛔ | ⛔ | -/// | \ref fennec::multimap "fennec::multimap" `std::unordered_multimap` | ⛔ | ⛔ | -/// | \ref fennec::multimap_sequence "fennec::multimap_sequence" `std::multimap` | ⛔ | ⛔ | -/// | \ref fennec::optional "fennec::optional" | ✅ | ✅ | -/// | \ref fennec::pair "fennec::pair" | ✅ | ✅ | -/// | \ref fennec::sequence "fennec::sequence" `std::set` | ⛔ | ⛔ | -/// | \ref fennec::set "fennec::set" `std::unordered_set` | ✅ | ✅ | +/// | \ref fennec::list "fennec::list" | ✅ | ✅ | +/// | \ref fennec::map "fennec::map" `std::unordered_map` | ✅ | ✅ | +/// | \ref fennec::map_sequence "fennec::map_sequence" `std::map` | ⛔ | ⛔ | +/// | \ref fennec::multiset "fennec::multiset" `std::unordered_multiset` | ⛔ | ⛔ | +/// | \ref fennec::multisequence "fennec::multisequence" `std::multiset` | ⛔ | ⛔ | +/// | \ref fennec::multimap "fennec::multimap" `std::unordered_multimap` | ⛔ | ⛔ | +/// | \ref fennec::multimap_sequence "fennec::multimap_sequence" `std::multimap` | ⛔ | ⛔ | +/// | \ref fennec::optional "fennec::optional" | ✅ | ✅ | +/// | \ref fennec::pair "fennec::pair" | ✅ | ✅ | +/// | \ref fennec::sequence "fennec::sequence" `std::set` | 🚧 | 🚧 | +/// | \ref fennec::set "fennec::set" `std::unordered_set` | ✅ | ✅ | /// | \ref fennec::tuple "fennec::tuple" | 🚧 | 🚧 | -/// | \ref fennec::variant "fennec::variant" | ⛔ | ⛔ | +/// | \ref fennec::variant "fennec::variant" | 🚧 | 🚧 | /// /// /// \section fennec_containers_fennec fennec @@ -70,7 +70,7 @@ /// |:-------------------------|:-----------:|:------:| /// | \ref fennec::graph | 🚧 | 🚧 | /// | \ref fennec::object_pool | 🚧 | 🚧 | -/// | \ref fennec::rdtree | ✅ | ✅ | +/// | \ref fennec::rdtree | ✅ | ✅ | /// /// /// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) diff --git a/include/fennec/containers/generic.h b/include/fennec/containers/generic.h index e953ebc..e5abb08 100644 --- a/include/fennec/containers/generic.h +++ b/include/fennec/containers/generic.h @@ -17,7 +17,7 @@ // ===================================================================================================================== /// -/// \file universal.h +/// \file generic.h /// \brief /// /// diff --git a/include/fennec/containers/list.h b/include/fennec/containers/list.h index b929bbe..f3740d3 100644 --- a/include/fennec/containers/list.h +++ b/include/fennec/containers/list.h @@ -256,6 +256,7 @@ public: /// \brief Copy Insertion /// \param it Location to insert at /// \param x value to copy + /// \returns The id of the inserted node /// /// \details \f$O(1)\f$ constexpr size_t insert(const iterator& it, const value_t& x) { @@ -266,6 +267,7 @@ public: /// \brief Move Insertion /// \param it Location to insert at /// \param x value to move + /// \returns The id of the inserted node /// /// \details \f$O(1)\f$ constexpr size_t insert(const iterator& it, value_t&& x) { @@ -276,6 +278,7 @@ public: /// \brief Copy Insertion /// \param i Index to insert at /// \param x value to copy + /// \returns The id of the inserted node /// /// \details \f$O(N)\f$ constexpr size_t insert(size_t i, const value_t& x) { @@ -289,6 +292,7 @@ public: /// \brief Move Insertion /// \param i Index to insert at /// \param x value to move + /// \returns The id of the inserted node /// /// \details \f$O(N)\f$ constexpr size_t insert(size_t i, value_t&& x) { @@ -303,6 +307,7 @@ public: /// \tparam ArgsT Argument types /// \param i Index to insert at /// \param args Arguments to construct with + /// \returns The id of the inserted node /// /// \details \f$O(N)\f$ template @@ -316,6 +321,7 @@ public: /// /// \brief Push Front Copy /// \param x Value to copy + /// \returns The id of the inserted node constexpr size_t push_front(const value_t& x) { return this->_insert(_root, x); } @@ -323,6 +329,7 @@ public: /// /// \brief Push Front Move /// \param x Value to move + /// \returns The id of the inserted node constexpr size_t push_front(value_t&& x) { return this->_insert(_root, fennec::forward(x)); } @@ -331,6 +338,7 @@ public: /// \brief Emplace Front /// \param args Arguments to construct with /// \tparam ArgsT Argument types + /// \returns The id of the inserted node template constexpr size_t emplace_front(ArgsT&&...args) { return this->_insert(_root, fennec::forward(args)...); @@ -339,6 +347,7 @@ public: /// /// \brief Push Back Copy /// \param x Value to copy + /// \returns The id of the inserted node constexpr size_t push_back(const value_t& x) { return this->_insert(npos, x); } @@ -346,6 +355,7 @@ public: /// /// \brief Push Back Move /// \param x Value to move + /// \returns The id of the inserted node constexpr size_t push_back(value_t&& x) { return this->_insert(npos, fennec::forward(x)); } @@ -354,6 +364,7 @@ public: /// \brief Emplace Back /// \param args Arguments to construct with /// \tparam ArgsT Argument types + /// \returns The id of the inserted node template constexpr size_t emplace_back(ArgsT&&...args) { return this->_insert(npos, fennec::forward(args)...); diff --git a/include/fennec/containers/map.h b/include/fennec/containers/map.h index b84181a..362056b 100644 --- a/include/fennec/containers/map.h +++ b/include/fennec/containers/map.h @@ -173,8 +173,8 @@ public: /// /// \brief Argument Key Access Operator - /// \tparam ArgT Argument Type - /// \param arg Argument to construct the key with + /// \tparam ArgsT Argument Types + /// \param args Arguments to construct the key with /// \returns A pointer to the value associated with `key`, `nullptr` if `key` is not present. template constexpr value_t* operator[](ArgsT&&...args) { @@ -210,6 +210,7 @@ public: /// /// \brief Key-Value Insertion + /// \param key key to insert /// \param args Arguments for constructing the key-value pair template constexpr void emplace(const KeyT& key, ArgsT&&...args) { diff --git a/include/fennec/containers/optional.h b/include/fennec/containers/optional.h index 006acfd..eb019ad 100644 --- a/include/fennec/containers/optional.h +++ b/include/fennec/containers/optional.h @@ -140,7 +140,8 @@ public: /// @{ /// - /// \brief Implicit Boolean Check, returns `true` when there is a value contained + /// \brief Implicit Boolean Check + /// \returns `true` when there is a value contained constexpr operator bool() const { return _set; } @@ -160,8 +161,8 @@ public: /// @{ /// - /// \brief Fundamental Type Assignment - /// \param val The value to set with + /// \brief Null Assignment + /// \returns A reference to self constexpr optional& operator=(nullopt_t) { if constexpr(not is_fundamental_v) { if (_set) { @@ -176,6 +177,7 @@ public: /// /// \brief Type Copy Assignment /// \param val The value to set with + /// \returns A reference to self constexpr optional& operator=(const T& val) requires is_copy_constructible_v and is_copy_assignable_v { if (_set) { _val = val; @@ -189,6 +191,7 @@ public: /// /// \brief Type Move Assignment /// \param val The value to set with + /// \returns A reference to self constexpr optional& operator=(T&& val) requires is_move_constructible_v and is_move_assignable_v { if (_set) { _val = fennec::forward(val); @@ -202,6 +205,7 @@ public: /// /// \brief Copy Assignment /// \param opt The optional to copy + /// \returns A reference to self constexpr optional& operator=(const optional& opt) requires is_copy_constructible_v and is_copy_assignable_v { if (_set != opt._set) { _set = opt._set; @@ -220,6 +224,7 @@ public: /// /// \brief Move Assignment /// \param opt The optional to move + /// \returns A reference to self constexpr optional& operator=(optional&& opt) noexcept requires is_move_constructible_v and is_move_assignable_v { if (_set != opt._set) { _set = opt._set; @@ -297,6 +302,7 @@ public: /// /// \brief Emplace Assignment, Move overload /// \param val The object to take ownership of + /// \returns A reference to the held value constexpr T& emplace(T&& val) { if (_set) { _val = fennec::forward(val); @@ -310,6 +316,7 @@ public: /// /// \brief Emplace Assignment, Copy overload /// \param val The object to copy + /// \returns A reference to the held value constexpr T& emplace(const T& val) { if (_set) { _val = val; @@ -323,6 +330,7 @@ public: /// /// \brief Emplace Assignment /// \param args The arguments to construct with + /// \returns A reference to the held value template constexpr T& emplace(ArgsT&&...args) { if (_set) { diff --git a/include/fennec/containers/pair.h b/include/fennec/containers/pair.h index e66b49e..98dc18f 100644 --- a/include/fennec/containers/pair.h +++ b/include/fennec/containers/pair.h @@ -95,6 +95,7 @@ struct pair { /// /// \brief Copy Constructor, copies both elements + /// \param pair The pair to copy constexpr pair(const pair& pair) : first(fennec::copy(pair.first)) , second(fennec::copy(pair.second)) { @@ -102,6 +103,7 @@ struct pair { /// /// \brief Move Constructor, moves both elements + /// \param pair The pair to move constexpr pair(pair&& pair) noexcept : first(fennec::move(pair.first)) , second(fennec::move(pair.second)) { @@ -109,6 +111,8 @@ struct pair { /// /// \brief Copy Assignment, copies both elements + /// \param pair The pair to copy + /// \returns A reference to self constexpr pair& operator=(const pair& pair) { first = fennec::copy(pair.first); second = fennec::copy(pair.second); @@ -117,6 +121,8 @@ struct pair { /// /// \brief Move Assignment, moves both elements + /// \param pair The pair to move + /// \returns A reference to self constexpr pair& operator=(pair&& pair) { first = fennec::move(pair.first); second = fennec::move(pair.second); diff --git a/include/fennec/containers/rdtree.h b/include/fennec/containers/rdtree.h index 3a8186d..8173b9f 100644 --- a/include/fennec/containers/rdtree.h +++ b/include/fennec/containers/rdtree.h @@ -194,6 +194,7 @@ public: /// /// \param i The id of the node to check + /// \param n The index of the child relative to the parent /// \returns The id of the child node constexpr size_t child(size_t i, size_t n = 0) const { if (i >= _table.capacity() && n != npos) return npos; @@ -205,6 +206,7 @@ public: /// /// \param i The id of the node to check + /// \param n The index of the child relative to the parent /// \returns The id of the next node constexpr size_t next(size_t i, size_t n = 0) const { if (i >= _table.capacity() && n != npos) return npos; @@ -229,6 +231,7 @@ public: /// /// \param i The id of the node to check + /// \param n The index of the child relative to the parent /// \returns The id of the previous node constexpr size_t prev(size_t i, size_t n = 0) const { if (i >= _table.capacity()) return npos; diff --git a/include/fennec/containers/set.h b/include/fennec/containers/set.h index b30e904..d7022d5 100644 --- a/include/fennec/containers/set.h +++ b/include/fennec/containers/set.h @@ -291,6 +291,7 @@ public: /// /// \brief Move Insertion /// \param val Value to insert + /// \returns An iterator at the held value constexpr iterator insert(elem_t&& val) { return this->_insert(fennec::forward(val)); } @@ -298,6 +299,7 @@ public: /// /// \brief Copy Insertion /// \param val Value to insert + /// \returns An iterator at the held value constexpr iterator insert(const elem_t& val) { return this->_insert(val); } @@ -306,6 +308,7 @@ public: /// \brief Emplace Insertion /// \tparam ArgsT Argument types /// \param args Arguments to construct with + /// \returns An iterator at the held value template constexpr iterator emplace(ArgsT&&...args) { return this->_insert(fennec::forward(args)...); diff --git a/include/fennec/lang/intrinsics.h b/include/fennec/lang/intrinsics.h index b0a20f4..7a14e2e 100644 --- a/include/fennec/lang/intrinsics.h +++ b/include/fennec/lang/intrinsics.h @@ -168,6 +168,14 @@ # define FENNEC_HAS_BUILTIN_IS_ARRAY #endif +// Inconsistent without intrinsics +#if __has_builtin(__is_bounded_array) +# define FENNEC_HAS_BUILTIN_IS_BOUNDED_ARRAY 1 +# define FENNEC_BUILTIN_IS_BOUNDED_ARRAY(arg) __is_bounded_array(arg) +#else +# define FENNEC_HAS_BUILTIN_IS_BOUNDED_ARRAY +#endif + // Inconsistent without intrinsics #if __has_builtin(__is_class) # define FENNEC_HAS_BUILTIN_IS_CLASS 1 @@ -176,6 +184,14 @@ # define FENNEC_HAS_BUILTIN_IS_CLASS #endif +// Inconsistent without intrinsics +#if __has_builtin(__is_scoped_enum) +# define FENNEC_HAS_BUILTIN_IS_SCOPED_ENUM 1 +# define FENNEC_BUILTIN_IS_SCOPED_ENUM(arg) __is_scoped_enum(arg) +#else +# define FENNEC_HAS_BUILTIN_IS_SCOPED_ENUM +#endif + #if __has_builtin(__is_member_pointer) # define FENNEC_HAS_BUILTIN_IS_MEMBER_POINTER 1 # define FENNEC_BUILTIN_IS_MEMBER_POINTER(arg) __is_member_pointer(arg) @@ -211,11 +227,19 @@ // Difficult and Inconsistent without intrinsics #if __has_builtin(__is_trivially_constructible) # define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 1 -# define FENNEC_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE(type) __is_trivially_constructible(type) +# define FENNEC_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE(type, ...) __is_trivially_constructible(type __VA_OPT__(,) __VA_ARGS__) #else # define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 0 #endif +// Difficult and Inconsistent without intrinsics +#if __has_builtin(__is_nothrow_constructible) +# define FENNEC_HAS_BUILTIN_IS_NOTHROW_CONSTRUCTIBLE 1 +# define FENNEC_BUILTIN_IS_NOTHROW_CONSTRUCTIBLE(type, ...) __is_nothrow_constructible(type __VA_OPT__(,) __VA_ARGS__) +#else +# define FENNEC_HAS_BUILTIN_IS_NOTHROW_CONSTRUCTIBLE 0 +#endif + // Difficult and Inconsistent without intrinsics #if __has_builtin(__has_trivial_destructor) # define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 1 @@ -235,6 +259,22 @@ # define FENNEC_HAS_BUILTIN_IS_ASSIGNABLE 0 #endif +// Difficult and Inconsistent without intrinsics +#if __has_builtin(__is_trivially_assignable) +# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_ASSIGNABLE 1 +# define FENNEC_BUILTIN_IS_TRIVIALLY_ASSIGNABLE(a, b) __is_trivially_assignable(a, b) +#else +# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_ASSIGNABLE 0 +#endif + +// Difficult and Inconsistent without intrinsics +#if __has_builtin(__is_nothrow_assignable) +# define FENNEC_HAS_BUILTIN_IS_NOTHROW_ASSIGNABLE 1 +# define FENNEC_BUILTIN_IS_NOTHROW_ASSIGNABLE(a, b) __is_nothrow_assignable(a, b) +#else +# define FENNEC_HAS_BUILTIN_IS_NOTHROW_ASSIGNABLE 0 +#endif + // Inconsistent without intrinsics #if __has_builtin(__is_trivial) # define FENNEC_HAS_BUILTIN_IS_TRIVIAL 1 diff --git a/include/fennec/lang/limits.h b/include/fennec/lang/limits.h index f87df2b..428954a 100644 --- a/include/fennec/lang/limits.h +++ b/include/fennec/lang/limits.h @@ -249,15 +249,15 @@ template struct numeric_limits static constexpr float_round_style rounding_style = round_indeterminate; ///< The rounding style of TypeT // This is very poorly named and defined in the C++ Standard so these functions differ - static constexpr TypeT min() { return TypeT(); } ///< Returns the minimum finite value of TypeT - static constexpr TypeT max() { return TypeT(); } ///< Returns the maximum finite value of TypeT - static constexpr TypeT lowest() { return TypeT(); } ///< Returns the smallest positive value of TypeT - static constexpr TypeT epsilon() { return TypeT(); } ///< Returns the difference between 1.0 and the next representable value - static constexpr TypeT round_error() { return TypeT(); } ///< Returns the max rounding error of TypeT - static constexpr TypeT infinity() { return TypeT(); } ///< Returns a value of TypeT holding a positive infinity - static constexpr TypeT quiet_NaN() { return TypeT(); } ///< Returns a value of TypeT holding a quiet NaN - static constexpr TypeT signaling_NaN() { return TypeT(); } ///< Returns a value of TypeT holding a signaling NaN - static constexpr TypeT denorm_min() { return TypeT(); } ///< Returns a value of TypeT holding the smallest positive subnormal + static constexpr TypeT min() { return TypeT(); } ///< \returns the minimum finite value of TypeT + static constexpr TypeT max() { return TypeT(); } ///< \returns the maximum finite value of TypeT + static constexpr TypeT lowest() { return TypeT(); } ///< \returns the smallest positive value of TypeT + static constexpr TypeT epsilon() { return TypeT(); } ///< \returns the difference between 1.0 and the next representable value + static constexpr TypeT round_error() { return TypeT(); } ///< \returns the max rounding error of TypeT + static constexpr TypeT infinity() { return TypeT(); } ///< \returns a value of TypeT holding a positive infinity + static constexpr TypeT quiet_NaN() { return TypeT(); } ///< \returns a value of TypeT holding a quiet NaN + static constexpr TypeT signaling_NaN() { return TypeT(); } ///< \returns a value of TypeT holding a signaling NaN + static constexpr TypeT denorm_min() { return TypeT(); } ///< \returns a value of TypeT holding the smallest positive subnormal }; // Overload definitions for basic types diff --git a/include/fennec/lang/type_traits.h b/include/fennec/lang/type_traits.h index 38fe857..c594cec 100644 --- a/include/fennec/lang/type_traits.h +++ b/include/fennec/lang/type_traits.h @@ -1,4 +1,4 @@ -// ===================================================================================================================== +// --------------------------------------------------------------------------------------------------------------------- // fennec, a free and open source game engine // Copyright © 2025 Medusa Slockbower // @@ -14,7 +14,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -// ===================================================================================================================== +// --------------------------------------------------------------------------------------------------------------------- /// /// \file type_traits.h @@ -41,383 +41,389 @@ /// /// /// -/// \section Primary Type Categories +/// \section fennec_lang_type_traits_section_primary_type_categories Primary Type Categories /// -/// -///
Syntax -/// Description -///

+/// +///
Syntax +/// Description +///

/// \ref fennec::is_void "is_void::value"
/// \ref fennec::is_void_v "is_void_v" -///
+/// /// \copydetails fennec::is_void /// -///

+///

/// \ref fennec::is_null_pointer "is_null_pointer::value"
/// \ref fennec::is_null_pointer_v "is_null_pointer_v" -///
+/// /// \copydetails fennec::is_null_pointer /// -///

+///

/// \ref fennec::is_bool "is_bool::value"
/// \ref fennec::is_bool_v "is_bool_v" -///
+/// /// \copydetails fennec::is_bool /// -///

+///

/// \ref fennec::is_integral "is_integral::value"
/// \ref fennec::is_integral_v "is_integral_v" -///
+/// /// \copydetails fennec::is_integral /// -///

+///

/// \ref fennec::is_floating_point "is_floating_point::value"
/// \ref fennec::is_floating_point_v "is_floating_point_v" -///
+/// /// \copydetails fennec::is_floating_point /// -///

+///

/// \ref fennec::is_array "is_array::value"
/// \ref fennec::is_array_v "is_array_v" -///
+/// /// \copydetails fennec::is_array /// -///

+///

/// \ref fennec::is_enum "is_enum::value"
/// \ref fennec::is_enum_v "is_enum_v" -///
+/// /// \copydetails fennec::is_enum /// -///

+///

/// \ref fennec::is_union "is_union::value"
/// \ref fennec::is_union_v "is_union_v" -///
+/// /// \copydetails fennec::is_union /// -///

+///

/// \ref fennec::is_class "is_class::value"
/// \ref fennec::is_class_v "is_class_v" -///
+/// /// \copydetails fennec::is_class /// -///

+///

/// \ref fennec::is_function "is_function::value"
/// \ref fennec::is_function_v "is_function_v" -///
+/// /// \copydetails fennec::is_function /// -///

+///

/// \ref fennec::is_pointer "is_pointer::value"
/// \ref fennec::is_pointer_v "is_pointer_v" -///
+/// /// \copydetails fennec::is_pointer /// -///

+///

/// \ref fennec::is_lvalue_reference "is_lvalue_reference::value"
/// \ref fennec::is_lvalue_reference_v "is_lvalue_reference_v" -///
+/// /// \copydetails fennec::is_lvalue_reference /// -///

+///

/// \ref fennec::is_rvalue_reference "is_rvalue_reference::value"
/// \ref fennec::is_rvalue_reference_v "is_rvalue_reference_v" -///
+/// /// \copydetails fennec::is_rvalue_reference /// -///

+///

/// \ref fennec::is_member_object_pointer "is_member_object_pointer::value"
/// \ref fennec::is_member_object_pointer_v "is_member_object_pointer_v" -///
+/// /// \copydetails fennec::is_member_object_pointer /// -///

+///

/// \ref fennec::is_member_function_pointer "is_member_function_pointer::value"
/// \ref fennec::is_member_function_pointer_v "is_member_function_pointer_v" -///
+/// /// \copydetails fennec::is_member_function_pointer /// ///
/// /// /// -/// \section Composite Type Categories +/// \section fennec_lang_type_traits_section_composite_type_categories Composite Type Categories /// -/// -///
Syntax -/// Description +/// +///
Syntax +/// Description /// -///

+///

/// \ref fennec::is_arithmetic "is_arithmetic::value"
/// \ref fennec::is_arithmetic_v "is_arithmetic_v" -///
+/// /// \copydetails fennec::is_arithmetic /// -///

+///

/// \ref fennec::is_fundamental "is_fundamental::value"
/// \ref fennec::is_fundamental_v "is_fundamental_v" -///
+/// /// \copydetails fennec::is_fundamental /// -///

+///

/// \ref fennec::is_scalar "is_scalar::value"
/// \ref fennec::is_scalar_v "is_scalar_v" -///
+/// /// \copydetails fennec::is_scalar /// -///

+///

/// \ref fennec::is_object "is_object::value"
/// \ref fennec::is_object_v "is_object_v" -///
+/// /// \copydetails fennec::is_object /// -///

+///

/// \ref fennec::is_compound "is_compound::value"
/// \ref fennec::is_compound_v "is_compound_v" -///
+/// /// \copydetails fennec::is_compound /// -///

+///

/// \ref fennec::is_reference "is_reference::value"
/// \ref fennec::is_reference_v "is_reference_v" -///
+/// /// \copydetails fennec::is_reference /// -///

+///

/// \ref fennec::is_member_pointer "is_member_pointer::value"
/// \ref fennec::is_member_pointer_v "is_member_pointer_v" -///
+/// /// \copydetails fennec::is_member_pointer /// ///
/// /// /// -/// \section Type Properties +/// \section fennec_lang_type_traits_section_type_properties Type Properties /// -/// -///
Syntax -/// Description +/// +///
Syntax +/// Description /// -///

+///

/// \ref fennec::is_const "is_const::value"
/// \ref fennec::is_const_v "is_const_v" -///
+/// /// \copydetails fennec::is_const /// -///

+///

/// \ref fennec::is_volatile "is_volatile::value"
/// \ref fennec::is_volatile_v "is_volatile_v" -///
+/// /// \copydetails fennec::is_volatile /// -///

+///

/// \ref fennec::is_trivial "is_trivial::value"
/// \ref fennec::is_trivial_v "is_trivial_v" -///
+/// /// \copydetails fennec::is_trivial /// -///

+///

/// \ref fennec::is_trivially_copyable "is_trivially_copyable::value"
/// \ref fennec::is_trivially_copyable_v "is_trivially_copyable_v" -///
+/// /// \copydetails fennec::is_trivially_copyable /// -///

+///

/// \ref fennec::is_standard_layout "is_standard_layout::value"
/// \ref fennec::is_standard_layout_v "is_standard_layout_v" -///
+/// /// \copydetails fennec::is_standard_layout /// -///

+///

/// \ref fennec::has_unique_object_representations "has_unique_object_representations::value"
/// \ref fennec::has_unique_object_representations_v "has_unique_object_representations_v" -///
+/// /// \copydetails fennec::has_unique_object_representations /// -///

+///

/// \ref fennec::is_empty "is_empty::value"
/// \ref fennec::is_empty_v "is_empty_v" -///
+/// /// \copydetails fennec::is_empty /// -///

+///

/// \ref fennec::is_polymorphic "is_polymorphic::value"
/// \ref fennec::is_polymorphic_v "is_polymorphic_v" -///
+/// /// \copydetails fennec::is_polymorphic /// -///

+///

/// \ref fennec::is_abstract "is_abstract::value"
/// \ref fennec::is_abstract_v "is_abstract_v" -///
+/// /// \copydetails fennec::is_abstract /// -///

+///

/// \ref fennec::is_complete "is_complete::value"
/// \ref fennec::is_complete_v "is_complete_v" -///
+/// /// \copydetails fennec::is_complete /// -///

+///

/// \ref fennec::is_final "is_final::value"
/// \ref fennec::is_final_v "is_final_v" -///
+/// /// \copydetails fennec::is_final /// -///

+///

/// \ref fennec::is_aggregate "is_aggregate::value"
/// \ref fennec::is_aggregate_v "is_aggregate_v" -///
+/// /// \copydetails fennec::is_aggregate /// -///

+///

/// \ref fennec::is_signed "is_signed::value"
/// \ref fennec::is_signed_v "is_signed_v" -///
+/// /// \copydetails fennec::is_signed /// -///

+///

/// \ref fennec::is_unsigned "is_unsigned::value"
/// \ref fennec::is_unsigned_v "is_unsigned_v" -///
+/// /// \copydetails fennec::is_unsigned /// -///

+///

/// \ref fennec::is_bounded_array "is_bounded_array::value"
/// \ref fennec::is_bounded_array_v "is_bounded_array_v" -///
+/// /// \copydetails fennec::is_bounded_array /// -///

+///

/// \ref fennec::is_unbounded_array "is_unbounded_array::value"
/// \ref fennec::is_unbounded_array_v "is_unbounded_array_v" -///
+/// /// \copydetails fennec::is_unbounded_array /// -///

+///

/// \ref fennec::is_scoped_enum "is_scoped_enum::value"
/// \ref fennec::is_scoped_enum_v "is_scoped_enum_v" -///
+/// /// \copydetails fennec::is_scoped_enum /// ///
/// /// /// -/// \section Supported Operations +/// \section fennec_lang_type_traits_section_supported_operations Supported Operations /// -/// -///
Syntax -/// Description +/// +///
Syntax +/// Description /// -///

+///

/// \ref fennec::is_convertible "is_convertible::value"
/// \ref fennec::is_convertible_v "is_convertible_v" -///
+/// /// \copydetails fennec::is_convertible /// -///

+///

/// \ref fennec::is_constructible "is_constructible::value"
/// \ref fennec::is_constructible_v "is_constructible_v" /// \ref fennec::is_trivially_constructible "is_trivially_constructible::value"
/// \ref fennec::is_trivially_constructible_v "is_trivially_constructible_v" /// \ref fennec::is_nothrow_constructible "is_nothrow_constructible::value"
/// \ref fennec::is_nothrow_constructible_v "is_nothrow_constructible_v" -///
+/// /// \copydetails fennec::is_constructible /// -///

+///

/// \ref fennec::is_default_constructible "is_default_constructible::value"
/// \ref fennec::is_default_constructible_v "is_default_constructible_v" /// \ref fennec::is_trivially_default_constructible "is_trivially_default_constructible::value"
/// \ref fennec::is_trivially_default_constructible_v "is_trivially_default_constructible_v" /// \ref fennec::is_nothrow_default_constructible "is_nothrow_default_constructible::value"
/// \ref fennec::is_nothrow_default_constructible_v "is_nothrow_default_constructible_v" -///
+/// /// \copydetails fennec::is_default_constructible /// -///

+///

/// \ref fennec::is_copy_constructible "is_copy_constructible::value"
/// \ref fennec::is_copy_constructible_v "is_copy_constructible_v" /// \ref fennec::is_trivially_copy_constructible "is_trivially_copy_constructible::value"
/// \ref fennec::is_trivially_copy_constructible_v "is_trivially_copy_constructible_v" /// \ref fennec::is_nothrow_copy_constructible "is_nothrow_copy_constructible::value"
/// \ref fennec::is_nothrow_copy_constructible_v "is_nothrow_copy_constructible_v" -///
+/// /// \copydetails fennec::is_copy_constructible /// -///

+///

/// \ref fennec::is_move_constructible "is_move_constructible::value"
/// \ref fennec::is_move_constructible_v "is_move_constructible_v" /// \ref fennec::is_trivially_move_constructible "is_trivially_move_constructible::value"
/// \ref fennec::is_trivially_move_constructible_v "is_trivially_move_constructible_v" /// \ref fennec::is_nothrow_move_constructible "is_nothrow_move_constructible::value"
/// \ref fennec::is_nothrow_move_constructible_v "is_nothrow_move_constructible_v" -///
+/// /// \copydetails fennec::is_move_constructible /// -///

+///

/// \ref fennec::is_assignable "is_assignable::value"
/// \ref fennec::is_assignable_v "is_assignable_v" /// \ref fennec::is_trivially_assignable "is_trivially_assignable::value"
/// \ref fennec::is_trivially_assignable_v "is_trivially_assignable_v" /// \ref fennec::is_nothrow_assignable "is_nothrow_assignable::value"
/// \ref fennec::is_nothrow_assignable_v "is_nothrow_assignable_v" -///
+/// /// \copydetails fennec::is_assignable /// -///

+///

/// \ref fennec::is_copy_assignable "is_copy_assignable::value"
/// \ref fennec::is_copy_assignable_v "is_copy_assignable_v" /// \ref fennec::is_trivially_copy_assignable "is_trivially_copy_assignable::value"
/// \ref fennec::is_trivially_copy_assignable_v "is_trivially_copy_assignable_v" /// \ref fennec::is_nothrow_copy_assignable "is_nothrow_copy_assignable::value"
/// \ref fennec::is_nothrow_copy_assignable_v "is_nothrow_copy_assignable_v" -///
+/// /// \copydetails fennec::is_copy_assignable /// -///

+///

/// \ref fennec::is_move_assignable "is_move_assignable::value"
/// \ref fennec::is_move_assignable_v "is_move_assignable_v" /// \ref fennec::is_trivially_move_assignable "is_trivially_move_assignable::value"
/// \ref fennec::is_trivially_move_assignable_v "is_trivially_move_assignable_v" /// \ref fennec::is_nothrow_move_assignable "is_nothrow_move_assignable::value"
/// \ref fennec::is_nothrow_move_assignable_v "is_nothrow_move_assignable_v" -///
+/// /// \copydetails fennec::is_move_assignable /// -///

+///

/// \ref fennec::is_destructible "is_destructible::value"
/// \ref fennec::is_destructible_v "is_destructible_v" /// \ref fennec::is_trivially_destructible "is_trivially_destructible::value"
/// \ref fennec::is_trivially_destructible_v "is_trivially_destructible_v" /// \ref fennec::is_nothrow_destructible "is_nothrow_destructible::value"
/// \ref fennec::is_nothrow_destructible_v "is_nothrow_destructible_v" -///
+/// /// \copydetails fennec::is_destructible /// -///

+///

/// \ref fennec::has_virtual_destructor "has_virtual_destructor::value"
/// \ref fennec::has_virtual_destructor_v "has_virtual_destructor_v" -///
+/// /// \copydetails fennec::has_virtual_destructor /// ///
/// /// /// -/// \section Type Relationships +/// \section fennec_lang_type_traits_section_type_relationships Type Relationships /// -/// -///
Syntax -/// Description +/// +///
Syntax +/// Description /// -///

+///

/// \ref fennec::is_same "is_same::value"
/// \ref fennec::is_same_v "is_same_v" -///
+/// /// \copydetails fennec::is_same /// +///

+/// \ref fennec::is_base_of "is_base_of::value"
+/// \ref fennec::is_base_of_v "is_base_of_v" +///
+/// \copydetails fennec::is_base_of +/// ///
/// @@ -437,7 +443,11 @@ constexpr inline bool is_constant_evaluated() noexcept { } -// fennec::is_void ===================================================================================================== + +// Primary Type Categories ============================================================================================= + + +// fennec::is_void ----------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is of type void @@ -454,7 +464,7 @@ template constexpr bool_t is_void_v = is_void::value; -// fennec::is_null_pointer ============================================================================================= +// fennec::is_null_pointer --------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is of type nullptr_t @@ -471,7 +481,7 @@ template constexpr bool_t is_null_pointer_v = is_null_pointer::va -// fennec::is_bool ===================================================================================================== +// fennec::is_bool ----------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is of type bool @@ -488,7 +498,7 @@ template constexpr bool_t is_bool_v = is_bool::value; -// fennec::is_integral ================================================================================================= +// fennec::is_integral ------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is of an integral @@ -505,7 +515,7 @@ template constexpr bool_t is_integral_v = is_integral::value; -// fennec::is_floating_point =========================================================================================== +// fennec::is_floating_point ------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is of a floating point type @@ -522,9 +532,9 @@ template constexpr bool_t is_floating_point_v = is_floating_point -// fennec::is_array ==================================================================================================== +// fennec::is_array ---------------------------------------------------------------------------------------------------- -#ifdef FENNEC_BUILTIN_IS_ARRAY +#if FENNEC_HAS_BUILTIN_IS_ARRAY /// /// \brief Check if \p T is of an array type @@ -557,7 +567,7 @@ template constexpr bool_t is_array_v = is_array::value; -// fennec::is_enum ==================================================================================================== +// fennec::is_enum ---------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is an enum @@ -572,7 +582,7 @@ template constexpr size_t is_enum_v = is_enum::value; -// fennec::is_union ==================================================================================================== +// fennec::is_union ---------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is a union @@ -587,7 +597,7 @@ template constexpr size_t is_union_v = is_union::value; -// fennec::is_class ==================================================================================================== +// fennec::is_class ---------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is a class @@ -602,7 +612,7 @@ template constexpr size_t is_class_v = is_class::value; -// fennec::is_function ================================================================================================= +// fennec::is_function ------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is a class @@ -617,7 +627,7 @@ template constexpr size_t is_function_v = is_function::value; -// fennec::is_pointer ================================================================================================== +// fennec::is_pointer -------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is of a pointer type @@ -634,7 +644,7 @@ template constexpr bool_t is_pointer_v = is_pointer {}; -// fennec::is_lvalue_reference ========================================================================================= +// fennec::is_lvalue_reference ----------------------------------------------------------------------------------------- /// /// \brief Check if \p T is of a floating point type @@ -651,7 +661,7 @@ template constexpr bool_t is_lvalue_reference_v = is_lvalue_referenc -// fennec::is_rvalue_reference ========================================================================================= +// fennec::is_rvalue_reference ----------------------------------------------------------------------------------------- /// /// \brief Check if \p T is of a floating point type @@ -668,7 +678,7 @@ template constexpr bool_t is_rvalue_reference_v = is_rvalue_referenc -// fennec::is_member_function_pointer ================================================================================== +// fennec::is_member_function_pointer ---------------------------------------------------------------------------------- /// /// \brief Check if \p T is a pointer to a member function @@ -685,7 +695,7 @@ template constexpr bool_t is_member_function_pointer_v = is_member_f -// fennec::is_member_object_pointer ==================================================================================== +// fennec::is_member_object_pointer ------------------------------------------------------------------------------------ /// /// \brief Check if \p T is a pointer to a member object @@ -702,7 +712,12 @@ template constexpr bool_t is_member_object_pointer_v = is_member_obj -// fennec::is_arithmetic =============================================================================================== + + +// Composite Type Categories =========================================================================================== + + +// fennec::is_arithmetic ----------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is an arithmetic type @@ -718,7 +733,7 @@ template struct is_arithmetic template constexpr bool_t is_arithmetic_v = is_arithmetic::value; -// fennec::is_fundamental ============================================================================================== +// fennec::is_fundamental ---------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is a fundamental type, i.e. arithmetic, void, or nullptr_t @@ -733,12 +748,12 @@ template constexpr bool_t is_fundamental_v = is_fundamental::valu -// fennec::is_scalar =================================================================================================== +// fennec::is_scalar --------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is an arithmetic type /// -/// \details Checks if type `T` is a built-in type with arithmetic operators and store it in `is_same::value`. +/// \details Checks if type `T` is a built-in type with arithmetic operators and store it in `is_scalar::value`. /// \tparam T type to check template struct is_scalar : bool_constant or is_enum_v or is_pointer_v>{}; @@ -750,12 +765,12 @@ template constexpr bool_t is_scalar_v = is_scalar::value; -// fennec::is_object =================================================================================================== +// fennec::is_object --------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is an object /// -/// \details Checks if type `T` is an object and store it in `is_same::value`. +/// \details Checks if type `T` is an object and store it in `is_object::value`. /// \tparam T type to check template struct is_object : bool_constant {}; @@ -766,12 +781,12 @@ template constexpr bool_t is_object_v = is_object::value; -// fennec::is_compound ================================================================================================= +// fennec::is_compound ------------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is a object compound type /// -/// \details Checks if type `T` is an object and store it in `is_same::value`. +/// \details Checks if type `T` is an object and store it in `is_compound::value`. /// \tparam T type to check template struct is_compound : bool_constant> {}; @@ -782,24 +797,24 @@ template constexpr bool_t is_compound_v = is_compound::value; -// fennec::is_reference ================================================================================================ +// fennec::is_reference ------------------------------------------------------------------------------------------------ /// -/// \brief Check if \p T is of a floating point type +/// \brief Check if \p T is of a reference type /// -/// \details Checks if type `T` is a floating point type and store it in `is_same::value`. +/// \details Checks if type `T` is a reference type and store it in `is_reference::value`. /// \tparam T type to check template struct is_reference : detail::_is_reference{}; /// -/// \brief Shorthand for ```is_floating_point::value``` +/// \brief Shorthand for ```is_reference::value``` /// \tparam T type to check template constexpr bool_t is_reference_v = is_reference {}; -// fennec::is_member_pointer =========================================================================================== +// fennec::is_member_pointer ------------------------------------------------------------------------------------------- /// /// \brief Check if \p T is a pointer to a member @@ -816,7 +831,46 @@ template constexpr bool_t is_member_pointer_v = is_member_pointer -// fennec::is_trivial ================================================================================================== + + +// Type Properties ===================================================================================================== + + +// fennec::is_const ---------------------------------------------------------------------------------------------------- + +/// +/// \brief Check if \p T is of a const type +/// +/// \details Checks if type `T` is a const type and store it in `is_same::value`. +/// \tparam T type to check +template struct is_const + : detail::_is_const{}; + +/// +/// \brief Shorthand for ```is_const::value``` +/// \tparam T type to check +template constexpr bool_t is_const_v = is_const {}; + + + +// fennec::is_volatile ------------------------------------------------------------------------------------------------- + +/// +/// \brief Check if \p T is of a volatile type +/// +/// \details Checks if type `T` is a volatile type and store it in `is_same::value`. +/// \tparam T type to check +template struct is_volatile + : detail::_is_volatile{}; + +/// +/// \brief Shorthand for ```is_volatile::value``` +/// \tparam T type to check +template constexpr bool_t is_volatile_v = is_volatile {}; + + + +// fennec::is_trivial -------------------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is trivial @@ -832,7 +886,7 @@ template constexpr bool_t is_trivial_v = is_trivial{}; -// fennec::is_trivially_copyable ======================================================================================= +// fennec::is_trivially_copyable --------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is trivially_copyable @@ -848,7 +902,7 @@ template constexpr bool_t is_trivially_copyable_v = is_trivially_cop -// fennec::is_standard_layout ========================================================================================== +// fennec::is_standard_layout ------------------------------------------------------------------------------------------ /// /// \brief Check if type `T` is standard_layout @@ -864,7 +918,7 @@ template constexpr bool_t is_standard_layout_v = is_standard_layout< -// fennec::has_unique_object_representations =========================================================================== +// fennec::has_unique_object_representations --------------------------------------------------------------------------- /// /// \brief Check if type `T` has unique object representations @@ -881,7 +935,7 @@ template constexpr bool_t has_unique_object_representations_v = has_ -// fennec::is_empty ==================================================================================================== +// fennec::is_empty ---------------------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is empty @@ -897,7 +951,7 @@ template constexpr bool_t is_empty_v = is_empty{}; -// fennec::is_polymorphic ============================================================================================== +// fennec::is_polymorphic ---------------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is polymorphic @@ -913,7 +967,7 @@ template constexpr bool_t is_polymorphic_v = is_polymorphic{}; -// fennec::is_abstract ================================================================================================= +// fennec::is_abstract ------------------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is abstract @@ -929,7 +983,7 @@ template constexpr bool_t is_abstract_v = is_abstract{}; -// fennec::is_complete ================================================================================================= +// fennec::is_complete ------------------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is complete @@ -945,7 +999,7 @@ template constexpr bool_t is_complete_v = is_complete{}; -// fennec::is_final ================================================================================================= +// fennec::is_final ------------------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is final @@ -961,7 +1015,7 @@ template constexpr bool_t is_final_v = is_final{}; -// fennec::is_aggregate ================================================================================================= +// fennec::is_aggregate ------------------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is aggregate @@ -977,7 +1031,7 @@ template constexpr bool_t is_aggregate_v = is_aggregate{}; -// fennec::is_signed ================================================================================================= +// fennec::is_signed ------------------------------------------------------------------------------------------------- /// @@ -995,7 +1049,7 @@ template constexpr bool_t is_signed_v = is_signed::value; -// fennec::is_unsigned ================================================================================================= +// fennec::is_unsigned ------------------------------------------------------------------------------------------------- /// @@ -1012,7 +1066,478 @@ template struct is_unsigned template constexpr bool_t is_unsigned_v = is_unsigned::value; -// fennec::is_same ===================================================================================================== + +// fennec::is_bounded_array -------------------------------------------------------------------------------------------- + +#if FENNEC_HAS_BUILTIN_BOUNDED_ARRAY + +/// +/// \brief Check if \p T is of a bounded array type +/// \tparam T type to check +template struct is_bounded_array + : bool_constant {}; + +#else + +/// +/// \brief Check if \p T is of an bounded type +/// \tparam T type to check +template struct is_bounded_array + : false_type {}; + +// overload for a sized array type +template struct is_bounded_array + : true_type {}; + +#endif + +/// +/// \brief Shorthand for ```is_bounded_array::value``` +/// \tparam T type to check +template constexpr bool_t is_bounded_array_v = is_bounded_array::value; + + + +// fennec::is_unbounded_array ------------------------------------------------------------------------------------------ + +#if FENNEC_HAS_BUILTIN_UNBOUNDED_ARRAY + +/// +/// \brief Check if \p T is of a unbounded array type +/// \tparam T type to check +template struct is_unbounded_array + : bool_constant {}; + +#else + +/// +/// \brief Check if \p T is of an unbounded type +/// \tparam T type to check +template struct is_unbounded_array + : false_type {}; + +// overload for a sized array type +template struct is_unbounded_array + : true_type {}; + +#endif + +/// +/// \brief Shorthand for ```is_unbounded_array::value``` +/// \tparam T type to check +template constexpr bool_t is_unbounded_array_v = is_unbounded_array::value; + + + +// fennec::is_scoped_enum ------------------------------------------------------------------------------------------ + +#if FENNEC_HAS_BUILTIN_SCOPED_ENUM + +/// +/// \brief Check if \p T is of a scoped enum type +/// \tparam T type to check +template struct is_scoped_enum + : bool_constant {}; + +#else + +/// +/// \brief Check if \p T is of an unbounded type +/// \tparam T type to check +template struct is_scoped_enum + : false_type {}; + +// 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 + +/// +/// \brief Shorthand for ```is_scoped_enum::value``` +/// \tparam T type to check +template constexpr bool_t is_scoped_enum_v = is_scoped_enum::value; + + + + + +// Supported Operations ================================================================================================ + + +// fennec::is_convertible ---------------------------------------------------------------------------------------------- + +/// +/// \brief Check if type `T0` can be converted `T1` +/// +/// \details Checks if `TypeT0` +/// \tparam FromT First type +/// \tparam ToT Second type +template struct is_convertible + : bool_constant {}; + +/// +/// \brief Shorthand for `can_convert::value` +/// \param FromT First type +/// \param ToT Second type +template constexpr bool_t is_convertible_v = is_convertible{}; + + + +// fennec::is_constructible -------------------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` can be constructed with `ArgsT,` i.e. `ClassT(ArgsT...)`. +/// This may be read as "is `ClassT` constructible with `ArgsT`" +/// \tparam ClassT The class type to test +/// \tparam ArgsT The arguments for the specific constructor +template struct is_constructible + : bool_constant {}; + +/// +/// \brief Shorthand for `is_constructible::value` +template constexpr bool_t is_constructible_v = is_constructible{}; + + + +// fennec::is_trivially_constructible ---------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is trivially constructible +/// \tparam ClassT The class type to test +/// \tparam ArgsT The arguments for the specific constructor +template struct is_trivially_constructible + : bool_constant {}; + +/// +/// \brief Shorthand for `is_trivially_constructible::value` +template constexpr bool_t is_trivially_constructible_v = is_trivially_constructible{}; + + + +// fennec::is_nothrow_constructible ------------------------------------------------------------------------------------ + +/// +/// \brief Check if `ClassT` is nothrow constructible +/// \tparam ClassT The class type to test +/// \tparam ArgsT The arguments for the specific constructor +template struct is_nothrow_constructible + : bool_constant {}; + +/// +/// \brief Shorthand for `is_nothrow_constructible::value` +template constexpr bool_t is_nothrow_constructible_v = is_nothrow_constructible{}; + + + +// fennec::is_default_constructible ------------------------------------------------------------------------------------ + +/// +/// \brief Check if `ClassT` is default constructible +/// \tparam ClassT The class type to test +template struct is_default_constructible + : bool_constant {}; + +/// +/// \brief Shorthand for `is_default_constructible::value` +template constexpr bool_t is_default_constructible_v = is_default_constructible{}; + + + +// fennec::is_trivially_default_constructible -------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is trivially default constructible +/// \tparam ClassT The class type to test +template struct is_trivially_default_constructible + : bool_constant {}; + +/// +/// \brief Shorthand for `is_trivially_default_constructible::value` +template constexpr bool_t is_trivially_default_constructible_v = is_trivially_default_constructible{}; + + + +// fennec::is_nothrow_default_constructible -------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is nothrow default constructible +/// \tparam ClassT The class type to test +template struct is_nothrow_default_constructible + : bool_constant {}; + +/// +/// \brief Shorthand for `is_nothrow_default_constructible::value` +template constexpr bool_t is_nothrow_default_constructible_v = is_nothrow_default_constructible{}; + + + +// fennec::is_copy_constructible --------------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is copy constructible +/// \tparam ClassT The class type to test +template struct is_copy_constructible + : bool_constant)> {}; + +/// +/// \brief Shorthand for `is_copy_constructible::value` +template constexpr bool_t is_copy_constructible_v = is_copy_constructible{}; + + + +// fennec::is_trivially_copy_constructible ----------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is trivially copy constructible +/// \tparam ClassT The class type to test +template struct is_trivially_copy_constructible + : bool_constant)> {}; + +/// +/// \brief Shorthand for `is_trivially_copy_constructible::value` + template constexpr bool_t is_trivially_copy_constructible_v = is_trivially_copy_constructible{}; + + + +// fennec::is_nothrow_copy_constructible ------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is nothrow copy constructible +/// \tparam ClassT The class type to test +template struct is_nothrow_copy_constructible + : bool_constant)> {}; + +/// +/// \brief Shorthand for `is_nothrow_copy_constructible::value` +template constexpr bool_t is_nothrow_copy_constructible_v = is_nothrow_copy_constructible{}; + + + +// fennec::is_move_constructible --------------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is move constructible +/// \tparam ClassT The class type to test +template struct is_move_constructible + : bool_constant)> {}; + +/// +/// \brief Shorthand for `is_copy_constructible::value` +template constexpr bool_t is_move_constructible_v = is_move_constructible{}; + + + +// fennec::is_trivially_move_constructible ----------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is trivially move constructible +/// \tparam ClassT The class type to test +template struct is_trivially_move_constructible + : bool_constant)> {}; + +/// +/// \brief Shorthand for `is_trivially_move_constructible::value` + template constexpr bool_t is_trivially_move_constructible_v = is_trivially_move_constructible{}; + + + +// fennec::is_nothrow_move_constructible ------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is nothrow move constructible +/// \tparam ClassT The class type to test +template struct is_nothrow_move_constructible + : bool_constant)> {}; + +/// +/// \brief Shorthand for `is_nothrow_move_constructible::value` +template constexpr bool_t is_nothrow_move_constructible_v = is_nothrow_move_constructible{}; + + + +// fennec::is_assignable ----------------------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is assignable +/// \tparam ClassAT The class type to test +/// \tparam ClassBT The arguments for the specific constructor +template struct is_assignable + : bool_constant {}; + +/// +/// \brief Shorthand for `is_constructible::value` +template constexpr bool_t is_assignable_v = is_assignable{}; + + + +// fennec::is_trivially_assignable ------------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is trivially assignable +/// \tparam ClassAT The class type to test +/// \tparam ClassBT The arguments for the specific constructor +template struct is_trivially_assignable + : bool_constant {}; + +/// +/// \brief Shorthand for `is_trivially_assignable::value` +template constexpr bool_t is_trivially_assignable_v = is_trivially_assignable{}; + + + + +// fennec::is_nothrow_assignable --------------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is nothrow assignable +/// \tparam ClassAT The class type to test +/// \tparam ClassBT The arguments for the specific constructor +template struct is_nothrow_assignable + : bool_constant {}; + +/// +/// \brief Shorthand for `is_nothrow_assignable::value` +template constexpr bool_t is_nothrow_assignable_v = is_nothrow_assignable{}; + + + +// fennec::is_copy_assignable ------------------------------------------------------------------------------------------ + +/// +/// \brief Check if `ClassT` is copy assignable +/// \tparam ClassT The class type to test +template struct is_copy_assignable + : bool_constant, add_lvalue_reference_t)> {}; + +/// +/// \brief Shorthand for `is_copy_assignable::value` +template constexpr bool_t is_copy_assignable_v = is_copy_assignable{}; + + + +// fennec::is_trivially_copy_assignable -------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is trivially_copy assignable +/// \tparam ClassT The class type to test +template struct is_trivially_copy_assignable + : bool_constant, add_lvalue_reference_t)> {}; + +/// +/// \brief Shorthand for `is_trivially_copy_assignable::value` +template constexpr bool_t is_trivially_copy_assignable_v = is_trivially_copy_assignable{}; + + + +// fennec::is_nothrow_copy_assignable ---------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is nothrow_copy assignable +/// \tparam ClassT The class type to test +template struct is_nothrow_copy_assignable + : bool_constant, add_lvalue_reference_t)> {}; + +/// +/// \brief Shorthand for `is_nothrow_copy_assignable::value` +template constexpr bool_t is_nothrow_copy_assignable_v = is_nothrow_copy_assignable{}; + + + +// fennec::is_move_assignable ------------------------------------------------------------------------------------------ + +/// +/// \brief Check if `ClassT` is move assignable +/// \tparam ClassT The class type to test +template struct is_move_assignable + : bool_constant, add_rvalue_reference_t)> {}; + +/// +/// \brief Shorthand for `is_move_assignable::value` +template constexpr bool_t is_move_assignable_v = is_move_assignable{}; + + + +// fennec::is_trivially_move_assignable -------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is trivially_move assignable +/// \tparam ClassT The class type to test +template struct is_trivially_move_assignable + : bool_constant, add_rvalue_reference_t)> {}; + +/// +/// \brief Shorthand for `is_trivially_move_assignable::value` +template constexpr bool_t is_trivially_move_assignable_v = is_trivially_move_assignable{}; + + + +// fennec::is_nothrow_move_assignable -------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is nothrow_move assignable +/// \tparam ClassT The class type to test +template struct is_nothrow_move_assignable + : bool_constant, add_rvalue_reference_t)> {}; + +/// +/// \brief Shorthand for `is_nothrow_move_assignable::value` +template constexpr bool_t is_nothrow_move_assignable_v = is_nothrow_move_assignable{}; + + + +// fennec::is_destructible --------------------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is destructible +/// \tparam ClassT The class type to test +template struct is_destructible + : detail::_is_destructible::type {}; + +/// +/// \brief Shorthand for `is_destructible::value` +template constexpr bool_t is_destructible_v = is_destructible{}; + + + +// fennec::is_trivially_destructible ----------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is trivially destructible +/// \tparam ClassT The class type to test +template struct is_trivially_destructible + : bool_constant {}; + +/// +/// \brief Shorthand for `is_trivially_destructible::value` +template constexpr bool_t is_trivially_destructible_v = is_trivially_destructible{}; + + + +// fennec::is_nothrow_destructible ------------------------------------------------------------------------------------- + +/// +/// \brief Check if `ClassT` is nothrow destructible +/// \tparam ClassT The class type to test +template struct is_nothrow_destructible + : detail::_is_nothrow_destructible::type {}; + +/// +/// \brief Shorthand for `is_nothrow_destructible::value` +template constexpr bool_t is_nothrow_destructible_v = is_nothrow_destructible{}; + + + + + +// Type Relationships ================================================================================================== + + +// fennec::is_same ----------------------------------------------------------------------------------------------------- /// /// \brief Check if the two types are identical @@ -1032,7 +1557,8 @@ template struct is_same : true_type {}; template constexpr bool_t is_same_v = is_same {}; -// fennec::is_base_of ================================================================================================== + +// fennec::is_base_of -------------------------------------------------------------------------------------------------- /// /// \brief Check if `Derived` has a base type of `Base` @@ -1052,184 +1578,7 @@ template constexpr bool_t is_base_of_v = is_bas -// fennec::is_convertible ============================================================================================== - -/// -/// \brief Check if type `T0` can be converted `T1` -/// -/// \details Checks if `TypeT0` -/// \tparam FromT First type -/// \tparam ToT Second type -template struct is_convertible - : bool_constant {}; - -/// -/// \brief Shorthand for `can_convert::value` -/// \param FromT First type -/// \param ToT Second type -template constexpr bool_t is_convertible_v = is_convertible{}; - - - -// fennec::is_constructible ============================================================================================ - -/// -/// \brief Check if `ClassT` can be constructed with `ArgsT,` i.e. `ClassT(ArgsT...)`. -/// This may be read as "is `ClassT` constructible with `ArgsT`" -/// \tparam ClassT The class type to test -/// \tparam ArgsT The arguments for the specific constructor -template struct is_constructible - : bool_constant {}; - -/// -/// \brief Shorthand for `is_constructible::value` -template constexpr bool_t is_constructible_v = is_constructible{}; - - - -// fennec::is_trivially_constructible ================================================================================== - -/// -/// \brief Check if `ClassT` is trivially constructible -/// \tparam ClassT The class type to test -template struct is_trivially_constructible - : bool_constant {}; - -/// -/// \brief Shorthand for `is_trivially_constructible::value` -template constexpr bool_t is_trivially_constructible_v = is_trivially_constructible{}; - - - -// fennec::is_default_constructible ==================================================================================== - -/// -/// \brief Check if `ClassT` is default constructible -/// \tparam ClassT The class type to test -template struct is_default_constructible - : bool_constant {}; - -/// -/// \brief Shorthand for `is_default_constructible::value` -template constexpr bool_t is_default_constructible_v = is_default_constructible{}; - - - -// fennec::is_copy_constructible ======================================================================================= - -/// -/// \brief Check if `ClassT` is copy constructible -/// \tparam ClassT The class type to test -template struct is_copy_constructible - : bool_constant)> {}; - -/// -/// \brief Shorthand for `is_copy_constructible::value` -template constexpr bool_t is_copy_constructible_v = is_copy_constructible{}; - - - -// fennec::is_move_constructible ======================================================================================= - -/// -/// \brief Check if `ClassT` is move constructible -/// \tparam ClassT The class type to test -template struct is_move_constructible - : bool_constant)> {}; - -/// -/// \brief Shorthand for `is_copy_constructible::value` -template constexpr bool_t is_move_constructible_v = is_move_constructible{}; - - - -// fennec::is_assignable =============================================================================================== - -/// -/// \brief Check if `ClassT` can be constructed with `ArgsT,` i.e. `ClassT(ArgsT...)`. -/// This may be read as "is `ClassT` constructible with `ArgsT`" -/// \tparam ClassAT The class type to test -/// \tparam ClassBT The arguments for the specific constructor -template struct is_assignable - : bool_constant {}; - -/// -/// \brief Shorthand for `is_constructible::value` -template constexpr bool_t is_assignable_v = is_assignable{}; - - - -// fennec::is_copy_assignable ========================================================================================== - -/// -/// \brief Check if `ClassT` is copy assignable -/// \tparam ClassT The class type to test -template struct is_copy_assignable - : bool_constant, add_lvalue_reference_t)> {}; - -/// -/// \brief Shorthand for `is_copy_assignable::value` -template constexpr bool_t is_copy_assignable_v = is_copy_assignable{}; - - - -// fennec::is_move_assignable ========================================================================================== - -/// -/// \brief Check if `ClassT` is move assignable -/// \tparam ClassT The class type to test -template struct is_move_assignable - : bool_constant, add_rvalue_reference_t)> {}; - -/// -/// \brief Shorthand for `is_move_assignable::value` -template constexpr bool_t is_move_assignable_v = is_move_assignable{}; - - - -// fennec::is_destructible ============================================================================================= - -/// -/// \brief Check if `ClassT` is destructible -/// \tparam ClassT The class type to test -template struct is_destructible - : detail::_is_destructible::type {}; - -/// -/// \brief Shorthand for `is_destructible::value` -template constexpr bool_t is_destructible_v = is_destructible{}; - - - -// fennec::is_trivially_destructible =================================================================================== - -/// -/// \brief Check if `ClassT` is trivially destructible -/// \tparam ClassT The class type to test -template struct is_trivially_destructible - : bool_constant {}; - -/// -/// \brief Shorthand for `is_trivially_destructible::value` -template constexpr bool_t is_trivially_destructible_v = is_trivially_destructible{}; - - - -// fennec::is_nothrow_destructible ===================================================================================== - -/// -/// \brief Check if `ClassT` is nothrow destructible -/// \tparam ClassT The class type to test -template struct is_nothrow_destructible - : detail::_is_nothrow_destructible::type {}; - -/// -/// \brief Shorthand for `is_nothrow_destructible::value` -template constexpr bool_t is_nothrow_destructible_v = is_nothrow_destructible{}; - - - -// fennec::is_iterable ================================================================================================= +// fennec::is_iterable ------------------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is iterable @@ -1245,7 +1594,7 @@ template constexpr bool_t is_iterable_v = is_iterable{}; -// fennec::is_indexable ================================================================================================ +// fennec::is_indexable ------------------------------------------------------------------------------------------------ /// /// \brief Check if type `T` is indexable @@ -1261,7 +1610,7 @@ template constexpr bool_t is_indexable_v = is_indexable{}; -// fennec::is_mappable ================================================================================================= +// fennec::is_mappable ------------------------------------------------------------------------------------------------- /// /// \brief Check if type `T` is mappable diff --git a/include/fennec/lang/type_transforms.h b/include/fennec/lang/type_transforms.h index 54ab14e..f0150e8 100644 --- a/include/fennec/lang/type_transforms.h +++ b/include/fennec/lang/type_transforms.h @@ -109,16 +109,16 @@ /// \copydetails fennec::remove_cv /// ///

-/// \ref fennec::add_cvr "add_cvr::type"
-/// \ref fennec::add_cvr_t "add_cvr_t" +/// \ref fennec::add_cvref "add_cvref::type"
+/// \ref fennec::add_cvref_t "add_cvref_t" ///
-/// \copydetails fennec::add_cvr +/// \copydetails fennec::add_cvref /// ///

-/// \ref fennec::remove_cvr "remove_cvr::type"
-/// \ref fennec::remove_cvr_t "remove_cvr_t" +/// \ref fennec::remove_cvref "remove_cvref::type"
+/// \ref fennec::remove_cvref_t "remove_cvref_t" ///
-/// \copydetails fennec::remove_cvr +/// \copydetails fennec::remove_cvref /// ///
/// diff --git a/include/fennec/math/common.h b/include/fennec/math/common.h index 4fe288b..a9927d5 100644 --- a/include/fennec/math/common.h +++ b/include/fennec/math/common.h @@ -506,7 +506,7 @@ constexpr genType modf(genType x, genType& i) { /// \returns **true** if \f$x\f$ holds a NaN. Returns **false** otherwise.

/// \details \f$NaN\f$ is a concept unique to computing. It strictly means, and more specifically, /// floating point values can only represent *real* numbers. This is why some functions, -/// like \ref fennec::sqrt(fennec::genFType) "sqrt()", return \f$NaN\f$ when an expression would return +/// like \ref fennec::sqrt "sqrt()", return \f$NaN\f$ when an expression would return /// a value in a different coordinate space. There are other cases, such as \f$\frac{1}{x}\f$, /// where \f$x=0\f$ is undefined, and respectively the return value is also \f$NaN\f$.

/// diff --git a/include/fennec/math/math.h b/include/fennec/math/math.h index b4469cb..7886d8b 100644 --- a/include/fennec/math/math.h +++ b/include/fennec/math/math.h @@ -46,7 +46,7 @@ /// /// \code #include \endcode /// -/// The \ref fennec Math Library is composed of the modules listed in below. +/// The fennecMath Library is composed of the modules listed in below. /// The overarching goal of this math library is to implement the math types and functions of the /// [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). /// diff --git a/include/fennec/math/matrix.h b/include/fennec/math/matrix.h index 9968279..813abcf 100644 --- a/include/fennec/math/matrix.h +++ b/include/fennec/math/matrix.h @@ -118,7 +118,7 @@ using dmat4x4 = tmat4x4; ///< Specification for size glsl double matri /// -/// \brief Multiply matrix \$x\f$ by matrix \f$y\f$ component-wise. +/// \brief Multiply matrix \f$x\f$ by matrix \f$y\f$ component-wise. /// \details Multiply matrix x by matrix y component-wise, i.e., result[i][j] is the scalar product of x[i][j] and y[i][j].

/// Note: to get linear algebraic matrix multiplication, use /// the multiply operator (*) @@ -165,14 +165,12 @@ constexpr mat transpose(const matrix constexpr scalar determinant(const matrix&) noexcept { - // ReSharper disable once CppStaticAssertFailure static_assert(false, "implementation undefined"); return 0; } template constexpr matrix inverse(const matrix&) noexcept { - // ReSharper disable once CppStaticAssertFailure static_assert(false, "implementation undefined"); return 1; } @@ -349,7 +347,9 @@ struct matrix /// @{ /// - /// \copydetails matrix::operator[](size_t) const + /// \details + /// \param i the index + /// \returns the column at index \f$i\f$ constexpr column_t& operator[](size_t i) { return data[i]; } @@ -365,16 +365,21 @@ struct matrix } /// - /// \copydetails matrix::operator()(size_t, size_t) const + /// \details + /// \param i the column + /// \param j the row + /// \returns the element in column \f$i\f$, row \f$j\f$ constexpr scalar_t& operator[](size_t i, size_t j) { return data[i][j]; } /// /// \brief returns the cell in row \p j column \p i + /// + /// \details /// \param i the column /// \param j the row - /// \returns the cell at the specified index. + /// \returns the element in column \f$i\f$, row \f$j\f$ constexpr scalar_t operator[](size_t i, size_t j) const { return data[i][j]; } diff --git a/include/fennec/math/scalar.h b/include/fennec/math/scalar.h index d584d77..b51968f 100644 --- a/include/fennec/math/scalar.h +++ b/include/fennec/math/scalar.h @@ -41,10 +41,10 @@ /// /// \code #include \endcode /// -/// The \ref fennec Library considers any type that passes ```is_arithmetic``` to be a \ref scalar "Scalar." Bools are +/// The fennecLibrary considers any type that passes ```is_arithmetic``` to be a \ref scalar "Scalar." Bools are /// supported as a logical type. /// -/// The GLSL Specification, and \ref fennec respectively, defines the following scalar types: +/// The GLSL Specification, and fennecrespectively, defines the following scalar types: /// /// | Type | Corresponding Type | Meaning | /// |----------|-----------------------|------------------------------| diff --git a/include/fennec/memory/allocator.h b/include/fennec/memory/allocator.h index 890d86d..9a6c8ba 100644 --- a/include/fennec/memory/allocator.h +++ b/include/fennec/memory/allocator.h @@ -144,61 +144,87 @@ template class allocator { public: + /// /// \brief Alias for the data type used for metaprogramming using value_t = T; + /// /// \brief Metaprogramming utility to rebind an allocator to a different data type template using rebind = allocator; + /// /// \brief Default Constructor constexpr allocator() = default; + /// /// \brief Default Destructor constexpr ~allocator() = default; + /// /// \brief Copy Constructor constexpr allocator(const allocator&) = default; + /// /// \brief Copy Assignment + /// \returns A reference to self constexpr allocator& operator=(const allocator&) = default; - + /// /// \brief Equality operator + /// \returns `true` constexpr bool_t operator==(const allocator&) { return true; } + /// /// \brief Inequality operator + /// \returns `false` constexpr bool_t operator!=(const allocator&) { return false; } + /// /// \brief Equality operator for allocators of same type but with different data type + /// \returns `false` template constexpr bool_t operator==(const allocator&) { - return true; + return false; } + /// /// \brief Inequality operator for allocators of same type but with different data type + /// \returns `true` template constexpr bool_t operator!=(const allocator&) { return true; } + /// /// \brief Allocate a block of memory large enough to hold `n` elements of type `T` + /// \param n The number of elements + /// \returns A pointer to the allocated block constexpr T* allocate(size_t n) { return static_cast(::operator new(n * sizeof(T))); } + /// /// \brief Allocate a block of memory large enough to hold `n` elements of type `T` + /// \param n The number of elements + /// \param align The alignment + /// \returns A pointer to the allocated block constexpr T* allocate(size_t n, align_t align) { return static_cast(::operator new(n * sizeof(T), align)); } + /// /// \brief Deallocate a block of memory with type `T` + /// \param ptr The block to release constexpr void deallocate(T* ptr) { return ::operator delete(ptr); } + /// /// \brief Deallocate a block of memory with type `T` + /// \param ptr The block to release + /// \param align The alignment constexpr void deallocate(T* ptr, align_t align) { return ::operator delete(ptr, align); } @@ -212,61 +238,88 @@ template class allocator { public: + /// /// \brief Alias for the data type used for metaprogramming using value_t = T; + /// /// \brief Metaprogramming utility to rebind an allocator to a different data type template using rebind = allocator; + /// /// \brief Default Constructor constexpr allocator() = default; + /// /// \brief Default Destructor constexpr ~allocator() = default; + /// /// \brief Copy Constructor constexpr allocator(const allocator&) = default; + /// /// \brief Copy Assignment + /// \returns A reference to self constexpr allocator& operator=(const allocator&) = default; + /// /// \brief Equality operator + /// \returns `true` constexpr bool_t operator==(const allocator&) { return true; } + /// /// \brief Inequality operator + /// \returns `false` constexpr bool_t operator!=(const allocator&) { return false; } + /// /// \brief Equality operator for allocators of same type but with different data type + /// \returns `false` template constexpr bool_t operator==(const allocator&) { - return true; + return false; } + /// /// \brief Inequality operator for allocators of same type but with different data type + /// \returns `true` template constexpr bool_t operator!=(const allocator&) { return true; } + /// /// \brief Allocate a block of memory large enough to hold `n` elements of type `T` + /// \param n The number of elements + /// \returns A pointer to the allocated block constexpr T* allocate(size_t n) { return static_cast(::operator new[](n * sizeof(T))); } + /// /// \brief Allocate a block of memory large enough to hold `n` elements of type `T` + /// \param n The number of elements + /// \param align The alignment + /// \returns A pointer to the allocated block constexpr T* allocate(size_t n, align_t align) { return static_cast(::operator new[](n * sizeof(T), align)); } + /// /// \brief Deallocate a block of memory with type `T` + /// \param ptr The block to release constexpr void deallocate(T* ptr) { return ::operator delete[](ptr); } + /// /// \brief Deallocate a block of memory with type `T` + /// \param ptr The block to release + /// \param align The alignment constexpr void deallocate(T* ptr, align_t align) { return ::operator delete[](ptr, align); } @@ -480,7 +533,9 @@ public: /// /// \brief Allocate a block of memory for the allocation. /// If there is already an allocated block of memory, the previous allocation is released. + /// /// \param n The number of elements of type `T` to allocate for + /// \param align The alignment to use constexpr void allocate(size_t n, align_t align = zero()) noexcept { deallocate(); @@ -494,7 +549,9 @@ public: /// /// \brief Allocate a block of memory for the allocation. /// If there is already an allocated block of memory, the previous allocation is released. + /// /// \param n The number of elements of type `T` to allocate for + /// \param align The alignment to use constexpr void callocate(size_t n, align_t align = zero()) noexcept { allocate(n, align); fennec::memset(static_cast(_data), 0, _capacity * sizeof(T)); @@ -519,6 +576,9 @@ public: /// /// \brief Reallocate the block with a new size. /// Contents are copied to the new allocation. + /// + /// \param n The number of elements of type `T` to allocate for + /// \param align The alignment to use constexpr void reallocate(size_t n, align_t align = zero()) noexcept { if (_data == nullptr) { allocate(n, align); @@ -538,6 +598,9 @@ public: /// /// \brief Reallocate the block with a new size. /// Contents are copied to the new allocation. + /// + /// \param n The number of elements of type `T` to allocate for + /// \param align The alignment to use constexpr void creallocate(size_t n, align_t align = zero()) noexcept { if (_data == nullptr) { callocate(n, align); @@ -561,36 +624,58 @@ public: // Access ============================================================================================================== + /// + /// \param i The index to access + /// \returns a reference to the value at position `i` in the allocation constexpr value_t& operator[](size_t i) { assertd(i < capacity(), "Array Out of Bounds"); return _data[i]; } + /// + /// \brief Array Access Operator + /// \param i The index to access + /// \returns a reference to the value at position `i` in the allocation constexpr const value_t& operator[](size_t i) const { assertd(i < capacity(), "Array Out of Bounds"); return _data[i]; } + /// + /// \returns The underlying pointer. constexpr operator value_t*() { return _data; } + /// + /// \brief Dereference Operators + /// \returns The underlying pointer. constexpr operator const value_t*() const { return _data; } + /// + /// \returns A pointer to the start of the allocation. value_t* begin() { return _data; } - value_t* end() { - return _data + capacity(); - } - + /// + /// \brief Iterator Begin + /// \returns A pointer to the start of the allocation. const value_t* begin() const { return _data; } + /// + /// \returns A pointer to the element one after the last. + value_t* end() { + return _data + capacity(); + } + + /// + /// \brief Iterator End + /// \returns A pointer to the element one after the last. const value_t* end() const { return _data + capacity(); } @@ -632,6 +717,9 @@ public: return _data; } + /// + /// \brief Getter for the alignment of the allocation. + /// \returns the alignment of the allocation constexpr align_t alignment() const { return _alignment; } diff --git a/include/fennec/platform/linux/wayland/server.h b/include/fennec/platform/linux/wayland/server.h index f36cc29..7988701 100644 --- a/include/fennec/platform/linux/wayland/server.h +++ b/include/fennec/platform/linux/wayland/server.h @@ -17,7 +17,7 @@ // ===================================================================================================================== /// -/// \file wayland_server.h +/// \file server.h /// \brief /// /// diff --git a/include/fennec/platform/linux/wayland/window.h b/include/fennec/platform/linux/wayland/window.h index 94b131d..9b3bf1d 100644 --- a/include/fennec/platform/linux/wayland/window.h +++ b/include/fennec/platform/linux/wayland/window.h @@ -17,7 +17,7 @@ // ===================================================================================================================== /// -/// \file wayland_window.h +/// \file window.h /// \brief /// /// diff --git a/include/fennec/renderers/opengl/lib/texture.h b/include/fennec/renderers/opengl/lib/texture.h index 30f5ae2..a69c059 100644 --- a/include/fennec/renderers/opengl/lib/texture.h +++ b/include/fennec/renderers/opengl/lib/texture.h @@ -233,9 +233,9 @@ 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 + /// \param bytes 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 + const void* faces[6], GLenum component = BYTE, GLenum layout = R, GLsizei = 0) requires is_2d and cubemap : _handle(NULL) , _width(size), _height(size), _depth(1) , _samples(1), _mips(mips) { @@ -262,11 +262,11 @@ 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 + /// \param bytes 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, - const void* data, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires is_2d and cubemap + const void* data, GLenum component = BYTE, GLenum layout = R, GLsizei = 0) requires is_2d and cubemap : _handle(NULL) , _width(size), _height(size), _depth(depth) , _samples(1), _mips(mips) { diff --git a/include/fennec/string/cstring.h b/include/fennec/string/cstring.h index d6c2c96..7797b2c 100644 --- a/include/fennec/string/cstring.h +++ b/include/fennec/string/cstring.h @@ -221,8 +221,7 @@ public: } /// - /// \brief Data Access - /// \returns A const qualified pointer to the underlying allocation + /// \returns A pointer to the underlying allocation constexpr char* data() { return _str; } @@ -236,6 +235,7 @@ public: /// /// \brief Implicit Dereference Cast + /// \returns A const qualified pointer to the underlying allocation constexpr operator const char*() const { return _cstr; } diff --git a/include/fennec/string/string.h b/include/fennec/string/string.h index 934b4b5..ae98b82 100644 --- a/include/fennec/string/string.h +++ b/include/fennec/string/string.h @@ -67,15 +67,28 @@ public: fennec::memset(_str, c, n); } + /// + /// \brief Alloc Constructor + /// \param alloc The allocator to use constexpr _string(const alloc_t& alloc) : _str(alloc) { } + /// + /// \brief Sized Alloc Constructor, initializes a null-terminated string of size `n` with `'c'...` + /// \param n the number of characters + /// \param c the character to fill with + /// \param alloc The allocator to use + /// + /// \details adds additional character for null termination. constexpr _string(size_t n, char c, const alloc_t& alloc) : _str(n + 1, alloc) { fennec::memset(_str, c, n); } + /// + /// \brief C-String Constructor + /// \param cstr The C-Style string to construct from. constexpr _string(const cstring& cstr) : _str(cstr, cstr.size() + 1) { } @@ -98,7 +111,7 @@ public: /// /// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present - /// \param str the buffer to wrap + /// \param buf the buffer to wrap /// \param n the number of characters in the buffer including the null-terminator, if present constexpr _string(const char* buf, size_t n) : _str(buf[n - 1] != '\0' ? n + 1 : n) { @@ -108,6 +121,9 @@ public: } } + /// + /// \brief String View Constructor + /// \param view The C-Style string view to construct from. constexpr _string(const string_view& view) : _string(view.str, view.len) { } @@ -128,16 +144,29 @@ public: // Assignment ========================================================================================================== + /// + /// \brief C-String Assignment + /// \param cstr The C-Style string to assign. + /// \returns A reference to self constexpr _string& operator=(const cstring& cstr) { _str.callocate(cstr.capacity()); fennec::memcpy(_str, cstr, cstr.capacity()); return *this; } + /// + /// \brief String Copy Assignment + /// \param str the string to copy + /// \returns A reference to self constexpr _string& operator=(const _string& str) { _str = str._str; return *this; } + + /// + /// \brief String Move Assignment + /// \param str the string to take ownership of + /// \returns A reference to self constexpr _string& operator=(_string&& str) noexcept { _str = fennec::move(str._str); return *this; @@ -157,6 +186,8 @@ public: return _str.capacity(); } + /// + /// \returns `true` if the string contains no characters, `false` otherwise. constexpr bool empty() const { return size() == 0; } @@ -179,14 +210,20 @@ public: return _str[i]; } + /// + /// \returns The underlying pointer to the held string constexpr char* data() { return _str; } + /// + /// \returns The underlying pointer to the held string constexpr const char* data() const { return _str; } + /// + /// \returns The underlying pointer to the held string constexpr const char* cstr() const { return _str; } @@ -200,46 +237,56 @@ public: } /// - /// \brief String Comparison - /// \param ostr the string to compare against + /// \param str the string to compare against + /// \param i An offset to start with in `this` + /// \param n The number of characters to compare /// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the /// current locale, otherwise a positive value. constexpr int compare(const cstring& str, size_t i = 0, size_t n = npos) const { if (i >= size()) { // bounds check return -1; } - n = fennec::min(n, fennec::max(size(), str.size()) + 1); + n = min(min(n, size() - i), str.size()); return ::strncmp(_str + i, str, n); } /// /// \brief String Comparison - /// \param ostr the string to compare against + /// \param str the string to compare against + /// \param i An offset to start at in `this` + /// \param n The number of characters to compare /// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the /// current locale, otherwise a positive value. - constexpr int compare(const string& str, size_t i = 0, size_t n = npos) const { + constexpr int compare(const _string& str, size_t i = 0, size_t n = npos) const { if (i >= size()) { // bounds check return -1; } - n = min(n, max(size(), str.size()) + 1); + n = min(min(n, size() - i), str.size()); return ::strncmp(_str + i, str.data(), n); } + /// + /// \param str The string to compare against + /// \returns Equivalent to `compare(str) == 0` constexpr bool operator==(const cstring& str) const { return compare(str) == 0; } + /// + /// \brief String Equality + /// \param str The string to compare against + /// \returns Equivalent to `compare(str) == 0` constexpr bool operator==(const _string& str) const { return compare(str) == 0; } /// /// \brief Check if the string contains a character - /// \param c - /// \param i - /// \return + /// \param c The character to find + /// \param i An offset to start at in `this` + /// \returns `true` if `c` is contained in `this` constexpr bool contains(char c, size_t i = 0) const { return find(c, i) != size(); } @@ -247,6 +294,7 @@ public: /// /// \brief Finds the index of the first occurrence of `c` in the string /// \param c the character to find + /// \param i An offset to start at in `this` /// \returns The index of `c` if it occurs in the string, otherwise returns `size()` constexpr size_t find(char c, size_t i = 0) const { if (i >= size()) { // bounds check @@ -260,6 +308,7 @@ public: /// /// \brief Finds the index of the first occurrence of `str` in the string. /// \param str the string to find + /// \param i An offset to start at in `this` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()` constexpr size_t find(const string& str, size_t i = 0) const { // bounds check if (i >= size()) { // bounds check @@ -273,6 +322,7 @@ public: /// /// \brief Finds the index of the first occurrence of `str` in the string. /// \param str the string to find + /// \param i An offset to start at in `this` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()` constexpr size_t find(const cstring& str, size_t i = 0) const { if (i + str.size() > size()) { // bounds check @@ -286,7 +336,7 @@ public: /// /// \brief Finds the index of the last occurrence of `c` in the string. /// \param c the string to find - /// \param i the index to start at + /// \param i An offset to start at in `this` /// \returns The index of `c` if it occurs in the string, otherwise returns `size()` constexpr size_t rfind(char c, size_t i = npos) const { if (size() == 0) { @@ -304,7 +354,7 @@ public: /// /// \brief Finds the index of the last occurrence of `str` in the string. /// \param str the string to find - /// \param i the index to start at + /// \param i An offset to start at in `this` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()` constexpr size_t rfind(const cstring& str, size_t i = npos) const { if (size() == 0) { @@ -325,7 +375,7 @@ public: /// /// \brief Finds the index of the last occurrence of `str` in the string. /// \param str the string to find - /// \param i the index to start at + /// \param i An offset to start at in `this` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()` constexpr size_t rfind(const string& str, size_t i = npos) const { if (size() == 0) { @@ -345,9 +395,9 @@ public: /// /// \brief Retrieve a substring of a string - /// \param i the start index + /// \param i An offset to start at in `this` /// \param n the number of characters - /// \return + /// \returns A new string containing the range of characters specified by `i` and `n` constexpr _string substring(size_t i, size_t n = npos) const { if (i >= size() || n == 0) { return _string(""); @@ -363,11 +413,19 @@ public: // Modifiers =========================================================================================================== + /// + /// \brief String Resize + /// \brief Resizes the underlying allocation to hold `n` characters and a null terminator. + /// \param n The new size of the string constexpr void resize(size_t n) { _str.creallocate(n + 1); _str[size()] = '\0'; } + /// + /// \brief Character Append + /// \param c A character to append + /// \returns A new string containing the previous contents and an additional character `c`. constexpr _string operator+(char c) const { if (_str == nullptr) { return _string(1, c); @@ -379,11 +437,20 @@ public: return res; } + /// + /// \brief Character Prepend + /// \param c A character to append + /// \returns A new string containing the character `c` followed by the previous contents. friend constexpr _string operator+(char c, const _string& str) { - _string res(1, c); - return res += str; + _string res(str.size() + 1); + res[0] = c; + fennec::memcpy(res.data() + 1, str.data(), str.size()); + return res; } + /// + /// \param cstr The string to append + /// \returns A new string containing the previous contents followed by the contents of `cstr` constexpr _string operator+(const cstring& cstr) const { if (_str == nullptr) { return _string(cstr); @@ -395,6 +462,10 @@ public: return res; } + /// + /// \brief String Append + /// \param str The string to append + /// \returns A new string containing the previous contents followed by the contents of `cstr` constexpr _string operator+(const _string& str) const { if (_str == nullptr) { return _string(str); @@ -409,6 +480,10 @@ public: return res; } + /// + /// \brief Character Append Assignment + /// \param c A character to append + /// \returns `this` string containing an additional character `c`. constexpr _string& operator+=(char c) { if (_str == nullptr) { _str.callocate(2); @@ -420,6 +495,9 @@ public: return *this; } + /// + /// \param cstr The string to append + /// \returns `this` string expanded to additionally contain `cstr` constexpr _string& operator+=(const cstring& cstr) { if (_str == nullptr) { return *this = cstr; @@ -430,6 +508,10 @@ public: return *this; } + /// + /// \brief String Append Assignment + /// \param str The string to append + /// \returns `this` string expanded to additionally contain `str` constexpr _string& operator+=(const _string& str) { if (_str == nullptr) { return *this = str; @@ -446,18 +528,29 @@ public: // Iteration =========================================================================================================== + /// + /// \returns A pointer to the first character in the string. constexpr char* begin() { return _str.data(); } + /// + /// \brief Iterable begin() + /// \returns A pointer to the first character in the string. constexpr const char* begin() const { return _str.data(); } + /// + /// \returns A pointer to the null terminator of the string. constexpr char* end() { return _str.data() + _str.capacity(); } + + /// + /// \brief Iterable end() + /// \returns A pointer to the null terminator of the string. constexpr const char* end() const { return _str.data() + _str.capacity(); } diff --git a/include/fennec/string/wcstring.h b/include/fennec/string/wcstring.h index b968c91..11fddc0 100644 --- a/include/fennec/string/wcstring.h +++ b/include/fennec/string/wcstring.h @@ -205,8 +205,7 @@ public: } /// - /// \brief Data Access - /// \returns A const qualified pointer to the underlying allocation + /// \returns A pointer to the underlying allocation constexpr wchar_t* data() { return _str; } @@ -220,6 +219,7 @@ public: /// /// \brief Implicit Dereference Cast + /// \returns A const qualified pointer to the underlying allocation constexpr operator const wchar_t*() const { return _cstr; } diff --git a/include/fennec/string/wstring.h b/include/fennec/string/wstring.h index f77640b..1674747 100644 --- a/include/fennec/string/wstring.h +++ b/include/fennec/string/wstring.h @@ -70,15 +70,28 @@ public: fennec::wmemset(_str, c, n); } + /// + /// \brief Alloc Constructor + /// \param alloc The allocator to use constexpr _wstring(const alloc_t& alloc) : _str(alloc) { } + /// + /// \brief Sized Alloc Constructor, initializes a null-terminated string of size `n` with `'c'...` + /// \param n the number of characters + /// \param c the character to fill with + /// \param alloc The allocator to use + /// + /// \details adds additional character for null termination. constexpr _wstring(size_t n, wchar_t c, const alloc_t& alloc) : _str(n + 1, alloc) { fennec::wmemset(_str, c, n); } + /// + /// \brief C-String Constructor + /// \param cstr The C-Style string to construct from. constexpr _wstring(const wcstring& cstr) : _str(cstr, cstr.size() + 1) { } @@ -98,7 +111,7 @@ public: /// /// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present - /// \param str the buffer to wrap + /// \param buf the buffer to wrap /// \param n the number of wchar_tacters in the buffer including the null-terminator, if present constexpr _wstring(const wchar_t* buf, size_t n) : _str(buf[n - 1] != '\0' ? n + 1 : n) { @@ -124,14 +137,33 @@ public: // Assignment ========================================================================================================== + /// + /// \brief C-String Assignment + /// \param cstr The C-Style string to assign. + /// \returns A reference to self constexpr _wstring& operator=(const wcstring& cstr) { _str.callocate(cstr.capacity()); - fennec::wmemcpy(_str, cstr, cstr.capacity()); + fennec::memcpy(_str, cstr, cstr.capacity()); return *this; } - constexpr _wstring& operator=(const _wstring& str) = default; - constexpr _wstring& operator=(_wstring&& str) noexcept = default; + /// + /// \brief String Copy Assignment + /// \param str the string to copy + /// \returns A reference to self + constexpr _wstring& operator=(const _wstring& str) { + _str = str._str; + return *this; + } + + /// + /// \brief String Move Assignment + /// \param str the string to take ownership of + /// \returns A reference to self + constexpr _wstring& operator=(_wstring&& str) noexcept { + _str = fennec::move(str._str); + return *this; + } // Properties ========================================================================================================== @@ -147,6 +179,8 @@ public: return _str.capacity(); } + /// + /// \returns `true` if the string contains no characters, `false` otherwise. constexpr bool empty() const { return size() == 0; } @@ -169,14 +203,20 @@ public: return _str[i]; } + /// + /// \returns The underlying pointer to the held string constexpr wchar_t* data() { return _str; } + /// + /// \returns The underlying pointer to the held string constexpr const wchar_t* data() const { return _str; } + /// + /// \returns The underlying pointer to the held string constexpr const wchar_t* cstr() const { return _str; } @@ -190,46 +230,56 @@ public: } /// - /// \brief String Comparison - /// \param ostr the string to compare against + /// \param str the string to compare against + /// \param i An offset to start with in `this` + /// \param n The number of characters to compare /// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the /// current locale, otherwise a positive value. constexpr int compare(const wcstring& str, size_t i = 0, size_t n = npos) const { if (i >= size()) { // bounds check return -1; } - n = fennec::min(n, fennec::max(_str, str.size()) + 1); + n = min(min(n, size() - i), str.size()); return ::wcsncmp(_str + i, str, n); } /// /// \brief String Comparison - /// \param ostr the string to compare against + /// \param str the string to compare against + /// \param i An offset to start at in `this` + /// \param n The number of characters to compare /// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the /// current locale, otherwise a positive value. constexpr int compare(const _wstring& str, size_t i = 0, size_t n = npos) const { if (i >= size()) { // bounds check return -1; } - n = min(n, max(size(), str.size()) + 1); + n = min(min(n, size() - i), str.size()); return ::wcsncmp(_str + i, str.data(), n); } + /// + /// \param str The string to compare against + /// \returns Equivalent to `compare(str) == 0` constexpr bool operator==(const wcstring& str) const { return compare(str) == 0; } + /// + /// \brief String Equality + /// \param str The string to compare against + /// \returns Equivalent to `compare(str) == 0` constexpr bool operator==(const _wstring& str) const { return compare(str) == 0; } /// /// \brief Check if the string contains a character - /// \param c - /// \param i - /// \return + /// \param c The character to find + /// \param i An offset to start at in `this` + /// \returns `true` if `c` is contained in `this` constexpr bool contains(char c, size_t i = 0) const { return find(c, i) != size(); } @@ -237,6 +287,7 @@ public: /// /// \brief Finds the index of the first occurrence of `c` in the string /// \param c the wchar_tacter to find + /// \param i An offset to start at in `this` /// \returns The index of `c` if it occurs in the string, otherwise returns `size()` constexpr size_t find(wchar_t c, size_t i = 0) const { if (i >= size()) { // bounds check @@ -250,6 +301,7 @@ public: /// /// \brief Finds the index of the first occurrence of `str` in the string. /// \param str the string to find + /// \param i An offset to start at in `this` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()` constexpr size_t find(const _wstring& str, size_t i = 0) const { // bounds check if (i >= size()) { // bounds check @@ -263,6 +315,7 @@ public: /// /// \brief Finds the index of the first occurrence of `str` in the string. /// \param str the string to find + /// \param i An offset to start at in `this` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()` constexpr size_t find(const wcstring& str, size_t i = 0) const { if (i + str.size() > size()) { // bounds check @@ -276,7 +329,7 @@ public: /// /// \brief Finds the index of the last occurrence of `c` in the string. /// \param c the string to find - /// \param i the index to start at + /// \param i An offset to start at in `this` /// \returns The index of `c` if it occurs in the string, otherwise returns `size()` constexpr size_t rfind(wchar_t c, size_t i = npos) const { if (size() == 0) { @@ -294,7 +347,7 @@ public: /// /// \brief Finds the index of the last occurrence of `str` in the string. /// \param str the string to find - /// \param i the index to start at + /// \param i An offset to start at in `this` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()` constexpr size_t rfind(const wcstring& str, size_t i = npos) const { if (size() == 0) { @@ -315,7 +368,7 @@ public: /// /// \brief Finds the index of the last occurrence of `str` in the string. /// \param str the string to find - /// \param i the index to start at + /// \param i An offset to start at in `this` /// \returns The index of `str` if it occurs in the string, otherwise returns `size()` constexpr size_t rfind(const string& str, size_t i = npos) const { if (size() == 0) { @@ -335,9 +388,9 @@ public: /// /// \brief Retrieve a substring of a string - /// \param i the start index - /// \param n the number of wchar_tacters - /// \return + /// \param i An offset to start at in `this` + /// \param n the number of characters + /// \returns A new string containing the range of characters specified by `i` and `n` constexpr _wstring substring(size_t i, size_t n = npos) const { if (i >= size()) { return _wstring(""); @@ -353,11 +406,19 @@ public: // Modifiers =========================================================================================================== + /// + /// \brief String Resize + /// \brief Resizes the underlying allocation to hold `n` characters and a null terminator. + /// \param n The new size of the string constexpr void resize(size_t n) { _str.creallocate(n + 1); _str[size()] = '\0'; } + /// + /// \brief Character Append + /// \param c A character to append + /// \returns A new string containing the previous contents and an additional character `c`. constexpr _wstring operator+(wchar_t c) const { if (_str == nullptr) { return _wstring(1, c); @@ -369,11 +430,18 @@ public: return res; } + /// + /// \brief Character Prepend + /// \param c A character to append + /// \returns A new string containing the character `c` followed by the previous contents. friend constexpr _wstring operator+(wchar_t c, const _wstring& str) { _wstring res(1, c); return res += str; } + /// + /// \param cstr The string to append + /// \returns A new string containing the previous contents followed by the contents of `cstr` constexpr _wstring operator+(const wcstring& cstr) const { if (_str == nullptr) { return _wstring(cstr); @@ -385,6 +453,10 @@ public: return res; } + /// + /// \brief String Append + /// \param str The string to append + /// \returns A new string containing the previous contents followed by the contents of `cstr` constexpr _wstring operator+(const _wstring& str) const { if (_str == nullptr) { return _wstring(str); @@ -399,6 +471,10 @@ public: return res; } + /// + /// \brief Character Append Assignment + /// \param c A character to append + /// \returns `this` string containing an additional character `c`. constexpr _wstring& operator+=(wchar_t c) { if (_str == nullptr) { _str.callocate(2); @@ -410,6 +486,9 @@ public: return *this; } + /// + /// \param cstr The string to append + /// \returns `this` string expanded to additionally contain `cstr` constexpr _wstring& operator+=(const wcstring& cstr) { if (_str == nullptr) { return *this = cstr; @@ -420,6 +499,10 @@ public: return *this; } + /// + /// \brief String Append Assignment + /// \param str The string to append + /// \returns `this` string expanded to additionally contain `str` constexpr _wstring& operator+=(const _wstring& str) { if (_str == nullptr) { return *this = str; @@ -434,6 +517,36 @@ public: } + // Iteration =========================================================================================================== + + /// + /// \returns A pointer to the first character in the string. + constexpr wchar_t* begin() { + return _str.data(); + } + + /// + /// \brief Iterable begin() + /// \returns A pointer to the first character in the string. + constexpr const wchar_t* begin() const { + return _str.data(); + } + + /// + /// \returns A pointer to the null terminator of the string. + constexpr wchar_t* end() { + return _str.data() + _str.capacity(); + } + + + /// + /// \brief Iterable end() + /// \returns A pointer to the null terminator of the string. + constexpr const wchar_t* end() const { + return _str.data() + _str.capacity(); + } + + private: alloc_t _str; }; diff --git a/include/fennec/threading/atomic.h b/include/fennec/threading/atomic.h index f6e00de..c33e38e 100644 --- a/include/fennec/threading/atomic.h +++ b/include/fennec/threading/atomic.h @@ -204,7 +204,6 @@ public: /// \param x The value to store in the atomic object if it is as expected. /// \param succ The memory synchronization ordering for the read-modify-write operation if the comparison succeeds. /// \param fail The memory synchronization ordering for the load operation if the comparison fails. - /// \param order The memory synchronization ordering for both operations. /// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise. bool compare_exchange_weak(T& exp, T x, memory_order succ, memory_order fail) noexcept { return ::atomic_compare_exchange_weak_explicit(&_value, &exp, x, succ, fail); @@ -218,7 +217,6 @@ public: /// \param x The value to store in the atomic object if it is as expected. /// \param succ The memory synchronization ordering for the read-modify-write operation if the comparison succeeds. /// \param fail The memory synchronization ordering for the load operation if the comparison fails. - /// \param order The memory synchronization ordering for both operations. /// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise. bool compare_exchange_weak(T& exp, T x, memory_order succ, memory_order fail) volatile noexcept { return ::atomic_compare_exchange_weak_explicit(&_value, &exp, x, succ, fail); @@ -230,8 +228,6 @@ public: /// Otherwise, loads the actual value stored in *this into `exp` (performs load operation). /// \param exp Reference to the value expected to be found in the atomic object. /// \param x The value to store in the atomic object if it is as expected. - /// \param succ The memory synchronization ordering for the read-modify-write operation if the comparison succeeds. - /// \param fail The memory synchronization ordering for the load operation if the comparison fails. /// \param order The memory synchronization ordering for both operations. /// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise. bool compare_exchange_weak(T& exp, T x, memory_order order = memory_order_seq_cst) noexcept { @@ -246,8 +242,6 @@ public: /// Otherwise, loads the actual value stored in *this into `exp` (performs load operation). /// \param exp Reference to the value expected to be found in the atomic object. /// \param x The value to store in the atomic object if it is as expected. - /// \param succ The memory synchronization ordering for the read-modify-write operation if the comparison succeeds. - /// \param fail The memory synchronization ordering for the load operation if the comparison fails. /// \param order The memory synchronization ordering for both operations. /// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise. bool compare_exchange_weak(T& exp, T x, memory_order order = memory_order_seq_cst) volatile noexcept { @@ -263,7 +257,6 @@ public: /// \param x The value to store in the atomic object if it is as expected. /// \param succ The memory synchronization ordering for the read-modify-write operation if the comparison succeeds. /// \param fail The memory synchronization ordering for the load operation if the comparison fails. - /// \param order The memory synchronization ordering for both operations. /// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise. bool compare_exchange_strong(T& exp, T x, memory_order succ, memory_order fail) noexcept { return ::atomic_compare_exchange_strong_explicit(&_value, &exp, x, succ, fail); @@ -277,7 +270,6 @@ public: /// \param x The value to store in the atomic object if it is as expected. /// \param succ The memory synchronization ordering for the read-modify-write operation if the comparison succeeds. /// \param fail The memory synchronization ordering for the load operation if the comparison fails. - /// \param order The memory synchronization ordering for both operations. /// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise. bool compare_exchange_strong(T& exp, T x, memory_order succ, memory_order fail) volatile noexcept { return ::atomic_compare_exchange_strong_explicit(&_value, &exp, x, succ, fail); @@ -289,8 +281,6 @@ public: /// Otherwise, loads the actual value stored in *this into `exp` (performs load operation). /// \param exp Reference to the value expected to be found in the atomic object. /// \param x The value to store in the atomic object if it is as expected. - /// \param succ The memory synchronization ordering for the read-modify-write operation if the comparison succeeds. - /// \param fail The memory synchronization ordering for the load operation if the comparison fails. /// \param order The memory synchronization ordering for both operations. /// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise. bool compare_exchange_strong(T& exp, T x, memory_order order = memory_order_seq_cst) noexcept { @@ -305,8 +295,6 @@ public: /// Otherwise, loads the actual value stored in *this into `exp` (performs load operation). /// \param exp Reference to the value expected to be found in the atomic object. /// \param x The value to store in the atomic object if it is as expected. - /// \param succ The memory synchronization ordering for the read-modify-write operation if the comparison succeeds. - /// \param fail The memory synchronization ordering for the load operation if the comparison fails. /// \param order The memory synchronization ordering for both operations. /// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise. bool compare_exchange_strong(T& exp, T x, memory_order order = memory_order_seq_cst) volatile noexcept { diff --git a/source/platform/interface/window.cpp b/source/platform/interface/window.cpp index b7ea1c4..9558d8c 100644 --- a/source/platform/interface/window.cpp +++ b/source/platform/interface/window.cpp @@ -16,18 +16,6 @@ // along with this program. If not, see . // ===================================================================================================================== -/// -/// \file window.h -/// \brief -/// -/// -/// \details -/// \author Medusa Slockbower -/// -/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) -/// -/// - #include #include #include