• Stars
    star
    230
  • Rank 173,384 (Top 4 %)
  • Language
    C++
  • License
    Boost Software Li...
  • Created almost 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

variant lite - A C++17-like variant, a type-safe union for C++98, C++11 and later in a single-file header-only library

variant lite: A single-file header-only version of a C++17-like variant, a type-safe union for C++98, C++11 and later

Language License Build Status Build status Version Latest download Conan Try it online Try it on godbolt online

Contents

Example usage

#include "nonstd/variant.hpp"

#include <cassert>
#include <string>

using namespace nonstd;

int main()
{
    std::string hello = "hello, world"; 

    variant< char, int, long, std::string > var;
    
    var =  'v' ; assert( get<  0 >( var ) == 'v' );
                 assert( get<char>( var ) == 'v' );
    var =   7  ; assert( get<int >( var ) ==  7  );
    var =  42L ; assert( get<long>( var ) == 42L );    
    var = hello; assert( get<std::string>( var ) == hello );
}

Compile and run

prompt>g++ -std=c++98 -Wall -I../include -o 01-basic.exe 01-basic.cpp && 01-basic.exe

In a nutshell

variant lite is a single-file header-only library to represent a type-safe union. The library aims to provide a C++17-like variant for use with C++98 and later. If available, std::variant is used.

Features and properties of variant lite are ease of installation (single header), freedom of dependencies other than the standard library and control over object alignment (if needed). variant lite shares the approach to in-place tags with any-lite, expected-lite and with optional-lite and these libraries can be used together.

Limitations of variant lite concern the number of alternative types and the number of visitor arguments. The maximum number of types and visitor arguments are configurable via script generate_header.py (default: 16 types, 5 visitor arguments). With C++98, the alternative types are required to be of different type and there's no move construction, move assignment and emplacement. variant lite does not provide allocator-extended constructors.

License

variant lite is distributed under the Boost Software License.

Dependencies

variant lite has no other dependencies than the C++ standard library.

Installation

variant lite is a single-file header-only library. Put variant.hpp in the include folder directly into the project source tree or somewhere reachable from your project.

Or, if you use the conan package manager, you might follow these steps:

  1. Create source file ./main.cpp, e.g. with the contents of the example code above.

  2. Create ./conanfile.txt file with a reference to variant-lite in the requires section:

    [requires]
    variant-lite/1.2.2  # variant-lite/2.0.0 when available
    
    [generators]
    cmake
    
  3. Create ./CMakeLists.txt:

    cmake_minimum_required(VERSION 3.1)
    project(variant-example CXX)
    
    include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
    conan_basic_setup()
    
    add_executable(${PROJECT_NAME} main.cpp)
    target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
  4. Run the following commands:

    mkdir build && cd build
    conan install .. --settings arch=x86 --settings compiler=gcc
    cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
    cmake --build . --config Release
    

Synopsis

Contents

Types in namespace nonstd

Purpose Type Notes
Type-safe union template< class T0...T6 >
class variant
non-standard: may hold up to seven types
Default constructible class monostate Type to make variant default constructible
Error reporting class bad_variant_access  
In-place construction struct in_place_tag  
  in_place select type or index for in-place construction
  in_place_type select type for in-place construction
  in_place_index select index for in-place construction
  nonstd_lite_in_place_type_t( T) macro for alias template in_place_type_t<T>
  nonstd_lite_in_place_index_t( T ) macro for alias template in_place_index_t<T>
Variant size template<...>
struct variant_size< variant<...> >
 
  variant_size_v< T > C++14
  variant_size_V( T ) macro for nonstd::variant_size<T>::value
Select variant type template< std::size_t I, ...>
struct variant_alternative< I, variant<...> >
 
  variant_alternative_t< I, T > C++11
  variant_alternative_T( I, T ) macro for typename nonstd::variant_alternative<I,T >::type

Interface of variant lite

Kind Std Method Result
Construction   variant() default-construct first type
    variant( Tx const & x ) copy-construct with value type Tx
  C++11 variant( Tx && x ) move-construct with value type Tx
    variant( variant const & rhs ) copy-construct from other variant
  C++11 variant( variant && rhs ) move-construct from other variant
  C++11 template< class T, class... Args >
explicit variant( in_place_type_t(T), Args&&... args)
in-place-construct type T
  C++11 template< class T, class U, class... Args >
explicit variant( in_place_type_t(T),
 std::initializer_list<U> il, Args&&... args )
in-place-construct type T
  C++11 template< std::size_t I, class... Args >
explicit variant( in_place_index_t(I), Args&&... args )
in-place-construct type at index I
  C++11 template< size_t I, class U, class... Args>
explicit variant( in_place_index_t(I),
 std::initializer_list<U> il, Args&&... args )
in-place-construct type at index I
Destruction   ~variant() destruct current content
Assignment   variant & operator=( variant const & rhs ) copy-assign from other
  C++11 variant & operator=( variant && rhs ) move-assign from other
  C++11 template< class Tx >
variant & operator=( Tx && t )
move-assign from value
  < C++11 template< class Tx >
variant & operator=( Tx const & t )
copy-assign from value;
non-standard
State   std::size_t index() const index of current content's type
    bool valueless_by_exception() const true if no content is present
Emplace C++11 template< class T, class... Args >
T & emplace( Args&&... args )
emplace type T
  C++11 template< class T, class U, class... Args >
T & emplace( std::initializer_list<U> il, Args&&... args )
emplace type T
  C++11 template< size_t I, class... Args >
variant_alternative_t<I,variant> &
emplace( Args&&... args );
emplace type at index I
  C++11 template< size_t I, class U, class... Args >
variant_alternative_t<I,variant> &
emplace( std::initializer_list<U> il, Args&&... args )
emplace type at index I
Swap   void swap( variant & other ); swap with other

Algorithms for variant lite

Kind Std Function
Relational operators    
==   template<...>
bool operator==( variant<...> const & v, variant<...> const & w )
!=   template<...>
bool operator==( variant<...> const & v, variant<...> const & w )
<   template<...>
bool operator<( variant<...> const & v, variant<...> const & w )
>   template<...>
bool operator>( variant<...> const & v, variant<...> const & w )
<=   template<...>
bool operator<=( variant<...> const & v, variant<...> const & w )
>=   template<...>
bool operator>=( variant<...> const & v, variant<...> const & w )
Content    
contains value of type T   template< class T, ...>
bool holds_alternative( variant<...> const & v ) [noexcept]
get by type   template< class R, ...>
R &
get( variant<...> & v, in_place_type_t(R) = in_place )
get by type (rvalue) C++11 template< class R, ...>
R &&
get( variant<...> && v, in_place_type_t(R) = in_place )
get by type (const)   template< class R, ...>
R const &
get( variant<...> const & v, in_place_type_t(R) = in_place )
get by type (const rvalue) C++11 template< class R, ...>
R const &&
get( variant<...> const && v, in_place_type_t(R) = in_place )
get by index   template< std::size_t I, ...>
typename variant_alternative< I, variant<...> >::type &
get( variant<...> & v, in_place_index_t(I) = in_place )
get by index (rvalue) C++11 template< std::size_t I, ...>
typename variant_alternative< I, variant<...> >::type &&
get( variant<...> && v, in_place_index_t(I) = in_place )
get by index (const)   template< std::size_t I, ...>
typename variant_alternative< I, variant<...> >::type const &
get( variant<...> const & v, in_place_index_t(I) = in_place )
get by index (const rvalue) C++11 template< std::size_t I, ...>
typename variant_alternative< I, variant<...> >::type const &&
get( variant<...> const && v, in_place_index_t(I) = in_place )
get_if by type   template< class T, ...>
typename detail::add_pointer<T>::type
get_if( variant<...> * pv, in_place_type_t(T) = in_place )
get_if by type (const)   template< class T, ...>
typename detail::add_pointer<const T>::type
get_if( variant<...> const * pv, in_place_type_t(T) = in_place)
get_if by index   template< std::size_t I, ...>
typename detail::add_pointer< typename variant_alternative<I, variant<T0, T1, T2, T3, T4, T5, T6> >::type >::type
get_if( variant<...> * pv, in_place_index_t(I) = in_place )
get_if by index (const)   template< std::size_t I, ...>
typename detail::add_pointer< const typename variant_alternative<I, variant<T0, T1, T2, T3, T4, T5, T6> >::type >::type
get_if( variant<...> const * pv, in_place_index_t(I) = in_place )
swap   template<...>
void swap( variant<...> & x, variant<...> & y )
visit Note 1 template< class Visitor, class Variant >
Variant visit( Visitor const & vis, Variant const & v )
Hash support    
variant C++11 template<...> struct hash< variant<...> >;
monostate C++11 template<> struct hash< monostate >;

