diff --git a/CMakeLists.txt b/CMakeLists.txt index ddfa32f..d4c55e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,16 +70,23 @@ add_library(fennec STATIC # CONTAINERS =========================================================================================================== + include/fennec/containers/containers.h + include/fennec/containers/array.h + include/fennec/containers/deque.h include/fennec/containers/dynarray.h + include/fennec/containers/graph.h include/fennec/containers/list.h include/fennec/containers/map.h + include/fennec/containers/object_pool.h include/fennec/containers/optional.h include/fennec/containers/pair.h include/fennec/containers/rdtree.h include/fennec/containers/set.h + include/fennec/containers/traversal.h include/fennec/containers/tuple.h + include/fennec/containers/detail/_tuple.h @@ -106,6 +113,9 @@ add_library(fennec STATIC include/fennec/lang/utility.h include/fennec/lang/integer.h + include/fennec/lang/assert.h source/lang/assert.cpp + + include/fennec/lang/detail/_bits.h include/fennec/lang/detail/_int.h include/fennec/lang/detail/_numeric_transforms.h @@ -115,8 +125,6 @@ add_library(fennec STATIC include/fennec/lang/detail/_type_sequences.h include/fennec/lang/detail/_typeuuid.h - include/fennec/lang/assert.h source/lang/assert.cpp - # MEMORY =============================================================================================================== include/fennec/memory/new.h source/memory/new.cpp @@ -200,10 +208,6 @@ add_library(fennec STATIC # EXTRA SOURCES ======================================================================================================== ${FENNEC_EXTRA_SOURCES} - include/fennec/containers/traversal.h - include/fennec/containers/graph.h - include/fennec/containers/deque.h - include/fennec/containers/object_pool.h ) add_dependencies(fennec metaprogramming) @@ -232,6 +236,7 @@ file(COPY logo DESTINATION docs/logo) if(DOXYGEN_FOUND) add_dependencies(fennec fennecdocs) set(DOXY_OUTPUT_DIR "${FENNEC_SOURCE_DIR}/docs") + set(DOXY_EXAMPLES_DIR "${FENNEC_SOURCE_DIR}/examples") get_filename_component(DOXYGEN_PROJECT_NAME ${FENNEC_SOURCE_DIR} NAME) # Set Doxy Project name to the name of the root dir set(DOXYGEN_CONFIG_IN "${FENNEC_SOURCE_DIR}/doxy/Doxyfile.in") # Input config file with preprocessor arguments set(DOXYGEN_CONFIG_OUT "${FENNEC_SOURCE_DIR}/doxy/Doxyfile") # Generated config file from input diff --git a/README.md b/README.md index 1fd919a..ee2895c 100644 --- a/README.md +++ b/README.md @@ -8,21 +8,21 @@

-## Table of Contents + +

Table of Contents

- * [Table of Contents](#table-of-contents) * [Introduction](#introduction) * [Coding Standards](#coding-standards) * [Building from Source](#building-from-source) * [Building from Terminal](#building-from-terminal) * [Debian](#debian) + * [Fedora](#fedora-dnf) → `dnf` * [Building on Windows](#building-on-windows) * [Running the Test Suite](#running-the-test-suite) * [Usage](#usage) * [Licensing](#licensing) * [Contribution](#contribution) -
@@ -152,6 +152,7 @@ using specific toolchains for specific platforms that necessitate this. The prim If you wish to build for Windows *and* Linux, your options are WSL or Dual Boot. I recommend Dual Boot over WSL. + #### Debian On Debian-based distributions, you can install dependencies using the following command: @@ -165,6 +166,7 @@ for Doxygen run: sudo apt install doxygen graphviz ``` + #### Fedora (`dnf`) On Debian-based distributions, you can install dependencies using the following command: @@ -238,23 +240,26 @@ information displayed is correct. ## Usage + ### Licensing The following content of this section is not legal advice, nor is it legally binding, and nor does it change the terms of the license. Please seek legal council if you have any concerns. -  fennec is licensed under GPLv3. The primary reason for the choice of license is to dissuade corporations from modifying -fennec and using it in a commercial manner. This of course does not bar them from using fennec commercially, however -it will prevent them from being able to make the derivative work proprietary. You are free to use and redistribute -fennec however you wish according to the terms of the license, which does not bar you from commercializing software -based on fennec. +TLDR; You may license your game under whichever license you please. Any C++ code that is by definition a derivative work +must be licensed under GPLv3 and freely available, everything else; assets, scripts, design documents, etc. may be under +the license of your choosing and remain proprietary. + +  fennec is licensed under GPLv3. The primary reason for the choice of license is to dissuade corporations from +modifying fennec and using it in a commercial manner. This of course does not bar them from using fennec commercially, +however it will prevent them from being able to make the derivative work proprietary. You are free to use and redistribute +fennec however you wish according to the terms of the license, which does not bar you from commercializing software based +on fennec.   If you wish to protect your game files, assets and generated content do not constitute a covered work and may be copyrighted under a non-compliant license. Think of it in terms of using Blender to create a mesh for a game, then licensing that mesh under another license. -Any code that is linked against fennec or uses any part is by definition a covered work must be licensed under GPLv3. -   Later down the line, I plan on implementing scripts in a manner that allows the script itself to remain proprietary. The scripts will likely be trans-compiled to another language before being compiled to binary, but this is only an intermediate step and will be erased when no longer needed. diff --git a/build.sh b/build.sh index a9652a8..b780158 100755 --- a/build.sh +++ b/build.sh @@ -38,7 +38,7 @@ Help() Debug() { mkdir -p build/debug - cd ./build/debug + cd ./build/debug || exit cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -S ../.. -B . cmake --build . --target fennec cd ../.. @@ -47,7 +47,7 @@ Debug() Release() { mkdir -p build/release - cd ./build/release + cd ./build/release || exit cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S ../.. -B . cmake --build . --target fennec cd ../.. @@ -56,7 +56,7 @@ Release() RelWithDebInfo() { mkdir -p build/relwithdebinfo - cd ./build/relwithdebinfo + cd ./build/relwithdebinfo || exit cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -S ../.. -B . cmake --build . --target fennec cd ../.. @@ -65,7 +65,7 @@ RelWithDebInfo() MinSizeRel() { mkdir -p build/minsizerel - cd ./build/minsizerel + cd ./build/minsizerel || exit cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel -S ../.. -B . cmake --build . --target fennec cd ../.. diff --git a/doxy/Doxyfile b/doxy/Doxyfile index 26d134c..ba17054 100644 --- a/doxy/Doxyfile +++ b/doxy/Doxyfile @@ -129,7 +129,7 @@ BRIEF_MEMBER_DESC = YES # brief descriptions will be completely suppressed. # The default value is: YES. -REPEAT_BRIEF = NO +REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found @@ -944,8 +944,7 @@ WARN_LOGFILE = # Note: If this tag is empty the current directory is searched. INPUT = "/home/medusa/Documents/Work/Personal/fennec/include" \ - "/home/medusa/Documents/Work/Personal/fennec/source" \ - "/home/medusa/Documents/Work/Personal/fennec/README.md" + "/home/medusa/Documents/Work/Personal/fennec/source" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -1099,7 +1098,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = +IMAGE_PATH = "/home/medusa/Documents/Work/Personal/fennec/doxy/static" # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -1981,7 +1980,7 @@ GENERATE_LATEX = NO # The default directory is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_OUTPUT = latex +LATEX_OUTPUT = ./latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. @@ -2664,7 +2663,7 @@ TEMPLATE_RELATIONS = NO # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDE_GRAPH = YES +INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing @@ -2676,7 +2675,7 @@ INCLUDE_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is set to YES then doxygen will generate a call # dependency graph for every global function or class method. diff --git a/doxy/Doxyfile.in b/doxy/Doxyfile.in index c460a84..7e8ae61 100644 --- a/doxy/Doxyfile.in +++ b/doxy/Doxyfile.in @@ -129,7 +129,7 @@ BRIEF_MEMBER_DESC = YES # brief descriptions will be completely suppressed. # The default value is: YES. -REPEAT_BRIEF = NO +REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found @@ -944,8 +944,7 @@ WARN_LOGFILE = # Note: If this tag is empty the current directory is searched. INPUT = "@PROJECT_SOURCE_DIR@/include" \ - "@PROJECT_SOURCE_DIR@/source" \ - "@PROJECT_SOURCE_DIR@/README.md" + "@PROJECT_SOURCE_DIR@/source" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -1099,7 +1098,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = +IMAGE_PATH = "@PROJECT_SOURCE_DIR@/doxy/static" # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -1981,7 +1980,7 @@ GENERATE_LATEX = NO # The default directory is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_OUTPUT = latex +LATEX_OUTPUT = ./latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. @@ -2664,7 +2663,7 @@ TEMPLATE_RELATIONS = NO # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDE_GRAPH = YES +INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing @@ -2676,7 +2675,7 @@ INCLUDE_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is set to YES then doxygen will generate a call # dependency graph for every global function or class method. diff --git a/doxy/retrieve-emojis.py b/doxy/retrieve-emojis.py new file mode 100644 index 0000000..6438689 --- /dev/null +++ b/doxy/retrieve-emojis.py @@ -0,0 +1,71 @@ +# script to download the emoticons from GitHub and to produce a table for +# inclusion in Doxygen. Works with python 2.7+ and python 3.x +import json +import os +import argparse +import re +try: + import urllib.request as urlrequest +except ImportError: + import urllib as urlrequest + +unicode_re = re.compile(r'.*?/unicode/(.*?).png\?.*') + +def get_emojis(): + response = urlrequest.urlopen('https://api.github.com/emojis') + raw_data = response.read() + return json.loads(raw_data) + +def download_images(dir_name, silent): + if not os.path.exists(dir_name): + os.makedirs(dir_name) + json_data = get_emojis() + num_items = len(json_data) + cur_item=0 + for image,url in sorted(json_data.items()): + image_name = image+'.png' + cur_item=cur_item+1 + if url.find('/unicode/')==-1 or not os.path.isfile(dir_name+'/'+image_name): + success = True + with open(dir_name+'/'+image_name,'wb') as file: + if not silent: + print('%s/%s: fetching %s' % (cur_item,num_items,image_name)) + try: + file.write(urlrequest.urlopen(url).read()) + except: + print('Unable to fetch %s' % (image_name)) + success = False + if not success: + os.remove(dir_name+'/'+image_name) + else: + if not silent: + print('%s/%s: skipping %s' % (cur_item,num_items,image_name)) + +def produce_table(): + json_data = get_emojis() + lines = [] + for image,url in sorted(json_data.items()): + match = unicode_re.match(url) + if match: + unicodes = match.group(1).split('-') + unicodes_html = ''.join(["&#x"+x+";" for x in unicodes]) + image_str = "\":"+image+":\"," + unicode_str = "\""+unicodes_html+"\"" + lines.append(' { %-42s %-38s }' % (image_str,unicode_str)) + out_str = ',\n'.join(lines) + print("{") + print(out_str) + print("};") + +if __name__=="__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('-d','--dir',help='directory to place images in') + parser.add_argument('-t','--table',help='generate code fragment',action='store_true') + parser.add_argument('-s','--silent',help='silent mode',action='store_true') + args = parser.parse_args() + + if args.table: + produce_table() + if args.dir: + download_images(args.dir, args.silent) \ No newline at end of file diff --git a/doxy/static/graphs/containers/rdtree.svg b/doxy/static/graphs/containers/rdtree.svg new file mode 100644 index 0000000..5fb4644 --- /dev/null +++ b/doxy/static/graphs/containers/rdtree.svg @@ -0,0 +1,4 @@ + + + +
Key
Root =
Node =
2-way ref = 
1-way ref = 
\ No newline at end of file diff --git a/external/cpptrace b/external/cpptrace index 9133b90..69179bb 160000 --- a/external/cpptrace +++ b/external/cpptrace @@ -1 +1 @@ -Subproject commit 9133b90a9995e438476206bb116c849dfd0fe712 +Subproject commit 69179bbe8fb1019cc9d9264f3b266accb996be5b diff --git a/include/fennec/containers/array.h b/include/fennec/containers/array.h index 8be4948..6b3dad8 100644 --- a/include/fennec/containers/array.h +++ b/include/fennec/containers/array.h @@ -40,24 +40,62 @@ namespace fennec /// /// -/// \brief wrapper for fixed size arrays +/// \brief Data Structure that defines a compile-time allocated array /// /// \details -/// | Property | Value | -/// |:--------:|:-----------------------:| -/// | stable | \emoji heavy_check_mark | -/// | access | \f$O(1)\f$ | -/// | space | \f$O(N)\f$ | +/// | 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 | ⛔ | /// /// \tparam ValueT value type /// \tparam ElemV number of elements template struct array { +// Public Members ====================================================================================================== + + /// \name Public Members + /// @{ + /// /// \brief backing c-style array handle ValueT elements[ElemV]; + /// @} + + + +// Properties ========================================================================================================== + + /// \name Properties + /// @{ + + /// + /// \brief returns the number of elements in the array + /// \returns the number of elements in the array + [[nodiscard]] constexpr size_t size() const { return ElemV; } + + /// + /// \brief returns **true** when the array is empty + /// \return \f$ElemV == 0\f$ + [[nodiscard]] constexpr bool_t empty() const { return ElemV == 0; } + + /// @} + + + +// Access ============================================================================================================== + /// \name Element Access /// @{ @@ -84,32 +122,11 @@ struct array return elements[i]; } - constexpr ValueT* begin() { return elements; } - constexpr ValueT* end() { return elements + ElemV; } - - constexpr const ValueT* begin() const { return elements; } - constexpr const ValueT* end() const { return elements + ElemV; } - /// @} - /// \name Capacity - /// @{ - - /// - /// \brief returns the number of elements in the array - /// \returns the number of elements in the array - [[nodiscard]] constexpr size_t size() const { return ElemV; } - - /// - /// \brief returns **true** when the array is empty - /// \return \f$ElemV == 0\f$ - [[nodiscard]] constexpr bool_t empty() const { return ElemV == 0; } - - /// @} - - +// Comparison ========================================================================================================== /// \name Comparison Operators /// @{ @@ -126,6 +143,32 @@ struct array /// @} + +// Iteration =========================================================================================================== + + /// \name Iteration + /// @{ + + /// + /// \returns A pointer to the first element of the array + constexpr ValueT* begin() { return elements; } + + /// + /// \returns A pointer to one after the end of the array + constexpr ValueT* end() { return elements + ElemV; } + + + + /// + /// \returns A const-qualified pointer to the first element of the array + constexpr const ValueT* begin() const { return elements; } + + /// + /// \returns A const-qualified pointer to one after the end of the array + constexpr const ValueT* end() const { return elements + ElemV; } + + /// @} + private: template static bool _compare(const array& lhs, const array& rhs, const_index_sequence) { diff --git a/include/fennec/containers/containers.h b/include/fennec/containers/containers.h new file mode 100644 index 0000000..6dcb13c --- /dev/null +++ b/include/fennec/containers/containers.h @@ -0,0 +1,94 @@ +// ===================================================================================================================== +// 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 containers.h +/// \brief fennec containers library main header +/// +/// +/// \details +/// \author Medusa Slockbower +/// +/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) +/// +/// + +#ifndef FENNEC_CONTAINERS_CONTAINERS_H +#define FENNEC_CONTAINERS_CONTAINERS_H + +/// +/// \page fennec_containers Containers Library +/// +/// \brief The fennec Containers Library. +/// Includes various data structures, those specified in the C++ Standard Library, and custom data structures +/// that fennec uses. +/// +/// \code #include \endcode +/// +/// \section fennec_containers_cppstdlib C++ Standard Template Library +/// +/// | Symbol | Implemented | Passed | +/// |:----------------------------------------------------------------------------|:-----------:|:------:| +/// | \ref fennec::any "fennec::any" | ⛔ | ⛔ | +/// | \ref fennec::array "fennec::array" | ✅ | ✅ | +/// | \ref fennec::bitset "fennec::bitset" | ⛔ | ⛔ | +/// | \ref fennec::deque "fennec::deque" | ⛔ | ⛔ | +/// | \ref fennec::dynarray "fennec::dynarray" `std::vector` | 🚧 | 🚧 | +/// | \ref fennec::list "fennec::list" | ✅ | ✅ | +/// | \ref fennec::map "fennec::map" `std::unordered_map` | ✅ | ✅ | +/// | \ref fennec::map_sequence "fennec::map_sequence" `std::map` | ⛔ | ⛔ | +/// | \ref fennec::multiset "fennec::multiset" `std::unordered_multiset` | ⛔ | ⛔ | +/// | \ref fennec::multisequence "fennec::multisequence" `std::multiset` | ⛔ | ⛔ | +/// | \ref fennec::multimap "fennec::multimap" `std::unordered_multimap` | ⛔ | ⛔ | +/// | \ref fennec::multimap_sequence "fennec::multimap_sequence" `std::multimap` | ⛔ | ⛔ | +/// | \ref fennec::optional "fennec::optional" | ✅ | ✅ | +/// | \ref fennec::pair "fennec::pair" | ✅ | ✅ | +/// | \ref fennec::sequence "fennec::sequence" `std::set` | ⛔ | ⛔ | +/// | \ref fennec::set "fennec::set" `std::unordered_set` | ✅ | ✅ | +/// | \ref fennec::tuple "fennec::tuple" | 🚧 | 🚧 | +/// | \ref fennec::variant "fennec::variant" | ⛔ | ⛔ | +/// +/// +/// \section fennec_containers_fennec fennec +/// +/// | Symbol | Implemented | Passed | +/// |:-------------------------|:-----------:|:------:| +/// | \ref fennec::graph | 🚧 | 🚧 | +/// | \ref fennec::object_pool | 🚧 | 🚧 | +/// | \ref fennec::rdtree | ✅ | ✅ | +/// +/// +/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) +/// + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // FENNEC_CONTAINERS_CONTAINERS_H \ No newline at end of file diff --git a/include/fennec/containers/deque.h b/include/fennec/containers/deque.h index 032a7e2..263105b 100644 --- a/include/fennec/containers/deque.h +++ b/include/fennec/containers/deque.h @@ -26,15 +26,40 @@ namespace fennec { +/// +/// +/// \brief Data structure defining a double-ended queue. +/// +/// \details +/// 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$ | +/// +/// \tparam TypeT value type template> struct deque { // Definitions ========================================================================================================= public: - using elem_t = TypeT; + using value_t = TypeT; + class iterator; +private: struct node { - elem_t value; + value_t value; node *prev, *next; template @@ -46,11 +71,18 @@ public: ~node() = default; }; +public: using alloc_t = allocator_traits::template rebind; + using elem_t = node*; // Constructors ======================================================================================================== + /// \name Constructors & Destructor + /// @{ + + /// + /// \brief Default Constructor, initializes an empty deque deque() : _alloc() , _first(nullptr) @@ -58,6 +90,24 @@ public: , _size(0) { } + /// + /// \brief Copy Constructor + /// \param deque the deque to copy + deque(const deque& deque) + : _alloc(deque._alloc) + , _first(nullptr) + , _last(nullptr) + , _size(0) { + const elem_t node = deque._first; + while (node) { + this->push_back(node->value); + node = node->next; + } + } + + /// + /// \brief Deque Move Constructor + /// \param deque the deque to move deque(deque&& deque) noexcept : _alloc(deque._alloc) , _first(deque._first) @@ -67,69 +117,128 @@ public: deque._last = nullptr; } + /// + /// \brief Destructor, calls deque::clear ~deque() { clear(); } + /// @} + // Properties ========================================================================================================== - bool empty() const { + /// \name Properties + /// @{ + + /// + /// \returns `true` when the deque is empty, `false` otherwise + constexpr bool empty() const { return _size == 0; } - size_t size() const { + /// + /// \returns the number of elements in size() + constexpr size_t size() const { return _size; } + /// @} + // Access ============================================================================================================== - elem_t& front() { + /// \name Access + /// @{ + + /// + /// \returns a reference to the first element in the deque + value_t& front() { assert(not empty(), "Attempted to access an empty deque."); return _first->value; } - elem_t& back() { + /// + /// \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."); + 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."); 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."); + return _last->value; + } -// Insertion =========================================================================================================== + /// @} - void push_front(elem_t&& elem) { + +// Modifiers =========================================================================================================== + + /// \name Modifiers + /// @{ + + /// + /// \brief Push Front Move, moves a value to the front of the deque + /// \param elem the value to move + void push_front(value_t&& elem) { this->_push_front(elem); } - void push_front(const elem_t& elem) { + /// + /// \brief Push Front Copy, copies a value to the front of the deque + /// \param elem the value to copy + void push_front(const value_t& elem) { this->_push_front(elem); } + /// + /// \brief Emplace Front, constructs a new value at the front of the deque + /// \tparam ArgsT Argument types + /// \param args Arguments used to construct the value template void emplace_front(ArgsT&&...args) { this->_push_front(fennec::forward(args)...); } - void push_back(elem_t&& elem) { + + /// + /// \brief Push Back Move, moves a value to the back of the deque + /// \param elem the value to move + void push_back(value_t&& elem) { this->_push_back(elem); } - void push_back(const elem_t& elem) { + /// + /// \brief Push Back Copy, copies a value to the back of the deque + /// \param elem the value to copy + void push_back(const value_t& elem) { this->_push_back(elem); } + /// + /// \brief Emplace Back, constructs a new value at the back of the deque + /// \tparam ArgsT Argument types + /// \param args Arguments used to construct the value template void emplace_back(ArgsT&&...args) { this->_push_back(fennec::forward(args)...); } - -// Deletion ============================================================================================================ - + /// + /// \brief Clears the contents of the deque void clear() { - node* it = _first; + elem_t it = _first; while (it) { - node* next = it->next; + elem_t next = it->next; fennec::destruct(it); _alloc.deallocate(it); it = next; @@ -139,11 +248,13 @@ public: _size = 0; } + /// + /// \brief Erase the First Element void pop_front() { if (_first == nullptr) { return; } - node* next = _first->next; + elem_t next = _first->next; fennec::destruct(_first); _alloc.deallocate(_first); _first = next; @@ -151,11 +262,13 @@ public: --_size; } + /// + /// \brief Erase the Last Element void pop_back() { if (_last == nullptr) { return; } - node* prev = _last->prev; + elem_t prev = _last->prev; fennec::destruct(_last); _alloc.deallocate(_last); _last = prev; @@ -163,6 +276,15 @@ public: --_size; } + /// @} + + +// Iteration =========================================================================================================== + + /* + * TODO: Decide whether you should be able to iterate over a deque + */ + private: alloc_t _alloc; node *_first, *_last; @@ -170,7 +292,7 @@ private: template void _push_front(ArgsT&&...args) { - node* next = _first; + elem_t next = _first; _first = _alloc.allocate(1); fennec::construct(_first, nullptr, next, fennec::forward(args)...); if (next) { @@ -183,7 +305,7 @@ private: template void _push_back(ArgsT&&...args) { - node* prev = _last; + elem_t prev = _last; _last = _alloc.allocate(1); fennec::construct(_last, prev, nullptr, fennec::forward(args)...); if (prev) { diff --git a/include/fennec/containers/dynarray.h b/include/fennec/containers/dynarray.h index 652e609..65dee72 100644 --- a/include/fennec/containers/dynarray.h +++ b/include/fennec/containers/dynarray.h @@ -40,15 +40,21 @@ namespace fennec /// /// -/// \brief wrapper for dynamically sized arrays +/// \brief Wrapper for dynamically sized arrays /// \details -/// | Property | Value | -/// |-----------|:----------:| -/// | stable | \emoji x | -/// | access | \f$O(1)\f$ | -/// | insertion | \f$O(N)\f$ | -/// | deletion | \f$O(N)\f$ | -/// | space | \f$O(N)\f$ | +/// | 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$ | /// /// \tparam TypeT value type template> @@ -63,13 +69,20 @@ public: // Constructors ======================================================================================================== + /// \name Constructors & Destructor + /// @{ + /// /// \brief Default Constructor, initializes an empty allocation. - constexpr dynarray() : _alloc(8), _size(0) {} + constexpr dynarray() + : _alloc(8) + , _size(0) { + } /// /// \brief Alloc Constructor, initialize empty allocation with allocator instance. - /// \param alloc An allocator object to copy, for instances where the allocator needs to be initialized with some data. + /// \param alloc An allocator object to copy, for instances where the allocator needs to be initialized with some + /// data. constexpr dynarray(const alloc_t& alloc) : _alloc(8, alloc) , _size(0) { @@ -77,14 +90,16 @@ public: /// /// \brief Alloc Move Constructor, initialize empty allocation with allocator instance. - /// \param alloc An allocator object to copy, for instances where the allocator needs to be initialized with some data. + /// \param alloc An allocator object to copy, for instances where the allocator needs to be initialized with some + /// data. constexpr dynarray(alloc_t&& alloc) noexcept : _alloc(8, alloc) , _size(0) { } /// - /// \brief Sized Allocation, create an allocation of size `n` elements, initialized with the default constructor. + /// \brief Sized Allocation, create an allocation of size `n` elements, + /// initialized with the default constructor. constexpr dynarray(size_t n) : _alloc(n) , _size(n) @@ -96,7 +111,8 @@ public: } /// - /// \brief Sized Allocation Alloc Constructor, initializes a dynarray with allocator `alloc` and `n` elements using the default constructor. + /// \brief Sized Allocation Alloc Constructor, initializes a dynarray with allocator `alloc` and `n` elements + /// using the default constructor. /// \param n The number of elements /// \param alloc The allocator object to copy constexpr dynarray(size_t n, const alloc_t& alloc) @@ -109,7 +125,8 @@ public: } /// - /// \brief Sized Allocation Alloc Move Constructor, initializes a dynarray with allocator `alloc` and `n` elements using the default constructor. + /// \brief Sized Allocation Alloc Move Constructor, initializes a dynarray with allocator `alloc` and `n` elements + /// using the default constructor. /// \param n The number of elements /// \param alloc The allocator object to copy constexpr dynarray(size_t n, alloc_t&& alloc) @@ -122,8 +139,9 @@ public: } /// - /// \brief Sized Allocation Copy Constructor, Create an allocation of size `n` elements, with each element constructed using the copy constructor - /// \brief n the number of elements + /// \brief Sized Allocation Copy Constructor, Create an allocation of size `n` elements, with each element + /// constructed using the copy constructor + /// \param n the number of elements constexpr dynarray(size_t n, const TypeT& val) : _alloc(n) , _size(n) { @@ -143,13 +161,33 @@ public: /// \param n The number of objects to create /// \param args The arguments to create each object with template - constexpr dynarray(size_t n, ArgsT&&...args) { - element_t* addr = _alloc.data(); - for(; n > 0; --n, ++addr) { - fennec::construct(addr, fennec::forward(args)...); + constexpr dynarray(size_t n, ArgsT&&...args) + : _alloc(n) + , _size(n) { + for(; n > 0; --n) { + fennec::construct(&_alloc[n], fennec::forward(args)...); } } + /// + /// \brief Copy Constructor, uses the copy constructor to copy each element + /// \param arr the dynarray to copy + constexpr dynarray(const dynarray& arr) + : _alloc(arr._size) + , _size(arr._size) { + for (size_t i = 0; i < _size; ++i) { + fennec::construct(&_alloc[i], arr[i]); + } + } + + /// + /// \brief Move Constructor, takes ownership of the allocation + /// \param arr the dynarray to move + constexpr dynarray(dynarray&& arr) + : _alloc(fennec::move(arr._alloc)) + , _size(arr._size) { + } + /// /// \brief Default Destructor, destructs all elements and frees the underlying allocation constexpr ~dynarray() { @@ -160,9 +198,14 @@ public: } } + /// @} + // Properties ========================================================================================================== + /// \name Properties + /// @{ + /// /// \returns The size of the dynarray in elements constexpr size_t size() const { @@ -181,9 +224,14 @@ public: return _size == 0; } + /// @} + // Element Access ====================================================================================================== + /// \name Access + /// @{ + /// /// \brief Array Access Operator /// \param i The index to access @@ -226,28 +274,13 @@ public: return this->operator[](size() - 1); } - /// - /// \brief "Iterator" Begin Function - /// \returns A pointer to the first element in the dynarray - constexpr TypeT* begin() { return _alloc.data(); } - - /// - /// \brief "Iterator" End Function - /// \return A pointer to the address after the last element in the dynarray - constexpr TypeT* end() { return begin() + _size; } - - /// - /// \brief Const "Iterator" Begin Function - /// \returns A const qualified pointer to the first element in the dynarray - constexpr const TypeT* begin() const { return _alloc; } - - /// - /// \brief Const "Iterator" End Function - /// \return A const qualified pointer to the address after the last element in the dynarray - constexpr const TypeT* end() const { return begin() + _size; } + /// @} -// Insertion & Deletion ================================================================================================ +// Modifiers =========================================================================================================== + + /// \name Modifiers + /// @{ /// /// \brief Move Insertion @@ -364,6 +397,36 @@ public: } } + /// @} + + +// Iteration =========================================================================================================== + + /// \name Iteration + /// @{ + + /// + /// \brief "Iterator" Begin Function + /// \returns A pointer to the first element in the dynarray + constexpr TypeT* begin() { return _alloc.data(); } + + /// + /// \brief "Iterator" End Function + /// \return A pointer to the address after the last element in the dynarray + constexpr TypeT* end() { return begin() + _size; } + + /// + /// \brief Const "Iterator" Begin Function + /// \returns A const qualified pointer to the first element in the dynarray + constexpr const TypeT* begin() const { return _alloc; } + + /// + /// \brief Const "Iterator" End Function + /// \return A const qualified pointer to the address after the last element in the dynarray + constexpr const TypeT* end() const { return begin() + _size; } + + /// @} + private: constexpr void _grow() { _alloc.creallocate(_alloc.capacity() * 2); diff --git a/include/fennec/containers/graph.h b/include/fennec/containers/graph.h index 73fdd82..f883482 100644 --- a/include/fennec/containers/graph.h +++ b/include/fennec/containers/graph.h @@ -39,26 +39,54 @@ namespace fennec { -template +/// +/// \brief Graph Data Structure, describes sets of arbitrarily connected nodes +/// \tparam NodeT The type associated with each node +/// \tparam WeightT The type associated with each connection +template struct graph { public: - using weight_t = ConnectionT; +// Definitions ========================================================================================================= + + /// \name Definitions + /// @{ + using weight_t = WeightT; using node_t = NodeT; using conn_map_t = dynarray>; using node_pool_t = object_pool; using conn_pool_t = object_pool; static constexpr size_t npos = -1; + /// @} + +// Constructors ======================================================================================================== + + /// \name Constructors + /// @{ + + /// + /// \brief Default Constructor, initializes empty graph constexpr graph() = default; + + /// + /// \brief Destructor constexpr ~graph() = default; + /// @} + + + /// \name Assignment Operators + /// @{ constexpr graph& operator=(const graph& g) = default; constexpr graph& operator=(graph&& g) = default; + /// @} // Properties ========================================================================================================== + /// \name Properties + /// @{ constexpr size_t num_nodes() const { return _node_pool.size(); } @@ -74,6 +102,7 @@ public: constexpr bool empty() const { return num_nodes() == 0; } + /// @} // Nodes =============================================================================================================== @@ -106,18 +135,24 @@ public: // Connections ========================================================================================================= - list connections(size_t n) { - list conns; - if (_conn_map.empty()) return conns; - - for (auto it : _conn_map[n]) { - conns.push_back(it.first); + list> connections(size_t n) { + list> conns; + for (size_t i = 0; i < _conn_map.size(); ++i) { + for (auto it : _conn_map[i]) { + if (i == n || it.first == n) { + conns.emplace_back(i, n); + } + } } return conns; } template constexpr void connect(size_t a, size_t b, ArgsT&&...args) { + if (a == b) { + return; + } + if (_conn_map.size() < _node_pool.capacity()) { _conn_map.resize(_node_pool.capacity()); } @@ -132,25 +167,29 @@ public: } _conn_map[a].emplace(b, conn); - _conn_map[b].emplace(a, conn); } constexpr void disconnect(size_t a, size_t b) { - size_t c = *_conn_map[a][b]; + const auto* it = _conn_map[a][b]; + if (not it) { + return; + } + size_t c = *it; _conn_pool.erase(c); _conn_map[a].erase(b); - _conn_map[b].erase(a); } void disconnect(size_t n) { - list conns = connections(n); - for (size_t conn : conns) { - disconnect(n, conn); + const auto conns = connections(n); + for (const auto& conn : conns) { + disconnect(conn.first, conn.second); } } constexpr weight_t& operator[](size_t a, size_t b) { - return _conn_pool[_conn_map[a][b]]; + weight_t* it = _conn_map[a][b]; + assertd(it, "Element not Found!"); + return _conn_pool[*it]; } constexpr const weight_t& operator[](size_t a, size_t b) const { diff --git a/include/fennec/containers/list.h b/include/fennec/containers/list.h index ef6f9f5..5eaea94 100644 --- a/include/fennec/containers/list.h +++ b/include/fennec/containers/list.h @@ -43,18 +43,24 @@ namespace fennec /// /// -/// \brief wrapper for lists of elements +/// \brief Data Structure defining lists of elements /// \details /// 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 | \emoji x | -/// | access | \f$O(N)\f$ or \f$O(1)\f$ (front/back) | -/// | insertion | \f$O(N)\f$ or \f$O(1)\f$ (iterator) | -/// | deletion | \f$O(N)\f$ or \f$O(1)\f$ (iterator) | -/// | space | \f$O(N)\f$ | +/// | 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$ | /// /// \tparam TypeT value type template> @@ -75,7 +81,10 @@ public: class const_iterator; -// Constructors ======================================================================================================== +// Constructors & Destructor =========================================================================================== + + /// \name Constructors & Destructor + /// @{ /// /// \brief Default Constructor, initializes an empty list. @@ -91,9 +100,13 @@ public: } } + /// @} // Properties ========================================================================================================== + /// \name Properties + /// @{ + /// /// \returns The size of the list in elements. constexpr size_t size() const { return _size; } @@ -106,9 +119,14 @@ public: /// \returns `true` when the list is empty, `false` otherwise. constexpr bool empty() const { return _root == npos; } + /// @} + // Access ============================================================================================================== + /// \name Access + /// @{ + /// /// \brief Array Access Operator /// \param i Index to access @@ -163,8 +181,13 @@ public: return *_table[_last].value; } + /// @} -// Insertions & Deletions ============================================================================================== + +// Modifiers =========================================================================================================== + + /// \name Modifiers + /// @{ /// /// \brief Copy Insertion @@ -301,6 +324,8 @@ public: _erase(_last); } + /// @} + // ITERATOR ============================================================================================================ /// @@ -403,6 +428,9 @@ public: } }; + /// \name Iteration + /// @{ + /// /// \returns An iterator for the first element in the list constexpr iterator begin() { @@ -427,6 +455,8 @@ public: return const_iterator(this, npos); } + /// @} + private: allocation _table; dynarray _freed; diff --git a/include/fennec/containers/map.h b/include/fennec/containers/map.h index be028ce..1be8f34 100644 --- a/include/fennec/containers/map.h +++ b/include/fennec/containers/map.h @@ -44,7 +44,22 @@ namespace fennec */ /// -/// \brief Map for Pairing Values to Keys +/// \brief Data Structure defining a mapping of `key` \f$KeyT\f$ to `value` \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$ | +/// /// \tparam KeyT The Key Type /// \tparam ValueT The Value Type /// \tparam Hash The Hash to Use @@ -79,7 +94,10 @@ public: }; -// Constructors ======================================================================================================== +// Constructors & Destructor =========================================================================================== + + /// \name Constructors & Destructor + /// @{ /// /// \brief Default Constructor, initializes empty map @@ -89,9 +107,40 @@ public: /// \brief Destructor, Destructs all elements and releases the allocation constexpr ~map() = default; + /// @} + + +// Properties ========================================================================================================== + + /// \name Properties + /// @{ + + /// + /// \returns The size of the set + constexpr size_t size() const { + return _set.size(); + } + + /// + /// \returns `true` when there are no elements in the set, `false` otherwise + constexpr size_t empty() const { + return _set.size(); + } + + /// + /// \returns The capacity of the underlying allocation + constexpr size_t capacity() const { + return _set.capacity(); + } + + /// @} + // Access ============================================================================================================== + /// \name Access + /// @{ + /// /// \brief Key Access Operator /// \param key Key value to access @@ -132,8 +181,13 @@ public: return it ? &it->second : nullptr; } + /// @} -// Insertion & Deletion ================================================================================================ + +// Modifiers =========================================================================================================== + + /// \name Modifiers + /// @{ /// /// \brief Key-Value Insertion @@ -181,9 +235,14 @@ public: _set.erase(this->_find(fennec::forward(args)...)); } + /// @} + // Iteration =========================================================================================================== + /// \name Iteration + /// @{ + constexpr iterator begin() { return _set.begin(); } @@ -192,6 +251,8 @@ public: return _set.end(); } + /// @} + private: set_t _set; diff --git a/include/fennec/containers/multiset.h b/include/fennec/containers/multiset.h index f579740..310e061 100644 --- a/include/fennec/containers/multiset.h +++ b/include/fennec/containers/multiset.h @@ -33,17 +33,21 @@ namespace fennec /// /// -/// \brief wrapper for multisets of elements +/// \brief A Data Structure that defines a set of elements that may repeat /// \details -/// This data-structure behaves like a multiset, but does not use pointers, instead storing the table in-array -/// -/// | Property | Value | -/// |:----------|:----------:| -/// | stable | \emoji x | -/// | access | \f$O(1)\f$ | -/// | insertion | \f$O(1)\f$ | -/// | deletion | \f$O(1)\f$ | -/// | space | \f$O(1)\f$ | +/// | 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$ | /// /// \tparam TypeT The type to contain template, class Equals = equality, class Alloc = allocator> @@ -73,6 +77,9 @@ private: // Constructors ======================================================================================================== public: + /// \name Constructors & Destructor + /// @{ + /// /// \brief Default Constructor, initializes empty multiset constexpr multiset() @@ -193,24 +200,40 @@ public: } } + /// @} + // Properties ========================================================================================================== + /// \name Properties + /// @{ + /// /// \returns Size of the multiset in elements constexpr size_t size() const { return _size; } + /// + /// \returns `true` when the set is empty, `false` otherwise + constexpr bool empty() const { + return _size == 0; + } + /// /// \returns Capacity of the multiset in elements constexpr size_t capacity() const { return _alloc.capacity(); } + /// @} + // Access ============================================================================================================== + /// \name Access + /// @{ + /// /// \brief Find an Element /// \param val Value to find @@ -295,7 +318,12 @@ public: return &*_alloc[it._i].value; } -// Insertion & Deletion ================================================================================================ + /// @} + +// Modifiers =========================================================================================================== + + /// \name Modifiers + /// @{ /// /// \brief Move Insertion @@ -352,6 +380,8 @@ public: this->erase(this->find(val)); } + /// @} + // ITERATOR ============================================================================================================ @@ -462,6 +492,9 @@ public: } }; + /// \name Iteration + /// @{ + constexpr iterator begin() const { iterator it(this, 0); if (not _alloc[it._i].value) { @@ -474,6 +507,8 @@ public: return iterator(this, npos); } + /// @} + // PRIVATE ============================================================================================================= diff --git a/include/fennec/containers/object_pool.h b/include/fennec/containers/object_pool.h index 2e49816..0fb0070 100644 --- a/include/fennec/containers/object_pool.h +++ b/include/fennec/containers/object_pool.h @@ -18,6 +18,7 @@ #ifndef FENNEC_CONTAINERS_OBJECT_POOL_H #define FENNEC_CONTAINERS_OBJECT_POOL_H + #include #include #include diff --git a/include/fennec/containers/set.h b/include/fennec/containers/set.h index 4c5a106..15b3e55 100644 --- a/include/fennec/containers/set.h +++ b/include/fennec/containers/set.h @@ -38,13 +38,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 | \emoji x | -/// | access | \f$O(1)\f$ | -/// | insertion | \f$O(1)\f$ | -/// | deletion | \f$O(1)\f$ | -/// | space | \f$O(1)\f$ | +/// | 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$ | /// /// \tparam TypeT The type to contain template, class Equals = equality, class Alloc = allocator> @@ -73,6 +79,9 @@ private: // Constructors ======================================================================================================== public: + /// \name Constructors & Destructor + /// @{ + /// /// \brief Default Constructor, initializes empty set constexpr set() @@ -193,24 +202,40 @@ public: } } + /// @} + // Properties ========================================================================================================== + /// \name Properties + /// @{ + /// /// \returns Size of the set in elements constexpr size_t size() const { return _size; } + /// + /// \returns `true` when the set is empty, `false` otherwise + constexpr bool empty() const { + return _size == 0; + } + /// /// \returns Capacity of the set in elements constexpr size_t capacity() const { return _alloc.capacity(); } + /// @} + // Access ============================================================================================================== + /// \name Access + /// @{ + /// /// \brief Find an Element /// \param val Value to find @@ -291,7 +316,12 @@ public: return &*_alloc[it._i].value; } -// Insertion & Deletion ================================================================================================ + /// @} + +// Modifiers =========================================================================================================== + + /// \name Properties + /// @{ /// /// \brief Move Insertion @@ -348,6 +378,8 @@ public: this->erase(this->find(val)); } + /// @} + // ITERATOR ============================================================================================================ @@ -406,6 +438,9 @@ public: friend set; }; + /// \name Iteration + /// @{ + constexpr iterator begin() const { iterator it(this, 0); if (not _alloc[it._i].value) { @@ -418,6 +453,8 @@ public: return iterator(this, npos); } + /// @} + // PRIVATE ============================================================================================================= diff --git a/include/fennec/containers/tuple.h b/include/fennec/containers/tuple.h index 8f43394..e0684ae 100644 --- a/include/fennec/containers/tuple.h +++ b/include/fennec/containers/tuple.h @@ -29,6 +29,21 @@ 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 | ⛔ | +/// /// \tparam TypesT The types to store template struct tuple; diff --git a/include/fennec/core/engine.h b/include/fennec/core/engine.h index aca7f49..74c0aff 100644 --- a/include/fennec/core/engine.h +++ b/include/fennec/core/engine.h @@ -29,32 +29,19 @@ /// /// -/// \page documentation Documentation +/// \page libraries Libraries +/// +/// | Library | Brief | +/// |:---------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +/// | \subpage fennec_lang | Implementation for functions and classes related to the C++ Language, including base types, common utility functions, and metaprogramming templates | +/// | \subpage fennec_math | Implementation of math functions according to the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). Additional extensions are provided for other common math functions. | +/// | \subpage fennec_memory | Implementation of functions related to memory management. | +/// | \subpage fennec_containers | Implementation of common data structures, those that are specified in the C++ STD Library, and custom data structures that fennec uses. | /// -/// 1. \ref introduction "Introduction" -/// 1. \ref coding-standards "Coding Standards" -/// 2. \ref building-from-source "Building from Source" -/// 1. \ref building-from-terminal "Building from Terminal" -/// 2. \ref building-on-windows "Building on Windows" -/// 3. \ref running-the-test-suite "Running the Test Suite" -/// 4. \ref usage "Usage" -/// 5. \ref contribution "Contribution" -/// 6. \subpage libraries -/// 1. \ref fennec_lang "C++ Language Library" -/// 2. \ref fennec_math "Math Library" /// /// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) /// -/// -/// \page libraries Libraries -/// -/// | Library | Brief | -/// | :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -/// | \subpage fennec_lang | Implementation for functions and classes related to the C++ Language, including base types, common utility functions, and metaprogramming templates | -/// | \subpage fennec_math | Implementation of math functions according to the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). Additional extensions are provided for other common math functions. | -/// | \subpage fennec_memory | Implementation of functions related to memory management. | - #ifndef FENNEC_CORE_ENGINE_H #define FENNEC_CORE_ENGINE_H diff --git a/include/fennec/langproc/filesystem/file.h b/include/fennec/langproc/filesystem/file.h index 87fe5bf..c4f5787 100644 --- a/include/fennec/langproc/filesystem/file.h +++ b/include/fennec/langproc/filesystem/file.h @@ -276,6 +276,16 @@ public: size_t write(const void* data, size_t size, size_t n); + template + size_t write(const char (&data)[n]) { + return write(data, sizeof(char), n - 1); + } + + template + size_t write(const wchar_t (&data)[n]) { + return write(data, sizeof(wchar_t), n - 1); + } + template size_t write(const T* data, size_t n) { return write(static_cast(data), sizeof(T), n); diff --git a/planning/CONTAINERS.md b/planning/CONTAINERS.md index 947ea85..42bd7a6 100644 --- a/planning/CONTAINERS.md +++ b/planning/CONTAINERS.md @@ -28,29 +28,30 @@ Library and Template Library. | Symbol | Implemented | Passed | |:-------------------------------------|:-----------:|:------:| -| pair | ✔ | ✔ | -| tuple | ⭕ | ⭕ | -| optional | ✔ | ✔ | -| variant | ❌ | ❌ | -| any | ❌ | ❌ | -| bitset | ❌ | ❌ | -| array | ✔ | ✔ | -| dynarray (`std::vector`) | ⭕ | ⭕ | -| deque | ❌ | ❌ | -| list | ✔ | ✔ | -| set (`std::unordered_set`) | ✔ | ✔ | -| sequence (`std::set`) | ❌ | ❌ | -| map (`std::unordered_map`) | ✔ | ✔ | -| map_sequence (`std::map`) | ❌ | ❌ | -| multiset (`std::unordered_multiset`) | ❌ | ❌ | -| multisequence (`std::multiset`) | ❌ | ❌ | -| multimap (`std::unordered_multimap`) | ❌ | ❌ | -| multimap_sequence (`std::multimap`) | ❌ | ❌ | +| map (`std::unordered_map`) | ✅ | ✅ | +| map_sequence (`std::map`) | ⛔ | ⛔ | +| multiset (`std::unordered_multiset`) | ⛔ | ⛔ | +| multisequence (`std::multiset`) | ⛔ | ⛔ | +| multimap (`std::unordered_multimap`) | ⛔ | ⛔ | +| multimap_sequence (`std::multimap`) | ⛔ | ⛔ | +| pair | ✅ | ✅ | +| tuple | 🚧 | 🚧 | +| optional | ✅ | ✅ | +| variant | ⛔ | ⛔ | +| any | ⛔ | ⛔ | +| bitset | ⛔ | ⛔ | +| array | ✅ | ✅ | +| dynarray (`std::vector`) | 🚧 | 🚧 | +| deque | ⛔ | ⛔ | +| list | ✅ | ✅ | +| set (`std::unordered_set`) | ✅ | ✅ | +| sequence (`std::set`) | ⛔ | ⛔ | ### fennec -| Symbol | Implemented | Passed | -|:--------|:-----------:|:------:| -| graph | ❌ | ❌ | -| rd_tree | ✔ | ✔ | +| Symbol | Implemented | Passed | +|:------------|:-----------:|:------:| +| graph | 🚧 | 🚧 | +| object_pool | 🚧 | 🚧 | +| rd_tree | ✅ | ✅ | diff --git a/planning/CONTENTS.md b/planning/CONTENTS.md index 2c3f79e..d868dea 100644 --- a/planning/CONTENTS.md +++ b/planning/CONTENTS.md @@ -54,17 +54,17 @@ denote implementation and testing progress. The symbols are defined below. | Symbol | Meaning | Notes | |:------:|:------------------------|:----------------------------------------------------------| -| ✔ | Completed | Complete implementation and all tests passing. | -| ⭕ | Partial | Partial implementation and all tests implemented passing. | +| ✅ | Completed | Complete implementation and all tests passing. | +| 🚧 | Partial | Partial implementation and all tests implemented passing. | | ❓ | Untested | Not tested | -| ❌ | Unimplemented / Failing | Not implemented or any test is failing. | +| ⛔ | Unimplemented / Failing | Not implemented or any test is failing. | -| Implemented / Passed | ✔ | ⭕ | ❓ | ❌ | +| Implemented / Passed | ✅ | 🚧 | ❓ | ⛔ | |:--------------------:|--------------------------------------------------------------------|-------------------------------------------------------------------------------|---------|-----------------| -| ✔ | Implemented and Passing | Invalid | Invalid | Not Implemented | -| ⭕ | Implemented and Partial Testing with all implemented tests passing | Partial Implementation and Partial Testing with all implemented tests passing | Invalid | Not Implemented | +| ✅ | Implemented and Passing | Invalid | Invalid | Not Implemented | +| 🚧 | Implemented and Partial Testing with all implemented tests passing | Partial Implementation and Partial Testing with all implemented tests passing | Invalid | Not Implemented | | ❓ | Implemented and Untested | Partial Implementation and Untested | Invalid | Not Implemented | -| ❌ | Implemented and Any Test is Failing | Partial Implementation and any test is Failing | Invalid | Not Implemented | +| ⛔ | Implemented and Any Test is Failing | Partial Implementation and any test is Failing | Invalid | Not Implemented | diff --git a/planning/CPP_LANGUAGE.md b/planning/CPP_LANGUAGE.md index f28628a..159aa07 100644 --- a/planning/CPP_LANGUAGE.md +++ b/planning/CPP_LANGUAGE.md @@ -42,44 +42,44 @@ See: ### Diagnostics | Symbol | Implemented | Passed | |:--------|:-----------:|:------:| -| assert | ✔ | ✔ | -| assertf | ✔ | ✔ | -| assertd | ✔ | ✔ | +| assert | ✅ | ✅ | +| assertf | ✅ | ✅ | +| assertd | ✅ | ✅ | ### Utility | Symbol | Implemented | Passed | |:-----------------|:-----------:|:------:| -| numeric_limits | ✔ | ✔ | -| initializer_list | ❌ | ❌ | +| numeric_limits | ✅ | ✅ | +| initializer_list | ⛔ | ⛔ | ### Primary Types | Symbol | Implemented | Passed | |:---------------------------|:-----------:|:------:| -| is_void | ✔ | ✔ | -| is_null_pointer | ✔ | ✔ | -| is_integral | ✔ | ✔ | -| is_floating_point | ✔ | ✔ | -| is_array | ✔ | ❓ | -| is_enum | ❌ | ❌ | -| is_union | ❌ | ❌ | -| is_class | ✔ | ✔ | -| is_function | ❌ | ❌ | -| is_pointer | ✔ | ✔ | -| is_lvalue_reference | ✔ | ✔ | +| is_void | ✅ | ✅ | +| is_null_pointer | ✅ | ✅ | +| is_integral | ✅ | ✅ | +| is_floating_point | ✅ | ✅ | +| is_array | ✅ | ❓ | +| is_enum | ⛔ | ⛔ | +| is_union | ⛔ | ⛔ | +| is_class | ✅ | ✅ | +| is_function | ⛔ | ⛔ | +| is_pointer | ✅ | ✅ | +| is_lvalue_reference | ✅ | ✅ | | is_rvalue_reference | ✔ | ✔ | -| is_member_object_pointer | ❌ | ❌ | -| is_member_function_pointer | ❌ | ❌ | +| is_member_object_pointer | ⛔ | ⛔ | +| is_member_function_pointer | ⛔ | ⛔ | ### Composite Types | Symbol | Implemented | Passed | |:------------------|:-----------:|:------:| | is_fundamental | ✔ | ✔ | | is_arithmetic | ✔ | ✔ | -| is_scalar | ❌ | ❌ | -| is_object | ❌ | ❌ | -| is_compound | ❌ | ❌ | -| is_reference | ❌ | ❌ | -| is_member_pointer | ❌ | ❌ | +| is_scalar | ⛔ | ⛔ | +| is_object | ⛔ | ⛔ | +| is_compound | ⛔ | ⛔ | +| is_reference | ⛔ | ⛔ | +| is_member_pointer | ⛔ | ⛔ | ### Type Properties | Symbol | Implemented | Passed | @@ -87,37 +87,37 @@ See: | is_const | ✔ | ✔ | | is_volatile | ✔ | ✔ | | is_trivially_copyable | ✔ | ✔ | -| is_standard_layout | ❌ | ❌ | -| has_unique_object_representations | ❌ | ❌ | -| is_empty | ❌ | ❌ | -| is_polymorphic | ❌ | ❌ | -| is_abstract | ❌ | ❌ | -| is_final | ❌ | ❌ | -| is_aggregate | ❌ | ❌ | -| is_implicit_lifetime | ❌ | ❌ | +| is_standard_layout | ⛔ | ⛔ | +| has_unique_object_representations | ⛔ | ⛔ | +| is_empty | ⛔ | ⛔ | +| is_polymorphic | ⛔ | ⛔ | +| is_abstract | ⛔ | ⛔ | +| is_final | ⛔ | ⛔ | +| is_aggregate | ⛔ | ⛔ | +| is_implicit_lifetime | ⛔ | ⛔ | | is_signed | ✔ | ✔ | | is_unsigned | ✔ | ✔ | -| is_bounded_array | ❌ | ❌ | -| is_unbounded_array | ❌ | ❌ | -| is_scoped_enum | ❌ | ❌ | +| is_bounded_array | ⛔ | ⛔ | +| is_unbounded_array | ⛔ | ⛔ | +| is_scoped_enum | ⛔ | ⛔ | ### Supported Operations | Symbol | Implemented | Passed | |:------------------------------------|:-----------:|:------:| | is_constructible | ✔ | ✔ | | is_trivially_constructible | ✔ | ✔ | -| is_nothrow_constructible | ❌ | ❌ | +| is_nothrow_constructible | ⛔ | ⛔ | | is_default_constructible | ✔ | ✔ | -| is_trivially_default_constructible | ❌ | ❌ | -| is_nothrow_default_constructible | ❌ | ❌ | +| is_trivially_default_constructible | ⛔ | ⛔ | +| is_nothrow_default_constructible | ⛔ | ⛔ | | is_copy_constructible | ✔ | ✔ | -| is_trivially_copy_constructible | ❌ | ❌ | -| is_nothrow_copy_constructible | ❌ | ❌ | +| is_trivially_copy_constructible | ⛔ | ⛔ | +| is_nothrow_copy_constructible | ⛔ | ⛔ | | is_move_constructible | ✔ | ✔ | -| is_trivially_move_constructible | ❌ | ❌ | -| is_nothrow_move_constructible | ❌ | ❌ | -| is_destructible | ❌ | ❌ | -| is_trivially_destructible | ❌ | ❌ | +| is_trivially_move_constructible | ⛔ | ⛔ | +| is_nothrow_move_constructible | ⛔ | ⛔ | +| is_destructible | ⛔ | ⛔ | +| is_trivially_destructible | ⛔ | ❌ | | is_nothrow_destructible | ❌ | ❌ | | has_virtual_destructor | ❌ | ❌ | | is_swappable | ❌ | ❌ | @@ -174,7 +174,7 @@ See: | aligned_storage | ❌ | ❌ | | aligned_union | ❌ | ❌ | | aligned_union | ❌ | ❌ | -| decay | ⭕ | ⭕ | +| decay | 🚧 | 🚧 | | remove_cvref | ✔ | ✔ | | enable_if | ✔ | ✔ | | conditional | ✔ | ✔ | diff --git a/planning/LANGUAGE_PROCESSING.md b/planning/LANGUAGE_PROCESSING.md index f68405e..c0287d9 100644 --- a/planning/LANGUAGE_PROCESSING.md +++ b/planning/LANGUAGE_PROCESSING.md @@ -37,10 +37,10 @@ highly performant on the right surface. | Symbol | Implemented | Passed | |:---------|:-----------:|:------:| -| cstring | ✔ | ✔ | -| string | ✔ | ✔ | -| wcstring | ✔ | ✔ | -| wstring | ✔ | ✔ | +| cstring | ✅ | ✅ | +| string | ✅ | ✅ | +| wcstring | ✅ | ✅ | +| wstring | ✅ | ✅ | @@ -53,9 +53,9 @@ is create C++ classes that handle file streams, directory streams, and file path | Symbol | Implemented | Passed | |:----------|:-----------:|:------:| -| path | ✔ | ✔ | -| file | ✔ | ✔ | -| directory | ❌ | ❌ | +| path | ✅ | ✅ | +| file | ✅ | ✅ | +| directory | ⛔ | ⛔ | @@ -102,44 +102,44 @@ data values (e.g. floats, ints, etc.) to a readable language (e.g. ascii/utf8/ut | Symbol | Implemented | Passed | |:-------|:-----------:|:------:| -| JSON | ❌ | ❌ | -| HTML | ❌ | ❌ | -| XML | ❌ | ❌ | -| YAML | ❌ | ❌ | +| JSON | ⛔ | ⛔ | +| HTML | ⛔ | ⛔ | +| XML | ⛔ | ⛔ | +| YAML | ⛔ | ⛔ | ### Configuration | Symbol | Implemented | Passed | |:-------|:-----------:|:------:| -| INI | ❌ | ❌ | -| TOML | ❌ | ❌ | +| INI | ⛔ | ⛔ | +| TOML | ⛔ | ⛔ | ### Documents | Symbol | Implemented | Passed | |:---------|:-----------:|:------:| -| ODF | ❌ | ❌ | -| Markdown | ❌ | ❌ | -| PDF | ❌ | ❌ | +| ODF | ⛔ | ⛔ | +| Markdown | ⛔ | ⛔ | +| PDF | ⛔ | ⛔ | ### Spreadsheets & Tables | Symbol | Implemented | Passed | |:---------|:-----------:|:------:| -| ODS | ❌ | ❌ | -| CSV | ❌ | ❌ | +| ODS | ⛔ | ⛔ | +| CSV | ⛔ | ⛔ | ### Audio Formats | Symbol | Implemented | Passed | |:---------|:-----------:|:------:| -| MP3 | ❌ | ❌ | -| WAV | ❌ | ❌ | -| AAC | ❌ | ❌ | +| MP3 | ⛔ | ⛔ | +| WAV | ⛔ | ⛔ | +| AAC | ⛔ | ⛔ | ### Graphics Formats @@ -148,20 +148,20 @@ data values (e.g. floats, ints, etc.) to a readable language (e.g. ascii/utf8/ut | Symbol | Implemented | Passed | |:-------|:-----------:|:------:| -| BMP | ❌ | ❌ | -| DDS | ❌ | ❌ | -| JPG | ❌ | ❌ | -| PNG | ❌ | ❌ | -| TIFF | ❌ | ❌ | +| BMP | ⛔ | ⛔ | +| DDS | ⛔ | ⛔ | +| JPG | ⛔ | ⛔ | +| PNG | ⛔ | ⛔ | +| TIFF | ⛔ | ⛔ | #### Vector Graphics | Symbol | Implemented | Passed | |:-------|:-----------:|:------:| -| OTF | ❌ | ❌ | -| SVG | ❌ | ❌ | -| TTF | ❌ | ❌ | +| OTF | ⛔ | ⛔ | +| SVG | ⛔ | ⛔ | +| TTF | ⛔ | ⛔ | #### 3D Model Formats @@ -172,10 +172,10 @@ by assimp. | Symbol | Implemented | Passed | |:----------------|:-----------:|:------:| -| 3D | ❌ | ❌ | -| 3DS | ❌ | ❌ | -| 3MF | ❌ | ❌ | -| AC | ❌ | ❌ | +| 3D | ⛔ | ⛔ | +| 3DS | ⛔ | ⛔ | +| 3MF | ⛔ | ⛔ | +| AC | ⛔ | ❌ | | AC3D | ❌ | ❌ | | ACC | ❌ | ❌ | | AMJ | ❌ | ❌ | diff --git a/planning/MEMORY.md b/planning/MEMORY.md index e64cadd..237ba99 100644 --- a/planning/MEMORY.md +++ b/planning/MEMORY.md @@ -24,10 +24,10 @@ C stdlib and either wraps them or aliases them. | Symbol | Implemented | Passed | |:-----------------|:-----------:|:------:| -| allocator | ✔ | ✔ | -| allocator_traits | ✔ | ✔ | -| allocation | ✔ | ✔ | -| default_delete | ✔ | ❓ | -| unique_pointer | ✔ | ❓ | -| shared_pointer | ❌ | ❌ | -| pointer_traits | ❌ | ❌ | \ No newline at end of file +| allocator | ✅ | ✅ | +| allocator_traits | ✅ | ✅ | +| allocation | ✅ | ✅ | +| default_delete | ✅ | ❓ | +| unique_pointer | ✅ | ❓ | +| shared_pointer | ⛔ | ⛔ | +| pointer_traits | ⛔ | ⛔ | \ No newline at end of file diff --git a/planning/PLATFORM_SUPPORT.md b/planning/PLATFORM_SUPPORT.md index 8ea0a72..3795e67 100644 --- a/planning/PLATFORM_SUPPORT.md +++ b/planning/PLATFORM_SUPPORT.md @@ -25,7 +25,7 @@ Drivers that must be initialized for the engine context. Platform Support will be implemented in the following order: - Linux/BSD - Wayland - - OpenGL (EGL) ✔ + - OpenGL (EGL) ✅ - XKB - PulseAudio - Vulkan diff --git a/test.sh b/test.sh index 0272235..76dc1dc 100755 --- a/test.sh +++ b/test.sh @@ -38,10 +38,10 @@ Help() Debug() { mkdir -p build/debug - cd ./build/debug + cd ./build/debug || exit cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -S ../.. -B . cmake --build . --target fennec-test - cd ../../bin/debug/ + cd ../../bin/debug/ || exit valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind.txt ./fennec-test cd ../.. } @@ -49,10 +49,10 @@ Debug() Release() { mkdir -p build/release - cd ./build/release + cd ./build/release || exit cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S ../.. -B . cmake --build . --target fennec-test - cd ../../bin/release/ + cd ../../bin/release/ || exit valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind.txt ./fennec-test cd ../.. } @@ -60,10 +60,10 @@ Release() RelWithDebInfo() { mkdir -p build/relwithdebinfo - cd ./build/relwithdebinfo + cd ./build/relwithdebinfo || exit cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -S ../.. -B . cmake --build . --target fennec-test - cd ../../bin/relwithdebinfo/ + cd ../../bin/relwithdebinfo/ || exit valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind.txt ./fennec-test cd ../.. } @@ -71,10 +71,10 @@ RelWithDebInfo() MinSizeRel() { mkdir -p build/minsizerel - cd ./build/minsizerel + cd ./build/minsizerel || exit cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel -S ../.. -B . cmake --build . --target fennec-test - cd ../../bin/minsizerel/ + cd ../../bin/minsizerel/ || exit valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind.txt ./fennec-test cd ../.. }