Compare commits
19 Commits
3ddc2b3d97
...
custom_pla
| Author | SHA1 | Date | |
|---|---|---|---|
| 086c73f058 | |||
| 339f5c8cd8 | |||
| 18c0a7099d | |||
| 540c7fbce8 | |||
| cbcd699ab0 | |||
| ff27caab4f | |||
| fe4c49d092 | |||
| 037c62bf12 | |||
| 494d766741 | |||
| 83f0c01e29 | |||
| 4ff739d625 | |||
| 7cd38604a7 | |||
| 733fca41ef | |||
| 55a8c54119 | |||
| 27754a56d7 | |||
| fcf9c6adcb | |||
| e6c0a60ea9 | |||
| 5252ba84c9 | |||
| 73041e994d |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@
|
|||||||
/docs/
|
/docs/
|
||||||
/bin/
|
/bin/
|
||||||
/lib/
|
/lib/
|
||||||
|
/doxy/README.md
|
||||||
|
|||||||
@@ -20,14 +20,29 @@ cmake_minimum_required(VERSION 3.30)
|
|||||||
project(fennec)
|
project(fennec)
|
||||||
|
|
||||||
# External dependencies should be loaded here
|
# External dependencies should be loaded here
|
||||||
|
|
||||||
# CppTrace is a dependency of the project, added as a git submodule
|
|
||||||
add_subdirectory(external/cpptrace)
|
add_subdirectory(external/cpptrace)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
set(CMAKE_C_STANDARD 23)
|
set(CMAKE_C_STANDARD 23)
|
||||||
set(FENNEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
set(FENNEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
add_custom_target(fennec-dependencies
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Running dependencies."
|
||||||
|
COMMENT "Running dependencies."
|
||||||
|
)
|
||||||
|
|
||||||
|
macro(fennec_add_sources)
|
||||||
|
list(APPEND FENNEC_EXTRA_SOURCES ${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(fennec_add_definitions)
|
||||||
|
list(APPEND FENNEC_COMPILE_DEFINITIONS ${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(fennec_add_link_libraries)
|
||||||
|
list(APPEND FENNEC_LINK_LIBRARIES ${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
# include scripts
|
# include scripts
|
||||||
include("${FENNEC_SOURCE_DIR}/cmake/version.cmake")
|
include("${FENNEC_SOURCE_DIR}/cmake/version.cmake")
|
||||||
include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake")
|
include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake")
|
||||||
@@ -70,15 +85,23 @@ add_library(fennec STATIC
|
|||||||
|
|
||||||
|
|
||||||
# CONTAINERS ===========================================================================================================
|
# CONTAINERS ===========================================================================================================
|
||||||
|
include/fennec/containers/containers.h
|
||||||
|
|
||||||
include/fennec/containers/array.h
|
include/fennec/containers/array.h
|
||||||
|
include/fennec/containers/deque.h
|
||||||
include/fennec/containers/dynarray.h
|
include/fennec/containers/dynarray.h
|
||||||
|
include/fennec/containers/graph.h
|
||||||
include/fennec/containers/list.h
|
include/fennec/containers/list.h
|
||||||
include/fennec/containers/map.h
|
include/fennec/containers/map.h
|
||||||
|
include/fennec/containers/object_pool.h
|
||||||
include/fennec/containers/optional.h
|
include/fennec/containers/optional.h
|
||||||
include/fennec/containers/pair.h
|
include/fennec/containers/pair.h
|
||||||
include/fennec/containers/rdtree.h
|
include/fennec/containers/rdtree.h
|
||||||
include/fennec/containers/set.h
|
include/fennec/containers/set.h
|
||||||
|
include/fennec/containers/traversal.h
|
||||||
include/fennec/containers/tuple.h
|
include/fennec/containers/tuple.h
|
||||||
|
include/fennec/containers/variant.h
|
||||||
|
|
||||||
|
|
||||||
include/fennec/containers/detail/_tuple.h
|
include/fennec/containers/detail/_tuple.h
|
||||||
|
|
||||||
@@ -106,6 +129,9 @@ add_library(fennec STATIC
|
|||||||
include/fennec/lang/utility.h
|
include/fennec/lang/utility.h
|
||||||
include/fennec/lang/integer.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/_bits.h
|
||||||
include/fennec/lang/detail/_int.h
|
include/fennec/lang/detail/_int.h
|
||||||
include/fennec/lang/detail/_numeric_transforms.h
|
include/fennec/lang/detail/_numeric_transforms.h
|
||||||
@@ -115,8 +141,6 @@ add_library(fennec STATIC
|
|||||||
include/fennec/lang/detail/_type_sequences.h
|
include/fennec/lang/detail/_type_sequences.h
|
||||||
include/fennec/lang/detail/_typeuuid.h
|
include/fennec/lang/detail/_typeuuid.h
|
||||||
|
|
||||||
include/fennec/lang/assert.h source/lang/assert.cpp
|
|
||||||
|
|
||||||
|
|
||||||
# MEMORY ===============================================================================================================
|
# MEMORY ===============================================================================================================
|
||||||
include/fennec/memory/new.h source/memory/new.cpp
|
include/fennec/memory/new.h source/memory/new.cpp
|
||||||
@@ -130,11 +154,6 @@ add_library(fennec STATIC
|
|||||||
|
|
||||||
include/fennec/memory/detail/_ptr_traits.h
|
include/fennec/memory/detail/_ptr_traits.h
|
||||||
|
|
||||||
# CONCURRENCY ==========================================================================================================
|
|
||||||
include/fennec/concurrency/thread.h
|
|
||||||
include/fennec/concurrency/mutex.h
|
|
||||||
include/fennec/concurrency/atomic.h
|
|
||||||
|
|
||||||
# DEBUG ================================================================================================================
|
# DEBUG ================================================================================================================
|
||||||
source/debug/assert_impl.cpp
|
source/debug/assert_impl.cpp
|
||||||
|
|
||||||
@@ -195,18 +214,15 @@ add_library(fennec STATIC
|
|||||||
include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp
|
include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp
|
||||||
include/fennec/platform/interface/display.h source/platform/interface/display.cpp
|
include/fennec/platform/interface/display.h source/platform/interface/display.cpp
|
||||||
include/fennec/platform/interface/gfxcontext.h
|
include/fennec/platform/interface/gfxcontext.h
|
||||||
|
include/fennec/platform/interface/gfxsurface.h
|
||||||
|
|
||||||
|
|
||||||
# EXTRA SOURCES ========================================================================================================
|
# EXTRA SOURCES ========================================================================================================
|
||||||
|
|
||||||
${FENNEC_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)
|
add_dependencies(fennec metaprogramming fennec-dependencies)
|
||||||
|
|
||||||
target_compile_definitions(fennec PUBLIC
|
target_compile_definitions(fennec PUBLIC
|
||||||
${FENNEC_COMPILE_DEFINITIONS}
|
${FENNEC_COMPILE_DEFINITIONS}
|
||||||
@@ -218,8 +234,9 @@ target_link_options(fennec PRIVATE ${FENNEC_PRIVATE_LINK_OPTIONS}) # Do not comp
|
|||||||
# This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated
|
# This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated
|
||||||
|
|
||||||
target_link_libraries(fennec PRIVATE
|
target_link_libraries(fennec PRIVATE
|
||||||
cpptrace::cpptrace
|
|
||||||
${FENNEC_LINK_LIBRARIES}
|
${FENNEC_LINK_LIBRARIES}
|
||||||
|
|
||||||
|
cpptrace::cpptrace
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -232,6 +249,7 @@ file(COPY logo DESTINATION docs/logo)
|
|||||||
if(DOXYGEN_FOUND)
|
if(DOXYGEN_FOUND)
|
||||||
add_dependencies(fennec fennecdocs)
|
add_dependencies(fennec fennecdocs)
|
||||||
set(DOXY_OUTPUT_DIR "${FENNEC_SOURCE_DIR}/docs")
|
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
|
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_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
|
set(DOXYGEN_CONFIG_OUT "${FENNEC_SOURCE_DIR}/doxy/Doxyfile") # Generated config file from input
|
||||||
|
|||||||
90
README.md
90
README.md
@@ -8,17 +8,23 @@
|
|||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
## Table of Contents
|
<a id="table-of-contents"></a>
|
||||||
|
<h2>Table of Contents</h2>
|
||||||
|
|
||||||
|
* [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) → `apt`
|
||||||
|
* [Arch](#arch) → `pacman`
|
||||||
|
* [Fedora](#fedora) → `dnf`
|
||||||
|
* [Building on Windows](#building-on-windows)
|
||||||
|
* [Running the Test Suite](#running-the-test-suite)
|
||||||
|
* [Usage](#usage)
|
||||||
|
* [Licensing](#licensing)
|
||||||
|
* [Contribution](#contribution)
|
||||||
|
|
||||||
1. [Introduction](#introduction)
|
|
||||||
1. [Coding Standards](#coding-standards)
|
|
||||||
2. [Building from Source](#building-from-source)
|
|
||||||
1. [Building from Terminal](#building-from-terminal)
|
|
||||||
2. [Building on Windows](#building-on-windows)
|
|
||||||
3. [Running the Test Suite](#running-the-test-suite)
|
|
||||||
4. [Usage](#usage)
|
|
||||||
5. [Contribution](#contribution)
|
|
||||||
6. [Documentation](./documentation.html)
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
@@ -125,6 +131,7 @@ is also a viable IDE but involves some extra setup.
|
|||||||
|-------------------|----------------------------------------------------------------------------------------------------------|
|
|-------------------|----------------------------------------------------------------------------------------------------------|
|
||||||
| C/C++ Compiler | GCC/G++ is the compiler that fennec is designed around, however, Clang, MSVC, and MinGW may also be used |
|
| C/C++ Compiler | GCC/G++ is the compiler that fennec is designed around, however, Clang, MSVC, and MinGW may also be used |
|
||||||
| CMake | The build manager used by the engine |
|
| CMake | The build manager used by the engine |
|
||||||
|
| glew | OpenGL Extension Wrangler, necessary for modern OpenGL |
|
||||||
| A build system | Any build system will work, however, `build.sh` uses Ninja by default. |
|
| A build system | Any build system will work, however, `build.sh` uses Ninja by default. |
|
||||||
| A memory debugger | Any memory debugger will work, however, `test.sh` uses Valgrind by default. |
|
| A memory debugger | Any memory debugger will work, however, `test.sh` uses Valgrind by default. |
|
||||||
| Doxygen | Doxygen is required for building the documentation for fennec. This is an optional dependency |
|
| Doxygen | Doxygen is required for building the documentation for fennec. This is an optional dependency |
|
||||||
@@ -141,11 +148,53 @@ for more info.
|
|||||||
  By default, the CMake generator used is Ninja, which requires Ninja to be installed. You can modify the
|
  By default, the CMake generator used is Ninja, which requires Ninja to be installed. You can modify the
|
||||||
build scripts to use another build manager, see the [CMake documentation for available generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html).
|
build scripts to use another build manager, see the [CMake documentation for available generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html).
|
||||||
|
|
||||||
|
|
||||||
  I will at no point provide official cross-compilation toolchains for fennec. However, I will provide tools for
|
  I will at no point provide official cross-compilation toolchains for fennec. However, I will provide tools for
|
||||||
using specific toolchains for specific platforms that necessitate this. The primary examples would be Android and iOS.
|
using specific toolchains for specific platforms that necessitate this. The primary examples would be Android and iOS.
|
||||||
If you wish to build for Windows *and* Linux, your options are WSL or Dual Boot. I recommend Dual Boot over WSL.
|
If you wish to build for Windows *and* Linux, your options are WSL or Dual Boot. I recommend Dual Boot over WSL.
|
||||||
|
|
||||||
|
|
||||||
|
<a id="debian"></a>
|
||||||
|
#### Debian
|
||||||
|
|
||||||
|
On Debian-based distributions, you can install dependencies using the following command:
|
||||||
|
```shell
|
||||||
|
sudo apt install build-essential cmake ninja-build libglew-dev valgrind
|
||||||
|
git submodule update --force --init --recursive --remote
|
||||||
|
```
|
||||||
|
|
||||||
|
for Doxygen run:
|
||||||
|
```shell
|
||||||
|
sudo apt install doxygen graphviz
|
||||||
|
```
|
||||||
|
|
||||||
|
<a id="arch"></a>
|
||||||
|
#### Arch
|
||||||
|
|
||||||
|
On Arch-based distributions, you can install dependencies using the following command:
|
||||||
|
```shell
|
||||||
|
sudo pacman -S base-devel cmake ninja glew valgrind
|
||||||
|
git submodule update --force --init --recursive --remote
|
||||||
|
```
|
||||||
|
|
||||||
|
for Doxygen run:
|
||||||
|
```shell
|
||||||
|
sudo pacman -S doxygen graphviz
|
||||||
|
```
|
||||||
|
|
||||||
|
<a id="fedora"></a>
|
||||||
|
#### Fedora
|
||||||
|
|
||||||
|
On Fedora-based distributions, you can install dependencies using the following command:
|
||||||
|
```shell
|
||||||
|
sudo dnf install build-essential g++ cmake ninja-build glew-devel valgrind
|
||||||
|
git submodule update --force --init --recursive --remote
|
||||||
|
```
|
||||||
|
|
||||||
|
for Doxygen run:
|
||||||
|
```shell
|
||||||
|
sudo dnf install doxygen graphviz
|
||||||
|
```
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<a id="building-on-windows"></a>
|
<a id="building-on-windows"></a>
|
||||||
@@ -155,7 +204,7 @@ If you wish to build for Windows *and* Linux, your options are WSL or Dual Boot.
|
|||||||
script in WSL, simply use the "bash" command in Command Prompt or PowerShell. The script will require
|
script in WSL, simply use the "bash" command in Command Prompt or PowerShell. The script will require
|
||||||
the build [dependencies](#dependencies) installed and configured to be available on the `PATH` environment variable.
|
the build [dependencies](#dependencies) installed and configured to be available on the `PATH` environment variable.
|
||||||
|
|
||||||
Fore more details, [see this blog post](https://blogs.windows.com/windows-insider/2016/04/06/announcing-windows-10-insider-preview-build-14316/) for Windows Build 14316.
|
For more details, [see this blog post](https://blogs.windows.com/windows-insider/2016/04/06/announcing-windows-10-insider-preview-build-14316/) for Windows Build 14316.
|
||||||
|
|
||||||
Otherwise, follow the sequence of commands provided in the bash script.
|
Otherwise, follow the sequence of commands provided in the bash script.
|
||||||
|
|
||||||
@@ -206,23 +255,26 @@ information displayed is correct.
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|
||||||
|
<a id="licensing"></a>
|
||||||
### Licensing
|
### Licensing
|
||||||
|
|
||||||
The following content of this section is not legal advice, nor is it legally binding, and nor does it change the terms
|
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.
|
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
|
TLDR; You may license your game under whichever license you please. Any C++ code that is by definition a derivative work
|
||||||
fennec and using it in a commercial manner. This of course does not bar them from using fennec commercially, however
|
must be licensed under GPLv3 and freely available, everything else; assets, scripts, design documents, etc. may be under
|
||||||
it will prevent them from being able to make the derivative work proprietary. You are free to use and redistribute
|
the license of your choosing and remain proprietary.
|
||||||
fennec however you wish according to the terms of the license, which does not bar you from commercializing software
|
|
||||||
based on fennec.
|
  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
|
  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
|
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.
|
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.
|
  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
|
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.
|
intermediate step and will be erased when no longer needed.
|
||||||
|
|||||||
8
build.sh
8
build.sh
@@ -38,7 +38,7 @@ Help()
|
|||||||
Debug()
|
Debug()
|
||||||
{
|
{
|
||||||
mkdir -p build/debug
|
mkdir -p build/debug
|
||||||
cd ./build/debug
|
cd ./build/debug || exit
|
||||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -S ../.. -B .
|
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -S ../.. -B .
|
||||||
cmake --build . --target fennec
|
cmake --build . --target fennec
|
||||||
cd ../..
|
cd ../..
|
||||||
@@ -47,7 +47,7 @@ Debug()
|
|||||||
Release()
|
Release()
|
||||||
{
|
{
|
||||||
mkdir -p build/release
|
mkdir -p build/release
|
||||||
cd ./build/release
|
cd ./build/release || exit
|
||||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S ../.. -B .
|
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S ../.. -B .
|
||||||
cmake --build . --target fennec
|
cmake --build . --target fennec
|
||||||
cd ../..
|
cd ../..
|
||||||
@@ -56,7 +56,7 @@ Release()
|
|||||||
RelWithDebInfo()
|
RelWithDebInfo()
|
||||||
{
|
{
|
||||||
mkdir -p build/relwithdebinfo
|
mkdir -p build/relwithdebinfo
|
||||||
cd ./build/relwithdebinfo
|
cd ./build/relwithdebinfo || exit
|
||||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -S ../.. -B .
|
cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -S ../.. -B .
|
||||||
cmake --build . --target fennec
|
cmake --build . --target fennec
|
||||||
cd ../..
|
cd ../..
|
||||||
@@ -65,7 +65,7 @@ RelWithDebInfo()
|
|||||||
MinSizeRel()
|
MinSizeRel()
|
||||||
{
|
{
|
||||||
mkdir -p build/minsizerel
|
mkdir -p build/minsizerel
|
||||||
cd ./build/minsizerel
|
cd ./build/minsizerel || exit
|
||||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel -S ../.. -B .
|
cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel -S ../.. -B .
|
||||||
cmake --build . --target fennec
|
cmake --build . --target fennec
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|||||||
@@ -22,4 +22,4 @@ add_compile_options("-mxsave" "-Wall" "-Wextra" "-pedantic" "-Werror")
|
|||||||
|
|
||||||
set(FENNEC_PRIVATE_LINK_OPTIONS "-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates")
|
set(FENNEC_PRIVATE_LINK_OPTIONS "-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates")
|
||||||
|
|
||||||
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_COMPILER_GCC=1 FENNEC_NO_INLINE=[[gnu::noinline]])
|
list(APPEND FENNEC_COMPILE_DEFINITIONS _GLIBCXX_INCLUDE_NEXT_C_HEADERS=1 FENNEC_COMPILER_GCC=1 FENNEC_NO_INLINE=[[gnu::noinline]])
|
||||||
@@ -23,13 +23,13 @@ macro(fennec_check_platform)
|
|||||||
include("${FENNEC_SOURCE_DIR}/cmake/unix.cmake")
|
include("${FENNEC_SOURCE_DIR}/cmake/unix.cmake")
|
||||||
|
|
||||||
# compile definitions
|
# compile definitions
|
||||||
list(APPEND FENNEC_COMPILE_DEFINITIONS
|
fennec_add_definitions(
|
||||||
FENNEC_PLATFORM_NAME="Linux"
|
FENNEC_PLATFORM_NAME="Linux"
|
||||||
FENNEC_PLATFORM_LINUX=1
|
FENNEC_PLATFORM_LINUX=1
|
||||||
)
|
)
|
||||||
|
|
||||||
# extra source files
|
# extra source files
|
||||||
list(APPEND FENNEC_EXTRA_SOURCES
|
fennec_add_sources(
|
||||||
include/fennec/platform/linux/platform.h source/platform/linux/platform.cpp
|
include/fennec/platform/linux/platform.h source/platform/linux/platform.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ if(FENNEC_GRAPHICS_WANT_EGL)
|
|||||||
message(STATUS "EGL Requested")
|
message(STATUS "EGL Requested")
|
||||||
else()
|
else()
|
||||||
find_package(OpenGL)
|
find_package(OpenGL)
|
||||||
|
find_package(GLEW REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(TARGET OpenGL::GL AND TARGET GLEW::GLEW)
|
if(TARGET OpenGL::GL AND TARGET GLEW::GLEW)
|
||||||
message(STATUS "Found OpenGL: ${OPENGL_gl_LIBRARY}")
|
message(STATUS "Found OpenGL: ${OPENGL_gl_LIBRARY}")
|
||||||
list(APPEND FENNEC_LINK_LIBRARIES OpenGL::GL GLEW::GLEW)
|
fennec_add_link_libraries(OpenGL::GL GLEW::GLEW)
|
||||||
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_OPENGL=1)
|
fennec_add_definitions(FENNEC_GRAPHICS_OPENGL=1)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "No Suitable OpenGL implementation found.")
|
message(FATAL_ERROR "No Suitable OpenGL implementation found.")
|
||||||
endif()
|
endif()
|
||||||
@@ -38,15 +39,19 @@ if(FENNEC_GRAPHICS_WANT_EGL)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "Found EGL: ${OPENGL_egl_LIBRARY}")
|
message(STATUS "Found EGL: ${OPENGL_egl_LIBRARY}")
|
||||||
list(APPEND FENNEC_LINK_LIBRARIES OpenGL::EGL)
|
|
||||||
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_EGL=1)
|
fennec_add_link_libraries(OpenGL::EGL)
|
||||||
list(APPEND FENNEC_EXTRA_SOURCES
|
fennec_add_definitions(FENNEC_GRAPHICS_EGL=1)
|
||||||
|
|
||||||
|
fennec_add_sources(
|
||||||
include/fennec/platform/opengl/lib/fwd.h
|
include/fennec/platform/opengl/lib/fwd.h
|
||||||
include/fennec/platform/opengl/lib/enum.h
|
include/fennec/platform/opengl/lib/enum.h
|
||||||
include/fennec/platform/opengl/lib/buffer.h
|
include/fennec/platform/opengl/lib/buffer.h
|
||||||
include/fennec/platform/opengl/lib/texture.h
|
include/fennec/platform/opengl/lib/texture.h
|
||||||
include/fennec/platform/opengl/lib/vertex_array.h
|
include/fennec/platform/opengl/lib/vertex_array.h
|
||||||
|
|
||||||
|
include/fennec/platform/opengl/egl/fwd.h
|
||||||
include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp
|
include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp
|
||||||
|
include/fennec/platform/opengl/egl/surface.h source/platform/opengl/egl/surface.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@@ -19,11 +19,11 @@
|
|||||||
# generic unix functionality
|
# generic unix functionality
|
||||||
|
|
||||||
# compile definitions
|
# compile definitions
|
||||||
list(APPEND FENNEC_COMPILE_DEFINITIONS
|
fennec_add_definitions(
|
||||||
FENNEC_PLATFORM_UNIX=1
|
FENNEC_PLATFORM_UNIX=1
|
||||||
)
|
)
|
||||||
|
|
||||||
# extra source files
|
# extra source files
|
||||||
list(APPEND FENNEC_EXTRA_SOURCES
|
fennec_add_sources(
|
||||||
include/fennec/platform/unix/platform.h source/platform/unix/platform.cpp
|
include/fennec/platform/unix/platform.h source/platform/unix/platform.cpp
|
||||||
)
|
)
|
||||||
@@ -19,6 +19,23 @@
|
|||||||
# https://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a
|
# https://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a
|
||||||
# this script finds libwayland and dependencies
|
# this script finds libwayland and dependencies
|
||||||
|
|
||||||
|
# some of this code is based on SDL3's use of wayland-scanner
|
||||||
|
|
||||||
|
macro(fennec_wayland_get_header _SCANNER _XML _FILE)
|
||||||
|
set(_WAYLAND_PROT_H_CODE "${WAYLAND_HEADERS_DIR}/${_FILE}-client-protocols.h")
|
||||||
|
set(_WAYLAND_PROT_C_CODE "${WAYLAND_SOURCES_DIR}/${_FILE}-client.c")
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${_SCANNER} client-header "${_XML}" "${_WAYLAND_PROT_H_CODE}"
|
||||||
|
)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${_SCANNER} private-code "${_XML}" "${_WAYLAND_PROT_C_CODE}"
|
||||||
|
)
|
||||||
|
|
||||||
|
fennec_add_sources(${_WAYLAND_PROT_C_CODE} ${_WAYLAND_PROT_H_CODE})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
macro(fennec_check_wayland)
|
macro(fennec_check_wayland)
|
||||||
set(WAYLAND_CLIENT_FOUND 0)
|
set(WAYLAND_CLIENT_FOUND 0)
|
||||||
|
|
||||||
@@ -30,6 +47,7 @@ macro(fennec_check_wayland)
|
|||||||
WAYLAND_CLIENT_LIBRARY
|
WAYLAND_CLIENT_LIBRARY
|
||||||
NAMES wayland-client libwayland-client
|
NAMES wayland-client libwayland-client
|
||||||
)
|
)
|
||||||
|
find_program(WAYLAND_SCANNER NAMES wayland-scanner)
|
||||||
|
|
||||||
# EGL is required
|
# EGL is required
|
||||||
find_path(
|
find_path(
|
||||||
@@ -41,13 +59,34 @@ macro(fennec_check_wayland)
|
|||||||
NAMES wayland-egl libwayland-egl
|
NAMES wayland-egl libwayland-egl
|
||||||
)
|
)
|
||||||
|
|
||||||
if( (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY)
|
if( (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY AND WAYLAND_SCANNER)
|
||||||
AND (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARY))
|
AND (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARY))
|
||||||
message(STATUS "Found Wayland: ${WAYLAND_CLIENT_LIBRARY}")
|
message(STATUS "Found Wayland: ${WAYLAND_CLIENT_LIBRARY}")
|
||||||
|
|
||||||
|
set(WAYLAND_PROTOCOLS_DIR ${FENNEC_SOURCE_DIR}/include/fennec/platform/linux/wayland/lib/protocols)
|
||||||
|
set(WAYLAND_HEADERS_DIR ${FENNEC_SOURCE_DIR}/include/fennec/platform/linux/wayland/lib/headers)
|
||||||
|
set(WAYLAND_SOURCES_DIR ${FENNEC_SOURCE_DIR}/include/fennec/platform/linux/wayland/lib/sources)
|
||||||
|
|
||||||
|
# Search for base protocol xml
|
||||||
|
find_file(WAYLAND_PROTOCOL NAMES wayland.xml PATHS /usr/share/wayland /usr/share/wayland-protocols)
|
||||||
|
file(COPY ${WAYLAND_PROTOCOL} DESTINATION ${WAYLAND_PROTOCOLS_DIR})
|
||||||
|
|
||||||
|
# search for xdg protocols
|
||||||
|
find_file(XDG_SHELL_PROTOCOL NAMES xdg-shell.xml PATHS /usr/share/wayland-protocols/stable/xdg-shell)
|
||||||
|
file(COPY ${XDG_SHELL_PROTOCOL} DESTINATION ${WAYLAND_PROTOCOLS_DIR})
|
||||||
|
|
||||||
|
# include sub-dependencies
|
||||||
include("${FENNEC_SOURCE_DIR}/cmake/xkb.cmake")
|
include("${FENNEC_SOURCE_DIR}/cmake/xkb.cmake")
|
||||||
fennec_check_xkb()
|
fennec_check_xkb()
|
||||||
|
|
||||||
|
# generate protocols, based on SDL3
|
||||||
|
file(GLOB WAYLAND_PROTOCOLS_XML RELATIVE "${WAYLAND_PROTOCOLS_DIR}" "${WAYLAND_PROTOCOLS_DIR}/*.xml")
|
||||||
|
foreach(_XML IN LISTS WAYLAND_PROTOCOLS_XML)
|
||||||
|
get_filename_component(_FILE ${_XML} NAME_WLE)
|
||||||
|
fennec_wayland_get_header("${WAYLAND_SCANNER}" "${WAYLAND_PROTOCOLS_DIR}/${_XML}" "${_FILE}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Add sources and libraries
|
||||||
get_filename_component(
|
get_filename_component(
|
||||||
WAYLAND_CLIENT_LIBRARY
|
WAYLAND_CLIENT_LIBRARY
|
||||||
${WAYLAND_CLIENT_LIBRARY}
|
${WAYLAND_CLIENT_LIBRARY}
|
||||||
@@ -63,19 +102,18 @@ macro(fennec_check_wayland)
|
|||||||
set(WAYLAND_EGL_FOUND 1)
|
set(WAYLAND_EGL_FOUND 1)
|
||||||
set(FENNEC_GRAPHICS_WANT_EGL 1)
|
set(FENNEC_GRAPHICS_WANT_EGL 1)
|
||||||
|
|
||||||
list(APPEND FENNEC_EXTRA_SOURCES
|
fennec_add_sources(
|
||||||
# Dynamic Library Files
|
# Dynamic Library Files
|
||||||
include/fennec/platform/linux/wayland/lib/fwd.h
|
|
||||||
include/fennec/platform/linux/wayland/lib/sym.h
|
include/fennec/platform/linux/wayland/lib/sym.h
|
||||||
include/fennec/platform/linux/wayland/lib/wayland-client.h
|
include/fennec/platform/linux/wayland/lib/wayland.h
|
||||||
include/fennec/platform/linux/wayland/lib/wayland-util.h
|
|
||||||
include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp
|
include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp
|
||||||
|
|
||||||
# Fennec Files
|
# Fennec Files
|
||||||
include/fennec/platform/linux/wayland/display.h source/platform/linux/wayland/display.cpp
|
include/fennec/platform/linux/wayland/display.h source/platform/linux/wayland/display.cpp
|
||||||
|
include/fennec/platform/linux/wayland/window.h source/platform/linux/wayland/window.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FENNEC_COMPILE_DEFINITIONS
|
fennec_add_definitions(
|
||||||
FENNEC_HAS_WAYLAND=1
|
FENNEC_HAS_WAYLAND=1
|
||||||
FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}"
|
FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}"
|
||||||
FENNEC_LIB_WAYLAND_EGL="${WAYLAND_EGL_LIBRARY}"
|
FENNEC_LIB_WAYLAND_EGL="${WAYLAND_EGL_LIBRARY}"
|
||||||
|
|||||||
@@ -41,17 +41,16 @@ macro(fennec_check_xkb)
|
|||||||
|
|
||||||
set(XKB_FOUND 1)
|
set(XKB_FOUND 1)
|
||||||
|
|
||||||
list(APPEND FENNEC_EXTRA_SOURCES
|
fennec_add_sources(
|
||||||
# Dynamic Library Files
|
# Dynamic Library Files
|
||||||
include/fennec/platform/linux/xkb/lib/fwd.h
|
|
||||||
include/fennec/platform/linux/xkb/lib/sym.h
|
include/fennec/platform/linux/xkb/lib/sym.h
|
||||||
include/fennec/platform/linux/xkb/lib/xkbcommon.h
|
include/fennec/platform/linux/xkb/lib/xkb.h
|
||||||
include/fennec/platform/linux/xkb/lib/loader.h source/platform/linux/xkb/lib/loader.cpp
|
include/fennec/platform/linux/xkb/lib/loader.h source/platform/linux/xkb/lib/loader.cpp
|
||||||
|
|
||||||
# Fennec files
|
# Fennec files
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FENNEC_COMPILE_DEFINITIONS
|
fennec_add_definitions(
|
||||||
FENNEC_HAS_XKB=1
|
FENNEC_HAS_XKB=1
|
||||||
FENNEC_LIB_XKB="${XKB_LIBRARY}"
|
FENNEC_LIB_XKB="${XKB_LIBRARY}"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
<includes visible="$SHOW_HEADERFILE"/>
|
<includes visible="$SHOW_HEADERFILE"/>
|
||||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
<inheritancegraph visible="$CLASS_GRAPH"/>
|
||||||
<collaborationgraph visible="yes"/>
|
<collaborationgraph visible="yes"/>
|
||||||
|
<detaileddescription title=""/>
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<nestedclasses visible="yes" title=""/>
|
<nestedclasses visible="yes" title=""/>
|
||||||
<publictypes title=""/>
|
<publictypes title=""/>
|
||||||
@@ -83,7 +84,6 @@
|
|||||||
<related title="" subtitle=""/>
|
<related title="" subtitle=""/>
|
||||||
<membergroups visible="yes"/>
|
<membergroups visible="yes"/>
|
||||||
</memberdecl>
|
</memberdecl>
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdef>
|
<memberdef>
|
||||||
<inlineclasses title=""/>
|
<inlineclasses title=""/>
|
||||||
<typedefs title=""/>
|
<typedefs title=""/>
|
||||||
@@ -105,6 +105,7 @@
|
|||||||
<!-- Layout definition for a namespace page -->
|
<!-- Layout definition for a namespace page -->
|
||||||
<namespace>
|
<namespace>
|
||||||
<briefdescription visible="yes"/>
|
<briefdescription visible="yes"/>
|
||||||
|
<detaileddescription title=""/>
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<nestednamespaces visible="yes" title=""/>
|
<nestednamespaces visible="yes" title=""/>
|
||||||
<constantgroups visible="yes" title=""/>
|
<constantgroups visible="yes" title=""/>
|
||||||
@@ -121,7 +122,6 @@
|
|||||||
<variables title=""/>
|
<variables title=""/>
|
||||||
<membergroups visible="yes"/>
|
<membergroups visible="yes"/>
|
||||||
</memberdecl>
|
</memberdecl>
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdef>
|
<memberdef>
|
||||||
<inlineclasses title=""/>
|
<inlineclasses title=""/>
|
||||||
<typedefs title=""/>
|
<typedefs title=""/>
|
||||||
@@ -150,6 +150,7 @@
|
|||||||
<includegraph visible="yes"/>
|
<includegraph visible="yes"/>
|
||||||
<includedbygraph visible="yes"/>
|
<includedbygraph visible="yes"/>
|
||||||
<sourcelink visible="yes"/>
|
<sourcelink visible="yes"/>
|
||||||
|
<detaileddescription title=""/>
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<interfaces visible="yes" title=""/>
|
<interfaces visible="yes" title=""/>
|
||||||
<classes visible="yes" title=""/>
|
<classes visible="yes" title=""/>
|
||||||
@@ -167,7 +168,6 @@
|
|||||||
<variables title=""/>
|
<variables title=""/>
|
||||||
<membergroups visible="yes"/>
|
<membergroups visible="yes"/>
|
||||||
</memberdecl>
|
</memberdecl>
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdef>
|
<memberdef>
|
||||||
<inlineclasses title=""/>
|
<inlineclasses title=""/>
|
||||||
<defines title=""/>
|
<defines title=""/>
|
||||||
@@ -185,6 +185,7 @@
|
|||||||
<group>
|
<group>
|
||||||
<briefdescription visible="yes"/>
|
<briefdescription visible="yes"/>
|
||||||
<groupgraph visible="yes"/>
|
<groupgraph visible="yes"/>
|
||||||
|
<detaileddescription title=""/>
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<nestedgroups visible="yes" title=""/>
|
<nestedgroups visible="yes" title=""/>
|
||||||
<modules visible="yes" title=""/>
|
<modules visible="yes" title=""/>
|
||||||
@@ -210,7 +211,6 @@
|
|||||||
<friends title=""/>
|
<friends title=""/>
|
||||||
<membergroups visible="yes"/>
|
<membergroups visible="yes"/>
|
||||||
</memberdecl>
|
</memberdecl>
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdef>
|
<memberdef>
|
||||||
<pagedocs/>
|
<pagedocs/>
|
||||||
<inlineclasses title=""/>
|
<inlineclasses title=""/>
|
||||||
@@ -237,6 +237,7 @@
|
|||||||
<module>
|
<module>
|
||||||
<briefdescription visible="yes"/>
|
<briefdescription visible="yes"/>
|
||||||
<exportedmodules visible="yes"/>
|
<exportedmodules visible="yes"/>
|
||||||
|
<detaileddescription title=""/>
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<concepts visible="yes" title=""/>
|
<concepts visible="yes" title=""/>
|
||||||
<classes visible="yes" title=""/>
|
<classes visible="yes" title=""/>
|
||||||
@@ -246,7 +247,6 @@
|
|||||||
<variables title=""/>
|
<variables title=""/>
|
||||||
<membergroups title=""/>
|
<membergroups title=""/>
|
||||||
</memberdecl>
|
</memberdecl>
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<files visible="yes"/>
|
<files visible="yes"/>
|
||||||
</memberdecl>
|
</memberdecl>
|
||||||
@@ -256,10 +256,10 @@
|
|||||||
<directory>
|
<directory>
|
||||||
<briefdescription visible="yes"/>
|
<briefdescription visible="yes"/>
|
||||||
<directorygraph visible="yes"/>
|
<directorygraph visible="yes"/>
|
||||||
|
<detaileddescription title=""/>
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<dirs visible="yes"/>
|
<dirs visible="yes"/>
|
||||||
<files visible="yes"/>
|
<files visible="yes"/>
|
||||||
</memberdecl>
|
</memberdecl>
|
||||||
<detaileddescription title=""/>
|
|
||||||
</directory>
|
</directory>
|
||||||
</doxygenlayout>
|
</doxygenlayout>
|
||||||
|
|||||||
@@ -944,7 +944,7 @@ WARN_LOGFILE =
|
|||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = "/home/medusa/Documents/Work/Personal/fennec/include" \
|
INPUT = "/home/medusa/Documents/Work/Personal/fennec/include" \
|
||||||
"/home/medusa/Documents/Work/Personal/fennec/source" \
|
"/home/medusa/Documents/Work/Personal/fennec/source" \
|
||||||
"/home/medusa/Documents/Work/Personal/fennec/README.md"
|
"/home/medusa/Documents/Work/Personal/fennec/README.md"
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
@@ -1099,7 +1099,7 @@ EXAMPLE_RECURSIVE = NO
|
|||||||
# that contain images that are to be included in the documentation (see the
|
# that contain images that are to be included in the documentation (see the
|
||||||
# \image command).
|
# \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
|
# 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
|
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||||
@@ -1981,7 +1981,7 @@ GENERATE_LATEX = NO
|
|||||||
# The default directory is: latex.
|
# The default directory is: latex.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# 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
|
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
||||||
# invoked.
|
# invoked.
|
||||||
@@ -2664,7 +2664,7 @@ TEMPLATE_RELATIONS = NO
|
|||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to 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
|
# 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
|
# set to YES then doxygen will generate a graph for each documented file showing
|
||||||
@@ -2676,7 +2676,7 @@ INCLUDE_GRAPH = YES
|
|||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to 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
|
# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
|
||||||
# dependency graph for every global function or class method.
|
# dependency graph for every global function or class method.
|
||||||
|
|||||||
@@ -944,7 +944,7 @@ WARN_LOGFILE =
|
|||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = "@PROJECT_SOURCE_DIR@/include" \
|
INPUT = "@PROJECT_SOURCE_DIR@/include" \
|
||||||
"@PROJECT_SOURCE_DIR@/source" \
|
"@PROJECT_SOURCE_DIR@/source" \
|
||||||
"@PROJECT_SOURCE_DIR@/README.md"
|
"@PROJECT_SOURCE_DIR@/README.md"
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
@@ -1099,7 +1099,7 @@ EXAMPLE_RECURSIVE = NO
|
|||||||
# that contain images that are to be included in the documentation (see the
|
# that contain images that are to be included in the documentation (see the
|
||||||
# \image command).
|
# \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
|
# 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
|
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||||
@@ -1981,7 +1981,7 @@ GENERATE_LATEX = NO
|
|||||||
# The default directory is: latex.
|
# The default directory is: latex.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# 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
|
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
||||||
# invoked.
|
# invoked.
|
||||||
@@ -2664,7 +2664,7 @@ TEMPLATE_RELATIONS = NO
|
|||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to 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
|
# 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
|
# set to YES then doxygen will generate a graph for each documented file showing
|
||||||
@@ -2676,7 +2676,7 @@ INCLUDE_GRAPH = YES
|
|||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to 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
|
# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
|
||||||
# dependency graph for every global function or class method.
|
# dependency graph for every global function or class method.
|
||||||
|
|||||||
@@ -287,3 +287,8 @@ html.dark-mode {
|
|||||||
td.odd_c {
|
td.odd_c {
|
||||||
background-color: var(--odd-color)
|
background-color: var(--odd-color)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a + h2.groupheader {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
71
doxy/retrieve-emojis.py
Normal file
71
doxy/retrieve-emojis.py
Normal file
@@ -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)
|
||||||
4
doxy/static/graphs/containers/rdtree.svg
Normal file
4
doxy/static/graphs/containers/rdtree.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 60 KiB |
2
external/cpptrace
vendored
2
external/cpptrace
vendored
Submodule external/cpptrace updated: 9133b90a99...787d8af6f6
@@ -396,10 +396,10 @@ class GraphPrinter:
|
|||||||
|
|
||||||
class Iterator:
|
class Iterator:
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.node_pool = val['_node_pool']['_table']['_alloc']['_data']
|
self.node_pool = val['_vertex_pool']['_table']['_alloc']['_data']
|
||||||
self.max_nodes = val['_node_pool']['_table']['_alloc']['_capacity']
|
self.max_nodes = val['_vertex_pool']['_table']['_alloc']['_capacity']
|
||||||
self.conn_map = val['_conn_map']['_alloc']['_data']
|
self.conn_map = val['_edge_map']['_alloc']['_data']
|
||||||
self.max_conn = val['_conn_map']['_size']
|
self.max_conn = val['_edge_map']['_size']
|
||||||
self.index = 0
|
self.index = 0
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
@@ -447,7 +447,7 @@ class GraphPrinter:
|
|||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
self.size = val['_node_pool']['_size']
|
self.size = val['_vertex_pool']['_size']
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
if self.size == 0:
|
if self.size == 0:
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class CStringPrinter:
|
|||||||
return 'string'
|
return 'string'
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
value = "\"" + self.val['_str'].string('', 'replace', self.val['_size'] - 1) + "\""
|
value = "\"" + self.val['_str'].string('', 'replace', self.val['_size']) + "\""
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def display_hint(self):
|
def display_hint(self):
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \file array.h
|
/// \file array.h
|
||||||
/// \brief statically allocated array wrapper
|
/// \brief A header containing the definition for a static/stack allocated array
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \details
|
/// \details
|
||||||
@@ -40,61 +40,48 @@ namespace fennec
|
|||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \brief wrapper for fixed size arrays
|
/// \brief Data Structure that defines a compile-time allocated array
|
||||||
///
|
///
|
||||||
/// \details
|
/// \details
|
||||||
/// | Property | Value |
|
/// | Property | Value |
|
||||||
/// |:--------:|:-----------------------:|
|
/// |:----------:|:----------:|
|
||||||
/// | stable | \emoji heavy_check_mark |
|
/// | stable | ✅ |
|
||||||
/// | access | \f$O(1)\f$ |
|
/// | dynamic | ⛔ |
|
||||||
/// | space | \f$O(N)\f$ |
|
/// | 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 ValueT value type
|
||||||
/// \tparam ElemV number of elements
|
/// \tparam ElemV number of elements
|
||||||
template<typename ValueT, size_t ElemV>
|
template<typename ValueT, size_t ElemV>
|
||||||
struct array
|
struct array {
|
||||||
{
|
|
||||||
///
|
|
||||||
/// \brief backing c-style array handle
|
|
||||||
ValueT elements[ElemV];
|
|
||||||
|
|
||||||
/// \name Element Access
|
// Definitions =========================================================================================================
|
||||||
|
public:
|
||||||
|
using value_t = ValueT; ///< Alias for `ValueT`
|
||||||
|
|
||||||
|
// Public Members ======================================================================================================
|
||||||
|
|
||||||
|
/// \name Public Members
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \copydetails array::operator[](size_t) const
|
/// \brief backing c-style array handle
|
||||||
constexpr ValueT& operator[](size_t i) {
|
value_t data[ElemV];
|
||||||
assertd(i < ElemV, "Array Out of Bounds");
|
|
||||||
return elements[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief access specified element
|
|
||||||
/// \details Returns a reference to the element at \c i
|
|
||||||
/// \param i index of the element to return
|
|
||||||
/// \return reference to the requested element
|
|
||||||
///
|
|
||||||
/// \par Time-Complexity
|
|
||||||
/// Constant
|
|
||||||
///
|
|
||||||
/// \par Space-Complexity
|
|
||||||
/// Constant
|
|
||||||
constexpr const ValueT& operator[](size_t i) const {
|
|
||||||
assertd(i < ElemV, "Array Out of Bounds");
|
|
||||||
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
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Properties
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -111,21 +98,123 @@ struct array
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
|
/// \name Element Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \copydetails array::operator[](size_t) const
|
||||||
|
constexpr value_t& operator[](size_t i) {
|
||||||
|
assertd(i < ElemV, "Array Out of Bounds");
|
||||||
|
return data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief access specified element
|
||||||
|
/// \details Returns a reference to the element at \c i
|
||||||
|
/// \param i index of the element to return
|
||||||
|
/// \return reference to the requested element
|
||||||
|
///
|
||||||
|
/// \par Time-Complexity
|
||||||
|
/// Constant
|
||||||
|
///
|
||||||
|
/// \par Space-Complexity
|
||||||
|
/// Constant
|
||||||
|
constexpr const value_t& operator[](size_t i) const {
|
||||||
|
assertd(i < ElemV, "Array Out of Bounds");
|
||||||
|
return data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Access the first element
|
||||||
|
/// \returns A reference to the element at `elements[0]`
|
||||||
|
constexpr value_t& front() {
|
||||||
|
return data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Const Access the first element
|
||||||
|
/// \returns A const-qualified reference to the element at `elements[0]`
|
||||||
|
constexpr const value_t& front() const {
|
||||||
|
return data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Access the first element
|
||||||
|
/// \returns A reference to the element at `elements[ElemV - 1]`
|
||||||
|
constexpr value_t& back() {
|
||||||
|
return data[ElemV - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Const Access the first element
|
||||||
|
/// \returns A const-qualified reference to the element at `elements[ElemV - 1]`
|
||||||
|
constexpr const value_t& back() const {
|
||||||
|
return data[ElemV - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Comparison ==========================================================================================================
|
||||||
|
|
||||||
/// \name Comparison Operators
|
/// \name Comparison Operators
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief
|
/// \brief Checks if all elements in the arrays are equal
|
||||||
friend constexpr bool_t operator==(const array& lhs, const array& rhs) {
|
friend constexpr bool_t operator==(const array& lhs, const array& rhs) {
|
||||||
return array::_compare(lhs, rhs, make_index_sequence<ElemV>{});
|
return array::_compare(lhs, rhs, make_index_sequence<ElemV>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Checks if any element in the arrays is not equal
|
||||||
friend constexpr bool_t operator!=(const array& lhs, const array& rhs) {
|
friend constexpr bool_t operator!=(const array& lhs, const array& rhs) {
|
||||||
return not array::_compare(lhs, rhs, make_index_sequence<ElemV>{});
|
return not array::_compare(lhs, rhs, make_index_sequence<ElemV>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
// Iteration ===========================================================================================================
|
||||||
|
|
||||||
|
/// \name Iteration
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C++ Iterator Specification `begin()`
|
||||||
|
/// \returns A pointer to the first element of the array
|
||||||
|
constexpr value_t* begin() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C++ Iterator Specification `end()`
|
||||||
|
/// \returns A pointer to one after the end of the array
|
||||||
|
constexpr value_t* end() {
|
||||||
|
return data + ElemV;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Const C++ Iterator Specification `begin()`
|
||||||
|
/// \returns A const-qualified pointer to the first element of the array
|
||||||
|
constexpr const value_t* begin() const {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Const C++ Iterator Specification `end()`
|
||||||
|
/// \returns A const-qualified pointer to one after the end of the array
|
||||||
|
constexpr const value_t* end() const {
|
||||||
|
return data + ElemV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<size_t...i>
|
template<size_t...i>
|
||||||
static bool _compare(const array& lhs, const array& rhs, const_index_sequence<i...>) {
|
static bool _compare(const array& lhs, const array& rhs, const_index_sequence<i...>) {
|
||||||
|
|||||||
94
include/fennec/containers/containers.h
Normal file
94
include/fennec/containers/containers.h
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \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 <fennec/containers/containers.h> \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 <fennec/containers/traversal.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/tuple.h>
|
||||||
|
|
||||||
|
#endif // FENNEC_CONTAINERS_CONTAINERS_H
|
||||||
@@ -16,6 +16,18 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file deque.h
|
||||||
|
/// \brief A header containing the definition for a double-ended queue
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_DEQUE_H
|
#ifndef FENNEC_CONTAINERS_DEQUE_H
|
||||||
#define FENNEC_CONTAINERS_DEQUE_H
|
#define FENNEC_CONTAINERS_DEQUE_H
|
||||||
|
|
||||||
@@ -26,15 +38,40 @@
|
|||||||
namespace fennec
|
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<typename TypeT, typename AllocT = allocator<TypeT>>
|
template<typename TypeT, typename AllocT = allocator<TypeT>>
|
||||||
struct deque {
|
struct deque {
|
||||||
|
|
||||||
// Definitions =========================================================================================================
|
// Definitions =========================================================================================================
|
||||||
public:
|
public:
|
||||||
using elem_t = TypeT;
|
using value_t = TypeT; ///< Alias for the value type
|
||||||
|
class iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
struct node {
|
struct node {
|
||||||
elem_t value;
|
value_t value;
|
||||||
node *prev, *next;
|
node *prev, *next;
|
||||||
|
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
@@ -46,11 +83,18 @@ public:
|
|||||||
~node() = default;
|
~node() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
using alloc_t = allocator_traits<AllocT>::template rebind<node>;
|
using alloc_t = allocator_traits<AllocT>::template rebind<node>;
|
||||||
|
using elem_t = node*;
|
||||||
|
|
||||||
|
|
||||||
// Constructors ========================================================================================================
|
// Constructors ========================================================================================================
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Default Constructor, initializes an empty deque
|
||||||
deque()
|
deque()
|
||||||
: _alloc()
|
: _alloc()
|
||||||
, _first(nullptr)
|
, _first(nullptr)
|
||||||
@@ -58,6 +102,34 @@ public:
|
|||||||
, _size(0) {
|
, _size(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Alloc Constructor, initializes an empty deque with the specified allocator
|
||||||
|
/// \param alloc the allocator to copy
|
||||||
|
deque(const alloc_t& alloc)
|
||||||
|
: _alloc(alloc)
|
||||||
|
, _first(nullptr)
|
||||||
|
, _last(nullptr)
|
||||||
|
, _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
|
deque(deque&& deque) noexcept
|
||||||
: _alloc(deque._alloc)
|
: _alloc(deque._alloc)
|
||||||
, _first(deque._first)
|
, _first(deque._first)
|
||||||
@@ -67,69 +139,128 @@ public:
|
|||||||
deque._last = nullptr;
|
deque._last = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Destructor, calls deque::clear
|
||||||
~deque() {
|
~deque() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
// Properties ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
bool empty() const {
|
/// \name Properties
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns `true` when the deque is empty, `false` otherwise
|
||||||
|
constexpr bool empty() const {
|
||||||
return _size == 0;
|
return _size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
///
|
||||||
|
/// \returns the number of elements in size()
|
||||||
|
constexpr size_t size() const {
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Access ==============================================================================================================
|
// 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.");
|
assert(not empty(), "Attempted to access an empty deque.");
|
||||||
return _first->value;
|
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.");
|
assert(not empty(), "Attempted to access an empty deque.");
|
||||||
return _last->value;
|
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);
|
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);
|
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<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
void emplace_front(ArgsT&&...args) {
|
void emplace_front(ArgsT&&...args) {
|
||||||
this->_push_front(fennec::forward<ArgsT>(args)...);
|
this->_push_front(fennec::forward<ArgsT>(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);
|
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);
|
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<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
void emplace_back(ArgsT&&...args) {
|
void emplace_back(ArgsT&&...args) {
|
||||||
this->_push_back(fennec::forward<ArgsT>(args)...);
|
this->_push_back(fennec::forward<ArgsT>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
// Deletion ============================================================================================================
|
/// \brief Clears the contents of the deque
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
node* it = _first;
|
elem_t it = _first;
|
||||||
while (it) {
|
while (it) {
|
||||||
node* next = it->next;
|
elem_t next = it->next;
|
||||||
fennec::destruct(it);
|
fennec::destruct(it);
|
||||||
_alloc.deallocate(it);
|
_alloc.deallocate(it);
|
||||||
it = next;
|
it = next;
|
||||||
@@ -139,11 +270,13 @@ public:
|
|||||||
_size = 0;
|
_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Erase the First Element
|
||||||
void pop_front() {
|
void pop_front() {
|
||||||
if (_first == nullptr) {
|
if (_first == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node* next = _first->next;
|
elem_t next = _first->next;
|
||||||
fennec::destruct(_first);
|
fennec::destruct(_first);
|
||||||
_alloc.deallocate(_first);
|
_alloc.deallocate(_first);
|
||||||
_first = next;
|
_first = next;
|
||||||
@@ -151,11 +284,13 @@ public:
|
|||||||
--_size;
|
--_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Erase the Last Element
|
||||||
void pop_back() {
|
void pop_back() {
|
||||||
if (_last == nullptr) {
|
if (_last == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node* prev = _last->prev;
|
elem_t prev = _last->prev;
|
||||||
fennec::destruct(_last);
|
fennec::destruct(_last);
|
||||||
_alloc.deallocate(_last);
|
_alloc.deallocate(_last);
|
||||||
_last = prev;
|
_last = prev;
|
||||||
@@ -163,6 +298,15 @@ public:
|
|||||||
--_size;
|
--_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
// Iteration ===========================================================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Decide whether you should be able to iterate over a deque
|
||||||
|
*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
alloc_t _alloc;
|
alloc_t _alloc;
|
||||||
node *_first, *_last;
|
node *_first, *_last;
|
||||||
@@ -170,7 +314,7 @@ private:
|
|||||||
|
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
void _push_front(ArgsT&&...args) {
|
void _push_front(ArgsT&&...args) {
|
||||||
node* next = _first;
|
elem_t next = _first;
|
||||||
_first = _alloc.allocate(1);
|
_first = _alloc.allocate(1);
|
||||||
fennec::construct(_first, nullptr, next, fennec::forward<ArgsT>(args)...);
|
fennec::construct(_first, nullptr, next, fennec::forward<ArgsT>(args)...);
|
||||||
if (next) {
|
if (next) {
|
||||||
@@ -183,7 +327,7 @@ private:
|
|||||||
|
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
void _push_back(ArgsT&&...args) {
|
void _push_back(ArgsT&&...args) {
|
||||||
node* prev = _last;
|
elem_t prev = _last;
|
||||||
_last = _alloc.allocate(1);
|
_last = _alloc.allocate(1);
|
||||||
fennec::construct(_last, prev, nullptr, fennec::forward<ArgsT>(args)...);
|
fennec::construct(_last, prev, nullptr, fennec::forward<ArgsT>(args)...);
|
||||||
if (prev) {
|
if (prev) {
|
||||||
|
|||||||
@@ -29,9 +29,12 @@ template <std::size_t I, typename T>
|
|||||||
struct _tuple_leaf
|
struct _tuple_leaf
|
||||||
{
|
{
|
||||||
template <typename ArgT>
|
template <typename ArgT>
|
||||||
_tuple_leaf(ArgT&& arg) : value(fennec::forward<ArgT>(arg)) {}
|
constexpr _tuple_leaf(ArgT&& arg) : value(fennec::forward<ArgT>(arg)) {}
|
||||||
|
|
||||||
~_tuple_leaf() = default;
|
constexpr ~_tuple_leaf() = default;
|
||||||
|
|
||||||
|
constexpr _tuple_leaf& operator=(const _tuple_leaf&) = default;
|
||||||
|
constexpr _tuple_leaf& operator=(_tuple_leaf&&) noexcept = default;
|
||||||
|
|
||||||
T value;
|
T value;
|
||||||
};
|
};
|
||||||
@@ -43,9 +46,14 @@ template <size_t...IndicesV, typename...TypesT>
|
|||||||
struct _tuple<const_index_sequence<IndicesV...>, TypesT...> : _tuple_leaf<IndicesV, TypesT>...
|
struct _tuple<const_index_sequence<IndicesV...>, TypesT...> : _tuple_leaf<IndicesV, TypesT>...
|
||||||
{
|
{
|
||||||
template <typename...ArgsT>
|
template <typename...ArgsT>
|
||||||
_tuple(ArgsT&&... args) : _tuple_leaf<IndicesV, TypesT>(fennec::forward<ArgsT>(args))... {}
|
constexpr _tuple(ArgsT&&... args)
|
||||||
|
: _tuple_leaf<IndicesV, TypesT>(fennec::forward<ArgsT>(args))... {
|
||||||
|
}
|
||||||
|
|
||||||
~_tuple() = default;
|
constexpr _tuple& operator=(const _tuple&) = default;
|
||||||
|
constexpr _tuple& operator=(_tuple&&) noexcept = default;
|
||||||
|
|
||||||
|
constexpr ~_tuple() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \file dynarray.h
|
/// \file dynarray.h
|
||||||
/// \brief dynamically allocated array wrapper
|
/// \brief A header containing the definition for a dynamically allocated array
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \details
|
/// \details
|
||||||
@@ -40,15 +40,23 @@ namespace fennec
|
|||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \brief wrapper for dynamically sized arrays
|
/// \brief Wrapper for dynamically sized and allocated arrays
|
||||||
/// \details
|
/// \details
|
||||||
/// | Property | Value |
|
/// | Property | Value |
|
||||||
/// |-----------|:----------:|
|
/// |:----------:|:----------:|
|
||||||
/// | stable | \emoji x |
|
/// | stable | ⛔ |
|
||||||
/// | access | \f$O(1)\f$ |
|
/// | dynamic | ✅ |
|
||||||
/// | insertion | \f$O(N)\f$ |
|
/// | homogenous | ✅ |
|
||||||
/// | deletion | \f$O(N)\f$ |
|
/// | distinct | ⛔ |
|
||||||
/// | space | \f$O(N)\f$ |
|
/// | 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
|
/// \tparam TypeT value type
|
||||||
template<class TypeT, class Alloc = allocator<TypeT>>
|
template<class TypeT, class Alloc = allocator<TypeT>>
|
||||||
@@ -57,77 +65,90 @@ public:
|
|||||||
|
|
||||||
// Definitions =========================================================================================================
|
// Definitions =========================================================================================================
|
||||||
|
|
||||||
using element_t = TypeT;
|
using value_t = TypeT; ///< Alias for the value type
|
||||||
using alloc_t = Alloc;
|
using alloc_t = Alloc; ///< Alias for the allocator type
|
||||||
|
|
||||||
|
|
||||||
// Constructors ========================================================================================================
|
// Constructors ========================================================================================================
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Constructor, initializes an empty allocation.
|
/// \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.
|
/// \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
|
||||||
constexpr dynarray(const alloc_t& alloc)
|
/// data.
|
||||||
|
explicit constexpr dynarray(const alloc_t& alloc)
|
||||||
: _alloc(8, alloc)
|
: _alloc(8, alloc)
|
||||||
, _size(0) {
|
, _size(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Alloc Move Constructor, initialize empty allocation with allocator instance.
|
/// \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
|
||||||
constexpr dynarray(alloc_t&& alloc) noexcept
|
/// data.
|
||||||
|
explicit constexpr dynarray(alloc_t&& alloc) noexcept
|
||||||
: _alloc(8, alloc)
|
: _alloc(8, alloc)
|
||||||
, _size(0) {
|
, _size(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Sized Allocation, create an allocation of size `n` elements, initialized with the default constructor.
|
/// \brief Sized Allocation, initializes a dynarray with `n` elements using the default constructor.
|
||||||
constexpr dynarray(size_t n)
|
/// \param n The number of elements.
|
||||||
|
explicit constexpr dynarray(size_t n)
|
||||||
: _alloc(n)
|
: _alloc(n)
|
||||||
, _size(n)
|
, _size(n)
|
||||||
{
|
{
|
||||||
element_t* addr = _alloc.data();
|
value_t* addr = _alloc.data();
|
||||||
for(; n > 0; --n, ++addr) {
|
for(; n > 0; --n, ++addr) {
|
||||||
fennec::construct(addr);
|
fennec::construct(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \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 n The number of elements
|
||||||
/// \param alloc The allocator object to copy
|
/// \param alloc The allocator object to copy
|
||||||
constexpr dynarray(size_t n, const alloc_t& alloc)
|
constexpr dynarray(size_t n, const alloc_t& alloc)
|
||||||
: _alloc(n, alloc)
|
: _alloc(n, alloc)
|
||||||
, _size(n) {
|
, _size(n) {
|
||||||
element_t* addr = _alloc.data();
|
value_t* addr = _alloc.data();
|
||||||
for(; n > 0; --n, ++addr) {
|
for(; n > 0; --n, ++addr) {
|
||||||
fennec::construct(addr);
|
fennec::construct(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \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 n The number of elements
|
||||||
/// \param alloc The allocator object to copy
|
/// \param alloc The allocator object to copy
|
||||||
constexpr dynarray(size_t n, alloc_t&& alloc)
|
constexpr dynarray(size_t n, alloc_t&& alloc)
|
||||||
: _alloc(n, alloc)
|
: _alloc(n, alloc)
|
||||||
, _size(n) {
|
, _size(n) {
|
||||||
element_t* addr = _alloc.data();
|
value_t* addr = _alloc.data();
|
||||||
for(; n > 0; --n, ++addr) {
|
for(; n > 0; --n, ++addr) {
|
||||||
fennec::construct(addr);
|
fennec::construct(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Sized Allocation Copy Constructor, Create an allocation of size `n` elements, with each element constructed using the copy constructor
|
/// \brief Sized Allocation Copy Constructor, Create an allocation of size `n` elements, with each element
|
||||||
/// \brief n the number of elements
|
/// constructed using the copy constructor
|
||||||
|
/// \param n the number of elements
|
||||||
|
/// \param val the value to copy
|
||||||
constexpr dynarray(size_t n, const TypeT& val)
|
constexpr dynarray(size_t n, const TypeT& val)
|
||||||
: _alloc(n)
|
: _alloc(n)
|
||||||
, _size(n) {
|
, _size(n) {
|
||||||
element_t* addr = _alloc.data();
|
value_t* addr = _alloc.data();
|
||||||
for(; n > 0; --n, ++addr) {
|
for(; n > 0; --n, ++addr) {
|
||||||
fennec::construct(addr, val);
|
fennec::construct(addr, val);
|
||||||
}
|
}
|
||||||
@@ -143,26 +164,83 @@ public:
|
|||||||
/// \param n The number of objects to create
|
/// \param n The number of objects to create
|
||||||
/// \param args The arguments to create each object with
|
/// \param args The arguments to create each object with
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr dynarray(size_t n, ArgsT&&...args) {
|
constexpr explicit dynarray(size_t n, ArgsT&&...args)
|
||||||
element_t* addr = _alloc.data();
|
: _alloc(n)
|
||||||
for(; n > 0; --n, ++addr) {
|
, _size(n) {
|
||||||
fennec::construct(addr, fennec::forward<ArgsT>(args)...);
|
for(; n > 0; --n) {
|
||||||
|
fennec::construct(&_alloc[n], fennec::forward<ArgsT>(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) noexcept
|
||||||
|
: _alloc(fennec::move(arr._alloc))
|
||||||
|
, _size(arr._size) {
|
||||||
|
arr._size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Destructor, destructs all elements and frees the underlying allocation
|
/// \brief Default Destructor, destructs all elements and frees the underlying allocation
|
||||||
constexpr ~dynarray() {
|
constexpr ~dynarray() {
|
||||||
element_t* addr = _alloc.data();
|
value_t* addr = _alloc.data();
|
||||||
if (addr == nullptr) return;
|
if (addr == nullptr) return;
|
||||||
for(int n = _size; n > 0; --n, ++addr) {
|
for(int n = _size; n > 0; --n, ++addr) {
|
||||||
fennec::destruct(addr);
|
fennec::destruct(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
// Assignment ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Properties
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Copy Assignment Operator
|
||||||
|
/// \param arr the array to copy
|
||||||
|
/// \returns A dynarray after having copied each element of `arr`
|
||||||
|
constexpr dynarray& operator=(const dynarray& arr) {
|
||||||
|
this->clear();
|
||||||
|
_alloc.creallocate(_size = arr._size);
|
||||||
|
for (size_t i = 0; i < _size; ++i) {
|
||||||
|
fennec::construct(&_alloc[i], fennec::copy(arr[i]));
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move Assignment Operator
|
||||||
|
/// \param arr the array to move
|
||||||
|
/// \returns A dynarray after having taken ownership of the contents of `arr`
|
||||||
|
constexpr dynarray& operator=(dynarray&& arr) noexcept {
|
||||||
|
this->clear();
|
||||||
|
_alloc = fennec::move(arr._alloc);
|
||||||
|
_size = arr._size;
|
||||||
|
arr._size = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
// Properties ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Properties
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \returns The size of the dynarray in elements
|
/// \returns The size of the dynarray in elements
|
||||||
constexpr size_t size() const {
|
constexpr size_t size() const {
|
||||||
@@ -181,15 +259,20 @@ public:
|
|||||||
return _size == 0;
|
return _size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Element Access ======================================================================================================
|
// Element Access ======================================================================================================
|
||||||
|
|
||||||
|
/// \name Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Array Access Operator
|
/// \brief Array Access Operator
|
||||||
/// \param i The index to access
|
/// \param i The index to access
|
||||||
/// \returns A reference to the element at index `i`
|
/// \returns A reference to the element at index `i`
|
||||||
constexpr TypeT& operator[](int i) {
|
constexpr TypeT& operator[](size_t i) {
|
||||||
assertd(i >= 0 and size_t(i) < _size, "Array Out of Bounds");
|
assertd(i < _size, "Array Out of Bounds");
|
||||||
return _alloc.data()[i];
|
return _alloc.data()[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,8 +280,8 @@ public:
|
|||||||
/// \brief Array Access Operator (const)
|
/// \brief Array Access Operator (const)
|
||||||
/// \param i The index to access
|
/// \param i The index to access
|
||||||
/// \returns A const qualified reference to the element at index `i`
|
/// \returns A const qualified reference to the element at index `i`
|
||||||
constexpr const TypeT& operator[](int i) const {
|
constexpr const TypeT& operator[](size_t i) const {
|
||||||
assertd(i >= 0 and size_t(i) < _size, "Array Out of Bounds");
|
assertd(i < _size, "Array Out of Bounds");
|
||||||
return _alloc.data()[i];
|
return _alloc.data()[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,28 +309,13 @@ public:
|
|||||||
return this->operator[](size() - 1);
|
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
|
/// \brief Move Insertion
|
||||||
@@ -364,12 +432,51 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Clears the contents of the dynarray, destructing all elements and releasing the allocation.
|
||||||
|
constexpr void clear() {
|
||||||
|
while (_size > 0) {
|
||||||
|
fennec::destruct(&_alloc[--_size]);
|
||||||
|
}
|
||||||
|
_alloc.deallocate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
// 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:
|
private:
|
||||||
constexpr void _grow() {
|
constexpr void _grow() {
|
||||||
_alloc.creallocate(_alloc.capacity() * 2);
|
_alloc.creallocate(_alloc.capacity() * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
allocation<element_t, alloc_t> _alloc;
|
allocation<value_t, alloc_t> _alloc;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,18 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file graph.h
|
||||||
|
/// \brief A header containing the definition for a graph of vertices connected by edges
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_GRAPH_H
|
#ifndef FENNEC_CONTAINERS_GRAPH_H
|
||||||
#define FENNEC_CONTAINERS_GRAPH_H
|
#define FENNEC_CONTAINERS_GRAPH_H
|
||||||
|
|
||||||
@@ -28,144 +40,475 @@
|
|||||||
/*
|
/*
|
||||||
* With the directed tree we were able to cheat a little, the structure has more rules to it which allows
|
* With the directed tree we were able to cheat a little, the structure has more rules to it which allows
|
||||||
* tighter constraints. A graph is basically no rules whatsoever. Some variants, such as weighted graphs, assign
|
* tighter constraints. A graph is basically no rules whatsoever. Some variants, such as weighted graphs, assign
|
||||||
* properties or rules to connections which can simply be an extension to this graph.
|
* properties or rules to edges which can simply be an extension to this graph.
|
||||||
*
|
*
|
||||||
* The most effective way to do this is to have a dynarray of lists, however this results in double the
|
* The most effective way to do this is to have a dynarray of lists, however this results in double the
|
||||||
* memory being used. This can also result in two connection objects being created.
|
* memory being used. This can also result in two edge objects being created.
|
||||||
*
|
*
|
||||||
* There is no nice way to avoid the problem of mapping pins to connections
|
* There is no nice way to avoid the problem of mapping vertices to edges
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename NodeT, typename ConnectionT = nullptr_t>
|
///
|
||||||
|
/// \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$ |
|
||||||
|
///
|
||||||
|
/// Graphs contain vertices and edges. Graphs are either directed
|
||||||
|
/// or undirected. This structure allows the creation of both directed and undirected edges. As
|
||||||
|
/// far as what that means; a directed graph means that edges have direction, where there are edges
|
||||||
|
/// that are "to" and "from," rather than "between" which is used in undirected graphs.
|
||||||
|
///
|
||||||
|
/// An undirected graph is connected if there is a path between every pair of vertices in the graph.
|
||||||
|
///
|
||||||
|
/// A directed graph is weakly connected if replacing all of its directed edges with undirected edges would
|
||||||
|
/// produce a connected graph. We will call this "disjointed"
|
||||||
|
///
|
||||||
|
/// A directed graph is semi-connected if there is a directed path p for `u` → `v` *or* `v` → `u` for every
|
||||||
|
/// pair of vertices `u, v`. We will call this "unilateral"
|
||||||
|
///
|
||||||
|
/// A directed graph is strongly-connected if there is a directed path p for `u` → `v` *and* `v` → `u` for every pair
|
||||||
|
/// of vertices `u, v`. We will call this "connected"
|
||||||
|
///
|
||||||
|
/// \tparam VertexT The type associated with each vertex
|
||||||
|
/// \tparam EdgeT The type associated with each edge
|
||||||
|
template<typename VertexT, typename EdgeT = empty_t>
|
||||||
struct graph {
|
struct graph {
|
||||||
public:
|
public:
|
||||||
using weight_t = ConnectionT;
|
// Definitions =========================================================================================================
|
||||||
using node_t = NodeT;
|
|
||||||
using conn_map_t = dynarray<map<size_t, size_t>>;
|
|
||||||
using node_pool_t = object_pool<node_t>;
|
|
||||||
using conn_pool_t = object_pool<weight_t>;
|
|
||||||
|
|
||||||
static constexpr size_t npos = -1;
|
using edge_t = EdgeT; ///< Alias for the edge type
|
||||||
|
using vertex_t = VertexT; ///< Alias for the vertex type
|
||||||
|
using vertex_pool_t = object_pool<vertex_t>; ///< Alias for a pool of vertices
|
||||||
|
using edge_map_t = dynarray<map<size_t, size_t>>; ///< Alias for edge mapping
|
||||||
|
using edge_pool_t = object_pool<edge_t>; ///< Alias for a pool of edges
|
||||||
|
|
||||||
|
static constexpr size_t npos = -1; ///< Constant for a non-existent vertex
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors ========================================================================================================
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Default Constructor, initializes empty graph
|
||||||
constexpr graph() = default;
|
constexpr graph() = default;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Destructor
|
||||||
constexpr ~graph() = default;
|
constexpr ~graph() = default;
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
/// \name Assignment Operators
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Copy Assignment Operator
|
||||||
|
/// \param g The graph to copy
|
||||||
|
/// \returns A reference to this after assigning g
|
||||||
constexpr graph& operator=(const graph& g) = default;
|
constexpr graph& operator=(const graph& g) = default;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move Assignment Operator
|
||||||
|
/// \param g The graph to copy
|
||||||
|
/// \returns A reference to this after assigning g
|
||||||
constexpr graph& operator=(graph&& g) = default;
|
constexpr graph& operator=(graph&& g) = default;
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Properties ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
constexpr size_t num_nodes() const {
|
/// \name Properties
|
||||||
return _node_pool.size();
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The number of vertices in the graph
|
||||||
|
constexpr size_t num_vertices() const {
|
||||||
|
return _vertex_pool.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr size_t num_connections() const {
|
///
|
||||||
return _conn_pool.size();
|
/// \returns The number of edges in the graph
|
||||||
|
constexpr size_t num_edges() const {
|
||||||
|
return _edge_pool.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The capacity of the vertex pool
|
||||||
constexpr size_t capacity() const {
|
constexpr size_t capacity() const {
|
||||||
return _node_pool.capacity();
|
return _vertex_pool.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns `true` when there are no vertices in the graph, `false` otherwise
|
||||||
constexpr bool empty() const {
|
constexpr bool empty() const {
|
||||||
return num_nodes() == 0;
|
return num_vertices() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
// Nodes ===============================================================================================================
|
/// \brief Checks if there exists an edge `e` that starts from `a` and ends at `b`
|
||||||
|
/// \param a The first vertex
|
||||||
constexpr size_t insert(node_t&& node) {
|
/// \param b The second vertex
|
||||||
return this->_insert(fennec::forward<node_t>(node));
|
/// \returns `true` if the edge exists, `false` otherwise
|
||||||
|
constexpr bool exists(size_t a, size_t b) const {
|
||||||
|
return _edge_map[a][b] != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr size_t insert(const node_t& node) {
|
///
|
||||||
return this->_insert(node);
|
/// \brief Checks if there exists an edge `e0` that starts from `a` and ends at `b` and `e1` that starts from `b`
|
||||||
|
/// and ends at `a`
|
||||||
|
/// \param a The first vertex
|
||||||
|
/// \param b The second vertex
|
||||||
|
/// \returns `true` if both edges exist, `false` otherwise
|
||||||
|
constexpr bool is_symmetric(size_t a, size_t b) const {
|
||||||
|
return exists(a, b) and exists(b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Checks if there exists an edge `e` between `a` and `b`
|
||||||
|
/// \param a The first vertex
|
||||||
|
/// \param b The second vertex
|
||||||
|
/// \returns `true` if both edges exist, `false` otherwise
|
||||||
|
constexpr bool is_undirected(size_t a, size_t b) const {
|
||||||
|
const auto* e0 = _edge_map[a][b];
|
||||||
|
const auto* e1 = _edge_map[b][a];
|
||||||
|
if (not (e0 != nullptr && e1 != nullptr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return *e0 == *e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: connected, disjoint, unilateral, get_component
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
|
/// \name Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief vertex Access Operator
|
||||||
|
/// \param vertex The id of the vertex
|
||||||
|
/// \returns A reference to the value stored in the vertex
|
||||||
|
constexpr vertex_t& operator[](size_t vertex) {
|
||||||
|
return _vertex_pool[vertex];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief vertex Const Access Operator
|
||||||
|
/// \param vertex The id of the vertex
|
||||||
|
/// \returns A reference to the value stored in the vertex
|
||||||
|
constexpr const vertex_t& operator[](size_t vertex) const {
|
||||||
|
return _vertex_pool[vertex];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief edge Access Operator
|
||||||
|
/// \param a The id of the first vertex
|
||||||
|
/// \param b The id of the second vertex
|
||||||
|
/// \returns A pointer to the value stored in the edge, `nullptr` if not found
|
||||||
|
constexpr edge_t* operator[](size_t a, size_t b) {
|
||||||
|
if (empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
edge_t* it = _edge_map[a][b];
|
||||||
|
if (it) {
|
||||||
|
return _edge_pool[*it];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief edge Const Access Operator
|
||||||
|
/// \param a The id of the first vertex
|
||||||
|
/// \param b The id of the second vertex
|
||||||
|
/// \returns A const-qualified pointer to the value stored in the edge, `nullptr` if not found
|
||||||
|
constexpr const edge_t* operator[](size_t a, size_t b) const {
|
||||||
|
if (empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const edge_t* it = _edge_map[a][b];
|
||||||
|
if (it) {
|
||||||
|
return _edge_pool[*it];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Getter for a list of vertices `x` that `vertex` has an edge to `x...`
|
||||||
|
/// \param vertex The id of the vertex
|
||||||
|
/// \returns A list containing all vertices `x` with edges from `vertex` to `x...`
|
||||||
|
list<size_t> outgoing(size_t vertex) {
|
||||||
|
list<size_t> res;
|
||||||
|
if (empty() || vertex >= _edge_map.size()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
for (const auto& it : _edge_map[vertex]) {
|
||||||
|
res.push_back(it.first);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Getter for a list of vertices `x` that `vertex` has an edge from `x...`
|
||||||
|
/// \param vertex The id of the vertex
|
||||||
|
/// \returns A list containing all vertices `x` with edges from `x...` to `vertex`
|
||||||
|
list<size_t> incoming(size_t vertex) {
|
||||||
|
list<size_t> res;
|
||||||
|
if (empty() || vertex >= _edge_map.size()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
for (size_t n = 0; n < _edge_map.size(); ++n) {
|
||||||
|
if (_edge_map[n][vertex]) {
|
||||||
|
res.push_back(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Getter for a list of vertices `x` that `vertex` has an edge to and from `x...`
|
||||||
|
/// \param vertex The id of the vertex
|
||||||
|
/// \returns A list containing all vertices `x` that have symmetric edges with `vertex`
|
||||||
|
list<size_t> symmetric(size_t vertex) {
|
||||||
|
list<size_t> res;
|
||||||
|
if (empty() || vertex >= _edge_map.size()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
for (const auto& it : _edge_map[vertex]) {
|
||||||
|
if (_edge_map[it.first][vertex]) {
|
||||||
|
res.push_back(it.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Getter for a list of vertices `x` that `vertex` has an edge to and from `x...` and share the same value
|
||||||
|
/// \details
|
||||||
|
/// "Joined" edges may also be referred to as "undirected." A joined, or undirected, edge may be
|
||||||
|
/// turned into a directed edge by changing the weight object associated with the edge, or by
|
||||||
|
/// removing one of the sub-edges.
|
||||||
|
/// \param vertex The id of the vertex
|
||||||
|
/// \returns A list containing all vertices `x` that have symmetric edges with `vertex`
|
||||||
|
list<size_t> undirected(size_t vertex) {
|
||||||
|
list<size_t> res;
|
||||||
|
if (empty() || vertex >= _edge_map.size()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
for (const auto& it : _edge_map[vertex]) {
|
||||||
|
const auto* at = _edge_map[it.first][vertex];
|
||||||
|
if (at != nullptr && *at == it.second) {
|
||||||
|
res.push_back(it.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Getter for the internal storage of mapped edges from this vertex.
|
||||||
|
/// Use this when you want to iterate over edges that start from this vertex.
|
||||||
|
/// \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()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return &_edge_map[vertex];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
// Modifiers ===========================================================================================================
|
||||||
|
|
||||||
|
/// \name Modifiers
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move a new vertex into the graph
|
||||||
|
/// \param vertex The vertex to move into the graph
|
||||||
|
/// \returns The id of the new vertex
|
||||||
|
constexpr size_t insert(vertex_t&& vertex) {
|
||||||
|
return this->_insert(fennec::forward<vertex_t>(vertex));
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Copy a new vertex into the graph
|
||||||
|
/// \param vertex The vertex to copy into the graph
|
||||||
|
/// \returns The id of the new vertex
|
||||||
|
constexpr size_t insert(const vertex_t& vertex) {
|
||||||
|
return this->_insert(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Construct a new vertex in the graph
|
||||||
|
/// \tparam ArgsT The types of the arguments
|
||||||
|
/// \param args The arguments to construct the vertex with
|
||||||
|
/// \returns The id of the new vertex
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr size_t emplace(ArgsT&&...args) {
|
constexpr size_t emplace(ArgsT&&...args) {
|
||||||
return this->_insert(fennec::forward<ArgsT>(args)...);
|
return this->_insert(fennec::forward<ArgsT>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void erase(size_t node) {
|
///
|
||||||
disconnect(node);
|
/// \brief Erase a vertex from the graph
|
||||||
_node_pool.erase(node);
|
/// \param vertex The id of the vertex to erase
|
||||||
}
|
constexpr void erase(size_t vertex) {
|
||||||
|
cut(vertex);
|
||||||
constexpr node_t& operator[](size_t node) {
|
_vertex_pool.erase(vertex);
|
||||||
return _node_pool[node];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr const node_t& operator[](size_t node) const {
|
|
||||||
return _node_pool[node];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connections =========================================================================================================
|
|
||||||
|
|
||||||
list<size_t> connections(size_t n) {
|
|
||||||
list<size_t> conns;
|
|
||||||
if (_conn_map.empty()) return conns;
|
|
||||||
|
|
||||||
for (auto it : _conn_map[n]) {
|
|
||||||
conns.push_back(it.first);
|
|
||||||
}
|
|
||||||
return conns;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Form an edge from vertex `a` to vertex `b`
|
||||||
|
/// \tparam ArgsT The argument types
|
||||||
|
/// \param a The first vertex id
|
||||||
|
/// \param b The second vertex id
|
||||||
|
/// \param args The arguments to construct the edge with
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr void connect(size_t a, size_t b, ArgsT&&...args) {
|
constexpr void make_edge(size_t a, size_t b, ArgsT&&...args) {
|
||||||
if (_conn_map.size() < _node_pool.capacity()) {
|
if (a == b) {
|
||||||
_conn_map.resize(_node_pool.capacity());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = _conn_map[a][b];
|
if (_edge_map.size() < _vertex_pool.capacity()) {
|
||||||
|
_edge_map.resize(_vertex_pool.capacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = _edge_map[a][b];
|
||||||
size_t conn;
|
size_t conn;
|
||||||
if (it != nullptr) {
|
if (it != nullptr) {
|
||||||
conn = *it;
|
conn = *it;
|
||||||
_conn_pool[conn] = node_t(fennec::forward<ArgsT>(args)...);
|
_edge_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...);
|
||||||
} else {
|
} else {
|
||||||
conn = _conn_pool.emplace(fennec::forward<ArgsT>(args)...);
|
conn = _edge_pool.emplace(fennec::forward<ArgsT>(args)...);
|
||||||
|
}
|
||||||
|
_edge_map[a].emplace(b, conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Form an undirected edge between vertex `a` and vertex `b`
|
||||||
|
/// \tparam ArgsT The argument types
|
||||||
|
/// \param a The first vertex id
|
||||||
|
/// \param b The second vertex id
|
||||||
|
/// \param args The arguments to construct the edge with
|
||||||
|
template<typename...ArgsT>
|
||||||
|
constexpr void make_edge2(size_t a, size_t b, ArgsT&&...args) {
|
||||||
|
if (a == b) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_conn_map[a].emplace(b, conn);
|
if (_edge_map.size() < _vertex_pool.capacity()) {
|
||||||
_conn_map[b].emplace(a, conn);
|
_edge_map.resize(_vertex_pool.capacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = _edge_map[a][b];
|
||||||
|
size_t conn;
|
||||||
|
if (it != nullptr) {
|
||||||
|
conn = *it;
|
||||||
|
_edge_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...);
|
||||||
|
} else {
|
||||||
|
conn = _edge_pool.emplace(fennec::forward<ArgsT>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
_edge_map[a].emplace(b, conn);
|
||||||
|
_edge_map[b].emplace(a, conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void disconnect(size_t a, size_t b) {
|
///
|
||||||
size_t c = *_conn_map[a][b];
|
/// \brief Disconnect an edge from vertex `a` to vertex `b`
|
||||||
_conn_pool.erase(c);
|
/// \param a The first vertex id
|
||||||
_conn_map[a].erase(b);
|
/// \param b The second vertex id
|
||||||
_conn_map[b].erase(a);
|
constexpr void cut_edge(size_t a, size_t b) {
|
||||||
|
|
||||||
|
// Find the edge object
|
||||||
|
const auto* it = _edge_map[a][b];
|
||||||
|
if (not it) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t c = *it;
|
||||||
|
|
||||||
|
// Check if undirected
|
||||||
|
const auto* at = _edge_map[b][a];
|
||||||
|
if (not at || *at != c) {
|
||||||
|
_edge_pool.erase(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase the edge mapping
|
||||||
|
_edge_map[a].erase(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disconnect(size_t n) {
|
///
|
||||||
list<size_t> conns = connections(n);
|
/// \brief Disconnect both directed edges between vertices `a` and `b`
|
||||||
for (size_t conn : conns) {
|
/// \param a The first vertex id
|
||||||
disconnect(n, conn);
|
/// \param b The second vertex id
|
||||||
|
constexpr void cut_edge2(size_t a, size_t b) {
|
||||||
|
const auto* ita = _edge_map[a][b];
|
||||||
|
const auto* itb = _edge_map[a][b];
|
||||||
|
if (not (ita || itb)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ita) _edge_pool.erase(*ita);
|
||||||
|
if (itb) _edge_pool.erase(*itb);
|
||||||
|
_edge_map[a].erase(b);
|
||||||
|
_edge_map[b].erase(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Break *all* edges to and from `n`
|
||||||
|
/// \param n The vertex id
|
||||||
|
void cut(size_t n) {
|
||||||
|
for (const auto it : outgoing(n)) {
|
||||||
|
cut_edge(n, it);
|
||||||
|
}
|
||||||
|
for (const auto it : incoming(n)) {
|
||||||
|
cut_edge(it, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr weight_t& operator[](size_t a, size_t b) {
|
///
|
||||||
return _conn_pool[_conn_map[a][b]];
|
/// \brief Clear the graph, destructing all vertices and edges.
|
||||||
|
void clear() {
|
||||||
|
_vertex_pool.clear();
|
||||||
|
_edge_pool.clear();
|
||||||
|
_edge_map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const weight_t& operator[](size_t a, size_t b) const {
|
/// @}
|
||||||
return _conn_pool[_conn_map[a][b]];
|
|
||||||
}
|
|
||||||
|
// edges =========================================================================================================
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
node_pool_t _node_pool;
|
vertex_pool_t _vertex_pool;
|
||||||
conn_pool_t _conn_pool;
|
edge_pool_t _edge_pool;
|
||||||
conn_map_t _conn_map;
|
edge_map_t _edge_map;
|
||||||
|
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
size_t _insert(ArgsT&&...args) {
|
size_t _insert(ArgsT&&...args) {
|
||||||
return _node_pool.emplace(fennec::forward<ArgsT>(args)...);
|
return _vertex_pool.emplace(fennec::forward<ArgsT>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \file list.h
|
/// \file list.h
|
||||||
/// \brief List of elements
|
/// \brief A header containing the definition for a linked list of values
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \details
|
/// \details
|
||||||
@@ -43,18 +43,24 @@ namespace fennec
|
|||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \brief wrapper for lists of elements
|
/// \brief Data Structure defining lists of elements
|
||||||
/// \details
|
/// \details
|
||||||
/// This data-structure behaves like a linked list, but does not use pointers. Instead, it is in-array. This creates the
|
/// This data-structure behaves like a linked list, but does not use pointers. Instead, it is in-array. This creates the
|
||||||
/// following properties:
|
/// following properties:
|
||||||
///
|
///
|
||||||
/// | Property | Value |
|
/// | Property | Value |
|
||||||
/// |:----------|:-------------------------------------:|
|
/// |:----------:|:----------:|
|
||||||
/// | stable | \emoji x |
|
/// | stable | ⛔ |
|
||||||
/// | access | \f$O(N)\f$ or \f$O(1)\f$ (front/back) |
|
/// | dynamic | ✅ |
|
||||||
/// | insertion | \f$O(N)\f$ or \f$O(1)\f$ (iterator) |
|
/// | homogenous | ✅ |
|
||||||
/// | deletion | \f$O(N)\f$ or \f$O(1)\f$ (iterator) |
|
/// | distinct | ⛔ |
|
||||||
/// | space | \f$O(N)\f$ |
|
/// | 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
|
/// \tparam TypeT value type
|
||||||
template<class TypeT, class Alloc = allocator<TypeT>>
|
template<class TypeT, class Alloc = allocator<TypeT>>
|
||||||
@@ -66,16 +72,21 @@ private:
|
|||||||
struct node;
|
struct node;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using alloc_t = typename allocator_traits<Alloc>::template rebind<TypeT>;
|
/// \brief Alias for the allocator type, rebound to list nodes
|
||||||
using value_t = TypeT;
|
using alloc_t = typename allocator_traits<Alloc>::template rebind<node>;
|
||||||
using elem_t = node;
|
|
||||||
static constexpr size_t npos = -1;
|
|
||||||
|
|
||||||
class iterator;
|
using value_t = TypeT; ///< Alias for the value type
|
||||||
class const_iterator;
|
|
||||||
|
static constexpr size_t npos = -1; ///< Constant representing a non-existant position
|
||||||
|
|
||||||
|
class iterator; ///< Iterator type for forward iteration over the list
|
||||||
|
class const_iterator; ///< Iterator type for forward iteration over a constant list
|
||||||
|
|
||||||
|
|
||||||
// Constructors ========================================================================================================
|
// Constructors & Destructor ===========================================================================================
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Constructor, initializes an empty list.
|
/// \brief Default Constructor, initializes an empty list.
|
||||||
@@ -83,6 +94,28 @@ public:
|
|||||||
: _table(), _freed(), _root(npos), _last(npos), _size(0) {
|
: _table(), _freed(), _root(npos), _last(npos), _size(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Copy Constructor, copies all elements in `l` with optimized layout
|
||||||
|
/// \param l The list to copy
|
||||||
|
constexpr list(const list& l)
|
||||||
|
: list() {
|
||||||
|
for (const value_t& it : l) {
|
||||||
|
this->push_back(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move Constructor, takes ownership of the list
|
||||||
|
/// \param l The list to move
|
||||||
|
constexpr list(list&& l) noexcept
|
||||||
|
: _table(fennec::move(l._table))
|
||||||
|
, _freed(fennec::move(l._freed))
|
||||||
|
, _root(l._root)
|
||||||
|
, _last(l._last)
|
||||||
|
, _size(l._size) {
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Destructor, destructs all elements then releases the allocation.
|
/// \brief Destructor, destructs all elements then releases the allocation.
|
||||||
constexpr ~list() {
|
constexpr ~list() {
|
||||||
@@ -91,9 +124,44 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
// Assignment ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Assignment
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Copy Assignment Operator
|
||||||
|
/// \param l the list to copy
|
||||||
|
/// \returns `this` after having copied all elements of `l`
|
||||||
|
constexpr list& operator=(const list& l) {
|
||||||
|
this->clear();
|
||||||
|
for (const value_t& it : l) {
|
||||||
|
this->push_back(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move Assignment Operator
|
||||||
|
/// \param l the list to copy
|
||||||
|
/// \returns `this` after having taken ownership over the contents of `l`
|
||||||
|
constexpr list& operator=(list&& l) noexcept {
|
||||||
|
this->clear();
|
||||||
|
_table = fennec::move(l._table);
|
||||||
|
_freed = fennec::move(l._freed);
|
||||||
|
_root = l._root; _last = l._last;
|
||||||
|
_size = l._size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Properties ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Properties
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \returns The size of the list in elements.
|
/// \returns The size of the list in elements.
|
||||||
constexpr size_t size() const { return _size; }
|
constexpr size_t size() const { return _size; }
|
||||||
@@ -106,9 +174,14 @@ public:
|
|||||||
/// \returns `true` when the list is empty, `false` otherwise.
|
/// \returns `true` when the list is empty, `false` otherwise.
|
||||||
constexpr bool empty() const { return _root == npos; }
|
constexpr bool empty() const { return _root == npos; }
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Access ==============================================================================================================
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
|
/// \name Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Array Access Operator
|
/// \brief Array Access Operator
|
||||||
/// \param i Index to access
|
/// \param i Index to access
|
||||||
@@ -163,8 +236,13 @@ public:
|
|||||||
return *_table[_last].value;
|
return *_table[_last].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
// Insertions & Deletions ==============================================================================================
|
|
||||||
|
// Modifiers ===========================================================================================================
|
||||||
|
|
||||||
|
/// \name Modifiers
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Copy Insertion
|
/// \brief Copy Insertion
|
||||||
@@ -301,8 +379,54 @@ public:
|
|||||||
_erase(_last);
|
_erase(_last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Clears the list, destructing all elements in order
|
||||||
|
constexpr void clear() {
|
||||||
|
size_t i = _root;
|
||||||
|
while (i != npos) {
|
||||||
|
fennec::destruct(_table[i]);
|
||||||
|
i = this->_next(i);
|
||||||
|
}
|
||||||
|
_table.deallocate(_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
// ITERATOR ============================================================================================================
|
// ITERATOR ============================================================================================================
|
||||||
|
|
||||||
|
/// \name Iteration
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C++ Iterator Specification `begin()`
|
||||||
|
/// \returns An iterator for the first element in the list
|
||||||
|
constexpr iterator begin() {
|
||||||
|
return iterator(this, _root);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C++ Iterator Specification `end()`
|
||||||
|
/// \returns An iterator for the end of the list
|
||||||
|
constexpr iterator end() {
|
||||||
|
return iterator(this, npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Const C++ Iterator Specification `begin()`
|
||||||
|
/// \returns A const iterator for the first element in the list
|
||||||
|
constexpr const_iterator begin() const {
|
||||||
|
return const_iterator(this, _root);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Const C++ Iterator Specification `end()`
|
||||||
|
/// \returns A const iterator for the end of the list
|
||||||
|
constexpr const_iterator end() const {
|
||||||
|
return const_iterator(this, npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Iterator Class
|
/// \brief Iterator Class
|
||||||
class iterator {
|
class iterator {
|
||||||
@@ -403,32 +527,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
///
|
|
||||||
/// \returns An iterator for the first element in the list
|
|
||||||
constexpr iterator begin() {
|
|
||||||
return iterator(this, _root);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \returns An iterator for the end of the list
|
|
||||||
constexpr iterator end() {
|
|
||||||
return iterator(this, npos);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \returns A const iterator for the first element in the list
|
|
||||||
constexpr const_iterator begin() const {
|
|
||||||
return const_iterator(this, _root);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \returns A const iterator for the end of the list
|
|
||||||
constexpr const_iterator end() const {
|
|
||||||
return const_iterator(this, npos);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
allocation<elem_t, alloc_t> _table;
|
allocation<node, alloc_t> _table;
|
||||||
dynarray<size_t> _freed;
|
dynarray<size_t> _freed;
|
||||||
size_t _root, _last, _size;
|
size_t _root, _last, _size;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,18 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file map.h
|
||||||
|
/// \brief A header containing the definition for a mapping of keys to values
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_MAP_H
|
#ifndef FENNEC_CONTAINERS_MAP_H
|
||||||
#define FENNEC_CONTAINERS_MAP_H
|
#define FENNEC_CONTAINERS_MAP_H
|
||||||
|
|
||||||
@@ -44,7 +56,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 KeyT The Key Type
|
||||||
/// \tparam ValueT The Value Type
|
/// \tparam ValueT The Value Type
|
||||||
/// \tparam Hash The Hash to Use
|
/// \tparam Hash The Hash to Use
|
||||||
@@ -54,15 +81,15 @@ struct map {
|
|||||||
|
|
||||||
// Definitions =========================================================================================================
|
// Definitions =========================================================================================================
|
||||||
public:
|
public:
|
||||||
struct key_hash;
|
struct key_hash; ///< Hash for node keys
|
||||||
struct node_equals;
|
struct key_equals; ///< Comparison for node keys
|
||||||
using key_t = KeyT;
|
using key_t = KeyT; ///< The key type
|
||||||
using value_t = ValueT;
|
using value_t = ValueT; ///< The value type
|
||||||
using elem_t = pair<KeyT, ValueT>;
|
using elem_t = pair<KeyT, ValueT>; ///< then node type
|
||||||
using alloc_t = typename allocator_traits<Alloc>::template rebind<elem_t>;
|
using alloc_t = typename allocator_traits<Alloc>::template rebind<elem_t>; ///< Rebinds the allocator type to nodes
|
||||||
using hash_t = Hash;
|
using hash_t = Hash; ///< The hash type
|
||||||
using set_t = set<elem_t, key_hash, node_equals, alloc_t>;
|
using set_t = set<elem_t, key_hash, key_equals, alloc_t>; ///< The underlying set
|
||||||
using iterator = set_t::iterator;
|
using iterator = set_t::iterator; ///< Iterator type
|
||||||
|
|
||||||
// We only want to hash the key
|
// We only want to hash the key
|
||||||
struct key_hash : hash_t {
|
struct key_hash : hash_t {
|
||||||
@@ -72,14 +99,17 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// We only want to compare the keys
|
// We only want to compare the keys
|
||||||
struct node_equals : equality<KeyT> {
|
struct key_equals : equality<KeyT> {
|
||||||
constexpr bool operator()(const elem_t& a, const elem_t& b) const {
|
constexpr bool operator()(const elem_t& a, const elem_t& b) const {
|
||||||
return equality<KeyT>::operator()(a.first, b.first);
|
return equality<KeyT>::operator()(a.first, b.first);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Constructors ========================================================================================================
|
// Constructors & Destructor ===========================================================================================
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Constructor, initializes empty map
|
/// \brief Default Constructor, initializes empty map
|
||||||
@@ -89,9 +119,40 @@ public:
|
|||||||
/// \brief Destructor, Destructs all elements and releases the allocation
|
/// \brief Destructor, Destructs all elements and releases the allocation
|
||||||
constexpr ~map() = default;
|
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 ==============================================================================================================
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
|
/// \name Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Key Access Operator
|
/// \brief Key Access Operator
|
||||||
/// \param key Key value to access
|
/// \param key Key value to access
|
||||||
@@ -132,8 +193,13 @@ public:
|
|||||||
return it ? &it->second : nullptr;
|
return it ? &it->second : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
// Insertion & Deletion ================================================================================================
|
|
||||||
|
// Modifiers ===========================================================================================================
|
||||||
|
|
||||||
|
/// \name Modifiers
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Key-Value Insertion
|
/// \brief Key-Value Insertion
|
||||||
@@ -181,23 +247,43 @@ public:
|
|||||||
_set.erase(this->_find(fennec::forward<ArgsT>(args)...));
|
_set.erase(this->_find(fennec::forward<ArgsT>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Clears the map destructing all elements
|
||||||
|
void clear() {
|
||||||
|
_set.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Iteration ===========================================================================================================
|
// Iteration ===========================================================================================================
|
||||||
|
|
||||||
|
/// \name Iteration
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C++ Iterator Specification `begin()`
|
||||||
|
/// \returns an iterator at the start of the map
|
||||||
constexpr iterator begin() {
|
constexpr iterator begin() {
|
||||||
return _set.begin();
|
return _set.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C++ Iterator Specification `end()`
|
||||||
|
/// \returns an iterator at the end of the map
|
||||||
constexpr iterator end() {
|
constexpr iterator end() {
|
||||||
return _set.end();
|
return _set.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
set_t _set;
|
set_t _set;
|
||||||
|
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
set_t::iterator _find(ArgsT&&...args) {
|
set_t::iterator _find(ArgsT&&...args) const {
|
||||||
union U { // Hacky way of avoiding constructing the value, TODO: Check for warnings on other compilers
|
union U { // Hacky way of avoiding constructing the value, TODO: Check for warnings on other compilers
|
||||||
pair<KeyT, char[sizeof(ValueT)]> root;
|
pair<KeyT, char[sizeof(ValueT)]> root;
|
||||||
pair<KeyT, ValueT> val;
|
pair<KeyT, ValueT> val;
|
||||||
|
|||||||
@@ -16,13 +16,25 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_SET_H
|
///
|
||||||
#define FENNEC_CONTAINERS_SET_H
|
/// \file multiset.h
|
||||||
|
/// \brief A header containing the definition for a set of repeating values
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
#ifndef FENNEC_CONTAINERS_MULTISET_H
|
||||||
|
#define FENNEC_CONTAINERS_MULTISET_H
|
||||||
|
|
||||||
// https://programming.guide/robin-hood-hashing.html
|
// https://programming.guide/robin-hood-hashing.html
|
||||||
|
|
||||||
#include <fennec/containers/optional.h>
|
#include <fennec/containers/optional.h>
|
||||||
#include <fennec/containers/set.h>
|
#include <fennec/containers/multiset.h>
|
||||||
#include <fennec/lang/compare.h>
|
#include <fennec/lang/compare.h>
|
||||||
#include <fennec/math/ext/primes.h>
|
#include <fennec/math/ext/primes.h>
|
||||||
#include <fennec/memory/allocator.h>
|
#include <fennec/memory/allocator.h>
|
||||||
@@ -33,21 +45,25 @@ namespace fennec
|
|||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \brief wrapper for sets of elements
|
/// \brief A Data Structure that defines a set of elements that may repeat
|
||||||
/// \details
|
/// \details
|
||||||
/// This data-structure behaves like a set, but does not use pointers, instead storing the table in-array
|
/// | Property | Value |
|
||||||
///
|
/// |:----------:|:----------:|
|
||||||
/// | Property | Value |
|
/// | stable | ⛔ |
|
||||||
/// |:----------|:----------:|
|
/// | dynamic | ✅ |
|
||||||
/// | stable | \emoji x |
|
/// | homogenous | ✅ |
|
||||||
/// | access | \f$O(1)\f$ |
|
/// | distinct | ⛔ |
|
||||||
/// | insertion | \f$O(1)\f$ |
|
/// | ordered | ⛔ |
|
||||||
/// | deletion | \f$O(1)\f$ |
|
/// | space | \f$O(N)\f$ |
|
||||||
/// | space | \f$O(1)\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
|
/// \tparam TypeT The type to contain
|
||||||
template<typename TypeT, class Hash = hash<TypeT>, class Equals = equality<TypeT>, class Alloc = allocator<TypeT>>
|
template<typename TypeT, class Hash = hash<TypeT>, class Equals = equality<TypeT>, class Alloc = allocator<TypeT>>
|
||||||
struct set {
|
struct multiset {
|
||||||
|
|
||||||
// Definitions =========================================================================================================
|
// Definitions =========================================================================================================
|
||||||
public:
|
public:
|
||||||
@@ -73,9 +89,12 @@ private:
|
|||||||
// Constructors ========================================================================================================
|
// Constructors ========================================================================================================
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Constructor, initializes empty set
|
/// \brief Default Constructor, initializes empty multiset
|
||||||
constexpr set()
|
constexpr multiset()
|
||||||
: _alloc()
|
: _alloc()
|
||||||
, _hash()
|
, _hash()
|
||||||
, _size(0)
|
, _size(0)
|
||||||
@@ -84,8 +103,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Hash Copy Constructor, initializes empty set with a hash
|
/// \brief Hash Copy Constructor, initializes empty multiset with a hash
|
||||||
constexpr set(const hash_t& hash)
|
constexpr multiset(const hash_t& hash)
|
||||||
: _alloc()
|
: _alloc()
|
||||||
, _hash(hash)
|
, _hash(hash)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
@@ -94,8 +113,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Hash Move Constructor, initializes empty set with a hash
|
/// \brief Hash Move Constructor, initializes empty multiset with a hash
|
||||||
constexpr set(hash_t&& hash) noexcept
|
constexpr multiset(hash_t&& hash) noexcept
|
||||||
: _alloc()
|
: _alloc()
|
||||||
, _hash(hash)
|
, _hash(hash)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
@@ -104,8 +123,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Alloc Copy Constructor, initializes empty set with an allocator
|
/// \brief Alloc Copy Constructor, initializes empty multiset with an allocator
|
||||||
constexpr set(const alloc_t& alloc)
|
constexpr multiset(const alloc_t& alloc)
|
||||||
: _alloc(alloc)
|
: _alloc(alloc)
|
||||||
, _hash()
|
, _hash()
|
||||||
, _size(0)
|
, _size(0)
|
||||||
@@ -114,8 +133,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Alloc Move Constructor, initializes empty set with an allocator
|
/// \brief Alloc Move Constructor, initializes empty multiset with an allocator
|
||||||
constexpr set(alloc_t&& alloc) noexcept
|
constexpr multiset(alloc_t&& alloc) noexcept
|
||||||
: _alloc(alloc)
|
: _alloc(alloc)
|
||||||
, _hash()
|
, _hash()
|
||||||
, _size(0)
|
, _size(0)
|
||||||
@@ -124,8 +143,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Hash Alloc Copy Constructor, initializes empty set with a hash and allocator
|
/// \brief Hash Alloc Copy Constructor, initializes empty multiset with a hash and allocator
|
||||||
constexpr set(const hash_t& hash, const alloc_t& alloc)
|
constexpr multiset(const hash_t& hash, const alloc_t& alloc)
|
||||||
: _alloc(alloc)
|
: _alloc(alloc)
|
||||||
, _hash(hash)
|
, _hash(hash)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
@@ -134,8 +153,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Hash Copy Alloc Move Constructor, initializes empty set with a hash and allocator
|
/// \brief Hash Copy Alloc Move Constructor, initializes empty multiset with a hash and allocator
|
||||||
constexpr set(const hash_t& hash, alloc_t&& alloc) noexcept
|
constexpr multiset(const hash_t& hash, alloc_t&& alloc) noexcept
|
||||||
: _alloc(alloc)
|
: _alloc(alloc)
|
||||||
, _hash(hash)
|
, _hash(hash)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
@@ -144,8 +163,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Hash Move Alloc Move Constructor, initializes empty set with a hash and allocator
|
/// \brief Hash Move Alloc Move Constructor, initializes empty multiset with a hash and allocator
|
||||||
constexpr set(hash_t&& hash, alloc_t&& alloc) noexcept
|
constexpr multiset(hash_t&& hash, alloc_t&& alloc) noexcept
|
||||||
: _alloc(alloc)
|
: _alloc(alloc)
|
||||||
, _hash(hash)
|
, _hash(hash)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
@@ -154,8 +173,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Hash Move Alloc Copy Constructor, initializes empty set with a hash and allocator
|
/// \brief Hash Move Alloc Copy Constructor, initializes empty multiset with a hash and allocator
|
||||||
constexpr set(hash_t&& hash, const alloc_t& alloc) noexcept
|
constexpr multiset(hash_t&& hash, const alloc_t& alloc) noexcept
|
||||||
: _alloc(alloc)
|
: _alloc(alloc)
|
||||||
, _hash(hash)
|
, _hash(hash)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
@@ -165,52 +184,68 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Set Copy Constructor
|
/// \brief Set Copy Constructor
|
||||||
/// \param set Set to copy
|
/// \param multiset Set to copy
|
||||||
constexpr set(const set& set)
|
constexpr multiset(const multiset& multiset)
|
||||||
: _alloc(set._alloc)
|
: _alloc( multiset._alloc)
|
||||||
, _hash(set._hash)
|
, _hash( multiset._hash)
|
||||||
, _size(set._size)
|
, _size( multiset._size)
|
||||||
, _sumpsl(set._sumpsl)
|
, _sumpsl( multiset._sumpsl)
|
||||||
, _load(set._load) {
|
, _load( multiset._load) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Set Move Constructor
|
/// \brief Set Move Constructor
|
||||||
/// \param set Set to move
|
/// \param multiset Set to move
|
||||||
constexpr set(set&& set) noexcept
|
constexpr multiset(multiset&& multiset) noexcept
|
||||||
: _alloc(fennec::move(set._alloc))
|
: _alloc(fennec::move( multiset._alloc))
|
||||||
, _hash(fennec::move(set._hash))
|
, _hash(fennec::move( multiset._hash))
|
||||||
, _size(fennec::move(set._size))
|
, _size(fennec::move( multiset._size))
|
||||||
, _sumpsl(set._sumpsl)
|
, _sumpsl( multiset._sumpsl)
|
||||||
, _load(set._load) {
|
, _load( multiset._load) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Destructor, destructs all elements and releases the allocation
|
/// \brief Destructor, destructs all elements and releases the allocation
|
||||||
constexpr ~set() {
|
constexpr ~multiset() {
|
||||||
for (size_t i = 0; i < capacity(); ++i) {
|
for (size_t i = 0; i < capacity(); ++i) {
|
||||||
_alloc[i].value = nullopt;
|
_alloc[i].value = nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Properties ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Properties
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \returns Size of the set in elements
|
/// \returns Size of the multiset in elements
|
||||||
constexpr size_t size() const {
|
constexpr size_t size() const {
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \returns Capacity of the set in elements
|
/// \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 {
|
constexpr size_t capacity() const {
|
||||||
return _alloc.capacity();
|
return _alloc.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Access ==============================================================================================================
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
|
/// \name Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Find an Element
|
/// \brief Find an Element
|
||||||
/// \param val Value to find
|
/// \param val Value to find
|
||||||
@@ -264,7 +299,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Check if a set contains a value
|
/// \brief Check if a multiset contains a value
|
||||||
/// \param val Value to check
|
/// \param val Value to check
|
||||||
/// \returns `true` if `val` can be found, `false` otherwise
|
/// \returns `true` if `val` can be found, `false` otherwise
|
||||||
constexpr bool contains(const elem_t& val) const {
|
constexpr bool contains(const elem_t& val) const {
|
||||||
@@ -295,7 +330,12 @@ public:
|
|||||||
return &*_alloc[it._i].value;
|
return &*_alloc[it._i].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insertion & Deletion ================================================================================================
|
/// @}
|
||||||
|
|
||||||
|
// Modifiers ===========================================================================================================
|
||||||
|
|
||||||
|
/// \name Modifiers
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Move Insertion
|
/// \brief Move Insertion
|
||||||
@@ -352,9 +392,34 @@ public:
|
|||||||
this->erase(this->find(val));
|
this->erase(this->find(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// ITERATOR ============================================================================================================
|
// ITERATOR ============================================================================================================
|
||||||
|
|
||||||
|
/// \name Iteration
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C++ Iterator Specification `begin()`
|
||||||
|
/// \returns An iterator for all elements of the set in no particular order
|
||||||
|
constexpr iterator begin() const {
|
||||||
|
iterator it(this, 0);
|
||||||
|
if (not _alloc[it._i].value) {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C++ Iterator Specification `end()`
|
||||||
|
/// \returns An iterator representing the end of the set
|
||||||
|
constexpr iterator end() const {
|
||||||
|
return iterator(this, npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Class for Iterating the Set
|
/// \brief Class for Iterating the Set
|
||||||
class iterator {
|
class iterator {
|
||||||
@@ -398,12 +463,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const set* _set;
|
const multiset* _set;
|
||||||
size_t _i;
|
size_t _i;
|
||||||
friend set;
|
friend multiset;
|
||||||
|
|
||||||
constexpr iterator(const set* set, size_t i)
|
constexpr iterator(const multiset* multiset, size_t i)
|
||||||
: _set(set)
|
: _set(multiset)
|
||||||
, _i(i) {
|
, _i(i) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -449,37 +514,25 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const set* _set;
|
const multiset* _set;
|
||||||
size_t _i;
|
size_t _i;
|
||||||
int _psl;
|
int _psl;
|
||||||
elem_t _value;
|
elem_t _value;
|
||||||
friend set;
|
friend multiset;
|
||||||
|
|
||||||
constexpr value_iterator(const set* set, size_t i, int psl, const elem_t& value)
|
constexpr value_iterator(const multiset* multiset, size_t i, int psl, const elem_t& value)
|
||||||
: _set(set)
|
: _set(multiset)
|
||||||
, _i(i)
|
, _i(i)
|
||||||
, _value(value) {
|
, _value(value) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr iterator begin() const {
|
|
||||||
iterator it(this, 0);
|
|
||||||
if (not _alloc[it._i].value) {
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator end() const {
|
|
||||||
return iterator(this, npos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// PRIVATE =============================================================================================================
|
// PRIVATE =============================================================================================================
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr void _expand() {
|
constexpr void _expand() {
|
||||||
set cpy; // Create a new set
|
multiset cpy; // Create a new multiset
|
||||||
cpy._alloc.callocate(
|
cpy._alloc.callocate(
|
||||||
fennec::next_prime2(_alloc.capacity())
|
fennec::next_prime2(_alloc.capacity())
|
||||||
);
|
);
|
||||||
@@ -497,7 +550,7 @@ private:
|
|||||||
|
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr void _insert(ArgsT&&...args) {
|
constexpr void _insert(ArgsT&&...args) {
|
||||||
if (_size == 0 or double(_size) / capacity() >= _load) { // expand when full
|
if (_size == 0 or static_cast<float>(_size) / capacity() >= _load) { // expand when full
|
||||||
_expand();
|
_expand();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,7 +578,7 @@ private:
|
|||||||
equal_t _equal;
|
equal_t _equal;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
size_t _sumpsl;
|
size_t _sumpsl;
|
||||||
double _load;
|
float _load;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,21 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file object_pool.h
|
||||||
|
/// \brief A header containing the definition for a pool of objects associated by ids
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_OBJECT_POOL_H
|
#ifndef FENNEC_CONTAINERS_OBJECT_POOL_H
|
||||||
#define FENNEC_CONTAINERS_OBJECT_POOL_H
|
#define FENNEC_CONTAINERS_OBJECT_POOL_H
|
||||||
|
|
||||||
#include <fennec/containers/dynarray.h>
|
#include <fennec/containers/dynarray.h>
|
||||||
#include <fennec/containers/list.h>
|
#include <fennec/containers/list.h>
|
||||||
#include <fennec/containers/optional.h>
|
#include <fennec/containers/optional.h>
|
||||||
@@ -31,14 +44,36 @@ namespace fennec
|
|||||||
/// \tparam AllocT The allocator type
|
/// \tparam AllocT The allocator type
|
||||||
template<typename TypeT, typename AllocT = allocator<TypeT>>
|
template<typename TypeT, typename AllocT = allocator<TypeT>>
|
||||||
struct object_pool {
|
struct object_pool {
|
||||||
|
|
||||||
|
// Definitions =========================================================================================================
|
||||||
public:
|
public:
|
||||||
using value_t = TypeT;
|
using value_t = TypeT;
|
||||||
using elem_t = optional<TypeT>;
|
using elem_t = optional<TypeT>;
|
||||||
using table_t = dynarray<elem_t, AllocT>;
|
using table_t = dynarray<elem_t, AllocT>;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors & Destructor ===========================================================================================
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Default Constructor, initializes an empty object pool
|
||||||
constexpr object_pool()
|
constexpr object_pool()
|
||||||
: _size(0) {
|
: _size(0) {
|
||||||
};
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Default Destructor, destructs objects then releases the allocation.
|
||||||
|
constexpr ~object_pool() = default;
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Properties
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \returns The number of active objects in the pool
|
/// \returns The number of active objects in the pool
|
||||||
@@ -52,41 +87,17 @@ public:
|
|||||||
return _table.capacity();
|
return _table.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns `true` when there are no objects in the pool, `false` otherwise
|
||||||
constexpr bool empty() const {
|
constexpr bool empty() const {
|
||||||
return size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr value_t& operator[](size_t i) {
|
///
|
||||||
assert(i < capacity(), "Index out of Bounds!");
|
/// \brief Retrieve the next id `i` that would be assigned to an object `o` were it added to the object pool
|
||||||
assert(_table[i], "Attempted to access Null Object.");
|
///
|
||||||
return *_table[i];
|
/// \details This can be useful if there are constant members that need to be assigned at construction.
|
||||||
}
|
/// \returns The id of the next inserted node
|
||||||
|
|
||||||
constexpr const value_t& operator[](size_t i) const {
|
|
||||||
assert(i < capacity(), "Index out of Bounds!");
|
|
||||||
assert(_table[i], "Attempted to access Null Object.");
|
|
||||||
return *_table[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t insert(value_t&& x) {
|
|
||||||
return this->_insert(fennec::forward<value_t>(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t insert(const value_t& x) {
|
|
||||||
return this->_insert(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename...ArgsT>
|
|
||||||
constexpr size_t emplace(ArgsT&&...args) {
|
|
||||||
return this->_insert(fennec::forward<ArgsT>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr void erase(size_t i) {
|
|
||||||
_table[i] = nullopt;
|
|
||||||
_freed.push_back(i);
|
|
||||||
--_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t next_id() const {
|
constexpr size_t next_id() const {
|
||||||
size_t next = _size;
|
size_t next = _size;
|
||||||
if (not _freed.empty()) {
|
if (not _freed.empty()) {
|
||||||
@@ -95,6 +106,78 @@ public:
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
|
/// \name Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Array Access Operator
|
||||||
|
/// \param i id of the object
|
||||||
|
/// \returns a reference to the object with id `i`
|
||||||
|
constexpr value_t& operator[](size_t i) {
|
||||||
|
assert(i < capacity(), "Index out of Bounds!");
|
||||||
|
assert(_table[i], "Attempted to access Null Object.");
|
||||||
|
return *_table[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Array Const Access Operator
|
||||||
|
/// \param i id of the object
|
||||||
|
/// \returns a const-qualified reference to the object with id `i`
|
||||||
|
constexpr const value_t& operator[](size_t i) const {
|
||||||
|
assert(i < capacity(), "Index out of Bounds!");
|
||||||
|
assert(_table[i], "Attempted to access Null Object.");
|
||||||
|
return *_table[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
// Modifiers ===========================================================================================================
|
||||||
|
|
||||||
|
/// \name Modifiers
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move Insertion, inserts `x` into the pool
|
||||||
|
/// \param x the object to move
|
||||||
|
/// \returns An integer corresponding to the id of the node
|
||||||
|
constexpr size_t insert(value_t&& x) {
|
||||||
|
return this->_insert(fennec::forward<value_t>(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move Insertion, inserts a copy of `x` into the pool
|
||||||
|
/// \param x the object to copy
|
||||||
|
/// \returns An integer corresponding to the id of the node
|
||||||
|
constexpr size_t insert(const value_t& x) {
|
||||||
|
return this->_insert(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Emplacement, constructs a new object using `args...`
|
||||||
|
/// \param args The arguments to construct the new object with
|
||||||
|
/// \returns An integer corresponding to the id of the node
|
||||||
|
template<typename...ArgsT>
|
||||||
|
constexpr size_t emplace(ArgsT&&...args) {
|
||||||
|
return this->_insert(fennec::forward<ArgsT>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Erase an object from the pool
|
||||||
|
/// \param i The id of the object
|
||||||
|
constexpr void erase(size_t i) {
|
||||||
|
_table[i] = nullopt;
|
||||||
|
_freed.push_back(i);
|
||||||
|
--_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
dynarray<elem_t, AllocT> _table;
|
dynarray<elem_t, AllocT> _table;
|
||||||
list<size_t> _freed;
|
list<size_t> _freed;
|
||||||
|
|||||||
@@ -16,6 +16,18 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file optional.h
|
||||||
|
/// \brief A header containing the definition for a container with an optionally present variable
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_OPTIONAL_H
|
#ifndef FENNEC_CONTAINERS_OPTIONAL_H
|
||||||
#define FENNEC_CONTAINERS_OPTIONAL_H
|
#define FENNEC_CONTAINERS_OPTIONAL_H
|
||||||
|
|
||||||
@@ -48,6 +60,9 @@ public:
|
|||||||
|
|
||||||
// Constructors ========================================================================================================
|
// Constructors ========================================================================================================
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Constructor
|
/// \brief Default Constructor
|
||||||
constexpr optional()
|
constexpr optional()
|
||||||
@@ -116,9 +131,34 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Properties
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Implicit Boolean Check, returns `true` when there is a value contained
|
||||||
|
constexpr operator bool() const {
|
||||||
|
return _set;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns `true` when there is no held value, `false` otherwise.
|
||||||
|
constexpr bool empty() const {
|
||||||
|
return not _set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Assignment Operators ================================================================================================
|
// Assignment Operators ================================================================================================
|
||||||
|
|
||||||
|
/// \name Assignment
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Fundamental Type Assignment
|
/// \brief Fundamental Type Assignment
|
||||||
/// \param val The value to set with
|
/// \param val The value to set with
|
||||||
@@ -195,34 +235,13 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
/// @}
|
||||||
/// \brief Emplace Assignment
|
|
||||||
/// \val The optional to move
|
|
||||||
template<typename...ArgsT>
|
|
||||||
constexpr T& emplace(ArgsT&&...args) {
|
|
||||||
if (_set) {
|
|
||||||
_val = T(fennec::forward<ArgsT>(args)...);
|
|
||||||
} else {
|
|
||||||
fennec::construct(&_val, fennec::forward<ArgsT>(args)...);
|
|
||||||
_set = true;
|
|
||||||
}
|
|
||||||
return _val;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Reset the Optional
|
|
||||||
void reset() {
|
|
||||||
this->operator=(nullopt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Operators ===========================================================================================================
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
///
|
/// \name Access
|
||||||
/// \brief Implicit Boolean Check, returns `true` when there is a value contained
|
/// @{
|
||||||
constexpr operator bool() const {
|
|
||||||
return _set;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \returns A pointer to the value, `nullptr` if there is no value
|
/// \returns A pointer to the value, `nullptr` if there is no value
|
||||||
@@ -268,6 +287,35 @@ public:
|
|||||||
return _val;
|
return _val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
// Modifiers ===========================================================================================================
|
||||||
|
|
||||||
|
/// \name Modifiers
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Emplace Assignment
|
||||||
|
/// \val The optional to move
|
||||||
|
template<typename...ArgsT>
|
||||||
|
constexpr T& emplace(ArgsT&&...args) {
|
||||||
|
if (_set) {
|
||||||
|
_val = T(fennec::forward<ArgsT>(args)...);
|
||||||
|
} else {
|
||||||
|
fennec::construct(&_val, fennec::forward<ArgsT>(args)...);
|
||||||
|
_set = true;
|
||||||
|
}
|
||||||
|
return _val;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Reset the Optional
|
||||||
|
void reset() {
|
||||||
|
this->operator=(nullopt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,18 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file pair.h
|
||||||
|
/// \brief A header containing the definition for a container holding a pair of values
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_PAIR_H
|
#ifndef FENNEC_CONTAINERS_PAIR_H
|
||||||
#define FENNEC_CONTAINERS_PAIR_H
|
#define FENNEC_CONTAINERS_PAIR_H
|
||||||
|
|
||||||
@@ -30,13 +42,21 @@ namespace fennec
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Struct for holding a pair of values
|
/// \brief Struct for holding a pair of values
|
||||||
/// \tparam T0 The type of the first value
|
/// \tparam TypeT0 The type of the first value
|
||||||
/// \tparam T1 The type of the second value
|
/// \tparam TypeT1 The type of the second value
|
||||||
template<typename T0, typename T1>
|
template<typename TypeT0, typename TypeT1>
|
||||||
struct pair {
|
struct pair {
|
||||||
|
|
||||||
|
// Members =============================================================================================================
|
||||||
|
|
||||||
|
TypeT0 first; ///< The first value in the pair
|
||||||
|
TypeT1 second; ///< The second value in the pair
|
||||||
|
|
||||||
// Constructors ========================================================================================================
|
// Constructors ========================================================================================================
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Constructor, invokes default constructor for both elements
|
/// \brief Default Constructor, invokes default constructor for both elements
|
||||||
constexpr pair() = default;
|
constexpr pair() = default;
|
||||||
@@ -49,7 +69,7 @@ struct pair {
|
|||||||
/// \brief Pair Copy Constructor
|
/// \brief Pair Copy Constructor
|
||||||
/// \param x Value to copy for the first element
|
/// \param x Value to copy for the first element
|
||||||
/// \param y Value to copy for the first element
|
/// \param y Value to copy for the first element
|
||||||
constexpr pair(const T0& x, const T1& y)
|
constexpr pair(const TypeT0& x, const TypeT1& y)
|
||||||
: first(x)
|
: first(x)
|
||||||
, second(y) {
|
, second(y) {
|
||||||
}
|
}
|
||||||
@@ -58,9 +78,9 @@ struct pair {
|
|||||||
/// \brief Pair Move Constructor
|
/// \brief Pair Move Constructor
|
||||||
/// \param x Value to move for the first element
|
/// \param x Value to move for the first element
|
||||||
/// \param y Value to move for the first element
|
/// \param y Value to move for the first element
|
||||||
constexpr pair(T0&& x, T1&& y) noexcept
|
constexpr pair(TypeT0&& x, TypeT1&& y) noexcept
|
||||||
: first(fennec::forward<T0>(x))
|
: first(fennec::forward<TypeT0>(x))
|
||||||
, second(fennec::forward<T1>(y)) {
|
, second(fennec::forward<TypeT1>(y)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -89,9 +109,14 @@ struct pair {
|
|||||||
/// \brief Move Assignment, moves both elements
|
/// \brief Move Assignment, moves both elements
|
||||||
constexpr pair& operator=(pair&&) noexcept = default;
|
constexpr pair& operator=(pair&&) noexcept = default;
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Comparison ==========================================================================================================
|
// Comparison ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Comparison
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Equality Operator
|
/// \brief Equality Operator
|
||||||
/// \param p Pair to compare with
|
/// \param p Pair to compare with
|
||||||
@@ -144,18 +169,15 @@ struct pair {
|
|||||||
return first > p.first or (first == p.first and second >= p.second);
|
return first > p.first or (first == p.first and second >= p.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Members =============================================================================================================
|
/// @}
|
||||||
|
|
||||||
T0 first;
|
|
||||||
T1 second;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T0, typename T1>
|
template<typename TypeT0, typename TypeT1>
|
||||||
struct hash<pair<T0, T1>> : hash<T0>, hash<T1> {
|
struct hash<pair<TypeT0, TypeT1>> : hash<TypeT0>, hash<TypeT1> {
|
||||||
constexpr size_t operator()(const pair<T0, T1>& p) const {
|
constexpr size_t operator()(const pair<TypeT0, TypeT1>& p) const {
|
||||||
return fennec::pair_hash( // pair the hashes of both elements
|
return fennec::pair_hash( // pair the hashes of both elements
|
||||||
hash<T0>::operator()(p.first),
|
hash<TypeT0>::operator()(p.first),
|
||||||
hash<T1>::operator()(p.second)
|
hash<TypeT1>::operator()(p.second)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,6 +16,18 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file rdtree.h
|
||||||
|
/// \brief A header containing the definition for a tree with a root and directed edges
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_RDTREE_H
|
#ifndef FENNEC_CONTAINERS_RDTREE_H
|
||||||
#define FENNEC_CONTAINERS_RDTREE_H
|
#define FENNEC_CONTAINERS_RDTREE_H
|
||||||
|
|
||||||
@@ -50,6 +62,13 @@ protected:
|
|||||||
size_t parent, child, prev, next;
|
size_t parent, child, prev, next;
|
||||||
size_t depth, num_children;
|
size_t depth, num_children;
|
||||||
|
|
||||||
|
constexpr node()
|
||||||
|
: value(nullopt)
|
||||||
|
, parent(npos), child(npos)
|
||||||
|
, prev(npos), next(npos)
|
||||||
|
, depth(0), num_children(0) {
|
||||||
|
}
|
||||||
|
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr node(size_t p, size_t c, size_t v, size_t n, size_t d, ArgsT&&...args)
|
constexpr node(size_t p, size_t c, size_t v, size_t n, size_t d, ArgsT&&...args)
|
||||||
: value(fennec::forward<ArgsT>(args)...)
|
: value(fennec::forward<ArgsT>(args)...)
|
||||||
@@ -62,7 +81,7 @@ protected:
|
|||||||
child = npos;
|
child = npos;
|
||||||
prev = npos;
|
prev = npos;
|
||||||
next = npos;
|
next = npos;
|
||||||
depth = npos;
|
depth = 0;
|
||||||
num_children = 0;
|
num_children = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -71,55 +90,91 @@ public:
|
|||||||
|
|
||||||
// Constructors ========================================================================================================
|
// Constructors ========================================================================================================
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Root Constructor, constructs the root node of the tree
|
||||||
|
/// \tparam ArgsT The argument types
|
||||||
|
/// \param args The arguments to construct the root with
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
explicit constexpr rdtree(ArgsT&&...args)
|
explicit constexpr rdtree(ArgsT&&...args)
|
||||||
: _table(), _freed(), _size(1) {
|
: _table(), _freed(), _size(1) {
|
||||||
_table.callocate(8);
|
_table.creallocate(8);
|
||||||
fennec::construct(&_table[0], npos, npos, npos, npos, 0, fennec::forward<ArgsT>(args)...);
|
fennec::construct(&_table[0], npos, npos, npos, npos, 0, fennec::forward<ArgsT>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Copy Constructor, copies the contents of `tree`
|
||||||
|
/// \param tree the rdtree to copy
|
||||||
constexpr rdtree(const rdtree& tree)
|
constexpr rdtree(const rdtree& tree)
|
||||||
: _table(tree._table), _freed(tree._freed), _size(tree._size) {
|
: _table(tree._table), _freed(tree._freed), _size(tree._size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move Constructor, takes ownership over the contents of `tree`
|
||||||
|
/// \param tree the rdtree to move
|
||||||
constexpr rdtree(rdtree&& tree) noexcept
|
constexpr rdtree(rdtree&& tree) noexcept
|
||||||
: _table(fennec::move(tree._table)), _freed(fennec::move(tree._freed)), _size(tree._size) {
|
: _table(fennec::move(tree._table)), _freed(fennec::move(tree._freed)), _size(tree._size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Assignment ==========================================================================================================
|
// Assignment ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Assignment
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Copy Assignment Operator
|
||||||
|
/// \param rhs the rdtree to copy
|
||||||
|
/// \returns `this` after copying the contents of `rhs`
|
||||||
constexpr rdtree& operator=(const rdtree& rhs) {
|
constexpr rdtree& operator=(const rdtree& rhs) {
|
||||||
for (value_t* it : this->_table) {
|
for (value_t* it : this->_table) {
|
||||||
fennec::destruct(it);
|
fennec::destruct(it);
|
||||||
}
|
}
|
||||||
_table = rhs._table;
|
_table = rhs._table;
|
||||||
_freed = rhs._freed;
|
_freed = rhs._freed;
|
||||||
_size = rhs._size;
|
_size = rhs._size;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move Assignment Operator
|
||||||
|
/// \param rhs the rdtree to move
|
||||||
|
/// \returns `this` after taking ownership over the contents of `rhs`
|
||||||
constexpr rdtree& operator=(rdtree&& rhs) noexcept {
|
constexpr rdtree& operator=(rdtree&& rhs) noexcept {
|
||||||
for (value_t* it : _table) {
|
for (value_t* it : _table) {
|
||||||
fennec::destruct(it);
|
fennec::destruct(it);
|
||||||
}
|
}
|
||||||
_table = fennec::move(rhs._table);
|
_table = fennec::move(rhs._table);
|
||||||
_freed = fennec::move(rhs._freed);
|
_freed = fennec::move(rhs._freed);
|
||||||
_size = rhs._size;
|
_size = rhs._size;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
// Properties ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Properties
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The number of nodes in the tree
|
||||||
constexpr size_t size() const {
|
constexpr size_t size() const {
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The capacity of the underlying allocation
|
||||||
constexpr size_t capacity() const {
|
constexpr size_t capacity() const {
|
||||||
return _table.capacity();
|
return _table.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns `true` when there are no nodes in the tree, `false` otherwise
|
||||||
constexpr bool empty() const {
|
constexpr bool empty() const {
|
||||||
return _size == 0;
|
return _size == 0;
|
||||||
}
|
}
|
||||||
@@ -249,7 +304,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \returns The next node id were `insert` or `emplace` to be called
|
/// \returns The next node id were `insert` or `emplace` to be called
|
||||||
constexpr size_t next_free() const {
|
constexpr size_t next_id() const {
|
||||||
size_t i = _size;
|
size_t i = _size;
|
||||||
if (not _freed.empty()) {
|
if (not _freed.empty()) {
|
||||||
i = _freed.front();
|
i = _freed.front();
|
||||||
@@ -347,6 +402,33 @@ public:
|
|||||||
|
|
||||||
// Traversal ===========================================================================================================
|
// Traversal ===========================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Traverse the tree using a specified order and visiting functor
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// The visitor should accept a reference to a value of type `TypeT` and a `size_t` which contains the node's id.
|
||||||
|
/// The visitor should return one of the following values in the `fennec::traversal_control_` enum
|
||||||
|
///
|
||||||
|
/// \tparam OrderT The order with which to traverse the tree.
|
||||||
|
/// \tparam VisitorT The visitor, should fulfill the signature `uint8_t visit(TypeT&, size_t)`
|
||||||
|
/// \param visit The visiting object
|
||||||
|
/// \param i The node to start at
|
||||||
|
template<typename OrderT, typename VisitorT>
|
||||||
|
void traverse(VisitorT&& visit, size_t i = root) {
|
||||||
|
OrderT order;
|
||||||
|
i = order(*this, i);
|
||||||
|
while (i != npos) {
|
||||||
|
uint8_t mode = traversal_control_continue;
|
||||||
|
if (_table[i].value) {
|
||||||
|
mode = visit(*_table[i].value, i);
|
||||||
|
}
|
||||||
|
if (mode == traversal_control_break) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i = order[*this, i, mode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct pre_order {
|
struct pre_order {
|
||||||
list<size_t> visit;
|
list<size_t> visit;
|
||||||
size_t head;
|
size_t head;
|
||||||
@@ -457,19 +539,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename OrderT, typename VisitorT>
|
|
||||||
void traverse(VisitorT&& visit, size_t i = root) {
|
|
||||||
OrderT order;
|
|
||||||
i = order(*this, i);
|
|
||||||
while (i != npos) {
|
|
||||||
uint8_t mode = visit(*_table[i].value, i);
|
|
||||||
if (mode == traversal_control_break) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i = order[*this, i, mode];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
allocation<node, alloc_t> _table;
|
allocation<node, alloc_t> _table;
|
||||||
|
|||||||
@@ -16,12 +16,23 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file set.h
|
||||||
|
/// \brief A header containing the definition for a set of unique values
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_SET_H
|
#ifndef FENNEC_CONTAINERS_SET_H
|
||||||
#define FENNEC_CONTAINERS_SET_H
|
#define FENNEC_CONTAINERS_SET_H
|
||||||
|
|
||||||
// https://programming.guide/robin-hood-hashing.html
|
// https://programming.guide/robin-hood-hashing.html
|
||||||
|
|
||||||
#include <fennec/containers/multiset.h>
|
|
||||||
#include <fennec/containers/optional.h>
|
#include <fennec/containers/optional.h>
|
||||||
#include <fennec/containers/set.h>
|
#include <fennec/containers/set.h>
|
||||||
#include <fennec/lang/compare.h>
|
#include <fennec/lang/compare.h>
|
||||||
@@ -38,13 +49,19 @@ namespace fennec
|
|||||||
/// \details
|
/// \details
|
||||||
/// This data-structure behaves like a set, but does not use pointers, instead storing the table in-array
|
/// This data-structure behaves like a set, but does not use pointers, instead storing the table in-array
|
||||||
///
|
///
|
||||||
/// | Property | Value |
|
/// | Property | Value |
|
||||||
/// |:----------|:----------:|
|
/// |:----------:|:----------:|
|
||||||
/// | stable | \emoji x |
|
/// | stable | ⛔ |
|
||||||
/// | access | \f$O(1)\f$ |
|
/// | dynamic | ✅ |
|
||||||
/// | insertion | \f$O(1)\f$ |
|
/// | homogenous | ✅ |
|
||||||
/// | deletion | \f$O(1)\f$ |
|
/// | distinct | ✅ |
|
||||||
/// | space | \f$O(1)\f$ |
|
/// | 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
|
/// \tparam TypeT The type to contain
|
||||||
template<typename TypeT, class Hash = hash<TypeT>, class Equals = equality<TypeT>, class Alloc = allocator<TypeT>>
|
template<typename TypeT, class Hash = hash<TypeT>, class Equals = equality<TypeT>, class Alloc = allocator<TypeT>>
|
||||||
@@ -73,6 +90,9 @@ private:
|
|||||||
// Constructors ========================================================================================================
|
// Constructors ========================================================================================================
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// \name Constructors & Destructor
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Constructor, initializes empty set
|
/// \brief Default Constructor, initializes empty set
|
||||||
constexpr set()
|
constexpr set()
|
||||||
@@ -85,6 +105,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Hash Copy Constructor, initializes empty set with a hash
|
/// \brief Hash Copy Constructor, initializes empty set with a hash
|
||||||
|
/// \param hash the hash object
|
||||||
constexpr set(const hash_t& hash)
|
constexpr set(const hash_t& hash)
|
||||||
: _alloc()
|
: _alloc()
|
||||||
, _hash(hash)
|
, _hash(hash)
|
||||||
@@ -93,18 +114,9 @@ public:
|
|||||||
, _load(default_load) {
|
, _load(default_load) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Hash Move Constructor, initializes empty set with a hash
|
|
||||||
constexpr set(hash_t&& hash) noexcept
|
|
||||||
: _alloc()
|
|
||||||
, _hash(hash)
|
|
||||||
, _size(0)
|
|
||||||
, _sumpsl(0)
|
|
||||||
, _load(default_load) {
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Alloc Copy Constructor, initializes empty set with an allocator
|
/// \brief Alloc Copy Constructor, initializes empty set with an allocator
|
||||||
|
/// \param alloc the allocator object
|
||||||
constexpr set(const alloc_t& alloc)
|
constexpr set(const alloc_t& alloc)
|
||||||
: _alloc(alloc)
|
: _alloc(alloc)
|
||||||
, _hash()
|
, _hash()
|
||||||
@@ -113,18 +125,10 @@ public:
|
|||||||
, _load(default_load) {
|
, _load(default_load) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Alloc Move Constructor, initializes empty set with an allocator
|
|
||||||
constexpr set(alloc_t&& alloc) noexcept
|
|
||||||
: _alloc(alloc)
|
|
||||||
, _hash()
|
|
||||||
, _size(0)
|
|
||||||
, _sumpsl(0)
|
|
||||||
, _load(default_load) {
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Hash Alloc Copy Constructor, initializes empty set with a hash and allocator
|
/// \brief Hash Alloc Copy Constructor, initializes empty set with a hash and allocator
|
||||||
|
/// \param hash the hash object
|
||||||
|
/// \param alloc the allocator object
|
||||||
constexpr set(const hash_t& hash, const alloc_t& alloc)
|
constexpr set(const hash_t& hash, const alloc_t& alloc)
|
||||||
: _alloc(alloc)
|
: _alloc(alloc)
|
||||||
, _hash(hash)
|
, _hash(hash)
|
||||||
@@ -133,36 +137,6 @@ public:
|
|||||||
, _load(default_load) {
|
, _load(default_load) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Hash Copy Alloc Move Constructor, initializes empty set with a hash and allocator
|
|
||||||
constexpr set(const hash_t& hash, alloc_t&& alloc) noexcept
|
|
||||||
: _alloc(alloc)
|
|
||||||
, _hash(hash)
|
|
||||||
, _size(0)
|
|
||||||
, _sumpsl(0)
|
|
||||||
, _load(default_load) {
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Hash Move Alloc Move Constructor, initializes empty set with a hash and allocator
|
|
||||||
constexpr set(hash_t&& hash, alloc_t&& alloc) noexcept
|
|
||||||
: _alloc(alloc)
|
|
||||||
, _hash(hash)
|
|
||||||
, _size(0)
|
|
||||||
, _sumpsl(0)
|
|
||||||
, _load(default_load) {
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Hash Move Alloc Copy Constructor, initializes empty set with a hash and allocator
|
|
||||||
constexpr set(hash_t&& hash, const alloc_t& alloc) noexcept
|
|
||||||
: _alloc(alloc)
|
|
||||||
, _hash(hash)
|
|
||||||
, _size(0)
|
|
||||||
, _sumpsl(0)
|
|
||||||
, _load(default_load) {
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Set Copy Constructor
|
/// \brief Set Copy Constructor
|
||||||
/// \param set Set to copy
|
/// \param set Set to copy
|
||||||
@@ -193,24 +167,40 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Properties ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
|
/// \name Properties
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \returns Size of the set in elements
|
/// \returns Size of the set in elements
|
||||||
constexpr size_t size() const {
|
constexpr size_t size() const {
|
||||||
return _size;
|
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
|
/// \returns Capacity of the set in elements
|
||||||
constexpr size_t capacity() const {
|
constexpr size_t capacity() const {
|
||||||
return _alloc.capacity();
|
return _alloc.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// Access ==============================================================================================================
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
|
/// \name Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Find an Element
|
/// \brief Find an Element
|
||||||
/// \param val Value to find
|
/// \param val Value to find
|
||||||
@@ -226,7 +216,7 @@ public:
|
|||||||
|
|
||||||
// Check the first element;
|
// Check the first element;
|
||||||
if (_alloc[i].psl >= psl && _alloc[i].value) {
|
if (_alloc[i].psl >= psl && _alloc[i].value) {
|
||||||
if (*_alloc[i].value == val) {
|
if (_equal(*_alloc[i].value, val)) {
|
||||||
return iterator(this, i);
|
return iterator(this, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,13 +230,13 @@ public:
|
|||||||
bool c0 = p0 >= 0 && _alloc[i0].psl >= p0, c1 = _alloc[i1].psl >= p1; // Check that we are in range
|
bool c0 = p0 >= 0 && _alloc[i0].psl >= p0, c1 = _alloc[i1].psl >= p1; // Check that we are in range
|
||||||
|
|
||||||
if (c0 && _alloc[i0].value) {
|
if (c0 && _alloc[i0].value) {
|
||||||
if (*_alloc[i0].value == val) {
|
if (_equal(*_alloc[i0].value, val)) {
|
||||||
return iterator(this, i0);
|
return iterator(this, i0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c1 && _alloc[i1].value) {
|
if (c1 && _alloc[i1].value) {
|
||||||
if (*_alloc[i1].value == val) {
|
if (_equal(*_alloc[i1].value, val)) {
|
||||||
return iterator(this, i1);
|
return iterator(this, i1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,20 +281,25 @@ public:
|
|||||||
return &*_alloc[it._i].value;
|
return &*_alloc[it._i].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insertion & Deletion ================================================================================================
|
/// @}
|
||||||
|
|
||||||
|
// Modifiers ===========================================================================================================
|
||||||
|
|
||||||
|
/// \name Modifiers
|
||||||
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Move Insertion
|
/// \brief Move Insertion
|
||||||
/// \param val Value to insert
|
/// \param val Value to insert
|
||||||
constexpr iterator insert(elem_t&& val) {
|
constexpr iterator insert(elem_t&& val) {
|
||||||
return fennec::move(this->_insert(fennec::forward<elem_t>(val)));
|
return this->_insert(fennec::forward<elem_t>(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Copy Insertion
|
/// \brief Copy Insertion
|
||||||
/// \param val Value to insert
|
/// \param val Value to insert
|
||||||
constexpr iterator insert(const elem_t& val) {
|
constexpr iterator insert(const elem_t& val) {
|
||||||
return fennec::move(this->_insert(val));
|
return this->_insert(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -313,7 +308,7 @@ public:
|
|||||||
/// \param args Arguments to construct with
|
/// \param args Arguments to construct with
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr iterator emplace(ArgsT&&...args) {
|
constexpr iterator emplace(ArgsT&&...args) {
|
||||||
return fennec::move(this->_insert(fennec::forward<ArgsT>(args)...));
|
return this->_insert(fennec::forward<ArgsT>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -348,9 +343,40 @@ public:
|
|||||||
this->erase(this->find(val));
|
this->erase(this->find(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief
|
||||||
|
constexpr void clear() {
|
||||||
|
for (size_t i = 0; i < _alloc.capacity(); ++i) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
// ITERATOR ============================================================================================================
|
// ITERATOR ============================================================================================================
|
||||||
|
|
||||||
|
/// \name Iteration
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns An iterator for all elements of the set in no particular order
|
||||||
|
constexpr iterator begin() const {
|
||||||
|
iterator it(this, 0);
|
||||||
|
if (not _alloc[it._i].value) {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns An iterator representing the end of the set
|
||||||
|
constexpr iterator end() const {
|
||||||
|
return iterator(this, npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Class for Iterating the Set
|
/// \brief Class for Iterating the Set
|
||||||
class iterator {
|
class iterator {
|
||||||
@@ -406,25 +432,13 @@ public:
|
|||||||
friend set;
|
friend set;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr iterator begin() const {
|
|
||||||
iterator it(this, 0);
|
|
||||||
if (not _alloc[it._i].value) {
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator end() const {
|
|
||||||
return iterator(this, npos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// PRIVATE =============================================================================================================
|
// PRIVATE =============================================================================================================
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr void _expand() {
|
constexpr void _expand() {
|
||||||
set cpy; // Create a new set
|
set cpy; // Create a new set
|
||||||
cpy._alloc.callocate(
|
cpy._alloc.resize(
|
||||||
fennec::next_prime2(_alloc.capacity())
|
fennec::next_prime2(_alloc.capacity())
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -441,7 +455,7 @@ private:
|
|||||||
|
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
constexpr iterator _insert(ArgsT&&...args) {
|
constexpr iterator _insert(ArgsT&&...args) {
|
||||||
if (_size == 0 or double(_size) / capacity() >= _load) { // expand when full
|
if (_size == 0 or static_cast<float>(_size) / capacity() >= _load) { // expand when full
|
||||||
_expand();
|
_expand();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,12 +479,12 @@ private:
|
|||||||
return iterator(this, npos);
|
return iterator(this, npos);
|
||||||
}
|
}
|
||||||
|
|
||||||
allocation<node, alloc_t> _alloc;
|
dynarray<node, alloc_t> _alloc;
|
||||||
hash_t _hash;
|
hash_t _hash;
|
||||||
equal_t _equal;
|
equal_t _equal;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
size_t _sumpsl;
|
size_t _sumpsl;
|
||||||
double _load;
|
float _load;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,30 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file traversal.h
|
||||||
|
/// \brief a header containing constants and utilities related to traversal
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_TRAVERSAL_H
|
#ifndef FENNEC_CONTAINERS_TRAVERSAL_H
|
||||||
#define FENNEC_CONTAINERS_TRAVERSAL_H
|
#define FENNEC_CONTAINERS_TRAVERSAL_H
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief A set of constants used in the traverser-visitor pattern
|
||||||
enum traversal_control_ {
|
enum traversal_control_ {
|
||||||
traversal_control_continue = 0,
|
traversal_control_continue = 0,
|
||||||
traversal_control_jump_over,
|
traversal_control_break = 1,
|
||||||
traversal_control_break
|
traversal_control_jump_over = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,18 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file tuple.h
|
||||||
|
/// \brief A header containing the definition for a container with multiple values of differing types
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CONTAINERS_TUPLE_H
|
#ifndef FENNEC_CONTAINERS_TUPLE_H
|
||||||
#define FENNEC_CONTAINERS_TUPLE_H
|
#define FENNEC_CONTAINERS_TUPLE_H
|
||||||
|
|
||||||
@@ -29,6 +41,21 @@ namespace fennec
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Tuple, holds a collection of values of different types
|
/// \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
|
/// \tparam TypesT The types to store
|
||||||
template<typename...TypesT> struct tuple;
|
template<typename...TypesT> struct tuple;
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,19 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
#ifndef FENNEC_CONCURRENCY_THREAD_H
|
///
|
||||||
#define FENNEC_CONCURRENCY_THREAD_H
|
/// \file variant.h
|
||||||
|
/// \brief Contains the definition for a structure that holds a single value from multiple types
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#endif // FENNEC_CONCURRENCY_THREAD_H
|
#ifndef FENNEC_CONTAINERS_VARIANT_H
|
||||||
|
#define FENNEC_CONTAINERS_VARIANT_H
|
||||||
|
|
||||||
|
#endif // FENNEC_CONTAINERS_VARIANT_H
|
||||||
@@ -29,19 +29,25 @@
|
|||||||
///
|
///
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \page documentation Documentation
|
/// \page contents Contents
|
||||||
///
|
///
|
||||||
/// 1. \ref introduction "Introduction"
|
/// 1. \ref introduction "Introduction"
|
||||||
/// 1. \ref coding-standards "Coding Standards"
|
/// 1. \ref coding-standards "Coding Standards"
|
||||||
/// 2. \ref building-from-source "Building from Source"
|
/// 2. \ref building-from-source "Building from Source"
|
||||||
/// 1. \ref building-from-terminal "Building from Terminal"
|
/// 1. \ref building-from-terminal "Building from Terminal"
|
||||||
|
/// 1. \ref debian "Debian"
|
||||||
|
/// 2. \ref arch "Arch"
|
||||||
|
/// 3. \ref fedora "Fedora"
|
||||||
/// 2. \ref building-on-windows "Building on Windows"
|
/// 2. \ref building-on-windows "Building on Windows"
|
||||||
/// 3. \ref running-the-test-suite "Running the Test Suite"
|
/// 3. \ref running-the-test-suite "Running the Test Suite"
|
||||||
/// 4. \ref usage "Usage"
|
/// 4. \ref usage "Usage"
|
||||||
|
/// 1. \ref licensing "Licensing"
|
||||||
/// 5. \ref contribution "Contribution"
|
/// 5. \ref contribution "Contribution"
|
||||||
/// 6. \subpage libraries
|
/// 6. \subpage libraries
|
||||||
/// 1. \ref fennec_lang "C++ Language Library"
|
/// 1. \ref fennec_lang "C++ Language Library"
|
||||||
/// 2. \ref fennec_math "Math Library"
|
/// 2. \ref fennec_math "Math Library"
|
||||||
|
/// 2. \ref fennec_memory "Memory Management Library"
|
||||||
|
/// 2. \ref fennec_containers "Containers Library"
|
||||||
///
|
///
|
||||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
///
|
///
|
||||||
@@ -49,11 +55,16 @@
|
|||||||
///
|
///
|
||||||
/// \page libraries Libraries
|
/// \page libraries Libraries
|
||||||
///
|
///
|
||||||
/// | Library | Brief |
|
/// | 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_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_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_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. |
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
|
||||||
#ifndef FENNEC_CORE_ENGINE_H
|
#ifndef FENNEC_CORE_ENGINE_H
|
||||||
#define FENNEC_CORE_ENGINE_H
|
#define FENNEC_CORE_ENGINE_H
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ void _assert_impl(const char* expression, const char* file, int line, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if FENNEC_RELEASE
|
#if FENNEC_RELEASE
|
||||||
#define assertd(expression, description) (0)
|
#define assertd(expression, description)
|
||||||
#else
|
#else
|
||||||
#define assertd(expression, description) assert(expression, description)
|
#define assertd(expression, description) assert(expression, description)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#define __PTRDIFF_TYPE__ ptrdiff_t
|
#define __PTRDIFF_TYPE__ ptrdiff_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Include math since stdint will define its own versions of isinf and isnan
|
||||||
|
#include <math.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ namespace fennec
|
|||||||
using uintmax_t = uintmax_t; ///< \brief Maximum Width Unsigned Integer Type
|
using uintmax_t = uintmax_t; ///< \brief Maximum Width Unsigned Integer Type
|
||||||
using size_t = size_t; ///< \brief Unsigned Integer Type Returned By `sizeof`, `sizeof...`, and `alignof`
|
using size_t = size_t; ///< \brief Unsigned Integer Type Returned By `sizeof`, `sizeof...`, and `alignof`
|
||||||
using ptrdiff_t = __PTRDIFF_TYPE__; ///< \brief Signed Integer Type Returned by the Subtraction of two Pointers
|
using ptrdiff_t = __PTRDIFF_TYPE__; ///< \brief Signed Integer Type Returned by the Subtraction of two Pointers
|
||||||
|
struct empty_t {};
|
||||||
|
|
||||||
|
|
||||||
class undefined_t; ///< \brief undefined class for SFINAE
|
class undefined_t; ///< \brief undefined class for SFINAE
|
||||||
|
|||||||
@@ -42,6 +42,22 @@ FENNEC_NO_INLINE uint64_t typeuuid() {
|
|||||||
return id = detail::_typeuuid<RootT>();
|
return id = detail::_typeuuid<RootT>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename RootT = void>
|
||||||
|
struct typed {
|
||||||
|
public:
|
||||||
|
const uint64_t type;
|
||||||
|
|
||||||
|
template<typename TypeT>
|
||||||
|
bool is_type() const {
|
||||||
|
return type == typeuuid<TypeT, RootT>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TypeT>
|
||||||
|
typed(TypeT*)
|
||||||
|
: type(typeuuid<TypeT, RootT>()) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FENNEC_LANG_TYPEUUID_H
|
#endif // FENNEC_LANG_TYPEUUID_H
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ public:
|
|||||||
bool eof() const;
|
bool eof() const;
|
||||||
|
|
||||||
|
|
||||||
// Read Operations =====================================================================================================
|
// Binary Read Operations ==============================================================================================
|
||||||
|
|
||||||
char getc();
|
char getc();
|
||||||
wchar_t getwc();
|
wchar_t getwc();
|
||||||
@@ -269,13 +269,23 @@ public:
|
|||||||
wstring getwline();
|
wstring getwline();
|
||||||
|
|
||||||
|
|
||||||
// Write Operations ====================================================================================================
|
// Binary Write Operations =============================================================================================
|
||||||
|
|
||||||
bool putc(char c);
|
bool putc(char c);
|
||||||
bool putwc(wchar_t c);
|
bool putwc(wchar_t c);
|
||||||
|
|
||||||
size_t write(const void* data, size_t size, size_t n);
|
size_t write(const void* data, size_t size, size_t n);
|
||||||
|
|
||||||
|
template<size_t n>
|
||||||
|
size_t write(const char (&data)[n]) {
|
||||||
|
return write(data, sizeof(char), n - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t n>
|
||||||
|
size_t write(const wchar_t (&data)[n]) {
|
||||||
|
return write(data, sizeof(wchar_t), n - 1);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
size_t write(const T* data, size_t n) {
|
size_t write(const T* data, size_t n) {
|
||||||
return write(static_cast<const void*>(data), sizeof(T), n);
|
return write(static_cast<const void*>(data), sizeof(T), n);
|
||||||
@@ -287,6 +297,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Printing Operations =================================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Error Handling ======================================================================================================
|
// Error Handling ======================================================================================================
|
||||||
|
|
||||||
const char* get_error() const { return _error; }
|
const char* get_error() const { return _error; }
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
/// \param str the cstring to convert
|
/// \param str the cstring to convert
|
||||||
path(const cstring& str)
|
path(const cstring& str)
|
||||||
: _str(str) {
|
: _str(str) {
|
||||||
while (not _str.empty() && _str[_str.size() - 1] == '/') {
|
if (str.size() > 2 && str[str.size() - 1] == '/') {
|
||||||
_str = _str.substring(0, str.size() - 1);
|
_str = _str.substring(0, str.size() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,8 +64,8 @@ public:
|
|||||||
/// \brief String Conversion Constructor
|
/// \brief String Conversion Constructor
|
||||||
/// \param str the string to convert
|
/// \param str the string to convert
|
||||||
path(const string& str)
|
path(const string& str)
|
||||||
: _str(str) {
|
: _str(str) {
|
||||||
while (_str[_str.size() - 1] == '/') {
|
if (str.size() > 2 && str[str.size() - 1] == '/') {
|
||||||
_str = _str.substring(0, str.size() - 1);
|
_str = _str.substring(0, str.size() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,6 +85,16 @@ public:
|
|||||||
|
|
||||||
// Assignment Operators ================================================================================================
|
// Assignment Operators ================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief C-String Assignment Operator
|
||||||
|
/// \param str the cstring to assign
|
||||||
|
/// \returns a reference to `this` after assigning `p`
|
||||||
|
template<size_t n>
|
||||||
|
path& operator=(const char (&str)[n]) {
|
||||||
|
_str = str;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief C-String Assignment Operator
|
/// \brief C-String Assignment Operator
|
||||||
/// \param p the cstring to assign
|
/// \param p the cstring to assign
|
||||||
@@ -145,6 +155,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const string& str() const { return _str; }
|
const string& str() const { return _str; }
|
||||||
|
const char* cstr() const { return _str.cstr(); }
|
||||||
|
|
||||||
bool empty() {
|
bool empty() {
|
||||||
size_t size = _str.size();
|
size_t size = _str.size();
|
||||||
@@ -176,7 +187,7 @@ public:
|
|||||||
#else
|
#else
|
||||||
size_t start = _str.size() - 1;
|
size_t start = _str.size() - 1;
|
||||||
start = _str[start] == '/' ? start - 1 : start;
|
start = _str[start] == '/' ? start - 1 : start;
|
||||||
return _str.substring(0, _str.rfind('/', start));
|
return path(_str.substring(0, _str.rfind('/', start)));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +206,7 @@ public:
|
|||||||
|
|
||||||
while (not parse.empty()) {
|
while (not parse.empty()) {
|
||||||
// Handle dots
|
// Handle dots
|
||||||
while (parse._str[0] == '.') {
|
while (not parse.empty() && parse._str[0] == '.') {
|
||||||
// Check for ".."
|
// Check for ".."
|
||||||
if (parse._str[1] == '.') {
|
if (parse._str[1] == '.') {
|
||||||
// ".."
|
// ".."
|
||||||
|
|||||||
@@ -171,6 +171,10 @@ public:
|
|||||||
/// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'`
|
/// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'`
|
||||||
constexpr size_t size() const { return _size; }
|
constexpr size_t size() const { return _size; }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \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 empty() const {
|
||||||
return _cstr == nullptr || _size == 0;
|
return _cstr == nullptr || _size == 0;
|
||||||
}
|
}
|
||||||
@@ -198,9 +202,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Dereference Operator
|
/// \brief Data Access
|
||||||
/// \returns A const qualified pointer to the underlying allocation
|
/// \returns A const qualified pointer to the underlying allocation
|
||||||
constexpr const char* operator*() const {
|
constexpr char* data() {
|
||||||
|
return _str;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Data Access
|
||||||
|
/// \returns A const qualified pointer to the underlying allocation
|
||||||
|
constexpr const char* data() const {
|
||||||
return _cstr;
|
return _cstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,8 +341,8 @@ private:
|
|||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct hash<cstring> : hash<byte_array> {
|
struct hash<cstring> : hash<byte_array> {
|
||||||
constexpr size_t operator()(const cstring& str) {
|
constexpr size_t operator()(const cstring& str) const {
|
||||||
return hash<byte_array>::operator()(byte_array(*str, str.size()));
|
return hash<byte_array>::operator()(byte_array(str, str.size()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -59,114 +59,104 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Sized Constructor, initializes a null-terminated string of size `n` with null characters
|
/// \brief Sized Constructor, initializes a null-terminated string of size `n` with `'c'...`
|
||||||
/// \param n the number of characters
|
/// \param n the number of characters
|
||||||
///
|
|
||||||
/// \details adds additional character for null termination.
|
|
||||||
constexpr _string(size_t n)
|
|
||||||
: _string('\0', n) {
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Sized Constructor, initializes a null-terminated string of size `n` filled with the character `c`
|
|
||||||
/// \param c the character to fill with
|
/// \param c the character to fill with
|
||||||
/// \param n the number of characters
|
|
||||||
///
|
///
|
||||||
/// \details adds additional character for null termination.
|
/// \details adds additional character for null termination.
|
||||||
constexpr _string(char c, size_t n)
|
constexpr _string(size_t n, char c = '\0')
|
||||||
: _str(n + 1) {
|
: _str(n + 1) {
|
||||||
fennec::memset(_str.data(), c, n);
|
fennec::memset(_str, c, n);
|
||||||
_str[n] = '\0';
|
}
|
||||||
|
|
||||||
|
constexpr _string(const alloc_t& alloc)
|
||||||
|
: _str(alloc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _string(size_t n, char c, const alloc_t& alloc)
|
||||||
|
: _str(n + 1, alloc) {
|
||||||
|
fennec::memset(_str, c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _string(const cstring& cstr)
|
||||||
|
: _str(cstr, cstr.size() + 1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Buffer Copy Constructor
|
/// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
|
||||||
/// \param str the buffer to copy
|
|
||||||
/// \param n number of characters in the buffer
|
|
||||||
///
|
|
||||||
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
|
||||||
/// This constructor makes the assumption that `n` is the intended number of characters.
|
|
||||||
constexpr _string(char* str, size_t n)
|
|
||||||
: _str(str[n - 1] == '\0' ? n : n + 1) {
|
|
||||||
fennec::memcpy(_str.data(), str, n);
|
|
||||||
if (str[n - 1] != '\0') _str[n] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Buffer Constructor, wraps the provided C-Style string
|
|
||||||
/// \param str the buffer to wrap
|
/// \param str the buffer to wrap
|
||||||
/// \tparam n the number of characters in the buffer plus the null terminator
|
/// \tparam n the number of characters in the buffer including the null-terminator, if present
|
||||||
template<size_t n>
|
template<size_t n>
|
||||||
explicit constexpr _string(char(&str)[n])
|
explicit constexpr _string(const char (&str)[n])
|
||||||
: _str(str, n) {
|
: _str(str[n - 1] != '\0' ? n + 1 : n) {
|
||||||
assert(_str[n - 1] == '\0', "Invalid NTBS.");
|
fennec::memcpy(_str, str, n);
|
||||||
|
if (str[n - 1] != '\0') {
|
||||||
|
_str[n] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Buffer Copy Constructor
|
/// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
|
||||||
/// \param str the buffer to copy
|
|
||||||
/// \param n number of characters in the buffer
|
|
||||||
///
|
|
||||||
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
|
||||||
/// This constructor makes the assumption that `n` is the intended number of characters.
|
|
||||||
constexpr _string(const char* str, size_t n)
|
|
||||||
: _str(str[n - 1] == '\0' ? n : n + 1) {
|
|
||||||
fennec::memcpy(_str.data(), str, n);
|
|
||||||
if (str[n - 1] != '\0') _str[n] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Buffer Constructor, wraps the provided C-Style string
|
|
||||||
/// \param str the buffer to wrap
|
/// \param str the buffer to wrap
|
||||||
/// \tparam n the number of characters in the buffer plus the null terminator
|
/// \param n the number of characters in the buffer including the null-terminator, if present
|
||||||
template<size_t n>
|
constexpr _string(const char* buf, size_t n)
|
||||||
explicit constexpr _string(const char(&str)[n])
|
: _str(buf[n - 1] != '\0' ? n + 1 : n) {
|
||||||
: _str(str, n) {
|
fennec::memcpy(_str, buf, n);
|
||||||
assert(_str[n - 1] == '\0', "Invalid NTBS.");
|
if (buf[n - 1] != '\0') {
|
||||||
}
|
_str[n] = '\0';
|
||||||
|
}
|
||||||
///
|
|
||||||
/// \brief Buffer Copy Constructor
|
|
||||||
/// \param str the buffer to copy
|
|
||||||
constexpr _string(const cstring& str)
|
|
||||||
: _str(str, str.size() + 1) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Copy Constructor
|
/// \brief String Copy Constructor
|
||||||
/// \param str the string to copy
|
/// \param str the string to copy
|
||||||
constexpr _string(const _string& str)
|
constexpr _string(const _string& str) = default;
|
||||||
: _str(str._str) {
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr _string(_string&& str) noexcept
|
|
||||||
: _str(fennec::move(str._str)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Destructor, cleans up the underlying allocation
|
/// \brief String Move Constructor
|
||||||
constexpr ~_string() = default; // allocation cleans up itself
|
/// \param str the string to take ownership of
|
||||||
|
constexpr _string(_string&& str) noexcept = default;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Destructor, cleans up underlying allocation
|
||||||
|
constexpr ~_string() = default;
|
||||||
|
|
||||||
|
// Assignment ==========================================================================================================
|
||||||
|
|
||||||
|
constexpr _string& operator=(const cstring& cstr) {
|
||||||
|
_str.callocate(cstr.capacity());
|
||||||
|
fennec::memcpy(_str, cstr, cstr.capacity());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _string& operator=(const _string& str) = default;
|
||||||
|
constexpr _string& operator=(_string&& str) noexcept = default;
|
||||||
|
|
||||||
// Properties ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \returns The size of the string excluding null terminator
|
/// \returns The size of the string excluding null terminator
|
||||||
constexpr size_t size() const {
|
constexpr size_t size() const {
|
||||||
return _str.capacity() - 1;
|
return _str.capacity() > 0 ? _str.capacity() - 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The size of the string including null terminator
|
||||||
|
constexpr size_t capacity() const {
|
||||||
|
return _str.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool empty() const {
|
constexpr bool empty() const {
|
||||||
return size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Access ==============================================================================================================
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Array Access Operator
|
/// \brief Array Access Operator
|
||||||
/// \param i the index to access
|
/// \param i the index to access
|
||||||
/// \returns a reference to the character
|
/// \returns a reference to the character
|
||||||
constexpr char& operator[](int i) {
|
constexpr char& operator[](size_t i) {
|
||||||
return _str[i];
|
return _str[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,24 +164,21 @@ public:
|
|||||||
/// \brief Const-Array Access Operator
|
/// \brief Const-Array Access Operator
|
||||||
/// \param i the index to access
|
/// \param i the index to access
|
||||||
/// \returns a copy of the character
|
/// \returns a copy of the character
|
||||||
constexpr char operator[](int i) const {
|
constexpr const char& operator[](size_t i) const {
|
||||||
assertd(i >= 0 && (size_t)i < size(), "Array Out of Bounds");
|
|
||||||
return _str[i];
|
return _str[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
constexpr char* data() {
|
||||||
/// \brief Dereference Operator
|
return _str;
|
||||||
/// \returns A const qualified pointer to the underlying allocation
|
|
||||||
constexpr const char* operator*() const {
|
|
||||||
return _str.data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
constexpr const char* data() const {
|
||||||
/// \brief Implicit Dereference Cast
|
return _str;
|
||||||
constexpr operator const char*() const {
|
|
||||||
return _str.data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr const char* cstr() const {
|
||||||
|
return _str;
|
||||||
|
}
|
||||||
|
|
||||||
// Examination =========================================================================================================
|
// Examination =========================================================================================================
|
||||||
|
|
||||||
@@ -212,7 +199,7 @@ public:
|
|||||||
}
|
}
|
||||||
n = fennec::min(n, fennec::max(_str, str.size()) + 1);
|
n = fennec::min(n, fennec::max(_str, str.size()) + 1);
|
||||||
|
|
||||||
return ::strncmp(_str.data() + i, str, n);
|
return ::strncmp(_str + i, str, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -226,7 +213,7 @@ public:
|
|||||||
}
|
}
|
||||||
n = min(n, max(size(), str.size()) + 1);
|
n = min(n, max(size(), str.size()) + 1);
|
||||||
|
|
||||||
return ::strncmp(_str.data() + i, str, n);
|
return ::strncmp(_str + i, str.data(), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool operator==(const _string& str) const {
|
constexpr bool operator==(const _string& str) const {
|
||||||
@@ -242,8 +229,8 @@ public:
|
|||||||
return size();
|
return size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* loc = ::strchr(_str.data() + i, c); // get location using strchr
|
const char* loc = ::strchr(_str + i, c); // get location using strchr
|
||||||
return loc ? loc - _str.data() : size(); // return size if not found
|
return loc ? loc - _str : size(); // return size if not found
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -332,63 +319,6 @@ public:
|
|||||||
return size(); // base case
|
return size(); // base case
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manipulation ========================================================================================================
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Resize the string, filling additional bytes with `'\0'`
|
|
||||||
/// \param n the new size of the string
|
|
||||||
constexpr void resize(size_t n) {
|
|
||||||
size_t i = size();
|
|
||||||
_str.reallocate(n + 1);
|
|
||||||
if (n > i) fennec::memset(_str.data() + i, '\0', n + 1 - i);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Copy Assignment Operator
|
|
||||||
/// \param str the string to copy
|
|
||||||
/// \returns a reference to `this`
|
|
||||||
constexpr _string& operator=(const cstring& str) {
|
|
||||||
if (str.empty()) {
|
|
||||||
_str.deallocate();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
resize(str.size());
|
|
||||||
fennec::memcpy(_str.data(), str, str.size());
|
|
||||||
_str[str.size()] = '\0';
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Copy Assignment Operator
|
|
||||||
/// \param str the string to copy
|
|
||||||
/// \returns a reference to `this`
|
|
||||||
constexpr _string& operator=(const string& str) {
|
|
||||||
resize(str.size());
|
|
||||||
fennec::memcpy(_str.data(), str, str.size());
|
|
||||||
_str[str.size()] = '\0';
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Move Assignment Operator
|
|
||||||
/// \param str the string to move
|
|
||||||
/// \returns a reference to `this`
|
|
||||||
constexpr _string& operator=(string&& str) noexcept {
|
|
||||||
_str = move(str._str);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Replace all instances of `x` with `y`
|
|
||||||
/// \param x the character to search for
|
|
||||||
/// \param y the character to replace with
|
|
||||||
void replace(char x, char y) {
|
|
||||||
size_t i = 0;
|
|
||||||
while ((i = find(x, 0)) != size()) {
|
|
||||||
_str[i] = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Retrieve a substring of a string
|
/// \brief Retrieve a substring of a string
|
||||||
/// \param i the start index
|
/// \param i the start index
|
||||||
@@ -398,60 +328,98 @@ public:
|
|||||||
if (i >= size()) {
|
if (i >= size()) {
|
||||||
return _string("");
|
return _string("");
|
||||||
}
|
}
|
||||||
n = min(n, size() - i);
|
n = fennec::min(n, size() - i);
|
||||||
return _string(_str.data() + i, n);
|
_string res;
|
||||||
}
|
res._str.callocate(n + 1);
|
||||||
|
fennec::memcpy(res.data(), _str + i, n);
|
||||||
///
|
|
||||||
/// \brief Returns a string with `c` appended to it
|
|
||||||
/// \param c
|
|
||||||
/// \returns
|
|
||||||
constexpr _string operator+(char c) const {
|
|
||||||
// Copy contents with one additional byte.
|
|
||||||
_string res(_str.data(), _str.size() + 1);
|
|
||||||
res[size()] = c; // Set the last character to c
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend constexpr _string operator+(char c, _string& str) {
|
|
||||||
return _string(c, 1) + str;
|
|
||||||
|
// Modifiers ===========================================================================================================
|
||||||
|
|
||||||
|
constexpr void resize(size_t n) {
|
||||||
|
_str.creallocate(n + 1);
|
||||||
|
_str[size()] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr _string operator+(const cstring& str) const {
|
constexpr _string operator+(char c) const {
|
||||||
_string res(size() + str.size()); // Make a new string with the size of this + str
|
if (_str == nullptr) {
|
||||||
fennec::memcpy(&res[0], _str.data(), size()); // Copy the contents of this
|
return _string(1, c);
|
||||||
fennec::memcpy(&res[size()], str, str.size()); // Append the contents of str
|
}
|
||||||
|
_string res;
|
||||||
|
res._str.callocate(capacity() + 1);
|
||||||
|
fennec::memcpy(res.data(), _str, size());
|
||||||
|
res[size()] = c;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend constexpr _string operator+(char c, const _string& str) {
|
||||||
|
_string res(1, c);
|
||||||
|
return res += str;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _string operator+(const cstring& cstr) const {
|
||||||
|
if (_str == nullptr) {
|
||||||
|
return _string(cstr);
|
||||||
|
}
|
||||||
|
_string res;
|
||||||
|
res._str.callocate(size() + cstr.size() + 1);
|
||||||
|
fennec::memcpy(res.data(), _str, size());
|
||||||
|
fennec::memcpy(res.data() + size(), cstr, cstr.size());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr _string operator+(const _string& str) const {
|
constexpr _string operator+(const _string& str) const {
|
||||||
_string res(size() + str.size()); // Make a new string with the size of this + str
|
if (_str == nullptr) {
|
||||||
fennec::memcpy(&res[0], _str.data(), size()); // Copy the contents of this
|
return _string(str);
|
||||||
fennec::memcpy(&res[size()], str, str.size()); // Append the contents of str
|
}
|
||||||
|
if (str.data() == nullptr) {
|
||||||
|
return _string(*this);
|
||||||
|
}
|
||||||
|
_string res;
|
||||||
|
res._str.callocate(size() + str.size() + 1);
|
||||||
|
fennec::memcpy(res.data(), _str, size());
|
||||||
|
fennec::memcpy(res.data() + size(), str.data(), str.size());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr _string& operator+=(char c) {
|
constexpr _string& operator+=(char c) {
|
||||||
size_t x = size();
|
if (_str == nullptr) {
|
||||||
resize(x + 1);
|
_str.callocate(2);
|
||||||
_str[x] = c;
|
_str[0] = c;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
_str.creallocate(capacity() + 1);
|
||||||
|
_str[size() - 1] = c;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr _string& operator+=(const cstring& str) {
|
constexpr _string& operator+=(const cstring& cstr) {
|
||||||
size_t x = size();
|
if (_str == nullptr) {
|
||||||
resize(x + str.size());
|
return *this = cstr;
|
||||||
fennec::memcpy(&_str[x], str, str.size());
|
}
|
||||||
|
size_t middle = size();
|
||||||
|
_str.creallocate(middle + cstr.size() + 1);
|
||||||
|
fennec::memcpy(_str + middle, cstr, cstr.size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr _string& operator+=(const _string& str) {
|
constexpr _string& operator+=(const _string& str) {
|
||||||
size_t x = size();
|
if (_str == nullptr) {
|
||||||
resize(x + str.size());
|
return *this = str;
|
||||||
fennec::memcpy(&_str[x], str, str.size());
|
}
|
||||||
|
if (str.data() == nullptr) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
size_t middle = size();
|
||||||
|
_str.creallocate(middle + str.size() + 1);
|
||||||
|
fennec::memcpy(_str + middle, str.data(), str.size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
alloc_t _str;
|
alloc_t _str;
|
||||||
};
|
};
|
||||||
@@ -459,7 +427,7 @@ private:
|
|||||||
template<>
|
template<>
|
||||||
struct hash<string> : hash<byte_array> {
|
struct hash<string> : hash<byte_array> {
|
||||||
constexpr size_t operator()(const string& str) const {
|
constexpr size_t operator()(const string& str) const {
|
||||||
return hash<byte_array>::operator()(byte_array(*str, str.size()));
|
return hash<byte_array>::operator()(byte_array(str.data(), str.size()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Default Constructor, initializes with nullptr
|
/// \brief Default Constructor, initializes with nullptr
|
||||||
constexpr wcstring()
|
constexpr wcstring()
|
||||||
: _str(nullptr)
|
: _str(nullptr), _size(0), _const(true) {
|
||||||
, _size(0)
|
|
||||||
, _const(true) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -93,7 +91,7 @@ public:
|
|||||||
/// \param str the buffer to wrap
|
/// \param str the buffer to wrap
|
||||||
/// \tparam n the number of characters in the buffer plus the null terminator
|
/// \tparam n the number of characters in the buffer plus the null terminator
|
||||||
template<size_t n>
|
template<size_t n>
|
||||||
constexpr wcstring(wchar_t(&str)[n])
|
constexpr wcstring(wchar_t (&str)[n])
|
||||||
: _str(str)
|
: _str(str)
|
||||||
, _size(n - 1)
|
, _size(n - 1)
|
||||||
, _const(false) {
|
, _const(false) {
|
||||||
@@ -116,7 +114,7 @@ public:
|
|||||||
/// \param str the buffer to wrap
|
/// \param str the buffer to wrap
|
||||||
/// \tparam n the number of characters in the buffer plus the null terminator
|
/// \tparam n the number of characters in the buffer plus the null terminator
|
||||||
template<size_t n>
|
template<size_t n>
|
||||||
constexpr wcstring(const wchar_t(&str)[n])
|
constexpr wcstring(const wchar_t (&str)[n])
|
||||||
: _cstr(str)
|
: _cstr(str)
|
||||||
, _size(n - 1)
|
, _size(n - 1)
|
||||||
, _const(true) {
|
, _const(true) {
|
||||||
@@ -148,7 +146,7 @@ public:
|
|||||||
template<size_t n>
|
template<size_t n>
|
||||||
constexpr wcstring& operator=(wchar_t(&str)[n]) {
|
constexpr wcstring& operator=(wchar_t(&str)[n]) {
|
||||||
assert(_str[n - 1] == '\0', "Invalid NTBS.");
|
assert(_str[n - 1] == '\0', "Invalid NTBS.");
|
||||||
_str = str; _size = n - 1; _const = false;
|
_str = str, _size = n - 1, _const = false;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +173,10 @@ public:
|
|||||||
/// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'`
|
/// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'`
|
||||||
constexpr size_t size() const { return _size; }
|
constexpr size_t size() const { return _size; }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \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 empty() const {
|
||||||
return _cstr == nullptr || _size == 0;
|
return _cstr == nullptr || _size == 0;
|
||||||
}
|
}
|
||||||
@@ -196,15 +198,22 @@ public:
|
|||||||
/// \brief Const-Array Access Operator
|
/// \brief Const-Array Access Operator
|
||||||
/// \param i the index to access
|
/// \param i the index to access
|
||||||
/// \returns a copy of the character
|
/// \returns a copy of the character
|
||||||
constexpr wchar_t operator[](size_t i) const {
|
constexpr const wchar_t& operator[](size_t i) const {
|
||||||
assertd(i < size(), "Array Out of Bounds");
|
assertd(i < size(), "Array Out of Bounds");
|
||||||
return _cstr[i];
|
return _cstr[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Dereference Operator
|
/// \brief Data Access
|
||||||
/// \returns A const qualified pointer to the underlying allocation
|
/// \returns A const qualified pointer to the underlying allocation
|
||||||
constexpr const wchar_t* operator*() const {
|
constexpr wchar_t* data() {
|
||||||
|
return _str;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Data Access
|
||||||
|
/// \returns A const qualified pointer to the underlying allocation
|
||||||
|
constexpr const wchar_t* data() const {
|
||||||
return _cstr;
|
return _cstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,12 +229,14 @@ public:
|
|||||||
///
|
///
|
||||||
/// \returns The length of the string to the first null-terminator
|
/// \returns The length of the string to the first null-terminator
|
||||||
constexpr size_t length() const {
|
constexpr size_t length() const {
|
||||||
return find(L'\0');
|
return find('\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Comparison
|
/// \brief String Comparison
|
||||||
/// \param str the string to compare against
|
/// \param str the string to compare against
|
||||||
|
/// \param i the index to start at
|
||||||
|
/// \param n the number of characters to compare
|
||||||
/// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the
|
/// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the
|
||||||
/// current locale, otherwise a positive value.
|
/// current locale, otherwise a positive value.
|
||||||
constexpr int compare(const wcstring& str, size_t i = 0, size_t n = npos) const {
|
constexpr int compare(const wcstring& str, size_t i = 0, size_t n = npos) const {
|
||||||
@@ -237,6 +248,15 @@ public:
|
|||||||
return ::wcsncmp(_cstr + i, str, n);
|
return ::wcsncmp(_cstr + i, str, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief String Equality
|
||||||
|
/// \param str the string to compare against
|
||||||
|
/// \returns True if all characters are equal, false otherwise
|
||||||
|
template<size_t n>
|
||||||
|
constexpr bool operator==(const wchar_t (&str)[n]) const {
|
||||||
|
return compare(wcstring(str)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Equality
|
/// \brief String Equality
|
||||||
/// \param str the string to compare against
|
/// \param str the string to compare against
|
||||||
@@ -278,7 +298,7 @@ public:
|
|||||||
/// \param c the string to find
|
/// \param c the string to find
|
||||||
/// \param i the index to start at
|
/// \param i the index to start at
|
||||||
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
|
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
|
||||||
constexpr size_t rfind(wchar_t c, size_t i = npos) const {
|
constexpr size_t rfind(char c, size_t i = npos) const {
|
||||||
if (_size == 0) {
|
if (_size == 0) {
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
@@ -300,7 +320,7 @@ public:
|
|||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wchar_t first = str[0];
|
const char first = str[0];
|
||||||
i = min(i, _size - str._size);
|
i = min(i, _size - str._size);
|
||||||
do {
|
do {
|
||||||
if(_cstr[i] == first) {
|
if(_cstr[i] == first) {
|
||||||
@@ -321,6 +341,13 @@ private:
|
|||||||
bool _const;
|
bool _const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct hash<wcstring> : hash<byte_array> {
|
||||||
|
constexpr size_t operator()(const wcstring& str) const {
|
||||||
|
return hash<byte_array>::operator()(byte_array(str, str.size()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FENNEC_LANGPROC_STRINGS_wcstring_H
|
#endif // FENNEC_LANGPROC_STRINGS_wcstring_H
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
#ifndef FENNEC_LANGPROC_wstringS_wstring_H
|
#ifndef FENNEC_LANGPROC_wstringS_WSTRING_H
|
||||||
#define FENNEC_LANGPROC_wstringS_wstring_H
|
#define FENNEC_LANGPROC_wstringS_WSTRING_H
|
||||||
|
|
||||||
#include <fennec/langproc/strings/detail/_ctype.h>
|
#include <fennec/langproc/strings/detail/_ctype.h>
|
||||||
#include <fennec/langproc/strings/wcstring.h>
|
#include <fennec/langproc/strings/wcstring.h>
|
||||||
@@ -59,110 +59,126 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Sized Constructor, initializes a null-terminated string of size `n` with null characters
|
/// \brief Sized Constructor, initializes a null-terminated string of size `n` with `'c'...`
|
||||||
/// \param n the number of characters
|
/// \param n the number of wchar_tacters
|
||||||
|
/// \param c the wchar_tacter to fill with
|
||||||
///
|
///
|
||||||
/// \details adds additional character for null termination.
|
/// \details adds additional wchar_tacter for null termination.
|
||||||
constexpr _wstring(size_t n)
|
constexpr _wstring(size_t n, wchar_t c = '\0')
|
||||||
: _wstring('\0', n) {
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Sized Constructor, initializes a null-terminated string of size `n` filled with the character `c`
|
|
||||||
/// \param c the characters to fill with
|
|
||||||
/// \param n the number of characters
|
|
||||||
///
|
|
||||||
/// \details adds additional character for null termination.
|
|
||||||
constexpr _wstring(wchar_t c, size_t n)
|
|
||||||
: _str(n + 1) {
|
: _str(n + 1) {
|
||||||
fennec::wmemset(_str.data(), c, n); _str[n] = '\0';
|
fennec::wmemset(_str, c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _wstring(const alloc_t& alloc)
|
||||||
|
: _str(alloc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _wstring(size_t n, wchar_t c, const alloc_t& alloc)
|
||||||
|
: _str(n + 1, alloc) {
|
||||||
|
fennec::wmemset(_str, c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _wstring(const wcstring& cstr)
|
||||||
|
: _str(cstr, cstr.size() + 1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Buffer Copy Constructor
|
/// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
|
||||||
/// \param str the buffer to copy
|
/// \param str the buffer to wrap
|
||||||
/// \param len number of characters in the buffer
|
/// \tparam n the number of wchar_tacters in the buffer including the null-terminator, if present
|
||||||
///
|
template<size_t n>
|
||||||
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
explicit constexpr _wstring(const wchar_t (&str)[n])
|
||||||
/// This constructor makes the assumption that `len` is the intended number of characters.
|
: _str(str[n - 1] != '\0' ? n + 1 : n) {
|
||||||
constexpr _wstring(const wchar_t* str, size_t n)
|
fennec::wmemcpy(_str, str, n);
|
||||||
: _str(str, n + 1) {
|
if (str[n - 1] != '\0') {
|
||||||
::wcsncpy(_str.data(), str, n);
|
_str[n] = '\0';
|
||||||
_str[n] = '\0';
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Buffer Copy Constructor
|
/// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
|
||||||
/// \param str the buffer to copy
|
/// \param str the buffer to wrap
|
||||||
/// \param len number of characters in the buffer
|
/// \param n the number of wchar_tacters in the buffer including the null-terminator, if present
|
||||||
///
|
constexpr _wstring(const wchar_t* buf, size_t n)
|
||||||
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
: _str(buf[n - 1] != '\0' ? n + 1 : n) {
|
||||||
/// This constructor makes the assumption that `len` is the intended number of characters.
|
fennec::wmemcpy(_str, buf, n);
|
||||||
constexpr _wstring(const wcstring& str)
|
if (buf[n - 1] != '\0') {
|
||||||
: _str(str, str.size() + 1) {
|
_str[n] = '\0';
|
||||||
_str[str.size()] = '\0';
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Copy Constructor
|
/// \brief String Copy Constructor
|
||||||
/// \param str the string to copy
|
/// \param str the string to copy
|
||||||
constexpr _wstring(const wstring& str)
|
constexpr _wstring(const _wstring& str) = default;
|
||||||
: _wstring(str, str.size() - 1) {
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr _wstring(_wstring&& str) noexcept
|
|
||||||
: _str(fennec::move(str._str)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Destructor, cleans up the underlying allocation
|
/// \brief String Move Constructor
|
||||||
constexpr ~_wstring() = default; // allocation cleans up itself
|
/// \param str the string to take ownership of
|
||||||
|
constexpr _wstring(_wstring&& str) noexcept = default;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Destructor, cleans up underlying allocation
|
||||||
|
constexpr ~_wstring() = default;
|
||||||
|
|
||||||
|
// Assignment ==========================================================================================================
|
||||||
|
|
||||||
|
constexpr _wstring& operator=(const wcstring& cstr) {
|
||||||
|
_str.callocate(cstr.capacity());
|
||||||
|
fennec::wmemcpy(_str, cstr, cstr.capacity());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _wstring& operator=(const _wstring& str) = default;
|
||||||
|
constexpr _wstring& operator=(_wstring&& str) noexcept = default;
|
||||||
|
|
||||||
// Properties ==========================================================================================================
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \returns The size of the string excluding null terminator
|
/// \returns The size of the string excluding null terminator
|
||||||
constexpr size_t size() const {
|
constexpr size_t size() const {
|
||||||
return _str.capacity() - 1;
|
return _str.capacity() > 0 ? _str.capacity() - 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The size of the string including null terminator
|
||||||
|
constexpr size_t capacity() const {
|
||||||
|
return _str.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool empty() const {
|
constexpr bool empty() const {
|
||||||
return size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Access ==============================================================================================================
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Array Access Operator
|
/// \brief Array Access Operator
|
||||||
/// \param i the index to access
|
/// \param i the index to access
|
||||||
/// \returns a reference to the character
|
/// \returns a reference to the wchar_tacter
|
||||||
constexpr wchar_t& operator[](int i) {
|
constexpr wchar_t& operator[](size_t i) {
|
||||||
return _str[i];
|
return _str[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Const-Array Access Operator
|
/// \brief Const-Array Access Operator
|
||||||
/// \param i the index to access
|
/// \param i the index to access
|
||||||
/// \returns a copy of the character
|
/// \returns a copy of the wchar_tacter
|
||||||
constexpr wchar_t operator[](int i) const {
|
constexpr const wchar_t& operator[](size_t i) const {
|
||||||
assertd(i >= 0 && i < size(), "Array Out of Bounds");
|
|
||||||
return _str[i];
|
return _str[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
constexpr wchar_t* data() {
|
||||||
/// \brief Dereference Operator
|
return _str;
|
||||||
/// \returns A const qualified pointer to the underlying allocation
|
|
||||||
constexpr const wchar_t* operator*() const {
|
|
||||||
return _str.data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
constexpr const wchar_t* data() const {
|
||||||
/// \brief Implicit Dereference Cast
|
return _str;
|
||||||
constexpr operator const wchar_t*() const {
|
|
||||||
return _str.data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr const wchar_t* cstr() const {
|
||||||
|
return _str;
|
||||||
|
}
|
||||||
|
|
||||||
// Examination =========================================================================================================
|
// Examination =========================================================================================================
|
||||||
|
|
||||||
@@ -183,7 +199,7 @@ public:
|
|||||||
}
|
}
|
||||||
n = fennec::min(n, fennec::max(_str, str.size()) + 1);
|
n = fennec::min(n, fennec::max(_str, str.size()) + 1);
|
||||||
|
|
||||||
return ::wcsncmp(_str.data() + i, str, n);
|
return ::wcsncmp(_str + i, str, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -191,13 +207,13 @@ public:
|
|||||||
/// \param ostr the string to compare against
|
/// \param ostr the string to compare against
|
||||||
/// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the
|
/// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the
|
||||||
/// current locale, otherwise a positive value.
|
/// current locale, otherwise a positive value.
|
||||||
constexpr int compare(const wstring& str, size_t i = 0, size_t n = npos) const {
|
constexpr int compare(const _wstring& str, size_t i = 0, size_t n = npos) const {
|
||||||
if (i >= size()) { // bounds check
|
if (i >= size()) { // bounds check
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n = min(n, max(size(), str.size()) + 1);
|
n = min(n, max(size(), str.size()) + 1);
|
||||||
|
|
||||||
return ::wcsncmp(_str.data() + i, str, n);
|
return ::wcsncmp(_str + i, str.data(), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool operator==(const _wstring& str) const {
|
constexpr bool operator==(const _wstring& str) const {
|
||||||
@@ -206,22 +222,22 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Finds the index of the first occurrence of `c` in the string
|
/// \brief Finds the index of the first occurrence of `c` in the string
|
||||||
/// \param c the character to find
|
/// \param c the wchar_tacter to find
|
||||||
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
|
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
|
||||||
constexpr size_t find(wchar_t c, size_t i = 0) const {
|
constexpr size_t find(wchar_t c, size_t i = 0) const {
|
||||||
if (i >= size()) { // bounds check
|
if (i >= size()) { // bounds check
|
||||||
return size();
|
return size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const wchar_t* loc = ::wcschr(_str.data() + i, c); // get location using strchr
|
const wchar_t* loc = ::wcschr(_str + i, c); // get location using strchr
|
||||||
return loc ? loc - _str.data() : size(); // return size if not found
|
return loc ? loc - _str : size(); // return size if not found
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Finds the index of the first occurrence of `str` in the string.
|
/// \brief Finds the index of the first occurrence of `str` in the string.
|
||||||
/// \param str the string to find
|
/// \param str the string to find
|
||||||
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
||||||
constexpr size_t find(const wstring& str, size_t i = 0) const { // bounds check
|
constexpr size_t find(const _wstring& str, size_t i = 0) const { // bounds check
|
||||||
if (i >= size()) { // bounds check
|
if (i >= size()) { // bounds check
|
||||||
return size();
|
return size();
|
||||||
}
|
}
|
||||||
@@ -287,7 +303,7 @@ public:
|
|||||||
/// \param str the string to find
|
/// \param str the string to find
|
||||||
/// \param i the index to start at
|
/// \param i the index to start at
|
||||||
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
||||||
constexpr size_t rfind(const wstring& str, size_t i = npos) const {
|
constexpr size_t rfind(const string& str, size_t i = npos) const {
|
||||||
if (size() == 0) {
|
if (size() == 0) {
|
||||||
return size();
|
return size();
|
||||||
}
|
}
|
||||||
@@ -303,116 +319,119 @@ public:
|
|||||||
return size(); // base case
|
return size(); // base case
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manipulation ========================================================================================================
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Resize the string, filling additional bytes with `'\0'`
|
|
||||||
/// \param n the new size of the string
|
|
||||||
constexpr void resize(size_t n) {
|
|
||||||
size_t i = size();
|
|
||||||
_str.reallocate(n + 1);
|
|
||||||
if (n > i) fennec::wmemset(_str.data() + i, L'\0', n - i);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Copy Assignment Operator
|
|
||||||
/// \param str the string to copy
|
|
||||||
/// \returns a reference to `this`
|
|
||||||
constexpr wstring& operator=(const wcstring& str) {
|
|
||||||
if (str.empty()) {
|
|
||||||
_str.deallocate();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
if (str.size() > size()) resize(str.size());
|
|
||||||
fennec::wmemcpy(_str.data(), str, str.size());
|
|
||||||
_str[str.size()] = L'\0';
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Copy Assignment Operator
|
|
||||||
/// \param str the string to copy
|
|
||||||
/// \returns a reference to `this`
|
|
||||||
constexpr wstring& operator=(const wstring& str) {
|
|
||||||
if (str.size() > size()) resize(str.size());
|
|
||||||
fennec::wmemcpy(_str.data(), str, str.size());
|
|
||||||
_str[str.size()] = '\0';
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Move Assignment Operator
|
|
||||||
/// \param str the string to move
|
|
||||||
/// \returns a reference to `this`
|
|
||||||
constexpr wstring& operator=(wstring&& str) noexcept {
|
|
||||||
_str = fennec::move(str._str);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Retrieve a substring of a string
|
/// \brief Retrieve a substring of a string
|
||||||
/// \param i the start index
|
/// \param i the start index
|
||||||
/// \param n the number of characters
|
/// \param n the number of wchar_tacters
|
||||||
/// \return
|
/// \return
|
||||||
constexpr wstring substring(size_t i, size_t n = npos) const {
|
constexpr _wstring substring(size_t i, size_t n = npos) const {
|
||||||
if (i >= size()) {
|
if (i >= size()) {
|
||||||
return wstring("");
|
return _wstring("");
|
||||||
}
|
}
|
||||||
n = min(n, size() - i);
|
n = fennec::min(n, size() - i);
|
||||||
return wstring(_str.data() + i, n);
|
_wstring res;
|
||||||
}
|
res._str.callocate(n + 1);
|
||||||
|
fennec::wmemcpy(res.data(), _str + i, n);
|
||||||
///
|
|
||||||
/// \brief Returns a string with `c` appended to it
|
|
||||||
/// \param c
|
|
||||||
/// \returns
|
|
||||||
constexpr wstring operator+(wchar_t c) const {
|
|
||||||
// Copy contents with one additional byte.
|
|
||||||
wstring res(_str, _str.size());
|
|
||||||
res[size()] = c; // Set the last character to c
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr wstring operator+(const wcstring& str) const {
|
|
||||||
wstring res(size() + str.size()); // Make a new string with the size of this + str
|
|
||||||
fennec::wmemcpy(&res[0], _str.data(), size()); // Copy the contents of this
|
// Modifiers ===========================================================================================================
|
||||||
fennec::wmemcpy(&res[size()], str, str.size()); // Append the contents of str
|
|
||||||
|
constexpr void resize(size_t n) {
|
||||||
|
_str.creallocate(n + 1);
|
||||||
|
_str[size()] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _wstring operator+(wchar_t c) const {
|
||||||
|
if (_str == nullptr) {
|
||||||
|
return _wstring(1, c);
|
||||||
|
}
|
||||||
|
_wstring res;
|
||||||
|
res._str.callocate(capacity() + 1);
|
||||||
|
fennec::wmemcpy(res.data(), _str, size());
|
||||||
|
res[size()] = c;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr wstring operator+(const wstring& str) const {
|
friend constexpr _wstring operator+(wchar_t c, const _wstring& str) {
|
||||||
wstring res(size() + str.size()); // Make a new string with the size of this + str
|
_wstring res(1, c);
|
||||||
fennec::wmemcpy(&res[0], _str.data(), size()); // Copy the contents of this
|
return res += str;
|
||||||
fennec::wmemcpy(&res[size()], str, str.size()); // Append the contents of str
|
}
|
||||||
|
|
||||||
|
constexpr _wstring operator+(const wcstring& cstr) const {
|
||||||
|
if (_str == nullptr) {
|
||||||
|
return _wstring(cstr);
|
||||||
|
}
|
||||||
|
_wstring res;
|
||||||
|
res._str.callocate(size() + cstr.size() + 1);
|
||||||
|
fennec::wmemcpy(res.data(), _str, size());
|
||||||
|
fennec::wmemcpy(res.data() + size(), cstr, cstr.size());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr wstring& operator+=(wchar_t c) {
|
constexpr _wstring operator+(const _wstring& str) const {
|
||||||
size_t x = size();
|
if (_str == nullptr) {
|
||||||
resize(x + 1);
|
return _wstring(str);
|
||||||
_str[x] = c;
|
}
|
||||||
|
if (str.data() == nullptr) {
|
||||||
|
return _wstring(*this);
|
||||||
|
}
|
||||||
|
_wstring res;
|
||||||
|
res._str.callocate(size() + str.size() + 1);
|
||||||
|
fennec::wmemcpy(res.data(), _str, size());
|
||||||
|
fennec::wmemcpy(res.data() + size(), str.data(), str.size());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr _wstring& operator+=(wchar_t c) {
|
||||||
|
if (_str == nullptr) {
|
||||||
|
_str.callocate(2);
|
||||||
|
_str[0] = c;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
_str.creallocate(capacity() + 1);
|
||||||
|
_str[size() - 1] = c;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr wstring& operator+=(const wcstring& str) {
|
constexpr _wstring& operator+=(const wcstring& cstr) {
|
||||||
size_t x = size();
|
if (_str == nullptr) {
|
||||||
resize(x + str.size());
|
return *this = cstr;
|
||||||
fennec::wmemcpy(&_str[x], str, str.size());
|
}
|
||||||
|
size_t middle = size();
|
||||||
|
_str.creallocate(middle + cstr.size() + 1);
|
||||||
|
fennec::wmemcpy(_str + middle, cstr, cstr.size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr wstring& operator+=(const wstring& str) {
|
constexpr _wstring& operator+=(const _wstring& str) {
|
||||||
size_t x = size();
|
if (_str == nullptr) {
|
||||||
resize(x + str.size());
|
return *this = str;
|
||||||
fennec::wmemcpy(&_str[x], str, str.size());
|
}
|
||||||
|
if (str.data() == nullptr) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
size_t middle = size();
|
||||||
|
_str.creallocate(middle + str.size() + 1);
|
||||||
|
fennec::wmemcpy(_str + middle, str.data(), str.size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
alloc_t _str;
|
alloc_t _str;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct hash<wstring> : hash<byte_array> {
|
||||||
|
constexpr size_t operator()(const string& str) const {
|
||||||
|
return hash<byte_array>::operator()(byte_array(str.data(), str.size()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // FENNEC_LANGPROC_wstringS_wstring_H
|
#endif // FENNEC_LANGPROC_wstringS_WSTRING_H
|
||||||
|
|||||||
@@ -491,13 +491,7 @@ public:
|
|||||||
/// If there is already an allocated block of memory, the previous allocation is released.
|
/// If there is already an allocated block of memory, the previous allocation is released.
|
||||||
/// \param n The number of elements of type `T` to allocate for
|
/// \param n The number of elements of type `T` to allocate for
|
||||||
constexpr void callocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
constexpr void callocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
deallocate();
|
allocate(n, align);
|
||||||
|
|
||||||
if (align != zero<align_t>()) {
|
|
||||||
_data = _alloc.allocate(_capacity = n, _alignment = align);
|
|
||||||
} else {
|
|
||||||
_data = _alloc.allocate(_capacity = n);
|
|
||||||
}
|
|
||||||
fennec::memset(static_cast<void*>(_data), 0, _capacity * sizeof(T));
|
fennec::memset(static_cast<void*>(_data), 0, _capacity * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,12 +517,15 @@ public:
|
|||||||
constexpr void reallocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
constexpr void reallocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
if (_data == nullptr) {
|
if (_data == nullptr) {
|
||||||
allocate(n, align);
|
allocate(n, align);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t* old = _data;
|
value_t* old = _data; size_t old_cap = _capacity;
|
||||||
_data = nullptr;
|
_data = nullptr;
|
||||||
allocate(n, align);
|
allocate(n, align);
|
||||||
fennec::memmove(static_cast<void*>(_data), old, min(_capacity, n) * sizeof(T));
|
|
||||||
|
fennec::memmove(static_cast<void*>(_data), old, min(_capacity, old_cap) * sizeof(T));
|
||||||
|
|
||||||
_alloc.deallocate(old);
|
_alloc.deallocate(old);
|
||||||
_capacity = n;
|
_capacity = n;
|
||||||
}
|
}
|
||||||
@@ -539,12 +536,19 @@ public:
|
|||||||
constexpr void creallocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
constexpr void creallocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
if (_data == nullptr) {
|
if (_data == nullptr) {
|
||||||
callocate(n, align);
|
callocate(n, align);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t* old = _data;
|
value_t* old = _data; size_t old_cap = _capacity;
|
||||||
_data = nullptr;
|
_data = nullptr;
|
||||||
callocate(n, align);
|
allocate(n, align);
|
||||||
fennec::memmove(static_cast<void*>(_data), old, min(_capacity, n) * sizeof(T));
|
|
||||||
|
fennec::memmove(static_cast<void*>(_data), old, min(_capacity, old_cap) * sizeof(T));
|
||||||
|
|
||||||
|
if (_capacity > old_cap) {
|
||||||
|
fennec::memset(static_cast<void*>(_data + old_cap), 0, _capacity - old_cap);
|
||||||
|
}
|
||||||
|
|
||||||
_alloc.deallocate(old);
|
_alloc.deallocate(old);
|
||||||
_capacity = n;
|
_capacity = n;
|
||||||
}
|
}
|
||||||
@@ -557,14 +561,17 @@ public:
|
|||||||
return _data[i];
|
return _data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr value_t operator[](size_t i) const requires is_fundamental_v<value_t> {
|
constexpr const value_t& operator[](size_t i) const {
|
||||||
assertd(i < capacity(), "Array Out of Bounds");
|
assertd(i < capacity(), "Array Out of Bounds");
|
||||||
return _data[i];
|
return _data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const value_t& operator[](size_t i) const {
|
constexpr operator value_t*() {
|
||||||
assertd(i < capacity(), "Array Out of Bounds");
|
return _data;
|
||||||
return _data[i];
|
}
|
||||||
|
|
||||||
|
constexpr operator const value_t*() const {
|
||||||
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t* begin() {
|
value_t* begin() {
|
||||||
|
|||||||
@@ -24,14 +24,20 @@
|
|||||||
// implementation
|
// implementation
|
||||||
|
|
||||||
#if FENNEC_COMPILER_GCC
|
#if FENNEC_COMPILER_GCC
|
||||||
#define __OPTIMIZE__
|
#ifndef __OPTIMIZE__
|
||||||
|
# define __OPTIMIZE__
|
||||||
|
#else
|
||||||
|
# define FENNEC_OPTIMIZE_FOUND
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
#if FENNEC_COMPILER_GCC
|
#if FENNEC_COMPILER_GCC
|
||||||
|
#ifndef FENNEC_OPTIMIZE_FOUND
|
||||||
#undef __OPTIMIZE__
|
#undef __OPTIMIZE__
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // FENNEC_MEMORY_DETAIL_MEMORY_H
|
#endif // FENNEC_MEMORY_DETAIL_MEMORY_H
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
class display
|
class display : public typed<display>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct pixel_format {
|
struct pixel_format {
|
||||||
@@ -42,7 +42,7 @@ public:
|
|||||||
virtual bool connected() const = 0;
|
virtual bool connected() const = 0;
|
||||||
virtual ~display();
|
virtual ~display();
|
||||||
|
|
||||||
virtual window* create_window() = 0;
|
virtual window* create_window(window* parent) = 0;
|
||||||
|
|
||||||
const pixel_format& get_color_format() const {
|
const pixel_format& get_color_format() const {
|
||||||
return _config.format;
|
return _config.format;
|
||||||
@@ -55,7 +55,6 @@ public:
|
|||||||
gfxcontext* get_context() { return _context; }
|
gfxcontext* get_context() { return _context; }
|
||||||
|
|
||||||
const string name;
|
const string name;
|
||||||
const uint64_t uuid;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
platform* _platform;
|
platform* _platform;
|
||||||
@@ -63,9 +62,9 @@ protected:
|
|||||||
config _config;
|
config _config;
|
||||||
|
|
||||||
template<typename DisplayT>
|
template<typename DisplayT>
|
||||||
explicit display(platform* platform, const cstring& name, DisplayT*)
|
explicit display(platform* platform, const cstring& name, DisplayT* type)
|
||||||
: name(name)
|
: typed(type)
|
||||||
, uuid(typeuuid<DisplayT>())
|
, name(name)
|
||||||
, _platform(platform)
|
, _platform(platform)
|
||||||
, _context(nullptr)
|
, _context(nullptr)
|
||||||
, _config {
|
, _config {
|
||||||
|
|||||||
@@ -22,33 +22,39 @@
|
|||||||
#include <fennec/langproc/strings/string.h>
|
#include <fennec/langproc/strings/string.h>
|
||||||
#include <fennec/lang/typeuuid.h>
|
#include <fennec/lang/typeuuid.h>
|
||||||
#include <fennec/platform/interface/fwd.h>
|
#include <fennec/platform/interface/fwd.h>
|
||||||
|
#include <fennec/platform/interface/window.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
class gfxcontext {
|
class gfxcontext : public typed<gfxcontext> {
|
||||||
public:
|
public:
|
||||||
const string name;
|
const string name;
|
||||||
const uint64_t uuid;
|
|
||||||
|
|
||||||
virtual bool connected() = 0;
|
virtual bool connected() = 0;
|
||||||
|
virtual const cstring& get_name() = 0;
|
||||||
virtual int32_t get_version_major() = 0;
|
virtual int32_t get_version_major() = 0;
|
||||||
virtual int32_t get_version_minor() = 0;
|
virtual int32_t get_version_minor() = 0;
|
||||||
virtual int32_t get_context_version() = 0;
|
virtual int32_t get_version() = 0;
|
||||||
virtual const cstring& get_context_name() = 0;
|
|
||||||
|
|
||||||
virtual bool check_extension(const cstring& ext) = 0;
|
virtual bool check_extension(const cstring& ext) = 0;
|
||||||
virtual void make_current(gfxsurface* surface) = 0;
|
virtual void make_current(gfxsurface* surface) = 0;
|
||||||
|
|
||||||
|
virtual gfxsurface* create_surface(window* window) = 0;
|
||||||
|
|
||||||
virtual ~gfxcontext() = default;
|
virtual ~gfxcontext() = default;
|
||||||
|
|
||||||
|
display* get_display() {
|
||||||
|
return _display;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
display* _display;
|
display* _display;
|
||||||
|
|
||||||
template<typename ContextT>
|
template<typename ContextT>
|
||||||
gfxcontext(display* display, const cstring& name, ContextT*)
|
gfxcontext(display* display, const cstring& name, ContextT* type)
|
||||||
: name(name)
|
: typed(type)
|
||||||
, uuid(typeuuid<ContextT>())
|
, name(name)
|
||||||
, _display(display) {
|
, _display(display) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
76
include/fennec/platform/interface/gfxsurface.h
Normal file
76
include/fennec/platform/interface/gfxsurface.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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 gfxsurface.h
|
||||||
|
/// \brief
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
#ifndef FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
|
||||||
|
#define FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
|
||||||
|
|
||||||
|
#include <fennec/lang/types.h>
|
||||||
|
#include <fennec/lang/typeuuid.h>
|
||||||
|
#include <fennec/platform/interface/fwd.h>
|
||||||
|
#include <fennec/platform/interface/window.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
class gfxsurface : public typed<gfxsurface> {
|
||||||
|
public:
|
||||||
|
virtual ~gfxsurface() = default;
|
||||||
|
|
||||||
|
virtual void resize(size_t width, size_t height) {
|
||||||
|
_width = width;
|
||||||
|
_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxcontext* get_context() {
|
||||||
|
return _context;
|
||||||
|
}
|
||||||
|
|
||||||
|
window* get_window() {
|
||||||
|
return _window;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
gfxcontext* _context;
|
||||||
|
window* _window;
|
||||||
|
size_t _width, _height;
|
||||||
|
|
||||||
|
template<typename SurfaceT>
|
||||||
|
gfxsurface(gfxcontext* ctx, window* window, SurfaceT* type)
|
||||||
|
: typed(type)
|
||||||
|
, _context(ctx)
|
||||||
|
, _window(window)
|
||||||
|
, _width(window->get_width()), _height(window->get_height()) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
|
||||||
@@ -59,13 +59,12 @@
|
|||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
class platform {
|
class platform : public typed<platform> {
|
||||||
public:
|
public:
|
||||||
using shared_object = struct shared_object;
|
using shared_object = struct shared_object;
|
||||||
using symbol = void*;
|
using symbol = void*;
|
||||||
|
|
||||||
const string name;
|
const string name;
|
||||||
const uint64_t uuid;
|
|
||||||
|
|
||||||
virtual ~platform() = default;
|
virtual ~platform() = default;
|
||||||
|
|
||||||
@@ -81,9 +80,9 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<typename PlatformT>
|
template<typename PlatformT>
|
||||||
explicit platform(const cstring& name, PlatformT*)
|
explicit platform(const cstring& name, PlatformT* type)
|
||||||
: name(name)
|
: typed(type)
|
||||||
, uuid(typeuuid<PlatformT>()) {
|
, name(name) {
|
||||||
auto& globals = _get_globals();
|
auto& globals = _get_globals();
|
||||||
assertf(globals.singleton == nullptr, "Conflicting Platform Definitions.");
|
assertf(globals.singleton == nullptr, "Conflicting Platform Definitions.");
|
||||||
globals.singleton = this;
|
globals.singleton = this;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <fennec/containers/optional.h>
|
#include <fennec/containers/optional.h>
|
||||||
#include <fennec/langproc/strings/string.h>
|
#include <fennec/langproc/strings/string.h>
|
||||||
#include <fennec/platform/interface/fwd.h>
|
#include <fennec/platform/interface/fwd.h>
|
||||||
|
#include <fennec/platform/linux/wayland/display.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
@@ -29,7 +30,7 @@ namespace fennec
|
|||||||
///
|
///
|
||||||
/// \brief interface for handling windows
|
/// \brief interface for handling windows
|
||||||
/// \details the interface makes no guarantees about the bit-depth and is completely dependent on the implementation.
|
/// \details the interface makes no guarantees about the bit-depth and is completely dependent on the implementation.
|
||||||
class window {
|
class window : public typed<window> {
|
||||||
public:
|
public:
|
||||||
enum class fullscreen_mode {
|
enum class fullscreen_mode {
|
||||||
windowed = 0,
|
windowed = 0,
|
||||||
@@ -53,6 +54,8 @@ public:
|
|||||||
fullscreen_mode fullscreen;
|
fullscreen_mode fullscreen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
virtual ~window() = default;
|
||||||
|
|
||||||
virtual bool running() = 0;
|
virtual bool running() = 0;
|
||||||
virtual void configure(const config& config) = 0;
|
virtual void configure(const config& config) = 0;
|
||||||
virtual bool initialize(bool modal) = 0;
|
virtual bool initialize(bool modal) = 0;
|
||||||
@@ -63,7 +66,7 @@ public:
|
|||||||
|
|
||||||
virtual bool set_width(size_t w) = 0;
|
virtual bool set_width(size_t w) = 0;
|
||||||
virtual bool set_height(size_t h) = 0;
|
virtual bool set_height(size_t h) = 0;
|
||||||
virtual bool set_size(size_t w, size_t h) = 0;
|
virtual bool resize(size_t w, size_t h) = 0;
|
||||||
|
|
||||||
virtual bool set_fullscreen_mode(fullscreen_mode mode) = 0;
|
virtual bool set_fullscreen_mode(fullscreen_mode mode) = 0;
|
||||||
|
|
||||||
@@ -73,6 +76,8 @@ public:
|
|||||||
virtual bool grab_mouse(bool e) = 0;
|
virtual bool grab_mouse(bool e) = 0;
|
||||||
virtual bool block_screensaver(bool e) = 0;
|
virtual bool block_screensaver(bool e) = 0;
|
||||||
|
|
||||||
|
virtual struct wl_surface* get_native_handle() = 0;
|
||||||
|
|
||||||
bool is_child() const {
|
bool is_child() const {
|
||||||
if (not _config) return false;
|
if (not _config) return false;
|
||||||
return _config->flags & flags_child;
|
return _config->flags & flags_child;
|
||||||
@@ -91,9 +96,13 @@ public:
|
|||||||
return _display;
|
return _display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const config& get_config() const {
|
||||||
|
return *_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const string& get_title() const {
|
const string& get_title() const {
|
||||||
static const string _null = { "null" };
|
static const string _null{"null"};
|
||||||
if (not _config) return _null;
|
if (not _config) return _null;
|
||||||
return _config->title;
|
return _config->title;
|
||||||
}
|
}
|
||||||
@@ -137,13 +146,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~window() = default;
|
template<typename TypeT>
|
||||||
window(display* display, window* parent);
|
window(display* display, window* parent, TypeT* type)
|
||||||
|
: typed(type)
|
||||||
|
, _display(display)
|
||||||
|
, _parent(parent)
|
||||||
|
, _surface(nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
display* _display;
|
display* _display;
|
||||||
window* _parent;
|
window* _parent;
|
||||||
optional<config> _config;
|
optional<config> _config;
|
||||||
gfxsurface* _context;
|
gfxsurface* _surface;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H
|
#define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H
|
||||||
|
|
||||||
#include <fennec/platform/interface/display.h>
|
#include <fennec/platform/interface/display.h>
|
||||||
#include <fennec/platform/linux/wayland/lib/fwd.h>
|
#include <fennec/platform/linux/wayland/lib/wayland.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
@@ -33,13 +33,28 @@ public:
|
|||||||
bool connected() const override;
|
bool connected() const override;
|
||||||
void* get_native_handle() override { return _handle; }
|
void* get_native_handle() override { return _handle; }
|
||||||
|
|
||||||
window* create_window() override;
|
window* create_window(window* parent) override;
|
||||||
|
|
||||||
|
wl_registry* get_registry() { return _registry; }
|
||||||
|
const wl_registry* get_registry() const { return _registry; }
|
||||||
|
|
||||||
|
wl_compositor* get_compositor() { return _compositor; }
|
||||||
|
const wl_compositor* get_compositor() const { return _compositor; }
|
||||||
|
|
||||||
|
// xdg_wm_base* get_shell() { return _shell; }
|
||||||
|
//const xdg_wm_base* get_shell() const { return _shell; }
|
||||||
|
|
||||||
|
wl_seat* get_seat() { return _seat; }
|
||||||
|
const wl_seat* get_seat() const { return _seat; }
|
||||||
|
|
||||||
|
wl_shm* get_shm() { return _shm; }
|
||||||
|
const wl_shm* get_shm() const { return _shm; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wl_display* _handle;
|
wl_display* _handle;
|
||||||
wl_registry* _registry;
|
wl_registry* _registry;
|
||||||
wl_compositor* _compositor;
|
wl_compositor* _compositor;
|
||||||
wl_shell* _shell;
|
//xdg_wm_base* _shell;
|
||||||
wl_seat* _seat;
|
wl_seat* _seat;
|
||||||
wl_shm* _shm;
|
wl_shm* _shm;
|
||||||
bool _fifo;
|
bool _fifo;
|
||||||
|
|||||||
@@ -1,86 +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/>.
|
|
||||||
// =====================================================================================================================
|
|
||||||
|
|
||||||
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_LIB_FWD_H
|
|
||||||
#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_FWD_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2008 Kristian Høgsberg
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial
|
|
||||||
* portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fennec/lang/types.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
struct wl_object;
|
|
||||||
struct wl_proxy;
|
|
||||||
struct wl_display;
|
|
||||||
struct wl_event_queue;
|
|
||||||
struct wl_buffer;
|
|
||||||
struct wl_callback;
|
|
||||||
struct wl_compositor;
|
|
||||||
struct wl_data_device;
|
|
||||||
struct wl_data_device_manager;
|
|
||||||
struct wl_data_offer;
|
|
||||||
struct wl_data_source;
|
|
||||||
struct wl_keyboard;
|
|
||||||
struct wl_output;
|
|
||||||
struct wl_pointer;
|
|
||||||
struct wl_region;
|
|
||||||
struct wl_registry;
|
|
||||||
struct wl_seat;
|
|
||||||
struct wl_shell;
|
|
||||||
struct wl_shell_surface;
|
|
||||||
struct wl_shm;
|
|
||||||
struct wl_shm_pool;
|
|
||||||
struct wl_subcompositor;
|
|
||||||
struct wl_subsurface;
|
|
||||||
struct wl_surface;
|
|
||||||
struct wl_touch;
|
|
||||||
|
|
||||||
struct wl_egl_window;
|
|
||||||
struct wl_surface;
|
|
||||||
|
|
||||||
typedef int32_t wl_fixed_t;
|
|
||||||
|
|
||||||
#define WL_PRINTF(x, y) __attribute__((__format__(__printf__, x, y)))
|
|
||||||
typedef void (*wl_log_func_t)(const char *fmt, va_list args) WL_PRINTF(1, 0);
|
|
||||||
|
|
||||||
#define WL_MARSHAL_FLAG_DESTROY (1 << 0)
|
|
||||||
|
|
||||||
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_LIB_FWD_H
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3248
include/fennec/platform/linux/wayland/lib/protocols/wayland.xml
Normal file
3248
include/fennec/platform/linux/wayland/lib/protocols/wayland.xml
Normal file
File diff suppressed because it is too large
Load Diff
1383
include/fennec/platform/linux/wayland/lib/protocols/xdg-shell.xml
Normal file
1383
include/fennec/platform/linux/wayland/lib/protocols/xdg-shell.xml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,526 @@
|
|||||||
|
/* Generated by wayland-scanner 1.23.1 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2008-2011 Kristian Høgsberg
|
||||||
|
* Copyright © 2010-2011 Intel Corporation
|
||||||
|
* Copyright © 2012-2013 Collabora, Ltd.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation files
|
||||||
|
* (the "Software"), to deal in the Software without restriction,
|
||||||
|
* including without limitation the rights to use, copy, modify, merge,
|
||||||
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||||
|
* and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial
|
||||||
|
* portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_buffer_interface;
|
||||||
|
extern const struct wl_interface wl_callback_interface;
|
||||||
|
extern const struct wl_interface wl_data_device_interface;
|
||||||
|
extern const struct wl_interface wl_data_offer_interface;
|
||||||
|
extern const struct wl_interface wl_data_source_interface;
|
||||||
|
extern const struct wl_interface wl_keyboard_interface;
|
||||||
|
extern const struct wl_interface wl_output_interface;
|
||||||
|
extern const struct wl_interface wl_pointer_interface;
|
||||||
|
extern const struct wl_interface wl_region_interface;
|
||||||
|
extern const struct wl_interface wl_registry_interface;
|
||||||
|
extern const struct wl_interface wl_seat_interface;
|
||||||
|
extern const struct wl_interface wl_shell_surface_interface;
|
||||||
|
extern const struct wl_interface wl_shm_pool_interface;
|
||||||
|
extern const struct wl_interface wl_subsurface_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface wl_touch_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *wayland_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_callback_interface,
|
||||||
|
&wl_registry_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
&wl_buffer_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_shm_pool_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_data_source_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_data_source_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_data_offer_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_data_offer_interface,
|
||||||
|
&wl_data_offer_interface,
|
||||||
|
&wl_data_source_interface,
|
||||||
|
&wl_data_device_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
&wl_shell_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_buffer_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_callback_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_pointer_interface,
|
||||||
|
&wl_keyboard_interface,
|
||||||
|
&wl_touch_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_subsurface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_display_requests[] = {
|
||||||
|
{ "sync", "n", wayland_types + 8 },
|
||||||
|
{ "get_registry", "n", wayland_types + 9 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_display_events[] = {
|
||||||
|
{ "error", "ous", wayland_types + 0 },
|
||||||
|
{ "delete_id", "u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_display_interface = {
|
||||||
|
"wl_display", 1,
|
||||||
|
2, wl_display_requests,
|
||||||
|
2, wl_display_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_registry_requests[] = {
|
||||||
|
{ "bind", "usun", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_registry_events[] = {
|
||||||
|
{ "global", "usu", wayland_types + 0 },
|
||||||
|
{ "global_remove", "u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_registry_interface = {
|
||||||
|
"wl_registry", 1,
|
||||||
|
1, wl_registry_requests,
|
||||||
|
2, wl_registry_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_callback_events[] = {
|
||||||
|
{ "done", "u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_callback_interface = {
|
||||||
|
"wl_callback", 1,
|
||||||
|
0, NULL,
|
||||||
|
1, wl_callback_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_compositor_requests[] = {
|
||||||
|
{ "create_surface", "n", wayland_types + 10 },
|
||||||
|
{ "create_region", "n", wayland_types + 11 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_compositor_interface = {
|
||||||
|
"wl_compositor", 6,
|
||||||
|
2, wl_compositor_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shm_pool_requests[] = {
|
||||||
|
{ "create_buffer", "niiiiu", wayland_types + 12 },
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "resize", "i", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_shm_pool_interface = {
|
||||||
|
"wl_shm_pool", 2,
|
||||||
|
3, wl_shm_pool_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shm_requests[] = {
|
||||||
|
{ "create_pool", "nhi", wayland_types + 18 },
|
||||||
|
{ "release", "2", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shm_events[] = {
|
||||||
|
{ "format", "u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_shm_interface = {
|
||||||
|
"wl_shm", 2,
|
||||||
|
2, wl_shm_requests,
|
||||||
|
1, wl_shm_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_buffer_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_buffer_events[] = {
|
||||||
|
{ "release", "", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_buffer_interface = {
|
||||||
|
"wl_buffer", 1,
|
||||||
|
1, wl_buffer_requests,
|
||||||
|
1, wl_buffer_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_offer_requests[] = {
|
||||||
|
{ "accept", "u?s", wayland_types + 0 },
|
||||||
|
{ "receive", "sh", wayland_types + 0 },
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "finish", "3", wayland_types + 0 },
|
||||||
|
{ "set_actions", "3uu", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_offer_events[] = {
|
||||||
|
{ "offer", "s", wayland_types + 0 },
|
||||||
|
{ "source_actions", "3u", wayland_types + 0 },
|
||||||
|
{ "action", "3u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_data_offer_interface = {
|
||||||
|
"wl_data_offer", 3,
|
||||||
|
5, wl_data_offer_requests,
|
||||||
|
3, wl_data_offer_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_source_requests[] = {
|
||||||
|
{ "offer", "s", wayland_types + 0 },
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "set_actions", "3u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_source_events[] = {
|
||||||
|
{ "target", "?s", wayland_types + 0 },
|
||||||
|
{ "send", "sh", wayland_types + 0 },
|
||||||
|
{ "cancelled", "", wayland_types + 0 },
|
||||||
|
{ "dnd_drop_performed", "3", wayland_types + 0 },
|
||||||
|
{ "dnd_finished", "3", wayland_types + 0 },
|
||||||
|
{ "action", "3u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_data_source_interface = {
|
||||||
|
"wl_data_source", 3,
|
||||||
|
3, wl_data_source_requests,
|
||||||
|
6, wl_data_source_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_device_requests[] = {
|
||||||
|
{ "start_drag", "?oo?ou", wayland_types + 21 },
|
||||||
|
{ "set_selection", "?ou", wayland_types + 25 },
|
||||||
|
{ "release", "2", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_device_events[] = {
|
||||||
|
{ "data_offer", "n", wayland_types + 27 },
|
||||||
|
{ "enter", "uoff?o", wayland_types + 28 },
|
||||||
|
{ "leave", "", wayland_types + 0 },
|
||||||
|
{ "motion", "uff", wayland_types + 0 },
|
||||||
|
{ "drop", "", wayland_types + 0 },
|
||||||
|
{ "selection", "?o", wayland_types + 33 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_data_device_interface = {
|
||||||
|
"wl_data_device", 3,
|
||||||
|
3, wl_data_device_requests,
|
||||||
|
6, wl_data_device_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_device_manager_requests[] = {
|
||||||
|
{ "create_data_source", "n", wayland_types + 34 },
|
||||||
|
{ "get_data_device", "no", wayland_types + 35 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_data_device_manager_interface = {
|
||||||
|
"wl_data_device_manager", 3,
|
||||||
|
2, wl_data_device_manager_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shell_requests[] = {
|
||||||
|
{ "get_shell_surface", "no", wayland_types + 37 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_shell_interface = {
|
||||||
|
"wl_shell", 1,
|
||||||
|
1, wl_shell_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shell_surface_requests[] = {
|
||||||
|
{ "pong", "u", wayland_types + 0 },
|
||||||
|
{ "move", "ou", wayland_types + 39 },
|
||||||
|
{ "resize", "ouu", wayland_types + 41 },
|
||||||
|
{ "set_toplevel", "", wayland_types + 0 },
|
||||||
|
{ "set_transient", "oiiu", wayland_types + 44 },
|
||||||
|
{ "set_fullscreen", "uu?o", wayland_types + 48 },
|
||||||
|
{ "set_popup", "ouoiiu", wayland_types + 51 },
|
||||||
|
{ "set_maximized", "?o", wayland_types + 57 },
|
||||||
|
{ "set_title", "s", wayland_types + 0 },
|
||||||
|
{ "set_class", "s", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shell_surface_events[] = {
|
||||||
|
{ "ping", "u", wayland_types + 0 },
|
||||||
|
{ "configure", "uii", wayland_types + 0 },
|
||||||
|
{ "popup_done", "", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_shell_surface_interface = {
|
||||||
|
"wl_shell_surface", 1,
|
||||||
|
10, wl_shell_surface_requests,
|
||||||
|
3, wl_shell_surface_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_surface_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "attach", "?oii", wayland_types + 58 },
|
||||||
|
{ "damage", "iiii", wayland_types + 0 },
|
||||||
|
{ "frame", "n", wayland_types + 61 },
|
||||||
|
{ "set_opaque_region", "?o", wayland_types + 62 },
|
||||||
|
{ "set_input_region", "?o", wayland_types + 63 },
|
||||||
|
{ "commit", "", wayland_types + 0 },
|
||||||
|
{ "set_buffer_transform", "2i", wayland_types + 0 },
|
||||||
|
{ "set_buffer_scale", "3i", wayland_types + 0 },
|
||||||
|
{ "damage_buffer", "4iiii", wayland_types + 0 },
|
||||||
|
{ "offset", "5ii", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_surface_events[] = {
|
||||||
|
{ "enter", "o", wayland_types + 64 },
|
||||||
|
{ "leave", "o", wayland_types + 65 },
|
||||||
|
{ "preferred_buffer_scale", "6i", wayland_types + 0 },
|
||||||
|
{ "preferred_buffer_transform", "6u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_surface_interface = {
|
||||||
|
"wl_surface", 6,
|
||||||
|
11, wl_surface_requests,
|
||||||
|
4, wl_surface_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_seat_requests[] = {
|
||||||
|
{ "get_pointer", "n", wayland_types + 66 },
|
||||||
|
{ "get_keyboard", "n", wayland_types + 67 },
|
||||||
|
{ "get_touch", "n", wayland_types + 68 },
|
||||||
|
{ "release", "5", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_seat_events[] = {
|
||||||
|
{ "capabilities", "u", wayland_types + 0 },
|
||||||
|
{ "name", "2s", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_seat_interface = {
|
||||||
|
"wl_seat", 9,
|
||||||
|
4, wl_seat_requests,
|
||||||
|
2, wl_seat_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_pointer_requests[] = {
|
||||||
|
{ "set_cursor", "u?oii", wayland_types + 69 },
|
||||||
|
{ "release", "3", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_pointer_events[] = {
|
||||||
|
{ "enter", "uoff", wayland_types + 73 },
|
||||||
|
{ "leave", "uo", wayland_types + 77 },
|
||||||
|
{ "motion", "uff", wayland_types + 0 },
|
||||||
|
{ "button", "uuuu", wayland_types + 0 },
|
||||||
|
{ "axis", "uuf", wayland_types + 0 },
|
||||||
|
{ "frame", "5", wayland_types + 0 },
|
||||||
|
{ "axis_source", "5u", wayland_types + 0 },
|
||||||
|
{ "axis_stop", "5uu", wayland_types + 0 },
|
||||||
|
{ "axis_discrete", "5ui", wayland_types + 0 },
|
||||||
|
{ "axis_value120", "8ui", wayland_types + 0 },
|
||||||
|
{ "axis_relative_direction", "9uu", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_pointer_interface = {
|
||||||
|
"wl_pointer", 9,
|
||||||
|
2, wl_pointer_requests,
|
||||||
|
11, wl_pointer_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_keyboard_requests[] = {
|
||||||
|
{ "release", "3", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_keyboard_events[] = {
|
||||||
|
{ "keymap", "uhu", wayland_types + 0 },
|
||||||
|
{ "enter", "uoa", wayland_types + 79 },
|
||||||
|
{ "leave", "uo", wayland_types + 82 },
|
||||||
|
{ "key", "uuuu", wayland_types + 0 },
|
||||||
|
{ "modifiers", "uuuuu", wayland_types + 0 },
|
||||||
|
{ "repeat_info", "4ii", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_keyboard_interface = {
|
||||||
|
"wl_keyboard", 9,
|
||||||
|
1, wl_keyboard_requests,
|
||||||
|
6, wl_keyboard_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_touch_requests[] = {
|
||||||
|
{ "release", "3", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_touch_events[] = {
|
||||||
|
{ "down", "uuoiff", wayland_types + 84 },
|
||||||
|
{ "up", "uui", wayland_types + 0 },
|
||||||
|
{ "motion", "uiff", wayland_types + 0 },
|
||||||
|
{ "frame", "", wayland_types + 0 },
|
||||||
|
{ "cancel", "", wayland_types + 0 },
|
||||||
|
{ "shape", "6iff", wayland_types + 0 },
|
||||||
|
{ "orientation", "6if", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_touch_interface = {
|
||||||
|
"wl_touch", 9,
|
||||||
|
1, wl_touch_requests,
|
||||||
|
7, wl_touch_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_output_requests[] = {
|
||||||
|
{ "release", "3", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_output_events[] = {
|
||||||
|
{ "geometry", "iiiiissi", wayland_types + 0 },
|
||||||
|
{ "mode", "uiii", wayland_types + 0 },
|
||||||
|
{ "done", "2", wayland_types + 0 },
|
||||||
|
{ "scale", "2i", wayland_types + 0 },
|
||||||
|
{ "name", "4s", wayland_types + 0 },
|
||||||
|
{ "description", "4s", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_output_interface = {
|
||||||
|
"wl_output", 4,
|
||||||
|
1, wl_output_requests,
|
||||||
|
6, wl_output_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_region_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "add", "iiii", wayland_types + 0 },
|
||||||
|
{ "subtract", "iiii", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_region_interface = {
|
||||||
|
"wl_region", 1,
|
||||||
|
3, wl_region_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_subcompositor_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "get_subsurface", "noo", wayland_types + 90 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_subcompositor_interface = {
|
||||||
|
"wl_subcompositor", 1,
|
||||||
|
2, wl_subcompositor_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_subsurface_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "set_position", "ii", wayland_types + 0 },
|
||||||
|
{ "place_above", "o", wayland_types + 93 },
|
||||||
|
{ "place_below", "o", wayland_types + 94 },
|
||||||
|
{ "set_sync", "", wayland_types + 0 },
|
||||||
|
{ "set_desync", "", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_subsurface_interface = {
|
||||||
|
"wl_subsurface", 1,
|
||||||
|
6, wl_subsurface_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
/* Generated by wayland-scanner 1.23.1 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2008-2013 Kristian Høgsberg
|
||||||
|
* Copyright © 2013 Rafael Antognolli
|
||||||
|
* Copyright © 2013 Jasper St. Pierre
|
||||||
|
* Copyright © 2010-2013 Intel Corporation
|
||||||
|
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||||
|
* Copyright © 2015-2017 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_output_interface;
|
||||||
|
extern const struct wl_interface wl_seat_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_popup_interface;
|
||||||
|
extern const struct wl_interface xdg_positioner_interface;
|
||||||
|
extern const struct wl_interface xdg_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_toplevel_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *xdg_shell_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&xdg_popup_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||||
|
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||||
|
{ "pong", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_events[] = {
|
||||||
|
{ "ping", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
|
||||||
|
"xdg_wm_base", 6,
|
||||||
|
4, xdg_wm_base_requests,
|
||||||
|
1, xdg_wm_base_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_positioner_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
|
||||||
|
"xdg_positioner", 6,
|
||||||
|
10, xdg_positioner_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||||
|
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||||
|
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_events[] = {
|
||||||
|
{ "configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
|
||||||
|
"xdg_surface", 6,
|
||||||
|
5, xdg_surface_requests,
|
||||||
|
1, xdg_surface_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||||
|
{ "set_title", "s", xdg_shell_types + 0 },
|
||||||
|
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||||
|
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||||
|
{ "move", "ou", xdg_shell_types + 16 },
|
||||||
|
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||||
|
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||||
|
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_events[] = {
|
||||||
|
{ "configure", "iia", xdg_shell_types + 0 },
|
||||||
|
{ "close", "", xdg_shell_types + 0 },
|
||||||
|
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||||
|
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
|
||||||
|
"xdg_toplevel", 6,
|
||||||
|
14, xdg_toplevel_requests,
|
||||||
|
4, xdg_toplevel_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "grab", "ou", xdg_shell_types + 22 },
|
||||||
|
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_events[] = {
|
||||||
|
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "popup_done", "", xdg_shell_types + 0 },
|
||||||
|
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
|
||||||
|
"xdg_popup", 6,
|
||||||
|
3, xdg_popup_requests,
|
||||||
|
3, xdg_popup_events,
|
||||||
|
};
|
||||||
|
|
||||||
@@ -17,32 +17,6 @@
|
|||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
#include <fennec/lang/types.h>
|
#include <fennec/lang/types.h>
|
||||||
#include <fennec/platform/linux/wayland/lib/fwd.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2008 Kristian Høgsberg
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial
|
|
||||||
* portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FENNEC_LIB
|
#ifndef FENNEC_LIB
|
||||||
#define FENNEC_LIB(...)
|
#define FENNEC_LIB(...)
|
||||||
@@ -60,7 +34,7 @@
|
|||||||
FENNEC_LIB(WAYLAND);
|
FENNEC_LIB(WAYLAND);
|
||||||
|
|
||||||
FENNEC_SYMBOL(void, wl_proxy_marshal, struct wl_proxy*, uint32_t, ...);
|
FENNEC_SYMBOL(void, wl_proxy_marshal, struct wl_proxy*, uint32_t, ...);
|
||||||
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_flags, struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, uint32_t flags, ...);
|
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_flags, struct wl_proxy*, uint32_t, const struct wl_interface*, uint32_t, uint32_t, ...);
|
||||||
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_create, struct wl_proxy*, const struct wl_interface*);
|
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_create, struct wl_proxy*, const struct wl_interface*);
|
||||||
FENNEC_SYMBOL(void, wl_proxy_destroy, struct wl_proxy*);
|
FENNEC_SYMBOL(void, wl_proxy_destroy, struct wl_proxy*);
|
||||||
FENNEC_SYMBOL(int, wl_proxy_add_listener, struct wl_proxy*, void (**)(void), void*);
|
FENNEC_SYMBOL(int, wl_proxy_add_listener, struct wl_proxy*, void (**)(void), void*);
|
||||||
@@ -72,6 +46,11 @@ FENNEC_SYMBOL(const char*, wl_proxy_get_class, st
|
|||||||
FENNEC_SYMBOL(void, wl_proxy_set_queue, struct wl_proxy*, struct wl_event_queue*);
|
FENNEC_SYMBOL(void, wl_proxy_set_queue, struct wl_proxy*, struct wl_event_queue*);
|
||||||
FENNEC_SYMBOL(void*, wl_proxy_create_wrapper, void*);
|
FENNEC_SYMBOL(void*, wl_proxy_create_wrapper, void*);
|
||||||
FENNEC_SYMBOL(void, wl_proxy_wrapper_destroy, void*);
|
FENNEC_SYMBOL(void, wl_proxy_wrapper_destroy, void*);
|
||||||
|
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor, struct wl_proxy*, uint32_t, const struct wl_interface*, ...);
|
||||||
|
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor_versioned, struct wl_proxy*, uint32_t, const struct wl_interface*, uint32_t, ...);
|
||||||
|
FENNEC_SYMBOL(void, wl_proxy_set_tag, struct wl_proxy*, const char* const*);
|
||||||
|
FENNEC_SYMBOL(const char* const*, wl_proxy_get_tag, struct wl_proxy*);
|
||||||
|
|
||||||
FENNEC_SYMBOL(struct wl_display*, wl_display_connect, const char*);
|
FENNEC_SYMBOL(struct wl_display*, wl_display_connect, const char*);
|
||||||
FENNEC_SYMBOL(struct wl_display*, wl_display_connect_to_fd, int);
|
FENNEC_SYMBOL(struct wl_display*, wl_display_connect_to_fd, int);
|
||||||
FENNEC_SYMBOL(void, wl_display_disconnect, struct wl_display*);
|
FENNEC_SYMBOL(void, wl_display_disconnect, struct wl_display*);
|
||||||
@@ -88,6 +67,7 @@ FENNEC_SYMBOL(int, wl_display_get_error, st
|
|||||||
FENNEC_SYMBOL(int, wl_display_flush, struct wl_display*);
|
FENNEC_SYMBOL(int, wl_display_flush, struct wl_display*);
|
||||||
FENNEC_SYMBOL(int, wl_display_roundtrip, struct wl_display*);
|
FENNEC_SYMBOL(int, wl_display_roundtrip, struct wl_display*);
|
||||||
FENNEC_SYMBOL(struct wl_event_queue*, wl_display_create_queue, struct wl_display*);
|
FENNEC_SYMBOL(struct wl_event_queue*, wl_display_create_queue, struct wl_display*);
|
||||||
|
|
||||||
FENNEC_SYMBOL(void, wl_event_queue_destroy, struct wl_event_queue*);
|
FENNEC_SYMBOL(void, wl_event_queue_destroy, struct wl_event_queue*);
|
||||||
FENNEC_SYMBOL(void, wl_log_set_handler_client, wl_log_func_t);
|
FENNEC_SYMBOL(void, wl_log_set_handler_client, wl_log_func_t);
|
||||||
FENNEC_SYMBOL(void, wl_list_init, struct wl_list*);
|
FENNEC_SYMBOL(void, wl_list_init, struct wl_list*);
|
||||||
@@ -96,10 +76,6 @@ FENNEC_SYMBOL(void, wl_list_remove, st
|
|||||||
FENNEC_SYMBOL(int, wl_list_length, const struct wl_list*);
|
FENNEC_SYMBOL(int, wl_list_length, const struct wl_list*);
|
||||||
FENNEC_SYMBOL(int, wl_list_empty, const struct wl_list*);
|
FENNEC_SYMBOL(int, wl_list_empty, const struct wl_list*);
|
||||||
FENNEC_SYMBOL(void, wl_list_insert_list, struct wl_list*, struct wl_list*);
|
FENNEC_SYMBOL(void, wl_list_insert_list, struct wl_list*, struct wl_list*);
|
||||||
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor, struct wl_proxy*, uint32_t opcode, const struct wl_interface*interface, ...);
|
|
||||||
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor_versioned, struct wl_proxy*proxy, uint32_t opcode, const struct wl_interface*interface, uint32_t version, ...);
|
|
||||||
FENNEC_SYMBOL(void, wl_proxy_set_tag, struct wl_proxy*, const char* const*);
|
|
||||||
FENNEC_SYMBOL(const char* const*, wl_proxy_get_tag, struct wl_proxy*);
|
|
||||||
|
|
||||||
FENNEC_GLOBAL(const struct wl_interface, wl_display_interface);
|
FENNEC_GLOBAL(const struct wl_interface, wl_display_interface);
|
||||||
FENNEC_GLOBAL(const struct wl_interface, wl_registry_interface);
|
FENNEC_GLOBAL(const struct wl_interface, wl_registry_interface);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,198 +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/>.
|
|
||||||
// =====================================================================================================================
|
|
||||||
|
|
||||||
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_UTIL_H
|
|
||||||
#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_UTIL_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2008 Kristian Høgsberg
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial
|
|
||||||
* portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
|
||||||
#define WL_EXPORT __attribute__ ((visibility("default")))
|
|
||||||
#else
|
|
||||||
#define WL_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __STDC_VERSION__ >= 202311L
|
|
||||||
#define WL_DEPRECATED [[deprecated]]
|
|
||||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
|
||||||
#define WL_DEPRECATED __attribute__ ((deprecated))
|
|
||||||
#else
|
|
||||||
#define WL_DEPRECATED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
|
||||||
#define WL_PRINTF(x, y) __attribute__((__format__(__printf__, x, y)))
|
|
||||||
#else
|
|
||||||
#define WL_PRINTF(x, y)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __STDC_VERSION__ >= 202311L
|
|
||||||
#define WL_TYPEOF(expr) typeof(expr)
|
|
||||||
#else
|
|
||||||
#define WL_TYPEOF(expr) __typeof__(expr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct wl_message {
|
|
||||||
const char *name;
|
|
||||||
const char *signature;
|
|
||||||
const struct wl_interface **types;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wl_interface {
|
|
||||||
const char *name;
|
|
||||||
int version;
|
|
||||||
int method_count;
|
|
||||||
const struct wl_message *methods;
|
|
||||||
int event_count;
|
|
||||||
const struct wl_message *events;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wl_list {
|
|
||||||
struct wl_list *prev;
|
|
||||||
struct wl_list *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define wl_container_of(ptr, sample, member) \
|
|
||||||
(WL_TYPEOF(sample))((char *)(ptr) - \
|
|
||||||
offsetof(WL_TYPEOF(*sample), member))
|
|
||||||
|
|
||||||
#define wl_list_for_each(pos, head, member) \
|
|
||||||
for (pos = wl_container_of((head)->next, pos, member); \
|
|
||||||
&pos->member != (head); \
|
|
||||||
pos = wl_container_of(pos->member.next, pos, member))
|
|
||||||
|
|
||||||
#define wl_list_for_each_safe(pos, tmp, head, member) \
|
|
||||||
for (pos = wl_container_of((head)->next, pos, member), \
|
|
||||||
tmp = wl_container_of((pos)->member.next, tmp, member); \
|
|
||||||
&pos->member != (head); \
|
|
||||||
pos = tmp, \
|
|
||||||
tmp = wl_container_of(pos->member.next, tmp, member))
|
|
||||||
|
|
||||||
#define wl_list_for_each_reverse(pos, head, member) \
|
|
||||||
for (pos = wl_container_of((head)->prev, pos, member); \
|
|
||||||
&pos->member != (head); \
|
|
||||||
pos = wl_container_of(pos->member.prev, pos, member))
|
|
||||||
|
|
||||||
#define wl_list_for_each_reverse_safe(pos, tmp, head, member) \
|
|
||||||
for (pos = wl_container_of((head)->prev, pos, member), \
|
|
||||||
tmp = wl_container_of((pos)->member.prev, tmp, member); \
|
|
||||||
&pos->member != (head); \
|
|
||||||
pos = tmp, \
|
|
||||||
tmp = wl_container_of(pos->member.prev, tmp, member))
|
|
||||||
|
|
||||||
struct wl_array {
|
|
||||||
size_t size;
|
|
||||||
size_t alloc;
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
wl_array_init(struct wl_array *array);
|
|
||||||
|
|
||||||
void
|
|
||||||
wl_array_release(struct wl_array *array);
|
|
||||||
|
|
||||||
void *
|
|
||||||
wl_array_add(struct wl_array *array, size_t size);
|
|
||||||
|
|
||||||
int
|
|
||||||
wl_array_copy(struct wl_array *array, struct wl_array *source);
|
|
||||||
|
|
||||||
#define wl_array_for_each(pos, array) \
|
|
||||||
for (pos = (array)->data; \
|
|
||||||
(array)->size != 0 && \
|
|
||||||
(const char *) pos < ((const char *) (array)->data + (array)->size); \
|
|
||||||
(pos)++)
|
|
||||||
|
|
||||||
typedef int32_t wl_fixed_t;
|
|
||||||
|
|
||||||
static inline double
|
|
||||||
wl_fixed_to_double(wl_fixed_t f)
|
|
||||||
{
|
|
||||||
return f / 256.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline wl_fixed_t
|
|
||||||
wl_fixed_from_double(double d)
|
|
||||||
{
|
|
||||||
return (wl_fixed_t) (d * 256.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
wl_fixed_to_int(wl_fixed_t f)
|
|
||||||
{
|
|
||||||
return f / 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline wl_fixed_t
|
|
||||||
wl_fixed_from_int(int i)
|
|
||||||
{
|
|
||||||
return i * 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
union wl_argument {
|
|
||||||
int32_t i;
|
|
||||||
uint32_t u;
|
|
||||||
wl_fixed_t f;
|
|
||||||
const char *s;
|
|
||||||
struct wl_object *o;
|
|
||||||
uint32_t n;
|
|
||||||
struct wl_array *a;
|
|
||||||
int32_t h;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef int (*wl_dispatcher_func_t)(const void *user_data, void *target,
|
|
||||||
uint32_t opcode, const struct wl_message *msg,
|
|
||||||
union wl_argument *args);
|
|
||||||
|
|
||||||
typedef void (*wl_log_func_t)(const char *fmt, va_list args) WL_PRINTF(1, 0);
|
|
||||||
|
|
||||||
enum wl_iterator_result {
|
|
||||||
WL_ITERATOR_STOP,
|
|
||||||
WL_ITERATOR_CONTINUE
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_UTIL_H
|
|
||||||
98
include/fennec/platform/linux/wayland/lib/wayland.h
Normal file
98
include/fennec/platform/linux/wayland/lib/wayland.h
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H
|
||||||
|
#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H
|
||||||
|
|
||||||
|
#include <wayland-client-core.h>
|
||||||
|
|
||||||
|
#define FENNEC_LIB(name) extern "C" bool FENNEC_HAS_LIB_##name;
|
||||||
|
#define FENNEC_SYMBOL(ret, fn, ...) using WAYLAND_sym_##fn = ret(*)(__VA_ARGS__); \
|
||||||
|
extern "C" WAYLAND_sym_##fn WAYLAND_##fn;
|
||||||
|
#define FENNEC_GLOBAL(type, name) extern "C" type* WAYLAND_##name;
|
||||||
|
#include <fennec/platform/linux/wayland/lib/sym.h>
|
||||||
|
|
||||||
|
#define wl_proxy_marshal WAYLAND_wl_proxy_marshal
|
||||||
|
#define wl_proxy_marshal_flags WAYLAND_wl_proxy_marshal_flags
|
||||||
|
#define wl_proxy_create WAYLAND_wl_proxy_create
|
||||||
|
#define wl_proxy_destroy WAYLAND_wl_proxy_destroy
|
||||||
|
#define wl_proxy_add_listener WAYLAND_wl_proxy_add_listener
|
||||||
|
#define wl_proxy_set_user_data WAYLAND_wl_proxy_set_user_data
|
||||||
|
#define wl_proxy_get_user_data WAYLAND_wl_proxy_get_user_data
|
||||||
|
#define wl_proxy_get_version WAYLAND_wl_proxy_get_version
|
||||||
|
#define wl_proxy_get_id WAYLAND_wl_proxy_get_id
|
||||||
|
#define wl_proxy_get_class WAYLAND_wl_proxy_get_class
|
||||||
|
#define wl_proxy_set_queue WAYLAND_wl_proxy_set_queue
|
||||||
|
#define wl_proxy_create_wrapper WAYLAND_wl_proxy_create_wrapper
|
||||||
|
#define wl_proxy_wrapper_destroy WAYLAND_wl_proxy_wrapper_destroy
|
||||||
|
#define wl_proxy_marshal_constructor WAYLAND_wl_proxy_marshal_constructor
|
||||||
|
#define wl_proxy_marshal_constructor_versioned WAYLAND_wl_proxy_marshal_constructor_versioned
|
||||||
|
#define wl_proxy_set_tag WAYLAND_wl_proxy_set_tag
|
||||||
|
#define wl_proxy_get_tag WAYLAND_wl_proxy_get_tag
|
||||||
|
|
||||||
|
#define wl_event_queue_destroy WAYLAND_wl_event_queue_destroy
|
||||||
|
#define wl_log_set_handler_client WAYLAND_wl_log_set_handler_client
|
||||||
|
#define wl_list_init WAYLAND_wl_list_init
|
||||||
|
#define wl_list_insert WAYLAND_wl_list_insert
|
||||||
|
#define wl_list_remove WAYLAND_wl_list_remove
|
||||||
|
#define wl_list_length WAYLAND_wl_list_length
|
||||||
|
#define wl_list_empty WAYLAND_wl_list_empty
|
||||||
|
#define wl_list_insert_list WAYLAND_wl_list_insert_list
|
||||||
|
|
||||||
|
#define wl_display_connect WAYLAND_wl_display_connect
|
||||||
|
#define wl_display_connect_to_fd WAYLAND_wl_display_connect_to_fd
|
||||||
|
#define wl_display_reconnect WAYLAND_wl_display_reconnect
|
||||||
|
#define wl_display_disconnect WAYLAND_wl_display_disconnect
|
||||||
|
#define wl_display_get_fd WAYLAND_wl_display_get_fd
|
||||||
|
#define wl_display_dispatch WAYLAND_wl_display_dispatch
|
||||||
|
#define wl_display_dispatch_queue WAYLAND_wl_display_dispatch_queue
|
||||||
|
#define wl_display_dispatch_queue_pending WAYLAND_wl_display_dispatch_queue_pending
|
||||||
|
#define wl_display_dispatch_pending WAYLAND_wl_display_dispatch_pending
|
||||||
|
#define wl_display_prepare_read WAYLAND_wl_display_prepare_read
|
||||||
|
#define wl_display_prepare_read_queue WAYLAND_wl_display_prepare_read_queue
|
||||||
|
#define wl_display_read_events WAYLAND_wl_display_read_events
|
||||||
|
#define wl_display_cancel_read WAYLAND_wl_display_cancel_read
|
||||||
|
#define wl_display_get_error WAYLAND_wl_display_get_error
|
||||||
|
#define wl_display_flush WAYLAND_wl_display_flush
|
||||||
|
#define wl_display_roundtrip WAYLAND_wl_display_roundtrip
|
||||||
|
#define wl_display_create_queue WAYLAND_wl_display_create_queue
|
||||||
|
|
||||||
|
#define wl_seat_interface *WAYLAND_wl_seat_interface
|
||||||
|
#define wl_surface_interface *WAYLAND_wl_surface_interface
|
||||||
|
#define wl_shm_pool_interface *WAYLAND_wl_shm_pool_interface
|
||||||
|
#define wl_buffer_interface *WAYLAND_wl_buffer_interface
|
||||||
|
#define wl_registry_interface *WAYLAND_wl_registry_interface
|
||||||
|
#define wl_region_interface *WAYLAND_wl_region_interface
|
||||||
|
#define wl_pointer_interface *WAYLAND_wl_pointer_interface
|
||||||
|
#define wl_keyboard_interface *WAYLAND_wl_keyboard_interface
|
||||||
|
#define wl_compositor_interface *WAYLAND_wl_compositor_interface
|
||||||
|
#define wl_output_interface *WAYLAND_wl_output_interface
|
||||||
|
#define wl_shm_interface *WAYLAND_wl_shm_interface
|
||||||
|
#define wl_data_device_interface *WAYLAND_wl_data_device_interface
|
||||||
|
#define wl_data_offer_interface *WAYLAND_wl_data_offer_interface
|
||||||
|
#define wl_data_source_interface *WAYLAND_wl_data_source_interface
|
||||||
|
#define wl_data_device_manager_interface *WAYLAND_wl_data_device_manager_interface
|
||||||
|
|
||||||
|
#define wl_egl_window_create WAYLAND_wl_egl_window_create
|
||||||
|
#define wl_egl_window_destroy WAYLAND_wl_egl_window_destroy
|
||||||
|
#define wl_egl_window_resize WAYLAND_wl_egl_window_resize
|
||||||
|
#define wl_egl_window_get_attached_size WAYLAND_wl_egl_window_get_attached_size
|
||||||
|
|
||||||
|
#include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
|
||||||
|
|
||||||
|
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H
|
||||||
83
include/fennec/platform/linux/wayland/window.h
Normal file
83
include/fennec/platform/linux/wayland/window.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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 window.h
|
||||||
|
/// \brief
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
|
||||||
|
#define FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
|
||||||
|
|
||||||
|
#include <fennec/platform/interface/window.h>
|
||||||
|
#include <fennec/platform/linux/wayland/display.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
class wayland_window : public window {
|
||||||
|
public:
|
||||||
|
bool running() override;
|
||||||
|
|
||||||
|
void configure(const config& config) override;
|
||||||
|
|
||||||
|
bool initialize(bool modal) override;
|
||||||
|
|
||||||
|
bool shutdown() override;
|
||||||
|
|
||||||
|
bool set_title(const cstring& title) override;
|
||||||
|
bool set_title(const string& title) override;
|
||||||
|
|
||||||
|
bool set_width(size_t w) override;
|
||||||
|
bool set_height(size_t h) override;
|
||||||
|
bool resize(size_t w, size_t h) override;
|
||||||
|
bool set_resizable(bool e) override;
|
||||||
|
bool set_fullscreen_mode(fullscreen_mode mode) override;
|
||||||
|
|
||||||
|
bool grab_keyboard(bool e) override;
|
||||||
|
bool grab_mouse(bool e) override;
|
||||||
|
|
||||||
|
bool block_screensaver(bool e) override;
|
||||||
|
|
||||||
|
wayland_window(wayland_display* display, wayland_window* parent);
|
||||||
|
~wayland_window() override;
|
||||||
|
|
||||||
|
struct wl_surface* get_native_handle() override {
|
||||||
|
return _handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wl_surface* _handle;
|
||||||
|
wl_shell_surface* _shell;
|
||||||
|
size_t _nfs_width, _nfs_height;
|
||||||
|
|
||||||
|
static void listen_ping(void*, wl_shell_surface*, uint32_t);
|
||||||
|
static void listen_configure(void*, wl_shell_surface*, uint32_t, int32_t, int32_t);
|
||||||
|
static void listen_popup_done(void*, wl_shell_surface*);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
|
||||||
@@ -1,215 +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/>.
|
|
||||||
// =====================================================================================================================
|
|
||||||
|
|
||||||
#ifndef FENNEC_PLATFORM_LINUX_XKB_LIB_FWD_H
|
|
||||||
#define FENNEC_PLATFORM_LINUX_XKB_LIB_FWD_H
|
|
||||||
|
|
||||||
#include <fennec/lang/types.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2009-2012 Daniel Stone
|
|
||||||
* Copyright © 2012 Intel Corporation
|
|
||||||
* Copyright © 2012 Ran Benita
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct xkb_context;
|
|
||||||
struct xkb_keymap;
|
|
||||||
struct xkb_state;
|
|
||||||
struct xkb_rule_names;
|
|
||||||
|
|
||||||
typedef uint32_t xkb_keycode_t;
|
|
||||||
typedef uint32_t xkb_keysym_t;
|
|
||||||
typedef uint32_t xkb_layout_index_t;
|
|
||||||
typedef uint32_t xkb_layout_mask_t;
|
|
||||||
typedef uint32_t xkb_level_index_t;
|
|
||||||
typedef uint32_t xkb_mod_index_t;
|
|
||||||
typedef uint32_t xkb_mod_mask_t;
|
|
||||||
typedef uint32_t xkb_led_index_t;
|
|
||||||
typedef uint32_t xkb_led_mask_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The iterator used by xkb_keymap_key_for_each().
|
|
||||||
*
|
|
||||||
* @sa xkb_keymap_key_for_each
|
|
||||||
* @memberof xkb_keymap
|
|
||||||
* @since 0.3.1
|
|
||||||
*/
|
|
||||||
typedef void
|
|
||||||
(*xkb_keymap_key_iter_t)(struct xkb_keymap *keymap, xkb_keycode_t key,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
/** Flags for xkb_keysym_from_name(). */
|
|
||||||
enum xkb_keysym_flags {
|
|
||||||
/** Do not apply any flags. */
|
|
||||||
XKB_KEYSYM_NO_FLAGS = 0,
|
|
||||||
/** Find keysym by case-insensitive search. */
|
|
||||||
XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Flags for context creation. */
|
|
||||||
enum xkb_context_flags {
|
|
||||||
/** Do not apply any context flags. */
|
|
||||||
XKB_CONTEXT_NO_FLAGS = 0,
|
|
||||||
/** Create this context with an empty include path. */
|
|
||||||
XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
|
|
||||||
/**
|
|
||||||
* Don't take RMLVO names from the environment.
|
|
||||||
*
|
|
||||||
* @since 0.3.0
|
|
||||||
*/
|
|
||||||
XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1),
|
|
||||||
/**
|
|
||||||
* Disable the use of secure_getenv for this context, so that privileged
|
|
||||||
* processes can use environment variables. Client uses at their own risk.
|
|
||||||
*
|
|
||||||
* @since 1.5.0
|
|
||||||
*/
|
|
||||||
XKB_CONTEXT_NO_SECURE_GETENV = (1 << 2)
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Specifies a logging level. */
|
|
||||||
enum xkb_log_level {
|
|
||||||
XKB_LOG_LEVEL_CRITICAL = 10, /**< Log critical internal errors only. */
|
|
||||||
XKB_LOG_LEVEL_ERROR = 20, /**< Log all errors. */
|
|
||||||
XKB_LOG_LEVEL_WARNING = 30, /**< Log warnings and errors. */
|
|
||||||
XKB_LOG_LEVEL_INFO = 40, /**< Log information, warnings, and errors. */
|
|
||||||
XKB_LOG_LEVEL_DEBUG = 50 /**< Log everything. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Flags for keymap compilation. */
|
|
||||||
enum xkb_keymap_compile_flags {
|
|
||||||
/** Do not apply any flags. */
|
|
||||||
XKB_KEYMAP_COMPILE_NO_FLAGS = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/** The possible keymap formats. */
|
|
||||||
enum xkb_keymap_format {
|
|
||||||
/** The current/classic XKB text format, as generated by xkbcomp -xkb. */
|
|
||||||
XKB_KEYMAP_FORMAT_TEXT_V1 = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Specifies the direction of the key (press / release). */
|
|
||||||
enum xkb_key_direction {
|
|
||||||
XKB_KEY_UP, /**< The key was released. */
|
|
||||||
XKB_KEY_DOWN /**< The key was pressed. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Modifier and layout types for state objects. This enum is bitmaskable,
|
|
||||||
* e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to
|
|
||||||
* exclude locked modifiers.
|
|
||||||
*
|
|
||||||
* In XKB, the DEPRESSED components are also known as 'base'.
|
|
||||||
*/
|
|
||||||
enum xkb_state_component {
|
|
||||||
/** Depressed modifiers, i.e. a key is physically holding them. */
|
|
||||||
XKB_STATE_MODS_DEPRESSED = (1 << 0),
|
|
||||||
/** Latched modifiers, i.e. will be unset after the next non-modifier
|
|
||||||
* key press. */
|
|
||||||
XKB_STATE_MODS_LATCHED = (1 << 1),
|
|
||||||
/** Locked modifiers, i.e. will be unset after the key provoking the
|
|
||||||
* lock has been pressed again. */
|
|
||||||
XKB_STATE_MODS_LOCKED = (1 << 2),
|
|
||||||
/** Effective modifiers, i.e. currently active and affect key
|
|
||||||
* processing (derived from the other state components).
|
|
||||||
* Use this unless you explicitly care how the state came about. */
|
|
||||||
XKB_STATE_MODS_EFFECTIVE = (1 << 3),
|
|
||||||
/** Depressed layout, i.e. a key is physically holding it. */
|
|
||||||
XKB_STATE_LAYOUT_DEPRESSED = (1 << 4),
|
|
||||||
/** Latched layout, i.e. will be unset after the next non-modifier
|
|
||||||
* key press. */
|
|
||||||
XKB_STATE_LAYOUT_LATCHED = (1 << 5),
|
|
||||||
/** Locked layout, i.e. will be unset after the key provoking the lock
|
|
||||||
* has been pressed again. */
|
|
||||||
XKB_STATE_LAYOUT_LOCKED = (1 << 6),
|
|
||||||
/** Effective layout, i.e. currently active and affects key processing
|
|
||||||
* (derived from the other state components).
|
|
||||||
* Use this unless you explicitly care how the state came about. */
|
|
||||||
XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7),
|
|
||||||
/** LEDs (derived from the other state components). */
|
|
||||||
XKB_STATE_LEDS = (1 << 8)
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Match flags for xkb_state_mod_indices_are_active() and
|
|
||||||
* xkb_state_mod_names_are_active(), specifying the conditions for a
|
|
||||||
* successful match. XKB_STATE_MATCH_NON_EXCLUSIVE is bitmaskable with
|
|
||||||
* the other modes.
|
|
||||||
*/
|
|
||||||
enum xkb_state_match {
|
|
||||||
/** Returns true if any of the modifiers are active. */
|
|
||||||
XKB_STATE_MATCH_ANY = (1 << 0),
|
|
||||||
/** Returns true if all of the modifiers are active. */
|
|
||||||
XKB_STATE_MATCH_ALL = (1 << 1),
|
|
||||||
/** Makes matching non-exclusive, i.e. will not return false if a
|
|
||||||
* modifier not specified in the arguments is active. */
|
|
||||||
XKB_STATE_MATCH_NON_EXCLUSIVE = (1 << 16)
|
|
||||||
};
|
|
||||||
|
|
||||||
enum xkb_consumed_mode {
|
|
||||||
/**
|
|
||||||
* This is the mode defined in the XKB specification and used by libX11.
|
|
||||||
*
|
|
||||||
* A modifier is consumed if and only if it *may affect* key translation.
|
|
||||||
*
|
|
||||||
* For example, if `Control+Alt+<Backspace>` produces some assigned keysym,
|
|
||||||
* then when pressing just `<Backspace>`, `Control` and `Alt` are consumed,
|
|
||||||
* even though they are not active, since if they *were* active they would
|
|
||||||
* have affected key translation.
|
|
||||||
*/
|
|
||||||
XKB_CONSUMED_MODE_XKB,
|
|
||||||
/**
|
|
||||||
* This is the mode used by the GTK+ toolkit.
|
|
||||||
*
|
|
||||||
* The mode consists of the following two independent heuristics:
|
|
||||||
*
|
|
||||||
* - The currently active set of modifiers, excluding modifiers which do
|
|
||||||
* not affect the key (as described for @ref XKB_CONSUMED_MODE_XKB), are
|
|
||||||
* considered consumed, if the keysyms produced when all of them are
|
|
||||||
* active are different from the keysyms produced when no modifiers are
|
|
||||||
* active.
|
|
||||||
*
|
|
||||||
* - A single modifier is considered consumed if the keysyms produced for
|
|
||||||
* the key when it is the only active modifier are different from the
|
|
||||||
* keysyms produced when no modifiers are active.
|
|
||||||
*/
|
|
||||||
XKB_CONSUMED_MODE_GTK
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FENNEC_PLATFORM_LINUX_XKB_LIB_FWD_H
|
|
||||||
@@ -44,7 +44,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fennec/platform/linux/xkb/lib/fwd.h>
|
|
||||||
|
|
||||||
#ifndef FENNEC_LIB
|
#ifndef FENNEC_LIB
|
||||||
#define FENNEC_LIB(...)
|
#define FENNEC_LIB(...)
|
||||||
@@ -60,82 +59,85 @@
|
|||||||
|
|
||||||
FENNEC_LIB(XKB);
|
FENNEC_LIB(XKB);
|
||||||
|
|
||||||
FENNEC_SYMBOL(int, xkb_keysym_get_name, xkb_keysym_t keysym, char *buffer, size_t size);
|
FENNEC_SYMBOL(int, xkb_keysym_get_name, xkb_keysym_t, char*, size_t);
|
||||||
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_from_name, const char *name, enum xkb_keysym_flags flags);
|
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_from_name, const char*, enum xkb_keysym_flags);
|
||||||
FENNEC_SYMBOL(int, xkb_keysym_to_utf8, xkb_keysym_t keysym, char *buffer, size_t size);
|
FENNEC_SYMBOL(int, xkb_keysym_to_utf8, xkb_keysym_t, char*, size_t);
|
||||||
FENNEC_SYMBOL(uint32_t, xkb_keysym_to_utf32, xkb_keysym_t keysym);
|
FENNEC_SYMBOL(uint32_t, xkb_keysym_to_utf32, xkb_keysym_t);
|
||||||
FENNEC_SYMBOL(xkb_keysym_t, xkb_utf32_to_keysym, uint32_t ucs);
|
FENNEC_SYMBOL(xkb_keysym_t, xkb_utf32_to_keysym, uint32_t);
|
||||||
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_upper, xkb_keysym_t ks);
|
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_upper, xkb_keysym_t);
|
||||||
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_lower, xkb_keysym_t ks);
|
FENNEC_SYMBOL(xkb_keysym_t, xkb_keysym_to_lower, xkb_keysym_t);
|
||||||
FENNEC_SYMBOL(struct xkb_context*, xkb_context_new, enum xkb_context_flags flags);
|
|
||||||
FENNEC_SYMBOL(struct xkb_context*, xkb_context_ref, struct xkb_context *context);
|
FENNEC_SYMBOL(struct xkb_context*, xkb_context_new, enum xkb_context_flags);
|
||||||
FENNEC_SYMBOL(void, xkb_context_unref, struct xkb_context *context);
|
FENNEC_SYMBOL(struct xkb_context*, xkb_context_ref, struct xkb_context*);
|
||||||
FENNEC_SYMBOL(void, xkb_context_set_user_data, struct xkb_context *context, void *user_data);
|
FENNEC_SYMBOL(void, xkb_context_unref, struct xkb_context*);
|
||||||
FENNEC_SYMBOL(void*, xkb_context_get_user_data, struct xkb_context *context);
|
FENNEC_SYMBOL(void, xkb_context_set_user_data, struct xkb_context*, void*);
|
||||||
FENNEC_SYMBOL(int, xkb_context_include_path_append, struct xkb_context *context, const char *path);
|
FENNEC_SYMBOL(void*, xkb_context_get_user_data, struct xkb_context*);
|
||||||
FENNEC_SYMBOL(int, xkb_context_include_path_append_default, struct xkb_context *context);
|
FENNEC_SYMBOL(int, xkb_context_include_path_append, struct xkb_context*, const char*);
|
||||||
FENNEC_SYMBOL(int, xkb_context_include_path_reset_defaults, struct xkb_context *context);
|
FENNEC_SYMBOL(int, xkb_context_include_path_append_default, struct xkb_context*);
|
||||||
FENNEC_SYMBOL(void, xkb_context_include_path_clear, struct xkb_context *context);
|
FENNEC_SYMBOL(int, xkb_context_include_path_reset_defaults, struct xkb_context*);
|
||||||
FENNEC_SYMBOL(unsigned int, xkb_context_num_include_paths, struct xkb_context *context);
|
FENNEC_SYMBOL(void, xkb_context_include_path_clear, struct xkb_context*);
|
||||||
FENNEC_SYMBOL(const char*, xkb_context_include_path_get, struct xkb_context *context, unsigned int index);
|
FENNEC_SYMBOL(unsigned int, xkb_context_num_include_paths, struct xkb_context*);
|
||||||
FENNEC_SYMBOL(void, xkb_context_set_log_level, struct xkb_context *context, enum xkb_log_level level);
|
FENNEC_SYMBOL(const char*, xkb_context_include_path_get, struct xkb_context*, unsigned int);
|
||||||
FENNEC_SYMBOL(enum xkb_log_level, xkb_context_get_log_level, struct xkb_context *context);
|
FENNEC_SYMBOL(void, xkb_context_set_log_level, struct xkb_context*, enum xkb_log_level);
|
||||||
FENNEC_SYMBOL(void, xkb_context_set_log_verbosity, struct xkb_context *context, int verbosity);
|
FENNEC_SYMBOL(enum xkb_log_level, xkb_context_get_log_level, struct xkb_context*);
|
||||||
FENNEC_SYMBOL(int, xkb_context_get_log_verbosity, struct xkb_context *context);
|
FENNEC_SYMBOL(void, xkb_context_set_log_verbosity, struct xkb_context*, int);
|
||||||
FENNEC_SYMBOL(void, xkb_context_set_log_fn, struct xkb_context *context, void (*log_fn)(struct xkb_context *context, enum xkb_log_level level, const char *format, va_list args));
|
FENNEC_SYMBOL(int, xkb_context_get_log_verbosity, struct xkb_context*);
|
||||||
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_names, struct xkb_context *context, const struct xkb_rule_names *names, enum xkb_keymap_compile_flags flags);
|
FENNEC_SYMBOL(void, xkb_context_set_log_fn, struct xkb_context*, void (*)(struct xkb_context*, enum xkb_log_level, const char*, va_list));
|
||||||
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_file, struct xkb_context *context, FILE *file, enum xkb_keymap_format format, enum xkb_keymap_compile_flags flags);
|
|
||||||
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_string, struct xkb_context *context, const char *string, enum xkb_keymap_format format, enum xkb_keymap_compile_flags flags);
|
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_names, struct xkb_context*, const struct xkb_rule_names*, enum xkb_keymap_compile_flags);
|
||||||
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_buffer, struct xkb_context *context, const char *buffer, size_t length, enum xkb_keymap_format format, enum xkb_keymap_compile_flags flags);
|
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_file, struct xkb_context*, FILE*, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
|
||||||
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_ref, struct xkb_keymap *keymap);
|
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_string, struct xkb_context*, const char*, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
|
||||||
FENNEC_SYMBOL(void, xkb_keymap_unref, struct xkb_keymap *keymap);
|
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_new_from_buffer, struct xkb_context*, const char*, size_t, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
|
||||||
FENNEC_SYMBOL(char*, xkb_keymap_get_as_string, struct xkb_keymap *keymap, enum xkb_keymap_format format);
|
FENNEC_SYMBOL(struct xkb_keymap*, xkb_keymap_ref, struct xkb_keymap*);
|
||||||
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_min_keycode, struct xkb_keymap *keymap);
|
FENNEC_SYMBOL(void, xkb_keymap_unref, struct xkb_keymap*);
|
||||||
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_max_keycode, struct xkb_keymap *keymap);
|
FENNEC_SYMBOL(char*, xkb_keymap_get_as_string, struct xkb_keymap*, enum xkb_keymap_format);
|
||||||
FENNEC_SYMBOL(void, xkb_keymap_key_for_each, struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter, void *data);
|
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_min_keycode, struct xkb_keymap*);
|
||||||
FENNEC_SYMBOL(const char*, xkb_keymap_key_get_name, struct xkb_keymap *keymap, xkb_keycode_t key);
|
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_max_keycode, struct xkb_keymap*);
|
||||||
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_key_by_name, struct xkb_keymap *keymap, const char *name);
|
FENNEC_SYMBOL(void, xkb_keymap_key_for_each, struct xkb_keymap*, xkb_keymap_key_iter_t, void*);
|
||||||
FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_num_mods, struct xkb_keymap *keymap);
|
FENNEC_SYMBOL(const char*, xkb_keymap_key_get_name, struct xkb_keymap*, xkb_keycode_t);
|
||||||
FENNEC_SYMBOL(const char*, xkb_keymap_mod_get_name, struct xkb_keymap *keymap, xkb_mod_index_t idx);
|
FENNEC_SYMBOL(xkb_keycode_t, xkb_keymap_key_by_name, struct xkb_keymap*, const char*);
|
||||||
FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_mod_get_index, struct xkb_keymap *keymap, const char *name);
|
FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_num_mods, struct xkb_keymap*);
|
||||||
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts, struct xkb_keymap *keymap);
|
FENNEC_SYMBOL(const char*, xkb_keymap_mod_get_name, struct xkb_keymap*, xkb_mod_index_t);
|
||||||
FENNEC_SYMBOL(const char*, xkb_keymap_layout_get_name, struct xkb_keymap *keymap, xkb_layout_index_t idx);
|
FENNEC_SYMBOL(xkb_mod_index_t, xkb_keymap_mod_get_index, struct xkb_keymap*, const char*);
|
||||||
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_layout_get_index, struct xkb_keymap *keymap, const char *name);
|
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts, struct xkb_keymap*);
|
||||||
FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_num_leds, struct xkb_keymap *keymap);
|
FENNEC_SYMBOL(const char*, xkb_keymap_layout_get_name, struct xkb_keymap*, xkb_layout_index_t);
|
||||||
FENNEC_SYMBOL(const char*, xkb_keymap_led_get_name, struct xkb_keymap *keymap, xkb_led_index_t idx);
|
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_layout_get_index, struct xkb_keymap*, const char*);
|
||||||
FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_led_get_index, struct xkb_keymap *keymap, const char *name);
|
FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_num_leds, struct xkb_keymap*);
|
||||||
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts_for_key, struct xkb_keymap *keymap, xkb_keycode_t key);
|
FENNEC_SYMBOL(const char*, xkb_keymap_led_get_name, struct xkb_keymap*, xkb_led_index_t);
|
||||||
FENNEC_SYMBOL(xkb_level_index_t, xkb_keymap_num_levels_for_key, struct xkb_keymap *keymap, xkb_keycode_t key, xkb_layout_index_t layout);
|
FENNEC_SYMBOL(xkb_led_index_t, xkb_keymap_led_get_index, struct xkb_keymap*, const char*);
|
||||||
FENNEC_SYMBOL(size_t, xkb_keymap_key_get_mods_for_level, struct xkb_keymap *keymap, xkb_keycode_t key, xkb_layout_index_t layout, xkb_level_index_t level, xkb_mod_mask_t *masks_out, size_t masks_size);
|
FENNEC_SYMBOL(xkb_layout_index_t, xkb_keymap_num_layouts_for_key, struct xkb_keymap*, xkb_keycode_t);
|
||||||
FENNEC_SYMBOL(int, xkb_keymap_key_get_syms_by_level, struct xkb_keymap *keymap, xkb_keycode_t key, xkb_layout_index_t layout, xkb_level_index_t level, const xkb_keysym_t **syms_out);
|
FENNEC_SYMBOL(xkb_level_index_t, xkb_keymap_num_levels_for_key, struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t);
|
||||||
FENNEC_SYMBOL(int, xkb_keymap_key_repeats, struct xkb_keymap *keymap, xkb_keycode_t key);
|
FENNEC_SYMBOL(size_t, xkb_keymap_key_get_mods_for_level, struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t, xkb_mod_mask_t*, size_t);
|
||||||
FENNEC_SYMBOL(struct xkb_state*, xkb_state_new, struct xkb_keymap *keymap);
|
FENNEC_SYMBOL(int, xkb_keymap_key_get_syms_by_level, struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t, const xkb_keysym_t**);
|
||||||
FENNEC_SYMBOL(struct xkb_state*, xkb_state_ref, struct xkb_state *state);
|
FENNEC_SYMBOL(int, xkb_keymap_key_repeats, struct xkb_keymap*, xkb_keycode_t);
|
||||||
FENNEC_SYMBOL(void, xkb_state_unref, struct xkb_state *state);
|
|
||||||
FENNEC_SYMBOL(struct xkb_keymap*, xkb_state_get_keymap, struct xkb_state *state);
|
FENNEC_SYMBOL(struct xkb_state*, xkb_state_new, struct xkb_keymap*);
|
||||||
FENNEC_SYMBOL(enum xkb_state_component, xkb_state_update_key, struct xkb_state *state, xkb_keycode_t key, enum xkb_key_direction direction);
|
FENNEC_SYMBOL(struct xkb_state*, xkb_state_ref, struct xkb_state*);
|
||||||
FENNEC_SYMBOL(enum xkb_state_component, xkb_state_update_mask, struct xkb_state *state, xkb_mod_mask_t depressed_mods, xkb_mod_mask_t latched_mods, xkb_mod_mask_t locked_mods, xkb_layout_index_t depressed_layout, xkb_layout_index_t latched_layout, xkb_layout_index_t locked_layout);
|
FENNEC_SYMBOL(void, xkb_state_unref, struct xkb_state*);
|
||||||
FENNEC_SYMBOL(int, xkb_state_key_get_syms, struct xkb_state *state, xkb_keycode_t key, const xkb_keysym_t **syms_out);
|
FENNEC_SYMBOL(struct xkb_keymap*, xkb_state_get_keymap, struct xkb_state*);
|
||||||
FENNEC_SYMBOL(int, xkb_state_key_get_utf8, struct xkb_state *state, xkb_keycode_t key, char *buffer, size_t size);
|
FENNEC_SYMBOL(enum xkb_state_component, xkb_state_update_key, struct xkb_state*, xkb_keycode_t, enum xkb_key_direction);
|
||||||
FENNEC_SYMBOL(uint32_t, xkb_state_key_get_utf32, struct xkb_state *state, xkb_keycode_t key);
|
FENNEC_SYMBOL(enum xkb_state_component, xkb_state_update_mask, struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
|
||||||
FENNEC_SYMBOL(xkb_keysym_t, xkb_state_key_get_one_sym, struct xkb_state *state, xkb_keycode_t key);
|
FENNEC_SYMBOL(int, xkb_state_key_get_syms, struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
|
||||||
FENNEC_SYMBOL(xkb_layout_index_t, xkb_state_key_get_layout, struct xkb_state *state, xkb_keycode_t key);
|
FENNEC_SYMBOL(int, xkb_state_key_get_utf8, struct xkb_state*, xkb_keycode_t, char*, size_t);
|
||||||
FENNEC_SYMBOL(xkb_level_index_t, xkb_state_key_get_level, struct xkb_state *state, xkb_keycode_t key, xkb_layout_index_t layout);
|
FENNEC_SYMBOL(uint32_t, xkb_state_key_get_utf32, struct xkb_state*, xkb_keycode_t);
|
||||||
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_serialize_mods, struct xkb_state *state, enum xkb_state_component components);
|
FENNEC_SYMBOL(xkb_keysym_t, xkb_state_key_get_one_sym, struct xkb_state*, xkb_keycode_t);
|
||||||
FENNEC_SYMBOL(xkb_layout_index_t, xkb_state_serialize_layout, struct xkb_state *state, enum xkb_state_component components);
|
FENNEC_SYMBOL(xkb_layout_index_t, xkb_state_key_get_layout, struct xkb_state*, xkb_keycode_t);
|
||||||
FENNEC_SYMBOL(int, xkb_state_mod_name_is_active, struct xkb_state *state, const char *name, enum xkb_state_component type);
|
FENNEC_SYMBOL(xkb_level_index_t, xkb_state_key_get_level, struct xkb_state*, xkb_keycode_t, xkb_layout_index_t);
|
||||||
FENNEC_SYMBOL(int, xkb_state_mod_names_are_active, struct xkb_state *state, enum xkb_state_component type, enum xkb_state_match match, ...);
|
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_serialize_mods, struct xkb_state*, enum xkb_state_component);
|
||||||
FENNEC_SYMBOL(int, xkb_state_mod_index_is_active, struct xkb_state *state, xkb_mod_index_t idx, enum xkb_state_component type);
|
FENNEC_SYMBOL(xkb_layout_index_t, xkb_state_serialize_layout, struct xkb_state*, enum xkb_state_component);
|
||||||
FENNEC_SYMBOL(int, xkb_state_mod_indices_are_active, struct xkb_state *state, enum xkb_state_component type, enum xkb_state_match match, ...);
|
FENNEC_SYMBOL(int, xkb_state_mod_name_is_active, struct xkb_state*, const char*, enum xkb_state_component);
|
||||||
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_key_get_consumed_mods2, struct xkb_state *state, xkb_keycode_t key, enum xkb_consumed_mode mode);
|
FENNEC_SYMBOL(int, xkb_state_mod_names_are_active, struct xkb_state*, enum xkb_state_component, enum xkb_state_match, ...);
|
||||||
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_key_get_consumed_mods, struct xkb_state *state, xkb_keycode_t key);
|
FENNEC_SYMBOL(int, xkb_state_mod_index_is_active, struct xkb_state*, xkb_mod_index_t, enum xkb_state_component);
|
||||||
FENNEC_SYMBOL(int, xkb_state_mod_index_is_consumed2, struct xkb_state *state, xkb_keycode_t key, xkb_mod_index_t idx, enum xkb_consumed_mode mode);
|
FENNEC_SYMBOL(int, xkb_state_mod_indices_are_active, struct xkb_state*, enum xkb_state_component, enum xkb_state_match, ...);
|
||||||
FENNEC_SYMBOL(int, xkb_state_mod_index_is_consumed, struct xkb_state *state, xkb_keycode_t key, xkb_mod_index_t idx);
|
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_key_get_consumed_mods2, struct xkb_state*, xkb_keycode_t, enum xkb_consumed_mode);
|
||||||
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_mod_mask_remove_consumed, struct xkb_state *state, xkb_keycode_t key, xkb_mod_mask_t mask);
|
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_key_get_consumed_mods, struct xkb_state*, xkb_keycode_t);
|
||||||
FENNEC_SYMBOL(int, xkb_state_layout_name_is_active, struct xkb_state *state, const char *name, enum xkb_state_component type);
|
FENNEC_SYMBOL(int, xkb_state_mod_index_is_consumed2, struct xkb_state*, xkb_keycode_t, xkb_mod_index_t, enum xkb_consumed_mode);
|
||||||
FENNEC_SYMBOL(int, xkb_state_layout_index_is_active, struct xkb_state *state, xkb_layout_index_t idx, enum xkb_state_component type);
|
FENNEC_SYMBOL(int, xkb_state_mod_index_is_consumed, struct xkb_state*, xkb_keycode_t, xkb_mod_index_t);
|
||||||
FENNEC_SYMBOL(int, xkb_state_led_name_is_active, struct xkb_state *state, const char *name);
|
FENNEC_SYMBOL(xkb_mod_mask_t, xkb_state_mod_mask_remove_consumed, struct xkb_state*, xkb_keycode_t, xkb_mod_mask_t);
|
||||||
FENNEC_SYMBOL(int, xkb_state_led_index_is_active, struct xkb_state *state, xkb_led_index_t idx);
|
FENNEC_SYMBOL(int, xkb_state_layout_name_is_active, struct xkb_state*, const char*, enum xkb_state_component);
|
||||||
|
FENNEC_SYMBOL(int, xkb_state_layout_index_is_active, struct xkb_state*, xkb_layout_index_t, enum xkb_state_component);
|
||||||
|
FENNEC_SYMBOL(int, xkb_state_led_name_is_active, struct xkb_state*, const char*);
|
||||||
|
FENNEC_SYMBOL(int, xkb_state_led_index_is_active, struct xkb_state*, xkb_led_index_t);
|
||||||
|
|
||||||
#undef FENNEC_LIB
|
#undef FENNEC_LIB
|
||||||
#undef FENNEC_SYMBOL
|
#undef FENNEC_SYMBOL
|
||||||
|
|||||||
110
include/fennec/platform/linux/xkb/lib/xkb.h
Normal file
110
include/fennec/platform/linux/xkb/lib/xkb.h
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_PLATFORM_LINUX_XKB_LIB_XKB_H
|
||||||
|
#define FENNEC_PLATFORM_LINUX_XKB_LIB_XKB_H
|
||||||
|
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
|
#define FENNEC_LIB(name) extern bool FENNEC_HAS_LIB_##name;
|
||||||
|
#define FENNEC_SYMBOL(ret, fn, ...) using XKB_sym_##fn = ret(*)(__VA_ARGS__); \
|
||||||
|
extern XKB_sym_##fn XKB_##fn;
|
||||||
|
#define FENNEC_GLOBAL(type, name) extern type* XKB_##name;
|
||||||
|
#include <fennec/platform/linux/xkb/lib/sym.h>
|
||||||
|
|
||||||
|
#define xkb_keysym_get_name XKB_xkb_keysym_get_name
|
||||||
|
#define xkb_keysym_from_name XKB_xkb_keysym_from_name
|
||||||
|
#define xkb_keysym_to_utf8 XKB_xkb_keysym_to_utf8
|
||||||
|
#define xkb_keysym_to_utf32 XKB_xkb_keysym_to_utf32
|
||||||
|
#define xkb_utf32_to_keysym XKB_xkb_utf32_to_keysym
|
||||||
|
#define xkb_keysym_to_upper XKB_xkb_keysym_to_upper
|
||||||
|
#define xkb_keysym_to_lower XKB_xkb_keysym_to_lower
|
||||||
|
|
||||||
|
#define xkb_context_new XKB_xkb_context_new
|
||||||
|
#define xkb_context_ref XKB_xkb_context_ref
|
||||||
|
#define xkb_context_unref XKB_xkb_context_unref
|
||||||
|
#define xkb_context_set_user_data XKB_xkb_context_set_user_data
|
||||||
|
#define xkb_context_get_user_data XKB_xkb_context_get_user_data
|
||||||
|
#define xkb_context_include_path_append XKB_xkb_context_include_path_append
|
||||||
|
#define xkb_context_include_path_append_default XKB_xkb_context_include_path_append_default
|
||||||
|
#define xkb_context_include_path_reset_defaults XKB_xkb_context_include_path_reset_defaults
|
||||||
|
#define xkb_context_include_path_clear XKB_xkb_context_include_path_clear
|
||||||
|
#define xkb_context_num_include_paths XKB_xkb_context_num_include_paths
|
||||||
|
#define xkb_context_include_path_get XKB_xkb_context_include_path_get
|
||||||
|
#define xkb_context_set_log_level XKB_xkb_context_set_log_level
|
||||||
|
#define xkb_context_get_log_level XKB_xkb_context_get_log_level
|
||||||
|
#define xkb_context_set_log_verbosity XKB_xkb_context_set_log_verbosity
|
||||||
|
#define xkb_context_get_log_verbosity XKB_xkb_context_get_log_verbosity
|
||||||
|
#define xkb_context_set_log_fn XKB_xkb_context_set_log_fn
|
||||||
|
|
||||||
|
#define xkb_keymap_new_from_names XKB_xkb_keymap_new_from_names
|
||||||
|
#define xkb_keymap_new_from_file XKB_xkb_keymap_new_from_file
|
||||||
|
#define xkb_keymap_new_from_string XKB_xkb_keymap_new_from_string
|
||||||
|
#define xkb_keymap_new_from_buffer XKB_xkb_keymap_new_from_buffer
|
||||||
|
#define xkb_keymap_ref XKB_xkb_keymap_ref
|
||||||
|
#define xkb_keymap_unref XKB_xkb_keymap_unref
|
||||||
|
#define xkb_keymap_get_as_string XKB_xkb_keymap_get_as_string
|
||||||
|
#define xkb_keymap_min_keycode XKB_xkb_keymap_min_keycode
|
||||||
|
#define xkb_keymap_max_keycode XKB_xkb_keymap_max_keycode
|
||||||
|
#define xkb_keymap_key_for_each XKB_xkb_keymap_key_for_each
|
||||||
|
#define xkb_keymap_key_get_name XKB_xkb_keymap_key_get_name
|
||||||
|
#define xkb_keymap_key_by_name XKB_xkb_keymap_key_by_name
|
||||||
|
#define xkb_keymap_num_mods XKB_xkb_keymap_num_mods
|
||||||
|
#define xkb_keymap_mod_get_name XKB_xkb_keymap_mod_get_name
|
||||||
|
#define xkb_keymap_mod_get_index XKB_xkb_keymap_mod_get_index
|
||||||
|
#define xkb_keymap_num_layouts XKB_xkb_keymap_num_layouts
|
||||||
|
#define xkb_keymap_layout_get_name XKB_xkb_keymap_layout_get_name
|
||||||
|
#define xkb_keymap_layout_get_index XKB_xkb_keymap_layout_get_index
|
||||||
|
#define xkb_keymap_num_leds XKB_xkb_keymap_num_leds
|
||||||
|
#define xkb_keymap_led_get_name XKB_xkb_keymap_led_get_name
|
||||||
|
#define xkb_keymap_led_get_index XKB_xkb_keymap_led_get_index
|
||||||
|
#define xkb_keymap_num_layouts_for_key XKB_xkb_keymap_num_layouts_for_key
|
||||||
|
#define xkb_keymap_num_levels_for_key XKB_xkb_keymap_num_levels_for_key
|
||||||
|
#define xkb_keymap_key_get_mods_for_level XKB_xkb_keymap_key_get_mods_for_level
|
||||||
|
#define xkb_keymap_key_get_syms_by_level XKB_xkb_keymap_key_get_syms_by_level
|
||||||
|
#define xkb_keymap_key_repeats XKB_xkb_keymap_key_repeats
|
||||||
|
|
||||||
|
#define xkb_state_new XKB_xkb_state_new
|
||||||
|
#define xkb_state_ref XKB_xkb_state_ref
|
||||||
|
#define xkb_state_unref XKB_xkb_state_unref
|
||||||
|
#define xkb_state_get_keymap XKB_xkb_state_get_keymap
|
||||||
|
#define xkb_state_update_key XKB_xkb_state_update_key
|
||||||
|
#define xkb_state_update_mask XKB_xkb_state_update_mask
|
||||||
|
#define xkb_state_key_get_syms XKB_xkb_state_key_get_syms
|
||||||
|
#define xkb_state_key_get_utf8 XKB_xkb_state_key_get_utf8
|
||||||
|
#define xkb_state_key_get_utf32 XKB_xkb_state_key_get_utf32
|
||||||
|
#define xkb_state_key_get_one_sym XKB_xkb_state_key_get_one_sym
|
||||||
|
#define xkb_state_key_get_layout XKB_xkb_state_key_get_layout
|
||||||
|
#define xkb_state_key_get_level XKB_xkb_state_key_get_level
|
||||||
|
#define xkb_state_serialize_mods XKB_xkb_state_serialize_mods
|
||||||
|
#define xkb_state_serialize_layout XKB_xkb_state_serialize_layout
|
||||||
|
#define xkb_state_mod_name_is_active XKB_xkb_state_mod_name_is_active
|
||||||
|
#define xkb_state_mod_names_are_active XKB_xkb_state_mod_names_are_active
|
||||||
|
#define xkb_state_mod_index_is_active XKB_xkb_state_mod_index_is_active
|
||||||
|
#define xkb_state_mod_indices_are_active XKB_xkb_state_mod_indices_are_active
|
||||||
|
#define xkb_state_key_get_consumed_mods2 XKB_xkb_state_key_get_consumed_mods2
|
||||||
|
#define xkb_state_key_get_consumed_mods XKB_xkb_state_key_get_consumed_mods
|
||||||
|
#define xkb_state_mod_index_is_consumed2 XKB_xkb_state_mod_index_is_consumed2
|
||||||
|
#define xkb_state_mod_index_is_consumed XKB_xkb_state_mod_index_is_consumed
|
||||||
|
#define xkb_state_mod_mask_remove_consumed XKB_xkb_state_mod_mask_remove_consumed
|
||||||
|
#define xkb_state_layout_name_is_active XKB_xkb_state_layout_name_is_active
|
||||||
|
#define xkb_state_layout_index_is_active XKB_xkb_state_layout_index_is_active
|
||||||
|
#define xkb_state_led_name_is_active XKB_xkb_state_led_name_is_active
|
||||||
|
#define xkb_state_led_index_is_active XKB_xkb_state_led_index_is_active
|
||||||
|
|
||||||
|
#endif // FENNEC_PLATFORM_LINUX_XKB_LIB_XKB_H
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2012 Intel Corporation
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _XKBCOMMON_NAMES_H
|
|
||||||
#define _XKBCOMMON_NAMES_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Predefined names for common modifiers and LEDs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define XKB_MOD_NAME_SHIFT "Shift"
|
|
||||||
#define XKB_MOD_NAME_CAPS "Lock"
|
|
||||||
#define XKB_MOD_NAME_CTRL "Control"
|
|
||||||
#define XKB_MOD_NAME_ALT "Mod1"
|
|
||||||
#define XKB_MOD_NAME_NUM "Mod2"
|
|
||||||
#define XKB_MOD_NAME_LOGO "Mod4"
|
|
||||||
|
|
||||||
#define XKB_LED_NAME_CAPS "Caps Lock"
|
|
||||||
#define XKB_LED_NAME_NUM "Num Lock"
|
|
||||||
#define XKB_LED_NAME_SCROLL "Scroll Lock"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,157 +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/>.
|
|
||||||
// =====================================================================================================================
|
|
||||||
|
|
||||||
#ifndef FENNEC_PLATFORM_LINUX_XKB_LIB_XKBCOMMON_H
|
|
||||||
#define FENNEC_PLATFORM_LINUX_XKB_LIB_XKBCOMMON_H
|
|
||||||
|
|
||||||
#define FENNEC_LIB(name) extern bool FENNEC_HAS_LIB_##name;
|
|
||||||
#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \
|
|
||||||
extern sym_##fn fn;
|
|
||||||
#define FENNEC_GLOBAL(type, name) extern type* name;
|
|
||||||
#include <fennec/platform/linux/xkb/lib/sym.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2009-2012 Daniel Stone
|
|
||||||
* Copyright © 2012 Intel Corporation
|
|
||||||
* Copyright © 2012 Ran Benita
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fennec/platform/linux/xkb/lib/xkbcommon-names.h>
|
|
||||||
#include <fennec/platform/linux/xkb/lib/xkbcommon-keysyms.h>
|
|
||||||
|
|
||||||
#define XKB_KEYCODE_INVALID (0xffffffff)
|
|
||||||
#define XKB_LAYOUT_INVALID (0xffffffff)
|
|
||||||
#define XKB_LEVEL_INVALID (0xffffffff)
|
|
||||||
#define XKB_MOD_INVALID (0xffffffff)
|
|
||||||
#define XKB_LED_INVALID (0xffffffff)
|
|
||||||
|
|
||||||
#define XKB_KEYCODE_MAX (0xffffffff - 1)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum keysym value
|
|
||||||
*
|
|
||||||
* @since 1.6.0
|
|
||||||
* @sa xkb_keysym_t
|
|
||||||
* @ingroup keysyms
|
|
||||||
*/
|
|
||||||
#define XKB_KEYSYM_MAX 0x1fffffff
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether a value is a valid extended keycode.
|
|
||||||
* @sa xkb_keycode_t
|
|
||||||
**/
|
|
||||||
#define xkb_keycode_is_legal_ext(key) (key <= XKB_KEYCODE_MAX)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether a value is a valid X11 keycode.
|
|
||||||
* @sa xkb_keycode_t
|
|
||||||
*/
|
|
||||||
#define xkb_keycode_is_legal_x11(key) (key >= 8 && key <= 255)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Names to compile a keymap with, also known as RMLVO.
|
|
||||||
*
|
|
||||||
* The names are the common configuration values by which a user picks
|
|
||||||
* a keymap.
|
|
||||||
*
|
|
||||||
* If the entire struct is NULL, then each field is taken to be NULL.
|
|
||||||
* You should prefer passing NULL instead of choosing your own defaults.
|
|
||||||
*/
|
|
||||||
struct xkb_rule_names {
|
|
||||||
/**
|
|
||||||
* The rules file to use. The rules file describes how to interpret
|
|
||||||
* the values of the model, layout, variant and options fields.
|
|
||||||
*
|
|
||||||
* If NULL or the empty string "", a default value is used.
|
|
||||||
* If the XKB_DEFAULT_RULES environment variable is set, it is used
|
|
||||||
* as the default. Otherwise the system default is used.
|
|
||||||
*/
|
|
||||||
const char *rules;
|
|
||||||
/**
|
|
||||||
* The keyboard model by which to interpret keycodes and LEDs.
|
|
||||||
*
|
|
||||||
* If NULL or the empty string "", a default value is used.
|
|
||||||
* If the XKB_DEFAULT_MODEL environment variable is set, it is used
|
|
||||||
* as the default. Otherwise the system default is used.
|
|
||||||
*/
|
|
||||||
const char *model;
|
|
||||||
/**
|
|
||||||
* A comma separated list of layouts (languages) to include in the
|
|
||||||
* keymap.
|
|
||||||
*
|
|
||||||
* If NULL or the empty string "", a default value is used.
|
|
||||||
* If the XKB_DEFAULT_LAYOUT environment variable is set, it is used
|
|
||||||
* as the default. Otherwise the system default is used.
|
|
||||||
*/
|
|
||||||
const char *layout;
|
|
||||||
/**
|
|
||||||
* A comma separated list of variants, one per layout, which may
|
|
||||||
* modify or augment the respective layout in various ways.
|
|
||||||
*
|
|
||||||
* Generally, should either be empty or have the same number of values
|
|
||||||
* as the number of layouts. You may use empty values as in "intl,,neo".
|
|
||||||
*
|
|
||||||
* If NULL or the empty string "", and a default value is also used
|
|
||||||
* for the layout, a default value is used. Otherwise no variant is
|
|
||||||
* used.
|
|
||||||
* If the XKB_DEFAULT_VARIANT environment variable is set, it is used
|
|
||||||
* as the default. Otherwise the system default is used.
|
|
||||||
*/
|
|
||||||
const char *variant;
|
|
||||||
/**
|
|
||||||
* A comma separated list of options, through which the user specifies
|
|
||||||
* non-layout related preferences, like which key combinations are used
|
|
||||||
* for switching layouts, or which key is the Compose key.
|
|
||||||
*
|
|
||||||
* If NULL, a default value is used. If the empty string "", no
|
|
||||||
* options are used.
|
|
||||||
* If the XKB_DEFAULT_OPTIONS environment variable is set, it is used
|
|
||||||
* as the default. Otherwise the system default is used.
|
|
||||||
*/
|
|
||||||
const char *options;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the keymap as a string in the format from which it was created.
|
|
||||||
* @sa xkb_keymap_get_as_string()
|
|
||||||
**/
|
|
||||||
#define XKB_KEYMAP_USE_ORIGINAL_FORMAT ((enum xkb_keymap_format) -1)
|
|
||||||
|
|
||||||
|
|
||||||
#endif // FENNEC_PLATFORM_LINUX_XKB_LIB_XKBCOMMON_H
|
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <fennec/platform/interface/gfxcontext.h>
|
#include <fennec/platform/interface/gfxcontext.h>
|
||||||
|
#include <fennec/platform/opengl/egl/fwd.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
@@ -34,12 +35,26 @@ public:
|
|||||||
bool connected() override;
|
bool connected() override;
|
||||||
int32_t get_version_major() override { return _eglvmajor; }
|
int32_t get_version_major() override { return _eglvmajor; }
|
||||||
int32_t get_version_minor() override { return _eglvminor; }
|
int32_t get_version_minor() override { return _eglvminor; }
|
||||||
int32_t get_context_version() override { return _eglctype; }
|
int32_t get_version() override { return _eglctype; }
|
||||||
const cstring& get_context_name() override;
|
const cstring& get_name() override;
|
||||||
bool check_extension(const cstring& ext) override;
|
bool check_extension(const cstring& ext) override;
|
||||||
|
|
||||||
|
gfxsurface* create_surface(window* window) override;
|
||||||
|
|
||||||
void make_current(gfxsurface* surface) override;
|
void make_current(gfxsurface* surface) override;
|
||||||
|
|
||||||
|
EGLDisplay get_egl_display() {
|
||||||
|
return _egldisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLDisplay get_egl_context() {
|
||||||
|
return _eglcontext;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLDisplay get_egl_config() {
|
||||||
|
return _eglconfig;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EGLDisplay _egldisplay;
|
EGLDisplay _egldisplay;
|
||||||
EGLContext _eglcontext;
|
EGLContext _eglcontext;
|
||||||
|
|||||||
@@ -16,7 +16,27 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
#ifndef FENNEC_CONCURRENCY_MUTEX_H
|
///
|
||||||
#define FENNEC_CONCURRENCY_MUTEX_H
|
/// \file fwd.h
|
||||||
|
/// \brief
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
#endif // FENNEC_CONCURRENCY_MUTEX_H
|
#ifndef FENNEC_PLATFORM_OPENGL_EGL_FWD_H
|
||||||
|
#define FENNEC_PLATFORM_OPENGL_EGL_FWD_H
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
class eglcontext;
|
||||||
|
class eglsurface;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_PLATFORM_OPENGL_EGL_FWD_H
|
||||||
60
include/fennec/platform/opengl/egl/surface.h
Normal file
60
include/fennec/platform/opengl/egl/surface.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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 surface.h
|
||||||
|
/// \brief
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
#ifndef FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
|
||||||
|
#define FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
|
||||||
|
|
||||||
|
#include <fennec/platform/interface/gfxsurface.h>
|
||||||
|
#include <fennec/platform/linux/wayland/window.h>
|
||||||
|
#include <fennec/platform/opengl/egl/context.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
class eglsurface : public gfxsurface {
|
||||||
|
public:
|
||||||
|
~eglsurface() override;
|
||||||
|
|
||||||
|
void resize(size_t width, size_t height) override;
|
||||||
|
|
||||||
|
eglsurface(eglcontext* context, window* window);
|
||||||
|
|
||||||
|
EGLSurface get_egl_surface() {
|
||||||
|
return _surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* _handle;
|
||||||
|
EGLSurface _surface;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
|
||||||
@@ -28,29 +28,30 @@ Library and Template Library.
|
|||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:-------------------------------------|:-----------:|:------:|
|
|:-------------------------------------|:-----------:|:------:|
|
||||||
| pair | ✔ | ✔ |
|
| map (`std::unordered_map`) | ✅ | ✅ |
|
||||||
| tuple | ⭕ | ⭕ |
|
| map_sequence (`std::map`) | ⛔ | ⛔ |
|
||||||
| optional | ✔ | ✔ |
|
| multiset (`std::unordered_multiset`) | ⛔ | ⛔ |
|
||||||
| variant | ❌ | ❌ |
|
| multisequence (`std::multiset`) | ⛔ | ⛔ |
|
||||||
| any | ❌ | ❌ |
|
| multimap (`std::unordered_multimap`) | ⛔ | ⛔ |
|
||||||
| bitset | ❌ | ❌ |
|
| multimap_sequence (`std::multimap`) | ⛔ | ⛔ |
|
||||||
| array | ✔ | ✔ |
|
| pair | ✅ | ✅ |
|
||||||
| dynarray (`std::vector`) | ⭕ | ⭕ |
|
| tuple | 🚧 | 🚧 |
|
||||||
| deque | ❌ | ❌ |
|
| optional | ✅ | ✅ |
|
||||||
| list | ✔ | ✔ |
|
| variant | ⛔ | ⛔ |
|
||||||
| set (`std::unordered_set`) | ✔ | ✔ |
|
| any | ⛔ | ⛔ |
|
||||||
| sequence (`std::set`) | ❌ | ❌ |
|
| bitset | ⛔ | ⛔ |
|
||||||
| map (`std::unordered_map`) | ✔ | ✔ |
|
| array | ✅ | ✅ |
|
||||||
| map_sequence (`std::map`) | ❌ | ❌ |
|
| dynarray (`std::vector`) | 🚧 | 🚧 |
|
||||||
| multiset (`std::unordered_multiset`) | ❌ | ❌ |
|
| deque | ⛔ | ⛔ |
|
||||||
| multisequence (`std::multiset`) | ❌ | ❌ |
|
| list | ✅ | ✅ |
|
||||||
| multimap (`std::unordered_multimap`) | ❌ | ❌ |
|
| set (`std::unordered_set`) | ✅ | ✅ |
|
||||||
| multimap_sequence (`std::multimap`) | ❌ | ❌ |
|
| sequence (`std::set`) | ⛔ | ⛔ |
|
||||||
|
|
||||||
|
|
||||||
### fennec
|
### fennec
|
||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:--------|:-----------:|:------:|
|
|:------------|:-----------:|:------:|
|
||||||
| graph | ❌ | ❌ |
|
| graph | 🚧 | 🚧 |
|
||||||
| rd_tree | ✔ | ✔ |
|
| object_pool | 🚧 | 🚧 |
|
||||||
|
| rd_tree | ✅ | ✅ |
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ configurability and programmability within those systems and their stages. This
|
|||||||
be achieved using events at different stages of those engines that are on-demand.
|
be achieved using events at different stages of those engines that are on-demand.
|
||||||
|
|
||||||
|
|
||||||
|
## External Libraries
|
||||||
|
|
||||||
|
* `cpptrace`
|
||||||
|
* Walking the stack and retrieving information about the code is *very* platform
|
||||||
|
dependent, and it makes little sense spending days writing a library that will
|
||||||
|
be less effective.
|
||||||
|
|
||||||
|
|
||||||
## Definitions
|
## Definitions
|
||||||
|
|
||||||
  Many subpages of these documents will contain tables that use symbols to
|
  Many subpages of these documents will contain tables that use symbols to
|
||||||
@@ -54,20 +62,15 @@ denote implementation and testing progress. The symbols are defined below.
|
|||||||
|
|
||||||
| Symbol | Meaning | Notes |
|
| Symbol | Meaning | Notes |
|
||||||
|:------:|:------------------------|:----------------------------------------------------------|
|
|:------:|:------------------------|:----------------------------------------------------------|
|
||||||
| ✔ | Completed | Complete implementation and all tests passing. |
|
| ✅ | Completed | Complete implementation and all tests passing. |
|
||||||
| ⭕ | Partial | Partial implementation and all tests implemented 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 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 |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Libraries
|
## Libraries
|
||||||
- [C++ Language Library](./CPP_LANGUAGE.md#c-language-library-lang)
|
- [C++ Language Library](./CPP_LANGUAGE.md#c-language-library-lang)
|
||||||
- [Platform Support Library](./PLATFORM_SUPPORT.md#platform--api-support)
|
- [Platform Support Library](./PLATFORM_SUPPORT.md#platform-support-library-platform)
|
||||||
|
- [Memory Library](./MEMORY.md#memory-library-memory)
|
||||||
|
- [Containers Library](./CONTAINERS.md#containers-library-containers)
|
||||||
|
- [Language Processing Library](./LANGUAGE_PROCESSING.md#language-processing-library-langproc)
|
||||||
@@ -42,82 +42,82 @@ See:
|
|||||||
### Diagnostics
|
### Diagnostics
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:--------|:-----------:|:------:|
|
|:--------|:-----------:|:------:|
|
||||||
| assert | ✔ | ✔ |
|
| assert | ✅ | ✅ |
|
||||||
| assertf | ✔ | ✔ |
|
| assertf | ✅ | ✅ |
|
||||||
| assertd | ✔ | ✔ |
|
| assertd | ✅ | ✅ |
|
||||||
|
|
||||||
### Utility
|
### Utility
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:-----------------|:-----------:|:------:|
|
|:-----------------|:-----------:|:------:|
|
||||||
| numeric_limits | ✔ | ✔ |
|
| numeric_limits | ✅ | ✅ |
|
||||||
| initializer_list | ❌ | ❌ |
|
| initializer_list | ⛔ | ⛔ |
|
||||||
|
|
||||||
### Primary Types
|
### Primary Types
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:---------------------------|:-----------:|:------:|
|
|:---------------------------|:-----------:|:------:|
|
||||||
| is_void | ✔ | ✔ |
|
| is_void | ✅ | ✅ |
|
||||||
| is_null_pointer | ✔ | ✔ |
|
| is_null_pointer | ✅ | ✅ |
|
||||||
| is_integral | ✔ | ✔ |
|
| is_integral | ✅ | ✅ |
|
||||||
| is_floating_point | ✔ | ✔ |
|
| is_floating_point | ✅ | ✅ |
|
||||||
| is_array | ✔ | ❓ |
|
| is_array | ✅ | 🚧 |
|
||||||
| is_enum | ❌ | ❌ |
|
| is_enum | ⛔ | ⛔ |
|
||||||
| is_union | ❌ | ❌ |
|
| is_union | ⛔ | ⛔ |
|
||||||
| is_class | ✔ | ✔ |
|
| is_class | ✅ | ✅ |
|
||||||
| is_function | ❌ | ❌ |
|
| is_function | ⛔ | ⛔ |
|
||||||
| is_pointer | ✔ | ✔ |
|
| is_pointer | ✅ | ✅ |
|
||||||
| is_lvalue_reference | ✔ | ✔ |
|
| is_lvalue_reference | ✅ | ✅ |
|
||||||
| is_rvalue_reference | ✔ | ✔ |
|
| is_rvalue_reference | ✅ | ✅ |
|
||||||
| is_member_object_pointer | ❌ | ❌ |
|
| is_member_object_pointer | ⛔ | ⛔ |
|
||||||
| is_member_function_pointer | ❌ | ❌ |
|
| is_member_function_pointer | ⛔ | ⛔ |
|
||||||
|
|
||||||
### Composite Types
|
### Composite Types
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:------------------|:-----------:|:------:|
|
|:------------------|:-----------:|:------:|
|
||||||
| is_fundamental | ✔ | ✔ |
|
| is_fundamental | ✅ | ✅ |
|
||||||
| is_arithmetic | ✔ | ✔ |
|
| is_arithmetic | ✅ | ✅ |
|
||||||
| is_scalar | ❌ | ❌ |
|
| is_scalar | ⛔ | ⛔ |
|
||||||
| is_object | ❌ | ❌ |
|
| is_object | ⛔ | ⛔ |
|
||||||
| is_compound | ❌ | ❌ |
|
| is_compound | ⛔ | ⛔ |
|
||||||
| is_reference | ❌ | ❌ |
|
| is_reference | ⛔ | ⛔ |
|
||||||
| is_member_pointer | ❌ | ❌ |
|
| is_member_pointer | ⛔ | ⛔ |
|
||||||
|
|
||||||
### Type Properties
|
### Type Properties
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:----------------------------------|:-----------:|:------:|
|
|:----------------------------------|:-----------:|:------:|
|
||||||
| is_const | ✔ | ✔ |
|
| is_const | ✅ | ✅ |
|
||||||
| is_volatile | ✔ | ✔ |
|
| is_volatile | ✅ | ✅ |
|
||||||
| is_trivially_copyable | ✔ | ✔ |
|
| is_trivially_copyable | ✅ | ✅ |
|
||||||
| is_standard_layout | ❌ | ❌ |
|
| is_standard_layout | ⛔ | ⛔ |
|
||||||
| has_unique_object_representations | ❌ | ❌ |
|
| has_unique_object_representations | ⛔ | ⛔ |
|
||||||
| is_empty | ❌ | ❌ |
|
| is_empty | ⛔ | ⛔ |
|
||||||
| is_polymorphic | ❌ | ❌ |
|
| is_polymorphic | ⛔ | ⛔ |
|
||||||
| is_abstract | ❌ | ❌ |
|
| is_abstract | ⛔ | ⛔ |
|
||||||
| is_final | ❌ | ❌ |
|
| is_final | ⛔ | ⛔ |
|
||||||
| is_aggregate | ❌ | ❌ |
|
| is_aggregate | ⛔ | ⛔ |
|
||||||
| is_implicit_lifetime | ❌ | ❌ |
|
| is_implicit_lifetime | ⛔ | ⛔ |
|
||||||
| is_signed | ✔ | ✔ |
|
| is_signed | ✅ | ✅ |
|
||||||
| is_unsigned | ✔ | ✔ |
|
| is_unsigned | ✅ | ✅ |
|
||||||
| is_bounded_array | ❌ | ❌ |
|
| is_bounded_array | ⛔ | ⛔ |
|
||||||
| is_unbounded_array | ❌ | ❌ |
|
| is_unbounded_array | ⛔ | ⛔ |
|
||||||
| is_scoped_enum | ❌ | ❌ |
|
| is_scoped_enum | ⛔ | ⛔ |
|
||||||
|
|
||||||
### Supported Operations
|
### Supported Operations
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:------------------------------------|:-----------:|:------:|
|
|:------------------------------------|:-----------:|:------:|
|
||||||
| is_constructible | ✔ | ✔ |
|
| is_constructible | ✅ | ✅ |
|
||||||
| is_trivially_constructible | ✔ | ✔ |
|
| is_trivially_constructible | ✅ | ✅ |
|
||||||
| is_nothrow_constructible | ❌ | ❌ |
|
| is_nothrow_constructible | ⛔ | ⛔ |
|
||||||
| is_default_constructible | ✔ | ✔ |
|
| is_default_constructible | ✅ | ✅ |
|
||||||
| is_trivially_default_constructible | ❌ | ❌ |
|
| is_trivially_default_constructible | ⛔ | ⛔ |
|
||||||
| is_nothrow_default_constructible | ❌ | ❌ |
|
| is_nothrow_default_constructible | ⛔ | ⛔ |
|
||||||
| is_copy_constructible | ✔ | ✔ |
|
| is_copy_constructible | ✅ | ✅ |
|
||||||
| is_trivially_copy_constructible | ❌ | ❌ |
|
| is_trivially_copy_constructible | ⛔ | ⛔ |
|
||||||
| is_nothrow_copy_constructible | ❌ | ❌ |
|
| is_nothrow_copy_constructible | ⛔ | ⛔ |
|
||||||
| is_move_constructible | ✔ | ✔ |
|
| is_move_constructible | ✅ | ✅ |
|
||||||
| is_trivially_move_constructible | ❌ | ❌ |
|
| is_trivially_move_constructible | ⛔ | ⛔ |
|
||||||
| is_nothrow_move_constructible | ❌ | ❌ |
|
| is_nothrow_move_constructible | ⛔ | ⛔ |
|
||||||
| is_destructible | ❌ | ❌ |
|
| is_destructible | ⛔ | ⛔ |
|
||||||
| is_trivially_destructible | ❌ | ❌ |
|
| is_trivially_destructible | ⛔ | ❌ |
|
||||||
| is_nothrow_destructible | ❌ | ❌ |
|
| is_nothrow_destructible | ❌ | ❌ |
|
||||||
| has_virtual_destructor | ❌ | ❌ |
|
| has_virtual_destructor | ❌ | ❌ |
|
||||||
| is_swappable | ❌ | ❌ |
|
| is_swappable | ❌ | ❌ |
|
||||||
@@ -137,10 +137,10 @@ See:
|
|||||||
### Type Relationships
|
### Type Relationships
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:------------------------------------|:-----------:|:------:|
|
|:------------------------------------|:-----------:|:------:|
|
||||||
| is_same | ✔ | ✔ |
|
| is_same | ✅ | ✅ |
|
||||||
| is_base_of | ❌ | ❌ |
|
| is_base_of | ❌ | ❌ |
|
||||||
| is_virtual_base_of | ❌ | ❌ |
|
| is_virtual_base_of | ❌ | ❌ |
|
||||||
| is_convertible | ✔ | ✔ |
|
| is_convertible | ✅ | ✅ |
|
||||||
| is_nothrow_convertible | ❌ | ❌ |
|
| is_nothrow_convertible | ❌ | ❌ |
|
||||||
| is_layout_compatible | ❌ | ❌ |
|
| is_layout_compatible | ❌ | ❌ |
|
||||||
| is_pointer_interconvertible_base_of | ❌ | ❌ |
|
| is_pointer_interconvertible_base_of | ❌ | ❌ |
|
||||||
@@ -152,19 +152,19 @@ See:
|
|||||||
### Type Transformations
|
### Type Transformations
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:---------------------|:-----------:|:------:|
|
|:---------------------|:-----------:|:------:|
|
||||||
| add_const | ✔ | ✔ |
|
| add_const | ✅ | ✅ |
|
||||||
| add_volatile | ✔ | ✔ |
|
| add_volatile | ✅ | ✅ |
|
||||||
| add_cv | ✔ | ✔ |
|
| add_cv | ✅ | ✅ |
|
||||||
| remove_const | ✔ | ✔ |
|
| remove_const | ✅ | ✅ |
|
||||||
| remove_volatile | ✔ | ✔ |
|
| remove_volatile | ✅ | ✅ |
|
||||||
| remove_cv | ✔ | ✔ |
|
| remove_cv | ✅ | ✅ |
|
||||||
| add_lvalue_reference | ✔ | ✔ |
|
| add_lvalue_reference | ✅ | ✅ |
|
||||||
| add_rvalue_reference | ✔ | ✔ |
|
| add_rvalue_reference | ✅ | ✅ |
|
||||||
| remove_reference | ✔ | ✔ |
|
| remove_reference | ✅ | ✅ |
|
||||||
| add_pointer | ✔ | ✔ |
|
| add_pointer | ✅ | ✅ |
|
||||||
| remove_pointer | ✔ | ✔ |
|
| remove_pointer | ✅ | ✅ |
|
||||||
| make_signed | ✔ | ✔ |
|
| make_signed | ✅ | ✅ |
|
||||||
| make_unsigned | ✔ | ✔ |
|
| make_unsigned | ✅ | ✅ |
|
||||||
| remove_extent | ❌ | ❌ |
|
| remove_extent | ❌ | ❌ |
|
||||||
| remove_all_extents | ❌ | ❌ |
|
| remove_all_extents | ❌ | ❌ |
|
||||||
|
|
||||||
@@ -174,17 +174,17 @@ See:
|
|||||||
| aligned_storage | ❌ | ❌ |
|
| aligned_storage | ❌ | ❌ |
|
||||||
| aligned_union | ❌ | ❌ |
|
| aligned_union | ❌ | ❌ |
|
||||||
| aligned_union | ❌ | ❌ |
|
| aligned_union | ❌ | ❌ |
|
||||||
| decay | ⭕ | ⭕ |
|
| decay | 🚧 | 🚧 |
|
||||||
| remove_cvref | ✔ | ✔ |
|
| remove_cvref | ✅ | ✅ |
|
||||||
| enable_if | ✔ | ✔ |
|
| enable_if | ✅ | ✅ |
|
||||||
| conditional | ✔ | ✔ |
|
| conditional | ✅ | ✅ |
|
||||||
| common_type | ❌ | ❌ |
|
| common_type | ❌ | ❌ |
|
||||||
| common_reference | ❌ | ❌ |
|
| common_reference | ❌ | ❌ |
|
||||||
| basic_common_reference | ❌ | ❌ |
|
| basic_common_reference | ❌ | ❌ |
|
||||||
| underlying_type | ❌ | ❌ |
|
| underlying_type | ❌ | ❌ |
|
||||||
| result_of | ❌ | ❌ |
|
| result_of | ❌ | ❌ |
|
||||||
| invoke_result | ❌ | ❌ |
|
| invoke_result | ❌ | ❌ |
|
||||||
| void_t | ✔ | ✔ |
|
| void_t | ✅ | ✅ |
|
||||||
|
|
||||||
### Logical Operations
|
### Logical Operations
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
@@ -196,9 +196,9 @@ See:
|
|||||||
### Sequences
|
### Sequences
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:-------------------------------------------------|:-----------:|:------:|
|
|:-------------------------------------------------|:-----------:|:------:|
|
||||||
| const_sequence | ✔ | ✔ |
|
| const_sequence | ✅ | ✅ |
|
||||||
| const_integer_sequence (`std::integer_sequence`) | ✔ | ✔ |
|
| const_integer_sequence (`std::integer_sequence`) | ✅ | ✅ |
|
||||||
| make_integer_sequence | ✔ | ✔ |
|
| make_integer_sequence | ✅ | ✅ |
|
||||||
| const_index_sequence (`std::index_sequence`) | ✔ | ✔ |
|
| const_index_sequence (`std::index_sequence`) | ✅ | ✅ |
|
||||||
| make_index_sequence | ✔ | ✔ |
|
| make_index_sequence | ✅ | ✅ |
|
||||||
| concat_sequence | ✔ | ✔ |
|
| concat_sequence | ✅ | ✅ |
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ highly performant on the right surface.
|
|||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:---------|:-----------:|:------:|
|
|:---------|:-----------:|:------:|
|
||||||
| cstring | ✔ | ✔ |
|
| cstring | ✅ | ✅ |
|
||||||
| string | ✔ | ✔ |
|
| string | ✅ | ✅ |
|
||||||
| wcstring | ✔ | ✔ |
|
| wcstring | ✅ | ✅ |
|
||||||
| wstring | ✔ | ✔ |
|
| wstring | ✅ | ✅ |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -53,18 +53,17 @@ is create C++ classes that handle file streams, directory streams, and file path
|
|||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:----------|:-----------:|:------:|
|
|:----------|:-----------:|:------:|
|
||||||
| path | ✔ | ✔ |
|
| path | ✅ | ✅ |
|
||||||
| file | ✔ | ✔ |
|
| file | ✅ | ✅ |
|
||||||
| directory | ❌ | ❌ |
|
| directory | ⛔ | ⛔ |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Interpreter (`langproc/interpret`)
|
## Interpreter (`langproc/parse`)
|
||||||
|
|
||||||
  This submodule will contain classes for interpreting data, particularly
|
  This submodule will contain classes for parsing data. We will need to be
|
||||||
through parsers. We will need to be able to do the following things to achieve
|
able to do the following things to achieve support for files that adhere to a
|
||||||
support for files that adhere to a certain specification. Here are some concepts
|
certain specification. Here are some concepts that will need to be implemented as classes:
|
||||||
that will need to be implemented as classes:
|
|
||||||
|
|
||||||
|
|
||||||
### Reading
|
### Reading
|
||||||
@@ -103,44 +102,44 @@ data values (e.g. floats, ints, etc.) to a readable language (e.g. ascii/utf8/ut
|
|||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:-------|:-----------:|:------:|
|
|:-------|:-----------:|:------:|
|
||||||
| JSON | ❌ | ❌ |
|
| JSON | ⛔ | ⛔ |
|
||||||
| HTML | ❌ | ❌ |
|
| HTML | ⛔ | ⛔ |
|
||||||
| XML | ❌ | ❌ |
|
| XML | ⛔ | ⛔ |
|
||||||
| YAML | ❌ | ❌ |
|
| YAML | ⛔ | ⛔ |
|
||||||
|
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:-------|:-----------:|:------:|
|
|:-------|:-----------:|:------:|
|
||||||
| INI | ❌ | ❌ |
|
| INI | ⛔ | ⛔ |
|
||||||
| TOML | ❌ | ❌ |
|
| TOML | ⛔ | ⛔ |
|
||||||
|
|
||||||
|
|
||||||
### Documents
|
### Documents
|
||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:---------|:-----------:|:------:|
|
|:---------|:-----------:|:------:|
|
||||||
| ODF | ❌ | ❌ |
|
| ODF | ⛔ | ⛔ |
|
||||||
| Markdown | ❌ | ❌ |
|
| Markdown | ⛔ | ⛔ |
|
||||||
| PDF | ❌ | ❌ |
|
| PDF | ⛔ | ⛔ |
|
||||||
|
|
||||||
|
|
||||||
### Spreadsheets & Tables
|
### Spreadsheets & Tables
|
||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:---------|:-----------:|:------:|
|
|:---------|:-----------:|:------:|
|
||||||
| ODS | ❌ | ❌ |
|
| ODS | ⛔ | ⛔ |
|
||||||
| CSV | ❌ | ❌ |
|
| CSV | ⛔ | ⛔ |
|
||||||
|
|
||||||
|
|
||||||
### Audio Formats
|
### Audio Formats
|
||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:---------|:-----------:|:------:|
|
|:---------|:-----------:|:------:|
|
||||||
| MP3 | ❌ | ❌ |
|
| MP3 | ⛔ | ⛔ |
|
||||||
| WAV | ❌ | ❌ |
|
| WAV | ⛔ | ⛔ |
|
||||||
| AAC | ❌ | ❌ |
|
| AAC | ⛔ | ⛔ |
|
||||||
|
|
||||||
|
|
||||||
### Graphics Formats
|
### Graphics Formats
|
||||||
@@ -149,20 +148,20 @@ data values (e.g. floats, ints, etc.) to a readable language (e.g. ascii/utf8/ut
|
|||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:-------|:-----------:|:------:|
|
|:-------|:-----------:|:------:|
|
||||||
| BMP | ❌ | ❌ |
|
| BMP | ⛔ | ⛔ |
|
||||||
| DDS | ❌ | ❌ |
|
| DDS | ⛔ | ⛔ |
|
||||||
| JPG | ❌ | ❌ |
|
| JPG | ⛔ | ⛔ |
|
||||||
| PNG | ❌ | ❌ |
|
| PNG | ⛔ | ⛔ |
|
||||||
| TIFF | ❌ | ❌ |
|
| TIFF | ⛔ | ⛔ |
|
||||||
|
|
||||||
|
|
||||||
#### Vector Graphics
|
#### Vector Graphics
|
||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:-------|:-----------:|:------:|
|
|:-------|:-----------:|:------:|
|
||||||
| OTF | ❌ | ❌ |
|
| OTF | ⛔ | ⛔ |
|
||||||
| SVG | ❌ | ❌ |
|
| SVG | ⛔ | ⛔ |
|
||||||
| TTF | ❌ | ❌ |
|
| TTF | ⛔ | ⛔ |
|
||||||
|
|
||||||
|
|
||||||
#### 3D Model Formats
|
#### 3D Model Formats
|
||||||
@@ -173,10 +172,10 @@ by assimp.
|
|||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:----------------|:-----------:|:------:|
|
|:----------------|:-----------:|:------:|
|
||||||
| 3D | ❌ | ❌ |
|
| 3D | ⛔ | ⛔ |
|
||||||
| 3DS | ❌ | ❌ |
|
| 3DS | ⛔ | ⛔ |
|
||||||
| 3MF | ❌ | ❌ |
|
| 3MF | ⛔ | ⛔ |
|
||||||
| AC | ❌ | ❌ |
|
| AC | ⛔ | ❌ |
|
||||||
| AC3D | ❌ | ❌ |
|
| AC3D | ❌ | ❌ |
|
||||||
| ACC | ❌ | ❌ |
|
| ACC | ❌ | ❌ |
|
||||||
| AMJ | ❌ | ❌ |
|
| AMJ | ❌ | ❌ |
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ C stdlib and either wraps them or aliases them.
|
|||||||
|
|
||||||
| Symbol | Implemented | Passed |
|
| Symbol | Implemented | Passed |
|
||||||
|:-----------------|:-----------:|:------:|
|
|:-----------------|:-----------:|:------:|
|
||||||
| allocator | ✔ | ✔ |
|
| allocator | ✅ | ✅ |
|
||||||
| allocator_traits | ✔ | ✔ |
|
| allocator_traits | ✅ | ✅ |
|
||||||
| allocation | ✔ | ✔ |
|
| allocation | ✅ | ✅ |
|
||||||
| default_delete | ✔ | ❓ |
|
| default_delete | ✅ | ❓ |
|
||||||
| unique_pointer | ✔ | ❓ |
|
| unique_pointer | ✅ | ❓ |
|
||||||
| shared_pointer | ❌ | ❌ |
|
| shared_pointer | ⛔ | ⛔ |
|
||||||
| pointer_traits | ❌ | ❌ |
|
| pointer_traits | ⛔ | ⛔ |
|
||||||
@@ -25,7 +25,7 @@ Drivers that must be initialized for the engine context.
|
|||||||
Platform Support will be implemented in the following order:
|
Platform Support will be implemented in the following order:
|
||||||
- Linux/BSD
|
- Linux/BSD
|
||||||
- Wayland
|
- Wayland
|
||||||
- OpenGL (EGL) ✔
|
- OpenGL (EGL) ✅
|
||||||
- XKB
|
- XKB
|
||||||
- PulseAudio
|
- PulseAudio
|
||||||
- Vulkan
|
- Vulkan
|
||||||
|
|||||||
@@ -138,8 +138,8 @@ file& file::operator=(file&& file) noexcept {
|
|||||||
_error = file._error;
|
_error = file._error;
|
||||||
|
|
||||||
file._handle = nullptr;
|
file._handle = nullptr;
|
||||||
file._path = "";
|
file._path = "";
|
||||||
file._error = nullptr;
|
file._error = nullptr;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ bool file::open(const string& p, uint8_t mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to open the file
|
// Attempt to open the file
|
||||||
_handle = fopen(p, fmode_translate(mode));
|
_handle = fopen(p.cstr(), fmode_translate(mode));
|
||||||
|
|
||||||
// Validate the file
|
// Validate the file
|
||||||
if (_handle == nullptr) {
|
if (_handle == nullptr) {
|
||||||
@@ -233,7 +233,7 @@ bool file::open(const path& p, uint8_t mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to open the file
|
// Attempt to open the file
|
||||||
_handle = fopen(p.str(), fmode_translate(mode));
|
_handle = fopen(p.cstr(), fmode_translate(mode));
|
||||||
|
|
||||||
// Validate the file
|
// Validate the file
|
||||||
if (_handle == nullptr) {
|
if (_handle == nullptr) {
|
||||||
@@ -313,7 +313,7 @@ bool file::erase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Erase the file
|
// Erase the file
|
||||||
remove(path.str());
|
remove(path.cstr());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -335,7 +335,7 @@ bool file::rename(const cstring& str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to open the new file
|
// Attempt to open the new file
|
||||||
FILE* fnew = fopen(fpath.str(), "wx");
|
FILE* fnew = fopen(fpath.cstr(), "wx");
|
||||||
|
|
||||||
// Check for open failure
|
// Check for open failure
|
||||||
if (fnew == nullptr) {
|
if (fnew == nullptr) {
|
||||||
@@ -395,7 +395,7 @@ bool file::rename(const cstring& str) {
|
|||||||
fclose(_handle);
|
fclose(_handle);
|
||||||
|
|
||||||
// Reopen the new file
|
// Reopen the new file
|
||||||
_handle = freopen(fpath.str(), fmode_translate(_mode), fnew);
|
_handle = freopen(fpath.cstr(), fmode_translate(_mode), fnew);
|
||||||
|
|
||||||
// Check for open failure
|
// Check for open failure
|
||||||
if (_handle == nullptr) {
|
if (_handle == nullptr) {
|
||||||
@@ -404,7 +404,7 @@ bool file::rename(const cstring& str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Erase the old file
|
// Erase the old file
|
||||||
remove(_path.str());
|
remove(_path.cstr());
|
||||||
|
|
||||||
// Set the new path
|
// Set the new path
|
||||||
_path = fpath;
|
_path = fpath;
|
||||||
@@ -429,7 +429,7 @@ bool file::rename(const string& str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to open the new file
|
// Attempt to open the new file
|
||||||
FILE* fnew = fopen(fpath.str(), "wx");
|
FILE* fnew = fopen(fpath.cstr(), "wx");
|
||||||
|
|
||||||
// Check for open failure
|
// Check for open failure
|
||||||
if (fnew == nullptr) {
|
if (fnew == nullptr) {
|
||||||
@@ -488,7 +488,7 @@ bool file::rename(const string& str) {
|
|||||||
fclose(_handle);
|
fclose(_handle);
|
||||||
|
|
||||||
// Reopen the new file
|
// Reopen the new file
|
||||||
_handle = freopen(_path.str(), fmode_translate(_mode), fnew);
|
_handle = freopen(_path.cstr(), fmode_translate(_mode), fnew);
|
||||||
|
|
||||||
// Check for open failure
|
// Check for open failure
|
||||||
if (_handle == nullptr) {
|
if (_handle == nullptr) {
|
||||||
@@ -518,7 +518,7 @@ bool file::rename(const path& p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to open the new file
|
// Attempt to open the new file
|
||||||
FILE* fnew = fopen(fpath.str(), "wx");
|
FILE* fnew = fopen(fpath.cstr(), "wx");
|
||||||
|
|
||||||
// Check for open failure
|
// Check for open failure
|
||||||
if (fnew == nullptr) {
|
if (fnew == nullptr) {
|
||||||
@@ -577,7 +577,7 @@ bool file::rename(const path& p) {
|
|||||||
fclose(_handle);
|
fclose(_handle);
|
||||||
|
|
||||||
// Reopen the new file
|
// Reopen the new file
|
||||||
_handle = freopen(_path.str(), fmode_translate(_mode), fnew);
|
_handle = freopen(_path.cstr(), fmode_translate(_mode), fnew);
|
||||||
|
|
||||||
// Check for open failure
|
// Check for open failure
|
||||||
if (_handle == nullptr) {
|
if (_handle == nullptr) {
|
||||||
@@ -608,7 +608,7 @@ file file::copy(const cstring& str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to open the new file
|
// Attempt to open the new file
|
||||||
FILE* fnew = fopen(fpath.str(), "wx");
|
FILE* fnew = fopen(fpath.cstr(), "wx");
|
||||||
|
|
||||||
// Check for open failure
|
// Check for open failure
|
||||||
if (fnew == nullptr) {
|
if (fnew == nullptr) {
|
||||||
@@ -698,7 +698,7 @@ file file::copy(const string& str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to open the new file
|
// Attempt to open the new file
|
||||||
FILE* fnew = fopen(fpath.str(), "wx");
|
FILE* fnew = fopen(fpath.cstr(), "wx");
|
||||||
|
|
||||||
// Check for open failure
|
// Check for open failure
|
||||||
if (fnew == nullptr) {
|
if (fnew == nullptr) {
|
||||||
@@ -789,7 +789,7 @@ file file::copy(const path& p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to open the new file
|
// Attempt to open the new file
|
||||||
FILE* fnew = fopen(fpath.str(), "wx");
|
FILE* fnew = fopen(fpath.cstr(), "wx");
|
||||||
|
|
||||||
// Check for open failure
|
// Check for open failure
|
||||||
if (fnew == nullptr) {
|
if (fnew == nullptr) {
|
||||||
@@ -989,7 +989,7 @@ wstring file::getwline() {
|
|||||||
|
|
||||||
// Check if there is a file
|
// Check if there is a file
|
||||||
if (_handle == nullptr) {
|
if (_handle == nullptr) {
|
||||||
return 0;
|
return _wstring{ L"" };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the next line;
|
// Read the next line;
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ path path::current() {
|
|||||||
path path::current() {
|
path path::current() {
|
||||||
char cstr[PATH_MAX];
|
char cstr[PATH_MAX];
|
||||||
if (getcwd(cstr, sizeof(cstr)) == nullptr) {
|
if (getcwd(cstr, sizeof(cstr)) == nullptr) {
|
||||||
return string("");
|
return path("");
|
||||||
}
|
}
|
||||||
return path(cstring(cstr, strlen(cstr) + 1));
|
return path(cstring(cstr, strlen(cstr) + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
path path::current(const path& path) {
|
path path::current(const path& path) {
|
||||||
if (chdir(path._str)) {
|
if (chdir(path._str.cstr())) {
|
||||||
return fennec::path("");
|
return fennec::path("");
|
||||||
}
|
}
|
||||||
return current();
|
return current();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ static constexpr void insert_driver(list<platform::driver<CtorT>>& drvrs, CtorT
|
|||||||
|
|
||||||
iter_t it = drvrs.begin();
|
iter_t it = drvrs.begin();
|
||||||
while (it != drvrs.end()) {
|
while (it != drvrs.end()) {
|
||||||
if (priority > it->priority) {
|
if (priority >= it->priority) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,11 @@
|
|||||||
|
|
||||||
#include <fennec/platform/linux/wayland/display.h>
|
#include <fennec/platform/linux/wayland/display.h>
|
||||||
#include <fennec/platform/linux/wayland/lib/loader.h>
|
#include <fennec/platform/linux/wayland/lib/loader.h>
|
||||||
#include <fennec/platform/linux/wayland/lib/wayland-client.h>
|
#include <fennec/platform/linux/wayland/lib/wayland.h>
|
||||||
|
|
||||||
#include <fennec/lang/startup.h>
|
#include <fennec/lang/startup.h>
|
||||||
|
#include <fennec/platform/linux/wayland/window.h>
|
||||||
|
#include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
@@ -42,7 +44,6 @@ wayland_display::wayland_display(platform* platform)
|
|||||||
, _handle(nullptr)
|
, _handle(nullptr)
|
||||||
, _registry(nullptr)
|
, _registry(nullptr)
|
||||||
, _compositor(nullptr)
|
, _compositor(nullptr)
|
||||||
, _shell(nullptr)
|
|
||||||
, _seat(nullptr)
|
, _seat(nullptr)
|
||||||
, _shm(nullptr)
|
, _shm(nullptr)
|
||||||
, _fifo(false) {
|
, _fifo(false) {
|
||||||
@@ -89,14 +90,13 @@ bool wayland_display::connected() const {
|
|||||||
return _handle != nullptr;
|
return _handle != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
window* wayland_display::create_window() {
|
window* wayland_display::create_window(window* parent) {
|
||||||
return nullptr;
|
return new wayland_window(this, static_cast<wayland_window*>(parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
void wayland_display::cleanup() {
|
void wayland_display::cleanup() {
|
||||||
|
|
||||||
// Cleanup members
|
// Cleanup members
|
||||||
if (_shell) wl_shell_destroy(_shell);
|
|
||||||
if (_compositor) wl_compositor_destroy(_compositor);
|
if (_compositor) wl_compositor_destroy(_compositor);
|
||||||
if (_registry) wl_registry_destroy(_registry);
|
if (_registry) wl_registry_destroy(_registry);
|
||||||
if (_handle) {
|
if (_handle) {
|
||||||
@@ -104,7 +104,6 @@ void wayland_display::cleanup() {
|
|||||||
wl_display_disconnect(_handle);
|
wl_display_disconnect(_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
_shell = nullptr;
|
|
||||||
_compositor = nullptr;
|
_compositor = nullptr;
|
||||||
_registry = nullptr;
|
_registry = nullptr;
|
||||||
_handle = nullptr;
|
_handle = nullptr;
|
||||||
@@ -121,11 +120,9 @@ void wayland_display::listen_global(void* data, wl_registry* registry, uint32_t
|
|||||||
const cstring interface = cstring(itfc, strlen(itfc) + 1);
|
const cstring interface = cstring(itfc, strlen(itfc) + 1);
|
||||||
|
|
||||||
if (interface == "wl_compositor") {
|
if (interface == "wl_compositor") {
|
||||||
device->_compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, name, wl_compositor_interface, version));
|
device->_compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, version));
|
||||||
} else if (interface == "wl_shell") {
|
|
||||||
device->_shell = static_cast<wl_shell*>(wl_registry_bind(registry, name, wl_shell_interface, version));
|
|
||||||
} else if (interface == "wl_seat") {
|
} else if (interface == "wl_seat") {
|
||||||
device->_seat = static_cast<wl_seat*>(wl_registry_bind(registry, name, wl_seat_interface, version));
|
device->_seat = static_cast<wl_seat*>(wl_registry_bind(registry, name, &wl_seat_interface, version));
|
||||||
wl_seat_add_listener(device->_seat, &seat_listener, device);
|
wl_seat_add_listener(device->_seat, &seat_listener, device);
|
||||||
} else if (interface == "wp_fifo_manager_v1") {
|
} else if (interface == "wp_fifo_manager_v1") {
|
||||||
device->_fifo = true;
|
device->_fifo = true;
|
||||||
|
|||||||
@@ -16,13 +16,13 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
#include <fennec/platform/linux/wayland/lib/wayland-client.h>
|
#include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
|
||||||
#include <fennec/platform/linux/wayland/lib/loader.h>
|
#include <fennec/platform/linux/wayland/lib/loader.h>
|
||||||
|
|
||||||
#define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name;
|
#define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name;
|
||||||
#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \
|
#define FENNEC_SYMBOL(ret, fn, ...) using WAYLAND_sym_##fn = ret(*)(__VA_ARGS__); \
|
||||||
sym_##fn fn;
|
WAYLAND_sym_##fn WAYLAND_##fn;
|
||||||
#define FENNEC_GLOBAL(type, name) type* name;
|
#define FENNEC_GLOBAL(type, name) type* WAYLAND_##name;
|
||||||
#include <fennec/platform/linux/wayland/lib/sym.h>
|
#include <fennec/platform/linux/wayland/lib/sym.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
@@ -57,10 +57,10 @@ bool load_symbols(platform* platform) {
|
|||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
current_lib = &_FENNEC_LIB_##lib;
|
current_lib = &_FENNEC_LIB_##lib;
|
||||||
#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \
|
#define FENNEC_SYMBOL(ret, fn, ...) WAYLAND_##fn = (WAYLAND_sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \
|
||||||
assertf(fn != nullptr, "Failed to find symbol: " #fn);
|
assertf(WAYLAND_##fn != nullptr, "Failed to find symbol: " #fn);
|
||||||
#define FENNEC_GLOBAL(type, name) name = (type*)(platform->find_symbol(current_lib->obj, #name)); \
|
#define FENNEC_GLOBAL(type, name) WAYLAND_##name = (type*)(platform->find_symbol(current_lib->obj, #name)); \
|
||||||
assertf(name != nullptr, "Failed to find global: " #name);
|
assertf(WAYLAND_##name != nullptr, "Failed to find global: " #name);
|
||||||
#include <fennec/platform/linux/wayland/lib/sym.h>
|
#include <fennec/platform/linux/wayland/lib/sym.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -74,9 +74,9 @@ void unload_symbols(platform* platform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \
|
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \
|
||||||
_FENNEC_LIB_##lib.obj = nullptr;
|
_FENNEC_LIB_##lib.obj = nullptr;
|
||||||
#define FENNEC_SYMBOL(ret, fn, ...) fn = nullptr;
|
#define FENNEC_SYMBOL(ret, fn, ...) WAYLAND_##fn = nullptr;
|
||||||
#define FENNEC_GLOBAL(type, name) name = nullptr;
|
#define FENNEC_GLOBAL(type, name) WAYLAND_##name = nullptr;
|
||||||
#include <fennec/platform/linux/wayland/lib/sym.h>
|
#include <fennec/platform/linux/wayland/lib/sym.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
139
source/platform/linux/wayland/window.cpp
Normal file
139
source/platform/linux/wayland/window.cpp
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#include <fennec/platform/interface/gfxcontext.h>
|
||||||
|
#include <fennec/platform/interface/gfxsurface.h>
|
||||||
|
|
||||||
|
#include <fennec/platform/linux/wayland/window.h>
|
||||||
|
#include <fennec/platform/linux/wayland/lib/wayland.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
bool wayland_window::running() {
|
||||||
|
return _surface != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wayland_window::configure(const config& config) {
|
||||||
|
_config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::initialize(bool) {
|
||||||
|
|
||||||
|
wayland_display* display = static_cast<wayland_display*>(_display);
|
||||||
|
|
||||||
|
_handle = wl_compositor_create_surface(display->get_compositor());
|
||||||
|
|
||||||
|
_surface = display->get_context()->create_surface(this);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::shutdown() {
|
||||||
|
delete _surface;
|
||||||
|
wl_surface_destroy(_handle);
|
||||||
|
_display = nullptr;
|
||||||
|
_surface = nullptr;
|
||||||
|
_shell = nullptr;
|
||||||
|
_handle = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::set_title(const cstring& title) {
|
||||||
|
if (not _config) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_config->title = title;
|
||||||
|
wl_shell_surface_set_title(_shell, _config->title.cstr());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::set_title(const string& title) {
|
||||||
|
if (not _config) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_config->title = title;
|
||||||
|
wl_shell_surface_set_title(_shell, _config->title.cstr());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::set_width(size_t w) {
|
||||||
|
if (not _config) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_config->width = w;
|
||||||
|
_surface->resize(_config->width, _config->height);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::set_height(size_t h) {
|
||||||
|
if (not _config) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_config->height = h;
|
||||||
|
_surface->resize(_config->width, _config->height);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::resize(size_t w, size_t h) {
|
||||||
|
if (not _config) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_config->width = w;
|
||||||
|
_config->height = h;
|
||||||
|
_surface->resize(_config->width, _config->height);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::set_resizable(bool) {
|
||||||
|
return false; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::set_fullscreen_mode(fullscreen_mode) {
|
||||||
|
return false; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::grab_keyboard(bool) {
|
||||||
|
return false; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::grab_mouse(bool) {
|
||||||
|
return false; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wayland_window::block_screensaver(bool) {
|
||||||
|
return false; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
wayland_window::wayland_window(wayland_display* display, wayland_window* parent)
|
||||||
|
: window(display, parent, this)
|
||||||
|
, _handle()
|
||||||
|
, _shell()
|
||||||
|
, _nfs_width(0), _nfs_height(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
wayland_window::~wayland_window() {
|
||||||
|
wayland_window::shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,16 +16,16 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
#define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name;
|
#include <fennec/platform/linux/xkb/lib/xkb.h>
|
||||||
#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \
|
|
||||||
sym_##fn fn;
|
|
||||||
#define FENNEC_GLOBAL(type, name) type* name;
|
|
||||||
#include <fennec/platform/linux/xkb/lib/sym.h>
|
|
||||||
|
|
||||||
#include <fennec/platform/linux/xkb/lib/xkbcommon.h>
|
|
||||||
#include <fennec/platform/linux/xkb/lib/loader.h>
|
#include <fennec/platform/linux/xkb/lib/loader.h>
|
||||||
#include <fennec/platform/interface/platform.h>
|
#include <fennec/platform/interface/platform.h>
|
||||||
|
|
||||||
|
#define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name;
|
||||||
|
#define FENNEC_SYMBOL(ret, fn, ...) using XKB_sym_##fn = ret(*)(__VA_ARGS__); \
|
||||||
|
XKB_sym_##fn XKB_##fn;
|
||||||
|
#define FENNEC_GLOBAL(type, name) type* XKB_##name;
|
||||||
|
#include <fennec/platform/linux/xkb/lib/sym.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -58,10 +58,10 @@ bool load_symbols(platform* platform) {
|
|||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
current_lib = &_FENNEC_LIB_##lib;
|
current_lib = &_FENNEC_LIB_##lib;
|
||||||
#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \
|
#define FENNEC_SYMBOL(ret, fn, ...) XKB_##fn = (XKB_sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \
|
||||||
assertf(fn != nullptr, "Failed to find symbol: " #fn);
|
assertf(XKB_##fn != nullptr, "Failed to find symbol: " #fn);
|
||||||
#define FENNEC_GLOBAL(type, name) name = (type*)(platform->find_symbol(current_lib->obj, #name)); \
|
#define FENNEC_GLOBAL(type, name) XKB_##name = (type*)(platform->find_symbol(current_lib->obj, #name)); \
|
||||||
assertf(name != nullptr, "Failed to find global: " #name);
|
assertf(XKB_##name != nullptr, "Failed to find global: " #name);
|
||||||
#include <fennec/platform/linux/xkb/lib/sym.h>
|
#include <fennec/platform/linux/xkb/lib/sym.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -76,8 +76,8 @@ void unload_symbols(platform* platform) {
|
|||||||
|
|
||||||
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \
|
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \
|
||||||
_FENNEC_LIB_##lib.obj = nullptr;
|
_FENNEC_LIB_##lib.obj = nullptr;
|
||||||
#define FENNEC_SYMBOL(ret, fn, ...) fn = nullptr;
|
#define FENNEC_SYMBOL(ret, fn, ...) XKB_##fn = nullptr;
|
||||||
#define FENNEC_GLOBAL(type, name) name = nullptr;
|
#define FENNEC_GLOBAL(type, name) XKB_##name = nullptr;
|
||||||
#include <fennec/platform/linux/xkb/lib/sym.h>
|
#include <fennec/platform/linux/xkb/lib/sym.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <fennec/platform/interface/display.h>
|
#include <fennec/platform/interface/display.h>
|
||||||
#include <fennec/platform/interface/platform.h>
|
#include <fennec/platform/interface/platform.h>
|
||||||
#include <fennec/platform/opengl/egl/context.h>
|
#include <fennec/platform/opengl/egl/context.h>
|
||||||
|
#include <fennec/platform/opengl/egl/surface.h>
|
||||||
|
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
|
||||||
@@ -40,7 +41,10 @@ STATIC_CONSTRUCTOR(_egl_init) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
eglcontext::eglcontext(display* display)
|
eglcontext::eglcontext(display* display)
|
||||||
: gfxcontext(display, "EGL", this) {
|
: gfxcontext(display, "EGL", this)
|
||||||
|
, _egldisplay(nullptr), _eglcontext(nullptr)
|
||||||
|
, _eglconfig(), _eglvmajor(0), _eglvminor(0)
|
||||||
|
, _eglctype(0), _extensions(nullptr) {
|
||||||
|
|
||||||
// Get the display format
|
// Get the display format
|
||||||
const display::pixel_format& fmt = _display->get_color_format();
|
const display::pixel_format& fmt = _display->get_color_format();
|
||||||
@@ -121,7 +125,7 @@ bool eglcontext::connected() {
|
|||||||
return _eglcontext != nullptr;
|
return _eglcontext != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cstring& eglcontext::get_context_name() {
|
const cstring& eglcontext::get_name() {
|
||||||
static constexpr cstring opengl = "OpenGL";
|
static constexpr cstring opengl = "OpenGL";
|
||||||
static constexpr cstring gles = "GLES";
|
static constexpr cstring gles = "GLES";
|
||||||
static constexpr cstring openvg = "OpenVG"; // this should never be used
|
static constexpr cstring openvg = "OpenVG"; // this should never be used
|
||||||
@@ -137,8 +141,13 @@ bool eglcontext::check_extension(const cstring& ext) {
|
|||||||
return _extensions.find(ext) != _extensions.size();
|
return _extensions.find(ext) != _extensions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void eglcontext::make_current(gfxsurface*) {
|
gfxsurface* eglcontext::create_surface(window* window) {
|
||||||
|
return new eglsurface(this, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void eglcontext::make_current(gfxsurface* surface) {
|
||||||
|
eglsurface* eglsurface = static_cast<fennec::eglsurface*>(surface);
|
||||||
|
eglMakeCurrent(_egldisplay, eglsurface->get_egl_surface(), eglsurface->get_egl_surface(), _eglcontext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eglcontext::cleanup() {
|
void eglcontext::cleanup() {
|
||||||
|
|||||||
66
source/platform/opengl/egl/surface.cpp
Normal file
66
source/platform/opengl/egl/surface.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#include <fennec/platform/opengl/egl/surface.h>
|
||||||
|
#include <fennec/platform/linux/wayland/lib/wayland.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
eglsurface::~eglsurface() {
|
||||||
|
if (_window->is_type<wayland_window>()) {
|
||||||
|
wl_egl_window_destroy(static_cast<wl_egl_window*>(_handle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void eglsurface::resize(size_t width, size_t height) {
|
||||||
|
gfxsurface::resize(width, height);
|
||||||
|
if (_window->is_type<wayland_window>()) {
|
||||||
|
wl_egl_window_resize(static_cast<wl_egl_window*>(_handle), width, height, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eglsurface::eglsurface(eglcontext* context, window* window)
|
||||||
|
: gfxsurface(context, window, this)
|
||||||
|
, _handle(nullptr)
|
||||||
|
, _surface(nullptr) {
|
||||||
|
|
||||||
|
const window::config& config = window->get_config();
|
||||||
|
if (window->is_type<wayland_window>()) {
|
||||||
|
_handle = wl_egl_window_create(window->get_native_handle(), config.width, config.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(
|
||||||
|
_handle != nullptr,
|
||||||
|
"Failed to create egl window!"
|
||||||
|
);
|
||||||
|
|
||||||
|
eglCreateWindowSurface(
|
||||||
|
context->get_egl_display(),
|
||||||
|
context->get_egl_config(),
|
||||||
|
reinterpret_cast<EGLNativeWindowType>(_handle),
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
EGL_TRUE == eglMakeCurrent(context->get_egl_display(), _surface, _surface, context->get_egl_context()),
|
||||||
|
"Failed to create egl window!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -38,10 +38,10 @@ void unix_platform::unload_object(shared_object* obj) {
|
|||||||
|
|
||||||
platform::symbol unix_platform::find_symbol(shared_object* obj, const cstring& name) {
|
platform::symbol unix_platform::find_symbol(shared_object* obj, const cstring& name) {
|
||||||
string _name = name;
|
string _name = name;
|
||||||
void* symbol = dlsym(obj, _name);
|
void* symbol = dlsym(obj, _name.cstr());
|
||||||
if (symbol == nullptr) {
|
if (symbol == nullptr) {
|
||||||
_name = '_' + _name;
|
_name = '_' + _name;
|
||||||
symbol = dlsym(obj, _name);
|
symbol = dlsym(obj, _name.cstr());
|
||||||
}
|
}
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|||||||
16
test.sh
16
test.sh
@@ -38,10 +38,10 @@ Help()
|
|||||||
Debug()
|
Debug()
|
||||||
{
|
{
|
||||||
mkdir -p build/debug
|
mkdir -p build/debug
|
||||||
cd ./build/debug
|
cd ./build/debug || exit
|
||||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -S ../.. -B .
|
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -S ../.. -B .
|
||||||
cmake --build . --target fennec-test
|
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
|
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind.txt ./fennec-test
|
||||||
cd ../..
|
cd ../..
|
||||||
}
|
}
|
||||||
@@ -49,10 +49,10 @@ Debug()
|
|||||||
Release()
|
Release()
|
||||||
{
|
{
|
||||||
mkdir -p build/release
|
mkdir -p build/release
|
||||||
cd ./build/release
|
cd ./build/release || exit
|
||||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S ../.. -B .
|
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S ../.. -B .
|
||||||
cmake --build . --target fennec-test
|
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
|
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind.txt ./fennec-test
|
||||||
cd ../..
|
cd ../..
|
||||||
}
|
}
|
||||||
@@ -60,10 +60,10 @@ Release()
|
|||||||
RelWithDebInfo()
|
RelWithDebInfo()
|
||||||
{
|
{
|
||||||
mkdir -p build/relwithdebinfo
|
mkdir -p build/relwithdebinfo
|
||||||
cd ./build/relwithdebinfo
|
cd ./build/relwithdebinfo || exit
|
||||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -S ../.. -B .
|
cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -S ../.. -B .
|
||||||
cmake --build . --target fennec-test
|
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
|
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind.txt ./fennec-test
|
||||||
cd ../..
|
cd ../..
|
||||||
}
|
}
|
||||||
@@ -71,10 +71,10 @@ RelWithDebInfo()
|
|||||||
MinSizeRel()
|
MinSizeRel()
|
||||||
{
|
{
|
||||||
mkdir -p build/minsizerel
|
mkdir -p build/minsizerel
|
||||||
cd ./build/minsizerel
|
cd ./build/minsizerel || exit
|
||||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel -S ../.. -B .
|
cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel -S ../.. -B .
|
||||||
cmake --build . --target fennec-test
|
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
|
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind.txt ./fennec-test
|
||||||
cd ../..
|
cd ../..
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ set(CMAKE_C_STANDARD 23)
|
|||||||
|
|
||||||
add_executable(fennec-test
|
add_executable(fennec-test
|
||||||
main.cpp
|
main.cpp
|
||||||
|
tests/containers/performance/test_iterator_visitor.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(fennec-test PUBLIC FENNEC_TEST_CWD="${CMAKE_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME}"
|
target_compile_definitions(fennec-test PUBLIC FENNEC_TEST_CWD="${CMAKE_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME}"
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "tests/test_lang.h"
|
#include "tests/test_lang.h"
|
||||||
#include "tests/test_math.h"
|
#include "tests/test_math.h"
|
||||||
#include "tests/test_memory.h"
|
#include "tests/test_memory.h"
|
||||||
@@ -27,7 +25,6 @@
|
|||||||
#include "tests/test_langproc.h"
|
#include "tests/test_langproc.h"
|
||||||
#include "tests/test_platform.h"
|
#include "tests/test_platform.h"
|
||||||
|
|
||||||
|
|
||||||
int main(int, char **)
|
int main(int, char **)
|
||||||
{
|
{
|
||||||
srand(0);
|
srand(0);
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ inline std::ostream& operator<<(std::ostream& os, const quaternion<ScalarT>& q)
|
|||||||
|
|
||||||
// Helper for printing strings
|
// Helper for printing strings
|
||||||
inline std::ostream& operator<<(std::ostream& os, const cstring& str) {
|
inline std::ostream& operator<<(std::ostream& os, const cstring& str) {
|
||||||
return os << *str;
|
return os << str.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for printing strings
|
// Helper for printing strings
|
||||||
inline std::ostream& operator<<(std::ostream& os, const string& str) {
|
inline std::ostream& operator<<(std::ostream& os, const string& str) {
|
||||||
return os << *str;
|
return os << str.cstr();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for printing strings
|
// Helper for printing strings
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
|
|
||||||
#ifndef FENNEC_CONCURRENCY_ATOMIC_H
|
#ifndef FENNEC_TEST_CONTAINERS_PERFORMANCE_ITERATOR_VISITOR_H
|
||||||
#define FENNEC_CONCURRENCY_ATOMIC_H
|
#define FENNEC_TEST_CONTAINERS_PERFORMANCE_ITERATOR_VISITOR_H
|
||||||
|
|
||||||
#endif // FENNEC_CONCURRENCY_ATOMIC_H
|
#endif // FENNEC_TEST_CONTAINERS_PERFORMANCE_ITERATOR_VISITOR_H
|
||||||
@@ -55,6 +55,11 @@ inline void fennec_test_containers_rdtree() {
|
|||||||
|
|
||||||
fennec_test_spacer(1);
|
fennec_test_spacer(1);
|
||||||
|
|
||||||
|
test.traverse<tree_t::pre_order>([](size_t i, size_t n) -> uint8_t {
|
||||||
|
assertf(i + 1 == n, "Tree Traverse Test Failed");
|
||||||
|
return traversal_control_continue;
|
||||||
|
});
|
||||||
|
|
||||||
test.erase(0);
|
test.erase(0);
|
||||||
|
|
||||||
fennec_test_run(test.empty(), true);
|
fennec_test_run(test.empty(), true);
|
||||||
|
|||||||
@@ -34,13 +34,33 @@ inline void fennec_test_platform() {
|
|||||||
platform* instance = platform::instance();
|
platform* instance = platform::instance();
|
||||||
instance->initialize();
|
instance->initialize();
|
||||||
|
|
||||||
fennec_test_run(instance->get_display() != nullptr, true);
|
display* display = instance->get_display();
|
||||||
fennec_test_run(instance->get_display()->get_context() != nullptr, true);
|
|
||||||
|
|
||||||
std::cout << instance->get_display()->get_context()->get_context_name() << " ";
|
fennec_test_run(display != nullptr, true);
|
||||||
std::cout << instance->get_display()->get_context()->get_version_major() << ".";
|
fennec_test_run(display->get_context() != nullptr, true);
|
||||||
std::cout << instance->get_display()->get_context()->get_version_minor() << std::endl;
|
|
||||||
|
|
||||||
|
gfxcontext* gfxcontext = display->get_context();
|
||||||
|
|
||||||
|
std::cout << gfxcontext->get_name() << " ";
|
||||||
|
std::cout << gfxcontext->get_version_major() << ".";
|
||||||
|
std::cout << gfxcontext->get_version_minor() << std::endl;
|
||||||
|
|
||||||
|
window::config winconfig = {
|
||||||
|
string{"fennec_test_platform"},
|
||||||
|
window::flags_none,
|
||||||
|
1280, 720,
|
||||||
|
window::fullscreen_mode::windowed
|
||||||
|
};
|
||||||
|
window* window = display->create_window(nullptr);
|
||||||
|
|
||||||
|
fennec_test_run(window != nullptr, true);
|
||||||
|
|
||||||
|
window->configure(winconfig);
|
||||||
|
window->initialize(false);
|
||||||
|
|
||||||
|
fennec_test_run(window->running(), true);
|
||||||
|
|
||||||
|
delete window;
|
||||||
instance->shutdown();
|
instance->shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user