{"id":15047256,"url":"https://github.com/nonstd-lite/variant-lite","last_synced_at":"2026-04-06T00:03:17.285Z","repository":{"id":53744730,"uuid":"70513372","full_name":"martinmoene/variant-lite","owner":"martinmoene","description":"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","archived":false,"fork":false,"pushed_at":"2025-01-31T21:21:37.000Z","size":486,"stargazers_count":238,"open_issues_count":6,"forks_count":27,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-03T21:12:42.920Z","etag":null,"topics":["cpp17","cpp98","header-only","no-dependencies","single-file","variant","variant-implementations"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martinmoene.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-10T17:45:14.000Z","updated_at":"2025-03-25T19:01:26.000Z","dependencies_parsed_at":"2025-02-12T11:05:05.557Z","dependency_job_id":"8cb3009d-488b-4a30-ac72-1f270099a3b1","html_url":"https://github.com/martinmoene/variant-lite","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Fvariant-lite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Fvariant-lite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Fvariant-lite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Fvariant-lite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martinmoene","download_url":"https://codeload.github.com/martinmoene/variant-lite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248618218,"owners_count":21134199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp17","cpp98","header-only","no-dependencies","single-file","variant","variant-implementations"],"created_at":"2024-09-24T20:55:49.281Z","updated_at":"2025-12-30T00:03:20.856Z","avatar_url":"https://github.com/martinmoene.png","language":"C++","funding_links":[],"categories":["Standard/Support Libraries"],"sub_categories":[],"readme":"# 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\n\n[![Language](https://img.shields.io/badge/C%2B%2B-98/11+-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![License](https://img.shields.io/badge/license-BSL-blue.svg)](https://opensource.org/licenses/BSL-1.0) [![Build Status](https://github.com/martinmoene/variant-lite/actions/workflows/ci.yml/badge.svg)](https://github.com/martinmoene/variant-lite/actions/workflows/ci.yml) [![Version](https://badge.fury.io/gh/martinmoene%2Fvariant-lite.svg)](https://github.com/martinmoene/variant-lite/releases) [![Latest download](https://img.shields.io/badge/latest-download-blue.svg)](https://raw.githubusercontent.com/martinmoene/variant-lite/master/include/nonstd/variant.hpp) [![Repology](https://img.shields.io/badge/on-repology-blue.svg)](https://repology.org/projects/?search=variant-lite) [![Vcpkg](https://img.shields.io/badge/on-vcpkg-blue.svg)](https://vcpkg.link/ports/variant-lite) [![Try it online](https://img.shields.io/badge/on-wandbox-blue.svg)](https://wandbox.org/permlink/tpG9nmapo2mUKUCo) [![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/WY7HhQ)\n\n**Contents**  \n- [Example usage](#example-usage)\n- [In a nutshell](#in-a-nutshell)\n- [License](#license)\n- [Dependencies](#dependencies)\n- [Installation](#installation)\n- [Synopsis](#synopsis)\n- [Features](#features)\n- [Reported to work with](#reported-to-work-with)\n- [Building the tests](#building-the-tests)\n- [Other implementations of variant](#other-implementations-of-variant)\n- [Notes and references](#notes-and-references)\n- [Appendix](#appendix)\n\n## Example usage\n\n```Cpp\n#include \"nonstd/variant.hpp\"\n\n#include \u003ccassert\u003e\n#include \u003cstring\u003e\n\nusing namespace nonstd;\n\nint main()\n{\n    std::string hello = \"hello, world\"; \n\n    variant\u003c char, int, long, std::string \u003e var;\n    \n    var =  'v' ; assert( get\u003c  0 \u003e( var ) == 'v' );\n                 assert( get\u003cchar\u003e( var ) == 'v' );\n    var =   7  ; assert( get\u003cint \u003e( var ) ==  7  );\n    var =  42L ; assert( get\u003clong\u003e( var ) == 42L );    \n    var = hello; assert( get\u003cstd::string\u003e( var ) == hello );\n}\n```\n\n### Compile and run\n\n```Console\nprompt\u003eg++ -std=c++98 -Wall -I../include -o 01-basic.exe 01-basic.cpp \u0026\u0026 01-basic.exe\n```\n\n## In a nutshell\n\n**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](http://en.cppreference.com/w/cpp/utility/variant) for use with C++98 and later. If available, std::variant is used. \n\n**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](https://github.com/martinmoene/any-lite), [expected-lite](https://github.com/martinmoene/expected-lite)  and with [optional-lite](https://github.com/martinmoene/optional-lite) and these libraries can be used together.\n\n**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](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.\n\n## License\n\n*variant lite* is distributed under the [Boost Software License](LICENSE.txt).\n \n## Dependencies\n\n*variant lite* has no other dependencies than the [C++ standard library](http://en.cppreference.com/w/cpp/header).\n\n## Installation\n\n*variant lite* is a single-file header-only library. Put `variant.hpp` in the [include](include) folder directly into the project source tree or somewhere reachable from your project.\n\nOr, if you use the [conan package manager](https://www.conan.io/), you might follow these steps:\n\n1. Create source file `./main.cpp`, e.g. with the contents of the example code above.\n\n2. Create `./conanfile.txt` file with  a reference to *variant-lite* in the *requires* section:\n    ```Conan\n    [requires]\n    variant-lite/1.2.2  # variant-lite/2.0.0 when available\n\n    [generators]\n    cmake\n    ```\n\n3. Create `./CMakeLists.txt`:\n    ```CMake\n    cmake_minimum_required(VERSION 3.1)\n    project(variant-example CXX)\n\n    include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)\n    conan_basic_setup()\n\n    add_executable(${PROJECT_NAME} main.cpp)\n    target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})\n    ```\n\n4. Run the following commands:\n    ```Text\n    mkdir build \u0026\u0026 cd build\n    conan install .. --settings arch=x86 --settings compiler=gcc\n    cmake .. -G \"Unix Makefiles\" -DCMAKE_BUILD_TYPE=Release\n    cmake --build . --config Release\n    ```\n\n## Synopsis\n\n**Contents**  \n- [Types in namespace nonstd](#types-in-namespace-nonstd)  \n- [Interface of *variant lite*](#interface-of-variant-lite)  \n- [Algorithms for *variant lite*](#algorithms-for-variant-lite)  \n- [Information macros](#information-macros)\n- [Configuration macros](#configuration-macros)\n- [Macros to control alignment](#macros-to-control-alignment)  \n\n### Types in namespace nonstd\n\n| Purpose               | Type | Notes |\n|-----------------------|------|-------|\n| Type-safe union       | template\u0026lt; class T0...T6 \u003e\u003cbr\u003eclass **variant** | non-standard: may hold up to seven types |\n| Default constructible | class **monostate**                  | Type to make variant default constructible |\n| Error reporting       | class **bad_variant_access**         | \u0026nbsp; |\n| In-place construction | struct **in_place_tag**              | \u0026nbsp; |\n| \u0026nbsp;                | **in_place**                         | select type or index for in-place construction |\n| \u0026nbsp;                | **in_place_type**                    | select type for in-place construction |\n| \u0026nbsp;                | **in_place_index**                   | select index for in-place construction |\n| \u0026nbsp;                | **nonstd_lite_in_place_type_t**( T)  | macro for alias template in_place_type_t\u0026lt;T\u003e  |\n| \u0026nbsp;                | **nonstd_lite_in_place_index_t**( T )| macro for alias template in_place_index_t\u0026lt;T\u003e |\n| Variant size          | template\u0026lt;...\u003e\u003cbr\u003estruct **variant_size**\u0026lt; variant\u0026lt;...\u003e \u003e | \u0026nbsp;|\n| \u0026nbsp;                | **variant_size_v**\u0026lt; T \u003e           | C++14 |\n| \u0026nbsp;                | **variant_size_V**( T )              | macro for nonstd::variant_size\u0026lt;T\u003e::value |\n| Select variant type   | template\u0026lt; std::size_t I, ...\u003e\u003cbr\u003estruct **variant_alternative**\u0026lt; I, variant\u0026lt;...\u003e \u003e | \u0026nbsp; |\n| \u0026nbsp;                | **variant_alternative_t**\u0026lt; I, T \u003e | C++11 |\n| \u0026nbsp;                | **variant_alternative_T**( I, T )    | macro for typename nonstd::variant_alternative\u0026lt;I,T \u003e::type |\n\n### Interface of *variant lite*\n\n| Kind         |Standard| Method                                       | Result |\n|--------------|--------|----------------------------------------------|--------|\n| Construction |\u0026nbsp;| **variant**()                                    | default-construct first type      |\n| \u0026nbsp;       |C++98 | **variant**( Tx const \u0026 x )                      | copy-construct with value type Tx, non-converting |\n| \u0026nbsp;       |C++11 | **variant**( T \u0026\u0026 x )                            | universal-construct from value type T |\n| \u0026nbsp;       |\u0026nbsp;| **variant**( variant const \u0026 rhs )               | copy-construct from other variant |\n| \u0026nbsp;       |C++11 | **variant**( variant \u0026\u0026 rhs )                    | move-construct from other variant |\n| \u0026nbsp;       |C++11 | template\u0026lt; class T, class... Args \u003e\u003cbr\u003eexplicit **variant**( in_place_type_t(T), Args\u0026\u0026... args) | in-place-construct type T |\n| \u0026nbsp;       |C++11 | template\u0026lt; class T, class U, class... Args \u003e\u003cbr\u003eexplicit **variant**( in_place_type_t(T),\u003cbr\u003e\u0026emsp;std::initializer_list\u0026lt;U\u003e il, Args\u0026\u0026... args ) | in-place-construct type T|\n| \u0026nbsp;       |C++11 | template\u0026lt; std::size_t I, class... Args \u003e\u003cbr\u003eexplicit **variant**( in_place_index_t(I), Args\u0026\u0026... args ) | in-place-construct type at index I | \n| \u0026nbsp;       |C++11 | template\u0026lt; size_t I, class U, class... Args\u003e\u003cbr\u003eexplicit **variant**( in_place_index_t(I),\u003cbr\u003e\u0026emsp;std::initializer_list\u0026lt;U\u003e il, Args\u0026\u0026... args ) | in-place-construct type at index I|\n| Destruction  |\u0026nbsp;| **~variant**()                                   | destruct current content |\n| Assignment   |\u0026nbsp;| variant \u0026 **operator=**( variant const \u0026 rhs )   | copy-assign from other |\n| \u0026nbsp;       |C++11 | variant \u0026 **operator=**( variant \u0026\u0026 rhs )        | move-assign from other |\n| \u0026nbsp;       |C++11 | template\u0026lt; class Tx \u003e\u003cbr\u003evariant \u0026 **operator=**( T \u0026\u0026 t ) | universal-assign from value type T |\n| \u0026nbsp;       |C++98 | template\u0026lt; class Tx \u003e\u003cbr\u003evariant \u0026 **operator=**( Tx const \u0026 t ) | copy-assign from value;\u003cbr\u003enon-standard |\n| State        |\u0026nbsp;| std::size_t **index**() const                    | index of current content's type |\n| \u0026nbsp;       |\u0026nbsp;| bool **valueless_by_exception**() const          | true if no content is present |\n| Emplace      |C++11 | template\u0026lt; class T, class... Args \u003e\u003cbr\u003eT \u0026 **emplace**( Args\u0026\u0026... args ) | emplace type T |\n| \u0026nbsp;       |C++11 | template\u0026lt; class T, class U, class... Args \u003e\u003cbr\u003eT \u0026 **emplace**( std::initializer_list\u0026lt;U\u003e il, Args\u0026\u0026... args ) | emplace type T |\n| \u0026nbsp;       |C++11 | template\u0026lt; size_t I, class... Args \u003e\u003cbr\u003evariant_alternative_t\u0026lt;I,variant\u003e \u0026\u003cbr\u003e**emplace**( Args\u0026\u0026... args ); | emplace type at index I |\n| \u0026nbsp;       |C++11 | template\u0026lt; size_t I, class U, class... Args \u003e\u003cbr\u003evariant_alternative_t\u0026lt;I,variant\u003e \u0026\u003cbr\u003e**emplace**( std::initializer_list\u0026lt;U\u003e il, Args\u0026\u0026... args ) | emplace type at index I |\n| Swap         |\u0026nbsp;| void **swap**( variant \u0026 other );                | swap with other |\n \n\n### Algorithms for *variant lite*\n\n| Kind                        |Standard| Function |\n|-----------------------------|--------|----------|\n| **Relational operators**    |\u0026nbsp;| \u0026nbsp;   |\n| ==                          |\u0026nbsp;| template\u003c...\u003e\u003cbr\u003ebool **operator==**( variant\u003c...\u003e const \u0026 v, variant\u0026lt;...\u003e const \u0026 w ) |\n| !=                          |\u0026nbsp;| template\u003c...\u003e\u003cbr\u003ebool **operator==**( variant\u003c...\u003e const \u0026 v, variant\u0026lt;...\u003e const \u0026 w ) |\n| \u003c                           |\u0026nbsp;| template\u003c...\u003e\u003cbr\u003ebool **operator\u003c**( variant\u003c...\u003e const \u0026 v, variant\u003c...\u003e const \u0026 w ) |\n| \u003e                           |\u0026nbsp;| template\u003c...\u003e\u003cbr\u003ebool **operator\u003e**( variant\u003c...\u003e const \u0026 v, variant\u003c...\u003e const \u0026 w ) |\n| \u003c=                          |\u0026nbsp;| template\u003c...\u003e\u003cbr\u003ebool **operator\u003c=**( variant\u003c...\u003e const \u0026 v, variant\u003c...\u003e const \u0026 w ) |\n| \u003e=                          |\u0026nbsp;| template\u003c...\u003e\u003cbr\u003ebool **operator\u003e=**( variant\u003c...\u003e const \u0026 v, variant\u003c...\u003e const \u0026 w ) |\n| **Content**                 |\u0026nbsp;| \u0026nbsp;   |\n| contains value of type T    |\u0026nbsp;| template\u003c class T, ...\u003e\u003cbr\u003ebool **holds_alternative**( variant\u003c...\u003e const \u0026 v ) [noexcept] |\n| get by type                 |\u0026nbsp;| template\u003c class R, ...\u003e\u003cbr\u003eR \u0026\u003cbr\u003e**get**( variant\u003c...\u003e \u0026 v, in_place_type_t(R) = in_place\u003cR\u003e ) |\n| get by type (rvalue)        |C++11 | template\u003c class R, ...\u003e\u003cbr\u003eR \u0026\u0026\u003cbr\u003e**get**( variant\u003c...\u003e \u0026\u0026 v, in_place_type_t(R) = in_place\u003cR\u003e ) |\n| get by type (const)         |\u0026nbsp;| template\u003c class R, ...\u003e\u003cbr\u003eR const \u0026\u003cbr\u003e**get**( variant\u003c...\u003e const \u0026 v, in_place_type_t(R) = in_place\u003cR\u003e ) |\n| get by type (const rvalue)  |C++11 | template\u003c class R, ...\u003e\u003cbr\u003eR const \u0026\u0026\u003cbr\u003e**get**( variant\u003c...\u003e const \u0026\u0026 v, in_place_type_t(R) = in_place\u003cR\u003e ) |\n| get by index                |\u0026nbsp;| template\u003c std::size_t I, ...\u003e\u003cbr\u003etypename variant_alternative\u003c I, variant\u003c...\u003e \u003e::type \u0026\u003cbr\u003e**get**( variant\u003c...\u003e \u0026 v, in_place_index_t(I) = in_place\u003cI\u003e ) |\n| get by index (rvalue)       |C++11 | template\u003c std::size_t I, ...\u003e\u003cbr\u003etypename variant_alternative\u003c I, variant\u003c...\u003e \u003e::type \u0026\u0026\u003cbr\u003e**get**( variant\u003c...\u003e \u0026\u0026 v, in_place_index_t(I) = in_place\u003cI\u003e ) |\n| get by index (const)        |\u0026nbsp;| template\u003c std::size_t I, ...\u003e\u003cbr\u003etypename variant_alternative\u003c I, variant\u003c...\u003e \u003e::type const \u0026\u003cbr\u003e**get**( variant\u003c...\u003e const \u0026 v, in_place_index_t(I) = in_place\u003cI\u003e ) |\n| get by index (const rvalue) |C++11 | template\u003c std::size_t I, ...\u003e\u003cbr\u003etypename variant_alternative\u003c I, variant\u003c...\u003e \u003e::type const \u0026\u0026\u003cbr\u003e**get**( variant\u003c...\u003e const \u0026\u0026 v, in_place_index_t(I) = in_place\u003cI\u003e ) |\n| get_if by type              |\u0026nbsp;| template\u003c class T, ...\u003e\u003cbr\u003etypename detail::add_pointer\u0026lt;T\u003e::type\u003cbr\u003e**get_if**( variant\u003c...\u003e * pv, in_place_type_t(T) = in_place\u003cT\u003e ) |\n| get_if by type (const)      |\u0026nbsp;| template\u003c class T, ...\u003e\u003cbr\u003etypename detail::add_pointer\u0026lt;const T\u003e::type\u003cbr\u003e**get_if**( variant\u003c...\u003e const * pv, in_place_type_t(T) = in_place\u003cT\u003e) |\n| get_if by index             |\u0026nbsp;| template\u003c std::size_t I, ...\u003e\u003cbr\u003etypename detail::add_pointer\u003c typename variant_alternative\u003cI, variant\u003cT0, T1, T2, T3, T4, T5, T6\u003e \u003e::type \u003e::type\u003cbr\u003e**get_if**( variant\u003c...\u003e * pv, in_place_index_t(I) = in_place\u003cI\u003e ) |\n| get_if by index (const)     |\u0026nbsp;| template\u003c std::size_t I, ...\u003e\u003cbr\u003etypename detail::add_pointer\u003c const typename variant_alternative\u003cI, variant\u003cT0, T1, T2, T3, T4, T5, T6\u003e \u003e::type \u003e::type\u003cbr\u003e**get_if**( variant\u003c...\u003e const * pv, in_place_index_t(I) = in_place\u003cI\u003e ) |\n| swap                        |\u0026nbsp;| template\u003c...\u003e\u003cbr\u003evoid **swap**( variant\u003c...\u003e \u0026 x, variant\u003c...\u003e \u0026 y ) |\n| visit                         |Note\u0026nbsp;1| template\u003c class Visitor, class Variant \u003e\u003cbr\u003eVariant **visit**( Visitor const \u0026 vis, Variant const \u0026 v ) |\n| **Hash support**            |\u0026nbsp;| \u0026nbsp;   |\n| variant                     |C++11 | template\u003c...\u003e struct **hash**\u003c variant\u003c...\u003e \u003e; |\n| monostate                   |C++11 | template\u003c\u003e struct **hash**\u003c monostate \u003e;       |\n\nNote 1: visitor is limited to always return a Variant.\n\n### Information macros\n\n\u003cb\u003evariant_CONFIG_MAX_TYPE_COUNT\u003c/b\u003e  \nThe maximum number of types thevariant can hold as configured via script [generate_header.py](script/generate_header.py).\n\n\u003cb\u003evariant_CONFIG_MAX_VISITOR_ARG_COUNT\u003c/b\u003e  \nThe maximum number of visitor arguments as configured via script [generate_header.py](script/generate_header.py).\n\n### Configuration macros\n\n#### Tweak header\n\nIf the compiler supports [`__has_include()`](https://en.cppreference.com/w/cpp/preprocessor/include), *variant lite* supports the [tweak header](https://vector-of-bool.github.io/2020/10/04/lib-configuration.html) 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`.\n\n#### Standard selection macro\n\n\\-D\u003cb\u003evariant\\_CPLUSPLUS\u003c/b\u003e=199711L  \nDefine this macro to override the auto-detection of the supported C++ standard, or if your compiler does not set the `__cplusplus` macro correctly.\n\n#### Select `std::variant` or `nonstd::variant`\n\nAt 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.\n\n-D\u003cb\u003evariant\\_CONFIG\\_SELECT\\_VARIANT\u003c/b\u003e=variant_VARIANT_DEFAULT  \nDefine 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`.\n\n#### Override `bad_variant_access`\n\n\\-D\u003cb\u003evariant_CONFIG_OVERRIDE_BAD_VARIANT_ACCESS\u003c/b\u003e=type \n\nDefine this macro to override the default definition of `bad_variant_access`. This is useful when integrating with other compatibility libraries or the standard library to avoid conflicting exception types.\n\nFor example: `#define variant_CONFIG_OVERRIDE_BAD_VARIANT_ACCESS std::bad_variant_access`.\n\nIf not defined, variant-lite uses its own `nonstd::bad_variant_access`.\n\n#### Override `monostate`\n\n\\-D\u003cb\u003evariant_CONFIG_OVERRIDE_MONOSTATE\u003c/b\u003e=type \n\nDefine this macro to override the default `monostate` type used by variant-lite. This helps prevent type conflicts when multiple libraries define their own monostate. \n\nFor example: `#define variant_CONFIG_OVERRIDE_MONOSTATE std::monostate`.\n\nIf not defined, variant-lite uses its own `nonstd::monostate`.\n\n#### Disable exceptions\n\n-D\u003cb\u003evariant_CONFIG_NO_EXCEPTIONS\u003c/b\u003e=0  \nDefine 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.\n\n#### Disable \\[\\[nodiscard\\]\\]\n\n-D\u003cb\u003evariant\\_CONFIG\\_NO\\_NODISCARD\u003c/b\u003e=0\nDefine this to 1 if you want to compile without \\[\\[nodiscard\\]\\]. Note that the default of marking `class bad_variant_access` with \\[\\[nodiscard\\]\\] is not part of the C++17 standard. The rationale to use \\[\\[nodiscard\\]\\] is that unnoticed discarded access error values may break the error handling flow.\n\n#### Presence of `variant_size_V()` simulation macro\n\n\\-D\u003cb\u003evariant\\_CONFIG\\_OMIT\\_VARIANT\\_SIZE\\_V\\_MACRO\u003c/b\u003e=0  \nDefine this macro to 1 to omit the `variant_size_V(T)` macro. Default is 0.\n\n#### Presence of `variant_alternative_T()` simulation macro\n\n\\-D\u003cb\u003evariant\\_CONFIG\\_OMIT\\_VARIANT\\_ALTERNATIVE\\_T\\_MACRO\u003c/b\u003e=0  \nDefine this macro to 1 to omit the `variant_alternative_T(I,T)` macro. Default is 0.\n\n#### Macros to control alignment\n\nIf *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](#implementation-notes).\n\n\\-D\u003cb\u003evariant\\_CONFIG\\_MAX\\_ALIGN\\_HACK\u003c/b\u003e=0  \nDefine this to 1 to use the max align hack for alignment. Default is 0.\n\n\\-D\u003cb\u003evariant\\_CONFIG\\_ALIGN\\_AS\u003c/b\u003e=*pod_type*  \nDefine this to the pod-type you want to align to (no default).\n\n\\-D\u003cb\u003evariant\\_CONFIG\\_ALIGN\\_AS\\_FALLBACK\u003c/b\u003e=*pod_type*  \nDefine 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`.\n\n## Reported to work with\n\nThe table below mentions the compiler versions *variant lite* is reported to work with.\n\nOS        | Compiler   | Versions |\n---------:|:-----------|:---------|\nWindows   | Clang/LLVM | ? |\n\u0026nbsp;    | GCC        | 5.2.0 |\n\u0026nbsp;    | Visual C++\u003cbr\u003e(Visual Studio)| 8 (2005), 9 (2008), 10 (2010), 11 (2012),\u003cbr\u003e12 (2013), 14 (2015), 15 (2017), 16 (2019) |\nGNU/Linux | Clang/LLVM | 3.5.0 |\n\u0026nbsp;    | GCC        | 4.8.4 |\nOS X      | ?          | ?   |\n\n## Building the tests\n\nTo build the tests you need:\n\n- [CMake](http://cmake.org), version 2.8.12 or later to be installed and in your PATH.\n- A [suitable compiler](#reported-to-work-with).\n\nThe [*lest* test framework](https://github.com/martinmoene/lest)  is included in the [test folder](test).\n\nThe following steps assume that the [*variant lite* source code](https://github.com/martinmoene/variant-lite) has been cloned into a directory named `c:\\variant-lite`.\n\n1. Create a directory for the build outputs for a particular architecture.\nHere we use c:\\variant-lite\\build-win-x86-vc10.\n\n        cd c:\\variant-lite\n        md build-win-x86-vc10\n        cd build-win-x86-vc10\n\n2. Configure CMake to use the compiler of your choice (run `cmake --help` for a list).\n\n        cmake -G \"Visual Studio 10 2010\" ..\n\n3. Build the test suite in the Debug configuration (alternatively use Release).    \n\n        cmake --build . --config Debug\n\n4. Run the test suite.    \n\n        ctest -V -C Debug\n\nAll tests should pass, indicating your platform is supported and you are ready to use *variant lite*.\n\n## Implementation notes\n\n### Object allocation and alignment\n\n*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.\n\nIf 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).\n\nAlthough 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].\n\nIf *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.\n\n*variant lite* uses the following rules for alignment:\n\n1. If the program compiles as C++11 or later, C++11 alignment facilities  are used.\n\n2. If you define -D\u003cb\u003evariant_CONFIG_MAX_ALIGN_HACK\u003c/b\u003e=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.\n\n3. If you define -D\u003cb\u003evariant_CONFIG_ALIGN_AS\u003c/b\u003e=*pod-type* the underlying type is aligned as *pod-type*. It's your obligation to specify a type with proper alignment.\n\n4. If you define -D\u003cb\u003evariant_CONFIG_ALIGN_AS_FALLBACK\u003c/b\u003e=*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.\n\n5. At default, *variant lite* tries to find a POD type with the same alignment as the underlying type.\n\n\tThe algorithm for alignment of 5. is:\n\t- Determine the alignment A of the underlying type using `alignment_of\u003c\u003e`.\n\t- Find a POD type from the list `alignment_types` with exactly alignment A.\n\t- 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).\n\nNote that the algorithm of 5. differs from the one Andrei Alexandrescu uses in [10, part 2].\n\nThe class template `alignment_of\u003c\u003e` is gleaned from [Boost.TypeTraits, alignment_of](http://www.boost.org/doc/libs/1_57_0/libs/type_traits/doc/html/boost_typetraits/reference/alignment_of.html) [14].\n\nFor more information on constructed unions and alignment, see [10-14].\n\n## Other implementations of variant\n\n- Isabella Muerte. [MNMLSTC Core](https://github.com/mnmlstc/core) (C++11).\n- Anthony Williams. [C++ variant class, matching the C++17 draft](https://bitbucket.org/anthonyw/variant).\n- Agustín Bergé. [Eggs.Variant, a C++11/14 generic, type-safe, discriminated union](https://github.com/eggs-cpp/variant).\n- Chris Beck. [strict_variant, a simpler type-safe union for C++11/C++14](https://github.com/cbeck88/strict-variant).\n- Mapbox. [C++11/C++14 Variant](https://github.com/mapbox/variant).\n- Michael Park. [Variant: A type-safe union (C++14)](https://github.com/mpark/variant).\n- Gregor Burger. [Typesafe tagged union with \"don't call us, we'll call you\" feature (C++14)](https://github.com/gregorburger/variant).\n- Anatoliy Tomilov. [C++1z variant, never empty, constexpr-enabled visit/multivisit, ... relational](https://github.com/tomilov/variant).\n\n## Notes and References\n\n### Acknowledgments\n\nThanks to @flexferrum for making the number of variant types and visitor arguments [configurable](#in-a-nutshell).\nThanks to @siffiejoe for contributing to fixing [lifetime](#31), [noexcept](34) and [hash](#32) issues. \n\n### References\n\n[1] CppReference. [Variant](http://en.cppreference.com/w/cpp/utility/variant).  \n\n[2] ISO/IEC WG21. [N4606, section 20.7 Variants](http://wg21.link/n4606). July 2016.\n\n[3] Axel Naumann. [Variant: a type-safe union for C++17 (v8)](http://wg21.link/p0088r3). June 2016.\n\n[4] Peter Dimov. [Valueless Variants Considered Harmful](http://wg21.link/p0308r0.html). March 2016.\n\n[5] Anthony Williams. [Standardizing Variant: Difficult Decisions](https://www.justsoftwaresolutions.co.uk/cplusplus/standardizing-variant.html). June 2015\n\n[6] Andrzej Krzemieński. [Constexpr unions](https://akrzemi1.wordpress.com/2012/12/13/constexpr-unions/). December 2012.\n\n[7] Agustín Bergé. [Eggs.Variant - Part I](http://talesofcpp.fusionfenix.com/post-17/eggs.variant---part-i). August 2014.\n\n[8] Agustín Bergé. [Eggs.Variant - Part II (the constexpr experience)](http://talesofcpp.fusionfenix.com/post-20/eggs.variant---part-ii-the-constexpr-experience). March 2015.\n\n[9] Andrei Alexandrescu. [An Implementation of Discriminated Unions in C++](https://www.researchgate.net/publication/2522635_An_Implementation_of_Discriminated_Unions_in_C). August 2002.\n\n[10] Andrei Alexandrescu. [Generic\u003cProgramming\u003e: Discriminated Unions part 1](http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2002/cexp2004/alexandr/alexandr.htm), [part 2](http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2002/cexp2006/alexandr/alexandr.htm), [part 3](http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2002/cexp2008/alexandr/alexandr.htm). April 2002.\n\n[11] Herb Sutter. [Style Case Study #3: Construction Unions](http://www.gotw.ca/gotw/085.htm). GotW #85. 2009\n\n[12] Kevin T. Manley. [Using Constructed Types in C++ Unions](http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2002/0208/manley/manley.htm). C/C++ Users Journal, 20(8), August 2002.\n\n[13] StackOverflow. [Determining maximum possible alignment in C++](http://stackoverflow.com/a/3126992).\n\n[14] [Boost.TypeTraits, alignment_of](http://www.boost.org/doc/libs/1_57_0/libs/type_traits/doc/html/boost_typetraits/reference/alignment_of.html) ( [code](http://www.boost.org/doc/libs/1_57_0/boost/type_traits/alignment_of.hpp) ).\n\n### Presentations\n\n[15] Ben Deane. [Using Types Effectively](https://youtu.be/ojZbFIQSdl8?list=PLHTh1InhhwT7J5jl4vAhO1WvGHUUFgUQH). CppCon 2016.\n\n## Appendix\n\n### A.1 Compile-time information\n\nThe 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]`.\n\n### A.2 Variant lite test specification\n\n\u003cdetails\u003e\n\u003csummary\u003eclick to expand\u003c/summary\u003e\n\u003cp\u003e\n\n```Text\nvariant: Disallows non-default constructible as first type\nvariant: Allows non-default constructible as second and later type (first: int)\nvariant: Allows non-default constructible as second and later type (first: monostate)\nvariant: Allows multiple identical types (C++11)\nvariant: Allows to default-construct variant\nvariant: Allows to copy-construct from variant\nvariant: Allows to move-construct from variant (C++11)\nvariant: Allows to move-construct if-noexcept from variant (C++11)\nvariant: Allows to obtain the index of the current type\nvariant: Allows to inspect if variant is \"valueless by exception\"\nvariant: Allows to copy-assign from variant\nvariant: Allows to copy-assign mutually empty variant\nvariant: Allows to copy-assign from empty variant\nvariant: Allows to copy-assign to empty variant\nvariant: Allows to move-assign from variant (C++11)\nvariant: Allows to move-assign mutually empty variant (C++11)\nvariant: Allows to move-assign from empty variant (C++11)\nvariant: Allows to move-assign to empty variant (C++11)\nvariant: Allows to construct from element value\nvariant: Allows to copy-construct from element\nvariant: Allows to move-construct from element (C++11)\nvariant: Allows to convert-copy-construct from element\nvariant: Allows to convert-move-construct from element (C++11)\nvariant: Allows to copy-assign from element value\nvariant: Allows to move-assign from element value\nvariant: Allows to copy-assign from element\nvariant: Allows to move-assign from element (C++11)\nvariant: Allows to convert-copy-assign from element value\nvariant: Allows to copy-construct from elements in intializer-list based on type (C++11)\nvariant: Allows to move-construct from elements in intializer-list based on type (C++11)\nvariant: Allows to in-place copy-construct element based on type (C++11)\nvariant: Allows to in-place move-construct element based on type (C++11)\nvariant: Allows to in-place copy-construct element based on index (C++11)\nvariant: Allows to in-place move-construct element based on index (C++11)\nvariant: Allows to in-place copy-construct elements from intializer-list based on type (C++11)\nvariant: Allows to in-place move-construct elements from intializer-list based on type (C++11)\nvariant: Allows to in-place copy-construct elements from intializer-list based on index (C++11)\nvariant: Allows to in-place move-construct elements from intializer-list based on index (C++11)\nvariant: Allows to copy-emplace element based on type (C++11)\nvariant: Disallows to copy-emplace non-unique element type on type (C++11)\nvariant: Allows to move-emplace element based on type (C++11)\nvariant: Allows to copy-emplace element based on index (C++11)\nvariant: Allows to move-emplace element based on index (C++11)\nvariant: Allows to copy-emplace elements from intializer-list based on type (C++11)\nvariant: Allows to move-emplace elements from intializer-list based on type (C++11)\nvariant: Allows to copy-emplace elements from intializer-list based on index (C++11)\nvariant: Allows to move-emplace elements from intializer-list based on index (C++11)\nvariant: Allows to swap variants, same index (member)\nvariant: Allows to swap variants, different index (member)\nvariant: Allows to visit contents (args: 1; configured max args: 5)\nvariant: Allows to visit contents (args: 2; configured max args: 5)\nvariant: Allows to visit contents (args: 3; configured max args: 5)\nvariant: Allows to visit contents, rvalue reference (args: 1; configured max args: 5)\nvariant: Allows to check for content by type\nvariant: Allows to get element by type\nvariant: Allows to get element by index\nvariant: Allows to get pointer to element or NULL by type\nvariant: Allows to get pointer to element or NULL by index\nvariant: Allows to compare variants\nvariant: Allows to swap variants, same index (non-member)\nvariant: Allows to swap variants, different index (non-member)\nmonostate: Allows to make variant default-constructible\nbad_variant_access: Indicates invalid variant access\nvariant_size\u003c\u003e: Allows to obtain number of element types (configured max types: 16)\nvariant_size_v\u003c\u003e: Allows to obtain number of element types (C++14; configured max types: 16)\nvariant_size_V(): Allows to obtain number of element types (non-standard: macro; configured max types: 16)\nvariant_alternative\u003c\u003e: Allows to select type by index\nvariant_alternative_t\u003c\u003e: Allows to select type by index (C++11)\nvariant_alternative_T(): Allows to select type by index (non-standard: macro)\nstd::hash\u003c\u003e: Allows to obtain hash (C++11)\ntweak header: reads tweak header if supported [tweak]\nbad_variant_access: Allows to override nonstd::bad_variant_access via variant_CONFIG_OVERRIDE_MONOSTATE\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnonstd-lite%2Fvariant-lite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnonstd-lite%2Fvariant-lite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnonstd-lite%2Fvariant-lite/lists"}