Loading...
Searching...
No Matches
fluentcpp

<picture> <source media="(prefers-color-scheme: dark)" srcset="assets/artwork/fluentcpp-sm.png"> Fluent C++ logo </picture>

Fluent C++

Statically typed, fluent query functions for C++20 containers that are easy to discover through auto-complete.

Build status Apache 2.0 license C++20 CMake 3.16.3+ Linux

Remarks
If you find this project useful, please consider supporting it as a sponsor and show some ❤️ for open source maintainers.

Wrap a container in fcpp::query and chain operations on it, instead of writing loops and temporary containers by hand.

.where(EXPR(x, x > 500))
.select(EXPR(x, x % 10))
.distinct()
.to_vector();
#define EXPR(...)
Syntactic sugar for terse expressions using pass by value.
Definition query.h:71
Queryable< T > query(std::vector< T > items)
Queries the sequence of items using a vector.
Definition query.h:663
  • :link: Chain filtering, projection, ordering, set and grouping operations in a single expression.
  • :mag: Find every operation through auto-complete on the returned fcpp::Queryable<T>.
  • :zap: Write terse lambdas with the EXPR and CR_EXPR macros.
  • :package: Works with move-only types; items are moved through the chain rather than copied.

Installation

Install the latest release with a single command:

curl -fsSL https://raw.githubusercontent.com/awalsh128/fluentcpp/master/scripts/install.sh | bash

This downloads the source, builds the library and installs it to /usr/local/lib/fluentcpp, with the headers in /usr/local/include/fluentcpp. It runs as your user and only asks for sudo to copy the files if the install location isn't writable. Requires curl, CMake 3.16.3 or newer, and a C++20 compiler; clang++ and Ninja are used when available.

Pass options after bash -s -- to pick a version or install location:

curl -fsSL https://raw.githubusercontent.com/awalsh128/fluentcpp/master/scripts/install.sh |
bash -s -- --version v0.2 --prefix "$HOME/.local"
Option Default Description
--version Latest release Release tag or branch to install, such as v0.2 or master.
--prefix /usr/local Installation prefix for the lib and include directories.

To build with a specific compiler, set CXX on the bash side of the pipe, for example ... | CXX=g++ bash. To read the script before running it, download it with curl -fsSLO and run bash install.sh.

Alternatively, download fluentcpp-<tag>.tar.gz from a release, extract it and run ./install.sh from the extracted directory.

Usage

Include the query header and wrap any std::vector:

#include <iostream>
#include <vector>
int main() {
std::vector<int> xs;
for (int x = 0; x < 1000; x++) xs.push_back(x);
std::vector<int> result =
.where(EXPR(x, x > 500))
.shuffle()
.skip(10)
.select(EXPR(x, x % 10))
.distinct()
.order_by(EXPR(x, x))
.branch(EXPR(x, x > 5))
.when_true([](auto q) { return q.select(EXPR(x, x + 100)); })
.when_false([](auto q) { return q.select(EXPR(x, x - 100)); })
.merge()
.select(EXPR(x, std::get<0>(x)))
.to_vector();
for (int x : result) std::cout << x << " ";
}
A library to express information in a functional way that allows for easy auto-complete and shorter e...

Link against the installed static library:

clang++ -std=c++20 main.cpp -L/usr/local/lib/fluentcpp -lfluentcpp

Find more in the [examples folder](examples). The full API reference is generated with Doxygen from the comments in include/fluentcpp and published at awalsh128.com/fluentcpp. See all of my published APIs at awalsh128.com/api.

Operations

Category Operations
Filtering where, distinct, skip, take, take_random, slice, trim
Projection select, flatten, zip, join
Ordering order_by, sort, reverse, shuffle
Sets difference, intersect, unionize
Grouping group_by, keyed_group_by, branch, when_true, when_false, merge
Aggregation accumulate, all, any, min, max, first_or_default
Side effects action
Conversion to_vector, to_set, to_single_value_map, to_multi_value_map

Building

Building from source requires Clang (clang++), CMake and Ninja:

sudo apt-get install -y clang cmake ninja-build

Debug Build with Tests

The debug preset in CMakePresets.json configures clang++, Ninja, tests and examples into build/debug:

cmake --preset debug
cmake --build --preset debug
ctest --preset debug

Or, without presets:

cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_CXX_COMPILER=clang++ \
-DBUILD_TESTS=ON
cmake --build build
ctest --test-dir build --output-on-failure

Release Build and Install

cmake --preset release
cmake --build --preset release --target fluentcpp
sudo cmake --install build/release

Build Options

Option Default Description
BUILD_TESTS OFF Build the Catch2 unit tests in [tests](tests).
BUILD_BENCHMARKS OFF Build the Google Benchmark tests in [benchmarks](benchmarks).
BUILD_EXAMPLES OFF Build the example programs in [examples](examples).
BUILD_WEBSITE OFF Build the Doxygen API website from [docs](docs); requires Doxygen.

Project Layout

include/fluentcpp/ Public headers, included as <fluentcpp/query.h>.
src/ Library implementation files.
tests/ Catch2 unit tests.
benchmarks/ Google Benchmark tests and reporting.
examples/ Example programs.
docs/ Doxygen configuration and website.
cmake/ CMake helper modules.
scripts/ Install, release and developer scripts.
assets/ Artwork and other non-code assets.

Dependencies

  • CMake - Build system.
  • Clang - C++20 compiler used for builds, formatting and static analysis.
  • Catch2 - Unit test framework, fetched by CMake when BUILD_TESTS=ON.
  • Google Benchmark - Benchmark framework, fetched by CMake when BUILD_BENCHMARKS=ON.
  • Doxygen - API documentation generator, used when BUILD_WEBSITE=ON.

Report bugs or request features through GitHub Issues. For development guidelines, see CONTRIBUTING.md.

License

[Apache 2.0](LICENSE).