From 9e6f00eb601c3df00528560c74fdf8a168f91989 Mon Sep 17 00:00:00 2001 From: Medusa Slockbower Date: Thu, 18 Dec 2025 00:00:36 -0500 Subject: [PATCH] - Documentation of containers, core, and format --- doxy/Doxyfile.in | 6 +- include/fennec/containers/array.h | 24 +- include/fennec/containers/bintree.h | 336 ++++++++++++++---- include/fennec/containers/bitfield.h | 59 ++- include/fennec/containers/deque.h | 6 +- include/fennec/containers/dynarray.h | 35 +- include/fennec/containers/generic.h | 59 ++- include/fennec/containers/graph.h | 50 +-- include/fennec/containers/initializer_list.h | 6 + include/fennec/containers/list.h | 66 +++- include/fennec/containers/map.h | 27 +- include/fennec/containers/object_pool.h | 188 +++++++--- include/fennec/containers/optional.h | 30 +- include/fennec/containers/pair.h | 20 +- include/fennec/containers/priority_queue.h | 37 +- include/fennec/containers/rdtree.h | 122 +++++-- include/fennec/containers/sequence.h | 243 ++++++++++--- include/fennec/containers/set.h | 85 +++-- include/fennec/containers/tuple.h | 47 ++- include/fennec/containers/variant.h | 37 +- include/fennec/core/event.h | 33 +- include/fennec/core/logger.h | 18 +- include/fennec/core/version.h | 8 +- include/fennec/filesystem/file.h | 119 ++++++- include/fennec/filesystem/path.h | 147 +++++--- include/fennec/format/charconv.h | 134 +++++++ include/fennec/format/format.h | 7 +- include/fennec/format/format_arg.h | 18 +- include/fennec/format/formatter.h | 52 +++ include/fennec/lang/assert.h | 8 +- include/fennec/lang/conditional_types.h | 8 +- include/fennec/lang/intrinsics.h | 14 +- include/fennec/lang/metasequences.h | 2 +- include/fennec/lang/type_sequences.h | 6 +- include/fennec/lang/type_traits.h | 140 ++++---- include/fennec/lang/type_transforms.h | 22 +- include/fennec/lang/types.h | 2 +- include/fennec/math/ext/quaternion.h | 32 +- include/fennec/math/matrix.h | 4 +- include/fennec/math/swizzle_storage.h | 26 +- include/fennec/math/vector.h | 34 +- include/fennec/math/vector_base.h | 43 +-- include/fennec/math/vector_storage.h | 27 +- include/fennec/memory/allocator.h | 78 ++-- include/fennec/memory/bytes.h | 8 +- include/fennec/memory/pointers.h | 19 +- .../platform/interface/display_server.h | 6 +- include/fennec/rtti/singleton.h | 2 +- include/fennec/rtti/type.h | 8 +- include/fennec/scene/component.h | 4 + include/fennec/scene/scene.h | 16 +- include/fennec/string/cstring.h | 16 +- include/fennec/string/string.h | 70 ++-- include/fennec/string/wcstring.h | 16 +- include/fennec/string/wstring.h | 70 ++-- include/fennec/threading/atomic.h | 92 ++--- source/scene/scene.cpp | 20 +- 57 files changed, 2007 insertions(+), 805 deletions(-) diff --git a/doxy/Doxyfile.in b/doxy/Doxyfile.in index b0d91a6..f095f1d 100644 --- a/doxy/Doxyfile.in +++ b/doxy/Doxyfile.in @@ -260,7 +260,7 @@ INHERIT_DOCS = YES # of the file/class/namespace that contains it. # The default value is: NO. -SEPARATE_MEMBER_PAGES = NO +SEPARATE_MEMBER_PAGES = YES # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. @@ -944,7 +944,6 @@ WARN_LOGFILE = # Note: If this tag is empty the current directory is searched. INPUT = "@PROJECT_SOURCE_DIR@/include" \ - "@PROJECT_SOURCE_DIR@/source" \ "@PROJECT_SOURCE_DIR@/README.md" # This tag can be used to specify the character encoding of the source files @@ -1050,6 +1049,7 @@ RECURSIVE = YES # run. EXCLUDE = "@PROJECT_SOURCE_DIR@/include/fennec/platform/linux/wayland/lib" \ + "@PROJECT_SOURCE_DIR@/include/fennec/platform/linux/wayland/libdecor" \ "@PROJECT_SOURCE_DIR@/include/fennec/platform/linux/xkb/lib" # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or @@ -2511,7 +2511,7 @@ EXTERNAL_PAGES = YES # and usage relations if the target is undocumented or is not a class. # The default value is: YES. -HIDE_UNDOC_RELATIONS = YES +HIDE_UNDOC_RELATIONS = NO # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: diff --git a/include/fennec/containers/array.h b/include/fennec/containers/array.h index 3069368..6125e15 100644 --- a/include/fennec/containers/array.h +++ b/include/fennec/containers/array.h @@ -44,17 +44,17 @@ namespace fennec /// \brief Data Structure that defines a compile-time allocated array /// /// \details -/// | Property | Value | -/// |:----------:|:----------:| +/// | Property | Value | +/// |:----------:|:-----------:| /// | stable | ✅ | /// | dynamic | ⛔ | /// | homogenous | ✅ | /// | distinct | ⛔ | /// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | +/// | space | \f$O(N)\f$ | /// | linear | ✅ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(N)\f$ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(N)\f$ | /// | insertion | ⛔ | /// | deletion | ⛔ | /// @@ -65,7 +65,7 @@ struct array { // Definitions ========================================================================================================= public: - using value_t = ValueT; ///< Alias for `ValueT` + using value_t = ValueT; ///< Alias for \f$ValueT\f$ // Public Members ====================================================================================================== @@ -105,7 +105,15 @@ public: /// @{ /// - /// \copydetails array::operator[](size_t) const + /// \details Returns a reference to the element at \c i + /// \param i index of the element to return + /// \return reference to the requested element + /// + /// \par Time-Complexity + /// Constant + /// + /// \par Space-Complexity + /// Constant constexpr value_t& operator[](size_t i) { assertd(i < ElemV, "Array Out of Bounds"); return data[i]; @@ -219,7 +227,7 @@ public: private: template static bool _compare(const array& lhs, const array& rhs, index_metasequence) { - return ((lhs[i] == rhs[i]) && ...); + return ((lhs[i] == rhs[i]) and ...); } }; diff --git a/include/fennec/containers/bintree.h b/include/fennec/containers/bintree.h index 2476b2d..5269b5c 100644 --- a/include/fennec/containers/bintree.h +++ b/include/fennec/containers/bintree.h @@ -48,18 +48,18 @@ template> struct bintree { // Definitions ========================================================================================================= -protected: +private: struct node; public: - using value_t = TypeT; - using alloc_t = allocator_traits::template rebind; - static constexpr size_t npos = -1; + using value_t = TypeT; //!< The element type + using alloc_t = allocator_traits::template rebind; //!< The allocator type + static constexpr size_t npos = -1; //!< null position constant friend class iterator; friend class const_iterator; -protected: +private: struct node { value_t value; size_t parent; @@ -144,7 +144,7 @@ public: } /// - /// \returns `true` when there are no elements in the tree, `false` otherwise. + /// \returns \f$true\f$ when there are no elements in the tree, \f$false\f$ otherwise. constexpr bool empty() const { return _size == 0; } @@ -156,7 +156,7 @@ public: } /// - /// \returns The next id to be returned by `insert` or `emplace`. + /// \returns The next id to be returned by \f$insert\f$ or \f$emplace\f$. constexpr size_t next_id() const { size_t i = _size; if (not _freed.empty()) { @@ -166,7 +166,7 @@ public: } /// - /// \returns The next id to be returned by `insert` or `emplace`. + /// \returns The next id to be returned by \f$insert\f$ or \f$emplace\f$. constexpr size_t root() const { return _root; } @@ -182,7 +182,7 @@ public: /// /// \details \f$O(1)\f$ /// \param i The node id - /// \returns The parent of node `i` + /// \returns The parent of node \f$i\f$ constexpr size_t parent(size_t i) const { return i == npos ? npos : _table[i].parent; } @@ -190,7 +190,7 @@ public: /// /// \details \f$O(1)\f$ /// \param i The node id - /// \returns The grandparent of node `i` + /// \returns The grandparent of node \f$i\f$ constexpr size_t grandparent(size_t i) const { return parent(parent(i)); } @@ -198,7 +198,7 @@ public: /// /// \details \f$O(1)\f$ /// \param i The node id - /// \returns The left child of node `i` + /// \returns The left child of node \f$i\f$ constexpr size_t left(size_t i) const { return i == npos ? npos : _table[i].child[false]; } @@ -206,7 +206,7 @@ public: /// /// \details \f$O(1)\f$ /// \param i The node id - /// \returns The right child of node `i` + /// \returns The right child of node \f$i\f$ constexpr size_t right(size_t i) const { return i == npos ? npos : _table[i].child[true]; } @@ -214,8 +214,8 @@ public: /// /// \details \f$O(1)\f$ /// \param i The node id - /// \param dir The direction to go `true` for right, `false` for left - /// \returns The child in the direction specified by `dir` + /// \param dir The direction to go \f$true\f$ for right, \f$false\f$ for left + /// \returns The child in the direction specified by \f$dir\f$ constexpr size_t child(size_t i, bool dir) const { return i == npos ? npos : _table[i].child[dir]; } @@ -223,7 +223,7 @@ public: /// /// \details \f$O(1)\f$ /// \param i The node id - /// \returns `true` if `i` is the right node of `parent(i)`, `false` otherwise + /// \returns \f$true\f$ if \f$i\f$ is the right node of `parent(i)`, \f$false\f$ otherwise constexpr bool direction(size_t i) const { return i == npos ? false : i == right(_parent(i)); } @@ -231,7 +231,7 @@ public: /// /// \brief \f$O(1)\f$ /// \param i The id of the node - /// \returns The id of the sibling of `i` + /// \returns The id of the sibling of \f$i\f$ constexpr size_t sibling(size_t i) const { if (i == npos) { return npos; @@ -247,7 +247,7 @@ public: /// /// \details \f$O(\log n)\f$ /// \param i The node id - /// \returns The depth of node `i` + /// \returns The depth of node \f$i\f$ constexpr size_t depth(size_t i) const { size_t d = 0; while (i != npos) { @@ -260,7 +260,7 @@ public: /// /// \brief \f$O(\log n)\f$ /// \param i The node id - /// \returns The id of the left-most node of `i` + /// \returns The id of the left-most node of \f$i\f$ constexpr size_t left_most(size_t i) const { if (i >= _table.size()) { return npos; @@ -274,7 +274,7 @@ public: /// /// \brief \f$O(\log n)\f$ /// \param i The node id - /// \returns The id of the right-most node of `i` + /// \returns The id of the right-most node of \f$i\f$ constexpr size_t right_most(size_t i) const { if (i >= _table.size()) { return npos; @@ -297,7 +297,7 @@ public: /// /// \details \f$O(1)\f$ /// \param i The node id - /// \returns `nullptr` if node `i` does not exist, otherwise, a pointer to the value of node `i` + /// \returns \f$nullptr\f$ if node \f$i\f$ does not exist, otherwise, a pointer to the value of node \f$i\f$ constexpr value_t& operator[](size_t i) { assertd(i < _table.size(), "Index out of bounds."); return _table[i].value; @@ -306,7 +306,7 @@ public: /// /// \details Const Access, \f$O(1)\f$ /// \param i The node id - /// \returns `nullptr` if node `i` does not exist, otherwise, a pointer to the value of node `i` + /// \returns \f$nullptr\f$ if node \f$i\f$ does not exist, otherwise, a pointer to the value of node \f$i\f$ constexpr const value_t& operator[](size_t i) const { assertd(i < _table.size(), "Index out of bounds."); return _table[i].value; @@ -320,8 +320,8 @@ public: /// @{ /// - /// \brief Move Left Insertion, constructs a new node as the left child of `p` - /// \details If the left node of `p` already exists, the move assignment operator is used instead + /// \brief Move Left Insertion, constructs a new node as the left child of \f$p\f$ + /// \details If the left node of \f$p\f$ already exists, the move assignment operator is used instead /// \param p The parent node /// \param val The object to move into the new node /// \returns The id of the new node @@ -330,8 +330,8 @@ public: } /// - /// \brief Copy Left Insertion, constructs a new node as the left child of `p` - /// \details If the left node of `p` already exists, the copy assignment operator is used instead + /// \brief Copy Left Insertion, constructs a new node as the left child of \f$p\f$ + /// \details If the left node of \f$p\f$ already exists, the copy assignment operator is used instead /// \param p The parent node /// \param val The object to copy to the new node /// \returns The id of the new node @@ -340,8 +340,8 @@ public: } /// - /// \brief Emplace Left Insertion, constructs a new node as the left child of `p` - /// \details If the left node of `p` already exists, the move assignment operator is used instead + /// \brief Emplace Left Insertion, constructs a new node as the left child of \f$p\f$ + /// \details If the left node of \f$p\f$ already exists, the move assignment operator is used instead /// \param p The parent node /// \param args The arguments to construct the new node with /// \returns The id of the new node @@ -351,8 +351,8 @@ public: } /// - /// \brief Move Right Insertion, constructs a new node as the right child of `p` - /// \details If the right node of `p` already exists, the move assignment operator is used instead + /// \brief Move Right Insertion, constructs a new node as the right child of \f$p\f$ + /// \details If the right node of \f$p\f$ already exists, the move assignment operator is used instead /// \param p The parent node /// \param val The object to move into the new node /// \returns The id of the new node @@ -361,8 +361,8 @@ public: } /// - /// \brief Copy Right Insertion, constructs a new node as the right child of `p` - /// \details If the right node of `p` already exists, the copy assignment operator is used instead + /// \brief Copy Right Insertion, constructs a new node as the right child of \f$p\f$ + /// \details If the right node of \f$p\f$ already exists, the copy assignment operator is used instead /// \param p The parent node /// \param val The object to copy to the new node /// \returns The id of the new node @@ -371,8 +371,8 @@ public: } /// - /// \brief Emplace Right Insertion, constructs a new node as the right child of `p` - /// \details If the right node of `p` already exists, the move assignment operator is used instead + /// \brief Emplace Right Insertion, constructs a new node as the right child of \f$p\f$ + /// \details If the right node of \f$p\f$ already exists, the move assignment operator is used instead /// \param p The parent node /// \param args The arguments to construct the new node with /// \returns The id of the new node @@ -384,9 +384,9 @@ public: /// - /// \brief Perform a Tree Rotation at `i` in the specified direction + /// \brief Perform a Tree Rotation at \f$i\f$ in the specified direction /// \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, \f$true\f$ for right, \f$false\f$ for left /// \returns the new root constexpr size_t rotate(size_t sub, bool dir) { if (sub == npos) { @@ -413,8 +413,8 @@ public: } /// - /// \brief Move Insertion, bool d, constructs a new node as the child of `p` - /// \details If the child of `p` already exists, the move assignment operator is used instead + /// \brief Move Insertion, bool d, constructs a new node as the child of \f$p\f$ + /// \details If the child of \f$p\f$ already exists, the move assignment operator is used instead /// \param p The parent node /// \param d The direction to insert /// \param val The object to move into the new node @@ -424,8 +424,8 @@ public: } /// - /// \brief Copy Insertion, bool d, constructs a new node as the child of `p` - /// \details If the child of `p` already exists, the copy assignment operator is used instead + /// \brief Copy Insertion, bool d, constructs a new node as the child of \f$p\f$ + /// \details If the child of \f$p\f$ already exists, the copy assignment operator is used instead /// \param p The parent node /// \param d The direction to insert /// \param val The object to copy to the new node @@ -435,8 +435,8 @@ public: } /// - /// \brief Emplace Insertion, constructs a new node as the child of `p` - /// \details If the child of `p` already exists, the move assignment operator is used instead + /// \brief Emplace Insertion, constructs a new node as the child of \f$p\f$ + /// \details If the child of \f$p\f$ already exists, the move assignment operator is used instead /// \param p The parent node /// \param d The direction to insert /// \param args The arguments to construct the new node with @@ -482,7 +482,7 @@ public: /// \brief Traverse the tree using a specified order and visiting functor /// /// \details - /// The visitor should accept a reference to a value of type `TypeT` and a `size_t` which contains the node's id. + /// The visitor should accept a reference to a value of type \f$TypeT\f$ and a `size_t` which contains the node's id. /// The visitor should return one of the following values in the `fennec::traversal_control_` enum /// /// \tparam OrderT The order with which to traverse the tree. @@ -508,13 +508,21 @@ public: /// /// \brief Traverser pattern for breadth-first traversal struct breadth_first { - list visit; - size_t head; + /// + /// \brief Traversal Init + /// \param start The node in the tree to start at + /// \returns The first index of the specified order size_t operator()(const bintree&, size_t start) { return head = start; } + /// + /// \brief Traverser Step + /// \param tree The tree we are operating on + /// \param node The current node + /// \param mode The mode specifying branch conditions + /// \returns The next index according to the traversal order size_t operator[](const bintree& tree, size_t node, uint8_t mode) { if (node == npos) { return npos; @@ -541,19 +549,31 @@ public: return node; } + + private: + list visit; + size_t head; }; /// /// \brief Traverser pattern for pre-order traversal struct pre_order { - list visit; - size_t head; + /// + /// \brief Traversal Init + /// \param start The node in the tree to start at + /// \returns The first index of the specified order constexpr size_t operator()(const bintree&, size_t start) { head = start; return start; } + /// + /// \brief Traverser Step + /// \param tree The tree we are operating on + /// \param node The current node + /// \param mode The mode specifying branch conditions + /// \returns The next index according to the traversal order constexpr size_t operator[](const bintree& tree, size_t node, uint8_t mode) { if (node == npos) { return npos; @@ -580,19 +600,31 @@ public: return node; } + + private: + list visit; + size_t head; }; /// /// \brief Traverser pattern for in-order traversal struct in_order { - list visit; - size_t head; + /// + /// \brief Traversal Init + /// \param tree The tree we are operating on + /// \param start The node in the tree to start at + /// \returns The first index of the specified order constexpr size_t operator()(const bintree& tree, size_t start) { head = start; return tree.left_most(start); } + /// + /// \brief Traverser Step + /// \param tree The tree we are operating on + /// \param node The current node + /// \returns The next index according to the traversal order constexpr size_t operator[](const bintree& tree, size_t node, uint8_t) { if (node == npos) { return npos; @@ -619,33 +651,31 @@ public: return node; } + + private: + list visit; + size_t head; }; /// /// \brief Traverser pattern for post-order traversal struct post_order { - list visit; - size_t head; - - constexpr size_t successor(const bintree& tree, size_t n) { - size_t s = tree.left_most(n); - while (n == s) { - size_t r = tree.right(n); - if (r != npos) { - n = r; - s = tree.left_most(n); - } else { - break; - } - } - return s == npos ? n : s; - } + /// + /// \brief Traversal Init + /// \param tree The tree we are operating on + /// \param start The node in the tree to start at + /// \returns The first index of the specified order constexpr size_t operator()(const bintree& tree, size_t start) { head = start; - return this->successor(tree, start); + return this->_successor(tree, start); } + /// + /// \brief Traverser Step + /// \param tree The tree we are operating on + /// \param node The current node + /// \returns The next index according to the traversal order constexpr size_t operator[](const bintree& tree, size_t node, uint8_t) { if (node == npos) { return npos; @@ -659,7 +689,7 @@ public: visit.push_front(parent); } } else if (pright != npos) { - visit.push_front(this->successor(tree, pright)); + visit.push_front(this->_successor(tree, pright)); } if (not visit.empty()) { @@ -672,23 +702,50 @@ public: return node; } + + private: + list visit; + size_t head; + + constexpr size_t _successor(const bintree& tree, size_t n) { + size_t s = tree.left_most(n); + while (n == s) { + size_t r = tree.right(n); + if (r != npos) { + n = r; + s = tree.left_most(n); + } else { + break; + } + } + return s == npos ? n : s; + } }; // Iterator ============================================================================================================ + + /// + /// \brief C++ Iterator Specification `iterator` + /// \details Performs pre-order traversal class iterator { - protected: - bintree* _tree; - in_order _order; - size_t _n; public: + /// + /// \brief bintree iterator constructor + /// \param tree A reference to the tree + /// \param root The root node for iteration constexpr iterator(bintree* tree, size_t root) : _tree(tree) , _order() , _n(_order(*tree, root)) { } + /// + /// \brief bintree iterator constructor + /// \param tree A reference to the tree + /// \param root The root node for iteration + /// \param node The node to jump to constexpr iterator(bintree* tree, size_t root, size_t node) : _tree(tree) , _order() @@ -696,42 +753,171 @@ public: _order.head = root; } + /// + /// \returns The index of the current node size_t index() const { return _n; } + /// + /// \brief iterator pre-increment operator + /// \returns A reference to self after having stepped to the next node iterator& operator++() { return _n = _order[*_tree, _n, traversal_control_continue], *this; } + /// + /// \brief dereference operator + /// \returns the value held in the current node value_t& operator*() { return (*_tree)[_n]; } - value_t* operator->() { - return &(*_tree)[_n]; - } - + /// + /// \returns the value held in the current node const value_t& operator*() const { return (*_tree)[_n]; } + /// + /// \brief pointer access operator + /// \returns a reference to the value held in the current node + value_t* operator->() { + return &(*_tree)[_n]; + } + + /// + /// \returns a reference to the value held in the current node const value_t* operator->() const { return &(*_tree)[_n]; } + /// + /// \brief iterator equality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if iterators are identical, \f$false\f$ otherwise constexpr bool operator==(const iterator& it) { return _tree == it._tree and _n == it._n; } + /// + /// \brief iterator inequality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if iterators are different, \f$false\f$ otherwise constexpr bool operator!=(const iterator& it) { return _tree != it._tree or _n != it._n; } + private: + bintree* _tree; + in_order _order; + size_t _n; }; + + /// + /// \brief C++ Iterator Specification `iterator` + /// \details Performs pre-order traversal + class const_iterator { + + public: + /// + /// \brief bintree iterator constructor + /// \param tree A reference to the tree + /// \param root The root node for iteration + constexpr const_iterator(bintree* tree, size_t root) + : _tree(tree) + , _order() + , _n(_order(*tree, root)) { + } + + /// + /// \brief bintree iterator constructor + /// \param tree A reference to the tree + /// \param root The root node for iteration + /// \param node The node to jump to + constexpr const_iterator(bintree* tree, size_t root, size_t node) + : _tree(tree) + , _order() + , _n(node) { + _order.head = root; + } + + /// + /// \returns The index of the current node + size_t index() const { + return _n; + } + + /// + /// \brief iterator pre-increment operator + /// \returns A reference to self after having stepped to the next node + const_iterator& operator++() { + return _n = _order[*_tree, _n, traversal_control_continue], *this; + } + + /// + /// \returns the value held in the current node + const value_t& operator*() const { + return (*_tree)[_n]; + } + + /// + /// \returns a reference to the value held in the current node + const value_t* operator->() const { + return &(*_tree)[_n]; + } + + /// + /// \brief iterator equality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if iterators are identical, \f$false\f$ otherwise + constexpr bool operator==(const iterator& it) { + return _tree == it._tree and _n == it._n; + } + + /// + /// \brief iterator inequality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if iterators are different, \f$false\f$ otherwise + constexpr bool operator!=(const iterator& it) { + return _tree != it._tree or _n != it._n; + } + + private: + bintree* _tree; + in_order _order; + size_t _n; + }; + + /// + /// \returns an iterator at the first element in pre-order traversal + iterator begin() { + return iterator(this, _root); + } + + /// + /// \brief C++ Iterator Specification `begin()` + /// \returns an iterator at the first element in pre-order traversal + const_iterator begin() const { + return iterator(this, _root); + } + + /// + /// \returns an iterator at the first element in pre-order traversal + iterator end() { + return iterator(this, _root, nullid); + } + + /// + /// \brief C++ Iterator Specification `begin()` + /// \returns an iterator at the first element in pre-order traversal + const_iterator end() const { + return iterator(this, _root, nullid); + } + // Fields ============================================================================================================== -protected: +private: table_t _table; freed_t _freed; size_t _root, _size; diff --git a/include/fennec/containers/bitfield.h b/include/fennec/containers/bitfield.h index 104a2ef..3e5ae25 100644 --- a/include/fennec/containers/bitfield.h +++ b/include/fennec/containers/bitfield.h @@ -43,14 +43,24 @@ namespace fennec /// \tparam N The number of bits in the bitfield template struct bitfield { - static constexpr size_t bits = N; - static constexpr size_t bytes = (N + 7) / 8; +// Constants =========================================================================================================== public: + static constexpr size_t bits = N; //!< The number of bits in the bitfield + static constexpr size_t bytes = (N + 7) / 8; //!< The number of bytes that hold the bitfield + + +// Constructors ======================================================================================================== +public: + /// + /// \brief default constructor, initializes with \f$0\f$ constexpr bitfield() : _bytes() { } + /// + /// \brief boolean array constructor + /// \param arr An array of boolean values resembling each bit. explicit constexpr bitfield(const bool (&arr)[N]) : _bytes() { for (size_t i = 0; i < arr; ++i) { @@ -58,6 +68,9 @@ public: } } + /// + /// \brief index array constructor + /// \param arr An array of indices values resembling which bits to set. template explicit constexpr bitfield(const size_t (&arr)[I]) : _bytes() { @@ -66,12 +79,17 @@ public: } } + /// + /// \brief variadic array constructor + /// \param args A set of indices values resembling which bits to set. template constexpr bitfield(ArgsT&&...args) : _bytes() { (this->store(fennec::forward(args), true), ...); } + /// + /// \param args A set of boolean values resembling each bit. template requires((is_bool_v or is_convertible_v) and ...) constexpr bitfield(ArgsT&&...args) : _bytes() { @@ -79,19 +97,40 @@ public: (this->store(i++, fennec::forward(args)), ...); } + /// + /// \brief copy constructor + /// \param bf bitfield to copy bitfield(const bitfield& bf) : _bytes(bf._bytes) { } + /// + /// \brief move constructor + /// \param bf bitfield to move bitfield(bitfield&& bf) noexcept : _bytes(bf._bytes) { } + /// + /// \brief destructor constexpr ~bitfield() = default; + /// + /// \brief copy assignment + /// \param bf bitfield to copy + /// \returns a reference to self bitfield& operator=(const bitfield& bf) = default; + + /// + /// \brief move assignment + /// \param bf bitfield to move + /// \returns a reference to self bitfield& operator=(bitfield&& bf) noexcept = default; + /// + /// \brief test a bit + /// \param i the index of the bit + /// \returns the value stored in the bit as a boolean bool test(size_t i) const { assertd(i < bits, "Index out of Bounds!"); size_t b = i / 8; @@ -99,6 +138,9 @@ public: return _bytes[b] & (1 << o); } + /// + /// \brief set a bit + /// \param i the index of the bit void set(size_t i) { assertd(i < bits, "Index out of Bounds!"); size_t b = i / 8; @@ -106,6 +148,9 @@ public: _bytes[b] |= (1 << o); } + /// + /// \brief clear a bit + /// \param i the index of the bit void clear(size_t i) { assertd(i < bits, "Index out of Bounds!"); size_t b = i / 8; @@ -113,6 +158,9 @@ public: _bytes[b] &= ~(1 << o); } + /// + /// \brief toggle a bit + /// \param i the index of the bit void toggle(size_t i) { assertd(i < bits, "Index out of Bounds!"); size_t b = i / 8; @@ -120,6 +168,10 @@ public: _bytes[b] ^= (1 << o); } + /// + /// \brief store \f$v\f$ in bit \f$i\f$ + /// \param i + /// \param v void store(size_t i, bool v) { assertd(i < bits, "Index out of Bounds!"); size_t b = i / 8; @@ -127,6 +179,9 @@ public: (_bytes[b] &= ~((1 << o))) |= ((v << o)); } + /// + /// \brief not operator + /// \returns a bitfield containing the bit-wise inverse bitfield operator~() const { bitfield res = *this; res._inv_helper(make_index_metasequence_t{}); diff --git a/include/fennec/containers/deque.h b/include/fennec/containers/deque.h index 79ff1fa..0d02495 100644 --- a/include/fennec/containers/deque.h +++ b/include/fennec/containers/deque.h @@ -84,8 +84,8 @@ private: }; public: - using alloc_t = allocator_traits::template rebind; - using elem_t = node*; + using alloc_t = allocator_traits::template rebind; //!< The underlying allocator type + using elem_t = node*; //!< The underlying element type // Constructors ======================================================================================================== @@ -153,7 +153,7 @@ public: /// @{ /// - /// \returns `true` when the deque is empty, `false` otherwise + /// \returns \f$true\f$ when the deque is empty, \f$false\f$ otherwise constexpr bool empty() const { return _size == 0; } diff --git a/include/fennec/containers/dynarray.h b/include/fennec/containers/dynarray.h index c031bcc..9ef8057 100644 --- a/include/fennec/containers/dynarray.h +++ b/include/fennec/containers/dynarray.h @@ -101,7 +101,7 @@ public: } /// - /// \brief Sized Allocation, initializes a dynarray with `n` elements using the default constructor. + /// \brief Sized Allocation, initializes a dynarray with \f$n\f$ elements using the default constructor. /// \param n The number of elements. explicit constexpr dynarray(size_t n) : _alloc(n) @@ -114,7 +114,7 @@ public: } /// - /// \brief Sized Allocation Alloc Constructor, initializes a dynarray with allocator `alloc` and `n` elements + /// \brief Sized Allocation Alloc Constructor, initializes a dynarray with allocator \f$alloc\f$ and \f$n\f$ elements /// using the default constructor. /// \param n The number of elements /// \param alloc The allocator object to copy @@ -128,7 +128,7 @@ public: } /// - /// \brief Sized Allocation Alloc Move Constructor, initializes a dynarray with allocator `alloc` and `n` elements + /// \brief Sized Allocation Alloc Move Constructor, initializes a dynarray with allocator \f$alloc\f$ and \f$n\f$ elements /// using the default constructor. /// \param n The number of elements /// \param alloc The allocator object to copy @@ -142,7 +142,7 @@ public: } /// - /// \brief Sized Allocation Copy Constructor, Create an allocation of size `n` elements, with each element + /// \brief Sized Allocation Copy Constructor, Create an allocation of size \f$n\f$ elements, with each element /// constructed using the copy constructor /// \param n the number of elements /// \param val the value to copy @@ -267,7 +267,7 @@ public: /// /// \brief Copy Assignment Operator /// \param arr the array to copy - /// \returns A dynarray after having copied each element of `arr` + /// \returns A dynarray after having copied each element of \f$arr\f$ constexpr dynarray& operator=(const dynarray& arr) { this->clear(); _alloc.creallocate(_size = arr._size); @@ -280,7 +280,7 @@ public: /// /// \brief Move Assignment Operator /// \param arr the array to move - /// \returns A dynarray after having taken ownership of the contents of `arr` + /// \returns A dynarray after having taken ownership of the contents of \f$arr\f$ constexpr dynarray& operator=(dynarray&& arr) noexcept { this->clear(); _alloc = fennec::move(arr._alloc); @@ -293,7 +293,7 @@ public: /// \brief Array Copy Assignment Operator /// \tparam N the length of the array /// \param arr the array to copy - /// \returns A dynarray after having copied each element of `arr` + /// \returns A dynarray after having copied each element of \f$arr\f$ template constexpr dynarray& operator=(const TypeT (&arr)[N]) { this->clear(); @@ -308,7 +308,7 @@ public: /// \brief Array Copy Assignment Operator /// \tparam N the length of the array /// \param arr the array to copy - /// \returns A dynarray after having moved each element of `arr` + /// \returns A dynarray after having moved each element of \f$arr\f$ template constexpr dynarray& operator=(TypeT (&&arr)[N]) { this->clear(); @@ -355,7 +355,7 @@ public: /// /// \brief Array Access Operator /// \param i The index to access - /// \returns A reference to the element at index `i` + /// \returns A reference to the element at index \f$i\f$ constexpr TypeT& operator[](size_t i) { assertd(i < _size, "Array Out of Bounds"); return _alloc.data()[i]; @@ -364,7 +364,7 @@ public: /// /// \brief Array Access Operator (const) /// \param i The index to access - /// \returns A const qualified reference to the element at index `i` + /// \returns A const qualified reference to the element at index \f$i\f$ constexpr const TypeT& operator[](size_t i) const { assertd(i < _size, "Array Out of Bounds"); return _alloc.data()[i]; @@ -547,22 +547,21 @@ public: /// @{ /// - /// \brief "Iterator" Begin Function /// \returns A pointer to the first element in the dynarray constexpr TypeT* begin() { return _alloc.data(); } /// - /// \brief "Iterator" End Function + /// \brief C++ Iterator Specification `begin()` + /// \returns A const qualified pointer to the first element in the dynarray + constexpr const TypeT* begin() const { return _alloc; } + + + /// /// \return A pointer to the address after the last element in the dynarray constexpr TypeT* end() { return begin() + _size; } /// - /// \brief Const "Iterator" Begin Function - /// \returns A const qualified pointer to the first element in the dynarray - constexpr const TypeT* begin() const { return _alloc; } - - /// - /// \brief Const "Iterator" End Function + /// \brief C++ Iterator Specification `end()` /// \return A const qualified pointer to the address after the last element in the dynarray constexpr const TypeT* end() const { return begin() + _size; } diff --git a/include/fennec/containers/generic.h b/include/fennec/containers/generic.h index e5abb08..50261a4 100644 --- a/include/fennec/containers/generic.h +++ b/include/fennec/containers/generic.h @@ -115,10 +115,15 @@ public: // Properties ========================================================================================================== + /// + /// \brief runtime type acquisition + /// \returns a runtime type struct referencing the held type type type() const { return *static_cast(_manage(op_type, nullptr)); } + /// + /// \returns \f$true\f$ if there is a held value, \f$false\f$ otherwise bool has_value() const { return _handle != nullptr; } @@ -126,6 +131,10 @@ public: // Assignment ========================================================================================================== + /// + /// \brief copy assignment + /// \param gen the generic to copy + /// \returns a reference to self after copying the contents of \f$gen\f$ generic& operator=(const generic& gen) { if (this == &gen) { // self-assignment case return *this; @@ -137,14 +146,20 @@ public: return *this; } + /// + /// \brief move assignment + /// \param gen the generic to move + /// \returns a reference to self after swapping contents with \f$gen\f$ generic& operator=(generic&& gen) noexcept { swap(gen); return *this; } - -// Utility ============================================================================================================= - + /// + /// \brief value assignment + /// \tparam T the type of the value + /// \param x the value to assign + /// \returns a reference to self after having assigned \f$x\f$ template generic& operator=(T&& x) { reset(); @@ -153,6 +168,16 @@ public: return *this; } + +// Utility ============================================================================================================= + + /// + /// \brief emplace value + /// + /// \details constructs a new value of type \f$T\f$ using \f$args...\f$ + /// \tparam T the type to construct + /// \tparam ArgsT the argument types + /// \param args the argument values template void emplace(ArgsT&&...args) { reset(); @@ -160,6 +185,9 @@ public: _manage = _manage_impl; } + /// + /// \brief reset value + /// \details clears the held value using the appropriate destructor void reset() { if (_manage) { _handle = _manage(op_destroy, _handle); @@ -167,19 +195,32 @@ public: } } + /// + /// \brief C++ 11 Swap Specification + /// \param gen the generic to swap with void swap(generic& gen) noexcept { fennec::swap(_handle, gen._handle); fennec::swap(_manage, gen._manage); } - template - T& cast() { - return *static_cast(_handle); + /// + /// \brief cast value + /// + /// \details equivalent to `reinterpret_cast` + /// \tparam T The type to cast to + /// \returns The contents of generic after having cast to \f$T\f$ + template> + T cast() { + return static_cast(*static_cast(_handle)); } - template - const T& cast() const { - return *static_cast(_handle); + /// + /// \details equivalent to `reinterpret_cast` + /// \tparam T The type to cast to + /// \returns The contents of generic after having cast to \f$T\f$ + template> + T cast() const { + return static_cast(*static_cast(_handle)); } private: diff --git a/include/fennec/containers/graph.h b/include/fennec/containers/graph.h index 744ec65..aa3daac 100644 --- a/include/fennec/containers/graph.h +++ b/include/fennec/containers/graph.h @@ -79,10 +79,10 @@ namespace fennec /// A directed graph is weakly connected if replacing all of its directed edges with undirected edges would /// produce a connected graph. We will call this "disjointed" /// -/// A directed graph is semi-connected if there is a directed path p for `u` → `v` *or* `v` → `u` for every +/// A directed graph is semi-connected if there is a directed path p for \f$u\f$ → \f$v\f$ *or* \f$v\f$ → \f$u\f$ for every /// pair of vertices `u, v`. We will call this "unilateral" /// -/// A directed graph is strongly-connected if there is a directed path p for `u` → `v` *and* `v` → `u` for every pair +/// A directed graph is strongly-connected if there is a directed path p for \f$u\f$ → \f$v\f$ *and* \f$v\f$ → \f$u\f$ for every pair /// of vertices `u, v`. We will call this "connected" /// /// \tparam VertexT The type associated with each vertex @@ -159,35 +159,35 @@ public: } /// - /// \returns `true` when there are no vertices in the graph, `false` otherwise + /// \returns \f$true\f$ when there are no vertices in the graph, \f$false\f$ otherwise constexpr bool empty() const { return num_vertices() == 0; } /// - /// \brief Checks if there exists an edge `e` that starts from `a` and ends at `b` + /// \brief Checks if there exists an edge \f$e\f$ that starts from \f$a\f$ and ends at \f$b\f$ /// \param a The first vertex /// \param b The second vertex - /// \returns `true` if the edge exists, `false` otherwise + /// \returns \f$true\f$ if the edge exists, \f$false\f$ otherwise constexpr bool exists(size_t a, size_t b) const { return _edge_map[a][b] != nullptr; } /// - /// \brief Checks if there exists an edge `e0` that starts from `a` and ends at `b` and `e1` that starts from `b` - /// and ends at `a` + /// \brief Checks if there exists an edge \f$e0\f$ that starts from \f$a\f$ and ends at \f$b\f$ and \f$e1\f$ that starts from \f$b\f$ + /// and ends at \f$a\f$ /// \param a The first vertex /// \param b The second vertex - /// \returns `true` if both edges exist, `false` otherwise + /// \returns \f$true\f$ if both edges exist, \f$false\f$ otherwise constexpr bool is_symmetric(size_t a, size_t b) const { return exists(a, b) and exists(b, a); } /// - /// \brief Checks if there exists an edge `e` between `a` and `b` + /// \brief Checks if there exists an edge \f$e\f$ between \f$a\f$ and \f$b\f$ /// \param a The first vertex /// \param b The second vertex - /// \returns `true` if both edges exist, `false` otherwise + /// \returns \f$true\f$ if both edges exist, \f$false\f$ otherwise constexpr bool is_undirected(size_t a, size_t b) const { const auto* e0 = _edge_map[a][b]; const auto* e1 = _edge_map[b][a]; @@ -227,7 +227,7 @@ public: /// \brief edge Access Operator /// \param a The id of the first vertex /// \param b The id of the second vertex - /// \returns A pointer to the value stored in the edge, `nullptr` if not found + /// \returns A pointer to the value stored in the edge, \f$nullptr\f$ if not found constexpr edge_t* operator[](size_t a, size_t b) { if (empty()) { return nullptr; @@ -243,7 +243,7 @@ public: /// \brief edge Const Access Operator /// \param a The id of the first vertex /// \param b The id of the second vertex - /// \returns A const-qualified pointer to the value stored in the edge, `nullptr` if not found + /// \returns A const-qualified pointer to the value stored in the edge, \f$nullptr\f$ if not found constexpr const edge_t* operator[](size_t a, size_t b) const { if (empty()) { return nullptr; @@ -256,9 +256,9 @@ public: } /// - /// \brief Getter for a list of vertices `x` that `vertex` has an edge to `x...` + /// \brief Getter for a list of vertices \f$x\f$ that \f$vertex\f$ has an edge to `x...` /// \param vertex The id of the vertex - /// \returns A list containing all vertices `x` with edges from `vertex` to `x...` + /// \returns A list containing all vertices \f$x\f$ with edges from \f$vertex\f$ to `x...` list outgoing(size_t vertex) { list res; if (empty() || vertex >= _edge_map.size()) { @@ -271,9 +271,9 @@ public: } /// - /// \brief Getter for a list of vertices `x` that `vertex` has an edge from `x...` + /// \brief Getter for a list of vertices \f$x\f$ that \f$vertex\f$ has an edge from `x...` /// \param vertex The id of the vertex - /// \returns A list containing all vertices `x` with edges from `x...` to `vertex` + /// \returns A list containing all vertices \f$x\f$ with edges from `x...` to \f$vertex\f$ list incoming(size_t vertex) { list res; if (empty() || vertex >= _edge_map.size()) { @@ -288,9 +288,9 @@ public: } /// - /// \brief Getter for a list of vertices `x` that `vertex` has an edge to and from `x...` + /// \brief Getter for a list of vertices \f$x\f$ that \f$vertex\f$ has an edge to and from `x...` /// \param vertex The id of the vertex - /// \returns A list containing all vertices `x` that have symmetric edges with `vertex` + /// \returns A list containing all vertices \f$x\f$ that have symmetric edges with \f$vertex\f$ list symmetric(size_t vertex) { list res; if (empty() || vertex >= _edge_map.size()) { @@ -305,13 +305,13 @@ public: } /// - /// \brief Getter for a list of vertices `x` that `vertex` has an edge to and from `x...` and share the same value + /// \brief Getter for a list of vertices \f$x\f$ that \f$vertex\f$ has an edge to and from `x...` and share the same value /// \details /// "Joined" edges may also be referred to as "undirected." A joined, or undirected, edge may be /// turned into a directed edge by changing the weight object associated with the edge, or by /// removing one of the sub-edges. /// \param vertex The id of the vertex - /// \returns A list containing all vertices `x` that have symmetric edges with `vertex` + /// \returns A list containing all vertices \f$x\f$ that have symmetric edges with \f$vertex\f$ list undirected(size_t vertex) { list res; if (empty() || vertex >= _edge_map.size()) { @@ -381,7 +381,7 @@ public: } /// - /// \brief Form an edge from vertex `a` to vertex `b` + /// \brief Form an edge from vertex \f$a\f$ to vertex \f$b\f$ /// \tparam ArgsT The argument types /// \param a The first vertex id /// \param b The second vertex id @@ -408,7 +408,7 @@ public: } /// - /// \brief Form an undirected edge between vertex `a` and vertex `b` + /// \brief Form an undirected edge between vertex \f$a\f$ and vertex \f$b\f$ /// \tparam ArgsT The argument types /// \param a The first vertex id /// \param b The second vertex id @@ -437,7 +437,7 @@ public: } /// - /// \brief Disconnect an edge from vertex `a` to vertex `b` + /// \brief Disconnect an edge from vertex \f$a\f$ to vertex \f$b\f$ /// \param a The first vertex id /// \param b The second vertex id constexpr void cut_edge(size_t a, size_t b) { @@ -460,7 +460,7 @@ public: } /// - /// \brief Disconnect both directed edges between vertices `a` and `b` + /// \brief Disconnect both directed edges between vertices \f$a\f$ and \f$b\f$ /// \param a The first vertex id /// \param b The second vertex id constexpr void cut_edge2(size_t a, size_t b) { @@ -476,7 +476,7 @@ public: } /// - /// \brief Break *all* edges to and from `n` + /// \brief Break *all* edges to and from \f$n\f$ /// \param n The vertex id void cut(size_t n) { for (const auto it : outgoing(n)) { diff --git a/include/fennec/containers/initializer_list.h b/include/fennec/containers/initializer_list.h index 23c4365..38e9a5c 100644 --- a/include/fennec/containers/initializer_list.h +++ b/include/fennec/containers/initializer_list.h @@ -42,11 +42,17 @@ namespace fennec using std::initializer_list; +/// +/// \param inls the initializer list +/// \returns A const qualified pointer to the first element in \f$inls\f$ template constexpr const T* begin(initializer_list inls) noexcept { return inls.begin(); } +/// +/// \param inls the initializer list +/// \returns A const qualified pointer to one past the last element in \f$inls\f$ template constexpr const T* end(initializer_list inls) noexcept { return inls.end(); diff --git a/include/fennec/containers/list.h b/include/fennec/containers/list.h index f3740d3..1b39e50 100644 --- a/include/fennec/containers/list.h +++ b/include/fennec/containers/list.h @@ -95,7 +95,7 @@ public: } /// - /// \brief Copy Constructor, copies all elements in `l` with optimized layout + /// \brief Copy Constructor, copies all elements in \f$l\f$ with optimized layout /// \param l The list to copy constexpr list(const list& l) : list() { @@ -134,7 +134,7 @@ public: /// /// \brief Copy Assignment Operator /// \param l the list to copy - /// \returns `this` after having copied all elements of `l` + /// \returns \f$this\f$ after having copied all elements of \f$l\f$ constexpr list& operator=(const list& l) { this->clear(); for (const value_t& it : l) { @@ -146,7 +146,7 @@ public: /// /// \brief Move Assignment Operator /// \param l the list to copy - /// \returns `this` after having taken ownership over the contents of `l` + /// \returns \f$this\f$ after having taken ownership over the contents of \f$l\f$ constexpr list& operator=(list&& l) noexcept { this->clear(); _table = fennec::move(l._table); @@ -177,7 +177,7 @@ public: } /// - /// \returns `true` when the list is empty, `false` otherwise. + /// \returns \f$true\f$ when the list is empty, \f$false\f$ otherwise. constexpr bool empty() const { return _root == npos; } @@ -193,7 +193,7 @@ public: /// /// \brief Array Access Operator /// \param i Index to access - /// \returns A reference to the element at `i` + /// \returns A reference to the element at \f$i\f$ /// /// \details \f$O(N)\f$ constexpr value_t& operator[](int i) { @@ -206,7 +206,7 @@ public: /// /// \brief Const Array Access Operator /// \param i Index to access - /// \returns A const-qualified reference to the element at `i` + /// \returns A const-qualified reference to the element at \f$i\f$ /// /// \details \f$O(N)\f$ constexpr const value_t& operator[](int i) const { @@ -417,7 +417,6 @@ public: /// @{ /// - /// \brief C++ Iterator Specification `begin()` /// \returns An iterator for the first element in the list constexpr iterator begin() { return iterator(this, _root); @@ -431,7 +430,6 @@ public: } /// - /// \brief Const C++ Iterator Specification `begin()` /// \returns A const iterator for the first element in the list constexpr const_iterator begin() const { return const_iterator(this, _root); @@ -447,37 +445,60 @@ public: /// @} /// - /// \brief Iterator Class + /// \brief C++ Iterator Specification `iterator` class iterator { public: + /// + /// \brief destructor ~iterator() { _list = nullptr; } - // prefix operator + /// + /// \brief prefix increment operator + /// \param rhs the iterator to increment + /// \returns \f$rhs\f$ after having moved to the next element in the list constexpr friend iterator& operator++(iterator& rhs) { rhs._n = rhs._list->_next(rhs._n); return rhs; } + /// + /// \brief postfix increment operator + /// \param lhs the iterator to increment + /// \returns \f$lhs\f$ before having moved to the next element in the list constexpr friend iterator operator++(iterator& lhs, int) { iterator prev = lhs; ++lhs; return prev; } + /// + /// \brief dereference operator + /// \returns a reference to the value pointed by the iterator constexpr value_t& operator*() { return *(_list->_table[_n].value); } + /// + /// \brief pointer access operator + /// \returns a pointer to the value pointed by the iterator constexpr value_t* operator->() { return &*(_list->_table[_n].value); } + /// + /// \brief iterator equality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are identical, \f$false\f$ otherwise constexpr bool operator==(const iterator& it) { return _list == it._list and _n == it._n; } + /// + /// \brief iterator inequality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are different, \f$false\f$ otherwise constexpr bool operator!=(const iterator& it) { return _list != it._list or _n != it._n; } @@ -497,11 +518,16 @@ public: /// \brief Iterator Class for Const Access class const_iterator { public: + /// + /// \brief destructor ~const_iterator() { _list = nullptr; } - // prefix operator + /// + /// \brief prefix increment operator + /// \param rhs the iterator to increment + /// \returns \f$rhs\f$ after having moved to the next element in the list constexpr friend const_iterator& operator++(const_iterator& rhs) { if (rhs._list->_next(rhs._n) < rhs._list->capacity()) { return rhs; @@ -510,24 +536,42 @@ public: return rhs; } + /// + /// \brief postfix increment operator + /// \param lhs the iterator to increment + /// \returns \f$lhs\f$ before having moved to the next element in the list constexpr friend const_iterator operator++(const_iterator& lhs, int) { const_iterator prev = lhs; ++lhs; return prev; } + /// + /// \brief dereference operator + /// \returns a reference to the value pointed by the iterator constexpr const value_t& operator*() { return *(_list->_table[_n].value); } + /// + /// \brief pointer access operator + /// \returns a pointer to the value pointed by the iterator constexpr const value_t* operator->() { return &*(_list->_table[_n].value); } + /// + /// \brief iterator equality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are identical, \f$false\f$ otherwise constexpr bool operator==(const const_iterator& it) { return _list == it._list and _n == it._n; } + /// + /// \brief iterator inequality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are different, \f$false\f$ otherwise constexpr bool operator!=(const const_iterator& it) { return _list != it._list or _n != it._n; } diff --git a/include/fennec/containers/map.h b/include/fennec/containers/map.h index 362056b..0a4e4f8 100644 --- a/include/fennec/containers/map.h +++ b/include/fennec/containers/map.h @@ -56,7 +56,7 @@ namespace fennec */ /// -/// \brief Data Structure defining a mapping of `key` \f$KeyT\f$ to `value` \f$ValueT\f$ +/// \brief Data Structure defining a mapping of \f$key\f$ \f$KeyT\f$ to \f$value\f$ \f$ValueT\f$ /// \details /// | Property | Value | /// |:----------:|:----------:| @@ -91,15 +91,26 @@ public: using set_t = set; ///< The underlying set using iterator = set_t::iterator; ///< Iterator type - // We only want to hash the key + /// + /// \brief key hash helper struct key_hash : hash_t { + /// + /// \brief C++ 11 Hash Specification `operator()` + /// \param p the pair to hash + /// \returns the hash of the key constexpr size_t operator()(const elem_t& p) const { return hash_t::operator()(p.first); } }; - // We only want to compare the keys + /// + /// \brief key comparison helper struct key_equals : equality { + /// + /// \brief C++ 11 Compare Specification `operator()` + /// \param a the first pair + /// \param b the second pair + /// \returns \f$true\f$ if the keys are equal, \f$false\f$ otherwise constexpr bool operator()(const elem_t& a, const elem_t& b) const { return equality::operator()(a.first, b.first); } @@ -134,7 +145,7 @@ public: } /// - /// \returns `true` when there are no elements in the set, `false` otherwise + /// \returns \f$true\f$ when there are no elements in the set, \f$false\f$ otherwise constexpr size_t empty() const { return _set.size(); } @@ -156,7 +167,7 @@ public: /// /// \brief Key Access Operator /// \param key Key value to access - /// \returns A pointer to the value associated with `key`, `nullptr` if `key` is not present. + /// \returns A pointer to the value associated with \f$key\f$, \f$nullptr\f$ if \f$key\f$ is not present. constexpr value_t* operator[](const KeyT& key) { auto it = _set.at(this->_find(key)); return it ? &it->second : nullptr; @@ -165,7 +176,7 @@ public: /// /// \brief Key Const Access Operator /// \param key Key value to access - /// \returns A const-qualified pointer to the value associated with `key`, `nullptr` if `key` is not present. + /// \returns A const-qualified pointer to the value associated with \f$key\f$, \f$nullptr\f$ if \f$key\f$ is not present. constexpr const value_t* operator[](const KeyT& key) const { auto it = _set.at(this->_find(key)); return it ? &it->second : nullptr; @@ -175,7 +186,7 @@ public: /// \brief Argument Key Access Operator /// \tparam ArgsT Argument Types /// \param args Arguments to construct the key with - /// \returns A pointer to the value associated with `key`, `nullptr` if `key` is not present. + /// \returns A pointer to the value associated with \f$key\f$, \f$nullptr\f$ if \f$key\f$ is not present. template constexpr value_t* operator[](ArgsT&&...args) { auto it = _set.at(this->_find(fennec::forward(args)...)); @@ -186,7 +197,7 @@ public: /// \brief Argument Key Const Access Operator /// \tparam ArgsT Argument Type /// \param args Argument to construct the key with - /// \returns A const-qualified pointer to the value associated with `key`, `nullptr` if `key` is not present. + /// \returns A const-qualified pointer to the value associated with \f$key\f$, \f$nullptr\f$ if \f$key\f$ is not present. template constexpr const value_t* operator[](ArgsT&&...args) const { auto it = _set.at(this->_find(fennec::forward(args)...)); diff --git a/include/fennec/containers/object_pool.h b/include/fennec/containers/object_pool.h index 032bfc8..2ed3fb6 100644 --- a/include/fennec/containers/object_pool.h +++ b/include/fennec/containers/object_pool.h @@ -47,10 +47,10 @@ struct object_pool { // Definitions ========================================================================================================= public: - using value_t = TypeT; - using elem_t = optional; - using table_t = dynarray; - using freed_t = list; + using value_t = TypeT; //!< The held object type + using elem_t = optional; //!< The element type + using table_t = dynarray; //!< The underlying table type + using freed_t = list; //!< The underlying free queue class iterator; class const_iterator; @@ -92,13 +92,13 @@ public: } /// - /// \returns `true` when there are no objects in the pool, `false` otherwise + /// \returns \f$true\f$ when there are no objects in the pool, \f$false\f$ otherwise constexpr bool empty() const { return size() == 0; } /// - /// \brief Retrieve the next id `i` that would be assigned to an object `o` were it added to the object pool + /// \brief Retrieve the next id \f$i\f$ that would be assigned to an object \f$o\f$ were it added to the object pool /// /// \details This can be useful if there are constant members that need to be assigned at construction. /// \returns The id of the next inserted node @@ -120,7 +120,7 @@ public: /// /// \brief Array Access Operator /// \param i id of the object - /// \returns a reference to the object with id `i` + /// \returns a reference to the object with id \f$i\f$ constexpr value_t& operator[](size_t i) { assert(i < capacity(), "Index out of Bounds!"); assert(_table[i], "Attempted to access null object.") @@ -130,7 +130,7 @@ public: /// /// \brief Array Const Access Operator /// \param i id of the object - /// \returns a const-qualified reference to the object with id `i` + /// \returns a const-qualified reference to the object with id \f$i\f$ constexpr const value_t& operator[](size_t i) const { assert(i < capacity(), "Index out of Bounds!"); assert(_table[i], "Attempted to access null object.") @@ -146,7 +146,7 @@ public: /// @{ /// - /// \brief Move Insertion, inserts `x` into the pool + /// \brief Move Insertion, inserts \f$x\f$ into the pool /// \param x the object to move /// \returns An integer corresponding to the id of the node constexpr size_t insert(value_t&& x) { @@ -154,7 +154,7 @@ public: } /// - /// \brief Move Insertion, inserts a copy of `x` into the pool + /// \brief Move Insertion, inserts a copy of \f$x\f$ into the pool /// \param x the object to copy /// \returns An integer corresponding to the id of the node constexpr size_t insert(const value_t& x) { @@ -195,62 +195,108 @@ public: // Iterator ============================================================================================================ + /// + /// \returns an iterator at the start of the object pool iterator begin() { return iterator(this, 0); } - iterator end() { - return iterator(this, _size); - } - + /// + /// \brief C++ Iterator Specification `begin()` + /// \returns an iterator at the start of the object pool const_iterator begin() const { return iterator(this, 0); } + /// + /// \returns an iterator at the start of the end of the object pool + iterator end() { + return iterator(this, _size); + } + + /// + /// \brief C++ Iterator Specification `end()` + /// \returns an iterator at the start of the end of the object pool const_iterator end() const { return iterator(this, _size); } + /// + /// \brief C++ Iterator Specification `iterator` class iterator { public: - iterator(object_pool* pool, size_t start) - : pool(pool), curr(start) { - _fix(); - } + /// + /// \brief copy constructor + /// \param it the iterator to copy + iterator(const iterator& it) = default; - iterator(const iterator&) = default; - iterator(iterator&&) noexcept = default; + /// + /// \brief move constructor + /// \param it the iterator to move + iterator(iterator&& it) noexcept = default; + /// + /// \brief public destructor ~iterator() = default; - iterator& operator=(const iterator&) = default; - iterator& operator=(iterator&&) noexcept = default; - iterator operator++(int) { - iterator ret = *this; - ++curr; - _fix(); + /// + /// \brief copy assignment + /// \param it the iterator to copy + /// \returns a reference to self after having copied \f$it\f$ + iterator& operator=(const iterator& it) = default; + + /// + /// \brief move assignment + /// \param it the iterator to move + /// \returns a reference to self after having moved \f$it\f$ + iterator& operator=(iterator&& it) noexcept = default; + + /// + /// \brief postfix increment operator + /// \returns \f$it\f$ before having been incremented + friend iterator operator++(iterator& it, int) { + iterator ret = it; + ++it.curr; + it._fix(); return ret; } - iterator& operator++() { - ++curr; - _fix(); - return *this; + /// + /// \brief prefix increment operator + /// \returns \f$it\f$ after having moved to the next element + friend iterator& operator++(iterator& it) { + ++it.curr; + it._fix(); + return it; } + /// + /// \brief dereference operator + /// \returns a reference to the value pointed by the iterator value_t& operator*() const { return *pool->_table[curr]; } + /// + /// \brief pointer access operator + /// \returns a pointer to the value pointed by the iterator value_t* operator->() const { return *pool->_table[curr]; } + /// + /// \brief iterator equality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are identical, \f$false\f$ otherwise bool operator==(const iterator& it) { return pool == it.pool and curr == it.curr; } + /// + /// \brief iterator inequality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are different, \f$false\f$ otherwise bool operator!=(const iterator& it) { return pool != it.pool or curr != it.curr; } @@ -264,48 +310,91 @@ public: ++curr; } } - }; - class const_iterator { - public: - const_iterator(const object_pool* pool, size_t start) + iterator(object_pool* pool, size_t start) : pool(pool), curr(start) { _fix(); } - const_iterator(const const_iterator&) = default; - const_iterator(const_iterator&&) noexcept = default; + friend struct object_pool; + }; + /// + /// \brief C++ Iterator Specification `const_iterator` + class const_iterator { + public: + /// + /// \brief copy constructor + /// \param it the iterator to copy + const_iterator(const const_iterator&it ) = default; + + /// + /// \brief move constructor + /// \param it the iterator to move + const_iterator(const_iterator&& it) noexcept = default; + + /// + /// \brief public destructor ~const_iterator() = default; - const_iterator& operator=(const const_iterator&) = default; - const_iterator& operator=(const_iterator&&) noexcept = default; - const_iterator operator++(int) { - const_iterator ret = *this; - ++curr; - _fix(); + /// + /// \brief copy assignment + /// \param it the iterator to copy + /// \returns a reference to self after having copied \f$it\f$ + const_iterator& operator=(const const_iterator& it) = default; + + /// + /// \brief move assignment + /// \param it the iterator to move + /// \returns a reference to self after having moved \f$it\f$ + const_iterator& operator=(const_iterator&& it) noexcept = default; + + /// + /// \brief postfix increment operator + /// \returns \f$it\f$ before having been incremented + friend const_iterator operator++(const_iterator& it, int) { + const_iterator ret = it; + ++it.curr; + it._fix(); return ret; } - const_iterator& operator++() { - ++curr; - _fix(); - return *this; + /// + /// \brief prefix increment operator + /// \returns \f$it\f$ after having moved to the next element + friend const_iterator& operator++(const_iterator& it) { + ++it.curr; + it._fix(); + return it; } + /// + /// \brief dereference operator + /// \returns a reference to the value pointed by the iterator const value_t& operator*() const { return *pool->_table[curr]; } + /// + /// \brief pointer access operator + /// \returns a pointer to the value pointed by the iterator const value_t* operator->() const { return *pool->_table[curr]; } + /// + /// \brief iterator equality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are identical, \f$false\f$ otherwise bool operator==(const const_iterator& it) { return pool == it.pool and curr == it.curr; } + /// + /// \brief iterator inequality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are different, \f$false\f$ otherwise bool operator!=(const const_iterator& it) { return pool != it.pool or curr != it.curr; } @@ -319,6 +408,13 @@ public: ++curr; } } + + const_iterator(const object_pool* pool, size_t start) + : pool(pool), curr(start) { + _fix(); + } + + friend struct object_pool; }; private: diff --git a/include/fennec/containers/optional.h b/include/fennec/containers/optional.h index eb019ad..989e34d 100644 --- a/include/fennec/containers/optional.h +++ b/include/fennec/containers/optional.h @@ -38,10 +38,16 @@ namespace fennec { - +/// +/// \brief struct to represent a \f$null\f$ `optional` struct nullopt_t {}; + +/// +/// \brief value representing a \f$null\f$ `optional` constexpr nullopt_t nullopt_v = {}; +/// +/// \brief alias for representing a \f$null\f$ `optional` #define nullopt nullopt_v /// @@ -52,10 +58,10 @@ struct optional { // Definitions ========================================================================================================= public: - using reference_t = T&; - using pointer_t = T*; - using const_reference_t = T&; - using const_pointer_t = const T*; + using reference_t = T&; //!< reference type + using pointer_t = T*; //!< pointer type + using const_reference_t = T&; //!< const reference type + using const_pointer_t = const T*; //!< const pointer type // Constructors ======================================================================================================== @@ -116,12 +122,18 @@ public: opt = nullopt; } + /// + /// \brief Emplace Constructor + /// \tparam ArgsT The argument types + /// \param args The argument values template constexpr optional(ArgsT&&...args) : _val(fennec::forward(args)...) , _set(true) { } + /// + /// \brief destructor constexpr ~optional() { if constexpr(is_fundamental_v) { return; @@ -141,13 +153,13 @@ public: /// /// \brief Implicit Boolean Check - /// \returns `true` when there is a value contained + /// \returns \f$true\f$ when there is a value contained constexpr operator bool() const { return _set; } /// - /// \returns `true` when there is no held value, `false` otherwise. + /// \returns \f$true\f$ when there is no held value, \f$false\f$ otherwise. constexpr bool empty() const { return not _set; } @@ -249,13 +261,13 @@ public: /// @{ /// - /// \returns A pointer to the value, `nullptr` if there is no value + /// \returns A pointer to the value, \f$nullptr\f$ if there is no value constexpr pointer_t operator->() noexcept { return _set ? &_val : nullptr; } /// - /// \returns A const-qualified pointer to the value, `nullptr` if there is no value + /// \returns A const-qualified pointer to the value, \f$nullptr\f$ if there is no value constexpr const_pointer_t operator->() const noexcept { return _set ? &_val : nullptr; } diff --git a/include/fennec/containers/pair.h b/include/fennec/containers/pair.h index 98dc18f..67c6cdc 100644 --- a/include/fennec/containers/pair.h +++ b/include/fennec/containers/pair.h @@ -140,7 +140,7 @@ struct pair { /// /// \brief Equality Operator /// \param p Pair to compare with - /// \returns `true` when both elements of each pair are equal + /// \returns \f$true\f$ when both elements of each pair are equal constexpr bool operator==(const pair& p) const { return first == p.first and second == p.second; } @@ -148,7 +148,7 @@ struct pair { /// /// \brief Inequality Operator /// \param p Pair to compare with - /// \returns `true` when either element of each pair are equal + /// \returns \f$true\f$ when either element of each pair are equal constexpr bool operator!=(const pair& p) const { return first != p.first or second != p.second; } @@ -156,7 +156,7 @@ struct pair { /// /// \brief Less Than Operator /// \param p Pair to compare with - /// \returns lexical comparison of both elements, i.e. returns `true` when the first element is less, or they are + /// \returns lexical comparison of both elements, i.e. returns \f$true\f$ when the first element is less, or they are /// equal and the second element is less constexpr bool operator<(const pair& p) const { return first < p.first or (first == p.first and second < p.second); @@ -165,7 +165,7 @@ struct pair { /// /// \brief Less Equal Operator /// \param p Pair to compare with - /// \returns lexical comparison of both elements, i.e. returns `true` when the first element is less, or they are + /// \returns lexical comparison of both elements, i.e. returns \f$true\f$ when the first element is less, or they are /// equal and the second element is less or equal constexpr bool operator<=(const pair& p) const { return first < p.first or (first == p.first and second <= p.second); @@ -174,7 +174,7 @@ struct pair { /// /// \brief Greater Than Operator /// \param p Pair to compare with - /// \returns lexical comparison of both elements, i.e. returns `true` when the first element is greater, or they are + /// \returns lexical comparison of both elements, i.e. returns \f$true\f$ when the first element is greater, or they are /// equal and the second element is greater constexpr bool operator>(const pair& p) const { return first > p.first or (first == p.first and second > p.second); @@ -183,7 +183,7 @@ struct pair { /// /// \brief Greater Equal Operator /// \param p Pair to compare with - /// \returns lexical comparison of both elements, i.e. returns `true` when the first element is greater, or they are + /// \returns lexical comparison of both elements, i.e. returns \f$true\f$ when the first element is greater, or they are /// equal and the second element is greater or equal constexpr bool operator>=(const pair& p) const { return first > p.first or (first == p.first and second >= p.second); @@ -192,8 +192,16 @@ struct pair { /// @} }; +/// +/// \brief C++ 11 Hash Specification for `pair` +/// \tparam TypeT0 The first type of the pair +/// \tparam TypeT1 The second type of the pair template struct hash> : hash, hash { + /// + /// \brief C++ 11 Hash Specification `operator()` + /// \param p The pair to hash + /// \returns a pairing of the hashes of both elements of \f$p\f$ using `fennec::pair_hash` constexpr size_t operator()(const pair& p) const { return fennec::pair_hash( // pair the hashes of both elements hash::operator()(p.first), diff --git a/include/fennec/containers/priority_queue.h b/include/fennec/containers/priority_queue.h index bb64a51..3975eaf 100644 --- a/include/fennec/containers/priority_queue.h +++ b/include/fennec/containers/priority_queue.h @@ -53,16 +53,21 @@ namespace fennec { +/// +/// \brief a priority queue data structure implemented using a binary heap +/// \tparam ValueT The value type +/// \tparam CompareT The compare type, defaults to `fennec::less` +/// \tparam AllocT The allocator type, defaults to `fennec::allocator` template, class AllocT = allocator> struct priority_queue { // Definitions & Constants ============================================================================================= public: - using value_t = ValueT; - using compare_t = CompareT; - using alloc_t = allocation; + using value_t = ValueT; //!< Alias for the value type + using compare_t = CompareT; //!< Alias for the compare type + using alloc_t = allocation; //!< The underlying allocation type - static constexpr size_t npos = -1; + static constexpr size_t npos = -1; //!< value representing a null node private: constexpr size_t left(size_t n) const { @@ -82,10 +87,15 @@ private: // Constructors & Destructor =========================================================================================== public: + /// + /// \brief default constructor + /// \details initializes an empty queue constexpr priority_queue() : _size(0) { } + /// + /// \brief destructor constexpr ~priority_queue() { while (_size > 0) { --_size; @@ -96,14 +106,20 @@ public: // Properties ========================================================================================================== + /// + /// \returns the size of the queue constexpr size_t size() const { return _size; } + /// + /// \returns the capacity of the underlying allocation constexpr size_t capacity() const { return _table.capacity(); } + /// + /// \returns \f$true\f$ if the queue holds no elements constexpr bool empty() const { return size() == 0; } @@ -111,6 +127,8 @@ public: // Access ============================================================================================================== + /// + /// \returns the value at the front of the queue constexpr const value_t& front() const { return _table[0]; } @@ -118,19 +136,30 @@ public: // Modifiers =========================================================================================================== + /// + /// \brief push a new key into the queue + /// \param key the key to insert constexpr void push(const value_t& key) { this->_insert(key); } + /// + /// \param key the key to insert constexpr void push(value_t&& key) { this->_insert(fennec::forward(key)); } + /// + /// \brief emplace a new key into the queue + /// \tparam ArgsT the argument types + /// \param args the argument values template constexpr void emplace(ArgsT&&...args) { this->_insert(fennec::forward(args)...); } + /// + /// \brief pop the element at the front of the queue constexpr void pop() { fennec::swap(_table[0], _table[--_size]); fennec::destruct(&_table[_size]); diff --git a/include/fennec/containers/rdtree.h b/include/fennec/containers/rdtree.h index 8173b9f..50f46eb 100644 --- a/include/fennec/containers/rdtree.h +++ b/include/fennec/containers/rdtree.h @@ -49,16 +49,16 @@ template> struct rdtree { // Definitions ========================================================================================================= -protected: +private: struct node; public: - using value_t = TypeT; - using alloc_t = typename allocator_traits::template rebind; - static constexpr size_t root = 0; - static constexpr size_t npos = -1; + using value_t = TypeT; //!< the held value type + using alloc_t = typename allocator_traits::template rebind; //!< the underlying allocator type + static constexpr size_t root = 0; //!< the id of the root node + static constexpr size_t npos = -1; //!< the id of a null node -protected: +private: struct node { value_t value; size_t parent, child, prev, next; @@ -107,14 +107,14 @@ public: } /// - /// \brief Copy Constructor, copies the contents of `tree` + /// \brief Copy Constructor, copies the contents of \f$tree\f$ /// \param tree the rdtree to copy constexpr rdtree(const rdtree& tree) : _table(tree._table), _freed(tree._freed), _size(tree._size) { } /// - /// \brief Move Constructor, takes ownership over the contents of `tree` + /// \brief Move Constructor, takes ownership over the contents of \f$tree\f$ /// \param tree the rdtree to move constexpr rdtree(rdtree&& tree) noexcept : _table(fennec::move(tree._table)), _freed(fennec::move(tree._freed)), _size(tree._size) { @@ -131,7 +131,7 @@ public: /// /// \brief Copy Assignment Operator /// \param rhs the rdtree to copy - /// \returns `this` after copying the contents of `rhs` + /// \returns \f$this\f$ after copying the contents of \f$rhs\f$ constexpr rdtree& operator=(const rdtree& rhs) { for (value_t* it : this->_table) { fennec::destruct(it); @@ -145,7 +145,7 @@ public: /// /// \brief Move Assignment Operator /// \param rhs the rdtree to move - /// \returns `this` after taking ownership over the contents of `rhs` + /// \returns \f$this\f$ after taking ownership over the contents of \f$rhs\f$ constexpr rdtree& operator=(rdtree&& rhs) noexcept { for (value_t* it : _table) { fennec::destruct(it); @@ -176,7 +176,7 @@ public: } /// - /// \returns `true` when there are no nodes in the tree, `false` otherwise + /// \returns \f$true\f$ when there are no nodes in the tree, \f$false\f$ otherwise constexpr bool empty() const { return _size == 0; } @@ -256,7 +256,7 @@ public: /// /// \param i the node to start at - /// \returns the left-most child of node `i` + /// \returns the left-most child of node \f$i\f$ constexpr size_t left_most(size_t i) const { if (i >= _table.capacity()) return npos; size_t n = i; @@ -273,7 +273,7 @@ public: /// /// \param i the node to start at - /// \returns the right-most child of node `i` + /// \returns the right-most child of node \f$i\f$ constexpr size_t right_most(size_t i) const { if (i >= _table.capacity()) return npos; if ((i = child(i)) == npos) { @@ -308,7 +308,7 @@ public: } /// - /// \returns The next node id were `insert` or `emplace` to be called + /// \returns The next node id were \f$insert\f$ or \f$emplace\f$ to be called constexpr size_t next_id() const { size_t i = _size; if (not _freed.empty()) { @@ -335,8 +335,8 @@ public: // Insertion & Deletion ================================================================================================ /// - /// \brief Insertion, creates a node in the tree with parent `parent` - /// \param parent the parent node, if `npos` sets the value of the root node + /// \brief Insertion, creates a node in the tree with parent \f$parent\f$ + /// \param parent the parent node, if \f$npos\f$ sets the value of the root node /// \param next the next node, as an index relative to the parent, i.e. parent[0] == parent.child, parent[1] == parent.child.next /// \param val the value to insert /// \returns the index of the created node @@ -345,8 +345,8 @@ public: } /// - /// \brief Insertion, creates a node in the tree with parent `parent` - /// \param parent the parent node, if `npos` sets the value of the root node + /// \brief Insertion, creates a node in the tree with parent \f$parent\f$ + /// \param parent the parent node, if \f$npos\f$ sets the value of the root node /// \param next the next node, as an index relative to the parent /// \param val the value to insert /// \returns the index of the created node @@ -354,6 +354,12 @@ public: return this->_insert(parent, next, fennec::forward(val)); } + /// + /// \brief tree insertion, copies the contents of tree into self with the root at the specified node location + /// \param parent the parent node, if \f$npos\f$ sets the value of the root node + /// \param next the next node, as an index relative to the parent + /// \param tree the tree to insert + /// \returns the index of the inserted root constexpr size_t insert(size_t parent, size_t next, const rdtree& tree) { list> visit; visit.push_front({ root, parent }); @@ -378,8 +384,8 @@ public: } /// - /// \brief Insertion, creates a node in the tree with parent `parent` - /// \param parent the parent node, if `npos` sets the value of the root node + /// \brief Insertion, creates a node in the tree with parent \f$parent\f$ + /// \param parent the parent node, if \f$npos\f$ sets the value of the root node /// \param next the next node, as an index relative to the parent, i.e. parent[0] == parent.child, parent[1] == parent.child.next /// \param args the args to construct the value to insert /// \returns the index of the created node @@ -426,7 +432,7 @@ public: /// \brief Traverse the tree using a specified order and visiting functor /// /// \details - /// The visitor should accept a reference to a value of type `TypeT` and a `size_t` which contains the node's id. + /// The visitor should accept a reference to a value of type \f$TypeT\f$ and a `size_t` which contains the node's id. /// The visitor should return one of the following values in the `fennec::traversal_control_` enum /// /// \tparam OrderT The order with which to traverse the tree. @@ -449,15 +455,25 @@ public: } } + /// + /// \brief Traverser pattern for breadth-first traversal struct breadth_first { - list visit; - size_t head; + /// + /// \brief Traversal Init + /// \param start The node in the tree to start at + /// \returns The first index of the specified order constexpr size_t operator()(const rdtree&, size_t start) { head = start; return start; } + /// + /// \brief Traverser Step + /// \param tree The tree we are operating on + /// \param node The current node + /// \param mode The mode specifying branch conditions + /// \returns The next index according to the traversal order constexpr size_t operator[](const rdtree& tree, size_t node, uint8_t mode) { if (node == npos) { return npos; @@ -483,17 +499,31 @@ public: return node; } + + private: + list visit; + size_t head; }; + /// + /// \brief Traverser pattern for pre-order traversal struct pre_order { - list visit; - size_t head; + /// + /// \brief Traversal Init + /// \param start The node in the tree to start at + /// \returns The first index of the specified order constexpr size_t operator()(const rdtree&, size_t start) { head = start; return start; } + /// + /// \brief Traverser Step + /// \param tree The tree we are operating on + /// \param node The current node + /// \param mode The mode specifying branch conditions + /// \returns The next index according to the traversal order constexpr size_t operator[](const rdtree& tree, size_t node, uint8_t mode) { if (node == npos) { return npos; @@ -519,17 +549,31 @@ public: return node; } - }; - struct in_order { + private: list visit; size_t head; + }; + /// + /// \brief Traverser pattern for in-order traversal + struct in_order { + + /// + /// \brief Traversal Init + /// \param tree The tree we are operating on + /// \param start The node in the tree to start at + /// \returns The first index of the specified order constexpr size_t operator()(const rdtree& tree, size_t start) { head = start; return tree.left_most(start); } + /// + /// \brief Traverser Step + /// \param tree The tree we are operating on + /// \param node The current node + /// \returns The next index according to the traversal order constexpr size_t operator[](const rdtree& tree, size_t node, uint8_t) { if (node == npos) { return npos; @@ -557,17 +601,31 @@ public: return node; } - }; - struct post_order { + private: list visit; size_t head; + }; + /// + /// \brief Traverser pattern for post-order traversal + struct post_order { + + /// + /// \brief Traversal Init + /// \param tree The tree we are operating on + /// \param start The node in the tree to start at + /// \returns The first index of the specified order constexpr size_t operator()(const rdtree& tree, size_t start) { head = start; return tree.left_most(start); } + /// + /// \brief Traverser Step + /// \param tree The tree we are operating on + /// \param node The current node + /// \returns The next index according to the traversal order constexpr size_t operator[](const rdtree& tree, size_t node, uint8_t) { if (node == npos) { return npos; @@ -593,10 +651,14 @@ public: return node; } + + private: + list visit; + size_t head; }; -protected: +private: allocation _table; list _freed; size_t _size; diff --git a/include/fennec/containers/sequence.h b/include/fennec/containers/sequence.h index b335544..e58896c 100644 --- a/include/fennec/containers/sequence.h +++ b/include/fennec/containers/sequence.h @@ -30,15 +30,9 @@ #ifndef FENNEC_CONTAINERS_SEQUENCE_H #define FENNEC_CONTAINERS_SEQUENCE_H -#include -#include + #include #include -#include -#include -#include -#include -#include #include #include @@ -64,13 +58,13 @@ namespace fennec /// /// | Property | Value | /// |:----------:|:---------------:| -/// | stable | ⛔ | -/// | dynamic | ✅ | -/// | homogenous | ✅ | -/// | distinct | ✅ | -/// | ordered | ✅ | +/// | stable | ✅ | +/// | dynamic | ✅ | +/// | homogenous | ✅ | +/// | distinct | ✅ | +/// | ordered | ✅ | /// | space | \f$O(N)\f$ | -/// | linear | ✅ | +/// | linear | ✅ | /// | access | \f$O(\log N)\f$ | /// | find | \f$O(\log N)\f$ | /// | insertion | \f$O(\log N)\f$ | @@ -83,15 +77,9 @@ template, class AllocT = allocat struct sequence { // Definitions ========================================================================================================= -protected: +private: struct _node; -public: - using value_t = TypeT; - using node_t = pair; - using alloc_t = allocator_traits::template rebind<_node>; - using compare_t = CompareT; - enum color_ : bool { black = false, red = true, @@ -102,9 +90,16 @@ public: dir_right = true, }; - class iterator; +public: + using value_t = TypeT; //!< the value type + using node_t = pair; //!< the node type + using alloc_t = allocator_traits::template rebind<_node>; //!< underlying alloc type + using compare_t = CompareT; //!< comparison type -protected: + class iterator; + class const_iterator; + +private: using node = _node*; struct _node { @@ -246,7 +241,7 @@ public: /// @{ /// - /// \brief Value Find Function, finds the iterator position for `val`, otherwise returns `end()` + /// \brief Value Find Function, finds the iterator position for \f$val\f$, otherwise returns `end()` /// \param val The value to find /// \returns An iterator at the value constexpr iterator find(const value_t& val) { @@ -266,7 +261,7 @@ public: /// /// \brief Value Contains Function, checks if the sequence contains a value /// \param val The value to find - /// \returns `true` if `val` is in the sequence, `false` otherwise + /// \returns \f$true\f$ if \f$val\f$ is in the sequence, \f$false\f$ otherwise bool contains(const value_t& val) { return find(val) != end(); } @@ -286,7 +281,7 @@ public: } /// - /// \returns `true` when there are no elements in the sequence, `false` otherwise. + /// \returns \f$true\f$ when there are no elements in the sequence, \f$false\f$ otherwise. constexpr bool empty() const { return _size == 0; } @@ -299,7 +294,7 @@ public: /// @{ /// - /// \brief Move Insertion, moves `val` into the sequence + /// \brief Move Insertion, moves \f$val\f$ into the sequence /// \param val The value to insert constexpr void insert(value_t&& val) { node i = _insert_bst(fennec::forward(val)); @@ -307,7 +302,7 @@ public: } /// - /// \brief Copy Insertion, inserts a copy of `val` into the sequence + /// \brief Copy Insertion, inserts a copy of \f$val\f$ into the sequence /// \param val The value to insert constexpr void insert(const value_t& val) { node i = _insert_bst(val); @@ -324,6 +319,9 @@ public: _fix_insert(i); } + /// + /// \brief Erase the specified value from the sequence + /// \param val the value to erase constexpr void erase(const value_t& val) { _erase(find(val)._node); } @@ -336,7 +334,7 @@ public: visit.push_back(it._node); } for (node n : visit) { - _free_node(n); + this->_free_node(n); } _root = nullptr; _size = 0; @@ -352,21 +350,35 @@ public: return sequence::iterator(this, _root); } + /// + /// \brief C++ Iterator Specification `begin()` + /// \returns An iterator at the smallest element in the sequence + constexpr const_iterator begin() const { + return sequence::const_iterator(this, _root); + } + /// /// \returns An iterator after the largest element in the sequence constexpr iterator end() { return sequence::iterator(this, _root, nullptr); } + /// + /// \brief Const C++ Iterator Specification `end()` + /// \returns An iterator after the largest element in the sequence + constexpr const_iterator end() const { + return sequence::const_iterator(this, _root, nullptr); + } + + /// + /// \brief C++ Iterator Specification `iterator` class iterator { - protected: + private: sequence* _seq; node _head; node _node; list _visit; - - public: constexpr iterator(sequence* seq, node start) : _seq(seq) , _head(start) @@ -379,49 +391,178 @@ public: , _node(start) { } - iterator& operator++() { - if (_node == nullptr) { - return *this; + public: + + /// + /// \brief prefix increment operator + /// \param it the iterator to increment + /// \returns \f$it\f$ after having moved to the next element in the list + friend iterator& operator++(iterator& it) { + if (it._node == nullptr) { + return it; } - node parent = _seq->_parent(_node); - node pright = _seq->right(parent); - node next = _seq->leftmost(_seq->right(_node)); + node parent = it._seq->_parent(it._node); + node pright = it._seq->right(parent); + node next = it._seq->leftmost(it._seq->right(it._node)); - if (_node != pright && parent != nullptr) { - _visit.push_front(parent); + if (it._node != pright && parent != nullptr) { + it._visit.push_front(parent); } if (next != nullptr) { - _visit.push_front(next); + it._visit.push_front(next); } - if (not _visit.empty()) { - _node = _visit.front(); - _visit.pop_front(); + if (not it._visit.empty()) { + it._node = it._visit.front(); + it._visit.pop_front(); } else { - _node = nullptr; + it._node = nullptr; } - return *this; + return it; } - iterator operator++(int) { - iterator prev = *this; - this->operator++(); + /// + /// \brief postfix increment operator + /// \param it the iterator to increment + /// \returns \f$it\f$ before having moved to the next element in the list + friend iterator operator++(iterator& it, int) { + iterator prev = it; + ++it; return prev; } + /// + /// \brief dereference operator + /// \returns a reference to the value pointed by the iterator const value_t& operator*() const { return _node->key; } + /// + /// \brief pointer access operator + /// \returns a pointer to the value pointed by the iterator const value_t* operator->() const { return &_node->key; } + /// + /// \brief iterator equality operator + /// \param lhs the iterator + /// \param rhs the iterator to compare with + /// \returns \f$true\f$ if the iterators are identical, \f$false\f$ otherwise constexpr friend bool operator==(const iterator& lhs, const iterator& rhs) { - return lhs._node == rhs._node; + return lhs._seq == rhs._seq and lhs._node == rhs._node; + } + + /// + /// \brief iterator inequality operator + /// \param lhs the iterator + /// \param rhs the iterator to compare with + /// \returns \f$true\f$ if the iterators are different, \f$false\f$ otherwise + constexpr friend bool operator!=(const iterator& lhs, const iterator& rhs) { + return lhs._seq != rhs._seq or lhs._node != rhs._node; + } + + friend struct sequence; + }; + + /// + /// \brief C++ Iterator Specification `iterator` + class const_iterator { + private: + const sequence* _seq; + node _head; + node _node; + list _visit; + + constexpr const_iterator(const sequence* seq, node start) + : _seq(seq) + , _head(start) + , _node(seq->leftmost(start)) { + } + + constexpr const_iterator(const sequence* seq, node root, node start) + : _seq(seq) + , _head(root) + , _node(start) { + } + + public: + + /// + /// \brief prefix increment operator + /// \param it the iterator to increment + /// \returns \f$it\f$ after having moved to the next element in the list + friend const_iterator& operator++(const_iterator& it) { + if (it._node == nullptr) { + return it; + } + + node parent = it._seq->_parent(it._node); + node pright = it._seq->right(parent); + node next = it._seq->leftmost(it._seq->right(it._node)); + + if (it._node != pright && parent != nullptr) { + it._visit.push_front(parent); + } + + if (next != nullptr) { + it._visit.push_front(next); + } + + if (not it._visit.empty()) { + it._node = it._visit.front(); + it._visit.pop_front(); + } else { + it._node = nullptr; + } + + return it; + } + + /// + /// \brief postfix increment operator + /// \param it the iterator to increment + /// \returns \f$it\f$ before having moved to the next element in the list + friend const_iterator operator++(const_iterator& it, int) { + const_iterator prev = it; + ++it; + return prev; + } + + /// + /// \brief dereference operator + /// \returns a reference to the value pointed by the iterator + const value_t& operator*() const { + return _node->key; + } + + /// + /// \brief pointer access operator + /// \returns a pointer to the value pointed by the iterator + const value_t* operator->() const { + return &_node->key; + } + + /// + /// \brief iterator equality operator + /// \param lhs the iterator + /// \param rhs the iterator to compare with + /// \returns \f$true\f$ if the iterators are identical, \f$false\f$ otherwise + constexpr friend bool operator==(const const_iterator& lhs, const const_iterator& rhs) { + return lhs._seq == rhs._seq and lhs._node == rhs._node; + } + + /// + /// \brief iterator inequality operator + /// \param lhs the iterator + /// \param rhs the iterator to compare with + /// \returns \f$true\f$ if the iterators are different, \f$false\f$ otherwise + constexpr friend bool operator!=(const const_iterator& lhs, const const_iterator& rhs) { + return lhs._seq != rhs._seq or lhs._node != rhs._node; } friend struct sequence; @@ -429,14 +570,14 @@ public: // Fields ============================================================================================================== -protected: +private: alloc_t _alloc; node _root; compare_t _compare; size_t _size; // Helpers ============================================================================================================= -protected: +private: template constexpr node _make_node(ArgsT&&...args) { diff --git a/include/fennec/containers/set.h b/include/fennec/containers/set.h index d7022d5..dc2cc47 100644 --- a/include/fennec/containers/set.h +++ b/include/fennec/containers/set.h @@ -69,14 +69,13 @@ struct set { // Definitions ========================================================================================================= public: - using alloc_t = typename allocator_traits::template rebind; - using hash_t = Hash; - using equal_t = Equals; - using elem_t = TypeT; + using alloc_t = typename allocator_traits::template rebind; //!< the allocator type + using hash_t = Hash; //!< the hash type + using equal_t = Equals; //!< the equality type + using elem_t = TypeT; //!< the element type + static constexpr double default_load = 0.8; //!< the default load factor for reallocation class iterator; - static constexpr size_t npos = -1; - static constexpr double default_load = 0.8; private: struct node { @@ -87,6 +86,8 @@ private: constexpr ~node() = default; }; + static constexpr size_t npos = -1; + // Constructors ======================================================================================================== public: @@ -182,7 +183,7 @@ public: } /// - /// \returns `true` when the set is empty, `false` otherwise + /// \returns \f$true\f$ when the set is empty, \f$false\f$ otherwise constexpr bool empty() const { return _size == 0; } @@ -252,7 +253,7 @@ public: /// /// \brief Check if a set contains a value /// \param val Value to check - /// \returns `true` if `val` can be found, `false` otherwise + /// \returns \f$true\f$ if \f$val\f$ can be found, \f$false\f$ otherwise constexpr bool contains(const elem_t& val) const { return this->find(val) != end(); } @@ -260,7 +261,7 @@ public: /// /// \brief Iterator Access /// \param it Location to access - /// \returns A pointer to the element, `nullptr` if not found. + /// \returns A pointer to the element, \f$nullptr\f$ if not found. /// The value should not be changed in a manner that will change the hash of the element. constexpr elem_t* at(const iterator& it) { if (it == end()) { @@ -275,7 +276,7 @@ public: /// /// \brief Iterator Const Access /// \param it Location to access - /// \returns A const-qualified pointer to the element, `nullptr` if not found. + /// \returns A const-qualified pointer to the element, \f$nullptr\f$ if not found. constexpr const elem_t* at(const iterator& it) const { if (not _alloc[it._i].value) return nullptr; return &*_alloc[it._i].value; @@ -347,11 +348,9 @@ public: } /// - /// \brief + /// \brief Clear all elements from the set, destructing them constexpr void clear() { - for (size_t i = 0; i < _alloc.capacity(); ++i) { - - } + _alloc.clear(); } /// @} @@ -381,57 +380,79 @@ public: /// @} /// - /// \brief Class for Iterating the Set + /// \brief C++ Iterator Specification `iterator` class iterator { public: - constexpr iterator(const set* set, size_t i) - : _set(set) - , _i(i) { - } - + /// + /// \brief destructor constexpr ~iterator() { _set = nullptr; } - // prefix operator - constexpr friend iterator& operator++(iterator& rhs) { - while (++rhs._i < rhs._set->capacity()) { - if (rhs._set->_alloc[rhs._i].value) { - return rhs; + /// + /// \brief prefix increment operator + /// \param it the iterator to increment + /// \returns \f$it\f$ after having moved to the next element in the list + constexpr friend iterator& operator++(iterator& it) { + while (++it._i < it._set->capacity()) { + if (it._set->_alloc[it._i].value) { + return it; } } - rhs._i = npos; - return rhs; + it._i = npos; + return it; } - constexpr friend iterator operator++(iterator& lhs, int) { - iterator prev = lhs; - ++lhs; + /// + /// \brief postfix increment operator + /// \param it the iterator to increment + /// \returns \f$it\f$ before having moved to the next element in the list + constexpr friend iterator operator++(iterator& it, int) { + iterator prev = it; + ++it; return prev; } + /// + /// \brief dereference operator + /// \returns a reference to the value pointed by the iterator constexpr const elem_t& operator*() const { return *_set->_alloc[_i].value; } + /// + /// \brief pointer access operator + /// \returns a pointer to the value pointed by the iterator constexpr const elem_t* operator->() const { if (not _set->_alloc[_i].value) return nullptr; return &*_set->_alloc[_i].value; } + /// + /// \brief iterator equality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are identical, \f$false\f$ otherwise constexpr bool operator==(const iterator& it) const { return _set == it._set and _i == it._i; } + /// + /// \brief iterator inequality operator + /// \param it the iterator to compare with + /// \returns \f$true\f$ if the iterators are different, \f$false\f$ otherwise constexpr bool operator!=(const iterator& it) const { return _set != it._set or _i != it._i; } - constexpr size_t index() const { return _i; } - private: const set* _set; size_t _i; + + constexpr iterator(const set* set, size_t i) + : _set(set) + , _i(i) { + } + friend set; }; diff --git a/include/fennec/containers/tuple.h b/include/fennec/containers/tuple.h index af6a2c1..5f07edb 100644 --- a/include/fennec/containers/tuple.h +++ b/include/fennec/containers/tuple.h @@ -42,24 +42,29 @@ namespace fennec /// /// \brief Tuple, holds a collection of values of different types /// \details -/// | Property | Value | -/// |:----------:|:----------:| +/// | Property | Value | +/// |:----------:|:-----------:| /// | stable | ⛔ | /// | dynamic | ✅ | /// | homogenous | ⛔ | /// | distinct | ⛔ | /// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | +/// | space | \f$O(N)\f$ | /// | linear | ✅ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(1)\f$ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(1)\f$ | /// | insertion | ⛔ | /// | deletion | ⛔ | /// /// \tparam TypesT The types to store template struct tuple; - +/// +/// \brief tuple get +/// \tparam i the index +/// \tparam TypesT the types held in the tuple +/// \param x the tuple +/// \returns the \f$i\f$th element of the tuple template constexpr typename tuple::template elem_t& get(tuple& x) { using elem_t = typename tuple::template elem_t; @@ -67,6 +72,11 @@ constexpr typename tuple::template elem_t& get(tuple& x return it.value; } +/// +/// \tparam i the index +/// \tparam TypesT the types held in the tuple +/// \param x the tuple +/// \returns the \f$i\f$th element of the tuple template constexpr const typename tuple::template elem_t& get(const tuple& x) { using elem_t = typename tuple::template elem_t; @@ -78,28 +88,41 @@ constexpr const typename tuple::template elem_t& get(const tuple struct tuple : public detail::_tuple, TypesT...> { - using base_t = detail::_tuple, TypesT...>; + using base_t = detail::_tuple, TypesT...>; //!< the base type template - using elem_t = typename nth_element::type; + using elem_t = typename nth_element::type; //!< helper for getting the \f$i\f$th element - static constexpr size_t size = sizeof...(TypesT); + static constexpr size_t size = sizeof...(TypesT); //!< the number of elements held by the tuple + /// + /// \brief tuple constructor + /// \tparam ArgsT The element types + /// \param args The arguments to initialize the tuple with template tuple(ArgsT&&...args) : base_t(fennec::forward(args)...) { } + /// + /// \brief copy constructor + /// \param cpy the tuple to copy tuple(const tuple& cpy) : base_t(cpy) { } - tuple(tuple&& cpy) - : base_t(cpy) { + /// + /// \brief move constructor + /// \param mov the tuple to move + tuple(tuple&& mov) + : base_t(mov) { } }; -// This is needed for +/// +/// \brief Helper for deducing the tuple constructor +/// \tparam TypesT the types of the tuple +/// \returns A new tuple containing the passed values template tuple(TypesT...) -> tuple; diff --git a/include/fennec/containers/variant.h b/include/fennec/containers/variant.h index 270b94e..e09ff63 100644 --- a/include/fennec/containers/variant.h +++ b/include/fennec/containers/variant.h @@ -56,8 +56,8 @@ struct variant { // Typedefs & Constants ================================================================================================ - static constexpr size_t size = max_element_size_v; - static constexpr size_t nulltype = sizeof...(TypesT); + static constexpr size_t size = max_element_size_v; //!< size of the variant in bytes + static constexpr size_t nulltype = sizeof...(TypesT); //!< id for a null type @@ -74,8 +74,8 @@ struct variant { } /// - /// \brief Conversion Constructor, constructs the type in `TypesT...` that is identical to `T` - /// or the first that is constructible with `T` + /// \brief Conversion Constructor, constructs the type in `TypesT...` that is identical to \f$T\f$ + /// or the first that is constructible with \f$T\f$ /// \tparam T The type of the value /// \param t The value to forward template @@ -146,10 +146,15 @@ struct variant { // Assignment ========================================================================================================== + /// + /// \brief value assignment operator + /// \tparam T The type to assign + /// \param t the value to assign + /// \returns a reference to \f$self\f$ after assigning \f$t\f$ template variant& operator=(T&& t) { - // First, check if `T` is in `TypesT...` + // First, check if \f$T\f$ is in `TypesT...` if constexpr((contains_element_v or ...)) { using type_t = remove_reference_t; if (_type == find_element_v) { @@ -182,12 +187,21 @@ struct variant { return *this; } + /// + /// \brief emplace function + /// \tparam T The type to construct + /// \tparam ArgsT the argument types + /// \param args the argument values template requires(contains_element_v) void emplace(ArgsT&&...args) { _clear(); fennec::construct(_handle, fennec::forward(args)...); } + /// + /// \brief deduced emplace function + /// \tparam ArgsT the argument types + /// \param args the argument values template void emplace(ArgsT&&...args) { using type_t = nth_element_t; @@ -198,21 +212,34 @@ struct variant { // Access ============================================================================================================== + /// + /// \brief get the value of the variant interpreted as \f$T\f$ + /// \tparam T the type to interpret as + /// \returns The value interpreted as \f$T\f$ template requires(contains_element_v) T& get() { return *static_cast(_handle); } + /// + /// \tparam T the type to interpret as + /// \returns The value interpreted as \f$T\f$ template requires(contains_element_v) const T& get() const { return *static_cast(_handle); } + /// + /// \tparam T the type to interpret as + /// \returns The value interpreted as \f$T\f$ template> requires(contains_element_v) T& get() { return *static_cast(_handle); } + /// + /// \tparam T the type to interpret as + /// \returns The value interpreted as \f$T\f$ template> requires(contains_element_v) const T& get() const { return *static_cast(_handle); diff --git a/include/fennec/core/event.h b/include/fennec/core/event.h index ac880b9..1b5b910 100644 --- a/include/fennec/core/event.h +++ b/include/fennec/core/event.h @@ -34,6 +34,10 @@ struct event; class event_listener { public: virtual ~event_listener() = default; + + /// + /// \brief event handler callback + /// \param event the event to handle virtual void handle_event(event* event) = 0; }; @@ -44,25 +48,42 @@ struct event { /// /// \brief Registers a listener for the event type - /// \tparam EventT - /// \param listener + /// \tparam EventT the event type + /// \param listener the listener to register template static void add_listener(event_listener* listener) { event::add_listener(listener, typeuuid()); } + /// + /// \brief Add a listener for an event type of \f$type\f$ + /// \param listener the listener to add + /// \param type the event type to listen for + static void add_listener(event_listener* listener, uint64_t type); + + /// + /// \brief removes a listener from the event system + /// \param listener the listener to remove + static void remove_listener(event_listener* listener); + + /// + /// \brief Dispatch an event + /// \tparam EventT The event type + /// \param event the event to dispatch template static void dispatch(EventT* event) { - dispatch(event); + event::dispatch(event); } - static void add_listener(event_listener* listener, uint64_t type); - static void remove_listener(event_listener* listener); + /// + /// \brief Dispatch an event + /// \param event the event to dispatch static void dispatch(event* event); +#ifndef FENNEC_DOXYGEN FENNEC_RTTI_CLASS_ENABLE() { - } +#endif }; } diff --git a/include/fennec/core/logger.h b/include/fennec/core/logger.h index 44be98d..449d2ed 100644 --- a/include/fennec/core/logger.h +++ b/include/fennec/core/logger.h @@ -39,14 +39,23 @@ namespace fennec { +/// +/// \brief logger class class logger : public singleton { public: + /// + /// \brief default constructor logger(); ~logger(); + /// + /// \brief Log a string to the log file and cout + /// \param str the string to log + /// \param _line the line of the log call + /// \param _file the file log was called in static void log(const cstring& str, - uint32_t _line = FENNEC_BUILTIN_LINE(), - const char* _file = FENNEC_BUILTIN_FILE() + uint32_t _line = FENNEC_BUILTIN_LINE(), + const char* _file = FENNEC_BUILTIN_FILE() ) { logger& inst = instance(); @@ -61,6 +70,11 @@ public: inst._cout->println(str); } + /// + /// \brief Log a string to the log file and cout + /// \param str the string to log + /// \param _line the line of the log call + /// \param _file the file log was called in static void log(const string& str, uint32_t _line = FENNEC_BUILTIN_LINE(), const char* _file = FENNEC_BUILTIN_FILE() diff --git a/include/fennec/core/version.h b/include/fennec/core/version.h index caa39fe..e14b263 100644 --- a/include/fennec/core/version.h +++ b/include/fennec/core/version.h @@ -38,9 +38,13 @@ namespace fennec { +/// +/// \brief simple version struct for drivers and systems struct version { - uint32_t major, minor, patch; - string str; + uint32_t major; //!< the major version + uint32_t minor; //!< the minor version + uint32_t patch; //!< the patch + string str; //!< string representation of the version }; } diff --git a/include/fennec/filesystem/file.h b/include/fennec/filesystem/file.h index d9e86ad..fc8d3a6 100644 --- a/include/fennec/filesystem/file.h +++ b/include/fennec/filesystem/file.h @@ -39,10 +39,10 @@ namespace fennec /// Flags /// Description /// -/// `read` +/// \f$read\f$ /// Opens file as read-only, reading from start /// -/// `write` +/// \f$write\f$ /// Opens file as write-only, writing to end /// /// `read | write` @@ -109,16 +109,28 @@ public: /// \brief default constructor, initializes an empty stream file(); + /// + /// \brief path constructor, initializes a stream pointing to \f$mode\f$ opened with \f$mode\f$ + /// \param path the path of the file + /// \param mode the mode to open with file(const cstring& path, uint8_t mode) : file() { open(path, mode); } + /// + /// \brief path constructor, initializes a stream pointing to \f$mode\f$ opened with \f$mode\f$ + /// \param path the path of the file + /// \param mode the mode to open with file(const string& path, uint8_t mode) : file() { open(path, mode); } + /// + /// \brief path constructor, initializes a stream pointing to \f$mode\f$ opened with \f$mode\f$ + /// \param path the path of the file + /// \param mode the mode to open with file(const path& path, uint8_t mode) : file() { open(path, mode); @@ -133,6 +145,9 @@ public: /// \param file the stream to take ownership of file(file&& file) noexcept; + /// + /// \brief move assignment + /// \param file the stream to take ownership of file& operator=(file&& file) noexcept; // don't allow copying streams @@ -258,21 +273,52 @@ public: // File Positioning ==================================================================================================== + /// + /// \returns the position index in the stream size_t get_pos() const; + + /// + /// \param i the new index to move to + /// \returns \f$false\f$ on success, \f$true\f$ otherwise bool set_pos(size_t i); + + /// + /// \brief return to the start of the stream + /// \returns \f$false\f$ on success, \f$true\f$ otherwise bool rewind(); + + /// + /// \returns \f$true\f$ if the stream has reached the end of the file, \f$false\f$ otherwise bool eof() const; // Binary Read Operations ============================================================================================== + /// + /// \brief binary read + /// \param data the buffer to write to + /// \param size the size of each object in bytes + /// \param n the number of objects to read + /// \returns the number of objects successfully read size_t read(void* data, size_t size, size_t n); + /// + /// \brief type read + /// \tparam T the type to read + /// \param data the buffer to write to + /// \param n the number of objects to read + /// \returns the number of objects successfully read template size_t read(T* data, size_t n) { return read(static_cast(data), sizeof(T), n); } + /// + /// \brief type read + /// \tparam T the type to read + /// \tparam n the number of objects to read + /// \param data the buffer to write to + /// \returns the number of objects successfully read template size_t read(T (&data)[n]) { return read(static_cast(data), sizeof(T), n); @@ -281,26 +327,63 @@ public: // Binary Write Operations ============================================================================================= + /// + /// \brief put a character at the current position in the stream + /// \param c the character to put + /// \returns \f$false\f$ on success, \f$true\f$ otherwise bool putc(char c); + + /// + /// \brief put a wide character at the current position in the stream + /// \param c the character to put + /// \returns \f$false\f$ on success, \f$true\f$ otherwise bool putwc(wchar_t c); + /// + /// \brief write a buffer to at the current position in the stream + /// \param data the buffer to read from + /// \param size the size of each object in bytes + /// \param n the number of objects to write + /// \returns the number of objects successfully written size_t write(const void* data, size_t size, size_t n); + /// + /// \brief write a character buffer to at the current position in the stream + /// \tparam n the number of characters to write + /// \param data the buffer to read from + /// \returns the number of objects successfully written template size_t write(const char (&data)[n]) { return write(data, sizeof(char), n - 1); } + /// + /// \brief write a wide character buffer to at the current position in the stream + /// \tparam n the number of characters to write + /// \param data the buffer to read from + /// \returns the number of objects successfully written template size_t write(const wchar_t (&data)[n]) { return write(data, sizeof(wchar_t), n - 1); } + /// + /// \brief write a buffer to at the current position in the stream + /// \tparam T the object type to write + /// \param data the buffer to read from + /// \param n the number of objects to write + /// \returns the number of objects successfully written template size_t write(const T* data, size_t n) { return write(static_cast(data), sizeof(T), n); } + /// + /// \brief write a buffer to at the current position in the stream + /// \tparam T the object type to write + /// \tparam n the number of objects to write + /// \param data the buffer to read from + /// \returns the number of objects successfully written template size_t write(const T (&data)[n]) { return write(static_cast(data), sizeof(T), n); @@ -309,21 +392,48 @@ public: // Read Operations ===================================================================================================== + /// + /// \returns the character read at the current position in the stream char getc(); + + /// + /// \returns the wide character read at the current position in the stream wchar_t getwc(); + /// + /// \returns a string containing all characters from the current position in the stream to the next newline character string getline(); + + /// + /// \returns a string containing all characters from the current position in the stream to the next newline character wstring getwline(); // Printing Operations ================================================================================================= + /// + /// \param str the string to print void print(const cstring& str); + + /// + /// \brief print a string to the stream + /// \param str the string to print void print(const string& str); + /// + /// \param str the string to print void println(const cstring& str); + + /// + /// \brief print a string to the stream followed by a newline character + /// \param str the string to print void println(const string& str); + /// + /// \brief print a formatted string to the stream + /// \tparam ArgsT the argument types + /// \param str the format string + /// \param args the argument values template void printf(const cstring& str, ArgsT&&...args) { string fmt = fennec::format(str, fennec::forward(args)...); @@ -335,7 +445,12 @@ public: // Error Handling ====================================================================================================== + /// + /// \returns the current error state of the file const char* get_error() const { return _error; } + + /// + /// \brief clears the errored state void clear_error() { _error = nullptr; } private: diff --git a/include/fennec/filesystem/path.h b/include/fennec/filesystem/path.h index fbf7f95..7c38ea2 100644 --- a/include/fennec/filesystem/path.h +++ b/include/fennec/filesystem/path.h @@ -36,7 +36,7 @@ public: // Definitions ========================================================================================================= class iterator; - friend iterator; + friend class iterator; // Static Functions ==================================================================================================== @@ -95,7 +95,7 @@ public: /// /// \brief C-String Assignment Operator /// \param str the cstring to assign - /// \returns a reference to `this` after assigning `p` + /// \returns a reference to \f$this\f$ after assigning \f$p\f$ template path& operator=(const char (&str)[n]) { _str = str; @@ -105,7 +105,7 @@ public: /// /// \brief C-String Assignment Operator /// \param p the cstring to assign - /// \returns a reference to `this` after assigning `p` + /// \returns a reference to \f$this\f$ after assigning \f$p\f$ path& operator=(const cstring& p) { _str = p; return *this; @@ -114,7 +114,7 @@ public: /// /// \brief String Assignment Operator /// \param p the cstring to assign - /// \returns a reference to `this` after assigning `p` + /// \returns a reference to \f$this\f$ after assigning \f$p\f$ path& operator=(const string& p) { _str = p; return *this; @@ -123,7 +123,7 @@ public: /// /// \brief Path Copy Assignment Operator /// \param p the path to copy - /// \returns a reference to `this` after copying `p` + /// \returns a reference to \f$this\f$ after copying \f$p\f$ path& operator=(const path& p) { _str = p._str; return *this; @@ -132,7 +132,7 @@ public: /// /// \brief Path Move Assignment Operator /// \param p the path to take ownership of - /// \returns a reference to `this` after taking ownership of `p` + /// \returns a reference to \f$this\f$ after taking ownership of \f$p\f$ path& operator=(path&& p) noexcept { _str = move(p._str); return *this; @@ -142,33 +142,55 @@ public: // Append Operators ==================================================================================================== /// - /// \brief - /// \param str - /// \return + /// \brief path append operator + /// \param str the filename to append + /// \returns a path containing the current path followed by \f$str\f$ path operator/(const cstring& str) const { return path(_str + '/' + str); } + /// + /// \brief path append operator + /// \param str the filename to append + /// \returns a path containing the current path followed by \f$str\f$ path operator/(const string& str) const { return path(_str + '/' + str); } + /// + /// \brief path append operator + /// \param p the path to append + /// \returns a path containing the current path followed by \f$p\f$ path operator/(const path& p) const { return path(_str + '/' + p._str); } + /// + /// \brief path equality operator + /// \param p the path to compare against + /// \returns \f$true\f$ if the paths are identical, \f$false\f$ otherwise. relative paths are not resolved bool operator==(const path& p) const { return _str == p._str; } + /// + /// \brief the filename of the current path + /// \returns a string containing a copy of the filename string filename() const { size_t i = _str.rfind('/'); return _str.substring(i + 1); } + /// + /// \returns the underlying string representation const string& str() const { return _str; } + + /// + /// \returns the underlying C-Style string representation const char* cstr() const { return _str.cstr(); } + /// + /// \returns \f$true\f$ if the path is empty or points to root bool empty() { size_t size = _str.size(); if (size == 0) return true; @@ -179,6 +201,8 @@ public: #endif } + /// + /// \returns a copy of the path with the filename removed path parent() const { #ifdef FENNEC_PLATFORM_WINDOWS size_t start = _str.size() - 1; @@ -203,6 +227,9 @@ public: #endif } + /// + /// \brief absolute path + /// \returns a copy of the path with relative paths resolved path absolute() const { path parse = *this; path working; working._str.resize(0); @@ -253,16 +280,83 @@ public: // Iterator ============================================================================================================ + /// + /// \brief C++ Iterator Specification `begin()` + /// \returns an iterator at the first filename in the path iterator begin() const { return iterator(this, 0); } + /// + /// \brief C++ Iterator Specification `end()` + /// \returns an iterator to the end of the path iterator end() const { return iterator(this, _str.size()); } + /// + /// \brief C++ Iterator Specification `iterator` class iterator { public: + /// + /// \brief copy constructor + /// \param it the iterator to copy + constexpr iterator(const iterator& it) = default; + + /// + /// \brief move constructor + /// \param it the iterator to move + constexpr iterator(iterator&& it) noexcept = default; + + /// + /// \brief dereference operator + /// \returns copy of the current file in the path + constexpr string operator*() const { + if ((*_str)[_pos] == '/') { + return string(""); + } + + size_t e = _str->find('/', _pos); + return _str->substring(_pos, e - _pos); + } + + /// + /// \brief prefix increment operator + /// \returns \f$self\f$ after having moved to the next element in the list + constexpr iterator& operator++() { + _pos = min(_str->find('/', _pos) + 1, _str->size()); + return *this; + } + + /// + /// \brief postfix increment operator + /// \returns \f$self\f$ before having moved to the next element in the list + constexpr iterator operator++(int) { + iterator it = *this; + this->operator++(); + return it; + } + + /// + /// \brief iterator equality operator + /// \param rhs the iterator to compare with + /// \returns \f$true\f$ if the iterators are identical, \f$false\f$ otherwise + constexpr bool operator==(const iterator& rhs) const { + return _str == rhs._str and _pos == rhs._pos; + } + + /// + /// \brief iterator inequality operator + /// \param rhs the iterator to compare with + /// \returns \f$true\f$ if the iterators are different, \f$false\f$ otherwise + constexpr bool operator!=(const iterator& rhs) const { + return _str != rhs._str or _pos != rhs._pos; + } + + private: + const string* _str; + size_t _pos; + constexpr iterator(const path* path, size_t p) : _str(&path->_str) , _pos(p) { @@ -289,40 +383,7 @@ public: } } - constexpr iterator(const iterator&) = default; - constexpr iterator(iterator&&) noexcept = default; - - constexpr string operator*() const { - if ((*_str)[_pos] == '/') { - return string(""); - } - - size_t e = _str->find('/', _pos); - return _str->substring(_pos, e - _pos); - } - - constexpr iterator& operator++() { - _pos = min(_str->find('/', _pos) + 1, _str->size()); - return *this; - } - - constexpr iterator operator++(int) { - iterator it = *this; - this->operator++(); - return it; - } - - constexpr bool operator==(const iterator& rhs) const { - return _str == rhs._str and _pos == rhs._pos; - } - - constexpr bool operator!=(const iterator& rhs) const { - return _str != rhs._str or _pos != rhs._pos; - } - - private: - const string* _str; - size_t _pos; + friend struct path; }; private: diff --git a/include/fennec/format/charconv.h b/include/fennec/format/charconv.h index fc6f2f3..9c16853 100644 --- a/include/fennec/format/charconv.h +++ b/include/fennec/format/charconv.h @@ -34,31 +34,165 @@ namespace fennec { +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, char x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, signed char x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, unsigned char x, int base); +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, signed short x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, unsigned short x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, signed int x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, unsigned int x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, signed long x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, unsigned long x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, signed long long x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, unsigned long long x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, signed long long x, int base); + +/// +/// \brief integer to ascii +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param base the base to interpret the integer as +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, unsigned long long x, int base); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, float x); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param fmt the float string format to use +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, float x, char fmt); + +/// +/// \brief float to ascii +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param fmt the float string format to use +/// \param precision the number of decimal places to write +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, float x, char fmt, int precision); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, double x); + +/// +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param fmt the float string format to use +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, double x, char fmt); + +/// +/// \brief float to ascii +/// \param first the start of the buffer +/// \param last the end of the buffer +/// \param x the value to write +/// \param fmt the float string format to use +/// \param precision the number of decimal places to write +/// \returns a pointer to one past the last written character char* to_chars(char* first, char* last, double x, char fmt, int precision); diff --git a/include/fennec/format/format.h b/include/fennec/format/format.h index b55b9ed..d60366c 100644 --- a/include/fennec/format/format.h +++ b/include/fennec/format/format.h @@ -38,7 +38,12 @@ namespace fennec { - +/// +/// \brief C++ 20 format specification +/// \tparam ArgsT The argument types +/// \param str The format string +/// \param args The argument values +/// \returns A formatted string using the C++20 format specification template string format(const cstring& str, ArgsT&&...args) { static constexpr size_t argc = sizeof...(ArgsT); diff --git a/include/fennec/format/format_arg.h b/include/fennec/format/format_arg.h index 0c92a68..a012b4e 100644 --- a/include/fennec/format/format_arg.h +++ b/include/fennec/format/format_arg.h @@ -35,14 +35,18 @@ namespace fennec { - +/// +/// \brief helper struct for `fennec::format` struct format_arg { - char fill; - char align, sign; - bool alt, upper; - size_t width, precision; - size_t base; - char type; + char fill; //!< the fill character of the argument + char align; //!< the alignment of the argument + char sign; //!< the sign to use + bool alt; //!< alternate form + bool upper; //!< print as uppercase + size_t width; //!< the width of the fill + size_t precision; //!< the number of decimal points + size_t base; //!< the base to use + char type; //!< the argument type }; } diff --git a/include/fennec/format/formatter.h b/include/fennec/format/formatter.h index 2060661..e13bfe9 100644 --- a/include/fennec/format/formatter.h +++ b/include/fennec/format/formatter.h @@ -45,6 +45,11 @@ namespace fennec /// \tparam T The type to format template struct formatter { + /// + /// \brief default format function + /// + /// \details throws a static assertion + /// \returns empty string string operator()(const format_arg&, const T&) { static_assert(false, "Formatter not implemented for the provided type."); return string(""); @@ -54,29 +59,55 @@ struct formatter { // strings ============================================================================================================= +/// +/// \brief formatter of a character array +/// \tparam N the number of characters template struct formatter { + /// + /// \brief format function + /// \param str the string argument + /// \returns the formatted version of \f$str\f$ string operator()(const format_arg&, const char (&str)[N]) { return string(str); } }; +/// +/// \brief formatter of a character array +/// \tparam N the number of characters template struct formatter { + /// + /// \brief format function + /// \param str the string argument + /// \returns the formatted version of \f$str\f$ string operator()(const format_arg&, const char (&str)[N]) { return string(str); } }; +/// +/// \brief formatter of a C-Style string template<> struct formatter { + /// + /// \brief format function + /// \param str the string argument + /// \returns the formatted version of \f$str\f$ string operator()(const format_arg&, const cstring& str) { return str; } }; +/// +/// \brief formatter of a string template<> struct formatter { + /// + /// \brief format function + /// \param str the string argument + /// \returns the formatted version of \f$str\f$ string operator()(const format_arg&, const string& str) { return str; } @@ -85,8 +116,15 @@ struct formatter { // decimal types ======================================================================================================= +/// +/// \brief formatter of integral types template requires(is_integral_v and not is_bool_v) struct formatter { + /// + /// \brief format function + /// \param fmt the format specification + /// \param x the integral argument + /// \returns the formatted version of \f$x\f$ string operator()(const format_arg& fmt, IntT x) { char digits[128] = {}; auto chk = fennec::to_chars(digits, digits + sizeof(digits), fennec::abs(x), fmt.base); @@ -154,8 +192,15 @@ struct formatter { } }; +/// +/// \brief formatter of boolean types template requires(is_bool_v) struct formatter { + /// + /// \brief format function + /// \param fmt the format specification + /// \param x the boolean argument + /// \returns the formatted version of \f$x\f$ string operator()(const format_arg& fmt, BoolT x) { if (fmt.type == 's' or fmt.type == '\0') { return x ? string("true") : string("false"); @@ -165,8 +210,15 @@ struct formatter { } }; +/// +/// \brief formatter of floating point types template requires(is_floating_point_v) struct formatter { + /// + /// \brief format function + /// \param fmt the format specification + /// \param x the float argument + /// \returns the formatted version of \f$x\f$ string operator()(const format_arg& fmt, FloatT x) { // nan & inf cases diff --git a/include/fennec/lang/assert.h b/include/fennec/lang/assert.h index fe799fa..1ff98df 100644 --- a/include/fennec/lang/assert.h +++ b/include/fennec/lang/assert.h @@ -46,18 +46,18 @@ ///
/// assert(expr, desc) /// -/// Make an assertion with expression `expr` and provide a description `desc`. Only halts in debug mode. +/// Make an assertion with expression \f$expr\f$ and provide a description \f$desc\f$. Only halts in debug mode. /// ///
/// assertf(expr, desc) /// -/// Make an assertion with expression `expr` and provide a description `desc`. Always halts. +/// Make an assertion with expression \f$expr\f$ and provide a description \f$desc\f$. Always halts. /// ///
/// assertd(expr, desc) /// -/// Make an assertion, ***only in debug mode***, with expression `expr` and provide a description `desc`. -/// This should be used when the branching caused by `assert` would hinder performance in release mode. +/// Make an assertion, ***only in debug mode***, with expression \f$expr\f$ and provide a description \f$desc\f$. +/// This should be used when the branching caused by \f$assert\f$ would hinder performance in release mode. /// /// /// diff --git a/include/fennec/lang/conditional_types.h b/include/fennec/lang/conditional_types.h index e38613a..b37dfa8 100644 --- a/include/fennec/lang/conditional_types.h +++ b/include/fennec/lang/conditional_types.h @@ -90,12 +90,12 @@ using conditional_t = typename conditional::type; -// specialization of fennec::conditional for `true` case +// specialization of fennec::conditional for \f$true\f$ case template struct conditional : type_identity{}; -// specialization of fennec::conditional for `false` case +// specialization of fennec::conditional for \f$false\f$ case template struct conditional : type_identity{}; @@ -105,7 +105,7 @@ struct conditional : type_identity{}; /// /// \brief Detect whether `DetectT` is a valid type /// -/// \details Selects `DetectT` if it exists, otherwise selects `DefaultT` The chosen type is stored in `detect::type` and +/// \details Selects `DetectT` if it exists, otherwise selects \f$DefaultT\f$ The chosen type is stored in `detect::type` and /// a boolean value is stored in `detect::is_detected` representing whether `DetectT` is found. /// \tparam DefaultT Default type /// \tparam DetectT Type to detect @@ -138,7 +138,7 @@ struct detect /// /// \brief Leverage SFINAE to conditionally enable a function or class at compile-time /// -/// \details If `B` is `true`, define a public member type `type`. Otherwise, there is no member.
+/// \details If \f$B\f$ is \f$true\f$, define a public member type \f$type\f$. Otherwise, there is no member.
/// **Example Usage** /// \code{.cpp} /// template /// `B FENNEC_BUILTIN_IS_CONVERTIBLE(X, Y)` /// -/// Checks if type `X` can be converted to type `Y`. +/// Checks if type \f$X\f$ can be converted to type \f$Y\f$. /// ///
/// `FENNEC_HAS_BUILTIN_IS_EMPTY`
/// `B FENNEC_BUILTIN_IS_EMPTY(X)` /// -/// Checks if type `X` stores no data. +/// Checks if type \f$X\f$ stores no data. /// ///
/// `FENNEC_HAS_BUILTIN_IS_POLYMORPHIC`
/// `B FENNEC_BUILTIN_IS_POLYMORPHIC(X)` /// -/// Checks if type `X` is polymorphic, this is for classes only thus checks only for subtyping +/// Checks if type \f$X\f$ is polymorphic, this is for classes only thus checks only for subtyping /// ///
/// `FENNEC_HAS_BUILTIN_IS_FINAL`
/// `B FENNEC_BUILTIN_IS_FINAL(X)` /// -/// Checks if type `X` is final, meaning a function or class cannot be derived from. +/// Checks if type \f$X\f$ is final, meaning a function or class cannot be derived from. /// ///
/// `FENNEC_HAS_BUILTIN_IS_ABSTRACT`
/// `B FENNEC_BUILTIN_IS_ABSTRACT(X)` /// -/// Opposite of `FENNEC_BUILTIN_IS_FINAL`, checks if abstract, meaning `X` has at least one pure virtual function. +/// Opposite of `FENNEC_BUILTIN_IS_FINAL`, checks if abstract, meaning \f$X\f$ has at least one pure virtual function. /// ///
/// `FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT`
/// `B FENNEC_BUILTIN_IS_STANDARD_LAYOUT(X)` /// -/// Checks if `X` has a standard layout, here is [full criteria](https://www.cppreference.com/w/cpp/language/classes.html#Standard-layout_class) +/// Checks if \f$X\f$ has a standard layout, here is [full criteria](https://www.cppreference.com/w/cpp/language/classes.html#Standard-layout_class) /// for this trait /// ///
/// `FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE`
/// `B FENNEC_BUILTIN_IS_CONSTRUCTIBLE(X, ...)` /// -/// Checks if type `X` is constructible with args `...`, such that `X::X(...)` exists. +/// Checks if type \f$X\f$ is constructible with args `...`, such that `X::X(...)` exists. /// /// /// diff --git a/include/fennec/lang/metasequences.h b/include/fennec/lang/metasequences.h index cca261c..2f82c26 100644 --- a/include/fennec/lang/metasequences.h +++ b/include/fennec/lang/metasequences.h @@ -80,7 +80,7 @@ namespace fennec /// /// \brief metaprogramming sequence /// -/// \details Stores a sequence of values of type `ValueT` as a template pack. +/// \details Stores a sequence of values of type \f$ValueT\f$ as a template pack. /// You can access the parameter pack in another template function, i.e. /// \code{cpp} /// template diff --git a/include/fennec/lang/type_sequences.h b/include/fennec/lang/type_sequences.h index a8c6c78..4ea1576 100644 --- a/include/fennec/lang/type_sequences.h +++ b/include/fennec/lang/type_sequences.h @@ -97,7 +97,7 @@ template using nth_element_t = nth_element` and replace the first `ArgT` of `ArgsT...` with `SubT` +/// \brief Take a Template with a Pack `ClassT` and replace the first \f$ArgT\f$ of `ArgsT...` with \f$SubT\f$ template struct replace_first_element { }; // Implementation @@ -127,7 +127,7 @@ template constexpr size_t max_element_size_v = max_element_size struct find_element : detail::_find_element<0, T, Ts...> {}; @@ -169,7 +169,7 @@ struct search_element_args, TypesT...> // fennec::contains_element ============================================================================================ /// -/// \brief Checks if the type sequence `Ts...` contains `T` +/// \brief Checks if the type sequence `Ts...` contains \f$T\f$ /// \tparam T The type to find /// \tparam Ts The type sequence to check template struct contains_element : bool_constant<(is_same_v or ...)> {}; diff --git a/include/fennec/lang/type_traits.h b/include/fennec/lang/type_traits.h index c594cec..efacf4a 100644 --- a/include/fennec/lang/type_traits.h +++ b/include/fennec/lang/type_traits.h @@ -649,7 +649,7 @@ template constexpr bool_t is_pointer_v = is_pointer {}; /// /// \brief Check if \p T is of a floating point type /// -/// \details Checks if type `T` is a floating point type and store it in `is_same::value`. +/// \details Checks if type \f$T\f$ is a floating point type and store it in `is_same::value`. /// \tparam T type to check template struct is_lvalue_reference : detail::_is_lvalue_reference{}; @@ -666,7 +666,7 @@ template constexpr bool_t is_lvalue_reference_v = is_lvalue_referenc /// /// \brief Check if \p T is of a floating point type /// -/// \details Checks if type `T` is a floating point type and store it in `is_same::value`. +/// \details Checks if type \f$T\f$ is a floating point type and store it in `is_same::value`. /// \tparam T type to check template struct is_rvalue_reference : detail::_is_rvalue_reference{}; @@ -683,7 +683,7 @@ template constexpr bool_t is_rvalue_reference_v = is_rvalue_referenc /// /// \brief Check if \p T is a pointer to a member function /// -/// \details Checks if type `T` is pointer to a member function and store it in `is_member_function_pointer::value`. +/// \details Checks if type \f$T\f$ is pointer to a member function and store it in `is_member_function_pointer::value`. /// \tparam T type to check template struct is_member_function_pointer : bool_constant {}; @@ -700,7 +700,7 @@ template constexpr bool_t is_member_function_pointer_v = is_member_f /// /// \brief Check if \p T is a pointer to a member object /// -/// \details Checks if type `T` is pointer to a member object and store it in `is_member_object_pointer::value`. +/// \details Checks if type \f$T\f$ is pointer to a member object and store it in `is_member_object_pointer::value`. /// \tparam T type to check template struct is_member_object_pointer : bool_constant {}; @@ -722,7 +722,7 @@ template constexpr bool_t is_member_object_pointer_v = is_member_obj /// /// \brief Check if \p T is an arithmetic type /// -/// \details Checks if type `T` is a built-in type with arithmetic operators and store it in `is_same::value`. +/// \details Checks if type \f$T\f$ is a built-in type with arithmetic operators and store it in `is_same::value`. /// \tparam T type to check template struct is_arithmetic : bool_constant or is_floating_point_v>{}; @@ -753,7 +753,7 @@ template constexpr bool_t is_fundamental_v = is_fundamental::valu /// /// \brief Check if \p T is an arithmetic type /// -/// \details Checks if type `T` is a built-in type with arithmetic operators and store it in `is_scalar::value`. +/// \details Checks if type \f$T\f$ is a built-in type with arithmetic operators and store it in `is_scalar::value`. /// \tparam T type to check template struct is_scalar : bool_constant or is_enum_v or is_pointer_v>{}; @@ -770,7 +770,7 @@ template constexpr bool_t is_scalar_v = is_scalar::value; /// /// \brief Check if \p T is an object /// -/// \details Checks if type `T` is an object and store it in `is_object::value`. +/// \details Checks if type \f$T\f$ is an object and store it in `is_object::value`. /// \tparam T type to check template struct is_object : bool_constant {}; @@ -786,7 +786,7 @@ template constexpr bool_t is_object_v = is_object::value; /// /// \brief Check if \p T is a object compound type /// -/// \details Checks if type `T` is an object and store it in `is_compound::value`. +/// \details Checks if type \f$T\f$ is an object and store it in `is_compound::value`. /// \tparam T type to check template struct is_compound : bool_constant> {}; @@ -802,7 +802,7 @@ template constexpr bool_t is_compound_v = is_compound::value; /// /// \brief Check if \p T is of a reference type /// -/// \details Checks if type `T` is a reference type and store it in `is_reference::value`. +/// \details Checks if type \f$T\f$ is a reference type and store it in `is_reference::value`. /// \tparam T type to check template struct is_reference : detail::_is_reference{}; @@ -819,7 +819,7 @@ template constexpr bool_t is_reference_v = is_reference {}; /// /// \brief Check if \p T is a pointer to a member /// -/// \details Checks if type `T` is pointer to a member and store it in `is_member_function_pointer::value`. +/// \details Checks if type \f$T\f$ is pointer to a member and store it in `is_member_function_pointer::value`. /// \tparam T type to check template struct is_member_pointer : bool_constant {}; @@ -841,7 +841,7 @@ template constexpr bool_t is_member_pointer_v = is_member_pointer /// /// \brief Check if \p T is of a const type /// -/// \details Checks if type `T` is a const type and store it in `is_same::value`. +/// \details Checks if type \f$T\f$ is a const type and store it in `is_same::value`. /// \tparam T type to check template struct is_const : detail::_is_const{}; @@ -858,7 +858,7 @@ template constexpr bool_t is_const_v = is_const {}; /// /// \brief Check if \p T is of a volatile type /// -/// \details Checks if type `T` is a volatile type and store it in `is_same::value`. +/// \details Checks if type \f$T\f$ is a volatile type and store it in `is_same::value`. /// \tparam T type to check template struct is_volatile : detail::_is_volatile{}; @@ -873,9 +873,9 @@ template constexpr bool_t is_volatile_v = is_volatile {}; // fennec::is_trivial -------------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is trivial +/// \brief Check if type \f$T\f$ is trivial /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_trivial : bool_constant {}; @@ -889,9 +889,9 @@ template constexpr bool_t is_trivial_v = is_trivial{}; // fennec::is_trivially_copyable --------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is trivially_copyable +/// \brief Check if type \f$T\f$ is trivially_copyable /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_trivially_copyable : bool_constant {}; @@ -905,9 +905,9 @@ template constexpr bool_t is_trivially_copyable_v = is_trivially_cop // fennec::is_standard_layout ------------------------------------------------------------------------------------------ /// -/// \brief Check if type `T` is standard_layout +/// \brief Check if type \f$T\f$ is standard_layout /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_standard_layout : bool_constant {}; @@ -921,9 +921,9 @@ template constexpr bool_t is_standard_layout_v = is_standard_layout< // fennec::has_unique_object_representations --------------------------------------------------------------------------- /// -/// \brief Check if type `T` has unique object representations +/// \brief Check if type \f$T\f$ has unique object representations /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct has_unique_object_representations : bool_constant)> {}; @@ -938,9 +938,9 @@ template constexpr bool_t has_unique_object_representations_v = has_ // fennec::is_empty ---------------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is empty +/// \brief Check if type \f$T\f$ is empty /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_empty : bool_constant {}; @@ -954,9 +954,9 @@ template constexpr bool_t is_empty_v = is_empty{}; // fennec::is_polymorphic ---------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is polymorphic +/// \brief Check if type \f$T\f$ is polymorphic /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_polymorphic : bool_constant {}; @@ -970,9 +970,9 @@ template constexpr bool_t is_polymorphic_v = is_polymorphic{}; // fennec::is_abstract ------------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is abstract +/// \brief Check if type \f$T\f$ is abstract /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_abstract : bool_constant {}; @@ -986,9 +986,9 @@ template constexpr bool_t is_abstract_v = is_abstract{}; // fennec::is_complete ------------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is complete +/// \brief Check if type \f$T\f$ is complete /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_complete : detail::_is_complete::type {}; @@ -1002,9 +1002,9 @@ template constexpr bool_t is_complete_v = is_complete{}; // fennec::is_final ------------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is final +/// \brief Check if type \f$T\f$ is final /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_final : bool_constant {}; @@ -1018,9 +1018,9 @@ template constexpr bool_t is_final_v = is_final{}; // fennec::is_aggregate ------------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is aggregate +/// \brief Check if type \f$T\f$ is aggregate /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_aggregate : bool_constant {}; @@ -1037,7 +1037,7 @@ template constexpr bool_t is_aggregate_v = is_aggregate{}; /// /// \brief Check if \p T is of a signed integral /// -/// \details Checks if type `T` is a signed type i.e. `T(-1) < T(0)` and stores it in `is_same::value`. +/// \details Checks if type \f$T\f$ is a signed type i.e. `T(-1) < T(0)` and stores it in `is_same::value`. /// \tparam T type to check template struct is_signed : detail::_is_signed> {}; @@ -1055,7 +1055,7 @@ template constexpr bool_t is_signed_v = is_signed::value; /// /// \brief Check if \p T is of an unsigned integral /// -/// \details Checks if type `T` is an unsigned type i.e. `T(-1) > T(0)` and stores it in `is_same::value`. +/// \details Checks if type \f$T\f$ is an unsigned type i.e. `T(-1) > T(0)` and stores it in `is_same::value`. /// \tparam T type to check template struct is_unsigned : detail::_is_unsigned> {}; @@ -1172,9 +1172,9 @@ template constexpr bool_t is_scoped_enum_v = is_scoped_enum::valu // fennec::is_convertible ---------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T0` can be converted `T1` +/// \brief Check if type \f$T0\f$ can be converted \f$T1\f$ /// -/// \details Checks if `TypeT0` +/// \details Checks if \f$TypeT0\f$ /// \tparam FromT First type /// \tparam ToT Second type template struct is_convertible @@ -1191,8 +1191,8 @@ template constexpr bool_t is_convertible_v = is_co // fennec::is_constructible -------------------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` can be constructed with `ArgsT,` i.e. `ClassT(ArgsT...)`. -/// This may be read as "is `ClassT` constructible with `ArgsT`" +/// \brief Check if \f$ClassT\f$ can be constructed with `ArgsT,` i.e. `ClassT(ArgsT...)`. +/// This may be read as "is \f$ClassT\f$ constructible with \f$ArgsT\f$" /// \tparam ClassT The class type to test /// \tparam ArgsT The arguments for the specific constructor template struct is_constructible @@ -1207,7 +1207,7 @@ template constexpr bool_t is_constructible_v // fennec::is_trivially_constructible ---------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is trivially constructible +/// \brief Check if \f$ClassT\f$ is trivially constructible /// \tparam ClassT The class type to test /// \tparam ArgsT The arguments for the specific constructor template struct is_trivially_constructible @@ -1222,7 +1222,7 @@ template constexpr bool_t is_trivially_constructible_v = is_tri // fennec::is_nothrow_constructible ------------------------------------------------------------------------------------ /// -/// \brief Check if `ClassT` is nothrow constructible +/// \brief Check if \f$ClassT\f$ is nothrow constructible /// \tparam ClassT The class type to test /// \tparam ArgsT The arguments for the specific constructor template struct is_nothrow_constructible @@ -1237,7 +1237,7 @@ template constexpr bool_t is_nothrow_constructible_v = is_nothr // fennec::is_default_constructible ------------------------------------------------------------------------------------ /// -/// \brief Check if `ClassT` is default constructible +/// \brief Check if \f$ClassT\f$ is default constructible /// \tparam ClassT The class type to test template struct is_default_constructible : bool_constant {}; @@ -1251,7 +1251,7 @@ template constexpr bool_t is_default_constructible_v = is_defau // fennec::is_trivially_default_constructible -------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is trivially default constructible +/// \brief Check if \f$ClassT\f$ is trivially default constructible /// \tparam ClassT The class type to test template struct is_trivially_default_constructible : bool_constant {}; @@ -1265,7 +1265,7 @@ template constexpr bool_t is_trivially_default_constructible_v // fennec::is_nothrow_default_constructible -------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is nothrow default constructible +/// \brief Check if \f$ClassT\f$ is nothrow default constructible /// \tparam ClassT The class type to test template struct is_nothrow_default_constructible : bool_constant {}; @@ -1279,7 +1279,7 @@ template constexpr bool_t is_nothrow_default_constructible_v = // fennec::is_copy_constructible --------------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is copy constructible +/// \brief Check if \f$ClassT\f$ is copy constructible /// \tparam ClassT The class type to test template struct is_copy_constructible : bool_constant)> {}; @@ -1293,7 +1293,7 @@ template constexpr bool_t is_copy_constructib // fennec::is_trivially_copy_constructible ----------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is trivially copy constructible +/// \brief Check if \f$ClassT\f$ is trivially copy constructible /// \tparam ClassT The class type to test template struct is_trivially_copy_constructible : bool_constant)> {}; @@ -1307,7 +1307,7 @@ template struct is_trivially_copy_constructible // fennec::is_nothrow_copy_constructible ------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is nothrow copy constructible +/// \brief Check if \f$ClassT\f$ is nothrow copy constructible /// \tparam ClassT The class type to test template struct is_nothrow_copy_constructible : bool_constant)> {}; @@ -1321,7 +1321,7 @@ template constexpr bool_t is_nothrow_copy_con // fennec::is_move_constructible --------------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is move constructible +/// \brief Check if \f$ClassT\f$ is move constructible /// \tparam ClassT The class type to test template struct is_move_constructible : bool_constant)> {}; @@ -1335,7 +1335,7 @@ template constexpr bool_t is_move_constructib // fennec::is_trivially_move_constructible ----------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is trivially move constructible +/// \brief Check if \f$ClassT\f$ is trivially move constructible /// \tparam ClassT The class type to test template struct is_trivially_move_constructible : bool_constant)> {}; @@ -1349,7 +1349,7 @@ template struct is_trivially_move_constructible // fennec::is_nothrow_move_constructible ------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is nothrow move constructible +/// \brief Check if \f$ClassT\f$ is nothrow move constructible /// \tparam ClassT The class type to test template struct is_nothrow_move_constructible : bool_constant)> {}; @@ -1363,7 +1363,7 @@ template constexpr bool_t is_nothrow_move_con // fennec::is_assignable ----------------------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is assignable +/// \brief Check if \f$ClassT\f$ is assignable /// \tparam ClassAT The class type to test /// \tparam ClassBT The arguments for the specific constructor template struct is_assignable @@ -1378,7 +1378,7 @@ template constexpr bool_t is_assignable_v = // fennec::is_trivially_assignable ------------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is trivially assignable +/// \brief Check if \f$ClassT\f$ is trivially assignable /// \tparam ClassAT The class type to test /// \tparam ClassBT The arguments for the specific constructor template struct is_trivially_assignable @@ -1394,7 +1394,7 @@ template constexpr bool_t is_trivially_assig // fennec::is_nothrow_assignable --------------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is nothrow assignable +/// \brief Check if \f$ClassT\f$ is nothrow assignable /// \tparam ClassAT The class type to test /// \tparam ClassBT The arguments for the specific constructor template struct is_nothrow_assignable @@ -1409,7 +1409,7 @@ template constexpr bool_t is_nothrow_assigna // fennec::is_copy_assignable ------------------------------------------------------------------------------------------ /// -/// \brief Check if `ClassT` is copy assignable +/// \brief Check if \f$ClassT\f$ is copy assignable /// \tparam ClassT The class type to test template struct is_copy_assignable : bool_constant, add_lvalue_reference_t)> {}; @@ -1423,7 +1423,7 @@ template constexpr bool_t is_copy_assignable_v = is_copy_assign // fennec::is_trivially_copy_assignable -------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is trivially_copy assignable +/// \brief Check if \f$ClassT\f$ is trivially_copy assignable /// \tparam ClassT The class type to test template struct is_trivially_copy_assignable : bool_constant, add_lvalue_reference_t)> {}; @@ -1437,7 +1437,7 @@ template constexpr bool_t is_trivially_copy_assignable_v = is_t // fennec::is_nothrow_copy_assignable ---------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is nothrow_copy assignable +/// \brief Check if \f$ClassT\f$ is nothrow_copy assignable /// \tparam ClassT The class type to test template struct is_nothrow_copy_assignable : bool_constant, add_lvalue_reference_t)> {}; @@ -1451,7 +1451,7 @@ template constexpr bool_t is_nothrow_copy_assignable_v = is_not // fennec::is_move_assignable ------------------------------------------------------------------------------------------ /// -/// \brief Check if `ClassT` is move assignable +/// \brief Check if \f$ClassT\f$ is move assignable /// \tparam ClassT The class type to test template struct is_move_assignable : bool_constant, add_rvalue_reference_t)> {}; @@ -1465,7 +1465,7 @@ template constexpr bool_t is_move_assignable_v = is_move_assign // fennec::is_trivially_move_assignable -------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is trivially_move assignable +/// \brief Check if \f$ClassT\f$ is trivially_move assignable /// \tparam ClassT The class type to test template struct is_trivially_move_assignable : bool_constant, add_rvalue_reference_t)> {}; @@ -1479,7 +1479,7 @@ template constexpr bool_t is_trivially_move_assignable_v = is_t // fennec::is_nothrow_move_assignable -------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is nothrow_move assignable +/// \brief Check if \f$ClassT\f$ is nothrow_move assignable /// \tparam ClassT The class type to test template struct is_nothrow_move_assignable : bool_constant, add_rvalue_reference_t)> {}; @@ -1493,7 +1493,7 @@ template constexpr bool_t is_nothrow_move_assignable_v = is_not // fennec::is_destructible --------------------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is destructible +/// \brief Check if \f$ClassT\f$ is destructible /// \tparam ClassT The class type to test template struct is_destructible : detail::_is_destructible::type {}; @@ -1507,7 +1507,7 @@ template constexpr bool_t is_destructible_v = is_destructible struct is_trivially_destructible : bool_constant {}; @@ -1521,7 +1521,7 @@ template constexpr bool_t is_trivially_destructible_v = is_triv // fennec::is_nothrow_destructible ------------------------------------------------------------------------------------- /// -/// \brief Check if `ClassT` is nothrow destructible +/// \brief Check if \f$ClassT\f$ is nothrow destructible /// \tparam ClassT The class type to test template struct is_nothrow_destructible : detail::_is_nothrow_destructible::type {}; @@ -1542,7 +1542,7 @@ template constexpr bool_t is_nothrow_destructible_v = is_nothro /// /// \brief Check if the two types are identical /// -/// \details Checks if `T0` and `T1` are identical and store it in `is_same::value` +/// \details Checks if \f$T0\f$ and \f$T1\f$ are identical and store it in `is_same::value` /// \tparam T0 first type to check /// \tparam T1 second type to check template struct is_same : false_type {}; @@ -1561,9 +1561,9 @@ template constexpr bool_t is_same_v = is_same // fennec::is_base_of -------------------------------------------------------------------------------------------------- /// -/// \brief Check if `Derived` has a base type of `Base` +/// \brief Check if \f$Derived\f$ has a base type of \f$Base\f$ /// -/// \details Checks if `Base` is a base type of `Derived` and stores it in `is_base_of::value` +/// \details Checks if \f$Base\f$ is a base type of \f$Derived\f$ and stores it in `is_base_of::value` /// \tparam Base base type to check /// \tparam Derived derived type to check template struct is_base_of : bool_constant< @@ -1581,9 +1581,9 @@ template constexpr bool_t is_base_of_v = is_bas // fennec::is_iterable ------------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is iterable +/// \brief Check if type \f$T\f$ is iterable /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_iterable : decltype(detail::_is_iterable(0)) {}; @@ -1597,9 +1597,9 @@ template constexpr bool_t is_iterable_v = is_iterable{}; // fennec::is_indexable ------------------------------------------------------------------------------------------------ /// -/// \brief Check if type `T` is indexable +/// \brief Check if type \f$T\f$ is indexable /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_indexable : decltype(detail::_is_indexable(0)) {}; @@ -1613,9 +1613,9 @@ template constexpr bool_t is_indexable_v = is_indexable{}; // fennec::is_mappable ------------------------------------------------------------------------------------------------- /// -/// \brief Check if type `T` is mappable +/// \brief Check if type \f$T\f$ is mappable /// -/// \details Checks if `T` +/// \details Checks if \f$T\f$ /// \tparam T type to check template struct is_mappable : decltype(detail::_is_mappable(0)) {}; diff --git a/include/fennec/lang/type_transforms.h b/include/fennec/lang/type_transforms.h index f0150e8..be8d43d 100644 --- a/include/fennec/lang/type_transforms.h +++ b/include/fennec/lang/type_transforms.h @@ -138,7 +138,7 @@ template using decay_t = typename decay::type; /// /// \brief adds a pointer level to \p T /// -/// \details adds a pointer to the provided type such that `T` becomes `T*` +/// \details adds a pointer to the provided type such that \f$T\f$ becomes `T*` /// \tparam T Resultant Type template struct add_pointer : detail::_add_pointer{}; @@ -150,7 +150,7 @@ template using add_pointer_t = typename add_pointer::type; /// /// \brief removes a pointer level from \p T /// -/// \details removes a pointer from the provided type such that `T*` becomes `T` +/// \details removes a pointer from the provided type such that `T*` becomes \f$T\f$ /// \tparam T Resultant Type template struct remove_pointer : detail::_remove_pointer {}; @@ -162,7 +162,7 @@ template using remove_pointer_t = typename remove_pointer::type; /// /// \brief removes all pointer levels from \p T /// -/// \details removes all pointers from the provided type such that `T*`, `T**`, etc. becomes `T` +/// \details removes all pointers from the provided type such that `T*`, `T**`, etc. becomes \f$T\f$ /// \tparam T Resultant Type template struct strip_pointers : conditional_t< detail::_is_pointer::value, @@ -179,7 +179,7 @@ template using strip_pointers_t = strip_pointers::type; /// /// \brief add a reference to \p T /// -/// \details adds a pointer to the provided type such that `T` becomes `T&` +/// \details adds a pointer to the provided type such that \f$T\f$ becomes `T&` /// \tparam T Resultant Type template struct add_reference : type_identity {}; @@ -191,7 +191,7 @@ template using add_reference_t = typename add_reference::type; /// /// \brief remove a reference from \p T /// -/// \details removes references from the provided type such that `T&` and `T&&` become `T` +/// \details removes references from the provided type such that `T&` and `T&&` become \f$T\f$ /// \tparam T Reference Type template struct remove_reference : type_identity {}; @@ -236,7 +236,7 @@ template using add_rvalue_reference_t = typename add_rvalue_referen /// /// \brief add the const qualifier to the provided type \p T /// -/// \details adds const qualification to the provided type such that `T` becomes `const T` +/// \details adds const qualification to the provided type such that \f$T\f$ becomes `const T` /// \tparam T Reference Type template struct add_const : detail::_add_const {}; @@ -248,7 +248,7 @@ template using add_const_t = typename add_const::type; /// /// \brief remove the const qualifier from the provided type \p T /// -/// \details removes const qualification from the provided type such that `const T` becomes `T` +/// \details removes const qualification from the provided type such that `const T` becomes \f$T\f$ /// \tparam T Reference Type template struct remove_const : detail::_remove_const {}; @@ -261,7 +261,7 @@ template using remove_const_t = typename remove_const::type; /// /// \brief add the volatile qualifier to the provided type \p T /// -/// \details removes references from the provided type such that `T` becomes `volatile T` +/// \details removes references from the provided type such that \f$T\f$ becomes `volatile T` /// \tparam T Reference Type template struct add_volatile : detail::_add_volatile {}; @@ -273,7 +273,7 @@ template using add_volatile_t = typename add_volatile::type; /// /// \brief remove the volatile qualifier from the provided type \p T /// -/// \details removes references from the provided type such that `volatile T` becomes `T` +/// \details removes references from the provided type such that `volatile T` becomes \f$T\f$ /// \tparam T Reference Type template struct remove_volatile : detail::_remove_volatile {}; @@ -286,7 +286,7 @@ template using remove_volatile_t = typename remove_volatile::type /// /// \brief remove the volatile qualifier from the provided type \p T /// -/// \details removes references from the provided type such that `T`, `const T`, and `volatile T` become +/// \details removes references from the provided type such that \f$T\f$, `const T`, and `volatile T` become /// `const volatile T` /// \tparam T Reference Type template struct add_cv : detail::_add_cv {}; @@ -301,7 +301,7 @@ template using add_cv_t = typename add_cv::type; /// \brief remove the const and volatile qualifiers from the provided type \p T /// /// \details removes const and volatile from the provided type such that `const T`, `volatile T`, and -/// `const volatile T` become `T` +/// `const volatile T` become \f$T\f$ /// \tparam T Reference Type template struct remove_cv : detail::_remove_cv {}; diff --git a/include/fennec/lang/types.h b/include/fennec/lang/types.h index c3874ca..861c35b 100644 --- a/include/fennec/lang/types.h +++ b/include/fennec/lang/types.h @@ -247,7 +247,7 @@ namespace fennec using uintptr_t = uintptr_t; ///< \brief Unsigned Integer Capable of Holding a Pointer to void using intmax_t = intmax_t; ///< \brief Maximum Width Signed Integer Type using uintmax_t = uintmax_t; ///< \brief Maximum Width Unsigned Integer Type - using size_t = size_t; ///< \brief Unsigned Integer Type Returned By `sizeof`, `sizeof...`, and `alignof` + using size_t = size_t; ///< \brief Unsigned Integer Type Returned By \f$sizeof\f$, `sizeof...`, and \f$alignof\f$ using ptrdiff_t = __PTRDIFF_TYPE__; ///< \brief Signed Integer Type Returned by the Subtraction of two Pointers struct empty_t {}; diff --git a/include/fennec/math/ext/quaternion.h b/include/fennec/math/ext/quaternion.h index f1ea368..1bae3e5 100644 --- a/include/fennec/math/ext/quaternion.h +++ b/include/fennec/math/ext/quaternion.h @@ -52,7 +52,7 @@ constexpr genType sqnorm(const qua& q) { /// /// \brief Norm Function /// \param q The Quaternion -/// \returns The Hamilton Tensor of `q` +/// \returns The Hamilton Tensor of \f$q\f$ template constexpr genType norm(const qua& q) { return fennec::sqrt(sqnorm(q)); @@ -61,7 +61,7 @@ constexpr genType norm(const qua& q) { /// /// \brief Unit Function (Versor) /// \param q The Quaternion -/// \returns A Quaternion of `q` with norm `1` +/// \returns A Quaternion of \f$q\f$ with norm \f$1\f$ template constexpr qua unit(const qua& q) { genType n = fennec::norm(q); @@ -97,7 +97,7 @@ public: // Constructors ======================================================================================================== /// - /// \brief Default Constructor, creates a quaternion such that the real part is `1` and all others are `0` + /// \brief Default Constructor, creates a quaternion such that the real part is \f$1\f$ and all others are \f$0\f$ constexpr quaternion() { data = { 0, 0, 0, 1 }; } @@ -105,9 +105,9 @@ public: /// /// \brief Component Constructor /// \param w The scalar component - /// \param x The coefficient of the `i` component - /// \param y The coefficient of the `j` component - /// \param z The coefficient of the `k` component + /// \param x The coefficient of the \f$i\f$ component + /// \param y The coefficient of the \f$j\f$ component + /// \param z The coefficient of the \f$k\f$ component constexpr quaternion(scalar_t w, scalar_t x, scalar_t y, scalar_t z) { data = { x, y, z, w }; } @@ -178,7 +178,7 @@ public: /// \brief Equality Operator /// \param lhs the left hand side of the expression /// \param rhs the right hand side of the expression - /// \returns `true` when all components of `lhs` and `rhs` are equal, false otherwise + /// \returns \f$true\f$ when all components of \f$lhs\f$ and \f$rhs\f$ are equal, false otherwise constexpr friend bool operator==(const quat_t& lhs, const quat_t& rhs) { return lhs.data == rhs.data; } @@ -187,7 +187,7 @@ public: /// \brief Inequality Operator /// \param lhs the left hand side of the expression /// \param rhs the right hand side of the expression - /// \returns `true` when any component of `lhs` and `rhs` are not equal, false otherwise + /// \returns \f$true\f$ when any component of \f$lhs\f$ and \f$rhs\f$ are not equal, false otherwise constexpr friend bool operator!=(const quat_t& lhs, const quat_t& rhs) { return lhs.data != rhs.data; } @@ -198,7 +198,7 @@ public: /// /// \brief Unary Negation Operator /// \param rhs The quaternion to negate - /// \returns A quaternion with each component of `rhs` negated. + /// \returns A quaternion with each component of \f$rhs\f$ negated. constexpr friend quat_t operator-(const quat_t& rhs) { return quat_t(-rhs.w, -rhs.x, -rhs.y, -rhs.z); } @@ -206,7 +206,7 @@ public: /// /// \brief Unary Conjugation Operator /// \param rhs The quaternion to conjugate - /// \returns A quaternion with each vector component of `rhs` negated. + /// \returns A quaternion with each vector component of \f$rhs\f$ negated. constexpr friend quat_t operator~(const quat_t& rhs) { return quat_t(rhs.w, -rhs.x, -rhs.y, -rhs.z); } @@ -218,7 +218,7 @@ public: /// \brief Quaternion-Scalar Multiplication Operator /// \param lhs The quaternion /// \param rhs The scalar - /// \returns A quaternion with each component of `lhs` multiplied by `rhs` + /// \returns A quaternion with each component of \f$lhs\f$ multiplied by \f$rhs\f$ constexpr friend quat_t operator*(const quat_t& lhs, scalar_t rhs) { return quat_t(lhs.w * rhs, lhs.x * rhs, lhs.y * rhs, lhs.z * rhs); } @@ -227,7 +227,7 @@ public: /// \brief Scalar-Quaternion Multiplication Operator /// \param lhs The scalar /// \param rhs The quaternion - /// \returns A quaternion with each component of `rhs` multiplied by `lhs` + /// \returns A quaternion with each component of \f$rhs\f$ multiplied by \f$lhs\f$ constexpr friend quat_t operator*(scalar_t lhs, const quat_t& rhs) { return quat_t(lhs * rhs.w, lhs * rhs.x, lhs * rhs.y, lhs * rhs.z); } @@ -236,7 +236,7 @@ public: /// \brief Quaternion-Scalar Division Operator /// \param lhs The quaternion /// \param rhs The scalar - /// \returns A quaternion with each component of `lhs` divided by `rhs` + /// \returns A quaternion with each component of \f$lhs\f$ divided by \f$rhs\f$ constexpr friend quat_t operator/(const quat_t& lhs, scalar_t rhs) { return quat_t(lhs.w / rhs, lhs.x / rhs, lhs.y / rhs, lhs.z / rhs); } @@ -245,7 +245,7 @@ public: /// \brief Scalar-Quaternion Division Operator /// \param lhs The scalar /// \param rhs The quaternion - /// \returns A quaternion with each component of `rhs` divided by `lhs` + /// \returns A quaternion with each component of \f$rhs\f$ divided by \f$lhs\f$ constexpr friend quat_t operator/(scalar_t lhs, const quat_t& rhs) { return quat_t(lhs / rhs.w, lhs / rhs.x, lhs / rhs.y, lhs / rhs.z); } @@ -257,7 +257,7 @@ public: /// \brief Quaternion-Scalar Multiplication Assignment Operator /// \param lhs The quaternion /// \param rhs The scalar - /// \returns `lhs` with each component multiplied by `rhs` + /// \returns \f$lhs\f$ with each component multiplied by \f$rhs\f$ constexpr friend quat_t& operator*=(quat_t& lhs, scalar_t rhs) { lhs.x *= rhs; lhs.y *= rhs; @@ -270,7 +270,7 @@ public: /// \brief Quaternion-Scalar Division Assignment Operator /// \param lhs The quaternion /// \param rhs The scalar - /// \returns `lhs` with each component divided by `rhs` + /// \returns \f$lhs\f$ with each component divided by \f$rhs\f$ constexpr friend quat_t& operator/=(const quat_t& lhs, scalar_t rhs) { lhs.x /= rhs; lhs.y /= rhs; diff --git a/include/fennec/math/matrix.h b/include/fennec/math/matrix.h index 813abcf..522563c 100644 --- a/include/fennec/math/matrix.h +++ b/include/fennec/math/matrix.h @@ -627,7 +627,7 @@ struct matrix /// \brief matrix comparison operator /// \param lhs the first matrix /// \param rhs the second matrix - /// \returns a boolean value that contains \f$true\f$ when all components of `lhs` and `rhs` are equal and \f$false\f$ otherwise + /// \returns a boolean value that contains \f$true\f$ when all components of \f$lhs\f$ and \f$rhs\f$ are equal and \f$false\f$ otherwise constexpr friend bool operator==(const matrix_t& lhs, const matrix_t& rhs) { return lhs.data == rhs.data; } @@ -636,7 +636,7 @@ struct matrix /// \brief matrix comparison operator /// \param lhs the first matrix /// \param rhs the second matrix - /// \returns a boolean value that contains \f$true\f$ when all components of `lhs` and `rhs` are not equal and \f$false\f$ otherwise + /// \returns a boolean value that contains \f$true\f$ when all components of \f$lhs\f$ and \f$rhs\f$ are not equal and \f$false\f$ otherwise constexpr friend bool operator!=(const matrix_t& lhs, const matrix_t& rhs) { return lhs.data != rhs.data; } diff --git a/include/fennec/math/swizzle_storage.h b/include/fennec/math/swizzle_storage.h index abac0a5..169e7e4 100644 --- a/include/fennec/math/swizzle_storage.h +++ b/include/fennec/math/swizzle_storage.h @@ -23,26 +23,26 @@ namespace fennec::detail { -// -// \brief Backing storage struct for \ref fennec::swizzle "swizzle" -// \tparam DataT Data Type -// \tparam ScalarT Element Types -// \tparam IndicesV Swizzle Order +/// +/// \brief Backing storage struct for \ref fennec::swizzle "swizzle" +/// \tparam DataT Data Type +/// \tparam ScalarT Element Types +/// \tparam IndicesV Swizzle Order template struct swizzle_storage { - // - // \brief an array containing the indices of this swizzle + /// + /// \brief an array containing the indices of this swizzle inline static constexpr size_t indices[] = { IndicesV... }; - // - // \brief an array containing the scalar values of this swizzle + /// + /// \brief an array containing the scalar values of this swizzle DataT data; - // - // \brief element access, returns a copy of the value at index \p i - // \param i the index - // \returns a copy of the scalar value at index \p i + /// + /// \brief element access, returns a copy of the value at index \p i + /// \param i the index + /// \returns a copy of the scalar value at index \p i constexpr ScalarT operator[](size_t i) const noexcept { return data[indices[i]]; } diff --git a/include/fennec/math/vector.h b/include/fennec/math/vector.h index 0943cc8..73b95ae 100644 --- a/include/fennec/math/vector.h +++ b/include/fennec/math/vector.h @@ -46,33 +46,33 @@ /// ///
Type Corresponding Type Brief ///
Floats -///
```vec2``` \ref fennec::vec2 \copybrief fennec::vec2 -///
```vec3``` \ref fennec::vec3 \copybrief fennec::vec3 -///
```vec4``` \ref fennec::vec4 \copybrief fennec::vec4 +///
``\f$vec2\f$`` \ref fennec::vec2 \copybrief fennec::vec2 +///
``\f$vec3\f$`` \ref fennec::vec3 \copybrief fennec::vec3 +///
``\f$vec4\f$`` \ref fennec::vec4 \copybrief fennec::vec4 ///
Doubles -///
```dvec2```\ref fennec::dvec2 \copybrief fennec::dvec2 -///
```dvec3```\ref fennec::dvec3 \copybrief fennec::dvec3 -///
```dvec4```\ref fennec::dvec4 \copybrief fennec::dvec4 +///
``\f$dvec2\f$``\ref fennec::dvec2 \copybrief fennec::dvec2 +///
``\f$dvec3\f$``\ref fennec::dvec3 \copybrief fennec::dvec3 +///
``\f$dvec4\f$``\ref fennec::dvec4 \copybrief fennec::dvec4 ///
Booleans -///
```bvec2``` \ref fennec::bvec2 \copybrief fennec::bvec2 -///
```bvec3``` \ref fennec::bvec3 \copybrief fennec::bvec3 -///
```bvec4``` \ref fennec::bvec4 \copybrief fennec::bvec4 +///
``\f$bvec2\f$`` \ref fennec::bvec2 \copybrief fennec::bvec2 +///
``\f$bvec3\f$`` \ref fennec::bvec3 \copybrief fennec::bvec3 +///
``\f$bvec4\f$`` \ref fennec::bvec4 \copybrief fennec::bvec4 ///
Integers -///
```ivec2``` \ref fennec::ivec2 \copybrief fennec::ivec2 -///
```ivec3``` \ref fennec::ivec3 \copybrief fennec::ivec3 -///
```ivec4``` \ref fennec::ivec4 \copybrief fennec::ivec4 +///
``\f$ivec2\f$`` \ref fennec::ivec2 \copybrief fennec::ivec2 +///
``\f$ivec3\f$`` \ref fennec::ivec3 \copybrief fennec::ivec3 +///
``\f$ivec4\f$`` \ref fennec::ivec4 \copybrief fennec::ivec4 ///
Unsigned Integers -///
```uvec2``` \ref fennec::uvec2 \copybrief fennec::uvec2 -///
```uvec3``` \ref fennec::uvec3 \copybrief fennec::uvec3 -///
```uvec4``` \ref fennec::uvec4 \copybrief fennec::uvec4 +///
``\f$uvec2\f$`` \ref fennec::uvec2 \copybrief fennec::uvec2 +///
``\f$uvec3\f$`` \ref fennec::uvec3 \copybrief fennec::uvec3 +///
``\f$uvec4\f$`` \ref fennec::uvec4 \copybrief fennec::uvec4 ///
/// /// /// /// \section vector_components Components /// -/// Vectors are usually made up of one to four components, named ```x```, ```y```, ```z```, and ```w```. -/// Each component also has aliases for usage in colors ```rgba```, and texture coordinates ```stpq```. Accessing a +/// Vectors are usually made up of one to four components, named ``\f$x\f$``, ``\f$y\f$``, ``\f$z\f$``, and ``\f$w\f$``. +/// Each component also has aliases for usage in colors ``\f$rgba\f$``, and texture coordinates ``\f$stpq\f$``. Accessing a /// component outside the vector will cause an error at compile time, for example: /// /// \code{.cpp} diff --git a/include/fennec/math/vector_base.h b/include/fennec/math/vector_base.h index 5313936..4c92624 100644 --- a/include/fennec/math/vector_base.h +++ b/include/fennec/math/vector_base.h @@ -30,54 +30,55 @@ namespace fennec::detail { -// -// \brief helper class for generating vectors -// \tparam scalar base scalar type -// \tparam size size of the vector type +/// +/// \brief helper class for generating vectors +/// \tparam scalar base scalar type +/// \tparam size size of the vector type template struct vector_base_type_helper { - // - // \var SizeV - // \brief size of the vector type + /// + /// \var SizeV + /// \brief size of the vector type inline static constexpr size_t SizeV = size; - // - // \brief Base scalar type + /// + /// \brief Base scalar type using ScalarT = scalar; - // - // \brief Base vector type + /// + /// \brief Base vector type using VectorT = vec; - // - // \brief Backing array holding the elements + /// + /// \brief Backing array holding the elements using DataT = array; - // - // \brief Helper for generating a swizzle from a set of indices - // \tparam IndicesV Indices of the vector to pull from + /// + /// \brief Helper for generating a swizzle from a set of indices + /// \tparam IndicesV Indices of the vector to pull from template struct SwizzleGen { // \brief generated swizzle type using type = swizzle; }; - // Specialization for single component swizzles to decay into a scalar + /// + /// \tparam IndicesV Indices of the vector to pull from template struct SwizzleGen { // \brief decayed scalar type using type = ScalarT; }; - // - // \brief backing storage type + /// + /// \brief backing storage type using StorageT = vector_storage; }; -// -// \brief helper for getting the storage type of the vector constructed with the provided size and scalar type +/// +/// \brief helper for getting the storage type of the vector constructed with the provided size and scalar type template using vector_base_type = typename vector_base_type_helper::StorageT; diff --git a/include/fennec/math/vector_storage.h b/include/fennec/math/vector_storage.h index b8225ed..8e3de31 100644 --- a/include/fennec/math/vector_storage.h +++ b/include/fennec/math/vector_storage.h @@ -33,15 +33,16 @@ namespace fennec::detail { - // - // \brief backing storage type for vectors - // \tparam SizeV size of the vector - // \tparam SwizzleGenT generator for swizzles - // \tparam DataT backing data type + /// + /// \brief backing storage type for vectors + /// \tparam SizeV size of the vector + /// \tparam SwizzleGenT generator for swizzles + /// \tparam DataT backing data type template class SwizzleGenT, typename DataT> struct vector_storage; - - // specialization for single component vectors + /// + /// \tparam SwizzleGenT generator for swizzles + /// \tparam DataT backing data type template