Last active
May 6, 2023 14:04
-
-
Save L0N3W0LF/c9f6e7bb4df1883b147e3c846968468a to your computer and use it in GitHub Desktop.
Rust's Option type and Result type in C++ using tagged unions
This file contains 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
//clang 3.8.0 | |
#include <iostream> | |
// Option type and Result type implementations (tagged unions). | |
enum class OptionType { Some, None }; | |
template<typename T> | |
struct Option | |
{ | |
OptionType type; | |
union | |
{ | |
struct { T value; }; // Some | |
struct {}; // None | |
}; | |
}; | |
enum class ResultType { Ok, Error }; | |
template<typename T, typename E> | |
struct Result | |
{ | |
ResultType type; | |
union | |
{ | |
struct { T value; }; // Ok | |
struct { E error; }; // Error | |
}; | |
}; | |
// Methods that use Option type and Result type. | |
enum class ErrorCode { DIVISION_BY_ZERO }; | |
template<typename T> | |
Option<T> option_div(T numerator, T denominator) | |
{ | |
if (denominator == 0) | |
{ | |
return Option<T> { OptionType::None }; | |
} | |
return Option<T> { OptionType::Some, .value = (numerator / denominator) }; | |
} | |
template<typename T> | |
Result<T, ErrorCode> result_div(T numerator, T denominator) | |
{ | |
if (denominator == 0) | |
{ | |
return Result<T, ErrorCode> { ResultType::Error, .error = ErrorCode::DIVISION_BY_ZERO }; | |
} | |
return Result<T, ErrorCode> { ResultType::Ok, .value = (numerator / denominator) }; | |
} | |
// Helpers. | |
template<typename T> | |
void print(Option<T> option) | |
{ | |
switch (option.type) | |
{ | |
case OptionType::Some: | |
std::cout << "Some: " << option.value << std::endl; | |
break; | |
case OptionType::None: | |
std::cout << "None" << std::endl; | |
break; | |
default: | |
break; | |
} | |
} | |
template<typename T, typename E> | |
void print(Result<T, E> result) | |
{ | |
switch (result.type) | |
{ | |
case ResultType::Ok: | |
std::cout << "Ok: " << result.value << std::endl; | |
break; | |
case ResultType::Error: | |
switch (result.error) | |
{ | |
case ErrorCode::DIVISION_BY_ZERO: | |
std::cout << "Error: Division by Zero" << std::endl; | |
break; | |
default: | |
std::cout << "Error" << std::endl; | |
break; | |
} | |
break; | |
default: | |
break; | |
} | |
} | |
// Examples. | |
int main() | |
{ | |
std::cout << "Option type examples" << std::endl; | |
print(option_div(4, 2)); | |
print(option_div(4, 1)); | |
print(option_div(4, 0)); | |
std::cout << "Result type examples" << std::endl; | |
print(result_div(4, 2)); | |
print(result_div(4, 1)); | |
print(result_div(4, 0)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment