LLVM

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.0yum 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:

See also online compiler sample code.

Last updated: July 1, 2020