-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Motivation
With gcc
15 and clang
20 now being released, which implement a lot of cool C++23 features, I think we can finally consider going for C++23. This isn't strictly required, but gives us access to a several nice features that have been added to the standard. We'll also make sure that we stay somewhat modern with our codebase.
Description
First step would be changine the required standard to 23 in our CMakeLists.txt:
Lines 37 to 38 in 865bd54
set(CMAKE_CXX_STANDARD 20) | |
set(CMAKE_CXX_STANDARD_REQUIRED ON) |
Theoretically our code should already be compatible. We don't use any of the removed features and there are not that many breaking changes. We would have to see how that turns out in practice though. There might also be a few new compiler warnings that we should fix. There might also be runtime issues.
We will also have to update our compiler and CMake dependencies. These ultimately depend on what C++23 features we want, but for a start we need a minimum of:
- gcc 11
- clang 12 (or 13?)
- CMake 3.20
Ideas
Here's a (probably) list of things that have been added in C++23 and are interesting for us. We should probably spawn issues from these once we have added general C++23 support.
flat_map
/flat_set
C++23 now supports ordered maps and sets that are optimized for fast access and small storage, while sacrificing some insertion/erasure speed. We don't have many uses for ordered maps, but they are used for the storage of some variables in the activity system in the game simulation, e.g. conditions for the XOR gateways (since these must be ordered). Since these maps also don't change much after initialization, they should be the perfect candidate for flat_map
.
More info on flat_map
/flat_set
: https://www.sandordargo.com/blog/2022/10/05/cpp23-flat_map
Cleaner error handling with std::expected
For performance reasons and generally cleaner code, we already prefer a design that doesn't rely on throwing and catching exceptions, since handling those scenarios is pretty expensive. In some cases, we can't get around that though, usually for I/O operations and interfacing with external libraries. std::expected
would allow us to encapsulate these situations a bit better. The idea behind it is similar to Rust's Result types. Instead of throwing an error, you return an object that either contains a valid result or an error. If it's an error, you can check for that and handle it accordingly.
A good starting point would probably be the AssetManager
code that handled missing assets. Currently that requires a try-catch block which is a not really nice. We can also think about using std::expected
in nyan to make game data handling more robust.
constexpr
/consteval
constexpr
and consteval
can be used in more situations with C++23, which might give us more opportunities for compile time optimization. There's also if consteval
now that can be used for evaluating branches at compile time. This could be useful for our templated code.
use C++ modules (especially std
module)
std
is now a module which we can add with import
. Using std
as a module could lead to faster build which is always nice. It could also lead to much reduced code complexity as a bonus. In the future, we could also define our own modules for our subcomponents, but that's not really on the agenda right now.
Format strings and <print>
instead of streams
C++23 finally let's developers use a print function like a normal human being. Also formatting has been improved a lot, so we can probably replace a bunch of string/output streams with proper formatting types.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status