48 int& argc() {
return *_argc; }
49 char** argv() {
return _argv; }
51 char* operator[](
int i) {
return _argv[i]; }
54 bool read(
int& i, T& v)
56 const int num_args = *_argc;
57 if (i >= num_args)
return false;
59 if constexpr (std::is_same_v<T, std::string>)
64 if constexpr (std::is_same_v<T, vsg::Path>)
71 std::size_t num_elements = type_num_elements(v);
74 if (num_elements == 1)
82 for (; num_elements > 0 && i < num_args; --num_elements, ++i)
92 return (!_istr.fail());
96 void remove(
int i,
int num)
98 if (i >= *_argc)
return;
100 int source = i + num;
101 if (source >= *_argc)
109 for (; source < *_argc; ++i, ++source)
111 _argv[i] = _argv[source];
117 _argv[*_argc] =
nullptr;
120 template<
typename... Args>
121 bool read(
const std::string& match, Args&... args)
123 for (
int i = 1; i < *_argc; ++i)
125 if (match == _argv[i])
131 bool result = (read(i, args) && ...);
135 remove(start, i - start);
139 std::string parameters = ((match +
" ") + ... + type_name(args));
140 std::string errorMessage = std::string(
"Failed to match command line required parameters for ") + parameters;
141 _errorMessages.push_back(errorMessage);
150 template<
typename... Args>
151 bool read(std::initializer_list<std::string> matches, Args&... args)
154 for (
auto str : matches) result = read(str, args...) | result;
158 template<
typename T,
typename... Args>
159 T value(T defaultValue,
const std::string& match, Args&... args)
162 read(match, args..., v);
166 template<
typename T,
typename... Args>
167 T value(T defaultValue, std::initializer_list<std::string> matches, Args&... args)
170 read(matches, args..., v);
175 bool readAndAssign(
const std::string& match,
Options* options)
177 if constexpr (std::is_same_v<T, void>)
179 if (options && read(std::string(
"--") + match))
188 if (options && read(std::string(
"--") + match, v))
199 using Messages = std::vector<std::string>;
200 bool errors()
const {
return !_errorMessages.empty(); }
202 Messages& getErrorMessages() {
return _errorMessages; }
203 const Messages& getErrorMessages()
const {
return _errorMessages; }
205 int writeErrorMessages(std::ostream& out)
const
207 if (_errorMessages.empty())
return 1;
208 for (
auto message : _errorMessages) out << message << std::endl;
215 std::istringstream _istr;
216 Messages _errorMessages;
229 if (std::strcmp(str,
"true") == 0 || std::strcmp(str,
"True") == 0 || std::strcmp(str,
"TRUE") == 0 || std::strcmp(str,
"1") == 0)
236 if (std::strcmp(str,
"false") == 0 || std::strcmp(str,
"False") == 0 || std::strcmp(str,
"FALSE") == 0 || std::strcmp(str,
"0") == 0)