- Documentation and logic fixes for various structures

This commit is contained in:
2025-12-17 12:40:10 -05:00
parent aee4e340dd
commit e7503ed92f
28 changed files with 1179 additions and 474 deletions

View File

@@ -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

View File

@@ -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<size_t> visit;
size_t head;
@@ -540,6 +543,8 @@ public:
}
};
///
/// \brief Traverser pattern for pre-order traversal
struct pre_order {
list<size_t> visit;
size_t head;
@@ -577,6 +582,8 @@ public:
}
};
///
/// \brief Traverser pattern for in-order traversal
struct in_order {
list<size_t> visit;
size_t head;
@@ -614,6 +621,8 @@ public:
}
};
///
/// \brief Traverser pattern for post-order traversal
struct post_order {
list<size_t> visit;
size_t head;

View File

@@ -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))

View File

@@ -17,7 +17,7 @@
// =====================================================================================================================
///
/// \file universal.h
/// \file generic.h
/// \brief
///
///

View File

@@ -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<typename...ArgsT>
@@ -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<value_t>(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<typename...ArgsT>
constexpr size_t emplace_front(ArgsT&&...args) {
return this->_insert(_root, fennec::forward<ArgsT>(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<value_t>(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<typename...ArgsT>
constexpr size_t emplace_back(ArgsT&&...args) {
return this->_insert(npos, fennec::forward<ArgsT>(args)...);

View File

@@ -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<typename...ArgsT>
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<typename...ArgsT>
constexpr void emplace(const KeyT& key, ArgsT&&...args) {

View File

@@ -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<T>) {
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<T> and is_copy_assignable_v<T> {
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<T> and is_move_assignable_v<T> {
if (_set) {
_val = fennec::forward<T>(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<T> and is_copy_assignable_v<T> {
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<T> and is_move_assignable_v<T> {
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<T>(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<typename...ArgsT>
constexpr T& emplace(ArgsT&&...args) {
if (_set) {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<elem_t>(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<typename...ArgsT>
constexpr iterator emplace(ArgsT&&...args) {
return this->_insert(fennec::forward<ArgsT>(args)...);

View File

@@ -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

View File

@@ -249,15 +249,15 @@ template<typename TypeT> 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

File diff suppressed because it is too large Load Diff

View File

@@ -109,16 +109,16 @@
/// \copydetails fennec::remove_cv
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::add_cvr "add_cvr<TypeT>::type"<br>
/// \ref fennec::add_cvr_t "add_cvr_t<TypeT>"
/// \ref fennec::add_cvref "add_cvref<TypeT>::type"<br>
/// \ref fennec::add_cvref_t "add_cvref_t<TypeT>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::add_cvr
/// \copydetails fennec::add_cvref
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::remove_cvr "remove_cvr<TypeT>::type"<br>
/// \ref fennec::remove_cvr_t "remove_cvr_t<TypeT>"
/// \ref fennec::remove_cvref "remove_cvref<TypeT>::type"<br>
/// \ref fennec::remove_cvref_t "remove_cvref_t<TypeT>"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::remove_cvr
/// \copydetails fennec::remove_cvref
///
/// </table>
///

View File

@@ -506,7 +506,7 @@ constexpr genType modf(genType x, genType& i) {
/// \returns **true** if \f$x\f$ holds a NaN. Returns **false** otherwise. <br> <br>
/// \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$. <br> <br>
///

View File

@@ -46,7 +46,7 @@
///
/// \code #include <fennec/math/math.h> \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).
///

View File

@@ -118,7 +118,7 @@ using dmat4x4 = tmat4x4<double_t>; ///< 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].<br><br>
/// Note: to get linear algebraic matrix multiplication, use
/// the multiply operator (*)
@@ -165,14 +165,12 @@ constexpr mat<scalar, rows, sizeof...(cols)> transpose(const matrix<scalar, rows
/// \returns the determinant of m.
template<typename scalar, size_t rows, size_t...cols>
constexpr scalar determinant(const matrix<scalar, rows, cols...>&) noexcept {
// ReSharper disable once CppStaticAssertFailure
static_assert(false, "implementation undefined");
return 0;
}
template<typename scalar, size_t rows, size_t...cols>
constexpr matrix<scalar, rows, cols...> inverse(const matrix<scalar, rows, cols...>&) 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];
}

View File

@@ -41,10 +41,10 @@
///
/// \code #include <fennec/math/scalar.h> \endcode
///
/// The \ref fennec Library considers any type that passes ```is_arithmetic<T>``` to be a \ref scalar "Scalar." Bools are
/// The fennecLibrary considers any type that passes ```is_arithmetic<T>``` 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 |
/// |----------|-----------------------|------------------------------|

View File

@@ -144,61 +144,87 @@ template<typename T>
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<typename R> using rebind = allocator<R>;
///
/// \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<typename U> constexpr bool_t operator==(const allocator<U>&) {
return true;
return false;
}
///
/// \brief Inequality operator for allocators of same type but with different data type
/// \returns `true`
template<typename U> constexpr bool_t operator!=(const allocator<U>&) {
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<T*>(::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<T*>(::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<typename T>
class allocator<T[]>
{
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<typename R> using rebind = allocator<R>;
///
/// \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<typename U> constexpr bool_t operator==(const allocator<U>&) {
return true;
return false;
}
///
/// \brief Inequality operator for allocators of same type but with different data type
/// \returns `true`
template<typename U> constexpr bool_t operator!=(const allocator<U>&) {
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<T*>(::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<T*>(::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<align_t>()) 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<align_t>()) noexcept {
allocate(n, align);
fennec::memset(static_cast<void*>(_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<align_t>()) 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<align_t>()) 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;
}

View File

@@ -17,7 +17,7 @@
// =====================================================================================================================
///
/// \file wayland_server.h
/// \file server.h
/// \brief
///
///

View File

@@ -17,7 +17,7 @@
// =====================================================================================================================
///
/// \file wayland_window.h
/// \file window.h
/// \brief
///
///

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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 {

View File

@@ -16,18 +16,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \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 <fennec/platform/interface/window.h>
#include <fennec/renderers/interface/gfxsurface.h>
#include <fennec/platform/interface/display_server.h>