Skip to content

Instantly share code, notes, and snippets.

@Dadie

Dadie/main.cpp Secret

Last active June 21, 2022 15:12
Show Gist options
  • Save Dadie/d06ea6aca53d37142577b4d1ce305246 to your computer and use it in GitHub Desktop.
Save Dadie/d06ea6aca53d37142577b4d1ce305246 to your computer and use it in GitHub Desktop.
#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;
}
================================
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