From 7c2f89b33114b393547f04a8c5caf42b79521e40 Mon Sep 17 00:00:00 2001 From: Medusa Slockbower Date: Fri, 2 Jan 2026 15:38:03 -0500 Subject: [PATCH] - A few Vulkan wrapper structs - Framework for Vulkan context - Fixed a bug with dynarray where if `resize()` shrinks the array, destructors are not called. - Fixed grammar issues with the containers library and added property tables to existing data structures. --- CMakeLists.txt | 11 +- cmake/vulkan.cmake | 3 + include/fennec/containers/array.h | 43 ++-- include/fennec/containers/bintree.h | 37 ++- include/fennec/containers/bitfield.h | 16 ++ include/fennec/containers/containers.h | 17 ++ include/fennec/containers/deque.h | 36 +-- include/fennec/containers/dynarray.h | 100 ++++++--- include/fennec/containers/generic.h | 28 ++- include/fennec/containers/graph.h | 42 ++-- include/fennec/containers/list.h | 122 +++++----- include/fennec/containers/map.h | 30 +-- include/fennec/containers/object_pool.h | 21 +- include/fennec/containers/optional.h | 17 +- include/fennec/containers/pair.h | 15 ++ include/fennec/containers/priority_queue.h | 23 +- include/fennec/containers/rdtree.h | 33 ++- include/fennec/containers/sequence.h | 32 +-- include/fennec/containers/set.h | 28 +-- include/fennec/containers/tuple.h | 26 +-- include/fennec/containers/variant.h | 15 ++ include/fennec/core/version.h | 16 +- include/fennec/filesystem/path.h | 10 +- include/fennec/memory/pointers.h | 2 +- .../fennec/renderers/interface/gfxcontext.h | 4 - include/fennec/renderers/interface/gfxpass.h | 60 ----- .../renderers/interface/gfxresourcepool.h | 43 ---- .../fennec/renderers/interface/gfxsubpass.h | 41 ---- include/fennec/renderers/opengl/glcontext.h | 3 - .../fennec/renderers/vulkan/lib/app_info.h | 210 ++++++++++++++++++ .../fennec/renderers/vulkan/lib/instance.h | 89 ++++++++ include/fennec/renderers/vulkan/vkcontext.cpp | 1 - include/fennec/renderers/vulkan/vkcontext.h | 5 +- include/fennec/rtti/type_data.h | 2 +- include/fennec/string/cstring.h | 10 +- include/fennec/string/string.h | 2 +- include/fennec/string/wcstring.h | 2 +- include/fennec/string/wstring.h | 2 +- include/fennec/threading/mpscq.h | 2 +- source/filesystem/path.cpp | 2 +- source/lang/assert.cpp | 2 +- source/platform/linux/wayland/server.cpp | 6 +- source/platform/window_manager.cpp | 2 +- source/renderers/opengl/glcontext.cpp | 3 - source/scene/scene.cpp | 4 +- test/tests/containers/test_bintree.h | 4 +- test/tests/containers/test_deque.h | 2 +- test/tests/containers/test_graph.h | 2 +- test/tests/containers/test_list.h | 4 +- test/tests/containers/test_object_pool.h | 2 +- test/tests/containers/test_rdtree.h | 4 +- test/tests/containers/test_sequence.h | 2 +- test/tests/test_threading.h | 2 +- 53 files changed, 825 insertions(+), 415 deletions(-) delete mode 100644 include/fennec/renderers/interface/gfxpass.h delete mode 100644 include/fennec/renderers/interface/gfxresourcepool.h delete mode 100644 include/fennec/renderers/interface/gfxsubpass.h create mode 100644 include/fennec/renderers/vulkan/lib/app_info.h create mode 100644 include/fennec/renderers/vulkan/lib/instance.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9034c0e..1abf6de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${FENNEC_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME} # Core Files fennec_add_sources( - # CORE ================================================================================================================= +# CORE ================================================================================================================= include/fennec/core/engine.h source/core/engine.cpp include/fennec/core/event.h source/core/event.cpp include/fennec/core/logger.h source/core/logger.cpp @@ -91,7 +91,7 @@ fennec_add_sources( include/fennec/core/system.h - # SCENE ================================================================================================================ +# SCENE ================================================================================================================ include/fennec/scene/scene.h source/scene/scene.cpp include/fennec/scene/component.h include/fennec/scene/scene_node.h @@ -100,15 +100,14 @@ fennec_add_sources( - # RENDERERS ============================================================================================================ +# RENDERERS ============================================================================================================ include/fennec/renderers/interface/forward.h include/fennec/renderers/interface/gfxcontext.h - include/fennec/renderers/interface/gfxsubpass.h - include/fennec/renderers/interface/gfxresourcepool.h + include/fennec/renderers/interface/gfxsurface.h - # CONTAINERS =========================================================================================================== +# CONTAINERS =========================================================================================================== include/fennec/containers/containers.h include/fennec/containers/array.h diff --git a/cmake/vulkan.cmake b/cmake/vulkan.cmake index be0c568..b5acbe7 100644 --- a/cmake/vulkan.cmake +++ b/cmake/vulkan.cmake @@ -30,6 +30,9 @@ if( TARGET Vulkan::Headers AND TARGET Vulkan::volk # Base Headers and Meta-Loade fennec_add_definitions(FENNEC_GRAPHICS_VULKAN=1) fennec_add_sources( + include/fennec/renderers/vulkan/lib/app_info.h + include/fennec/renderers/vulkan/lib/instance.h + include/fennec/renderers/vulkan/vkcontext.h include/fennec/renderers/vulkan/vkcontext.cpp ) else() diff --git a/include/fennec/containers/array.h b/include/fennec/containers/array.h index 6125e15..5f926db 100644 --- a/include/fennec/containers/array.h +++ b/include/fennec/containers/array.h @@ -44,19 +44,19 @@ namespace fennec /// \brief Data Structure that defines a compile-time allocated array /// /// \details -/// | Property | Value | -/// |:----------:|:-----------:| -/// | stable | ✅ | -/// | dynamic | ⛔ | -/// | homogenous | ✅ | -/// | distinct | ⛔ | -/// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | -/// | linear | ✅ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(N)\f$ | -/// | insertion | ⛔ | -/// | deletion | ⛔ | +/// | Property | Value | +/// |:-----------:|:-----------:| +/// | stable | ✅ | +/// | dynamic | ⛔ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(N)\f$ | +/// | insertion | ⛔ | +/// | deletion | ⛔ | /// /// \tparam ValueT value type /// \tparam ElemV number of elements @@ -65,9 +65,18 @@ struct array { // Definitions ========================================================================================================= public: + + /// \name Definitions + /// @{ + using value_t = ValueT; ///< Alias for \f$ValueT\f$ + /// @} + + + // Public Members ====================================================================================================== +public: /// \name Public Members /// @{ @@ -81,6 +90,7 @@ public: // Properties ========================================================================================================== +public: /// \name Properties /// @{ @@ -93,13 +103,14 @@ public: /// /// \brief returns **true** when the array is empty /// \return \f$ElemV == 0\f$ - [[nodiscard]] constexpr bool_t empty() const { return ElemV == 0; } + [[nodiscard]] constexpr bool_t is_empty() const { return ElemV == 0; } /// @} // Access ============================================================================================================== +public: /// \name Element Access /// @{ @@ -168,6 +179,7 @@ public: // Comparison ========================================================================================================== +public: /// \name Comparison Operators /// @{ @@ -188,6 +200,7 @@ public: // Iteration =========================================================================================================== +public: /// \name Iteration /// @{ @@ -224,6 +237,8 @@ public: /// @} + +// Helpers ============================================================================================================= private: template static bool _compare(const array& lhs, const array& rhs, index_metasequence) { diff --git a/include/fennec/containers/bintree.h b/include/fennec/containers/bintree.h index 5269b5c..23f7ddc 100644 --- a/include/fennec/containers/bintree.h +++ b/include/fennec/containers/bintree.h @@ -42,6 +42,22 @@ namespace fennec /// /// \brief Structure defining a binary tree +/// +/// \details +/// | Property | Value | +/// |:-----------:|:-----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ⛔ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(N)\f$ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | +/// /// \tparam TypeT The data type /// \tparam AllocT An allocator class template> @@ -52,10 +68,15 @@ private: struct node; public: + /// \name Definitions + /// @{ + 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; @@ -145,7 +166,7 @@ public: /// /// \returns \f$true\f$ when there are no elements in the tree, \f$false\f$ otherwise. - constexpr bool empty() const { + constexpr bool is_empty() const { return _size == 0; } @@ -159,7 +180,7 @@ public: /// \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()) { + if (not _freed.is_empty()) { i = _freed.front(); } return i; @@ -455,7 +476,7 @@ public: queue.push_back(_root); } - while (not queue.empty()) { + while (not queue.is_empty()) { size_t i = queue.front(); queue.pop_front(); @@ -540,7 +561,7 @@ public: visit.push_back(chd); } - if (not visit.empty()) { + if (not visit.is_empty()) { node = visit.front(); visit.pop_front(); } else { @@ -591,7 +612,7 @@ public: visit.push_front(chd); } - if (not visit.empty()) { + if (not visit.is_empty()) { node = visit.front(); visit.pop_front(); } else { @@ -642,7 +663,7 @@ public: visit.push_front(next); } - if (not visit.empty()) { + if (not visit.is_empty()) { node = visit.front(); visit.pop_front(); } else { @@ -692,7 +713,7 @@ public: visit.push_front(this->_successor(tree, pright)); } - if (not visit.empty()) { + if (not visit.is_empty()) { node = visit.front(); visit.pop_front(); } else { @@ -926,7 +947,7 @@ private: constexpr size_t _next_free() { size_t i = _size; - if (not _freed.empty()) { + if (not _freed.is_empty()) { i = _freed.front(); _freed.pop_front(); } diff --git a/include/fennec/containers/bitfield.h b/include/fennec/containers/bitfield.h index 3e5ae25..25bc8ee 100644 --- a/include/fennec/containers/bitfield.h +++ b/include/fennec/containers/bitfield.h @@ -40,6 +40,22 @@ namespace fennec /// /// \brief Bitfield Container with basic Bit Ops +/// +/// \details +/// | Property | Value | +/// |:-----------:|:------------------------------:| +/// | stable | Elements cannot be referenced. | +/// | dynamic | ⛔ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(N)\f$ | +/// | insertion | ⛔ | +/// | deletion | ⛔ | +/// /// \tparam N The number of bits in the bitfield template struct bitfield { diff --git a/include/fennec/containers/containers.h b/include/fennec/containers/containers.h index 6b1459d..63070cf 100644 --- a/include/fennec/containers/containers.h +++ b/include/fennec/containers/containers.h @@ -40,6 +40,23 @@ /// /// \code #include \endcode /// +/// \section Data Structure Properties +/// +/// | Property | Meaning | +/// |:-----------:|:----------------------------------------------------------------------------------------------:| +/// | stable | Any pointer reference to an element remains constant for the lifetime of the data structure. | +/// | dynamic | Memory for this data structure is allocated on the heap. | +/// | homogeneous | The types of all elements are either identical, or inherit the same base type. | +/// | distinct | Elements are guaranteed to be unique in their value. | +/// | ordered | Elements are guaranteed to be in order, such that for any index \f$i\f$, \f$E_i < E_{i + 1}\f$ | +/// | space | The amount of memory allocated with respect to the number of elements, in big-O notation. | +/// | linear | Each element is sequential in terms of access. | +/// | access | The runtime of the access operators and functions, in big-O notation. | +/// | find | The runtime of finding an element in the data structure, in big-O notation. | +/// | insertion | The runtime of inserting an element in the data structure, in big-O notation. | +/// | deletion | The runtime of erasing an element in the data structure, in big-O notation. | +/// +/// /// \section fennec_containers_cppstdlib C++ Standard Template Library /// /// | Symbol | Implemented | Passed | diff --git a/include/fennec/containers/deque.h b/include/fennec/containers/deque.h index 0d02495..cb2cca1 100644 --- a/include/fennec/containers/deque.h +++ b/include/fennec/containers/deque.h @@ -46,19 +46,19 @@ namespace fennec /// This behaves the similar to fennec::list, however it does not allow arbitrary access, insertion, or deletion. /// It is one of the few data structures in this library that is stable, i.e. pointers to elements do not change. /// -/// | Property | Value | -/// |:----------:|:----------:| -/// | stable | ✅ | -/// | dynamic | ✅ | -/// | homogenous | ✅ | -/// | distinct | ⛔ | -/// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | -/// | linear | ⛔ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(N)\f$ | -/// | insertion | \f$O(1)\f$ | -/// | deletion | \f$O(1)\f$ | +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ✅ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ⛔ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(N)\f$ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | /// /// \tparam TypeT value type template> @@ -154,7 +154,7 @@ public: /// /// \returns \f$true\f$ when the deque is empty, \f$false\f$ otherwise - constexpr bool empty() const { + constexpr bool is_empty() const { return _size == 0; } @@ -175,28 +175,28 @@ public: /// /// \returns a reference to the first element in the deque value_t& front() { - assert(not empty(), "Attempted to access an empty deque."); + assert(not is_empty(), "Attempted to access an empty deque."); return _first->value; } /// /// \returns a const-qualified reference to the first element in the deque const value_t& front() const { - assert(not empty(), "Attempted to access an empty deque."); + assert(not is_empty(), "Attempted to access an empty deque."); return _first->value; } /// /// \returns a reference to the last element in the deque value_t& back() { - assert(not empty(), "Attempted to access an empty deque."); + assert(not is_empty(), "Attempted to access an empty deque."); return _last->value; } /// /// \returns a const-qualified reference to the last element in the deque const value_t& back() const { - assert(not empty(), "Attempted to access an empty deque."); + assert(not is_empty(), "Attempted to access an empty deque."); return _last->value; } diff --git a/include/fennec/containers/dynarray.h b/include/fennec/containers/dynarray.h index 9ef8057..d881517 100644 --- a/include/fennec/containers/dynarray.h +++ b/include/fennec/containers/dynarray.h @@ -43,34 +43,34 @@ namespace fennec /// /// \brief Wrapper for dynamically sized and allocated arrays /// \details -/// | Property | Value | -/// |:----------:|:----------:| -/// | stable | ⛔ | -/// | dynamic | ✅ | -/// | homogenous | ✅ | -/// | distinct | ⛔ | -/// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | -/// | linear | ✅ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(N)\f$ | -/// | insertion | \f$O(N)\f$ | -/// | deletion | \f$O(N)\f$ | +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(N)\f$ | +/// | insertion | \f$O(N)\f$ | +/// | deletion | \f$O(N)\f$ | /// /// This structure prefers shallow moves and deep copies. /// /// \tparam TypeT value type template> struct dynarray { -public: // Definitions ========================================================================================================= - +public: using value_t = TypeT; ///< Alias for the value type using alloc_t = Alloc; ///< Alias for the allocator type // Constructors ======================================================================================================== +public: /// \name Constructors & Destructor /// @{ @@ -260,6 +260,7 @@ public: /// @} // Assignment ========================================================================================================== +public: /// \name Properties /// @{ @@ -322,6 +323,7 @@ public: /// @} // Properties ========================================================================================================== +public: /// \name Properties /// @{ @@ -340,7 +342,7 @@ public: /// /// \returns True when there are no elements active, otherwise false - constexpr bool empty() const { + constexpr bool is_empty() const { return _size == 0; } @@ -348,6 +350,7 @@ public: // Element Access ====================================================================================================== +public: /// \name Access /// @{ @@ -358,7 +361,7 @@ public: /// \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]; + return _alloc[i]; } /// @@ -367,7 +370,7 @@ public: /// \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]; + return _alloc[i]; } /// @@ -394,10 +397,23 @@ public: return this->operator[](size() - 1); } + /// + /// \returns A pointer to the underlying allocation + constexpr TypeT* data() { + return _alloc.data(); + } + + /// + /// \returns A pointer to the underlying allocation + constexpr const TypeT* data() const { + return _alloc.data(); + } + /// @} // Modifiers =========================================================================================================== +public: /// \name Modifiers /// @{ @@ -510,31 +526,47 @@ public: /// \brief Resize the dynarray, invoking the default constructor for all new elements /// \param n The new size in elements constexpr void resize(size_t n) { + _reduce(n); _alloc.creallocate(n); - while (_size < n) { - emplace_back(); + for (size_t i = _size; i < n; ++i) { + fennec::construct(&_alloc[i]); } + + _size = n; } /// /// \brief Resize the dynarray, invoking the copy constructor for all new elements /// \param n The new size in elements /// \param val The value to fill with + /// + /// \details if \f$n\f$ is less than the current size, any elements that would be removed are destructed constexpr void resize(size_t n, const TypeT& val) { + _reduce(n); _alloc.creallocate(n); - while (_size < n) { - emplace_back(val); + for (size_t i = _size; i < n; ++i) { + fennec::construct(&_alloc[i], val); } + + _size = n; + } + + /// + /// \brief Reserve the array, allocating new space without initialization + /// \param n The new capacity in elements + /// + /// \details if \f$n\f$ is less than the current size, any elements that would be removed are destructed + constexpr void reserve(size_t n) { + _reduce(n); + _alloc.creallocate(n); } /// /// \brief Clears the contents of the dynarray, destructing all elements and releasing the allocation. constexpr void clear() { - while (_size > 0) { - fennec::destruct(&_alloc[--_size]); - } + _reduce(0); _alloc.deallocate(); } @@ -542,6 +574,7 @@ public: // Iteration =========================================================================================================== +public: /// \name Iteration /// @{ @@ -567,13 +600,26 @@ public: /// @} +// Private Members ===================================================================================================== private: + allocation _alloc; + size_t _size; + + +// Private Helpers ===================================================================================================== +private: + + // helper to double the capacity of the allocation constexpr void _grow() { _alloc.creallocate(_alloc.capacity() * 2); } - allocation _alloc; - size_t _size; + // helper to destruct elements past n + constexpr void _reduce(size_t n) { + while (_size > n) { + fennec::destruct(&_alloc[--_size]); + } + } }; } diff --git a/include/fennec/containers/generic.h b/include/fennec/containers/generic.h index 50261a4..dc501dd 100644 --- a/include/fennec/containers/generic.h +++ b/include/fennec/containers/generic.h @@ -39,6 +39,20 @@ namespace fennec /// /// \brief A struct capable of holding a single object of any type +/// \details +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ✅ | +/// | dynamic | ⛔ | +/// | homogeneous | ⛔ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(1)\f$ | +/// | linear | ✅ | +/// | access | \f$O(1)\f$ | +/// | find | ⛔ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | struct generic { // Definitions ========================================================================================================= @@ -114,6 +128,7 @@ public: // Properties ========================================================================================================== +public: /// /// \brief runtime type acquisition @@ -130,6 +145,7 @@ public: // Assignment ========================================================================================================== +public: /// /// \brief copy assignment @@ -169,7 +185,8 @@ public: } -// Utility ============================================================================================================= +// Insertion & Deletion ================================================================================================ +public: /// /// \brief emplace value @@ -195,6 +212,10 @@ public: } } + +// Utility ============================================================================================================= +public: + /// /// \brief C++ 11 Swap Specification /// \param gen the generic to swap with @@ -223,10 +244,15 @@ public: return static_cast(*static_cast(_handle)); } + +// Members ============================================================================================================= private: void* _handle; manager_t _manage; + +// Helpers ============================================================================================================= +private: template static void* _manage_impl(uint8_t op, void* hnd) { static fennec::type t = type::get(); diff --git a/include/fennec/containers/graph.h b/include/fennec/containers/graph.h index aa3daac..f451fd2 100644 --- a/include/fennec/containers/graph.h +++ b/include/fennec/containers/graph.h @@ -55,19 +55,19 @@ namespace fennec /// \brief Graph Data Structure, describes sets of arbitrarily connected vertices /// /// \details -/// | Property | Value | -/// |:----------:|:----------:| -/// | stable | ⛔ | -/// | dynamic | ✅ | -/// | homogenous | ✅ | -/// | distinct | ⛔ | -/// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | -/// | linear | ✅ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(1)\f$ | -/// | insertion | \f$O(1)\f$ | -/// | deletion | \f$O(N)\f$ | +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(1)\f$ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(M)\f$ | /// /// Graphs contain vertices and edges. Graphs are either directed /// or undirected. This structure allows the creation of both directed and undirected edges. As @@ -160,7 +160,7 @@ public: /// /// \returns \f$true\f$ when there are no vertices in the graph, \f$false\f$ otherwise - constexpr bool empty() const { + constexpr bool is_empty() const { return num_vertices() == 0; } @@ -229,7 +229,7 @@ public: /// \param b The id of the second vertex /// \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()) { + if (is_empty()) { return nullptr; } edge_t* it = _edge_map[a][b]; @@ -245,7 +245,7 @@ public: /// \param b The id of the second vertex /// \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()) { + if (is_empty()) { return nullptr; } const edge_t* it = _edge_map[a][b]; @@ -261,7 +261,7 @@ public: /// \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()) { + if (is_empty() || vertex >= _edge_map.size()) { return res; } for (const auto& it : _edge_map[vertex]) { @@ -276,7 +276,7 @@ public: /// \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()) { + if (is_empty() || vertex >= _edge_map.size()) { return res; } for (size_t n = 0; n < _edge_map.size(); ++n) { @@ -293,7 +293,7 @@ public: /// \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()) { + if (is_empty() || vertex >= _edge_map.size()) { return res; } for (const auto& it : _edge_map[vertex]) { @@ -314,7 +314,7 @@ public: /// \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()) { + if (is_empty() || vertex >= _edge_map.size()) { return res; } for (const auto& it : _edge_map[vertex]) { @@ -332,7 +332,7 @@ public: /// \param vertex The id of the vertex /// \returns A pointer to a map containing edges mapped from this vertex const auto* edges(size_t vertex) { - if (empty() || vertex >= _edge_map.size()) { + if (is_empty() || vertex >= _edge_map.size()) { return nullptr; } return &_edge_map[vertex]; diff --git a/include/fennec/containers/list.h b/include/fennec/containers/list.h index a7bac0b..b6951ae 100644 --- a/include/fennec/containers/list.h +++ b/include/fennec/containers/list.h @@ -48,19 +48,22 @@ namespace fennec /// This data-structure behaves like a linked list, but does not use pointers. Instead, it is in-array. This creates the /// following properties: /// -/// | Property | Value | -/// |:----------:|:----------:| -/// | stable | ⛔ | -/// | dynamic | ✅ | -/// | homogenous | ✅ | -/// | distinct | ⛔ | -/// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | -/// | linear | ✅ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(N)\f$ | -/// | insertion | \f$O(N)\f$ | -/// | deletion | \f$O(N)\f$ | +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(N)\f$ | +/// | find | \f$O(N)\f$ | +/// | insertion | \f$O(N)\f$ | +/// | deletion | \f$O(N)\f$ | +/// +/// \note Access, Insertion, and Deletion are \f$O(N)\f$ using the index pattern, +/// using the iterator pattern yields \f$O(1)\f$ runtime. /// /// \tparam TypeT value type template> @@ -82,8 +85,13 @@ public: class iterator; ///< Iterator type for forward iteration over the list class const_iterator; ///< Iterator type for forward iteration over a constant list +private: + using table_t = dynarray; + using freed_t = dynarray; + // Constructors & Destructor =========================================================================================== +public: /// \name Constructors & Destructor /// @{ @@ -127,6 +135,7 @@ public: /// @} // Assignment ========================================================================================================== +public: /// \name Assignment /// @{ @@ -160,6 +169,7 @@ public: // Properties ========================================================================================================== +public: /// \name Properties /// @{ @@ -173,12 +183,12 @@ public: /// /// \returns The capacity of the list in elements. constexpr size_t capacity() const { - return _table.capacity(); + return _table.size(); } /// /// \returns \f$true\f$ when the list is empty, \f$false\f$ otherwise. - constexpr bool empty() const { + constexpr bool is_empty() const { return _root == npos; } @@ -186,6 +196,7 @@ public: // Access ============================================================================================================== +public: /// \name Access /// @{ @@ -248,6 +259,7 @@ public: // Modifiers =========================================================================================================== +public: /// \name Modifiers /// @{ @@ -259,7 +271,7 @@ public: /// \returns The id of the inserted node /// /// \details \f$O(1)\f$ - constexpr size_t insert(const iterator& it, const value_t& x) { + constexpr iterator insert(const iterator& it, const value_t& x) { return this->_insert(it._n, x); } @@ -270,7 +282,7 @@ public: /// \returns The id of the inserted node /// /// \details \f$O(1)\f$ - constexpr size_t insert(const iterator& it, value_t&& x) { + constexpr iterator insert(const iterator& it, value_t&& x) { return this->_insert(it._n, fennec::forward(x)); } @@ -281,7 +293,7 @@ public: /// \returns The id of the inserted node /// /// \details \f$O(N)\f$ - constexpr size_t insert(size_t i, const value_t& x) { + constexpr iterator insert(size_t i, const value_t& x) { assert(i <= size(), "Index out of Bounds"); size_t n = _walk(min(i, size_t(size() - 1))); @@ -295,7 +307,7 @@ public: /// \returns The id of the inserted node /// /// \details \f$O(N)\f$ - constexpr size_t insert(size_t i, value_t&& x) { + constexpr iterator insert(size_t i, value_t&& x) { assert(i <= size(), "Index out of Bounds"); size_t n = _walk(min(i, size_t(size() - 1))); @@ -311,18 +323,31 @@ public: /// /// \details \f$O(N)\f$ template - constexpr size_t emplace(size_t i, ArgsT&&...args) { + constexpr iterator emplace(size_t i, ArgsT&&...args) { assert(i <= size(), "Index out of Bounds"); size_t n = _walk(min(i, size_t(size() - 1))); return this->_insert(n, fennec::forward(args)...); } + /// + /// \brief Emplace Insertion + /// \tparam ArgsT Argument types + /// \param it Location to insert at + /// \param args Arguments to construct with + /// \returns The id of the inserted node + /// + /// \details \f$O(N)\f$ + template + constexpr iterator emplace(const iterator& it, ArgsT&&...args) { + return this->_insert(it._n, fennec::forward(args)...); + } + /// /// \brief Push Front Copy /// \param x Value to copy /// \returns The id of the inserted node - constexpr size_t push_front(const value_t& x) { + constexpr iterator push_front(const value_t& x) { return this->_insert(_root, x); } @@ -330,7 +355,7 @@ public: /// \brief Push Front Move /// \param x Value to move /// \returns The id of the inserted node - constexpr size_t push_front(value_t&& x) { + constexpr iterator push_front(value_t&& x) { return this->_insert(_root, fennec::forward(x)); } @@ -340,7 +365,7 @@ public: /// \tparam ArgsT Argument types /// \returns The id of the inserted node template - constexpr size_t emplace_front(ArgsT&&...args) { + constexpr iterator emplace_front(ArgsT&&...args) { return this->_insert(_root, fennec::forward(args)...); } @@ -348,7 +373,7 @@ public: /// \brief Push Back Copy /// \param x Value to copy /// \returns The id of the inserted node - constexpr size_t push_back(const value_t& x) { + constexpr iterator push_back(const value_t& x) { return this->_insert(npos, x); } @@ -356,7 +381,7 @@ public: /// \brief Push Back Move /// \param x Value to move /// \returns The id of the inserted node - constexpr size_t push_back(value_t&& x) { + constexpr iterator push_back(value_t&& x) { return this->_insert(npos, fennec::forward(x)); } @@ -366,7 +391,7 @@ public: /// \tparam ArgsT Argument types /// \returns The id of the inserted node template - constexpr size_t emplace_back(ArgsT&&...args) { + constexpr iterator emplace_back(ArgsT&&...args) { return this->_insert(npos, fennec::forward(args)...); } @@ -383,7 +408,7 @@ public: /// \brief Erase Element /// \param it Location to Erase constexpr void erase(const iterator& it) { - _erase(it._n); + this->_erase(it._n); } /// @@ -403,15 +428,16 @@ public: constexpr void clear() { size_t i = _root; while (i != npos) { - fennec::destruct(&_table[i]); + _table[i].value = nullopt; i = this->_next(i); } - _table.deallocate(); + _table.clear(); } /// @} -// ITERATOR ============================================================================================================ +// Iterator ============================================================================================================ +public: /// \name Iteration /// @{ @@ -587,15 +613,19 @@ public: } }; +// Members ============================================================================================================= private: - allocation _table; - dynarray _freed; + table_t _table; + freed_t _freed; size_t _root, _last, _size; friend class iterator; + +// Helpers ============================================================================================================= +private: constexpr void _expand() { - _table.creallocate(fennec::max(_table.capacity(), size_t(1)) * 2); + _table.resize(fennec::max(_table.size(), size_t(4)) * 2); } struct node { @@ -608,18 +638,6 @@ private: , next(npos) { } - constexpr node(size_t p, size_t n) - : value() - , prev(p) - , next(n) { - } - - constexpr node(size_t p, size_t n, value_t&& val) - : value(fennec::forward(val)) - , prev(p) - , next(n) { - } - constexpr ~node() = default; constexpr void clear() { @@ -647,7 +665,7 @@ private: } constexpr size_t _next_free() { - if (not _freed.empty()) { + if (not _freed.is_empty()) { size_t n = _freed.back(); _freed.pop_back(); return n; @@ -656,20 +674,20 @@ private: } template - constexpr size_t _insert(size_t n, ArgsT&&...args) { + constexpr iterator _insert(size_t n, ArgsT&&...args) { if (size() == capacity()) { _expand(); } size_t i = _next_free(); ++_size; - fennec::construct(&_table[i].value, fennec::forward(args)...); + _table[i].value.emplace(fennec::forward(args)...); if (_root == npos) { _table[i].prev = npos; _table[i].next = npos; _root = _last = i; - return i; + return iterator(this, i); } if (n == npos) { @@ -677,20 +695,20 @@ private: _table[i].prev = _last; _table[i].next = npos; _last = i; - return i; + return iterator(this, i); } _table[i].prev = _prev(n); _table[i].next = n; _table[n].prev = i; _root = n == _root ? i : _root; - return i; + return iterator(this, i); } constexpr void _erase(size_t n) { if (n == npos) return; - fennec::destruct(&_table[n].value); + _table[n].value = nullopt; _freed.push_back(n); --_size; diff --git a/include/fennec/containers/map.h b/include/fennec/containers/map.h index 0a4e4f8..a3c8206 100644 --- a/include/fennec/containers/map.h +++ b/include/fennec/containers/map.h @@ -58,19 +58,21 @@ namespace fennec /// /// \brief Data Structure defining a mapping of \f$key\f$ \f$KeyT\f$ to \f$value\f$ \f$ValueT\f$ /// \details -/// | Property | Value | -/// |:----------:|:----------:| -/// | stable | ⛔ | -/// | dynamic | ✅ | -/// | homogenous | ✅ | -/// | distinct | ✅ | -/// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | -/// | linear | ✅ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(1)\f$ | -/// | insertion | \f$O(1)\f$ | -/// | deletion | \f$O(1)\f$ | +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ✅ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ⛔ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(1)\f$ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | +/// +/// \note These runtimes are amortized, in theory the worst case is \f$O(N)\f$, but that is highly improbable. /// /// \tparam KeyT The Key Type /// \tparam ValueT The Value Type @@ -146,7 +148,7 @@ public: /// /// \returns \f$true\f$ when there are no elements in the set, \f$false\f$ otherwise - constexpr size_t empty() const { + constexpr size_t is_empty() const { return _set.size(); } diff --git a/include/fennec/containers/object_pool.h b/include/fennec/containers/object_pool.h index fc455cf..1390001 100644 --- a/include/fennec/containers/object_pool.h +++ b/include/fennec/containers/object_pool.h @@ -40,6 +40,21 @@ namespace fennec /// /// \brief Struct which holds a pool of objects associated with ids +/// \details +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ⛔ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(N)\f$ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | +/// /// \tparam TypeT The value type /// \tparam AllocT The allocator type template> @@ -93,7 +108,7 @@ public: /// /// \returns \f$true\f$ when there are no objects in the pool, \f$false\f$ otherwise - constexpr bool empty() const { + constexpr bool is_empty() const { return size() == 0; } @@ -104,7 +119,7 @@ public: /// \returns The id of the next inserted node constexpr size_t next_id() const { size_t next = _size; - if (not _freed.empty()) { + if (not _freed.is_empty()) { next = _freed.front(); } return next; @@ -429,7 +444,7 @@ private: size_t _next_free() { size_t next = _size; - if (not _freed.empty()) { + if (not _freed.is_empty()) { next = _freed.front(); _freed.pop_front(); } diff --git a/include/fennec/containers/optional.h b/include/fennec/containers/optional.h index 989e34d..6181360 100644 --- a/include/fennec/containers/optional.h +++ b/include/fennec/containers/optional.h @@ -52,6 +52,21 @@ constexpr nullopt_t nullopt_v = {}; /// /// \brief Structure to hold an optional value. +/// \details +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ✅ | +/// | dynamic | ⛔ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ⛔ | +/// | access | \f$O(1)\f$ | +/// | find | ⛔ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | +/// /// \tparam T template struct optional { @@ -160,7 +175,7 @@ public: /// /// \returns \f$true\f$ when there is no held value, \f$false\f$ otherwise. - constexpr bool empty() const { + constexpr bool is_empty() const { return not _set; } diff --git a/include/fennec/containers/pair.h b/include/fennec/containers/pair.h index 67c6cdc..a608a9d 100644 --- a/include/fennec/containers/pair.h +++ b/include/fennec/containers/pair.h @@ -42,6 +42,21 @@ namespace fennec /// /// \brief Struct for holding a pair of values +/// \details +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ✅ | +/// | dynamic | ⛔ | +/// | homogeneous | ⛔ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(1)\f$ | +/// | find | ⛔ | +/// | insertion | ⛔ | +/// | deletion | ⛔ | +/// /// \tparam TypeT0 The type of the first value /// \tparam TypeT1 The type of the second value template diff --git a/include/fennec/containers/priority_queue.h b/include/fennec/containers/priority_queue.h index 3975eaf..a22d6c5 100644 --- a/include/fennec/containers/priority_queue.h +++ b/include/fennec/containers/priority_queue.h @@ -55,6 +55,21 @@ namespace fennec /// /// \brief a priority queue data structure implemented using a binary heap +/// \details +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ✅ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(1)\f$ | +/// | find | ⛔ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | +/// /// \tparam ValueT The value type /// \tparam CompareT The compare type, defaults to `fennec::less` /// \tparam AllocT The allocator type, defaults to `fennec::allocator` @@ -87,6 +102,7 @@ private: // Constructors & Destructor =========================================================================================== public: + /// /// \brief default constructor /// \details initializes an empty queue @@ -105,6 +121,7 @@ public: // Properties ========================================================================================================== +public: /// /// \returns the size of the queue @@ -120,12 +137,13 @@ public: /// /// \returns \f$true\f$ if the queue holds no elements - constexpr bool empty() const { + constexpr bool is_empty() const { return size() == 0; } // Access ============================================================================================================== +public: /// /// \returns the value at the front of the queue @@ -135,6 +153,7 @@ public: // Modifiers =========================================================================================================== +public: /// /// \brief push a new key into the queue @@ -173,7 +192,9 @@ private: alloc_t _table; size_t _size; + // Helpers ============================================================================================================= +private: template constexpr void _insert(ArgsT&&...args) { diff --git a/include/fennec/containers/rdtree.h b/include/fennec/containers/rdtree.h index 50f46eb..394df5c 100644 --- a/include/fennec/containers/rdtree.h +++ b/include/fennec/containers/rdtree.h @@ -43,6 +43,21 @@ namespace fennec /// /// \brief Rooted-Directed Tree +/// \details +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ⛔ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(N)\f$ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | +/// /// \tparam TypeT Data type /// \tparam AllocT Allocator Type template> @@ -177,7 +192,7 @@ public: /// /// \returns \f$true\f$ when there are no nodes in the tree, \f$false\f$ otherwise - constexpr bool empty() const { + constexpr bool is_empty() const { return _size == 0; } @@ -311,7 +326,7 @@ public: /// \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()) { + if (not _freed.is_empty()) { i = _freed.front(); } return i; @@ -365,7 +380,7 @@ public: visit.push_front({ root, parent }); size_t res = npos; - while (not visit.empty()) { + while (not visit.is_empty()) { auto node = visit.front(); visit.pop_front(); @@ -490,7 +505,7 @@ public: visit.push_back(chd); } - if (not visit.empty()) { + if (not visit.is_empty()) { node = visit.front(); visit.pop_front(); } else { @@ -540,7 +555,7 @@ public: visit.push_front(chd); } - if (not visit.empty()) { + if (not visit.is_empty()) { node = visit.front(); visit.pop_front(); } else { @@ -592,7 +607,7 @@ public: } } - if (not visit.empty()) { + if (not visit.is_empty()) { node = visit.front(); visit.pop_front(); } else { @@ -642,7 +657,7 @@ public: } } - if (not visit.empty()) { + if (not visit.is_empty()) { node = visit.front(); visit.pop_front(); } else { @@ -669,7 +684,7 @@ private: size_t _next_free() { size_t next = _size; - if (not _freed.empty()) { + if (not _freed.is_empty()) { next = _freed.front(); _freed.pop_front(); } @@ -723,7 +738,7 @@ private: constexpr void _erase(size_t i) { list queue; queue.push_back(child(i)); - while (not queue.empty()) { + while (not queue.is_empty()) { size_t n = queue.front(); queue.pop_front(); if (n == npos) continue; queue.push_back(next(n)); diff --git a/include/fennec/containers/sequence.h b/include/fennec/containers/sequence.h index e58896c..ce200ee 100644 --- a/include/fennec/containers/sequence.h +++ b/include/fennec/containers/sequence.h @@ -56,19 +56,19 @@ namespace fennec /// \details /// This data-structure behaves like an ordered-set, but does not use pointers, instead storing the table in-array /// -/// | Property | Value | -/// |:----------:|:---------------:| -/// | stable | ✅ | -/// | dynamic | ✅ | -/// | homogenous | ✅ | -/// | distinct | ✅ | -/// | ordered | ✅ | -/// | space | \f$O(N)\f$ | -/// | linear | ✅ | -/// | access | \f$O(\log N)\f$ | -/// | find | \f$O(\log N)\f$ | -/// | insertion | \f$O(\log N)\f$ | -/// | deletion | \f$O(\log N)\f$ | +/// | Property | Value | +/// |:-----------:|:---------------:| +/// | stable | ✅ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ✅ | +/// | ordered | ✅ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(\log N)\f$ | +/// | find | \f$O(\log N)\f$ | +/// | insertion | \f$O(\log N)\f$ | +/// | deletion | \f$O(\log N)\f$ | /// /// \tparam TypeT The type to contain /// \tparam CompareT Function for comparing two values @@ -282,7 +282,7 @@ public: /// /// \returns \f$true\f$ when there are no elements in the sequence, \f$false\f$ otherwise. - constexpr bool empty() const { + constexpr bool is_empty() const { return _size == 0; } @@ -414,7 +414,7 @@ public: it._visit.push_front(next); } - if (not it._visit.empty()) { + if (not it._visit.is_empty()) { it._node = it._visit.front(); it._visit.pop_front(); } else { @@ -513,7 +513,7 @@ public: it._visit.push_front(next); } - if (not it._visit.empty()) { + if (not it._visit.is_empty()) { it._node = it._visit.front(); it._visit.pop_front(); } else { diff --git a/include/fennec/containers/set.h b/include/fennec/containers/set.h index e69fd7f..a0088ad 100644 --- a/include/fennec/containers/set.h +++ b/include/fennec/containers/set.h @@ -49,19 +49,19 @@ namespace fennec /// \details /// This data-structure behaves like a set, but does not use pointers, instead storing the table in-array /// -/// | Property | Value | -/// |:----------:|:----------:| -/// | stable | ⛔ | -/// | dynamic | ✅ | -/// | homogenous | ✅ | -/// | distinct | ✅ | -/// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | -/// | linear | ✅ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(1)\f$ | -/// | insertion | \f$O(1)\f$ | -/// | deletion | \f$O(1)\f$ | +/// | Property | Value | +/// |:-----------:|:----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ✅ | +/// | distinct | ✅ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(1)\f$ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | /// /// \tparam TypeT The type to contain template, class Equals = equality, class Alloc = allocator> @@ -184,7 +184,7 @@ public: /// /// \returns \f$true\f$ when the set is empty, \f$false\f$ otherwise - constexpr bool empty() const { + constexpr bool is_empty() const { return _size == 0; } diff --git a/include/fennec/containers/tuple.h b/include/fennec/containers/tuple.h index 5f07edb..c90a24c 100644 --- a/include/fennec/containers/tuple.h +++ b/include/fennec/containers/tuple.h @@ -42,19 +42,19 @@ namespace fennec /// /// \brief Tuple, holds a collection of values of different types /// \details -/// | Property | Value | -/// |:----------:|:-----------:| -/// | stable | ⛔ | -/// | dynamic | ✅ | -/// | homogenous | ⛔ | -/// | distinct | ⛔ | -/// | ordered | ⛔ | -/// | space | \f$O(N)\f$ | -/// | linear | ✅ | -/// | access | \f$O(1)\f$ | -/// | find | \f$O(1)\f$ | -/// | insertion | ⛔ | -/// | deletion | ⛔ | +/// | Property | Value | +/// |:-----------:|:-----------:| +/// | stable | ⛔ | +/// | dynamic | ✅ | +/// | homogeneous | ⛔ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ✅ | +/// | access | \f$O(1)\f$ | +/// | find | \f$O(1)\f$ | +/// | insertion | ⛔ | +/// | deletion | ⛔ | /// /// \tparam TypesT The types to store template struct tuple; diff --git a/include/fennec/containers/variant.h b/include/fennec/containers/variant.h index e09ff63..c4dcaf0 100644 --- a/include/fennec/containers/variant.h +++ b/include/fennec/containers/variant.h @@ -41,6 +41,21 @@ namespace fennec /// /// \brief A structure that represents a union between `TypesT...` +/// \details +/// | Property | Value | +/// |:-----------:|:-----------:| +/// | stable | ✅ | +/// | dynamic | ⛔ | +/// | homogeneous | ⛔ | +/// | distinct | ⛔ | +/// | ordered | ⛔ | +/// | space | \f$O(N)\f$ | +/// | linear | ⛔ | +/// | access | \f$O(1)\f$ | +/// | find | ⛔ | +/// | insertion | \f$O(1)\f$ | +/// | deletion | \f$O(1)\f$ | +/// /// \tparam TypesT The types to hold in the variant template struct variant { diff --git a/include/fennec/core/version.h b/include/fennec/core/version.h index e14b263..74a8204 100644 --- a/include/fennec/core/version.h +++ b/include/fennec/core/version.h @@ -41,10 +41,18 @@ namespace fennec /// /// \brief simple version struct for drivers and systems struct version { - uint32_t major; //!< the major version - uint32_t minor; //!< the minor version - uint32_t patch; //!< the patch - string str; //!< string representation of the version + uint32_t major = { 1 }; //!< the major version + uint32_t minor = { 0 }; //!< the minor version + uint32_t patch = { 0 }; //!< the patch + string str = { string("") }; //!< string representation of the version + + friend bool operator==(const version& lhs, const version& rhs) { + return lhs.major == rhs.major and lhs.minor == rhs.minor and lhs.patch == rhs.patch and lhs.str == rhs.str; + } + + friend bool operator!=(const version& lhs, const version& rhs) { + return lhs.major != rhs.major or lhs.minor != rhs.minor or lhs.patch != rhs.patch or lhs.str != rhs.str; + } }; } diff --git a/include/fennec/filesystem/path.h b/include/fennec/filesystem/path.h index 7c38ea2..85edf6d 100644 --- a/include/fennec/filesystem/path.h +++ b/include/fennec/filesystem/path.h @@ -191,7 +191,7 @@ public: /// /// \returns \f$true\f$ if the path is empty or points to root - bool empty() { + bool is_empty() { size_t size = _str.size(); if (size == 0) return true; #if FENNEC_PLATFORM_WINDOWS @@ -221,7 +221,7 @@ public: } return _str.substring(0, start); #else - size_t start = _str.size() - 1; + size_t start = _str.size(); start = _str[start] == '/' ? start - 1 : start; return path(_str.substring(0, _str.rfind('/', start))); #endif @@ -243,9 +243,9 @@ public: working = current(); } - while (not parse.empty()) { + while (not parse.is_empty()) { // Handle dots - while (not parse.empty() && parse._str[0] == '.') { + while (not parse.is_empty() && parse._str[0] == '.') { // Check for ".." if (parse._str[1] == '.') { // ".." @@ -265,7 +265,7 @@ public: } } - if (parse.empty()) break; + if (parse.is_empty()) break; // Push the path const size_t loc = parse._str.find('/'); diff --git a/include/fennec/memory/pointers.h b/include/fennec/memory/pointers.h index bd207b4..264cdd1 100644 --- a/include/fennec/memory/pointers.h +++ b/include/fennec/memory/pointers.h @@ -188,7 +188,7 @@ public: /// /// \returns \f$true\f$ if there is not a held pointer, \f$false\f$ otherwise - bool empty() { + bool is_empty() { return _handle == nullptr; } diff --git a/include/fennec/renderers/interface/gfxcontext.h b/include/fennec/renderers/interface/gfxcontext.h index c18f21f..f4bf33a 100644 --- a/include/fennec/renderers/interface/gfxcontext.h +++ b/include/fennec/renderers/interface/gfxcontext.h @@ -40,7 +40,6 @@ #include #include -#include namespace fennec { @@ -49,8 +48,6 @@ class gfxcontext { public: using handle_t = uint32_t; - gfxresourcepool resources; - gfxcontext(display_server* display) : display(display) , version(0, 0, 0, string("")) { @@ -65,7 +62,6 @@ public: virtual gfxsurface* create_surface(window* window) = 0; - virtual gfxpass* create_pass() = 0; virtual const version& get_version() const { return version; }; protected: diff --git a/include/fennec/renderers/interface/gfxpass.h b/include/fennec/renderers/interface/gfxpass.h deleted file mode 100644 index 8aa5aac..0000000 --- a/include/fennec/renderers/interface/gfxpass.h +++ /dev/null @@ -1,60 +0,0 @@ -// ===================================================================================================================== -// fennec, a free and open source game engine -// Copyright © 2025 Medusa Slockbower -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ===================================================================================================================== - -/// -/// \file gfxcontext.h -/// \brief -/// -/// -/// \details -/// \author Medusa Slockbower -/// -/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) -/// -/// - -#ifndef FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H -#define FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H - -#include -#include -#include - -namespace fennec -{ - -/// -/// \brief Defines an interface that holds a series of passes with one coherent objective -/// \details This represents the overarching renderer, and not any platform specific behaviour. -/// I.E. This acts as a proxy for creating API objects, but the behaviour of those objects -/// is defined elsewhere. -class gfxpass { -public: - gfxsubpass* add_subpass(); - -private: - -}; - -class gfxsubpass { - -}; - -} - -#endif // FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H \ No newline at end of file diff --git a/include/fennec/renderers/interface/gfxresourcepool.h b/include/fennec/renderers/interface/gfxresourcepool.h deleted file mode 100644 index 7218665..0000000 --- a/include/fennec/renderers/interface/gfxresourcepool.h +++ /dev/null @@ -1,43 +0,0 @@ -// ===================================================================================================================== -// fennec, a free and open source game engine -// Copyright © 2025 Medusa Slockbower -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ===================================================================================================================== - -/// -/// \file gfxresourcepool.h -/// \brief -/// -/// -/// \details -/// \author Medusa Slockbower -/// -/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) -/// -/// - -#ifndef FENNEC_RENDERERS_INTERFACE_GFXRESOURCEPOOL_H -#define FENNEC_RENDERERS_INTERFACE_GFXRESOURCEPOOL_H - -namespace fennec -{ - -class gfxresourcepool { - -}; - -} - -#endif // FENNEC_RENDERERS_INTERFACE_GFXRESOURCEPOOL_H \ No newline at end of file diff --git a/include/fennec/renderers/interface/gfxsubpass.h b/include/fennec/renderers/interface/gfxsubpass.h deleted file mode 100644 index 4ddc67c..0000000 --- a/include/fennec/renderers/interface/gfxsubpass.h +++ /dev/null @@ -1,41 +0,0 @@ -// ===================================================================================================================== -// fennec, a free and open source game engine -// Copyright © 2025 Medusa Slockbower -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ===================================================================================================================== - -/// -/// \file gfxsubpass.h -/// \brief -/// -/// -/// \details -/// \author Medusa Slockbower -/// -/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) -/// -/// - -#ifndef FENNEC_RENDERERS_INTERFACE_GFXSUBPASS_H -#define FENNEC_RENDERERS_INTERFACE_GFXSUBPASS_H - -namespace fennec -{ - - - -} - -#endif // FENNEC_RENDERERS_INTERFACE_GFXSUBPASS_H \ No newline at end of file diff --git a/include/fennec/renderers/opengl/glcontext.h b/include/fennec/renderers/opengl/glcontext.h index 6a142fe..718dba8 100644 --- a/include/fennec/renderers/opengl/glcontext.h +++ b/include/fennec/renderers/opengl/glcontext.h @@ -45,9 +45,6 @@ public: : gfxcontext(display) { } - /// \brief create a render pass - /// \returns a new render pass - gfxpass* create_pass() override; private: #ifndef FENNEC_DOXYGEN diff --git a/include/fennec/renderers/vulkan/lib/app_info.h b/include/fennec/renderers/vulkan/lib/app_info.h new file mode 100644 index 0000000..abd3a02 --- /dev/null +++ b/include/fennec/renderers/vulkan/lib/app_info.h @@ -0,0 +1,210 @@ +// ===================================================================================================================== +// fennec, a free and open source game engine +// Copyright © 2025 Medusa Slockbower +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ===================================================================================================================== + +/// +/// \file instance.h +/// \brief +/// +/// +/// \details +/// \author Medusa Slockbower +/// +/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) +/// +/// + + +#ifndef FENNEC_RENDERERS_VULKAN_LIB_APP_INFO_H +#define FENNEC_RENDERERS_VULKAN_LIB_APP_INFO_H + +#include + +#include +#include + +namespace fennec::vk +{ + +struct app_info : private VkApplicationInfo { + +// Constructors & Destructor =========================================================================================== +public: + /// + /// \brief Create a Vulkan application information structure + /// \param app_name the name of the application, this cstring must exist for the lifetime of this object + /// until a structure of type fennec::vk::instance is constructed + /// \param app_version the internal version of the application + /// \param engine_name the name of the engine, this cstring must exist for the lifetime of this object + /// until a structure of type fennec::vk::instance is constructed + /// \param engine_version the internal version of the engine + /// \param api_version the Vulkan API version to use, version::patch and version::str are ignored + /// \param ext a pointer to an extension structure, the object next points to must exist for the lifetime of this + /// object until a structure of type fennec::vk::instance is constructed + /// TODO: DEFINE EXTENSION STRUCTURE WRAPPERS + app_info( + const cstring& app_name = {}, const version& app_version = {}, + const cstring& engine_name = {}, const version& engine_version = {}, + const version& api_version = {}, + void* ext = nullptr + ) noexcept : VkApplicationInfo { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pNext = ext, + .pApplicationName = app_name, + .applicationVersion = VK_MAKE_VERSION(app_version.major, app_version.minor, app_version.patch), + .pEngineName = engine_name, + .engineVersion = VK_MAKE_VERSION(engine_version.major, engine_version.minor, engine_version.patch), + .apiVersion = VK_MAKE_API_VERSION(0, api_version.major, api_version.minor, 0), + } { + } + + /// + /// \brief Copy Constructor + app_info(const app_info&) noexcept = default; + + /// + /// \brief Move Constructor + app_info(app_info&&) noexcept = default; + + /// + /// \brief Destructor + ~app_info() noexcept = default; + + +// Assignment Operators ================================================================================================ +public: + + /// + /// \brief Copy Assignment + app_info& operator=(const app_info&) noexcept = default; + + /// + /// \brief Move Assignment + app_info& operator=(app_info&&) noexcept = default; + + +// Implicit Conversions ================================================================================================ +public: + + /// + operator VkApplicationInfo*() noexcept { + return this; + } + + /// + /// \brief Implicit Pointer Conversion + operator const VkApplicationInfo*() const noexcept { + return this; + } + + +// Properties ========================================================================================================== +public: + + /// + /// \returns A cstring containing the application name + cstring get_app_name() const { + return cstring(pApplicationName, strlen(pApplicationName)); + } + + /// + /// \brief Set the application name + /// \param str A cstring containing the new name + void set_app_name(const cstring& str) { + pApplicationName = str; + } + + /// + /// \returns A version struct containing the application version + version get_app_version() const { + return version { + .major = VK_VERSION_MAJOR(applicationVersion), + .minor = VK_VERSION_MINOR(applicationVersion), + .patch = VK_VERSION_PATCH(applicationVersion) + }; + } + + /// + /// \brief Set the engine version + /// \param ver A version struct containing the new version + void set_engine_version(const version& ver) { + engineVersion = VK_MAKE_VERSION(ver.major, ver.minor, ver.patch); + } + + /// + /// \returns A cstring containing the engine name + cstring get_engine_name() const { return cstring(pEngineName, strlen(pEngineName)); } + + /// + /// \brief Set the engine name + /// \param str A cstring containing the new name + void set_engine_name(const cstring& str) { pEngineName = str; } + + /// + /// \returns A version struct containing the engine version + version get_engine_version() const { + return version { + .major = VK_VERSION_MAJOR(engineVersion), + .minor = VK_VERSION_MINOR(engineVersion), + .patch = VK_VERSION_PATCH(engineVersion) + }; + } + + /// + /// \brief Set the engine version + /// \param ver A version struct containing the new version + void set_engine_version(const version& ver) { + engineVersion = VK_MAKE_VERSION(ver.major, ver.minor, ver.patch); + } + + /// + /// \returns A version struct containing the Vulkan API version + version get_api_version() const { + return version { + .major = VK_API_VERSION_MAJOR(apiVersion), + .minor = VK_API_VERSION_MINOR(apiVersion) + }; + } + + /// + /// \brief Set the Vulkan API version + /// \param ver A version struct containing the new version + void set_api_version(const version& ver) { + apiVersion = VK_MAKE_API_VERSION(0, ver.major, ver.minor, 0); + } + + /// + /// \brief Set the extension structure + /// \param ext A pointer to the new extension object + void set_extension(void* ext) { + pNext = ext; + } + + /// + /// \brief Clear the extension structure with \f$nullptr\f$ + void set_extension(nullptr_t) { + pNext = nullptr; + } + + +// Private Members ===================================================================================================== +private: +}; + +} + +#endif // FENNEC_RENDERERS_VULKAN_LIB_APP_INFO_H \ No newline at end of file diff --git a/include/fennec/renderers/vulkan/lib/instance.h b/include/fennec/renderers/vulkan/lib/instance.h new file mode 100644 index 0000000..a0cac14 --- /dev/null +++ b/include/fennec/renderers/vulkan/lib/instance.h @@ -0,0 +1,89 @@ +// ===================================================================================================================== +// fennec, a free and open source game engine +// Copyright © 2025 Medusa Slockbower +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ===================================================================================================================== + +/// +/// \file instance.h +/// \brief +/// +/// +/// \details +/// \author Medusa Slockbower +/// +/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) +/// +/// + + +#ifndef FENNEC_RENDERERS_VULKAN_LIB_INSTANCE_H +#define FENNEC_RENDERERS_VULKAN_LIB_INSTANCE_H + +#include +#include + +#include + +namespace fennec::vk +{ + +struct instance { +public: + using create_flags = VkInstanceCreateFlags; + + struct create_info : private VkInstanceCreateInfo { + public: + template + create_info( + create_flags flags, const app_info& info, + const cstring (&layers)[LayersN], const cstring (&extensions)[ExtensionsN], + void* ext + ) : VkInstanceCreateInfo { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pNext = ext, + .flags = flags, + .pApplicationInfo = info, + .enabledLayerCount = LayersN, + .ppEnabledLayerNames = nullptr, + .enabledExtensionCount = ExtensionsN, + .ppEnabledExtensionNames = nullptr, + } { + _layers.reserve(LayersN); + for (const auto& layer : layers) { _layers.push_back(layer); } + + _extensions.reserve(ExtensionsN); + for (const auto& extension : extensions) { _extensions.push_back(extension); } + + ppEnabledLayerNames = _layers.data(); + ppEnabledExtensionNames = _extensions.data(); + } + + + + private: + dynarray _layers; + dynarray _extensions; + }; + + instance(); + +private: + VkInstance _handle; +}; + +} + +#endif // FENNEC_RENDERERS_VULKAN_LIB_INSTANCE_H \ No newline at end of file diff --git a/include/fennec/renderers/vulkan/vkcontext.cpp b/include/fennec/renderers/vulkan/vkcontext.cpp index aa04223..d78fd90 100644 --- a/include/fennec/renderers/vulkan/vkcontext.cpp +++ b/include/fennec/renderers/vulkan/vkcontext.cpp @@ -23,7 +23,6 @@ namespace fennec { vkcontext::vkcontext(display_server* display) : gfxcontext(display) { - } vkcontext::~vkcontext() { diff --git a/include/fennec/renderers/vulkan/vkcontext.h b/include/fennec/renderers/vulkan/vkcontext.h index 6d9d431..6569733 100644 --- a/include/fennec/renderers/vulkan/vkcontext.h +++ b/include/fennec/renderers/vulkan/vkcontext.h @@ -40,15 +40,14 @@ namespace fennec { -class vkcontext : gfxcontext { +class vkcontext : public gfxcontext { public: vkcontext(display_server* display); ~vkcontext(); bool is_valid() override; -private: - +protected: }; } // fennec diff --git a/include/fennec/rtti/type_data.h b/include/fennec/rtti/type_data.h index 820fe3c..abe8961 100644 --- a/include/fennec/rtti/type_data.h +++ b/include/fennec/rtti/type_data.h @@ -116,7 +116,7 @@ public: typelist.resize(uuid * 2); } - if (typelist[uuid].empty()) { + if (typelist[uuid].is_empty()) { typelist[uuid] = fennec::forward>(_make_data()); } diff --git a/include/fennec/string/cstring.h b/include/fennec/string/cstring.h index 4d99f91..31bfa15 100644 --- a/include/fennec/string/cstring.h +++ b/include/fennec/string/cstring.h @@ -87,10 +87,10 @@ public: /// \note If used with `::strlen`, the result should be incremented by 1 to include the null terminator constexpr cstring(char* str, size_t n) : _str(str) - , _size(n - 1) + , _size(n) , _const(false) { if constexpr(not is_constant_evaluated()) { - assert(_str[n - 1] == '\0', "Invalid NTBS."); + assert(_str[n] == '\0', "Invalid NTBS."); } } @@ -114,10 +114,10 @@ public: /// \note If used with `::strlen`, the result should be incremented by 1 to include the null terminator constexpr cstring(const char* str, size_t n) : _cstr(str) - , _size(n - 1) + , _size(n) , _const(true) { if constexpr(not is_constant_evaluated()) { - assert(_str[n - 1] == '\0', "Invalid NTBS."); + assert(_str[n] == '\0', "Invalid NTBS."); } } @@ -195,7 +195,7 @@ public: return _size + 1; } - constexpr bool empty() const { + constexpr bool is_empty() const { return _cstr == nullptr || _size == 0; } diff --git a/include/fennec/string/string.h b/include/fennec/string/string.h index bd5967c..2bfa421 100644 --- a/include/fennec/string/string.h +++ b/include/fennec/string/string.h @@ -188,7 +188,7 @@ public: /// /// \returns \f$true\f$ if the string contains no characters, \f$false\f$ otherwise. - constexpr bool empty() const { + constexpr bool is_empty() const { return size() == 0; } diff --git a/include/fennec/string/wcstring.h b/include/fennec/string/wcstring.h index 2e32cc3..0f88491 100644 --- a/include/fennec/string/wcstring.h +++ b/include/fennec/string/wcstring.h @@ -178,7 +178,7 @@ public: /// \returns the size of the string including its null terminator, i.e. `(*str)[capacity() - 1] == '\0'` constexpr size_t capacity() const { return _size + 1; } - constexpr bool empty() const { + constexpr bool is_empty() const { return _cstr == nullptr || _size == 0; } diff --git a/include/fennec/string/wstring.h b/include/fennec/string/wstring.h index 76798b3..33d880b 100644 --- a/include/fennec/string/wstring.h +++ b/include/fennec/string/wstring.h @@ -181,7 +181,7 @@ public: /// /// \returns \f$true\f$ if the string contains no characters, \f$false\f$ otherwise. - constexpr bool empty() const { + constexpr bool is_empty() const { return size() == 0; } diff --git a/include/fennec/threading/mpscq.h b/include/fennec/threading/mpscq.h index 765cb35..3091e5c 100644 --- a/include/fennec/threading/mpscq.h +++ b/include/fennec/threading/mpscq.h @@ -87,7 +87,7 @@ public: return _data.capacity(); } - bool empty() const { + bool is_empty() const { return size() == 0; } diff --git a/source/filesystem/path.cpp b/source/filesystem/path.cpp index fa5d1f5..cd3d48d 100644 --- a/source/filesystem/path.cpp +++ b/source/filesystem/path.cpp @@ -42,7 +42,7 @@ path path::current() { if (getcwd(cstr, sizeof(cstr)) == nullptr) { return path(""); } - return path(cstring(cstr, strlen(cstr) + 1)); + return path(cstring(cstr, strlen(cstr))); } path path::current(const path& path) { diff --git a/source/lang/assert.cpp b/source/lang/assert.cpp index 977f35f..b0902cc 100644 --- a/source/lang/assert.cpp +++ b/source/lang/assert.cpp @@ -30,7 +30,7 @@ void _assert_impl(const char* expr, size_t expr_l, fennec::cstring(expr, expr_l), fennec::cstring(file, file_l), line, fennec::cstring(func, func_l), - fennec::cstring(desc, ::strlen(desc) + 1) + fennec::cstring(desc, ::strlen(desc)) ); if (halt) { diff --git a/source/platform/linux/wayland/server.cpp b/source/platform/linux/wayland/server.cpp index 39932e4..20482c0 100644 --- a/source/platform/linux/wayland/server.cpp +++ b/source/platform/linux/wayland/server.cpp @@ -112,7 +112,7 @@ void wayland_server::connect() { #endif auto contexts = ctx_registry::get_type_list(); - while (not contexts.empty()) { + while (not contexts.is_empty()) { const auto& ctx = contexts.front(); gfx_context = unique_ptr(ctx.ctor(this)); @@ -125,7 +125,7 @@ void wayland_server::connect() { } } - assertf(not gfx_context.empty(), "Failed to create graphics context."); + assertf(not gfx_context.is_empty(), "Failed to create graphics context."); } void wayland_server::disconnect() { @@ -191,7 +191,7 @@ void wayland_server::_wl_registry_listen_global(void* data, wl_registry* reg, ui }; wayland_server* server = static_cast(data); - const cstring interface = cstring(name, strlen(name) + 1); + const cstring interface = cstring(name, strlen(name)); if (interface == "wl_compositor") { server->compositor = static_cast(wl_registry_bind(reg, id, &wl_compositor_interface, version)); diff --git a/source/platform/window_manager.cpp b/source/platform/window_manager.cpp index 258d866..54e7164 100644 --- a/source/platform/window_manager.cpp +++ b/source/platform/window_manager.cpp @@ -44,7 +44,7 @@ void window_manager::initialize() { display_server::entrylist_t display_servers = display_server::get_type_list(); // Find first valid server - while (not display_servers.empty()) { + while (not display_servers.is_empty()) { display_server::entry it = display_servers.front(); display_servers.pop(); diff --git a/source/renderers/opengl/glcontext.cpp b/source/renderers/opengl/glcontext.cpp index 9c92492..fc777a3 100644 --- a/source/renderers/opengl/glcontext.cpp +++ b/source/renderers/opengl/glcontext.cpp @@ -21,8 +21,5 @@ namespace fennec { -gfxpass* glcontext::create_pass() { - return nullptr; -} } diff --git a/source/scene/scene.cpp b/source/scene/scene.cpp index e988cda..ef1588b 100644 --- a/source/scene/scene.cpp +++ b/source/scene/scene.cpp @@ -37,7 +37,7 @@ namespace fennec scene_node* scene::operator[](const cstring& name) const { list parse; parse.push_back(table_t::root); - while (not parse.empty()) { + while (not parse.is_empty()) { size_t n = parse.front(); if (_table[n]->name == name) { return _table[n].get(); @@ -54,7 +54,7 @@ scene_node* scene::operator[](const cstring& name) const { scene_node* scene::operator[](const string& name) const { list parse; parse.push_back(table_t::root); - while (not parse.empty()) { + while (not parse.is_empty()) { size_t n = parse.front(); if (_table[n]->name == name) { return _table[n].get(); diff --git a/test/tests/containers/test_bintree.h b/test/tests/containers/test_bintree.h index 85cf448..5be7a94 100644 --- a/test/tests/containers/test_bintree.h +++ b/test/tests/containers/test_bintree.h @@ -51,7 +51,7 @@ inline void fennec_test_containers_bintree() { test.clear(); - fennec_test_run(test.empty(), true); + fennec_test_run(test.is_empty(), true); fennec_test_spacer(1); @@ -98,7 +98,7 @@ inline void fennec_test_containers_bintree() { test.clear(); - fennec_test_run(test.empty(), true); + fennec_test_run(test.is_empty(), true); } diff --git a/test/tests/containers/test_deque.h b/test/tests/containers/test_deque.h index 9ff15fd..4f35751 100644 --- a/test/tests/containers/test_deque.h +++ b/test/tests/containers/test_deque.h @@ -42,7 +42,7 @@ inline void fennec_test_containers_deque() { test.pop_back(); } - fennec_test_run(test.empty(), true); + fennec_test_run(test.is_empty(), true); } } diff --git a/test/tests/containers/test_graph.h b/test/tests/containers/test_graph.h index f01aa82..b21fccb 100644 --- a/test/tests/containers/test_graph.h +++ b/test/tests/containers/test_graph.h @@ -42,7 +42,7 @@ inline void fennec_test_containers_graph() { test.erase(i); } - fennec_test_run(test.empty(), true); + fennec_test_run(test.is_empty(), true); } diff --git a/test/tests/containers/test_list.h b/test/tests/containers/test_list.h index 8cc589b..4889807 100644 --- a/test/tests/containers/test_list.h +++ b/test/tests/containers/test_list.h @@ -39,11 +39,11 @@ inline void fennec_test_containers_list() { assertf(test.insert(p, i) == i, "List Construct Test Failed."); } - while (test.empty() == false) { + while (test.is_empty() == false) { test.pop_back(); } - fennec_test_run(test.empty(), true); + fennec_test_run(test.is_empty(), true); } diff --git a/test/tests/containers/test_object_pool.h b/test/tests/containers/test_object_pool.h index c242429..f54de41 100644 --- a/test/tests/containers/test_object_pool.h +++ b/test/tests/containers/test_object_pool.h @@ -42,7 +42,7 @@ inline void fennec_test_containers_object_pool() { test.erase(i); } - fennec_test_run(test.empty(), true); + fennec_test_run(test.is_empty(), true); } diff --git a/test/tests/containers/test_rdtree.h b/test/tests/containers/test_rdtree.h index 2a309d2..71f88f1 100644 --- a/test/tests/containers/test_rdtree.h +++ b/test/tests/containers/test_rdtree.h @@ -61,7 +61,7 @@ inline void fennec_test_containers_rdtree() { test.erase(0); - fennec_test_run(test.empty(), true); + fennec_test_run(test.is_empty(), true); fennec_test_spacer(1); @@ -108,7 +108,7 @@ inline void fennec_test_containers_rdtree() { test.erase(0); - fennec_test_run(test.empty(), true); + fennec_test_run(test.is_empty(), true); } diff --git a/test/tests/containers/test_sequence.h b/test/tests/containers/test_sequence.h index 91ef57e..70d7642 100644 --- a/test/tests/containers/test_sequence.h +++ b/test/tests/containers/test_sequence.h @@ -66,7 +66,7 @@ inline void fennec_test_containers_sequence() { test.erase(v); } - fennec_test_run(test.empty(), true); + fennec_test_run(test.is_empty(), true); } } diff --git a/test/tests/test_threading.h b/test/tests/test_threading.h index caedcd1..dd9ffe6 100644 --- a/test/tests/test_threading.h +++ b/test/tests/test_threading.h @@ -91,7 +91,7 @@ inline void fennec_test_threading_test_mpscq_producer(mpscq* queue, size } inline void fennec_test_threading_test_mpscq_consumer(mpscq* queue, atomic* res, atomic* done) { - while (not done->load() or not queue->empty()) { + while (not done->load() or not queue->is_empty()) { unique_ptr ptr = queue->pop(); if (ptr) { *res += *ptr;