- 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.
This commit is contained in:
2026-01-02 15:38:03 -05:00
parent c1be5385d3
commit 7c2f89b331
53 changed files with 825 additions and 415 deletions

View File

@@ -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<size_t...i>
static bool _compare(const array& lhs, const array& rhs, index_metasequence<i...>) {

View File

@@ -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<typename TypeT, class AllocT = allocator<TypeT>>
@@ -52,10 +68,15 @@ private:
struct node;
public:
/// \name Definitions
/// @{
using value_t = TypeT; //!< The element type
using alloc_t = allocator_traits<AllocT>::template rebind<node>; //!< 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();
}

View File

@@ -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<size_t N>
struct bitfield {

View File

@@ -40,6 +40,23 @@
///
/// \code #include <fennec/containers/containers.h> \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 |

View File

@@ -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<typename TypeT, typename AllocT = allocator<TypeT>>
@@ -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;
}

View File

@@ -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<class TypeT, class Alloc = allocator<TypeT>>
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<value_t, alloc_t> _alloc;
size_t _size;
// Private Helpers =====================================================================================================
private:
// helper to double the capacity of the allocation
constexpr void _grow() {
_alloc.creallocate(_alloc.capacity() * 2);
}
allocation<value_t, alloc_t> _alloc;
size_t _size;
// helper to destruct elements past n
constexpr void _reduce(size_t n) {
while (_size > n) {
fennec::destruct(&_alloc[--_size]);
}
}
};
}

View File

@@ -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<T>(*static_cast<U*>(_handle));
}
// Members =============================================================================================================
private:
void* _handle;
manager_t _manage;
// Helpers =============================================================================================================
private:
template<typename T>
static void* _manage_impl(uint8_t op, void* hnd) {
static fennec::type t = type::get<T>();

View File

@@ -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<size_t> outgoing(size_t vertex) {
list<size_t> 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<size_t> incoming(size_t vertex) {
list<size_t> 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<size_t> symmetric(size_t vertex) {
list<size_t> 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<size_t> undirected(size_t vertex) {
list<size_t> 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];

View File

@@ -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<class TypeT, class Alloc = allocator<TypeT>>
@@ -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<node, alloc_t>;
using freed_t = dynarray<size_t>;
// 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<value_t>(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<typename...ArgsT>
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<ArgsT>(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<typename...ArgsT>
constexpr iterator emplace(const iterator& it, ArgsT&&...args) {
return this->_insert(it._n, fennec::forward<ArgsT>(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<value_t>(x));
}
@@ -340,7 +365,7 @@ public:
/// \tparam ArgsT Argument types
/// \returns The id of the inserted node
template<typename...ArgsT>
constexpr size_t emplace_front(ArgsT&&...args) {
constexpr iterator emplace_front(ArgsT&&...args) {
return this->_insert(_root, fennec::forward<ArgsT>(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<value_t>(x));
}
@@ -366,7 +391,7 @@ public:
/// \tparam ArgsT Argument types
/// \returns The id of the inserted node
template<typename...ArgsT>
constexpr size_t emplace_back(ArgsT&&...args) {
constexpr iterator emplace_back(ArgsT&&...args) {
return this->_insert(npos, fennec::forward<ArgsT>(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<node, alloc_t> _table;
dynarray<size_t> _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<value_t>(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<typename...ArgsT>
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<ArgsT>(args)...);
_table[i].value.emplace(fennec::forward<ArgsT>(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;

View File

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

View File

@@ -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<typename TypeT, typename AllocT = allocator<TypeT>>
@@ -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();
}

View File

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

View File

@@ -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<typename TypeT0, typename TypeT1>

View File

@@ -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<typename...ArgsT>
constexpr void _insert(ArgsT&&...args) {

View File

@@ -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<typename TypeT, typename AllocT = allocator<TypeT>>
@@ -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<size_t> 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));

View File

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

View File

@@ -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<typename TypeT, class Hash = hash<TypeT>, class Equals = equality<TypeT>, class Alloc = allocator<TypeT>>
@@ -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;
}

View File

@@ -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<typename...TypesT> struct tuple;

View File

@@ -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<typename...TypesT>
struct variant {

View File

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

View File

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

View File

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

View File

@@ -40,7 +40,6 @@
#include <fennec/rtti/enable.h>
#include <fennec/renderers/interface/forward.h>
#include <fennec/renderers/interface/gfxresourcepool.h>
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:

View File

@@ -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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \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 <fennec/lang/types.h>
#include <fennec/string/string.h>
#include <fennec/renderers/interface/forward.h>
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

View File

@@ -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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \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

View File

@@ -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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \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

View File

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

View File

@@ -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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \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 <volk.h>
#include <fennec/core/version.h>
#include <fennec/string/cstring.h>
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

View File

@@ -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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \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 <volk.h>
#include <fennec/containers/dynarray.h>
#include <fennec/renderers/vulkan/lib/app_info.h>
namespace fennec::vk
{
struct instance {
public:
using create_flags = VkInstanceCreateFlags;
struct create_info : private VkInstanceCreateInfo {
public:
template<size_t LayersN, size_t ExtensionsN>
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<const char*> _layers;
dynarray<const char*> _extensions;
};
instance();
private:
VkInstance _handle;
};
}
#endif // FENNEC_RENDERERS_VULKAN_LIB_INSTANCE_H

View File

@@ -23,7 +23,6 @@ namespace fennec {
vkcontext::vkcontext(display_server* display)
: gfxcontext(display) {
}
vkcontext::~vkcontext() {

View File

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

View File

@@ -116,7 +116,7 @@ public:
typelist.resize(uuid * 2);
}
if (typelist[uuid].empty()) {
if (typelist[uuid].is_empty()) {
typelist[uuid] = fennec::forward<unique_ptr<type_data>>(_make_data<T>());
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -87,7 +87,7 @@ public:
return _data.capacity();
}
bool empty() const {
bool is_empty() const {
return size() == 0;
}