- Documentation and logic fixes for various structures
This commit is contained in:
@@ -582,7 +582,7 @@ RESOLVE_UNNAMED_PARAMS = YES
|
|||||||
# section is generated. This option has no effect if EXTRACT_ALL is enabled.
|
# section is generated. This option has no effect if EXTRACT_ALL is enabled.
|
||||||
# The default value is: NO.
|
# 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
|
# 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
|
# 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.
|
# if EXTRACT_ALL is enabled.
|
||||||
# The default value is: NO.
|
# 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
|
# 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
|
# declarations. If set to NO, these declarations will be included in the
|
||||||
@@ -701,7 +701,7 @@ SORT_BRIEF_DOCS = NO
|
|||||||
# detailed member documentation.
|
# detailed member documentation.
|
||||||
# The default value is: NO.
|
# 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
|
# 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
|
# of group names into alphabetical order. If set to NO the group names will
|
||||||
|
|||||||
@@ -385,8 +385,9 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Perform a Tree Rotation at `i` in the specified direction
|
/// \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
|
/// \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) {
|
constexpr size_t rotate(size_t sub, bool dir) {
|
||||||
if (sub == npos) {
|
if (sub == npos) {
|
||||||
return npos;
|
return npos;
|
||||||
@@ -504,6 +505,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Traverser pattern for breadth-first traversal
|
||||||
struct breadth_first {
|
struct breadth_first {
|
||||||
list<size_t> visit;
|
list<size_t> visit;
|
||||||
size_t head;
|
size_t head;
|
||||||
@@ -540,6 +543,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Traverser pattern for pre-order traversal
|
||||||
struct pre_order {
|
struct pre_order {
|
||||||
list<size_t> visit;
|
list<size_t> visit;
|
||||||
size_t head;
|
size_t head;
|
||||||
@@ -577,6 +582,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Traverser pattern for in-order traversal
|
||||||
struct in_order {
|
struct in_order {
|
||||||
list<size_t> visit;
|
list<size_t> visit;
|
||||||
size_t head;
|
size_t head;
|
||||||
@@ -614,6 +621,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Traverser pattern for post-order traversal
|
||||||
struct post_order {
|
struct post_order {
|
||||||
list<size_t> visit;
|
list<size_t> visit;
|
||||||
size_t head;
|
size_t head;
|
||||||
|
|||||||
@@ -44,10 +44,10 @@
|
|||||||
///
|
///
|
||||||
/// | Symbol | Implemented | Passed |
|
/// | Symbol | Implemented | Passed |
|
||||||
/// |:----------------------------------------------------------------------------|:-----------:|:------:|
|
/// |:----------------------------------------------------------------------------|:-----------:|:------:|
|
||||||
/// | \ref fennec::any "fennec::any" | ⛔ | ⛔ |
|
/// | \ref fennec::generic "fennec::generic" `std::any` | 🚧 | 🚧 |
|
||||||
/// | \ref fennec::array "fennec::array" | ✅ | ✅ |
|
/// | \ref fennec::array "fennec::array" | ✅ | ✅ |
|
||||||
/// | \ref fennec::bitset "fennec::bitset" | ⛔ | ⛔ |
|
/// | \ref fennec::bitfield "fennec::bitfield" `std::bitset` | 🚧 | 🚧 |
|
||||||
/// | \ref fennec::deque "fennec::deque" | ⛔ | ⛔ |
|
/// | \ref fennec::deque "fennec::deque" | 🚧 | 🚧 |
|
||||||
/// | \ref fennec::dynarray "fennec::dynarray" `std::vector` | 🚧 | 🚧 |
|
/// | \ref fennec::dynarray "fennec::dynarray" `std::vector` | 🚧 | 🚧 |
|
||||||
/// | \ref fennec::list "fennec::list" | ✅ | ✅ |
|
/// | \ref fennec::list "fennec::list" | ✅ | ✅ |
|
||||||
/// | \ref fennec::map "fennec::map" `std::unordered_map` | ✅ | ✅ |
|
/// | \ref fennec::map "fennec::map" `std::unordered_map` | ✅ | ✅ |
|
||||||
@@ -58,10 +58,10 @@
|
|||||||
/// | \ref fennec::multimap_sequence "fennec::multimap_sequence" `std::multimap` | ⛔ | ⛔ |
|
/// | \ref fennec::multimap_sequence "fennec::multimap_sequence" `std::multimap` | ⛔ | ⛔ |
|
||||||
/// | \ref fennec::optional "fennec::optional" | ✅ | ✅ |
|
/// | \ref fennec::optional "fennec::optional" | ✅ | ✅ |
|
||||||
/// | \ref fennec::pair "fennec::pair" | ✅ | ✅ |
|
/// | \ref fennec::pair "fennec::pair" | ✅ | ✅ |
|
||||||
/// | \ref fennec::sequence "fennec::sequence" `std::set` | ⛔ | ⛔ |
|
/// | \ref fennec::sequence "fennec::sequence" `std::set` | 🚧 | 🚧 |
|
||||||
/// | \ref fennec::set "fennec::set" `std::unordered_set` | ✅ | ✅ |
|
/// | \ref fennec::set "fennec::set" `std::unordered_set` | ✅ | ✅ |
|
||||||
/// | \ref fennec::tuple "fennec::tuple" | 🚧 | 🚧 |
|
/// | \ref fennec::tuple "fennec::tuple" | 🚧 | 🚧 |
|
||||||
/// | \ref fennec::variant "fennec::variant" | ⛔ | ⛔ |
|
/// | \ref fennec::variant "fennec::variant" | 🚧 | 🚧 |
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \section fennec_containers_fennec fennec
|
/// \section fennec_containers_fennec fennec
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \file universal.h
|
/// \file generic.h
|
||||||
/// \brief
|
/// \brief
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -256,6 +256,7 @@ public:
|
|||||||
/// \brief Copy Insertion
|
/// \brief Copy Insertion
|
||||||
/// \param it Location to insert at
|
/// \param it Location to insert at
|
||||||
/// \param x value to copy
|
/// \param x value to copy
|
||||||
|
/// \returns The id of the inserted node
|
||||||
///
|
///
|
||||||
/// \details \f$O(1)\f$
|
/// \details \f$O(1)\f$
|
||||||
constexpr size_t insert(const iterator& it, const value_t& x) {
|
constexpr size_t insert(const iterator& it, const value_t& x) {
|
||||||
@@ -266,6 +267,7 @@ public:
|
|||||||
/// \brief Move Insertion
|
/// \brief Move Insertion
|
||||||
/// \param it Location to insert at
|
/// \param it Location to insert at
|
||||||
/// \param x value to move
|
/// \param x value to move
|
||||||
|
/// \returns The id of the inserted node
|
||||||
///
|
///
|
||||||
/// \details \f$O(1)\f$
|
/// \details \f$O(1)\f$
|
||||||
constexpr size_t insert(const iterator& it, value_t&& x) {
|
constexpr size_t insert(const iterator& it, value_t&& x) {
|
||||||
@@ -276,6 +278,7 @@ public:
|
|||||||
/// \brief Copy Insertion
|
/// \brief Copy Insertion
|
||||||
/// \param i Index to insert at
|
/// \param i Index to insert at
|
||||||
/// \param x value to copy
|
/// \param x value to copy
|
||||||
|
/// \returns The id of the inserted node
|
||||||
///
|
///
|
||||||
/// \details \f$O(N)\f$
|
/// \details \f$O(N)\f$
|
||||||
constexpr size_t insert(size_t i, const value_t& x) {
|
constexpr size_t insert(size_t i, const value_t& x) {
|
||||||
@@ -289,6 +292,7 @@ public:
|
|||||||
/// \brief Move Insertion
|
/// \brief Move Insertion
|
||||||
/// \param i Index to insert at
|
/// \param i Index to insert at
|
||||||
/// \param x value to move
|
/// \param x value to move
|
||||||
|
/// \returns The id of the inserted node
|
||||||
///
|
///
|
||||||
/// \details \f$O(N)\f$
|
/// \details \f$O(N)\f$
|
||||||
constexpr size_t insert(size_t i, value_t&& x) {
|
constexpr size_t insert(size_t i, value_t&& x) {
|
||||||
@@ -303,6 +307,7 @@ public:
|
|||||||
/// \tparam ArgsT Argument types
|
/// \tparam ArgsT Argument types
|
||||||
/// \param i Index to insert at
|
/// \param i Index to insert at
|
||||||
/// \param args Arguments to construct with
|
/// \param args Arguments to construct with
|
||||||
|
/// \returns The id of the inserted node
|
||||||
///
|
///
|
||||||
/// \details \f$O(N)\f$
|
/// \details \f$O(N)\f$
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
@@ -316,6 +321,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Push Front Copy
|
/// \brief Push Front Copy
|
||||||
/// \param x Value to copy
|
/// \param x Value to copy
|
||||||
|
/// \returns The id of the inserted node
|
||||||
constexpr size_t push_front(const value_t& x) {
|
constexpr size_t push_front(const value_t& x) {
|
||||||
return this->_insert(_root, x);
|
return this->_insert(_root, x);
|
||||||
}
|
}
|
||||||
@@ -323,6 +329,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Push Front Move
|
/// \brief Push Front Move
|
||||||
/// \param x Value to move
|
/// \param x Value to move
|
||||||
|
/// \returns The id of the inserted node
|
||||||
constexpr size_t push_front(value_t&& x) {
|
constexpr size_t push_front(value_t&& x) {
|
||||||
return this->_insert(_root, fennec::forward<value_t>(x));
|
return this->_insert(_root, fennec::forward<value_t>(x));
|
||||||
}
|
}
|
||||||
@@ -331,6 +338,7 @@ public:
|
|||||||
/// \brief Emplace Front
|
/// \brief Emplace Front
|
||||||
/// \param args Arguments to construct with
|
/// \param args Arguments to construct with
|
||||||
/// \tparam ArgsT Argument types
|
/// \tparam ArgsT Argument types
|
||||||
|
/// \returns The id of the inserted node
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr size_t emplace_front(ArgsT&&...args) {
|
constexpr size_t emplace_front(ArgsT&&...args) {
|
||||||
return this->_insert(_root, fennec::forward<ArgsT>(args)...);
|
return this->_insert(_root, fennec::forward<ArgsT>(args)...);
|
||||||
@@ -339,6 +347,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Push Back Copy
|
/// \brief Push Back Copy
|
||||||
/// \param x Value to copy
|
/// \param x Value to copy
|
||||||
|
/// \returns The id of the inserted node
|
||||||
constexpr size_t push_back(const value_t& x) {
|
constexpr size_t push_back(const value_t& x) {
|
||||||
return this->_insert(npos, x);
|
return this->_insert(npos, x);
|
||||||
}
|
}
|
||||||
@@ -346,6 +355,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Push Back Move
|
/// \brief Push Back Move
|
||||||
/// \param x Value to move
|
/// \param x Value to move
|
||||||
|
/// \returns The id of the inserted node
|
||||||
constexpr size_t push_back(value_t&& x) {
|
constexpr size_t push_back(value_t&& x) {
|
||||||
return this->_insert(npos, fennec::forward<value_t>(x));
|
return this->_insert(npos, fennec::forward<value_t>(x));
|
||||||
}
|
}
|
||||||
@@ -354,6 +364,7 @@ public:
|
|||||||
/// \brief Emplace Back
|
/// \brief Emplace Back
|
||||||
/// \param args Arguments to construct with
|
/// \param args Arguments to construct with
|
||||||
/// \tparam ArgsT Argument types
|
/// \tparam ArgsT Argument types
|
||||||
|
/// \returns The id of the inserted node
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr size_t emplace_back(ArgsT&&...args) {
|
constexpr size_t emplace_back(ArgsT&&...args) {
|
||||||
return this->_insert(npos, fennec::forward<ArgsT>(args)...);
|
return this->_insert(npos, fennec::forward<ArgsT>(args)...);
|
||||||
|
|||||||
@@ -173,8 +173,8 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Argument Key Access Operator
|
/// \brief Argument Key Access Operator
|
||||||
/// \tparam ArgT Argument Type
|
/// \tparam ArgsT Argument Types
|
||||||
/// \param arg Argument to construct the key with
|
/// \param args Arguments to construct the key with
|
||||||
/// \returns A pointer to the value associated with `key`, `nullptr` if `key` is not present.
|
/// \returns A pointer to the value associated with `key`, `nullptr` if `key` is not present.
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr value_t* operator[](ArgsT&&...args) {
|
constexpr value_t* operator[](ArgsT&&...args) {
|
||||||
@@ -210,6 +210,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Key-Value Insertion
|
/// \brief Key-Value Insertion
|
||||||
|
/// \param key key to insert
|
||||||
/// \param args Arguments for constructing the key-value pair
|
/// \param args Arguments for constructing the key-value pair
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr void emplace(const KeyT& key, ArgsT&&...args) {
|
constexpr void emplace(const KeyT& key, ArgsT&&...args) {
|
||||||
|
|||||||
@@ -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 {
|
constexpr operator bool() const {
|
||||||
return _set;
|
return _set;
|
||||||
}
|
}
|
||||||
@@ -160,8 +161,8 @@ public:
|
|||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Fundamental Type Assignment
|
/// \brief Null Assignment
|
||||||
/// \param val The value to set with
|
/// \returns A reference to self
|
||||||
constexpr optional& operator=(nullopt_t) {
|
constexpr optional& operator=(nullopt_t) {
|
||||||
if constexpr(not is_fundamental_v<T>) {
|
if constexpr(not is_fundamental_v<T>) {
|
||||||
if (_set) {
|
if (_set) {
|
||||||
@@ -176,6 +177,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Type Copy Assignment
|
/// \brief Type Copy Assignment
|
||||||
/// \param val The value to set with
|
/// \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> {
|
constexpr optional& operator=(const T& val) requires is_copy_constructible_v<T> and is_copy_assignable_v<T> {
|
||||||
if (_set) {
|
if (_set) {
|
||||||
_val = val;
|
_val = val;
|
||||||
@@ -189,6 +191,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Type Move Assignment
|
/// \brief Type Move Assignment
|
||||||
/// \param val The value to set with
|
/// \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> {
|
constexpr optional& operator=(T&& val) requires is_move_constructible_v<T> and is_move_assignable_v<T> {
|
||||||
if (_set) {
|
if (_set) {
|
||||||
_val = fennec::forward<T>(val);
|
_val = fennec::forward<T>(val);
|
||||||
@@ -202,6 +205,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Copy Assignment
|
/// \brief Copy Assignment
|
||||||
/// \param opt The optional to copy
|
/// \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> {
|
constexpr optional& operator=(const optional& opt) requires is_copy_constructible_v<T> and is_copy_assignable_v<T> {
|
||||||
if (_set != opt._set) {
|
if (_set != opt._set) {
|
||||||
_set = opt._set;
|
_set = opt._set;
|
||||||
@@ -220,6 +224,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Move Assignment
|
/// \brief Move Assignment
|
||||||
/// \param opt The optional to move
|
/// \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> {
|
constexpr optional& operator=(optional&& opt) noexcept requires is_move_constructible_v<T> and is_move_assignable_v<T> {
|
||||||
if (_set != opt._set) {
|
if (_set != opt._set) {
|
||||||
_set = opt._set;
|
_set = opt._set;
|
||||||
@@ -297,6 +302,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Emplace Assignment, Move overload
|
/// \brief Emplace Assignment, Move overload
|
||||||
/// \param val The object to take ownership of
|
/// \param val The object to take ownership of
|
||||||
|
/// \returns A reference to the held value
|
||||||
constexpr T& emplace(T&& val) {
|
constexpr T& emplace(T&& val) {
|
||||||
if (_set) {
|
if (_set) {
|
||||||
_val = fennec::forward<T>(val);
|
_val = fennec::forward<T>(val);
|
||||||
@@ -310,6 +316,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Emplace Assignment, Copy overload
|
/// \brief Emplace Assignment, Copy overload
|
||||||
/// \param val The object to copy
|
/// \param val The object to copy
|
||||||
|
/// \returns A reference to the held value
|
||||||
constexpr T& emplace(const T& val) {
|
constexpr T& emplace(const T& val) {
|
||||||
if (_set) {
|
if (_set) {
|
||||||
_val = val;
|
_val = val;
|
||||||
@@ -323,6 +330,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Emplace Assignment
|
/// \brief Emplace Assignment
|
||||||
/// \param args The arguments to construct with
|
/// \param args The arguments to construct with
|
||||||
|
/// \returns A reference to the held value
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr T& emplace(ArgsT&&...args) {
|
constexpr T& emplace(ArgsT&&...args) {
|
||||||
if (_set) {
|
if (_set) {
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ struct pair {
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Copy Constructor, copies both elements
|
/// \brief Copy Constructor, copies both elements
|
||||||
|
/// \param pair The pair to copy
|
||||||
constexpr pair(const pair& pair)
|
constexpr pair(const pair& pair)
|
||||||
: first(fennec::copy(pair.first))
|
: first(fennec::copy(pair.first))
|
||||||
, second(fennec::copy(pair.second)) {
|
, second(fennec::copy(pair.second)) {
|
||||||
@@ -102,6 +103,7 @@ struct pair {
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Move Constructor, moves both elements
|
/// \brief Move Constructor, moves both elements
|
||||||
|
/// \param pair The pair to move
|
||||||
constexpr pair(pair&& pair) noexcept
|
constexpr pair(pair&& pair) noexcept
|
||||||
: first(fennec::move(pair.first))
|
: first(fennec::move(pair.first))
|
||||||
, second(fennec::move(pair.second)) {
|
, second(fennec::move(pair.second)) {
|
||||||
@@ -109,6 +111,8 @@ struct pair {
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Copy Assignment, copies both elements
|
/// \brief Copy Assignment, copies both elements
|
||||||
|
/// \param pair The pair to copy
|
||||||
|
/// \returns A reference to self
|
||||||
constexpr pair& operator=(const pair& pair) {
|
constexpr pair& operator=(const pair& pair) {
|
||||||
first = fennec::copy(pair.first);
|
first = fennec::copy(pair.first);
|
||||||
second = fennec::copy(pair.second);
|
second = fennec::copy(pair.second);
|
||||||
@@ -117,6 +121,8 @@ struct pair {
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Move Assignment, moves both elements
|
/// \brief Move Assignment, moves both elements
|
||||||
|
/// \param pair The pair to move
|
||||||
|
/// \returns A reference to self
|
||||||
constexpr pair& operator=(pair&& pair) {
|
constexpr pair& operator=(pair&& pair) {
|
||||||
first = fennec::move(pair.first);
|
first = fennec::move(pair.first);
|
||||||
second = fennec::move(pair.second);
|
second = fennec::move(pair.second);
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \param i The id of the node to check
|
/// \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
|
/// \returns The id of the child node
|
||||||
constexpr size_t child(size_t i, size_t n = 0) const {
|
constexpr size_t child(size_t i, size_t n = 0) const {
|
||||||
if (i >= _table.capacity() && n != npos) return npos;
|
if (i >= _table.capacity() && n != npos) return npos;
|
||||||
@@ -205,6 +206,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \param i The id of the node to check
|
/// \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
|
/// \returns The id of the next node
|
||||||
constexpr size_t next(size_t i, size_t n = 0) const {
|
constexpr size_t next(size_t i, size_t n = 0) const {
|
||||||
if (i >= _table.capacity() && n != npos) return npos;
|
if (i >= _table.capacity() && n != npos) return npos;
|
||||||
@@ -229,6 +231,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \param i The id of the node to check
|
/// \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
|
/// \returns The id of the previous node
|
||||||
constexpr size_t prev(size_t i, size_t n = 0) const {
|
constexpr size_t prev(size_t i, size_t n = 0) const {
|
||||||
if (i >= _table.capacity()) return npos;
|
if (i >= _table.capacity()) return npos;
|
||||||
|
|||||||
@@ -291,6 +291,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Move Insertion
|
/// \brief Move Insertion
|
||||||
/// \param val Value to insert
|
/// \param val Value to insert
|
||||||
|
/// \returns An iterator at the held value
|
||||||
constexpr iterator insert(elem_t&& val) {
|
constexpr iterator insert(elem_t&& val) {
|
||||||
return this->_insert(fennec::forward<elem_t>(val));
|
return this->_insert(fennec::forward<elem_t>(val));
|
||||||
}
|
}
|
||||||
@@ -298,6 +299,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Copy Insertion
|
/// \brief Copy Insertion
|
||||||
/// \param val Value to insert
|
/// \param val Value to insert
|
||||||
|
/// \returns An iterator at the held value
|
||||||
constexpr iterator insert(const elem_t& val) {
|
constexpr iterator insert(const elem_t& val) {
|
||||||
return this->_insert(val);
|
return this->_insert(val);
|
||||||
}
|
}
|
||||||
@@ -306,6 +308,7 @@ public:
|
|||||||
/// \brief Emplace Insertion
|
/// \brief Emplace Insertion
|
||||||
/// \tparam ArgsT Argument types
|
/// \tparam ArgsT Argument types
|
||||||
/// \param args Arguments to construct with
|
/// \param args Arguments to construct with
|
||||||
|
/// \returns An iterator at the held value
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr iterator emplace(ArgsT&&...args) {
|
constexpr iterator emplace(ArgsT&&...args) {
|
||||||
return this->_insert(fennec::forward<ArgsT>(args)...);
|
return this->_insert(fennec::forward<ArgsT>(args)...);
|
||||||
|
|||||||
@@ -168,6 +168,14 @@
|
|||||||
# define FENNEC_HAS_BUILTIN_IS_ARRAY
|
# define FENNEC_HAS_BUILTIN_IS_ARRAY
|
||||||
#endif
|
#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
|
// Inconsistent without intrinsics
|
||||||
#if __has_builtin(__is_class)
|
#if __has_builtin(__is_class)
|
||||||
# define FENNEC_HAS_BUILTIN_IS_CLASS 1
|
# define FENNEC_HAS_BUILTIN_IS_CLASS 1
|
||||||
@@ -176,6 +184,14 @@
|
|||||||
# define FENNEC_HAS_BUILTIN_IS_CLASS
|
# define FENNEC_HAS_BUILTIN_IS_CLASS
|
||||||
#endif
|
#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)
|
#if __has_builtin(__is_member_pointer)
|
||||||
# define FENNEC_HAS_BUILTIN_IS_MEMBER_POINTER 1
|
# define FENNEC_HAS_BUILTIN_IS_MEMBER_POINTER 1
|
||||||
# define FENNEC_BUILTIN_IS_MEMBER_POINTER(arg) __is_member_pointer(arg)
|
# define FENNEC_BUILTIN_IS_MEMBER_POINTER(arg) __is_member_pointer(arg)
|
||||||
@@ -211,11 +227,19 @@
|
|||||||
// Difficult and Inconsistent without intrinsics
|
// Difficult and Inconsistent without intrinsics
|
||||||
#if __has_builtin(__is_trivially_constructible)
|
#if __has_builtin(__is_trivially_constructible)
|
||||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 1
|
# 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
|
#else
|
||||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 0
|
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 0
|
||||||
#endif
|
#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
|
// Difficult and Inconsistent without intrinsics
|
||||||
#if __has_builtin(__has_trivial_destructor)
|
#if __has_builtin(__has_trivial_destructor)
|
||||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 1
|
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 1
|
||||||
@@ -235,6 +259,22 @@
|
|||||||
# define FENNEC_HAS_BUILTIN_IS_ASSIGNABLE 0
|
# define FENNEC_HAS_BUILTIN_IS_ASSIGNABLE 0
|
||||||
#endif
|
#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
|
// Inconsistent without intrinsics
|
||||||
#if __has_builtin(__is_trivial)
|
#if __has_builtin(__is_trivial)
|
||||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIAL 1
|
# define FENNEC_HAS_BUILTIN_IS_TRIVIAL 1
|
||||||
|
|||||||
@@ -249,15 +249,15 @@ template<typename TypeT> struct numeric_limits
|
|||||||
static constexpr float_round_style rounding_style = round_indeterminate; ///< The rounding style of TypeT
|
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
|
// 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 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 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 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 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 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 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 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 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 denorm_min() { return TypeT(); } ///< \returns a value of TypeT holding the smallest positive subnormal
|
||||||
};
|
};
|
||||||
|
|
||||||
// Overload definitions for basic types
|
// Overload definitions for basic types
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -109,16 +109,16 @@
|
|||||||
/// \copydetails fennec::remove_cv
|
/// \copydetails fennec::remove_cv
|
||||||
///
|
///
|
||||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||||
/// \ref fennec::add_cvr "add_cvr<TypeT>::type"<br>
|
/// \ref fennec::add_cvref "add_cvref<TypeT>::type"<br>
|
||||||
/// \ref fennec::add_cvr_t "add_cvr_t<TypeT>"
|
/// \ref fennec::add_cvref_t "add_cvref_t<TypeT>"
|
||||||
/// <td width="50%" style="vertical-align: top">
|
/// <td width="50%" style="vertical-align: top">
|
||||||
/// \copydetails fennec::add_cvr
|
/// \copydetails fennec::add_cvref
|
||||||
///
|
///
|
||||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||||
/// \ref fennec::remove_cvr "remove_cvr<TypeT>::type"<br>
|
/// \ref fennec::remove_cvref "remove_cvref<TypeT>::type"<br>
|
||||||
/// \ref fennec::remove_cvr_t "remove_cvr_t<TypeT>"
|
/// \ref fennec::remove_cvref_t "remove_cvref_t<TypeT>"
|
||||||
/// <td width="50%" style="vertical-align: top">
|
/// <td width="50%" style="vertical-align: top">
|
||||||
/// \copydetails fennec::remove_cvr
|
/// \copydetails fennec::remove_cvref
|
||||||
///
|
///
|
||||||
/// </table>
|
/// </table>
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -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>
|
/// \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,
|
/// \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,
|
/// 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$,
|
/// 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>
|
/// where \f$x=0\f$ is undefined, and respectively the return value is also \f$NaN\f$. <br> <br>
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
///
|
///
|
||||||
/// \code #include <fennec/math/math.h> \endcode
|
/// \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
|
/// 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).
|
/// [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf).
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -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>
|
/// \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
|
/// Note: to get linear algebraic matrix multiplication, use
|
||||||
/// the multiply operator (*)
|
/// the multiply operator (*)
|
||||||
@@ -165,14 +165,12 @@ constexpr mat<scalar, rows, sizeof...(cols)> transpose(const matrix<scalar, rows
|
|||||||
/// \returns the determinant of m.
|
/// \returns the determinant of m.
|
||||||
template<typename scalar, size_t rows, size_t...cols>
|
template<typename scalar, size_t rows, size_t...cols>
|
||||||
constexpr scalar determinant(const matrix<scalar, rows, cols...>&) noexcept {
|
constexpr scalar determinant(const matrix<scalar, rows, cols...>&) noexcept {
|
||||||
// ReSharper disable once CppStaticAssertFailure
|
|
||||||
static_assert(false, "implementation undefined");
|
static_assert(false, "implementation undefined");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename scalar, size_t rows, size_t...cols>
|
template<typename scalar, size_t rows, size_t...cols>
|
||||||
constexpr matrix<scalar, rows, cols...> inverse(const matrix<scalar, rows, cols...>&) noexcept {
|
constexpr matrix<scalar, rows, cols...> inverse(const matrix<scalar, rows, cols...>&) noexcept {
|
||||||
// ReSharper disable once CppStaticAssertFailure
|
|
||||||
static_assert(false, "implementation undefined");
|
static_assert(false, "implementation undefined");
|
||||||
return 1;
|
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) {
|
constexpr column_t& operator[](size_t i) {
|
||||||
return data[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) {
|
constexpr scalar_t& operator[](size_t i, size_t j) {
|
||||||
return data[i][j];
|
return data[i][j];
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief returns the cell in row \p j column \p i
|
/// \brief returns the cell in row \p j column \p i
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
/// \param i the column
|
/// \param i the column
|
||||||
/// \param j the row
|
/// \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 {
|
constexpr scalar_t operator[](size_t i, size_t j) const {
|
||||||
return data[i][j];
|
return data[i][j];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,10 +41,10 @@
|
|||||||
///
|
///
|
||||||
/// \code #include <fennec/math/scalar.h> \endcode
|
/// \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.
|
/// 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 |
|
/// | Type | Corresponding Type | Meaning |
|
||||||
/// |----------|-----------------------|------------------------------|
|
/// |----------|-----------------------|------------------------------|
|
||||||
|
|||||||
@@ -144,61 +144,87 @@ template<typename T>
|
|||||||
class allocator
|
class allocator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
///
|
||||||
/// \brief Alias for the data type used for metaprogramming
|
/// \brief Alias for the data type used for metaprogramming
|
||||||
using value_t = T;
|
using value_t = T;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Metaprogramming utility to rebind an allocator to a different data type
|
/// \brief Metaprogramming utility to rebind an allocator to a different data type
|
||||||
template<typename R> using rebind = allocator<R>;
|
template<typename R> using rebind = allocator<R>;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Default Constructor
|
/// \brief Default Constructor
|
||||||
constexpr allocator() = default;
|
constexpr allocator() = default;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Default Destructor
|
/// \brief Default Destructor
|
||||||
constexpr ~allocator() = default;
|
constexpr ~allocator() = default;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Copy Constructor
|
/// \brief Copy Constructor
|
||||||
constexpr allocator(const allocator&) = default;
|
constexpr allocator(const allocator&) = default;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Copy Assignment
|
/// \brief Copy Assignment
|
||||||
|
/// \returns A reference to self
|
||||||
constexpr allocator& operator=(const allocator&) = default;
|
constexpr allocator& operator=(const allocator&) = default;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Equality operator
|
/// \brief Equality operator
|
||||||
|
/// \returns `true`
|
||||||
constexpr bool_t operator==(const allocator&) {
|
constexpr bool_t operator==(const allocator&) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Inequality operator
|
/// \brief Inequality operator
|
||||||
|
/// \returns `false`
|
||||||
constexpr bool_t operator!=(const allocator&) {
|
constexpr bool_t operator!=(const allocator&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Equality operator for allocators of same type but with different data type
|
/// \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>&) {
|
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
|
/// \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>&) {
|
template<typename U> constexpr bool_t operator!=(const allocator<U>&) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Allocate a block of memory large enough to hold `n` elements of type `T`
|
/// \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) {
|
constexpr T* allocate(size_t n) {
|
||||||
return static_cast<T*>(::operator new(n * sizeof(T)));
|
return static_cast<T*>(::operator new(n * sizeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Allocate a block of memory large enough to hold `n` elements of type `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) {
|
constexpr T* allocate(size_t n, align_t align) {
|
||||||
return static_cast<T*>(::operator new(n * sizeof(T), align));
|
return static_cast<T*>(::operator new(n * sizeof(T), align));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Deallocate a block of memory with type `T`
|
/// \brief Deallocate a block of memory with type `T`
|
||||||
|
/// \param ptr The block to release
|
||||||
constexpr void deallocate(T* ptr) {
|
constexpr void deallocate(T* ptr) {
|
||||||
return ::operator delete(ptr);
|
return ::operator delete(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Deallocate a block of memory with type `T`
|
/// \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) {
|
constexpr void deallocate(T* ptr, align_t align) {
|
||||||
return ::operator delete(ptr, align);
|
return ::operator delete(ptr, align);
|
||||||
}
|
}
|
||||||
@@ -212,61 +238,88 @@ template<typename T>
|
|||||||
class allocator<T[]>
|
class allocator<T[]>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
///
|
||||||
/// \brief Alias for the data type used for metaprogramming
|
/// \brief Alias for the data type used for metaprogramming
|
||||||
using value_t = T;
|
using value_t = T;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Metaprogramming utility to rebind an allocator to a different data type
|
/// \brief Metaprogramming utility to rebind an allocator to a different data type
|
||||||
template<typename R> using rebind = allocator<R>;
|
template<typename R> using rebind = allocator<R>;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Default Constructor
|
/// \brief Default Constructor
|
||||||
constexpr allocator() = default;
|
constexpr allocator() = default;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Default Destructor
|
/// \brief Default Destructor
|
||||||
constexpr ~allocator() = default;
|
constexpr ~allocator() = default;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Copy Constructor
|
/// \brief Copy Constructor
|
||||||
constexpr allocator(const allocator&) = default;
|
constexpr allocator(const allocator&) = default;
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Copy Assignment
|
/// \brief Copy Assignment
|
||||||
|
/// \returns A reference to self
|
||||||
constexpr allocator& operator=(const allocator&) = default;
|
constexpr allocator& operator=(const allocator&) = default;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Equality operator
|
/// \brief Equality operator
|
||||||
|
/// \returns `true`
|
||||||
constexpr bool_t operator==(const allocator&) {
|
constexpr bool_t operator==(const allocator&) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Inequality operator
|
/// \brief Inequality operator
|
||||||
|
/// \returns `false`
|
||||||
constexpr bool_t operator!=(const allocator&) {
|
constexpr bool_t operator!=(const allocator&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Equality operator for allocators of same type but with different data type
|
/// \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>&) {
|
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
|
/// \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>&) {
|
template<typename U> constexpr bool_t operator!=(const allocator<U>&) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Allocate a block of memory large enough to hold `n` elements of type `T`
|
/// \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) {
|
constexpr T* allocate(size_t n) {
|
||||||
return static_cast<T*>(::operator new[](n * sizeof(T)));
|
return static_cast<T*>(::operator new[](n * sizeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Allocate a block of memory large enough to hold `n` elements of type `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) {
|
constexpr T* allocate(size_t n, align_t align) {
|
||||||
return static_cast<T*>(::operator new[](n * sizeof(T), align));
|
return static_cast<T*>(::operator new[](n * sizeof(T), align));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Deallocate a block of memory with type `T`
|
/// \brief Deallocate a block of memory with type `T`
|
||||||
|
/// \param ptr The block to release
|
||||||
constexpr void deallocate(T* ptr) {
|
constexpr void deallocate(T* ptr) {
|
||||||
return ::operator delete[](ptr);
|
return ::operator delete[](ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Deallocate a block of memory with type `T`
|
/// \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) {
|
constexpr void deallocate(T* ptr, align_t align) {
|
||||||
return ::operator delete[](ptr, align);
|
return ::operator delete[](ptr, align);
|
||||||
}
|
}
|
||||||
@@ -480,7 +533,9 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Allocate a block of memory for the allocation.
|
/// \brief Allocate a block of memory for the allocation.
|
||||||
/// If there is already an allocated block of memory, the previous allocation is released.
|
/// 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 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 {
|
constexpr void allocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
deallocate();
|
deallocate();
|
||||||
|
|
||||||
@@ -494,7 +549,9 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Allocate a block of memory for the allocation.
|
/// \brief Allocate a block of memory for the allocation.
|
||||||
/// If there is already an allocated block of memory, the previous allocation is released.
|
/// 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 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 {
|
constexpr void callocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
allocate(n, align);
|
allocate(n, align);
|
||||||
fennec::memset(static_cast<void*>(_data), 0, _capacity * sizeof(T));
|
fennec::memset(static_cast<void*>(_data), 0, _capacity * sizeof(T));
|
||||||
@@ -519,6 +576,9 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Reallocate the block with a new size.
|
/// \brief Reallocate the block with a new size.
|
||||||
/// Contents are copied to the new allocation.
|
/// 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 {
|
constexpr void reallocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
if (_data == nullptr) {
|
if (_data == nullptr) {
|
||||||
allocate(n, align);
|
allocate(n, align);
|
||||||
@@ -538,6 +598,9 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Reallocate the block with a new size.
|
/// \brief Reallocate the block with a new size.
|
||||||
/// Contents are copied to the new allocation.
|
/// 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 {
|
constexpr void creallocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
if (_data == nullptr) {
|
if (_data == nullptr) {
|
||||||
callocate(n, align);
|
callocate(n, align);
|
||||||
@@ -561,36 +624,58 @@ public:
|
|||||||
|
|
||||||
// Access ==============================================================================================================
|
// 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) {
|
constexpr value_t& operator[](size_t i) {
|
||||||
assertd(i < capacity(), "Array Out of Bounds");
|
assertd(i < capacity(), "Array Out of Bounds");
|
||||||
return _data[i];
|
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 {
|
constexpr const value_t& operator[](size_t i) const {
|
||||||
assertd(i < capacity(), "Array Out of Bounds");
|
assertd(i < capacity(), "Array Out of Bounds");
|
||||||
return _data[i];
|
return _data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The underlying pointer.
|
||||||
constexpr operator value_t*() {
|
constexpr operator value_t*() {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Dereference Operators
|
||||||
|
/// \returns The underlying pointer.
|
||||||
constexpr operator const value_t*() const {
|
constexpr operator const value_t*() const {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns A pointer to the start of the allocation.
|
||||||
value_t* begin() {
|
value_t* begin() {
|
||||||
return _data;
|
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 {
|
const value_t* begin() const {
|
||||||
return _data;
|
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 {
|
const value_t* end() const {
|
||||||
return _data + capacity();
|
return _data + capacity();
|
||||||
}
|
}
|
||||||
@@ -632,6 +717,9 @@ public:
|
|||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Getter for the alignment of the allocation.
|
||||||
|
/// \returns the alignment of the allocation
|
||||||
constexpr align_t alignment() const {
|
constexpr align_t alignment() const {
|
||||||
return _alignment;
|
return _alignment;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \file wayland_server.h
|
/// \file server.h
|
||||||
/// \brief
|
/// \brief
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \file wayland_window.h
|
/// \file window.h
|
||||||
/// \brief
|
/// \brief
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -233,9 +233,9 @@ public:
|
|||||||
/// \param faces An array of pointers to textures containing pixel data for each face
|
/// \param faces An array of pointers to textures containing pixel data for each face
|
||||||
/// \param component The component type of the data
|
/// \param component The component type of the data
|
||||||
/// \param layout The layout of the components in the pixel
|
/// \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,
|
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)
|
: _handle(NULL)
|
||||||
, _width(size), _height(size), _depth(1)
|
, _width(size), _height(size), _depth(1)
|
||||||
, _samples(1), _mips(mips) {
|
, _samples(1), _mips(mips) {
|
||||||
@@ -262,11 +262,11 @@ public:
|
|||||||
/// \param data A pointer to a buffer containing image data
|
/// \param data A pointer to a buffer containing image data
|
||||||
/// \param component The component type of the data
|
/// \param component The component type of the data
|
||||||
/// \param layout The layout of the components in the pixel
|
/// \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
|
/// \details Requires OES_texture_cube_map_array
|
||||||
texture(GLsizei size, GLsizei depth, GLsizei mips,
|
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)
|
: _handle(NULL)
|
||||||
, _width(size), _height(size), _depth(depth)
|
, _width(size), _height(size), _depth(depth)
|
||||||
, _samples(1), _mips(mips) {
|
, _samples(1), _mips(mips) {
|
||||||
|
|||||||
@@ -221,8 +221,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Data Access
|
/// \returns A pointer to the underlying allocation
|
||||||
/// \returns A const qualified pointer to the underlying allocation
|
|
||||||
constexpr char* data() {
|
constexpr char* data() {
|
||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
@@ -236,6 +235,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Implicit Dereference Cast
|
/// \brief Implicit Dereference Cast
|
||||||
|
/// \returns A const qualified pointer to the underlying allocation
|
||||||
constexpr operator const char*() const {
|
constexpr operator const char*() const {
|
||||||
return _cstr;
|
return _cstr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,15 +67,28 @@ public:
|
|||||||
fennec::memset(_str, c, n);
|
fennec::memset(_str, c, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Alloc Constructor
|
||||||
|
/// \param alloc The allocator to use
|
||||||
constexpr _string(const alloc_t& alloc)
|
constexpr _string(const alloc_t& alloc)
|
||||||
: _str(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)
|
constexpr _string(size_t n, char c, const alloc_t& alloc)
|
||||||
: _str(n + 1, alloc) {
|
: _str(n + 1, alloc) {
|
||||||
fennec::memset(_str, c, n);
|
fennec::memset(_str, c, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C-String Constructor
|
||||||
|
/// \param cstr The C-Style string to construct from.
|
||||||
constexpr _string(const cstring& cstr)
|
constexpr _string(const cstring& cstr)
|
||||||
: _str(cstr, cstr.size() + 1) {
|
: _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
|
/// \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
|
/// \param n the number of characters in the buffer including the null-terminator, if present
|
||||||
constexpr _string(const char* buf, size_t n)
|
constexpr _string(const char* buf, size_t n)
|
||||||
: _str(buf[n - 1] != '\0' ? n + 1 : 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)
|
constexpr _string(const string_view& view)
|
||||||
: _string(view.str, view.len) {
|
: _string(view.str, view.len) {
|
||||||
}
|
}
|
||||||
@@ -128,16 +144,29 @@ public:
|
|||||||
|
|
||||||
// Assignment ==========================================================================================================
|
// Assignment ==========================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C-String Assignment
|
||||||
|
/// \param cstr The C-Style string to assign.
|
||||||
|
/// \returns A reference to self
|
||||||
constexpr _string& operator=(const cstring& cstr) {
|
constexpr _string& operator=(const cstring& cstr) {
|
||||||
_str.callocate(cstr.capacity());
|
_str.callocate(cstr.capacity());
|
||||||
fennec::memcpy(_str, cstr, cstr.capacity());
|
fennec::memcpy(_str, cstr, cstr.capacity());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief String Copy Assignment
|
||||||
|
/// \param str the string to copy
|
||||||
|
/// \returns A reference to self
|
||||||
constexpr _string& operator=(const _string& str) {
|
constexpr _string& operator=(const _string& str) {
|
||||||
_str = str._str;
|
_str = str._str;
|
||||||
return *this;
|
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 {
|
constexpr _string& operator=(_string&& str) noexcept {
|
||||||
_str = fennec::move(str._str);
|
_str = fennec::move(str._str);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -157,6 +186,8 @@ public:
|
|||||||
return _str.capacity();
|
return _str.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns `true` if the string contains no characters, `false` otherwise.
|
||||||
constexpr bool empty() const {
|
constexpr bool empty() const {
|
||||||
return size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
@@ -179,14 +210,20 @@ public:
|
|||||||
return _str[i];
|
return _str[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The underlying pointer to the held string
|
||||||
constexpr char* data() {
|
constexpr char* data() {
|
||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The underlying pointer to the held string
|
||||||
constexpr const char* data() const {
|
constexpr const char* data() const {
|
||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The underlying pointer to the held string
|
||||||
constexpr const char* cstr() const {
|
constexpr const char* cstr() const {
|
||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
@@ -200,46 +237,56 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Comparison
|
/// \param str the string to compare against
|
||||||
/// \param ostr 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
|
/// \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.
|
/// current locale, otherwise a positive value.
|
||||||
constexpr int compare(const cstring& str, size_t i = 0, size_t n = npos) const {
|
constexpr int compare(const cstring& str, size_t i = 0, size_t n = npos) const {
|
||||||
if (i >= size()) { // bounds check
|
if (i >= size()) { // bounds check
|
||||||
return -1;
|
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);
|
return ::strncmp(_str + i, str, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Comparison
|
/// \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
|
/// \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.
|
/// 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
|
if (i >= size()) { // bounds check
|
||||||
return -1;
|
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);
|
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 {
|
constexpr bool operator==(const cstring& str) const {
|
||||||
return compare(str) == 0;
|
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 {
|
constexpr bool operator==(const _string& str) const {
|
||||||
return compare(str) == 0;
|
return compare(str) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Check if the string contains a character
|
/// \brief Check if the string contains a character
|
||||||
/// \param c
|
/// \param c The character to find
|
||||||
/// \param i
|
/// \param i An offset to start at in `this`
|
||||||
/// \return
|
/// \returns `true` if `c` is contained in `this`
|
||||||
constexpr bool contains(char c, size_t i = 0) const {
|
constexpr bool contains(char c, size_t i = 0) const {
|
||||||
return find(c, i) != size();
|
return find(c, i) != size();
|
||||||
}
|
}
|
||||||
@@ -247,6 +294,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Finds the index of the first occurrence of `c` in the string
|
/// \brief Finds the index of the first occurrence of `c` in the string
|
||||||
/// \param c the character to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t find(char c, size_t i = 0) const {
|
||||||
if (i >= size()) { // bounds check
|
if (i >= size()) { // bounds check
|
||||||
@@ -260,6 +308,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Finds the index of the first occurrence of `str` in the string.
|
/// \brief Finds the index of the first occurrence of `str` in the string.
|
||||||
/// \param str the string to find
|
/// \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()`
|
/// \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
|
constexpr size_t find(const string& str, size_t i = 0) const { // bounds check
|
||||||
if (i >= size()) { // 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.
|
/// \brief Finds the index of the first occurrence of `str` in the string.
|
||||||
/// \param str the string to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t find(const cstring& str, size_t i = 0) const {
|
||||||
if (i + str.size() > size()) { // bounds check
|
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.
|
/// \brief Finds the index of the last occurrence of `c` in the string.
|
||||||
/// \param c the string to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t rfind(char c, size_t i = npos) const {
|
||||||
if (size() == 0) {
|
if (size() == 0) {
|
||||||
@@ -304,7 +354,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Finds the index of the last occurrence of `str` in the string.
|
/// \brief Finds the index of the last occurrence of `str` in the string.
|
||||||
/// \param str the string to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t rfind(const cstring& str, size_t i = npos) const {
|
||||||
if (size() == 0) {
|
if (size() == 0) {
|
||||||
@@ -325,7 +375,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Finds the index of the last occurrence of `str` in the string.
|
/// \brief Finds the index of the last occurrence of `str` in the string.
|
||||||
/// \param str the string to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t rfind(const string& str, size_t i = npos) const {
|
||||||
if (size() == 0) {
|
if (size() == 0) {
|
||||||
@@ -345,9 +395,9 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Retrieve a substring of a string
|
/// \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
|
/// \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 {
|
constexpr _string substring(size_t i, size_t n = npos) const {
|
||||||
if (i >= size() || n == 0) {
|
if (i >= size() || n == 0) {
|
||||||
return _string("");
|
return _string("");
|
||||||
@@ -363,11 +413,19 @@ public:
|
|||||||
|
|
||||||
// Modifiers ===========================================================================================================
|
// 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) {
|
constexpr void resize(size_t n) {
|
||||||
_str.creallocate(n + 1);
|
_str.creallocate(n + 1);
|
||||||
_str[size()] = '\0';
|
_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 {
|
constexpr _string operator+(char c) const {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return _string(1, c);
|
return _string(1, c);
|
||||||
@@ -379,11 +437,20 @@ public:
|
|||||||
return res;
|
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) {
|
friend constexpr _string operator+(char c, const _string& str) {
|
||||||
_string res(1, c);
|
_string res(str.size() + 1);
|
||||||
return res += str;
|
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 {
|
constexpr _string operator+(const cstring& cstr) const {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return _string(cstr);
|
return _string(cstr);
|
||||||
@@ -395,6 +462,10 @@ public:
|
|||||||
return res;
|
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 {
|
constexpr _string operator+(const _string& str) const {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return _string(str);
|
return _string(str);
|
||||||
@@ -409,6 +480,10 @@ public:
|
|||||||
return res;
|
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) {
|
constexpr _string& operator+=(char c) {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
_str.callocate(2);
|
_str.callocate(2);
|
||||||
@@ -420,6 +495,9 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \param cstr The string to append
|
||||||
|
/// \returns `this` string expanded to additionally contain `cstr`
|
||||||
constexpr _string& operator+=(const cstring& cstr) {
|
constexpr _string& operator+=(const cstring& cstr) {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return *this = cstr;
|
return *this = cstr;
|
||||||
@@ -430,6 +508,10 @@ public:
|
|||||||
return *this;
|
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) {
|
constexpr _string& operator+=(const _string& str) {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return *this = str;
|
return *this = str;
|
||||||
@@ -446,18 +528,29 @@ public:
|
|||||||
|
|
||||||
// Iteration ===========================================================================================================
|
// Iteration ===========================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns A pointer to the first character in the string.
|
||||||
constexpr char* begin() {
|
constexpr char* begin() {
|
||||||
return _str.data();
|
return _str.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Iterable begin()
|
||||||
|
/// \returns A pointer to the first character in the string.
|
||||||
constexpr const char* begin() const {
|
constexpr const char* begin() const {
|
||||||
return _str.data();
|
return _str.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns A pointer to the null terminator of the string.
|
||||||
constexpr char* end() {
|
constexpr char* end() {
|
||||||
return _str.data() + _str.capacity();
|
return _str.data() + _str.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Iterable end()
|
||||||
|
/// \returns A pointer to the null terminator of the string.
|
||||||
constexpr const char* end() const {
|
constexpr const char* end() const {
|
||||||
return _str.data() + _str.capacity();
|
return _str.data() + _str.capacity();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,8 +205,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Data Access
|
/// \returns A pointer to the underlying allocation
|
||||||
/// \returns A const qualified pointer to the underlying allocation
|
|
||||||
constexpr wchar_t* data() {
|
constexpr wchar_t* data() {
|
||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
@@ -220,6 +219,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Implicit Dereference Cast
|
/// \brief Implicit Dereference Cast
|
||||||
|
/// \returns A const qualified pointer to the underlying allocation
|
||||||
constexpr operator const wchar_t*() const {
|
constexpr operator const wchar_t*() const {
|
||||||
return _cstr;
|
return _cstr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,15 +70,28 @@ public:
|
|||||||
fennec::wmemset(_str, c, n);
|
fennec::wmemset(_str, c, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Alloc Constructor
|
||||||
|
/// \param alloc The allocator to use
|
||||||
constexpr _wstring(const alloc_t& alloc)
|
constexpr _wstring(const alloc_t& alloc)
|
||||||
: _str(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)
|
constexpr _wstring(size_t n, wchar_t c, const alloc_t& alloc)
|
||||||
: _str(n + 1, alloc) {
|
: _str(n + 1, alloc) {
|
||||||
fennec::wmemset(_str, c, n);
|
fennec::wmemset(_str, c, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C-String Constructor
|
||||||
|
/// \param cstr The C-Style string to construct from.
|
||||||
constexpr _wstring(const wcstring& cstr)
|
constexpr _wstring(const wcstring& cstr)
|
||||||
: _str(cstr, cstr.size() + 1) {
|
: _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
|
/// \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
|
/// \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)
|
constexpr _wstring(const wchar_t* buf, size_t n)
|
||||||
: _str(buf[n - 1] != '\0' ? n + 1 : n) {
|
: _str(buf[n - 1] != '\0' ? n + 1 : n) {
|
||||||
@@ -124,14 +137,33 @@ public:
|
|||||||
|
|
||||||
// Assignment ==========================================================================================================
|
// Assignment ==========================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C-String Assignment
|
||||||
|
/// \param cstr The C-Style string to assign.
|
||||||
|
/// \returns A reference to self
|
||||||
constexpr _wstring& operator=(const wcstring& cstr) {
|
constexpr _wstring& operator=(const wcstring& cstr) {
|
||||||
_str.callocate(cstr.capacity());
|
_str.callocate(cstr.capacity());
|
||||||
fennec::wmemcpy(_str, cstr, cstr.capacity());
|
fennec::memcpy(_str, cstr, cstr.capacity());
|
||||||
return *this;
|
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 ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
@@ -147,6 +179,8 @@ public:
|
|||||||
return _str.capacity();
|
return _str.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns `true` if the string contains no characters, `false` otherwise.
|
||||||
constexpr bool empty() const {
|
constexpr bool empty() const {
|
||||||
return size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
@@ -169,14 +203,20 @@ public:
|
|||||||
return _str[i];
|
return _str[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The underlying pointer to the held string
|
||||||
constexpr wchar_t* data() {
|
constexpr wchar_t* data() {
|
||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The underlying pointer to the held string
|
||||||
constexpr const wchar_t* data() const {
|
constexpr const wchar_t* data() const {
|
||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The underlying pointer to the held string
|
||||||
constexpr const wchar_t* cstr() const {
|
constexpr const wchar_t* cstr() const {
|
||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
@@ -190,46 +230,56 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Comparison
|
/// \param str the string to compare against
|
||||||
/// \param ostr 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
|
/// \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.
|
/// current locale, otherwise a positive value.
|
||||||
constexpr int compare(const wcstring& str, size_t i = 0, size_t n = npos) const {
|
constexpr int compare(const wcstring& str, size_t i = 0, size_t n = npos) const {
|
||||||
if (i >= size()) { // bounds check
|
if (i >= size()) { // bounds check
|
||||||
return -1;
|
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);
|
return ::wcsncmp(_str + i, str, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Comparison
|
/// \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
|
/// \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.
|
/// current locale, otherwise a positive value.
|
||||||
constexpr int compare(const _wstring& str, size_t i = 0, size_t n = npos) const {
|
constexpr int compare(const _wstring& str, size_t i = 0, size_t n = npos) const {
|
||||||
if (i >= size()) { // bounds check
|
if (i >= size()) { // bounds check
|
||||||
return -1;
|
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);
|
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 {
|
constexpr bool operator==(const wcstring& str) const {
|
||||||
return compare(str) == 0;
|
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 {
|
constexpr bool operator==(const _wstring& str) const {
|
||||||
return compare(str) == 0;
|
return compare(str) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Check if the string contains a character
|
/// \brief Check if the string contains a character
|
||||||
/// \param c
|
/// \param c The character to find
|
||||||
/// \param i
|
/// \param i An offset to start at in `this`
|
||||||
/// \return
|
/// \returns `true` if `c` is contained in `this`
|
||||||
constexpr bool contains(char c, size_t i = 0) const {
|
constexpr bool contains(char c, size_t i = 0) const {
|
||||||
return find(c, i) != size();
|
return find(c, i) != size();
|
||||||
}
|
}
|
||||||
@@ -237,6 +287,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Finds the index of the first occurrence of `c` in the string
|
/// \brief Finds the index of the first occurrence of `c` in the string
|
||||||
/// \param c the wchar_tacter to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t find(wchar_t c, size_t i = 0) const {
|
||||||
if (i >= size()) { // bounds check
|
if (i >= size()) { // bounds check
|
||||||
@@ -250,6 +301,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Finds the index of the first occurrence of `str` in the string.
|
/// \brief Finds the index of the first occurrence of `str` in the string.
|
||||||
/// \param str the string to find
|
/// \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()`
|
/// \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
|
constexpr size_t find(const _wstring& str, size_t i = 0) const { // bounds check
|
||||||
if (i >= size()) { // 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.
|
/// \brief Finds the index of the first occurrence of `str` in the string.
|
||||||
/// \param str the string to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t find(const wcstring& str, size_t i = 0) const {
|
||||||
if (i + str.size() > size()) { // bounds check
|
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.
|
/// \brief Finds the index of the last occurrence of `c` in the string.
|
||||||
/// \param c the string to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t rfind(wchar_t c, size_t i = npos) const {
|
||||||
if (size() == 0) {
|
if (size() == 0) {
|
||||||
@@ -294,7 +347,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Finds the index of the last occurrence of `str` in the string.
|
/// \brief Finds the index of the last occurrence of `str` in the string.
|
||||||
/// \param str the string to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t rfind(const wcstring& str, size_t i = npos) const {
|
||||||
if (size() == 0) {
|
if (size() == 0) {
|
||||||
@@ -315,7 +368,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Finds the index of the last occurrence of `str` in the string.
|
/// \brief Finds the index of the last occurrence of `str` in the string.
|
||||||
/// \param str the string to find
|
/// \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()`
|
/// \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 {
|
constexpr size_t rfind(const string& str, size_t i = npos) const {
|
||||||
if (size() == 0) {
|
if (size() == 0) {
|
||||||
@@ -335,9 +388,9 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Retrieve a substring of a string
|
/// \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 wchar_tacters
|
/// \param n the number of characters
|
||||||
/// \return
|
/// \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 {
|
constexpr _wstring substring(size_t i, size_t n = npos) const {
|
||||||
if (i >= size()) {
|
if (i >= size()) {
|
||||||
return _wstring("");
|
return _wstring("");
|
||||||
@@ -353,11 +406,19 @@ public:
|
|||||||
|
|
||||||
// Modifiers ===========================================================================================================
|
// 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) {
|
constexpr void resize(size_t n) {
|
||||||
_str.creallocate(n + 1);
|
_str.creallocate(n + 1);
|
||||||
_str[size()] = '\0';
|
_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 {
|
constexpr _wstring operator+(wchar_t c) const {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return _wstring(1, c);
|
return _wstring(1, c);
|
||||||
@@ -369,11 +430,18 @@ public:
|
|||||||
return res;
|
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) {
|
friend constexpr _wstring operator+(wchar_t c, const _wstring& str) {
|
||||||
_wstring res(1, c);
|
_wstring res(1, c);
|
||||||
return res += str;
|
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 {
|
constexpr _wstring operator+(const wcstring& cstr) const {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return _wstring(cstr);
|
return _wstring(cstr);
|
||||||
@@ -385,6 +453,10 @@ public:
|
|||||||
return res;
|
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 {
|
constexpr _wstring operator+(const _wstring& str) const {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return _wstring(str);
|
return _wstring(str);
|
||||||
@@ -399,6 +471,10 @@ public:
|
|||||||
return res;
|
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) {
|
constexpr _wstring& operator+=(wchar_t c) {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
_str.callocate(2);
|
_str.callocate(2);
|
||||||
@@ -410,6 +486,9 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \param cstr The string to append
|
||||||
|
/// \returns `this` string expanded to additionally contain `cstr`
|
||||||
constexpr _wstring& operator+=(const wcstring& cstr) {
|
constexpr _wstring& operator+=(const wcstring& cstr) {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return *this = cstr;
|
return *this = cstr;
|
||||||
@@ -420,6 +499,10 @@ public:
|
|||||||
return *this;
|
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) {
|
constexpr _wstring& operator+=(const _wstring& str) {
|
||||||
if (_str == nullptr) {
|
if (_str == nullptr) {
|
||||||
return *this = str;
|
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:
|
private:
|
||||||
alloc_t _str;
|
alloc_t _str;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -204,7 +204,6 @@ public:
|
|||||||
/// \param x The value to store in the atomic object if it is as expected.
|
/// \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 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 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.
|
/// \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 {
|
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);
|
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 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 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 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.
|
/// \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 {
|
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);
|
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).
|
/// 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 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 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.
|
/// \param order The memory synchronization ordering for both operations.
|
||||||
/// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise.
|
/// \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 {
|
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).
|
/// 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 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 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.
|
/// \param order The memory synchronization ordering for both operations.
|
||||||
/// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise.
|
/// \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 {
|
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 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 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 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.
|
/// \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 {
|
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);
|
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 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 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 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.
|
/// \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 {
|
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);
|
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).
|
/// 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 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 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.
|
/// \param order The memory synchronization ordering for both operations.
|
||||||
/// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise.
|
/// \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 {
|
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).
|
/// 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 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 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.
|
/// \param order The memory synchronization ordering for both operations.
|
||||||
/// \returns `true` if the underlying atomic value was successfully changed, `false` otherwise.
|
/// \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 {
|
bool compare_exchange_strong(T& exp, T x, memory_order order = memory_order_seq_cst) volatile noexcept {
|
||||||
|
|||||||
@@ -16,18 +16,6 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// 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/platform/interface/window.h>
|
||||||
#include <fennec/renderers/interface/gfxsurface.h>
|
#include <fennec/renderers/interface/gfxsurface.h>
|
||||||
#include <fennec/platform/interface/display_server.h>
|
#include <fennec/platform/interface/display_server.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user