To create a new Beman library, first click the "Use this template" dropdown in the top-right and select "Create a new repository":
|
This will create a new repository that's an exact copy of exemplar. The next step is to customize it for your use case.
To do so, execute the bash script stamp.sh. This script will prompt for parameters like
the new library's name, paper number, and description. Then it will replace your exemplar
copy with a stamped-out template containing these parameters and create a corresponding
git commit and branch:
$ ./stamp.sh
[1/7] project_name (my_project_name): example_library
[2/7] maintainer (your_github_username): your_username
[3/7] minimum_cpp_build_version (20):
[4/7] paper (PnnnnRr): P9999R9
[5/7] description (Short project description.):
[6/7] Select library_type
1 - interface
2 - static
Choose from [1/2] (1):
[7/7] Select unit_test_library
1 - gtest
2 - catch2
Choose from [1/2] (1):
Switched to a new branch 'stamp'
Successfully stamped out exemplar template to the new branch 'stamp'.
Try 'git push origin stamp' to push the branch upstream,
then create a pull request.
From there, you can simply fill in all the remaining parts of the repository that are labeled 'todo'.
What follow is an example of a Beman library README.
beman.exemplar is a minimal C++ library conforming to The Beman Standard.
This can be used as a template for those intending to write Beman libraries.
It may also find use as a minimal and modern C++ project structure.
Implements: std::identity proposed in Standard Library Concepts (P0898R3).
Status: Under development and not yet ready for production use.
beman.exemplar is licensed under the Apache License v2.0 with LLVM Exceptions.
std::identity is a function object type whose operator() returns its argument unchanged.
std::identity serves as the default projection in constrained algorithms.
Its direct usage is usually not needed.
The following code snippet illustrates how we can achieve a default projection using beman::exemplar::identity:
#include <beman/exemplar/exemplar.hpp>
namespace exe = beman::exemplar;
// Class with a pair of values.
struct Pair
{
int n;
std::string s;
// Output the pair in the form {n, s}.
// Used by the range-printer if no custom projection is provided (default: identity projection).
friend std::ostream &operator<<(std::ostream &os, const Pair &p)
{
return os << "Pair" << '{' << p.n << ", " << p.s << '}';
}
};
// A range-printer that can print projected (modified) elements of a range.
// All the elements of the range are printed in the form {element1, element2, ...}.
// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three}
// e.g., pairs with custom projection: {1:one, 2:two, 3:three}
template <std::ranges::input_range R,
typename Projection>
void print(const std::string_view rem, R &&range, Projection projection = exe::identity>)
{
std::cout << rem << '{';
std::ranges::for_each(
range,
[O = 0](const auto &o) mutable
{ std::cout << (O++ ? ", " : "") << o; },
projection);
std::cout << "}\n";
};
int main()
{
// A vector of pairs to print.
const std::vector<Pair> pairs = {
{1, "one"},
{2, "two"},
{3, "three"},
};
// Print the pairs using the default projection.
print("\tpairs with beman: ", pairs);
return 0;
}
Full runnable examples can be found in examples/.
This project requires at least the following to build:
- A C++ compiler that conforms to the C++17 standard or greater
- CMake 3.30 or later
- (Test Only) GoogleTest
You can disable building tests by setting CMake option BEMAN_EXEMPLAR_BUILD_TESTS to
OFF when configuring the project.
| Compiler | Version | C++ Standards | Standard Library |
|---|---|---|---|
| GCC | 15-13 | C++26-C++17 | libstdc++ |
| GCC | 12-11 | C++23-C++17 | libstdc++ |
| Clang | 22-19 | C++26-C++17 | libstdc++, libc++ |
| Clang | 18-17 | C++26-C++17 | libc++ |
| Clang | 18-17 | C++20, C++17 | libstdc++ |
| AppleClang | latest | C++26-C++17 | libc++ |
| MSVC | latest | C++23 | MSVC STL |
See the Contributing Guidelines.
You can build exemplar using a CMake workflow preset:
cmake --workflow --preset gcc-releaseTo list available workflow presets, you can invoke:
cmake --list-presets=workflowFor details on building beman.exemplar without using a CMake preset, refer to the Contributing Guidelines.
To install beman.exemplar globally after building with the gcc-release preset, you can
run:
sudo cmake --install build/gcc-releaseAlternatively, to install to a prefix, for example /opt/beman, you can run:
sudo cmake --install build/gcc-release --prefix /opt/bemanThis will generate the following directory structure:
/opt/beman
├── include
│ └── beman
│ └── exemplar
│ ├── exemplar.hpp
│ └── ...
└── lib
└── cmake
└── beman.exemplar
├── beman.exemplar-config-version.cmake
├── beman.exemplar-config.cmake
└── beman.exemplar-targets.cmakeIf you installed beman.exemplar to a prefix, you can specify that prefix to your CMake
project using CMAKE_PREFIX_PATH; for example, -DCMAKE_PREFIX_PATH=/opt/beman.
You need to bring in the beman.exemplar package to define the beman::exemplar CMake
target:
find_package(beman.exemplar REQUIRED)You will then need to add beman::exemplar to the link libraries of any libraries or
executables that include beman.exemplar headers.
target_link_libraries(yourlib PUBLIC beman::exemplar)To use beman.exemplar in your C++ project,
include an appropriate beman.exemplar header from your source code.
#include <beman/exemplar/exemplar.hpp>Note
beman.exemplar headers are to be included with the beman/exemplar/ prefix.
Altering include search paths to spell the include target another way (e.g.
#include <exemplar.hpp>) is unsupported.
