GitHub Pages with snippets for Modern C++
- We often need to copy and paste some snippets to code more productively.
- Snippets can help us when it's not easy to remember all high levels features Modern C++ has to offer.
- This repository contains lots of organized, reusable, and safe snippets for Modern C++.
- All snippets are available in GitHub pages in a convenient way for copying and pasting.
Table of Contents
This is how this repository works:
- The
snippets
directory has lots of short programs with useful C++20 snippets - The
examples
directory has lots of short tasks using these snippets - GitHub actions ensures all snippets are working on GCC, MSVC, and Clang
- We generate GitHub pages with all snippets by groups of tasks using mkdocs material and mdsplit
Libraries
We give preference to libraries in this order:
- Libraries supported by most C++ compilers
- Libraries accepted into the C++ standard
- Libraries likely to be accepted into the next C++ standard
- Libraries representative of existing practice
External Libraries
For external libraries, we also include a short CMake snippet in the build script with:
find_package
to find, setup, and link the large external librariesFetchContents
to download, build, and link the external library
Snippets and Examples
The snippets, as they are, might seem like they are examples in the sense that they are in long files sometimes. What makes them snippets is that, at the source file level, they represent lots of independent short tasks separated by comments. Unlike in the examples, the tasks separated by comments are unrelated. You can just copy and paste the snippets between pairs of comments.
GitHub Pages
We generate GitHub pages with all snippets:
- The GitHub pages are generated with mkdocs material and mdsplit
- Snippets organized are categorized by groups of tasks
- Sections are easy to explore, copy, and paste
--8<-- "snippets/input_output/CMakeLists.txt"
--8<-- "snippets/input_output/hello_world.cpp"
--8<-- "snippets/input_output/cin.cpp"
--8<-- "snippets/input_output/printing.cpp"
Related examples:
--8<-- "snippets/input_output/format.cpp"
--8<-- "snippets/input_output/tabulate.cpp"
--8<-- "snippets/control_flow/CMakeLists.txt"
--8<-- "snippets/control_flow/sequential.cpp"
--8<-- "snippets/control_flow/conditional.cpp"
--8<-- "snippets/control_flow/loops.cpp"
--8<-- "snippets/data_types/CMakeLists.txt"
--8<-- "snippets/data_types/data_types.cpp"
--8<-- "snippets/data_types/operators.cpp"
--8<-- "snippets/data_types/auto.cpp"
--8<-- "snippets/data_types/constants.cpp"
--8<-- "snippets/basic_types/CMakeLists.txt"
--8<-- "snippets/basic_types/raw_arrays.cpp"
--8<-- "snippets/basic_types/arrays.cpp"
--8<-- "snippets/basic_types/vectors.cpp"
--8<-- "snippets/basic_types/strings.cpp"
--8<-- "snippets/basic_types/move.cpp"
--8<-- "snippets/basic_types/aggregate_initialization.cpp"
--8<-- "snippets/basic_types/structured_binding.cpp"
--8<-- "snippets/pointers/CMakeLists.txt"
--8<-- "snippets/pointers/raw_pointers.cpp"
--8<-- "snippets/pointers/smart_pointers.cpp"
--8<-- "snippets/functions/CMakeLists.txt"
--8<-- "snippets/functions/functions.cpp"
Related examples:
--8<-- "snippets/functions/lambda.cpp"
--8<-- "snippets/files/CMakeLists.txt"
FindFilesystem.cmake:
--8<-- "cmake/FindFilesystem.cmake"
--8<-- "snippets/files/files.cpp"
--8<-- "snippets/files/filesystem.cpp"
--8<-- "snippets/datetime/CMakeLists.txt"
--8<-- "snippets/datetime/clock.cpp"
Related examples:
--8<-- "snippets/datetime/datetime.cpp"
--8<-- "snippets/random/CMakeLists.txt"
--8<-- "snippets/random/random.cpp"
--8<-- "snippets/random/pcg.cpp"
--8<-- "snippets/templates/CMakeLists.txt"
--8<-- "snippets/templates/template_functions.cpp"
--8<-- "snippets/templates/template_alias.cpp"
--8<-- "snippets/templates/concepts.cpp"
FindConcepts.cmake:
--8<-- "cmake/FindConcepts.cmake"
--8<-- "snippets/templates/sfinae.cpp"
--8<-- "snippets/algorithm/CMakeLists.txt"
--8<-- "snippets/algorithm/searching.cpp"
--8<-- "snippets/algorithm/sorting.cpp"
--8<-- "snippets/algorithm/algorithms.cpp"
--8<-- "snippets/algorithm/ranges.cpp"
--8<-- "snippets/data_structures/CMakeLists.txt"
--8<-- "snippets/data_structures/sequential_containers.cpp"
--8<-- "snippets/data_structures/associative_containers.cpp"
--8<-- "snippets/data_structures/memory_resource.cpp"
FindPMR.cmake:
--8<-- "cmake/FindPMR.cmake"
--8<-- "snippets/data_structures/span.cpp"
--8<-- "snippets/data_structures/bitset.cpp"
--8<-- "snippets/data_structures/spatial_containers.cpp"
--8<-- "snippets/heterogeneous_types/CMakeLists.txt"
--8<-- "snippets/heterogeneous_types/tuples.cpp"
--8<-- "snippets/heterogeneous_types/any.cpp"
--8<-- "snippets/heterogeneous_types/optional.cpp"
--8<-- "snippets/heterogeneous_types/variant.cpp"
--8<-- "snippets/paradigms/CMakeLists.txt"
--8<-- "snippets/paradigms/polymorphism.cpp"
--8<-- "snippets/paradigms/shared_from_this.cpp"
--8<-- "snippets/paradigms/metaprogramming.cpp"
--8<-- "snippets/paradigms/CRTP.cpp"
--8<-- "snippets/paradigms/SFINAE.cpp"
--8<-- "snippets/parallel/CMakeLists.txt"
--8<-- "snippets/parallel/policies.cpp"
--8<-- "snippets/parallel/multithreading.cpp"
--8<-- "snippets/parallel/executors.cpp"
--8<-- "snippets/parallel/timers.cpp"
--8<-- "snippets/parallel/signals.cpp"
--8<-- "snippets/parallel/async_pools.cpp"
--8<-- "snippets/utilities/CMakeLists.txt"
--8<-- "snippets/utilities/regex.cpp"
--8<-- "snippets/networking/CMakeLists.txt"
--8<-- "snippets/networking/network.cpp"
--8<-- "snippets/networking/network_async.cpp"
main.cpp
--8<-- "snippets/networking/server/main.cpp"
server.hpp
--8<-- "snippets/networking/server/server.hpp"
connection_manager.hpp
--8<-- "snippets/networking/server/connection_manager.hpp"
connection.hpp
--8<-- "snippets/networking/server/connection.hpp"
header.hpp
--8<-- "snippets/networking/server/header.hpp"
reply.hpp
--8<-- "snippets/networking/server/reply.hpp"
request.hpp
--8<-- "snippets/networking/server/request.hpp"
request_parser.hpp
--8<-- "snippets/networking/server/request_parser.hpp"
mime_types.hpp
--8<-- "snippets/networking/server/mime_types.hpp"
request_handler.hpp
--8<-- "snippets/networking/server/request_handler.hpp"
mime_types.cpp
--8<-- "snippets/networking/server/mime_types.cpp"
request_parser.cpp
--8<-- "snippets/networking/server/request_parser.cpp"
reply.cpp
--8<-- "snippets/networking/server/reply.cpp"
request_handler.cpp
--8<-- "snippets/networking/server/request_handler.cpp"
connection.cpp
--8<-- "snippets/networking/server/connection.cpp"
connection_manager.cpp
--8<-- "snippets/networking/server/connection_manager.cpp"
server.cpp
--8<-- "snippets/networking/server/server.cpp"
--8<-- "snippets/gui/CMakeLists.txt"
--8<-- "snippets/gui/qt/qt_hello.cpp"
Build script:
--8<-- "snippets/gui/qt/CMakeLists.txt"
--8<-- "snippets/gui/opengl/sdl/sdl_hello.cpp"
Build script:
--8<-- "snippets/gui/opengl/sdl/CMakeLists.txt"
--8<-- "snippets/gui/opengl/glfw/opengl_hello.cpp"
Build script:
--8<-- "snippets/gui/opengl/glfw/CMakeLists.txt"
--8<-- "snippets/gui/imgui/imgui_hello.cpp"
Build script:
--8<-- "snippets/gui/imgui/CMakeLists.txt"
--8<-- "snippets/gui/webview/webview_hello.cpp"
Build script:
--8<-- "snippets/gui/webview/CMakeLists.txt"
--8<-- "snippets/gui/tray/tray_hello.cpp"
Build script:
--8<-- "snippets/gui/tray/CMakeLists.txt"
--8<-- "snippets/tests/CMakeLists.txt"
--8<-- "snippets/tests/unit_tests_catch.cpp"
--8<-- "snippets/tests/unit_tests_ut.cpp"
--8<-- "snippets/tests/source_location.cpp"
--8<-- "snippets/tests/plots.cpp"
Some useful CMake functions:
--8<-- "cmake/functions.cmake"
Many operating systems don't come with C++20 by default. Follow these instructions to install C++20.
Update GCC:
sudo apt install build-essential
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt install gcc-10
sudo apt install g++-10
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
Set your default compiler with:
update-alternatives --config g++
Download a recent version of Clang.
curl --output clang.tar.xz -L https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-apple-darwin.tar.xz
mkdir clang
tar -xvJf clang.tar.xz -C clang
Copy the files to usr/local/
:
cd clang/clang+llvm-11.0.0-x86_64-apple-darwin
sudo cp -R * /usr/local/
Let CMake know that's the compiler you want to use.
If you want this to be your default compiler, you can set the CXX
environment variable:
export CXX=/usr/local/bin/clang++
If you want to use this compiler in a single project, run CMake with these options:
-DCMAKE_C_COMPILER=/usr/local/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/bin/clang++
Or tell you IDE to pass these options to CMake:
Update your Visual Studio Compiler.
The most recent version of Visual Studio should include C++20.
!!! warning We still don't know of a script for installing C++20 on Windows from the terminal.
This would be especially useful for our [build workflow](./.github/workflows/build.yml), which has not been testing MSVC since we moved to C++20.
Please let us know or open a PR if you know of such a script.
Where are the examples? Are the snippets examples?
The complete examples are in the examples
directory, but they not explicitly replicated in the docs because they are much longer than the snippets.
What's the difference between snippets and examples?
Examples are often long and don't represent independent tasks you can copy and paste. Snippets represent independent tasks between pairs of comments that you can copy and paste.
Shouldn't the snippet files be short files?
The snippets could go into a new category level and we could separate them at their lowest level by file, but that would make them difficult to explore if the resolution is too high, like 3-4 lines of code per file. Also, because snippets have pre-conditions and post-conditions, it would make it much harder to test all snippets.
Why not get my snippets directly from cppreference or cplusplus.com?
The cppreference is not meant for snippets and this repository is not meant to be a reference for the C++ standard. Some implications are:
- The snippets:
- Meant to list the commands you most often need in a library.
- Lots of independent tasks for copying and pasting
- Include corresponding build scripts when something more complex is required
- Include external libraries when it's existing practice
- Organized roughly in the order someone learning C++ might need them
- The examples in cppreference or cplusplus.com:
- Meant to make points about the internals of the libraries.
- A single task meant to prove a point
- Has nothing to do with build scripts
- Has nothing to do with external libraries
- Mix simple and complex concepts to make a point
Why do you use std::endl
so much in the snippets? Isn't it evil?
The snippets usually use std::endl
instead of '\n'
:
- Flushing does have a semantic meaning different from
'\n
which is a nice convention for small snippets (please show me what's in the buffer vs. put a newline in the buffer) - Most snippets require creating variables first and using them later so that we can test the snippets with GitHub Actions. The flushing part is not what you are going to copy and paste in a snippet.
- The time difference of flushing
std::cout
to the console (not files!) is negligible - Almost no application is spending more time flushing than calculating things to flush. Unless it's a flushing benchmark.
- After getting started with this library, please complete this survey to let us know how we can improve your experience.
- Discussions are concentrated on our GitHub discussions page. Don't refrain from asking questions and proposing ideas.
- If you are a programmer with good ideas, please share these ideas with us.
- Academic collaboration is more than welcome.
Contributing
Feel free to contribute with new snippets to this repository. For complex features and changes, consider getting feedback from the community first.
There are many ways in which you can contribute to this library:
- Testing the library in new environments
- Contributing with interesting snippets and examples
- Finding problems in the documentation
- Finding bugs in general
- Whatever idea seems interesting to you
The only thing we ask you is to make sure your contribution is not destructive. Some contributions in which we are not interested are:
- "I don't like this optional feature so I removed/deprecated it"
- "I removed this feature to support older versions of C++" but have not provided an equivalent alternative. This repository is focused on Modern C++.
- "I removed this feature so I don't have to install/update ______" but have not provided an equivalent alternative
- "I'm creating this high-cost promise that we'll support ________ forever" but I'm not sticking around to keep that promise
In doubt, please open a discussion first.
Guidelines
If contributing with code, please leave the pedantic mode ON (-DBUILD_WITH_PEDANTIC_WARNINGS=ON
), use cppcheck, and clang-format.
If contributing to the documentation, please edit README.md
directly, as the files in this documentation are automatically generated with mdsplit.