#pragma once #include "schema.h" namespace saw { namespace encode { struct Args {}; } namespace schema { template using Args = Struct< Member, Member, Member >; } template class data { static_assert(always_false,"Not supported. Use the schema::Args alias or check how it's defined."); }; template class data...>, schema::Tuple>, encode::Args> { private: char** argv_; int argc_; public: data(char** argv, int argc): argv_{argv}, argc_{argc} {} size_t size() const { if(argc_ < 0){ return 0; } static_assert(sizeof(int) <= sizeof(size_t), "size_t is smaller than int"); return static_cast(argc_); } std::string_view arg_view(size_t i){ if(i < size()){ return std::string_view{argv_[i]}; } return ""; } }; namespace impl { template struct args_decode { static_assert(always_false, "Not supported"); }; template struct args_decode...>,schema::Tuple>,ToDec> { using Schema = schema::Args< schema::Struct...>, schema::Tuple >; static error_or decode(data& from, data& to){ if(from.size() == 0){ return make_error(); } to.get<"program">().set(std::string{from.arg_view(0)}); std::size_t tuple_pos = 0; for(size_t i = 1; i < from.size(); ++i){ auto view = from.arg_view(i); if(view.starts_with("--")){ view.remove_prefix(std::min(2u, view.size())); ++i; if( i >= from.size() ){ return make_error(); } auto value_view = from.arg_view(i); auto eov = decode_struct_member<0>(to.get<"args">(), view, value_view); if(eov.is_error()){ return eov; } } else { auto eov = decode_tuple_member<0>(to.get<"positionals">(), view); if(eov.is_error()){ return eov; } ++tuple_pos; } } if(tuple_pos != sizeof...(Tup)){ return make_error(); } return void_t{}; } }; } template class codec { public: template error_or decode(data& from, data& to){ struct name_and_value { std::string name; std::string value; }; std::string program; std::vector navs; std::vector positionals; return void_t{}; } }; }