This single header library is part of my C++ extended standard stdex
libraries. Check our my profile for more.
Working with C++ 17's std::variant
can be cumbersome and verbose.
This single header library contains the alternative stdex::variant
,
which has the same interface as std::variant
and usually works as a drop-in replacement,
but has a cleaner interface and more goodies.
✔️ Single header file, C++ 17
✔️ STL interface support (std::get
, std::get_if
, std::visit
etc..)
✔️ Cleaner and less verbose interface (see examples below)
✔️ Lower memory footprint (uses smart index type based on type count)
✔️ Allows custom data alignment
✔️ Full constexpr
support
✔️ Small template code generation
✔️ Fast compile times
✔️ Bonus functions and methods (see examples below)
Just copy the extended_variant.hpp
file into your source code, that's it.
Please remember to include the LICENSE
file according to the license agreement.
With std::variant
:
if(std::holds_alternative<int>(variant))
...
With stdex::variant
:
if(variant.holds_alternative<int>)
...
With std::variant
:
if(std::holds_alternative<int>(variant) && std::get<int>(variant) == 3)
...
With stdex::variant
:
if(variant.holds_value<int>(3))
...
Since the type can be elided from the literal, we can even write:
if(variant.holds_value(3))
...
With std::variant
:
int value = std::get<int>(variant);
With stdex::variant
using std::optional
:
std::optional<int> value = variant.get<int>();
With stdex::variant
using a default value on type mismatch:
// Returns the default value of int (0) when the types do not match:
int value = variant.get_or_default<int>();
With stdex::variant
using a custom value on type mismatch:
// Returns 10 when the types do not match:
int value = variant.get_or_custom_value<int>(10);
With stdex::variant
using a lambda:
// Invokes the lambda and returns 20 when the types do not match:
int value = variant.get_or_invoke<int>([]() -> int { return 10 + 10; });
With stdex::variant
:
stdex::variant<int, float> variant{};
std::tuple<int, float> tuple = variant.as_tuple();
With stdex::variant
:
stdex::variant<int, float> variant{};
std::variant<int, float> tuple = variant.as_std();
With std::variant
using the overload pattern:
template <typename... Ts> struct overload : Ts... { using Ts::operator()...; };
template <typename... Ts> overload(Ts...) -> overload<Ts...>;
std::variant<int, float> variant{};
std::visit
(
overload
{
[](int) { std::cout << "integer"; },
[](float) { std::cout << "floating point"; },
},
variant
);
With stdex::variant
using visit
:
stdex::variant<int, float> variant{};
variant.visit
(
[](int) { std::cout << "integer"; },
[](float) { std::cout << "floating point"; }
);
With stdex::variant
:
auto indexOfInt = stdex::variant<int, float>::index_of<int>();
This library is not finished yet,
so it's very open to contributions!
Everybody is welcome, just create an issue or submit your PR!