Skip to content

A cleaner and more intuitive std::variant alternative

License

Notifications You must be signed in to change notification settings

MarioSieg/ExtendedVariant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

[WIP] ExtendedVariant

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.

Features

✔️ 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)

Usage

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.

Examples

Checking element type

With std::variant:

if(std::holds_alternative<int>(variant))
 ...

With stdex::variant:

if(variant.holds_alternative<int>)
 ...

Checking element type and value without exceptions

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))
 ...

Getting the value directly

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; });

Converting to std::tuple

With stdex::variant:

stdex::variant<int, float> variant{};
std::tuple<int, float> tuple = variant.as_tuple();

Converting to std::variant

With stdex::variant:

stdex::variant<int, float> variant{};
std::variant<int, float> tuple = variant.as_std();

Visiting types

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"; }
);

Getting the index at compile time

With stdex::variant:

auto indexOfInt = stdex::variant<int, float>::index_of<int>();

Contributing

This library is not finished yet, so it's very open to contributions!
Everybody is welcome, just create an issue or submit your PR!

About

A cleaner and more intuitive std::variant alternative

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published