The LLVM compiler project provides a header file called STLExtras.h that extends the capabilities of C++ without any dependency on the rest of LLVM. In this article, we take a quick look at its basic functionality.
LLVM STLExtras.h
For the /usr/include/llvm/ADT/STLExtras.h
file, you need to install:
- Fedora:
dnf install llvm-devel
- RHEL-8:
yum install llvm-devel
- RHEL-7/8 with LLVM toolset 7.0:
yum install llvm-toolset-7.0-{clang,llvm-devel};scl enable llvm-toolset-7.0 -- clang++ -I$(scl enable llvm-toolset-7.0 -- llvm-config --includedir) -std=c++17 ...
llvm::reverse
= reverse range-based for loop
C++11 brought range-based for loops. We no longer have to deal with iterators in the most common cases.
See also online compiler sample code.
std::vector vec{1, 2, 3, 4}; // C++11 initializer list // C++98 iterator: 1 2 3 4 for (std::vector::iterator it = vec.begin(); it != vec.end(); ++it) std::cout << *it; // C++11 range-based for loop: 1 2 3 4 for (int i : vec) std::cout << i;
Except... when we need to iterate in the opposite way. C++11 somehow forgot about that. Here comes LLVM with its llvm::reverse container adapter.
See also online compiler sample code.
std::vector vec{1, 2, 3, 4}; // Reverse range-based for loop - llvm::reverse: 4 3 2 1 for (int i : llvm::reverse(vec)) std::cout << i; }
Range-based algorithms
= vec.begin(),vec.end()
→ vec
It's a bit annoying to always write both begin()
and end()
for container algorithms, right?
std::vector vec{1, 2, 3, 4}; std::sort(vec.begin(),vec.end()); // or: std::sort(vec.begin(),vec.end(), std::greater());
The problem is solved already; it really is that simple:
#define LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING 1 // no LLVM libraries needed #include <llvm/ADT/STLExtras.h> std::vector vec{1, 2, 3, 4}; llvm::sort(vec); // or: llvm::sort(vec, std::greater());
It applies to all the C++ algorithms: std::sort std::for_each std::all_of std::any_of std::none_of std::find std::find_if std::find_if_not std::remove_if std::copy_if std::copy std::count std::count_if std::transform std::partition std::lower_bound std::upper_bound
It is expected as std::ranges::
in C++20.
Additionally, it provides:
- is_contained = std::find with a
bool
result - is_splat = return a
bool
whether all elements in a container are the same - erase_if = std::remove_if with more convient calling (expected in C++20)
See also online compiler sample code.
Last updated: July 1, 2020