/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2022, Danny Robson */ #pragma once #include #include #include #include #include #include #include #include namespace cruft::cmdopt2 { struct argument_t { std::string name; std::optional description; bool required_ = false; using acceptor1_t = std::function; std::optional acceptor1; }; template concept parseable = std::is_arithmetic_v or std::is_same_v; template struct ops_t : argument_t { template requires (!std::is_convertible_v) BaseT bind (ValueT&&) = delete; template BaseT bind (ValueT &ref) { CHECK (!acceptor1); if constexpr (parseable) { acceptor1 = [&ref] (char const* str) { ref = parse::from_string (str); }; } else { acceptor1 = [&ref] (char const* str) { ref = str; }; } return get (); } template BaseT bind (std::optional &ref) { CHECK (!acceptor1); if constexpr (parseable) { acceptor1 = [&ref] (char const* str) { ref = parse::from_string (str); }; } else { acceptor1 = [&ref] (char const* str) { ref = str; }; } return get (); } template BaseT bind (std::vector &ref) { if (!repeat_) throw std::logic_error ("vector argument with non-repeatable argument"); if constexpr (parseable) { acceptor1 = [&ref] (char const* str) { ref.emplace_back (parse::from_string (str)); }; } else { acceptor1 = [&ref] (char const* str) { ref.emplace_back (str); }; } return get (); } BaseT bind (acceptor1_t _acceptor1) { CHECK (!acceptor1); acceptor1 = std::move (_acceptor1); return get (); } BaseT get (void) const { return reinterpret_cast (*this); } BaseT acceptor (acceptor1_t _acceptor) const { BaseT res = get (); res.acceptor1 = _acceptor; return res; } bool required (void) const { return required_; } BaseT required (bool val) const { BaseT res = get (); res.required_ = val; return res; } bool repeat_; BaseT repeat (bool val) const { BaseT res = get (); res.repeat_ = val; return res; } }; struct positional_t : public ops_t { positional_t ignore (void) const; }; positional_t positional (char const *name); positional_t positional (std::string_view name); positional_t positional (std::string const &name); positional_t positional (std::string &&name); struct keyword_t : public ops_t { using acceptor0_t = std::function; std::optional acceptor0; using ops_t::acceptor; keyword_t acceptor (acceptor0_t); keyword_t ignore (void) const; keyword_t flag (void) const; keyword_t flag (std::string_view long_) const; keyword_t flag (char short_) const; keyword_t count (int &) const; keyword_t present (bool &) const; std::optional short_; std::optional long_; }; keyword_t keyword (char const *name); keyword_t keyword (std::string_view name); keyword_t keyword (std::string const &name); keyword_t keyword (std::string &&name); }