diff --git a/.clang-format b/.clang-format
index ffd5aa94..8e0b146b 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,98 +1,8 @@
-AccessModifierOffset: -2
-AlignAfterOpenBracket: DontAlign
-AlignConsecutiveAssignments: false
-AlignConsecutiveDeclarations: false
-AlignEscapedNewlines: Left
-AlignOperands: true
-AlignTrailingComments: false
-AllowAllParametersOfDeclarationOnNextLine: false
-AllowShortBlocksOnASingleLine: true
-AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: All
-AllowShortIfStatementsOnASingleLine: true
-AllowShortLoopsOnASingleLine: true
-AlwaysBreakAfterDefinitionReturnType: None
-AlwaysBreakAfterReturnType: None
-AlwaysBreakBeforeMultilineStrings: true
-AlwaysBreakTemplateDeclarations: false
-BinPackArguments: false
-BinPackParameters: false
-BraceWrapping:
- AfterClass: true
- AfterControlStatement: false
- AfterEnum: false
- AfterFunction: true
- AfterNamespace: false
- AfterObjCDeclaration: false
- AfterStruct: true
- AfterUnion: false
- BeforeCatch: false
- BeforeElse: false
- IndentBraces: false
- SplitEmptyFunction: false
- SplitEmptyNamespace: true
- SplitEmptyRecord: true
-BreakAfterJavaFieldAnnotations: true
-BreakBeforeBinaryOperators: NonAssignment
-BreakBeforeBraces: Custom
-BreakBeforeInheritanceComma: true
-BreakBeforeTernaryOperators: true
-BreakConstructorInitializers: BeforeColon
-BreakConstructorInitializersBeforeComma: false
-BreakStringLiterals: true
-ColumnLimit: 120
-CommentPragmas: '^ IWYU pragma:'
-CompactNamespaces: false
-ConstructorInitializerAllOnOneLineOrOnePerLine: false
-ConstructorInitializerIndentWidth: 2
-ContinuationIndentWidth: 2
-Cpp11BracedListStyle: false
-DerivePointerAlignment: false
-DisableFormat: false
-ExperimentalAutoDetectBinPacking: true
-FixNamespaceComments: true
-ForEachMacros:
-- foreach
-- Q_FOREACH
-- BOOST_FOREACH
-IncludeCategories:
-- Priority: 2
- Regex: ^"(llvm|llvm-c|clang|clang-c)/
-- Priority: 3
- Regex: ^(<|"(gtest|gmock|isl|json)/)
-- Priority: 1
- Regex: .*
-IncludeIsMainRegex: (Test)?$
-IndentCaseLabels: false
-IndentWidth: 2
-IndentWrappedFunctionNames: true
-JavaScriptQuotes: Leave
-JavaScriptWrapImports: true
-KeepEmptyLinesAtTheStartOfBlocks: true
+BasedOnStyle: Google
+IndentWidth: 4
+AccessModifierOffset: -4
Language: Cpp
-MacroBlockBegin: ''
-MacroBlockEnd: ''
-MaxEmptyLinesToKeep: 2
-NamespaceIndentation: Inner
-ObjCBlockIndentWidth: 7
-ObjCSpaceAfterProperty: true
-ObjCSpaceBeforeProtocolList: false
-PointerAlignment: Right
-ReflowComments: true
-SortIncludes: true
-SortUsingDeclarations: false
-SpaceAfterCStyleCast: false
-SpaceAfterTemplateKeyword: false
-SpaceBeforeAssignmentOperators: true
-SpaceBeforeParens: ControlStatements
-SpaceInEmptyParentheses: false
-SpacesBeforeTrailingComments: 0
-SpacesInAngles: false
-SpacesInCStyleCastParentheses: false
-SpacesInContainerLiterals: true
-SpacesInParentheses: false
-SpacesInSquareBrackets: false
Standard: c++20
-TabWidth: 8
+TabWidth: 4
UseTab: Never
diff --git a/.clang-tidy b/.clang-tidy
index cdfaf8b2..c7cce2a4 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,30 +1,25 @@
---
Checks: "*,
- -abseil-*,
- -altera-*,
- -android-*,
- -fuchsia-*,
- -google-*,
- -llvm*,
- -modernize-use-trailing-return-type,
- -zircon-*,
- -readability-else-after-return,
- -readability-static-accessed-through-instance,
- -readability-avoid-const-params-in-decls,
- -cppcoreguidelines-non-private-member-variables-in-classes,
- -misc-non-private-member-variables-in-classes,
-"
-WarningsAsErrors: ''
-HeaderFilterRegex: ''
-FormatStyle: none
+ -abseil-*,
+ -altera-*,
+ -android-*,
+ -fuchsia-*,
+ -google-*,
+ -llvm*,
+ -modernize-use-trailing-return-type,
+ -zircon-*,
+ -readability-else-after-return,
+ -readability-static-accessed-through-instance,
+ -readability-avoid-const-params-in-decls,
+ -cppcoreguidelines-non-private-member-variables-in-classes,
+ -misc-non-private-member-variables-in-classes"
+
+WarningsAsErrors: ""
+HeaderFilterRegex: ""
+FormatStyle: none
CheckOptions:
- key: readability-identifier-length.IgnoredVariableNames
- value: 'x|y|z'
+ value: "x|y|z"
- key: readability-identifier-length.IgnoredParameterNames
- value: 'x|y|z'
-
-
-
-
-
+ value: "x|y|z"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 45e19f03..614ddb95 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.21)
# manual dependency management
# Only set the cxx_standard if it is not set by someone else
-if (NOT DEFINED CMAKE_CXX_STANDARD)
+if(NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 20)
endif()
@@ -25,7 +25,6 @@ project(
include(cmake/PreventInSourceBuilds.cmake)
include(ProjectOptions.cmake)
-
myproject_setup_options()
myproject_global_options()
@@ -73,10 +72,9 @@ if(BUILD_TESTING)
add_subdirectory(test)
endif()
-
if(myproject_BUILD_FUZZ_TESTS)
message(AUTHOR_WARNING "Building Fuzz Tests, using fuzzing sanitizer https://www.llvm.org/docs/LibFuzzer.html")
- if (NOT myproject_ENABLE_ADDRESS_SANITIZER AND NOT myproject_ENABLE_THREAD_SANITIZER)
+ if(NOT myproject_ENABLE_ADDRESS_SANITIZER AND NOT myproject_ENABLE_THREAD_SANITIZER)
message(WARNING "You need asan or tsan enabled for meaningful fuzz testing")
endif()
add_subdirectory(fuzz_test)
@@ -92,7 +90,7 @@ if(MSVC)
endif()
# set the startup project for the "play" button in MSVC
-set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT intro)
+set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT app)
if(CMAKE_SKIP_INSTALL_RULES)
return()
@@ -104,7 +102,7 @@ include(cmake/PackageProject.cmake)
# we know we want to ship
myproject_package_project(
TARGETS
- intro
+ app
myproject_options
myproject_warnings
# FIXME: this does not work! CK
diff --git a/Dependencies.cmake b/Dependencies.cmake
index a84378d2..00ab4f90 100644
--- a/Dependencies.cmake
+++ b/Dependencies.cmake
@@ -32,12 +32,17 @@ function(myproject_setup_dependencies)
cpmaddpackage("gh:CLIUtils/CLI11@2.3.2")
endif()
- if(NOT TARGET ftxui::screen)
- cpmaddpackage("gh:ArthurSonzogni/FTXUI#e23dbc7473654024852ede60e2121276c5aab660")
- endif()
-
- if(NOT TARGET tools::tools)
- cpmaddpackage("gh:lefticus/tools#update_build_system")
+ if(NOT TARGET Eigen3::Eigen)
+ cpmaddpackage(
+ GITLAB_REPOSITORY
+ "libeigen/eigen"
+ GIT_TAG
+ "3.4.0"
+ OPTIONS
+ "EIGEN_BUILD_DOC NO"
+ "EIGEN_LEAVE_TEST_IN_ALL_TARGET YES"
+ "BUILD_TESTING NO"
+ "EIGEN_BUILD_PKGCONFIG NO")
endif()
endfunction()
diff --git a/README.md b/README.md
index bc766ae4..75578629 100644
--- a/README.md
+++ b/README.md
@@ -7,10 +7,7 @@
## About cmake_template
-**NOTE** This is undergoing a major overhaul on a new branch currently.
-
-
-This is a C++ Best Practices GitHub template for getting up and running with C++ quickly.
+This is a C++ Best Practices GitHub template fork for getting up and running with C++ quickly.
By default (collectively known as `ENABLE_DEVELOPER_MODE`)
diff --git a/README_building.md b/README_building.md
deleted file mode 100644
index 99ceacfc..00000000
--- a/README_building.md
+++ /dev/null
@@ -1,192 +0,0 @@
-## Build Instructions
-
-A full build has different steps:
-1) Specifying the compiler using environment variables
-2) Configuring the project
-3) Building the project
-
-For the subsequent builds, in case you change the source code, you only need to repeat the last step.
-
-### (1) Specify the compiler using environment variables
-
-By default (if you don't set environment variables `CC` and `CXX`), the system default compiler will be used.
-
-CMake uses the environment variables CC and CXX to decide which compiler to use. So to avoid the conflict issues only specify the compilers using these variables.
-
-
-
-Commands for setting the compilers
-
-- Debian/Ubuntu/MacOS:
-
- Set your desired compiler (`clang`, `gcc`, etc):
-
- - Temporarily (only for the current shell)
-
- Run one of the followings in the terminal:
-
- - clang
-
- CC=clang CXX=clang++
-
- - gcc
-
- CC=gcc CXX=g++
-
- - Permanent:
-
- Open `~/.bashrc` using your text editor:
-
- gedit ~/.bashrc
-
- Add `CC` and `CXX` to point to the compilers:
-
- export CC=clang
- export CXX=clang++
-
- Save and close the file.
-
-- Windows:
-
- - Permanent:
-
- Run one of the followings in PowerShell:
-
- - Visual Studio generator and compiler (cl)
-
- [Environment]::SetEnvironmentVariable("CC", "cl.exe", "User")
- [Environment]::SetEnvironmentVariable("CXX", "cl.exe", "User")
- refreshenv
-
- Set the architecture using [vcvarsall](https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=vs-2019#vcvarsall-syntax):
-
- vcvarsall.bat x64
-
- - clang
-
- [Environment]::SetEnvironmentVariable("CC", "clang.exe", "User")
- [Environment]::SetEnvironmentVariable("CXX", "clang++.exe", "User")
- refreshenv
-
- - gcc
-
- [Environment]::SetEnvironmentVariable("CC", "gcc.exe", "User")
- [Environment]::SetEnvironmentVariable("CXX", "g++.exe", "User")
- refreshenv
-
-
- - Temporarily (only for the current shell):
-
- $Env:CC="clang.exe"
- $Env:CXX="clang++.exe"
-
-
-
-### (2) Configure your build
-
-To configure the project, you could use `cmake`, or `ccmake` or `cmake-gui`. Each of them are explained in the following:
-
-#### (2.a) Configuring via cmake:
-With Cmake directly:
-
- cmake -S . -B ./build
-
-Cmake will automatically create the `./build` folder if it does not exist, and it wil configure the project.
-
-Instead, if you have CMake version 3.21+, you can use one of the configuration presets that are listed in the CmakePresets.json file.
-
- cmake . --preset
- cmake --build
-
-#### (2.b) Configuring via ccmake:
-
-With the Cmake Curses Dialog Command Line tool:
-
- ccmake -S . -B ./build
-
-Once `ccmake` has finished setting up, press 'c' to configure the project,
-press 'g' to generate, and 'q' to quit.
-
-#### (2.c) Configuring via cmake-gui:
-
-To use the GUI of the cmake:
-
-2.c.1) Open cmake-gui from the project directory:
-```
-cmake-gui .
-```
-2.c.2) Set the build directory:
-
-![build_dir](https://user-images.githubusercontent.com/16418197/82524586-fa48e380-9af4-11ea-8514-4e18a063d8eb.jpg)
-
-2.c.3) Configure the generator:
-
-In cmake-gui, from the upper menu select `Tools/Configure`.
-
-**Warning**: if you have set `CC` and `CXX` always choose the `use default native compilers` option. This picks `CC` and `CXX`. Don't change the compiler at this stage!
-
-
-Windows - MinGW Makefiles
-
-Choose MinGW Makefiles as the generator:
-
-
-
-
-
-
-Windows - Visual Studio generator and compiler
-
-You should have already set `C` and `CXX` to `cl.exe`.
-
-Choose "Visual Studio 16 2019" as the generator:
-
-
-
-
-
-
-
-Windows - Visual Studio generator and Clang Compiler
-
-You should have already set `C` and `CXX` to `clang.exe` and `clang++.exe`.
-
-Choose "Visual Studio 16 2019" as the generator. To tell Visual studio to use `clang-cl.exe`:
-- If you use the LLVM that is shipped with Visual Studio: write `ClangCl` under "optional toolset to use".
-
-
-
-- If you use an external LLVM: write [`LLVM_v142`](https://github.com/zufuliu/llvm-utils#llvm-for-visual-studio-2017-and-2019)
- under "optional toolset to use".
-
-
-
-
-
-
-2.c.4) Choose the Cmake options and then generate:
-
-![generate](https://user-images.githubusercontent.com/16418197/82781591-c97feb80-9e1f-11ea-86c8-f2748b96f516.png)
-
-### (3) Build the project
-Once you have selected all the options you would like to use, you can build the
-project (all targets):
-
- cmake --build ./build
-
-For Visual Studio, give the build configuration (Release, RelWithDeb, Debug, etc) like the following:
-
- cmake --build ./build -- /p:configuration=Release
-
-
-### Running the tests
-
-You can use the `ctest` command run the tests.
-
-```shell
-cd ./build
-ctest -C Debug
-cd ../
-```
-
-
diff --git a/README_dependencies.md b/README_dependencies.md
deleted file mode 100644
index 42e4dab0..00000000
--- a/README_dependencies.md
+++ /dev/null
@@ -1,192 +0,0 @@
-## Dependencies
-
-Note about install commands:
-- for Windows, we use [choco](https://chocolatey.org/install).
-- for MacOS, we use [brew](https://brew.sh/).
-- In case of an error in cmake, make sure that the dependencies are on the PATH.
-
-
-### Too Long, Didn't Install
-
-This is a really long list of dependencies, and it's easy to mess up. That's why:
-
-#### Docker
-We have a Docker image that's already set up for you. See the [Docker instructions](#docker-instructions).
-
-#### Setup-cpp
-
-We have [setup-cpp](https://github.com/aminya/setup-cpp) that is a cross-platform tool to install all the compilers and dependencies on the system.
-
-Please check [the setup-cpp documentation](https://github.com/aminya/setup-cpp) for more information.
-
-For example, on Windows, you can run the following to install llvm, cmake, ninja, ccache, and cppcheck.
-```ps1
-# windows example (open shell as admin)
-curl -LJO "https://github.com/aminya/setup-cpp/releases/download/v0.5.7/setup_cpp_windows.exe"
-./setup_cpp_windows --compiler llvm --cmake true --ninja true --ccache true --cppcheck true
-
-RefreshEnv.cmd # reload the environment
-```
-
-### Necessary Dependencies
-1. A C++ compiler that supports C++17.
-See [cppreference.com](https://en.cppreference.com/w/cpp/compiler_support)
-to see which features are supported by each compiler.
-The following compilers should work:
-
- * [gcc 7+](https://gcc.gnu.org/)
-
- Install command
-
- - Debian/Ubuntu:
-
- sudo apt install build-essential
-
- - Windows:
-
- choco install mingw -y
-
- - MacOS:
-
- brew install gcc
-
-
- * [clang 6+](https://clang.llvm.org/)
-
- Install command
-
- - Debian/Ubuntu:
-
- bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
-
- - Windows:
-
- Visual Studio 2019 ships with LLVM (see the Visual Studio section). However, to install LLVM separately:
-
- choco install llvm -y
-
- llvm-utils for using external LLVM with Visual Studio generator:
-
- git clone https://github.com/zufuliu/llvm-utils.git
- cd llvm-utils/VS2017
- .\install.bat
-
- - MacOS:
-
- brew install llvm
-
-
- * [Visual Studio 2019 or higher](https://visualstudio.microsoft.com/)
-
- Install command + Environment setup
-
- On Windows, you need to install Visual Studio 2019 because of the SDK and libraries that ship with it.
-
- Visual Studio IDE - 2019 Community (installs Clang too):
-
- choco install -y visualstudio2019community --package-parameters "add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --includeOptional --passive --locale en-US"
-
- Put MSVC compiler, Clang compiler, and vcvarsall.bat on the path:
-
- choco install vswhere -y
- refreshenv
-
- # change to x86 for 32bit
- $clpath = vswhere -products * -latest -prerelease -find **/Hostx64/x64/*
- $clangpath = vswhere -products * -latest -prerelease -find **/Llvm/bin/*
- $vcvarsallpath = vswhere -products * -latest -prerelease -find **/Auxiliary/Build/*
-
- $path = [System.Environment]::GetEnvironmentVariable("PATH", "User")
- [Environment]::SetEnvironmentVariable("Path", $path + ";$clpath" + ";$clangpath" + ";$vcvarsallpath", "User")
- refreshenv
-
-
-
-
-2. [CMake 3.15+](https://cmake.org/)
-
- Install Command
-
- - Debian/Ubuntu:
-
- sudo apt-get install cmake
-
- - Windows:
-
- choco install cmake -y
-
- - MacOS:
-
- brew install cmake
-
-
-
-### Optional Dependencies
-#### C++ Tools
- * [Doxygen](http://doxygen.nl/)
-
- Install Command
-
- - Debian/Ubuntu:
-
- sudo apt-get install doxygen
- sudo apt-get install graphviz
-
- - Windows:
-
- choco install doxygen.install -y
- choco install graphviz -y
-
- - MacOS:
-
- brew install doxygen
- brew install graphviz
-
-
-
-
- * [ccache](https://ccache.dev/)
-
- Install Command
-
- - Debian/Ubuntu:
-
- sudo apt-get install ccache
-
- - Windows:
-
- choco install ccache -y
-
- - MacOS:
-
- brew install ccache
-
-
-
-
- * [Cppcheck](http://cppcheck.sourceforge.net/)
-
- Install Command
-
- - Debian/Ubuntu:
-
- sudo apt-get install cppcheck
-
- - Windows:
-
- choco install cppcheck -y
-
- - MacOS:
-
- brew install cppcheck
-
-
-
-
- * [include-what-you-use](https://include-what-you-use.org/)
-
- Install Command
-
- Follow instructions here:
- https://github.com/include-what-you-use/include-what-you-use#how-to-install
-
diff --git a/README_docker.md b/README_docker.md
deleted file mode 100644
index b1f5bf52..00000000
--- a/README_docker.md
+++ /dev/null
@@ -1,71 +0,0 @@
-## Docker Instructions
-
-If you have [Docker](https://www.docker.com/) installed, you can run this
-in your terminal, when the Dockerfile is inside the `.devcontainer` directory:
-
-```bash
-docker build -f ./.devcontainer/Dockerfile --tag=my_project:latest .
-docker run -it my_project:latest
-```
-
-This command will put you in a `bash` session in a Ubuntu 20.04 Docker container,
-with all of the tools listed in the [Dependencies](#dependencies) section already installed.
-Additionally, you will have `g++-11` and `clang++-13` installed as the default
-versions of `g++` and `clang++`.
-
-If you want to build this container using some other versions of gcc and clang,
-you may do so with the `GCC_VER` and `LLVM_VER` arguments:
-
-```bash
-docker build --tag=myproject:latest --build-arg GCC_VER=10 --build-arg LLVM_VER=11 .
-```
-
-The CC and CXX environment variables are set to GCC version 11 by default.
-If you wish to use clang as your default CC and CXX environment variables, you
-may do so like this:
-
-```bash
-docker build --tag=my_project:latest --build-arg USE_CLANG=1 .
-```
-
-You will be logged in as root, so you will see the `#` symbol as your prompt.
-You will be in a directory that contains a copy of the `cpp_starter_project`;
-any changes you make to your local copy will not be updated in the Docker image
-until you rebuild it.
-If you need to mount your local copy directly in the Docker image, see
-[Docker volumes docs](https://docs.docker.com/storage/volumes/).
-TLDR:
-
-```bash
-docker run -it \
- -v absolute_path_on_host_machine:absolute_path_in_guest_container \
- my_project:latest
-```
-
-You can configure and build [as directed above](#build) using these commands:
-
-```bash
-/starter_project# mkdir build
-/starter_project# cmake -S . -B ./build
-/starter_project# cmake --build ./build
-```
-
-You can configure and build using `clang-13`, without rebuilding the container,
-with these commands:
-
-```bash
-/starter_project# mkdir build
-/starter_project# CC=clang CXX=clang++ cmake -S . -B ./build
-/starter_project# cmake --build ./build
-```
-
-The `ccmake` tool is also installed; you can substitute `ccmake` for `cmake` to
-configure the project interactively.
-All of the tools this project supports are installed in the Docker image;
-enabling them is as simple as flipping a switch using the `ccmake` interface.
-Be aware that some of the sanitizers conflict with each other, so be sure to
-run them separately.
-
-A script called `build_examples.sh` is provided to help you to build the example
-GUI projects in this container.
-
diff --git a/include/myproject/Utils/Random.hpp b/include/myproject/Utils/Random.hpp
new file mode 100644
index 00000000..8f8d938a
--- /dev/null
+++ b/include/myproject/Utils/Random.hpp
@@ -0,0 +1,38 @@
+#pragma once
+#include
+#include
+#include
+#include
+
+class Random {
+public:
+ static inline void seed() { s_RandomEngine.seed(std::random_device()()); }
+ static inline void seed(uint32_t seed) { s_RandomEngine.seed(seed); }
+
+ static inline int32_t nextInt32() { return s_int32Dist(s_RandomEngine); }
+
+ static inline double nextDouble() { return s_doubleDist(s_RandomEngine); }
+ static inline double uniform(double min, double max) {
+ return min + (max - min) * nextDouble();
+ }
+ static inline double gauss() { return s_normalDist(s_RandomEngine); }
+
+ static inline std::mt19937& getEngine() { return s_RandomEngine; }
+
+ static inline void saveState(std::ostream& os) {
+ os << s_RandomEngine << '\n'
+ << s_int32Dist << '\n'
+ << s_doubleDist << '\n'
+ << s_normalDist << '\n';
+ }
+
+ static inline void loadState(std::istream& os) {
+ os >> s_RandomEngine >> s_int32Dist >> s_doubleDist >> s_normalDist;
+ }
+
+private:
+ static inline thread_local std::mt19937 s_RandomEngine;
+ static inline std::uniform_int_distribution s_int32Dist;
+ static inline std::uniform_real_distribution s_doubleDist;
+ static inline std::normal_distribution s_normalDist;
+};
\ No newline at end of file
diff --git a/include/myproject/Utils/Sampler2d.hpp b/include/myproject/Utils/Sampler2d.hpp
new file mode 100644
index 00000000..0d364744
--- /dev/null
+++ b/include/myproject/Utils/Sampler2d.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include
+#include
+#include
+
+class Sampler2d {
+public:
+ Sampler2d(const Eigen::AlignedBox2d& box);
+
+ virtual ~Sampler2d();
+
+ virtual Eigen::Vector2d sample() const = 0;
+
+ double getArea() const;
+
+protected:
+ Eigen::AlignedBox2d m_box;
+};
+
+class UniformSampler2d : public Sampler2d {
+public:
+ using Sampler2d::Sampler2d;
+
+ Eigen::Vector2d sample() const override;
+};
diff --git a/include/myproject/sample_library.hpp b/include/myproject/sample_library/sample_library.hpp
similarity index 54%
rename from include/myproject/sample_library.hpp
rename to include/myproject/sample_library/sample_library.hpp
index 1b2b1772..fd0990ca 100644
--- a/include/myproject/sample_library.hpp
+++ b/include/myproject/sample_library/sample_library.hpp
@@ -1,15 +1,12 @@
-#ifndef SAMPLE_LIBRARY_HPP
-#define SAMPLE_LIBRARY_HPP
-
+#pragma once
#include
[[nodiscard]] SAMPLE_LIBRARY_EXPORT int factorial(int) noexcept;
-[[nodiscard]] constexpr int factorial_constexpr(int input) noexcept
-{
- if (input == 0) { return 1; }
+[[nodiscard]] constexpr int factorial_constexpr(int input) noexcept {
+ if (input == 0) {
+ return 1;
+ }
- return input * factorial_constexpr(input - 1);
+ return input * factorial_constexpr(input - 1);
}
-
-#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0f92a9d6..5ab2be1b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,2 +1,3 @@
+add_subdirectory(Utils)
add_subdirectory(sample_library)
-add_subdirectory(ftxui_sample)
+add_subdirectory(app)
diff --git a/src/Utils/CMakeLists.txt b/src/Utils/CMakeLists.txt
new file mode 100644
index 00000000..5d261d34
--- /dev/null
+++ b/src/Utils/CMakeLists.txt
@@ -0,0 +1,25 @@
+include(GenerateExportHeader)
+
+add_library(Utils Random.cpp Sampler2d.cpp)
+
+add_library(myproject::Utils ALIAS Utils)
+
+target_link_libraries(Utils PRIVATE myproject_options myproject_warnings)
+target_link_system_libraries(Utils PRIVATE Eigen3::Eigen)
+
+target_include_directories(Utils ${WARNING_GUARD} PUBLIC $
+ $)
+
+target_compile_features(Utils PUBLIC cxx_std_20)
+
+set_target_properties(
+ Utils
+ PROPERTIES VERSION ${PROJECT_VERSION}
+ CXX_VISIBILITY_PRESET hidden
+ VISIBILITY_INLINES_HIDDEN YES)
+
+generate_export_header(Utils EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/include/myproject/Utils_export.hpp)
+
+if(NOT BUILD_SHARED_LIBS)
+ target_compile_definitions(Utils PUBLIC Utils_STATIC_DEFINE)
+endif()
diff --git a/src/Utils/Random.cpp b/src/Utils/Random.cpp
new file mode 100644
index 00000000..c7c74d1f
--- /dev/null
+++ b/src/Utils/Random.cpp
@@ -0,0 +1 @@
+#include
diff --git a/src/Utils/Sampler2d.cpp b/src/Utils/Sampler2d.cpp
new file mode 100644
index 00000000..d683b5c3
--- /dev/null
+++ b/src/Utils/Sampler2d.cpp
@@ -0,0 +1,13 @@
+#include
+#include
+
+Sampler2d::Sampler2d(const Eigen::AlignedBox2d& box) : m_box(box) {}
+
+Sampler2d::~Sampler2d() = default;
+
+double Sampler2d::getArea() const { return m_box.volume(); }
+
+Eigen::Vector2d UniformSampler2d::sample() const {
+ return {Random::uniform(m_box.min().x(), m_box.max().x()),
+ Random::uniform(m_box.min().y(), m_box.max().y())};
+}
diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
new file mode 100644
index 00000000..73c39eec
--- /dev/null
+++ b/src/app/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_executable(app main.cpp)
+
+target_link_libraries(app PRIVATE myproject::myproject_options myproject::myproject_warnings Utils)
+
+target_link_system_libraries(
+ app
+ PRIVATE
+ CLI11::CLI11
+ fmt::fmt
+ spdlog::spdlog)
+
+target_include_directories(app PRIVATE "${CMAKE_BINARY_DIR}/configured_files/include")
diff --git a/src/app/main.cpp b/src/app/main.cpp
new file mode 100644
index 00000000..a8fd817d
--- /dev/null
+++ b/src/app/main.cpp
@@ -0,0 +1,46 @@
+#include
+
+#include
+#include // project_name, project_version
+#include
+
+int main(int argc, const char** argv) {
+ try {
+ CLI::App app{fmt::format("{} version {}",
+ myproject::cmake::project_name,
+ myproject::cmake::project_version)};
+
+ // std::optional message;
+ // app.add_option("-m,--message", message, "A message to print out");
+ bool show_version = false;
+ app.add_flag("--version", show_version, "Show version information");
+
+ // bool is_turn_based = false;
+ // auto* turn_based = app.add_flag("--turn_based", is_turn_based);
+
+ // bool is_loop_based = false;
+ // auto* loop_based = app.add_flag("--loop_based", is_loop_based);
+
+ // turn_based->excludes(loop_based);
+ // loop_based->excludes(turn_based);
+
+ CLI11_PARSE(app, argc, argv);
+
+ if (show_version) {
+ fmt::print("{}\n", myproject::cmake::project_version);
+ return EXIT_SUCCESS;
+ }
+
+ // if (message) {
+ // fmt::print("{}\n", *message);
+ // }
+
+ Random::seed();
+ std::cout << Random::nextDouble() << '\n';
+
+ } catch (const std::exception& e) {
+ spdlog::error("Unhandled exception in main: {}", e.what());
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/src/ftxui_sample/CMakeLists.txt b/src/ftxui_sample/CMakeLists.txt
deleted file mode 100644
index fc5c65e2..00000000
--- a/src/ftxui_sample/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-add_executable(intro main.cpp)
-
-target_link_libraries(
- intro
- PRIVATE myproject::myproject_options
- myproject::myproject_warnings)
-
-target_link_system_libraries(
- intro
- PRIVATE
- CLI11::CLI11
- fmt::fmt
- spdlog::spdlog
- lefticus::tools
- ftxui::screen
- ftxui::dom
- ftxui::component)
-
-target_include_directories(intro PRIVATE "${CMAKE_BINARY_DIR}/configured_files/include")
diff --git a/src/ftxui_sample/main.cpp b/src/ftxui_sample/main.cpp
deleted file mode 100644
index aa53beaf..00000000
--- a/src/ftxui_sample/main.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-#include
-#include
-#include
-#include
-
-#include
-
-#include
-#include // for ftxui
-#include // for Slider
-#include // for ScreenInteractive
-#include
-
-#include
-
-// This file will be generated automatically when cur_you run the CMake
-// configuration step. It creates a namespace called `myproject`. You can modify
-// the source template at `configured_files/config.hpp.in`.
-#include
-
-template struct GameBoard
-{
- static constexpr std::size_t width = Width;
- static constexpr std::size_t height = Height;
-
- std::array, width> strings;
- std::array, width> values{};
-
- std::size_t move_count{ 0 };
-
- std::string &get_string(std::size_t cur_x, std::size_t cur_y) { return strings.at(cur_x).at(cur_y); }
-
-
- void set(std::size_t cur_x, std::size_t cur_y, bool new_value)
- {
- get(cur_x, cur_y) = new_value;
-
- if (new_value) {
- get_string(cur_x, cur_y) = " ON";
- } else {
- get_string(cur_x, cur_y) = "OFF";
- }
- }
-
- void visit(auto visitor)
- {
- for (std::size_t cur_x = 0; cur_x < width; ++cur_x) {
- for (std::size_t cur_y = 0; cur_y < height; ++cur_y) { visitor(cur_x, cur_y, *this); }
- }
- }
-
- [[nodiscard]] bool get(std::size_t cur_x, std::size_t cur_y) const { return values.at(cur_x).at(cur_y); }
-
- [[nodiscard]] bool &get(std::size_t cur_x, std::size_t cur_y) { return values.at(cur_x).at(cur_y); }
-
- GameBoard()
- {
- visit([](const auto cur_x, const auto cur_y, auto &gameboard) { gameboard.set(cur_x, cur_y, true); });
- }
-
- void update_strings()
- {
- for (std::size_t cur_x = 0; cur_x < width; ++cur_x) {
- for (std::size_t cur_y = 0; cur_y < height; ++cur_y) { set(cur_x, cur_y, get(cur_x, cur_y)); }
- }
- }
-
- void toggle(std::size_t cur_x, std::size_t cur_y) { set(cur_x, cur_y, !get(cur_x, cur_y)); }
-
- void press(std::size_t cur_x, std::size_t cur_y)
- {
- ++move_count;
- toggle(cur_x, cur_y);
- if (cur_x > 0) { toggle(cur_x - 1, cur_y); }
- if (cur_y > 0) { toggle(cur_x, cur_y - 1); }
- if (cur_x < width - 1) { toggle(cur_x + 1, cur_y); }
- if (cur_y < height - 1) { toggle(cur_x, cur_y + 1); }
- }
-
- [[nodiscard]] bool solved() const
- {
- for (std::size_t cur_x = 0; cur_x < width; ++cur_x) {
- for (std::size_t cur_y = 0; cur_y < height; ++cur_y) {
- if (!get(cur_x, cur_y)) { return false; }
- }
- }
-
- return true;
- }
-};
-
-
-void consequence_game()
-{
- auto screen = ftxui::ScreenInteractive::TerminalOutput();
-
- GameBoard<3, 3> game_board;
-
- std::string quit_text;
-
- const auto update_quit_text = [&quit_text](const auto &game_board_param) {
- quit_text = fmt::format("Quit ({} moves)", game_board_param.move_count);
- if (game_board_param.solved()) { quit_text += " Solved!"; }
- };
-
- const auto make_buttons = [&] {
- std::vector buttons;
- for (std::size_t cur_x = 0; cur_x < game_board.width; ++cur_x) {
- for (std::size_t cur_y = 0; cur_y < game_board.height; ++cur_y) {
- buttons.push_back(ftxui::Button(&game_board.get_string(cur_x, cur_y), [=, &game_board] {
- if (!game_board.solved()) { game_board.press(cur_x, cur_y); }
- update_quit_text(game_board);
- }));
- }
- }
- return buttons;
- };
-
- auto buttons = make_buttons();
-
- auto quit_button = ftxui::Button(&quit_text, screen.ExitLoopClosure());
-
- auto make_layout = [&] {
- std::vector rows;
-
- std::size_t idx = 0;
-
- for (std::size_t cur_x = 0; cur_x < game_board.width; ++cur_x) {
- std::vector row;
- for (std::size_t cur_y = 0; cur_y < game_board.height; ++cur_y) {
- row.push_back(buttons[idx]->Render());
- ++idx;
- }
- rows.push_back(ftxui::hbox(std::move(row)));
- }
-
- rows.push_back(ftxui::hbox({ quit_button->Render() }));
-
- return ftxui::vbox(std::move(rows));
- };
-
-
- static constexpr int randomization_iterations = 100;
- static constexpr int random_seed = 42;
-
- std::mt19937 gen32{ random_seed };// NOLINT fixed seed
-
- // NOLINTNEXTLINE This cannot be const
- std::uniform_int_distribution cur_x(static_cast(0), game_board.width - 1);
- // NOLINTNEXTLINE This cannot be const
- std::uniform_int_distribution cur_y(static_cast(0), game_board.height - 1);
-
- for (int i = 0; i < randomization_iterations; ++i) { game_board.press(cur_x(gen32), cur_y(gen32)); }
- game_board.move_count = 0;
- update_quit_text(game_board);
-
- auto all_buttons = buttons;
- all_buttons.push_back(quit_button);
- auto container = ftxui::Container::Horizontal(all_buttons);
-
- auto renderer = ftxui::Renderer(container, make_layout);
-
- screen.Loop(renderer);
-}
-
-struct Color
-{
- lefticus::tools::uint_np8_t R{ static_cast(0) };
- lefticus::tools::uint_np8_t G{ static_cast(0) };
- lefticus::tools::uint_np8_t B{ static_cast(0) };
-};
-
-// A simple way of representing a bitmap on screen using only characters
-struct Bitmap : ftxui::Node
-{
- Bitmap(std::size_t width, std::size_t height)// NOLINT same typed parameters adjacent to each other
- : width_(width), height_(height)
- {}
-
- Color &at(std::size_t cur_x, std::size_t cur_y) { return pixels.at(width_ * cur_y + cur_x); }
-
- void ComputeRequirement() override
- {
- requirement_ = ftxui::Requirement{
- .min_x = static_cast(width_), .min_y = static_cast(height_ / 2), .selected_box{ 0, 0, 0, 0 }
- };
- }
-
- void Render(ftxui::Screen &screen) override
- {
- for (std::size_t cur_x = 0; cur_x < width_; ++cur_x) {
- for (std::size_t cur_y = 0; cur_y < height_ / 2; ++cur_y) {
- auto &pixel = screen.PixelAt(box_.x_min + static_cast(cur_x), box_.y_min + static_cast(cur_y));
- pixel.character = "▄";
- const auto &top_color = at(cur_x, cur_y * 2);
- const auto &bottom_color = at(cur_x, cur_y * 2 + 1);
- pixel.background_color = ftxui::Color{ top_color.R.get(), top_color.G.get(), top_color.B.get() };
- pixel.foreground_color = ftxui::Color{ bottom_color.R.get(), bottom_color.G.get(), bottom_color.B.get() };
- }
- }
- }
-
- [[nodiscard]] auto width() const noexcept { return width_; }
-
- [[nodiscard]] auto height() const noexcept { return height_; }
-
- [[nodiscard]] auto &data() noexcept { return pixels; }
-
-private:
- std::size_t width_;
- std::size_t height_;
-
- std::vector pixels = std::vector(width_ * height_, Color{});
-};
-
-void game_iteration_canvas()
-{
- // this should probably have a `bitmap` helper function that does what cur_you expect
- // similar to the other parts of FTXUI
- auto bm = std::make_shared(50, 50);// NOLINT magic numbers
- auto small_bm = std::make_shared(6, 6);// NOLINT magic numbers
-
- double fps = 0;
-
- std::size_t max_row = 0;
- std::size_t max_col = 0;
-
- // to do, add total game time clock also, not just current elapsed time
- auto game_iteration = [&](const std::chrono::steady_clock::duration elapsed_time) {
- // in here we simulate however much game time has elapsed. Update animations,
- // run character AI, whatever, update stats, etc
-
- // this isn't actually timing based for now, it's just updating the display however fast it can
- fps = 1.0
- / (static_cast(std::chrono::duration_cast(elapsed_time).count())
- / 1'000'000.0);// NOLINT magic numbers
-
- for (std::size_t row = 0; row < max_row; ++row) {
- for (std::size_t col = 0; col < bm->width(); ++col) { ++(bm->at(col, row).R); }
- }
-
- for (std::size_t row = 0; row < bm->height(); ++row) {
- for (std::size_t col = 0; col < max_col; ++col) { ++(bm->at(col, row).G); }
- }
-
- // for the fun of it, let's have a second window doing interesting things
- auto &small_bm_pixel =
- small_bm->data().at(static_cast(elapsed_time.count()) % small_bm->data().size());
-
- switch (elapsed_time.count() % 3) {
- case 0:
- small_bm_pixel.R += 11;// NOLINT Magic Number
- break;
- case 1:
- small_bm_pixel.G += 11;// NOLINT Magic Number
- break;
- case 2:
- small_bm_pixel.B += 11;// NOLINT Magic Number
- break;
- }
-
-
- ++max_row;
- if (max_row >= bm->height()) { max_row = 0; }
- ++max_col;
- if (max_col >= bm->width()) { max_col = 0; }
- };
-
- auto screen = ftxui::ScreenInteractive::TerminalOutput();
-
- int counter = 0;
-
- auto last_time = std::chrono::steady_clock::now();
-
- auto make_layout = [&] {
- // This code actually processes the draw event
- const auto new_time = std::chrono::steady_clock::now();
-
- ++counter;
- // we will dispatch to the game_iteration function, where the work happens
- game_iteration(new_time - last_time);
- last_time = new_time;
-
- // now actually draw the game elements
- return ftxui::hbox({ bm | ftxui::border,
- ftxui::vbox({ ftxui::text("Frame: " + std::to_string(counter)),
- ftxui::text("FPS: " + std::to_string(fps)),
- small_bm | ftxui::border }) });
- };
-
- auto renderer = ftxui::Renderer(make_layout);
-
-
- std::atomic refresh_ui_continue = true;
-
- // This thread exists to make sure that the event queue has an event to
- // process at approximately a rate of 30 FPS
- std::thread refresh_ui([&] {
- while (refresh_ui_continue) {
- using namespace std::chrono_literals;
- std::this_thread::sleep_for(1.0s / 30.0);// NOLINT magic numbers
- screen.PostEvent(ftxui::Event::Custom);
- }
- });
-
- screen.Loop(renderer);
-
- refresh_ui_continue = false;
- refresh_ui.join();
-}
-
-// NOLINTNEXTLINE(bugprone-exception-escape)
-int main(int argc, const char **argv)
-{
- try {
- CLI::App app{ fmt::format("{} version {}", myproject::cmake::project_name, myproject::cmake::project_version) };
-
- std::optional message;
- app.add_option("-m,--message", message, "A message to print back out");
- bool show_version = false;
- app.add_flag("--version", show_version, "Show version information");
-
- bool is_turn_based = false;
- auto *turn_based = app.add_flag("--turn_based", is_turn_based);
-
- bool is_loop_based = false;
- auto *loop_based = app.add_flag("--loop_based", is_loop_based);
-
- turn_based->excludes(loop_based);
- loop_based->excludes(turn_based);
-
-
- CLI11_PARSE(app, argc, argv);
-
- if (show_version) {
- fmt::print("{}\n", myproject::cmake::project_version);
- return EXIT_SUCCESS;
- }
-
- if (is_turn_based) {
- consequence_game();
- } else {
- game_iteration_canvas();
- }
-
- } catch (const std::exception &e) {
- spdlog::error("Unhandled exception in main: {}", e.what());
- }
-}
diff --git a/src/sample_library/sample_library.cpp b/src/sample_library/sample_library.cpp
index 878deae2..d566e4a4 100644
--- a/src/sample_library/sample_library.cpp
+++ b/src/sample_library/sample_library.cpp
@@ -1,13 +1,12 @@
-#include
+#include
-int factorial(int input) noexcept
-{
- int result = 1;
+int factorial(int input) noexcept {
+ int result = 1;
- while (input > 0) {
- result *= input;
- --input;
- }
+ while (input > 0) {
+ result *= input;
+ --input;
+ }
- return result;
+ return result;
}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 0739f424..0c2d33a9 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -7,7 +7,7 @@ project(CmakeConfigPackageTests LANGUAGES CXX)
if(PROJECT_IS_TOP_LEVEL OR TEST_INSTALLED_VERSION)
enable_testing()
- find_package(myproject CONFIG REQUIRED) # for intro, project_options, ...
+ find_package(myproject CONFIG REQUIRED) # for app, project_options, ...
if(NOT TARGET myproject_options)
message(FATAL_ERROR "Requiered config package not found!")
@@ -20,13 +20,13 @@ endif()
include(${Catch2_SOURCE_DIR}/extras/Catch.cmake)
# Provide a simple smoke test to make sure that the CLI works and can display a --help message
-add_test(NAME cli.has_help COMMAND intro --help)
+add_test(NAME cli.has_help COMMAND app --help)
# Provide a test to verify that the version being reported from the application
# matches the version given to CMake. This will be important once you package
# your program. Real world shows that this is the kind of simple mistake that is easy
# to make, but also easy to test for.
-add_test(NAME cli.version_matches COMMAND intro --version)
+add_test(NAME cli.version_matches COMMAND app --version)
set_tests_properties(cli.version_matches PROPERTIES PASS_REGULAR_EXPRESSION "${PROJECT_VERSION}")
add_executable(tests tests.cpp)
diff --git a/test/constexpr_tests.cpp b/test/constexpr_tests.cpp
index fe36db5e..e069d20a 100644
--- a/test/constexpr_tests.cpp
+++ b/test/constexpr_tests.cpp
@@ -1,12 +1,10 @@
#include
+#include
-#include
-
-TEST_CASE("Factorials are computed with constexpr", "[factorial]")
-{
- STATIC_REQUIRE(factorial_constexpr(0) == 1);
- STATIC_REQUIRE(factorial_constexpr(1) == 1);
- STATIC_REQUIRE(factorial_constexpr(2) == 2);
- STATIC_REQUIRE(factorial_constexpr(3) == 6);
- STATIC_REQUIRE(factorial_constexpr(10) == 3628800);
+TEST_CASE("Factorials are computed with constexpr", "[factorial]") {
+ STATIC_REQUIRE(factorial_constexpr(0) == 1);
+ STATIC_REQUIRE(factorial_constexpr(1) == 1);
+ STATIC_REQUIRE(factorial_constexpr(2) == 2);
+ STATIC_REQUIRE(factorial_constexpr(3) == 6);
+ STATIC_REQUIRE(factorial_constexpr(10) == 3628800);
}
diff --git a/test/tests.cpp b/test/tests.cpp
index 5b632e2e..375b2841 100644
--- a/test/tests.cpp
+++ b/test/tests.cpp
@@ -1,14 +1,10 @@
#include
-
-
-#include
-
-
-TEST_CASE("Factorials are computed", "[factorial]")
-{
- REQUIRE(factorial(0) == 1);
- REQUIRE(factorial(1) == 1);
- REQUIRE(factorial(2) == 2);
- REQUIRE(factorial(3) == 6);
- REQUIRE(factorial(10) == 3628800);
+#include
+
+TEST_CASE("Factorials are computed", "[factorial]") {
+ REQUIRE(factorial(0) == 1);
+ REQUIRE(factorial(1) == 1);
+ REQUIRE(factorial(2) == 2);
+ REQUIRE(factorial(3) == 6);
+ REQUIRE(factorial(10) == 3628800);
}