Created
October 10, 2023 15:40
-
-
Save H2CO3/52613a9a200f742b1aea07fec655df96 to your computer and use it in GitHub Desktop.
Safe, simple Option<T> for C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <iomanip> | |
template<typename T> | |
union OptionInner { | |
T full; | |
char empty; | |
OptionInner(): empty(0) {} | |
~OptionInner() {} | |
}; | |
template<typename T> | |
struct Option { | |
private: | |
OptionInner<T> inner; | |
bool is_full; | |
public: | |
Option(): | |
is_full(false) | |
{} | |
Option(T value): | |
is_full(true) | |
{ | |
new (&this->inner.full) T(std::move(value)); | |
} | |
Option(const Option<T> &) = default; | |
Option(Option<T> &&) = default; | |
~Option() { | |
if (this->is_full) { | |
this->inner.full.~T(); | |
} | |
} | |
Option &operator=(Option<T> value) { | |
this->inner = std::move(value.inner); | |
this->is_full = value.is_full; | |
return *this; | |
} | |
bool has_value() const { | |
return this->is_full; | |
} | |
const T &operator*() const { | |
if (!this->is_full) { | |
throw std::runtime_error("Option was empty"); | |
} | |
return this->inner.full; | |
} | |
T &operator*() { | |
if (!this->is_full) { | |
throw std::runtime_error("Option was empty"); | |
} | |
return this->inner.full; | |
} | |
const T *operator->() const { | |
return &**this; | |
} | |
T *operator->() { | |
return &**this; | |
} | |
}; | |
int main() { | |
const Option<int> empty; | |
const Option<std::string> full { std::string("I'm a string") }; | |
std::cout << std::boolalpha; | |
std::cout << "empty has a value: " << empty.has_value() << '\n'; | |
std::cout << "full contains: " << *full << '\n'; | |
// std::cout << "empty contains: " << *empty << '\n'; // throws | |
return 0; | |
} |
It's to have something to initialize the union with when the option is empty.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm curious: What does
char empty;
do? Seems unused to me.