-
-
Save Dadie/d06ea6aca53d37142577b4d1ce305246 to your computer and use it in GitHub Desktop.
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
#include <optional> // std::optional | |
#include <variant> // std::variant, std::monostate | |
#include <string> // std::string | |
#include <iostream> // std::cout | |
#include <type_traits> // std::enable_if_t<>, std::is_integral<> | |
#include <vector> // std::vector<> | |
#include <vector> // std::vector<> | |
#include <typeinfo> // std::type_info::name | |
namespace experimental::docopt | |
{ | |
struct value { | |
using integer_type = int; | |
using string_type = std::string; | |
std::variant< | |
std::monostate, | |
integer_type, | |
string_type | |
> __value; | |
template< | |
template<typename> typename OptContainer, | |
typename T, | |
std::enable_if_t<std::is_integral<T>::value, bool> = true | |
> | |
auto wrap() const noexcept -> OptContainer<integer_type> | |
{ | |
try{ | |
return std::get<integer_type>(__value); | |
} | |
catch(...) | |
{ | |
return {}; | |
} | |
} | |
template< | |
template<typename> typename OptContainer, | |
typename T, | |
std::enable_if_t<std::is_base_of<string_type, T>::value, bool> = true | |
> | |
auto wrap() const noexcept -> OptContainer<string_type> | |
{ | |
try{ | |
return std::get<string_type>(__value); | |
} | |
catch(...) | |
{ | |
return {}; | |
} | |
} | |
}; | |
} | |
int main() | |
{ | |
const std::string line = "================================"; | |
// Usage: | |
// Start by having a value (in this case empty, with an integer or with a string) | |
const experimental::docopt::value empty_v{}; | |
const experimental::docopt::value int_v{123456}; | |
const experimental::docopt::value str_v{"s_s_s_s"}; | |
// Give the wrap function an container and a inner type for the value to be wrapped in | |
// In this case, both optional are empty, as the value `empty_v` is empty. | |
const auto my_opt_empty_v_int = empty_v.wrap<std::optional, int>(); | |
const auto my_opt_empty_v_str = empty_v.wrap<std::optional, std::string>(); | |
std::cout << line << std::endl; | |
std::cout << "my_opt_empty_v_int.has_value():" << my_opt_empty_v_int.has_value() << std::endl; | |
std::cout << "my_opt_empty_v_str.has_value():" << my_opt_empty_v_str.has_value() << std::endl; | |
std::cout << std::endl; | |
// In this case, as the value contains an integer, we can wrap it inside an integral type | |
const auto my_opt_int_v_int = int_v.wrap<std::optional, int>(); | |
const auto my_opt_int_v_long = int_v.wrap<std::optional, long>(); | |
const auto my_opt_int_v_unsigned = int_v.wrap<std::optional, unsigned>(); | |
const auto my_opt_int_v_long_long = int_v.wrap<std::optional, long long>(); | |
const auto my_opt_int_v_str = int_v.wrap<std::optional, std::string>(); | |
std::cout << line << std::endl; | |
std::cout << "my_opt_int_v_int.has_value():" << my_opt_int_v_int.has_value() << std::endl; | |
std::cout << "my_opt_int_v_long.has_value():" << my_opt_int_v_long.has_value() << std::endl; | |
std::cout << "my_opt_int_v_unsigned.has_value():" << my_opt_int_v_unsigned.has_value() << std::endl; | |
std::cout << "my_opt_int_v_long_long.has_value():" << my_opt_int_v_long_long.has_value() << std::endl; | |
std::cout << "my_opt_empty_v_str.has_value():" << my_opt_empty_v_str.has_value() << std::endl; | |
std::cout << std::endl; | |
// More Examples | |
std::cout << line << std::endl; | |
{ | |
using wrap_type = int; | |
const experimental::docopt::value v; | |
const auto opt_v = v.wrap<std::optional, wrap_type>(); | |
std::cout << "wrap_value:" << "void" << std::endl; | |
std::cout << "wrap_type:" << typeid(wrap_type).name() << std::endl; | |
std::cout << "v.__value.index():" << v.__value.index() << std::endl; | |
std::cout << "opt_v.has_value():" << opt_v.has_value() << std::endl; | |
} | |
std::cout << line << std::endl; | |
std::cout << std::endl; | |
std::cout << line << std::endl; | |
{ | |
using wrap_type = int; | |
const int wrap_value = 123456; | |
const experimental::docopt::value v{wrap_value}; | |
const auto opt_v = v.wrap<std::optional, wrap_type>(); | |
std::cout << "wrap_value:" << wrap_value << std::endl; | |
std::cout << "wrap_type:" << typeid(wrap_type).name() << std::endl; | |
std::cout << "v.__value.index():" << v.__value.index() << std::endl; | |
std::cout << "opt_v.has_value():" << opt_v.has_value() << std::endl; | |
std::cout << "*opt_v:" << opt_v.value_or(-1) << std::endl; | |
} | |
std::cout << line << std::endl; | |
std::cout << std::endl; | |
std::cout << line << std::endl; | |
{ | |
using wrap_type = long; | |
const int wrap_value = 123456; | |
const experimental::docopt::value v{wrap_value}; | |
const auto opt_v = v.wrap<std::optional, wrap_type>(); | |
std::cout << "wrap_value:" << wrap_value << std::endl; | |
std::cout << "wrap_type:" << typeid(wrap_type).name() << std::endl; | |
std::cout << "v.__value.index():" << v.__value.index() << std::endl; | |
std::cout << "opt_v.has_value():" << opt_v.has_value() << std::endl; | |
std::cout << "*opt_v:" << opt_v.value_or(-1) << std::endl; | |
} | |
std::cout << line << std::endl; | |
std::cout << std::endl; | |
std::cout << line << std::endl; | |
{ | |
using wrap_type = std::string; | |
const int wrap_value = 123456; | |
const experimental::docopt::value v{wrap_value}; | |
const auto opt_v = v.wrap<std::optional, wrap_type>(); | |
std::cout << "wrap_value:" << wrap_value << std::endl; | |
std::cout << "wrap_type:" << typeid(wrap_type).name() << std::endl; | |
std::cout << "v.__value.index():" << v.__value.index() << std::endl; | |
std::cout << "opt_v.has_value():" << opt_v.has_value() << std::endl; | |
std::cout << "*opt_v:" << opt_v.value_or("") << std::endl; | |
} | |
std::cout << line << std::endl; | |
std::cout << std::endl; | |
std::cout << line << std::endl; | |
{ | |
using wrap_type = std::string; | |
const std::string wrap_value = "s__s__s__s"; | |
const experimental::docopt::value v{wrap_value}; | |
const auto opt_v = v.wrap<std::optional, wrap_type>(); | |
std::cout << "wrap_value:" << wrap_value << std::endl; | |
std::cout << "wrap_type:" << typeid(wrap_type).name() << std::endl; | |
std::cout << "v.__value.index():" << v.__value.index() << std::endl; | |
std::cout << "opt_v.has_value():" << opt_v.has_value() << std::endl; | |
std::cout << "*opt_v:" << opt_v.value_or("") << std::endl; | |
} | |
std::cout << line << std::endl; | |
std::cout << std::endl; | |
} |
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
================================ | |
my_opt_empty_v_int.has_value():0 | |
my_opt_empty_v_str.has_value():0 | |
================================ | |
my_opt_int_v_int.has_value():1 | |
my_opt_int_v_long.has_value():1 | |
my_opt_int_v_unsigned.has_value():1 | |
my_opt_int_v_long_long.has_value():1 | |
my_opt_empty_v_str.has_value():0 | |
================================ | |
wrap_value:void | |
wrap_type:i | |
v.__value.index():0 | |
opt_v.has_value():0 | |
================================ | |
================================ | |
wrap_value:123456 | |
wrap_type:i | |
v.__value.index():1 | |
opt_v.has_value():1 | |
*opt_v:123456 | |
================================ | |
================================ | |
wrap_value:123456 | |
wrap_type:l | |
v.__value.index():1 | |
opt_v.has_value():1 | |
*opt_v:123456 | |
================================ | |
================================ | |
wrap_value:123456 | |
wrap_type:NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE | |
v.__value.index():1 | |
opt_v.has_value():0 | |
*opt_v: | |
================================ | |
================================ | |
wrap_value:s__s__s__s | |
wrap_type:NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE | |
v.__value.index():2 | |
opt_v.has_value():1 | |
*opt_v:s__s__s__s | |
================================ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment