beman.take_before is a C++ library implementing the views::take_before range adaptor as proposed in
P3220R2, conforming to
The Beman Standard.
Implements: views::take_before range adaptor.
Status: Under development and not yet ready for production use.
views::take_before accepts a range (or iterator) and a specified value and produces a range ending with the
first occurrence of that value. It's particularly useful for constructing null-terminated byte string (NTBS)
ranges without calculating their actual length.
beman.take_before is licensed under the Apache License v2.0 with LLVM Exceptions.
#include <beman/take_before/take_before.hpp>
#include <vector>
#include <iostream>
namespace beman = beman::take_before;
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// Take elements before the first occurrence of 3
for (int i : v | beman::views::take_before(3)) {
std::cout << i << ' '; // prints: 1 2
}
}#include <beman/take_before/take_before.hpp>
#include <iostream>
namespace beman = beman::take_before;
int main() {
const char* one_two = "One?Two";
for (auto c : beman::views::take_before(one_two, '?')) {
std::cout << c; // prints: One
}
}#include <beman/take_before/take_before.hpp>
#include <vector>
#include <algorithm>
namespace beman = beman::take_before;
int main() {
std::vector<int> v = {10, 20, 30, 40};
auto result = beman::views::take_before(v, 30);
// result contains: {10, 20}
}#include <beman/take_before/take_before.hpp>
#include <ranges>
#include <vector>
namespace beman = beman::take_before;
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
auto result = v
| std::views::transform([](int x) { return x * 2; })
| beman::views::take_before(6); // {2, 4}
}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++20 standard or greater
- CMake 3.30 or later
- (Test Only) GoogleTest
You can disable building tests by setting CMake option BEMAN_TAKE_BEFORE_BUILD_TESTS to
OFF when configuring the project.
| Compiler | Version | C++ Standards | Standard Library |
|---|---|---|---|
| GCC | 15-13 | C++26-C++20 | libstdc++ |
| GCC | 12-11 | C++23, C++20 | libstdc++ |
| Clang | 22-19 | C++26-C++20 | libstdc++, libc++ |
| Clang | 18-17 | C++26-C++20 | libc++ |
| Clang | 18-17 | C++20 | libstdc++ |
| AppleClang | latest | C++26-C++20 | libc++ |
| MSVC | latest | C++23 | MSVC STL |
See the Contributing Guidelines.
You can build take_before 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.take_before without using a CMake preset, refer to the Contributing Guidelines.
To install beman.take_before 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
│ └── take_before
│ ├── take_before.hpp
│ └── ...
└── lib
└── cmake
└── beman.take_before
├── beman.take_before-config-version.cmake
├── beman.take_before-config.cmake
└── beman.take_before-targets.cmakeIf you installed beman.take_before 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.take_before package to define the beman::take_before CMake
target:
find_package(beman.take_before REQUIRED)You will then need to add beman::take_before to the link libraries of any libraries or
executables that include beman.take_before headers.
target_link_libraries(yourlib PUBLIC beman::take_before)To use beman.take_before in your C++ project,
include an appropriate beman.take_before header from your source code.
#include <beman/take_before/take_before.hpp>Note
beman.take_before headers are to be included with the beman/take_before/ prefix.
Altering include search paths to spell the include target another way (e.g.
#include <take_before.hpp>) is unsupported.
namespace beman::take_before::views {
inline constexpr /* unspecified */ take_before;
}Parameters:
range- A viewable range or input iteratorvalue- The delimiter value to search for
Returns: A view of elements from the beginning up to (but not including) the first occurrence of value.
Behavior:
- If
valueis not found, returns the entire range - If
valueis the first element, returns an empty range - Stops at the first occurrence of
value
template<std::ranges::view V, std::move_constructible T>
requires std::ranges::input_range<V> && std::is_object_v<T> &&
std::indirect_binary_predicate<std::ranges::equal_to,
std::ranges::iterator_t<V>, const T*>
class take_before_view;template<class T>
constexpr bool tidy_obj =
std::is_empty_v<T> &&
std::is_trivially_default_constructible_v<T> &&
std::is_trivially_destructible_v<T>;When the delimiter type satisfies tidy_obj and the underlying range is borrowed, take_before_view is also
a borrowed range.