Note 1: visitor is limited to always return a Variant.

Information macros

variant_CONFIG_MAX_TYPE_COUNT
The maximum number of types thevariant can hold as configured via script generate_header.py.

variant_CONFIG_MAX_VISITOR_ARG_COUNT
The maximum number of visitor arguments as configured via script generate_header.py.

Configuration macros

Tweak header

If the compiler supports __has_include(), variant lite supports the tweak header mechanism. Provide your tweak header as nonstd/variant.tweak.hpp in a folder in the include-search-path. In the tweak header, provide definitions as documented below, like #define boolean_CPLUSPLUS 201103L.

Standard selection macro

-Dvariant_CPLUSPLUS=199711L
Define this macro to override the auto-detection of the supported C++ standard, or if your compiler does not set the __cplusplus macro correctly.

Select std::variant or nonstd::variant

At default, variant lite uses std::variant if it is available and lets you use it via namespace nonstd. You can however override this default and explicitly request to use std::variant or variant lite's nonstd::variant as nonstd::variant via the following macros.

-Dvariant_CONFIG_SELECT_VARIANT=variant_VARIANT_DEFAULT
Define this to variant_VARIANT_STD to select std::variant as nonstd::variant. Define this to variant_VARIANT_NONSTD to select nonstd::variant as nonstd::variant. Default is undefined, which has the same effect as defining to variant_VARIANT_DEFAULT.

Disable exceptions

-Dvariant_CONFIG_NO_EXCEPTIONS=0
Define this to 1 if you want to compile without exceptions. If not defined, the header tries and detect if exceptions have been disabled (e.g. via -fno-exceptions). Default is undefined.

Presence of variant_size_V() simulation macro

-Dvariant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO=0
Define this macro to 1 to omit the variant_size_V(T) macro. Default is 0.

Presence of variant_alternative_T() simulation macro

-Dvariant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO=0
Define this macro to 1 to omit the variant_alternative_T(I,T) macro. Default is 0.

Macros to control alignment

If variant lite is compiled as C++11 or later, C++11 alignment facilities are used for storage of the underlying object. When compiled as pre-C++11, variant lite tries to determine proper alignment itself. If this doesn't work out, you can control alignment via the following macros. See also section Implementation notes.

-Dvariant_CONFIG_MAX_ALIGN_HACK=0
Define this to 1 to use the max align hack for alignment. Default is 0.

-Dvariant_CONFIG_ALIGN_AS=pod_type
Define this to the pod-type you want to align to (no default).

-Dvariant_CONFIG_ALIGN_AS_FALLBACK=pod_type
Define this to the pod-type to use for alignment if the algorithm of variant lite cannot find a suitable POD type to use for alignment. Default is double.

Reported to work with

The table below mentions the compiler versions variant lite is reported to work with.

OS Compiler Versions
Windows Clang/LLVM ?
  GCC 5.2.0
  Visual C++
(Visual Studio)
8 (2005), 9 (2008), 10 (2010), 11 (2012),
12 (2013), 14 (2015), 15 (2017), 16 (2019)
GNU/Linux Clang/LLVM 3.5.0
  GCC 4.8.4
OS X ? ?

Building the tests

To build the tests you need:

The lest test framework is included in the test folder.

The following steps assume that the variant lite source code has been cloned into a directory named c:\variant-lite.

  1. Create a directory for the build outputs for a particular architecture. Here we use c:\variant-lite\build-win-x86-vc10.

     cd c:\variant-lite
     md build-win-x86-vc10
     cd build-win-x86-vc10
    
  2. Configure CMake to use the compiler of your choice (run cmake --help for a list).

     cmake -G "Visual Studio 10 2010" ..
    
  3. Build the test suite in the Debug configuration (alternatively use Release).

     cmake --build . --config Debug
    
  4. Run the test suite.

     ctest -V -C Debug
    

All tests should pass, indicating your platform is supported and you are ready to use variant lite.

Implementation notes

Object allocation and alignment

variant lite reserves POD-type storage for an object of the underlying type inside a union to prevent unwanted construction and uses placement new to construct the object when required. Using non-placement new (malloc) to obtain storage, ensures that the memory is properly aligned for the object's type, whereas that's not the case with placement new.

If you access data that's not properly aligned, it 1) may take longer than when it is properly aligned (on x86 processors), or 2) it may terminate the program immediately (many other processors).

Although the C++ standard does not guarantee that all user-defined types have the alignment of some POD type, in practice it's likely they do [10, part 2].

If variant lite is compiled as C++11 or later, C++11 alignment facilities are used for storage of the underlying object. When compiling as pre-C++11, variant lite tries to determine proper alignment using meta programming. If this doesn't work out, you can control alignment via three macros.

variant lite uses the following rules for alignment:

  1. If the program compiles as C++11 or later, C++11 alignment facilities are used.

  2. If you define -Dvariant_CONFIG_MAX_ALIGN_HACK=1 the underlying type is aligned as the most restricted type in struct max_align_t. This potentially wastes many bytes per variant if the actually required alignment is much less, e.g. 24 bytes used instead of the 2 bytes required.

  3. If you define -Dvariant_CONFIG_ALIGN_AS=pod-type the underlying type is aligned as pod-type. It's your obligation to specify a type with proper alignment.

  4. If you define -Dvariant_CONFIG_ALIGN_AS_FALLBACK=pod-type the fallback type for alignment of rule 5 below becomes pod-type. It's your obligation to specify a type with proper alignment.

  5. At default, variant lite tries to find a POD type with the same alignment as the underlying type.

    The algorithm for alignment of 5. is:

    • Determine the alignment A of the underlying type using alignment_of<>.
    • Find a POD type from the list alignment_types with exactly alignment A.
    • If no such POD type is found, use a type with a relatively strict alignment requirement such as double; this type is specified in variant_CONFIG_ALIGN_AS_FALLBACK (default double).

Note that the algorithm of 5. differs from the one Andrei Alexandrescu uses in [10, part 2].

The class template alignment_of<> is gleaned from Boost.TypeTraits, alignment_of [14].

For more information on constructed unions and alignment, see [10-14].

Other implementations of variant

Notes and References

Acknowledgments

Thanks to @flexferrum for making the number of variant types and visitor arguments configurable. Thanks to @siffiejoe for contributing to fixing lifetime, noexcept and hash issues.

References

[1] CppReference. Variant.

[2] ISO/IEC WG21. N4606, section 20.7 Variants. July 2016.

[3] Axel Naumann. Variant: a type-safe union for C++17 (v8). June 2016.

[4] Peter Dimov. Valueless Variants Considered Harmful. March 2016.

[5] Anthony Williams. Standardizing Variant: Difficult Decisions. June 2015

[6] Andrzej Krzemieński. Constexpr unions. December 2012.

[7] Agustín Bergé. Eggs.Variant - Part I. August 2014.

[8] Agustín Bergé. Eggs.Variant - Part II (the constexpr experience). March 2015.

[9] Andrei Alexandrescu. An Implementation of Discriminated Unions in C++. August 2002.

[10] Andrei Alexandrescu. Generic: Discriminated Unions part 1, part 2, part 3. April 2002.

[11] Herb Sutter. Style Case Study #3: Construction Unions. GotW #85. 2009

[12] Kevin T. Manley. Using Constructed Types in C++ Unions. C/C++ Users Journal, 20(8), August 2002.

[13] StackOverflow. Determining maximum possible alignment in C++.

[14] Boost.TypeTraits, alignment_of ( code ).

Presentations

[15] Ben Deane. Using Types Effectively. CppCon 2016.

Appendix

A.1 Compile-time information

The version of variant lite is available via tag [.version]. The following tags are available for information on the compiler and on the C++ standard library used: [.compiler], [.stdc++], [.stdlanguage] and [.stdlibrary].

A.2 Variant lite test specification

click to expand

variant: Disallows non-default constructible as first type
variant: Allows non-default constructible as second and later type (first: int)
variant: Allows non-default constructible as second and later type (first: monostate)
variant: Allows multiple identical types (C++11)
variant: Allows to default-construct variant
variant: Allows to copy-construct from variant
variant: Allows to move-construct from variant (C++11)
variant: Allows to move-construct if-noexcept from variant (C++11)
variant: Allows to obtain the index of the current type
variant: Allows to inspect if variant is "valueless by exception"
variant: Allows to copy-assign from variant
variant: Allows to copy-assign mutually empty variant
variant: Allows to copy-assign from empty variant
variant: Allows to copy-assign to empty variant
variant: Allows to move-assign from variant (C++11)
variant: Allows to move-assign mutually empty variant (C++11)
variant: Allows to move-assign from empty variant (C++11)
variant: Allows to move-assign to empty variant (C++11)
variant: Allows to construct from element value
variant: Allows to copy-construct from element
variant: Allows to move-construct from element (C++11)
variant: Allows to convert-copy-construct from element
variant: Allows to convert-move-construct from element (C++11)
variant: Allows to copy-assign from element value
variant: Allows to move-assign from element value
variant: Allows to copy-assign from element
variant: Allows to move-assign from element (C++11)
variant: Allows to convert-copy-assign from element value
variant: Allows to copy-construct from elements in intializer-list based on type (C++11)
variant: Allows to move-construct from elements in intializer-list based on type (C++11)
variant: Allows to in-place copy-construct element based on type (C++11)
variant: Allows to in-place move-construct element based on type (C++11)
variant: Allows to in-place copy-construct element based on index (C++11)
variant: Allows to in-place move-construct element based on index (C++11)
variant: Allows to in-place copy-construct elements from intializer-list based on type (C++11)
variant: Allows to in-place move-construct elements from intializer-list based on type (C++11)
variant: Allows to in-place copy-construct elements from intializer-list based on index (C++11)
variant: Allows to in-place move-construct elements from intializer-list based on index (C++11)
variant: Allows to copy-emplace element based on type (C++11)
variant: Disallows to copy-emplace non-unique element type on type (C++11)
variant: Allows to move-emplace element based on type (C++11)
variant: Allows to copy-emplace element based on index (C++11)
variant: Allows to move-emplace element based on index (C++11)
variant: Allows to copy-emplace elements from intializer-list based on type (C++11)
variant: Allows to move-emplace elements from intializer-list based on type (C++11)
variant: Allows to copy-emplace elements from intializer-list based on index (C++11)
variant: Allows to move-emplace elements from intializer-list based on index (C++11)
variant: Allows to swap variants, same index (member)
variant: Allows to swap variants, different index (member)
variant: Allows to visit contents (args: 1; configured max args: 5)
variant: Allows to visit contents (args: 2; configured max args: 5)
variant: Allows to visit contents (args: 3; configured max args: 5)
variant: Allows to visit contents, rvalue reference (args: 1; configured max args: 5)
variant: Allows to check for content by type
variant: Allows to get element by type
variant: Allows to get element by index
variant: Allows to get pointer to element or NULL by type
variant: Allows to get pointer to element or NULL by index
variant: Allows to compare variants
variant: Allows to swap variants, same index (non-member)
variant: Allows to swap variants, different index (non-member)
monostate: Allows to make variant default-constructible
bad_variant_access: Indicates invalid variant access
variant_size<>: Allows to obtain number of element types (configured max types: 16)
variant_size_v<>: Allows to obtain number of element types (C++14; configured max types: 16)
variant_size_V(): Allows to obtain number of element types (non-standard: macro; configured max types: 16)
variant_alternative<>: Allows to select type by index
variant_alternative_t<>: Allows to select type by index (C++11)
variant_alternative_T(): Allows to select type by index (non-standard: macro)
std::hash<>: Allows to obtain hash (C++11)
tweak header: reads tweak header if supported [tweak]

More Repositories

1

span-lite

span lite - A C++20-like span for C++98, C++11 and later in a single-file header-only library
C++
495
star
2

optional-lite

optional lite - A C++17-like optional, a nullable object for C++98, C++11 and later in a single-file header-only library
C++
393
star
3

lest

A modern, C++11-native, single-file header-only, tiny framework for unit-tests, TDD and BDD (includes C++98 variant)
C++
366
star
4

string-view-lite

string_view lite - A C++17-like string_view for C++98, C++11 and later in a single-file header-only library
C++
364
star
5

expected-lite

expected lite - Expected objects in C++11 and later in a single-file header-only library
C++
274
star
6

ring-span-lite

ring-span lite - A C++yy-like ring_span type for C++98, C++11 and later in a single-file header-only library
C++
136
star
7

any-lite

any lite - A C++17-like any, a type-safe container for single values of any type for C++98, C++11 and later in a single-file header-only library
C++
123
star
8

PhysUnits-CT-Cpp11

A small C++11, C++14 header-only library for compile-time dimensional analysis and unit/quantity manipulation and conversion
C++
77
star
9

nonstd-lite

Parent of *-lite repositories, a migration path to post-C++11 features for pre-C++11 environments
Batchfile
68
star
10

clue

A tiny single-file header-only C++ logging framework
C++
56
star
11

jthread-lite

C++20's jthread for C++11 and later in a single-file header-only library
C++
53
star
12

expected-dark

Expected objects for C++11 and later (and later perhaps C++98 )
C++
52
star
13

byte-lite

byte lite - A C++17-like byte type for C++98, C++11 and later in a single-file header-only library
C++
51
star
14

value-ptr-lite

value-ptr-lite - A C++ smart-pointer with value semantics for C++98, C++11 and later in a single-file header-only library
C++
44
star
15

observer-ptr-lite

observer-ptr - An observer_ptr for C++98 and later in a single-file header-only library (Extensions for Library Fundamentals, v2, v3)
C++
36
star
16

scope-lite

A migration path to C++ library extensions scope_exit, scope_fail, scope_success, unique_resource
C++
34
star
17

type-lite

type - Strong types for C++98, C++11 and later in a single-file header-only library
C++
34
star
18

bit-lite

bit-lite - C++20 bit operations for C++98 and later in a single-file header-only library
C++
33
star
19

martin-moene.blogspot.com

Code from my Blog
C++
30
star
20

invoke-lite

A single-file header-only version of C++17-like invoke() for C++98, C++11 and later
C++
29
star
21

catch-lest-other-comparison

Tabularised feature comparison between Catch, doctest and lest C++ test frameworks
23
star
22

kalman-estimator

kalman-estimator - a Kalman estimator in C++
C++
22
star
23

string-lite

String facilities for C++98 and later - a library in search of its identity.
C++
19
star
24

optional-bare

optional bare - A simple version of a C++17-like optional for default-constructible, copyable types, for C++98 and later in a single-file header-only library
C++
18
star
25

spike-expected

expected: kind of optional?
HTML
16
star
26

status-value-lite

status-value - A class for status and optional value for C++11 and later, C++98 variant provided in a single-file header-only library
C++
14
star
27

atomic-lite

atomic lite - a C++11 atomic operations library for C++98 and later
C++
12
star
28

PhysUnits-RT

A C++ header-only library for run-time dimensional analysis and unit/quantity manipulation and conversion
C++
11
star
29

PhysUnits-CT

A C++ header-only library for compile-time dimensional analysis and unit/quantity manipulation and conversion
C++
11
star
30

WholeValue

Whole value idiom made easy in C++
C++
8
star
31

optional-fun-lite

optional-fun lite - Functional algorithms for optional (lite) for C++98, C++11 and later in a single-file header-only library
C++
6
star
32

EngFormat-Cpp

C++ based Engineering Notation Formatter
C++
6
star
33

indirect-value-lite

indirect_value lite – An indirect value-type for C++11 and later in a single-file header-only library (p1950)
C++
6
star
34

ACCUConf2016

Slides and other materials from ACCU Conference 2016
5
star
35

array_view2d

A simple 2D view on an array or vector for C++98 and C++11
C++
5
star
36

clamp

Limit a value or a range of values to fall between two extremes
C++
4
star
37

boolean-lite

boolean lite: A strong boolean type for C++98 and later
C++
4
star
38

svn-churn

A simple Python script to determine file churn and fix count of a Subversion repository.
Python
3
star
39

active-lite

Active objects
CMake
2
star
40

clamp-proposal

Propose clamp for C++ standard
CSS
2
star
41

kalman-estimator-ada

kalman-estimator - a Kalman estimator in Ada, sibling of Kalman estimator in C++
Makefile
2
star
42

nonstd-lite-project

Stuff common to nonstd lite repositories
CMake
2
star
43

Test-Normalised

1
star
44

bibliography

My bookshelf
TeX
1
star
45

hamlest

Matchers for lest
C++
1
star
46

wordindex

wordindex: create a linenumber cross-referenced list of words
C++
1
star
47

Test-NonNormalised

1
star
48

wordindex-ranged

wordindex: create a linenumber cross-referenced list of words using C++20 std::ranges
C++
1
star
49

testdox

TestDox - generate a readable overview of test case names from the specified files.
Hack
1
star