SAT Solver Template
Loading...
Searching...
No Matches
cli.hpp
Go to the documentation of this file.
1/**
2* @author Tim Luchterhand
3* @date 02.12.24
4* @file cli.hpp
5* @brief Contains Command Line Interface parsing utility
6*/
7
8#ifndef CLI_HPP
9#define CLI_HPP
10
11#include <span>
12#include <stdexcept>
13#include <string>
14#include <concepts>
15#include <iostream>
16
17#include "concepts.hpp"
18
19namespace cli {
20 /**
21 * @brief Argument specification for switch arguments
22 */
23 struct Switch {
24 Switch(std::string name, bool &value): name(std::move(name)), value(value) {
25 }
26
27 std::string name;
28 bool &value;
29 };
30
31 /**
32 * @brief Argument specification for value arguments
33 * @tparam T argument type
34 */
35 template<typename T>
36 struct ValueArg {
37 using type = T;
38
39 ValueArg(std::string name, T &value, bool required = false): name(std::move(name)), value(value),
40 required(required) {
41 }
42
43 std::string name;
44 T &value;
45 bool required;
46 };
47
48 namespace detail {
49 /**
50 * Argument concept
51 */
52 template<typename T>
53 concept arg = std::same_as<T, Switch> or sat::concepts::same_template<T, ValueArg>;
54
55 template<typename T>
56 struct TypeParse {
57 static_assert(sat::traits::always_false_v<T>, "Unsupported value type");
58 };
59
60 template<>
61 struct TypeParse<float> {
62 float operator()(const std::string &s) const {
63 return std::stof(s);
64 }
65 };
66
67 template<>
68 struct TypeParse<double> {
69 double operator()(const std::string &s) const {
70 return std::stod(s);
71 }
72 };
73
74 template<std::integral T>
75 struct TypeParse<T> {
76 T operator()(const std::string &s) const {
77 return std::stoi(s);
78 }
79 };
80
81 template<sat::concepts::enum_type T>
82 struct TypeParse<T> {
83 T operator()(const std::string &s) const {
84 return static_cast<T>(std::stoi(s));
85 }
86 };
87 }
88
89
90 /**
91 * Parser function.
92 * @note this function stops the template recursion
93 * @param argc
94 * @param argv
95 * @return instance file
96 */
97 inline std::string parse(int argc, char *argv[]) {
98 if (argc < 2) {
99 std::cerr << "Specify the input file" << std::endl;
100 std::exit(1);
101 }
102
103 return argv[1];
104 }
105
106 /**
107 * Compiletime recursive parse method
108 * @tparam Option
109 * @tparam Options
110 * @param argc
111 * @param argv
112 * @param option
113 * @param rest
114 * @return instance file
115 */
116 template<detail::arg Option, detail::arg ... Options>
117 std::string parse(int argc, char *argv[], const Option &option, const Options &... rest) {
118 using namespace std::string_literals;
119 if (argc < 2) {
120 std::cerr << "Specify the input file" << std::endl;
121 std::exit(1);
122 }
123
124 const std::span options(argv + 2, argv + argc);
125 auto res = std::ranges::find(options, option.name);
126 if (res != options.end()) {
127 if constexpr (std::same_as<Option, Switch>) {
128 option.value = not option.value;
129 } else {
130 if (++res == options.end()) {
131 throw std::runtime_error("Could not find argument for option "s + option.name);
132 }
133
134 option.value = detail::TypeParse<typename Option::type>()(*res);
135 std::cout << "c -- using value " << option.value << " for option " << option.name << std::endl;
136 }
137 } else {
138 if constexpr (sat::concepts::same_template<Option, ValueArg>) {
139 if (option.required) {
140 throw std::runtime_error("Required argument "s + option.name + " not specified");
141 }
142
143 std::cout << "c -- using default value " << option.value << " for option " << option.name << std::endl;
144 }
145 }
146
147 return parse(argc, argv, rest...);
148 }
149}
150
151#endif //CLI_HPP
std::string parse(int argc, char *argv[])
Definition cli.hpp:97
std::string parse(int argc, char *argv[], const Option &option, const Options &... rest)
Definition cli.hpp:117
namespace containing various type traits. Prefer using the concepts.
Definition concepts.hpp:21
Definition basic_structures.cpp:10
Argument specification for switch arguments.
Definition cli.hpp:23
Argument specification for value arguments.
Definition cli.hpp:36
Definition cli.hpp:56