Freundlich's C++ toolkit
No Matches

Freundlich's C++ Toolkit (fcppt) is a collection of libraries that aim to improve general C++ code through better typing and functional programming.

Source code and downloads

The source code and releases are available on github.


See Installation and Usage on how to install fcppt and on how to use it in your project.


Avoiding partial functions (functions that do not terminate, i.e. crash, on certain inputs) is one of fcppt's main goals. These are, unfortunately, all over the place in common C or C++ code: std::unique_ptr can be null, operator[] of std::vector can be used for out-of-bounds access, iterators can be incremented past their end, and so on. Partial functions place a huge burden on the programmer since they have to ensure that no code path is taken that actually calls a function with invalid arguments. Consider the following example, where we avoid partial functions:

void print_at_2(std::vector<int> const &_vec)
[] { std::cout << "No value at position 2\n"; },
std::cout << "The value is " << _value.get() << '\n';

The fcppt::container::at_optional function returns an optional reference into the container, which the fcppt::optional::maybe function uses to either print the value or print that no element at position 2 exists. Notice we do not ask explicitly if the optional has a value or dereference it (which can crash if the value is null).

Explicit loops are another source of mistakes: The loop not only specifies what to loop over but also how the result is formed. What to loop over is best expressed using ranges, while forming the result can be expressed using special algorithms. A very common operation is mapping one container into another. Here, we want to convert a container of integers into a container of strings by using fcppt::output_to_std_string, which converts any type into a string that has an output operator defined:

std::vector<std::string> int_vec_to_string_vec(std::vector<int> &&_vec)
return fcppt::algorithm::map<std::vector<std::string>>(
std::move(_vec), [](int const _value) { return fcppt::output_to_std_string(_value); });

Code using a standard loop would allocate an empty vector and then use push_back repeatedly. For good performance, it should also call reserve before the first push_back. All of this is nicely encapsulated in fcppt::algorithm::map, so that you only have to focus on how to transform a single element into another.

This also brings us to the next point, which is initialization. It is important to directly initialize objects and declare them as const whenever possible. Obviously you cannot do that with loops that change their result in each iteration, like by calling push_back. There are, however, even more complicated cases in which direct initialization becomes hard to express: Consider an array that should be initialized depending on its size. For simplicity, let us initialize each element with its index:

template <std::size_t N>
struct make_value
static constexpr unsigned int const value = fcppt::cast::size<unsigned int>(N);
template <std::size_t N>
[]<std::size_t Index>(std::integral_constant<std::size_t, Index>)
{ return make_value<Index>::value; });

Notice that the parameter is actually an integral constant, which we use to access the make_value template.

To force initialization, fcppt also replaces certain standard types with types that have no default constructor, for example fcppt::unique_ptr, fcppt::function and fcppt::variant::object.

Following is a list of a few other libraries (for a complete list, see the modules page at the top):

  • fcppt.record allows to create record types, which are a collection of statically named elements.
  • fcppt.options provides declarative command-line option parsers, similar to Haskell's optparse-applicative library.
  • fcppt.either carries a success or an error value. In comparison, fcppt.optional only has a single error value.
  • fcppt.optional provides utility functions for optionals.
  • fcppt.enum allows, for example, to iterate over enums, convert enums from and to strings, create arrays that are indexed by enums, and so on.

For more technical details, you can also take a look at our Coding style.

Site map

The documentation is split into the following parts: