This is a header-only C++11 library that provides several new or lesser-known containers, most of which can be used in C++20 constant expressions.
vector— Vector equivalent tostd::vector, but not specialized forbool.devector— Double-ended vector that allows faster insertion and deletion at the front compared tovector.small_vector— Vector that embeds small statically allocated storage internally to avoid dynamic memory allocation when the number of elements is small.static_vector— Vector with a fixed maximum capacity defined at compile time, backed entirely by statically allocated storage. Dynamic memory is never used.compact_vector— Vector whosecapacity()is always equal to itssize(). It is inspired by OpenFOAM's containerList.segmented_vector— Vector with segmented storage that allows fast insertion and deletion at the back without memory reallocation.segmented_devector— Double-ended vector with segmented storage that allows fast insertion and deletion at both the front and back without memory reallocation. It is a superior alternative tostd::deque.
small_unordered_linear_mapsmall_unordered_linear_setsmall_unordered_linear_multimapsmall_unordered_linear_multiset
static_unordered_linear_mapstatic_unordered_linear_setstatic_unordered_linear_multimapstatic_unordered_linear_multiset
- Compiles with GCC 4.8.5 and Clang 3.4.2.
- Most containers can be used in C++20 constant expressions. For more information, please see section C++20 constexpr.
- Containers support stateful allocators and allocators with fancy pointers.
- Containers provide a range constructor
container(sfl::from_range_t, Range&& r)in C++11. - Containers provide a range insertion member function
insert_range(Range&& r)in C++11. - Maps and sets support heterogeneous insertion, erasure, and lookup in C++11.
- Functions taking iterator ranges properly handle input iterators.
- There is no undefined behavior when constructing maps and sets from ranges containing duplicates.
- There is no undefined behavior when inserting ranges containing duplicates into maps and sets.
- Vectors are not specialized for
bool. - Static containers can be used in bare-metal embedded software development.
This library requires C++11 compiler or newer. If available, library uses features of newer C++ standards.
Tested compilers:
- GCC 4.8.5 on CentOS 7 (C++11)
- Clang 3.4.2 on CentOS 7 (C++11)
- GCC 7.3.1 on CentOS 7 (C++11, 14, 17)
- Clang 5.0.1 on CentOS 7 (C++11, 14, 17)
- GCC 15.2.1 on Arch Linux (C++11, 14, 17, 20, 23)
- Clang 22.1.1 on Arch Linux (C++11, 14, 17, 20, 23)
- MSVC 19.44 (C++14, 17, 20, latest)
Step 1: Copy sfl subdirectory from include into your project directory.
Step 2: Configure your project or compiler to search for include files in the directory containing sfl subdirectory.
Step 3: #include what you need.
This library can be integrated into CMake project using CMake module FetchContent.
Step 1: Add the following lines into your CMakeLists.txt:
include(FetchContent)
FetchContent_Declare(
sfl
GIT_REPOSITORY https://github.com/slavenf/sfl-library)
FetchContent_MakeAvailable(sfl)Step 2: Add this library as a dependency into your CMakeLists.txt::
target_link_libraries(your_target_name PRIVATE sfl)Step 3: #include what you need.
All containers except those with the small_* prefix are usable in C++20 constant expressions.
Containers with the small_* prefix are currently not usable in constant expressions, but support may be added in future library versions.
This library provides sfl::hash, a drop-in replacement for std::hash that can be used in C++20 constant expressions. All unordered associative containers are using sfl::hash as a default key hash functors.
Support for C++20 constant expressions is not fully mature in the major compilers (GCC, Clang, and MSVC), so the following limitations apply:
- The
data()member function of anystatic_*container cannot be used in constant expressions. - On GCC, it is not possible to declare
constexprobjects ofstatic_*containers, whereas Clang and MSVC allow it. This is a compiler-specific limitation (possibly a bug). - On MSVC, when using
unordered_*orstatic_unordered_*containers in constant expressions:- Both the key hash (
KeyHash) and key equality (KeyEqual) functors must be empty types:std::is_empty<KeyHash>::value == true std::is_empty<KeyEqual>::value == true
- The default functors (
sfl::hashandstd::equal_to) are already empty, so this restriction does not apply when using them. - This limitation only applies in constant expressions; it does not affect usage in non-constant expressions. This is a compiler bug.
- Both the key hash (
This library by default throw exceptions in case of error.
If macro SFL_NO_EXCEPTIONS is defined then library avoids using exceptions and calls std::abort in case of error.
This library does not automatically detect whether the compiler is invoked with appropriate flag or not, like -fno-exceptions in GCC and Clang.
This library extensively uses macro assert from header <cassert>.
The definition of the macro assert depends on another macro, NDEBUG, which is not defined by the standard library.
If macro NDEBUG is defined then assert does nothing.
If macro NDEBUG is not defined then assert performs check. If check fails, assert outputs implementation-specific diagnostic information on the standard error output and calls std::abort.
The detailed documentation is located in directory doc. The detailed documentation is handwritten in Markdown format, it is not automatically generated with tools like Doxygen, so there may be some errors or mistakes. If you find one, please report it.
Test programs and scripts are located in directory test.
Tested compilers are listed in section Requirements.
Each test program is checked with Valgrind tool.
Licensed under zlib license. The license text is in file LICENSE.txt.