diff --git a/include/frg/cmdline.hpp b/include/frg/cmdline.hpp new file mode 100644 index 0000000..a22d275 --- /dev/null +++ b/include/frg/cmdline.hpp @@ -0,0 +1,146 @@ +#ifndef FRG_CMDLINE_HPP +#define FRG_CMDLINE_HPP + +#include +#include +#include + +#include + +namespace frg FRG_VISIBILITY { + +struct option { + struct fn_type { + void (*ptr)(frg::string_view, void *); + void *ctx; + bool has_arg; + }; + + frg::string_view opt; + fn_type fn; + + void apply(frg::string_view value) { + FRG_ASSERT(fn.ptr); + fn.ptr(value, fn.ctx); + } +}; + +template +auto as_number(T &here) { + return option::fn_type{ + [] (frg::string_view value, void *ctx) { + auto n = value.to_number(); + if (n) + *static_cast(ctx) = n.value(); + }, + &here, + true + }; +} + +inline auto as_string_view(frg::string_view &here) { + return option::fn_type{ + [] (frg::string_view value, void *ctx) { + *static_cast(ctx) = value; + }, + &here, + true + }; +} + +template +auto store_const(T &here) { + return option::fn_type{ + [] (frg::string_view, void *ctx) { + *static_cast(ctx) = value; + }, + &here, + false + }; +} + +inline auto store_true(bool &here) { + return store_const(here); +} + +inline auto store_false(bool &here) { + return store_const(here); +} + +template +concept option_span = requires (T t) { + { t.data() } -> std::convertible_to