These are some tools for using C++14/17/20 features in pre-C++14/17/20 compilation, as well as some PLF-specific functions/objects. The tools are divided into 4 toolsets. Each toolset is #ifdef-guarded such that it will not be defined in a project more than once.
The first toolset, compiler defines, are assessments of availability of C++ features for most compilers (but mainly GCC/Clang/MSVC), resulting in defined macros for those features which are available. These are always instantiated, since they are used in the other 3 toolsets. An additional header, plf_tools_undef.h, undefines these macros - this can be used as needed at the end of a given project, however you should guard this with a per-file macro within your code if you're likely to have a class containing another class which also uses the tools eg. plf::list<plf::colony<int>>.
The other three toolsets are only instantiated if their matching macro is defined. These are:
The _INCLUDE macros are automatically undefined at the end of the .h, you do not need to undefine them manually.
The macros are:
See the header file for more information on all of these definitions and what they represent. The _noexcept, _constexpr and _constfunc macros are always defined, only their value changes. The _support macros are either defined or undefined.
In addition some supplementary macros are defined for construction/etc of objects using either std::allocator or std::allocator_traits, and with or without variadic support, based on the C++ version:
The functions above are equivalents to their C++20 counterparts and will use the std:: versions internally if C++20/above is available, however countr/countl specifically do not check whether the supplied number is zero if the underlying platform only supports BSR instructions (only very old CPUs). This is intentional as the projects I use these functions in never supply zero.
The above take an allocator, however if the allocator is determined to not have it's own custom construct function, the functions will use std::uninitialized_copy/move/fill_n internally. This means that if the allocator has a custom construct, it gets used and anything using these functions remains allocator-aware. If it doesn't, we get to use the internal optimizations typically-available in std::uninitialized_copy/move/fill_n (eg. for scalar types, fill_n may use memset or AVX fills). uninitialized_fill is not supplied as I don't need it. These are useful for using the functions with allocator-aware containers.
These tools are under a permissive zlib license. This means: Software is used on 'as-is' basis. It can be modified and used in commercial software. Authors are not liable for any damages arising from its use. The distribution of a modified version of the software is subject to the following restrictions:
Download here or view
the repository
The library is a simple .h header file, to be included with a #include
command. Optionally the plf_tools_undef.h file can be included at the end of a project to undefine the compiler support macros.
Contact: 
plf:: library and this page Copyright (c) 2026, Matthew Bentley