CLI11 2.7.1
C++11 Command Line Interface Parser
Loading...
Searching...
No Matches
Option_inl.hpp
1// Copyright (c) 2017-2026, University of Cincinnati, developed by Henry Schreiner
2// under NSF AWARD 1414736 and by the respective contributors.
3// All rights reserved.
4//
5// SPDX-License-Identifier: BSD-3-Clause
6
7#pragma once
8
9// IWYU pragma: private, include "CLI/CLI.hpp"
10
11// This include is only needed for IDEs to discover symbols
12#include "../Option.hpp"
13
14// [CLI11:public_includes:set]
15#include <algorithm>
16#include <cerrno>
17#include <memory>
18#include <string>
19#include <utility>
20#include <vector>
21// [CLI11:public_includes:end]
22
23namespace CLI {
24// [CLI11:option_inl_hpp:verbatim]
25
26template <typename CRTP> template <typename T> void OptionBase<CRTP>::copy_to(T *other) const {
27 other->group(group_);
28 other->required(required_);
29 other->ignore_case(ignore_case_);
30 other->ignore_underscore(ignore_underscore_);
31 other->configurable(configurable_);
32 other->disable_flag_override(disable_flag_override_);
33 other->delimiter(delimiter_);
34 other->always_capture_default(always_capture_default_);
35 other->multi_option_policy(multi_option_policy_);
36 other->callback_priority(callback_priority_);
37}
38
39CLI11_INLINE Option *Option::expected(int value) {
40 if(value < 0) {
41 expected_min_ = -value;
44 }
45 allow_extra_args_ = true;
46 flag_like_ = false;
47 } else if(value == detail::expected_max_vector_size) {
48 expected_min_ = 1;
49 expected_max_ = detail::expected_max_vector_size;
50 allow_extra_args_ = true;
51 flag_like_ = false;
52 } else {
53 expected_min_ = value;
54 expected_max_ = value;
56 }
57 return this;
58}
59
60CLI11_INLINE Option *Option::expected(int value_min, int value_max) {
61 if(value_min < 0) {
62 value_min = -value_min;
63 }
64
65 if(value_max < 0) {
66 value_max = detail::expected_max_vector_size;
67 }
68 if(value_max < value_min) {
69 expected_min_ = value_max;
70 expected_max_ = value_min;
71 } else {
72 expected_max_ = value_max;
73 expected_min_ = value_min;
74 }
75
76 return this;
77}
78
79CLI11_INLINE Option *Option::check(Validator_p validator) {
80 validator->non_modifying();
81 validators_.push_back(std::move(validator));
82
83 return this;
84}
85
86CLI11_INLINE Option *Option::check(Validator validator, const std::string &validator_name) {
87 validator.non_modifying();
88 auto vp = std::make_shared<Validator>(std::move(validator));
89 if(!validator_name.empty()) {
90 vp->name(validator_name);
91 }
92 validators_.push_back(std::move(vp));
93
94 return this;
95}
96
97CLI11_INLINE Option *Option::check(std::function<std::string(const std::string &)> validator_func,
98 std::string validator_description,
99 std::string validator_name) {
100
101 auto vp = std::make_shared<Validator>(
102 std::move(validator_func), std::move(validator_description), std::move(validator_name));
103 vp->non_modifying();
104 validators_.push_back(std::move(vp));
105 return this;
106}
107
108CLI11_INLINE Option *Option::transform(Validator_p validator) {
109 validators_.insert(validators_.begin(), std::move(validator));
110
111 return this;
112}
113
114CLI11_INLINE Option *Option::transform(Validator validator, const std::string &transform_name) {
115 auto vp = std::make_shared<Validator>(std::move(validator));
116 if(!transform_name.empty()) {
117 vp->name(transform_name);
118 }
119 validators_.insert(validators_.begin(), std::move(vp));
120 return this;
121}
122
123CLI11_INLINE Option *
124Option::transform(Validator validator, const std::string &transform_description, const std::string &transform_name) {
125 auto vp = std::make_shared<Validator>(std::move(validator));
126 if(!transform_name.empty()) {
127 vp->name(transform_name);
128 }
129 vp->description(transform_description);
130 validators_.insert(validators_.begin(), std::move(vp));
131 return this;
132}
133
134CLI11_INLINE Option *Option::transform(const std::function<std::string(std::string)> &transform_func,
135 std::string transform_description,
136 std::string transform_name) {
137 auto vp = std::make_shared<Validator>(
138 [transform_func](std::string &val) {
139 val = transform_func(val);
140 return std::string{};
141 },
142 std::move(transform_description),
143 std::move(transform_name));
144 validators_.insert(validators_.begin(), std::move(vp));
145
146 return this;
147}
148
149CLI11_INLINE Option *Option::each(const std::function<void(std::string)> &func) {
150 auto vp = std::make_shared<Validator>(
151 [func](std::string &inout) {
152 func(inout);
153 return std::string{};
154 },
155 std::string{});
156 validators_.push_back(std::move(vp));
157 return this;
158}
159
160CLI11_INLINE Validator *Option::get_validator(const std::string &validator_name) {
161 for(auto &validator : validators_) {
162 if(validator_name == validator->get_name()) {
163 return validator.get();
164 }
165 }
166 if((validator_name.empty()) && (!validators_.empty())) {
167 return validators_.front().get();
168 }
169 throw OptionNotFound(std::string{"Validator "} + validator_name + " Not Found");
170}
171
172CLI11_INLINE Validator *Option::get_validator(int index) {
173 // This is a signed int so that it is not equivalent to a pointer.
174 if(index >= 0 && index < static_cast<int>(validators_.size())) {
175 return validators_[static_cast<decltype(validators_)::size_type>(index)].get();
176 }
177 throw OptionNotFound("Validator index is not valid");
178}
179
180CLI11_INLINE bool Option::remove_needs(Option *opt) {
181 auto iterator = std::find(std::begin(needs_), std::end(needs_), opt);
182
183 if(iterator == std::end(needs_)) {
184 return false;
185 }
186 needs_.erase(iterator);
187 return true;
188}
189
190CLI11_INLINE Option *Option::excludes(Option *opt) {
191 if(opt == this) {
192 throw(IncorrectConstruction("and option cannot exclude itself"));
193 }
194 excludes_.insert(opt);
195
196 // Help text should be symmetric - excluding a should exclude b
197 opt->excludes_.insert(this);
198
199 // Ignoring the insert return value, excluding twice is now allowed.
200 // (Mostly to allow both directions to be excluded by user, even though the library does it for you.)
201
202 return this;
203}
204
205CLI11_INLINE bool Option::remove_excludes(Option *opt) {
206 auto iterator = std::find(std::begin(excludes_), std::end(excludes_), opt);
207
208 if(iterator == std::end(excludes_)) {
209 return false;
210 }
211 excludes_.erase(iterator);
212 return true;
213}
214
215template <typename T> Option *Option::ignore_case(bool value) {
216 if(!ignore_case_ && value) {
217 ignore_case_ = value;
218 auto *parent = static_cast<T *>(parent_);
219 for(const Option_p &opt : parent->options_) {
220 if(opt.get() == this) {
221 continue;
222 }
223 const auto &omatch = opt->matching_name(*this);
224 if(!omatch.empty()) {
225 ignore_case_ = false;
226 throw OptionAlreadyAdded("adding ignore case caused a name conflict with " + omatch);
227 }
228 }
229 } else {
230 ignore_case_ = value;
231 }
232 return this;
233}
234
235template <typename T> Option *Option::ignore_underscore(bool value) {
236
237 if(!ignore_underscore_ && value) {
238 ignore_underscore_ = value;
239 auto *parent = static_cast<T *>(parent_);
240 for(const Option_p &opt : parent->options_) {
241 if(opt.get() == this) {
242 continue;
243 }
244 const auto &omatch = opt->matching_name(*this);
245 if(!omatch.empty()) {
246 ignore_underscore_ = false;
247 throw OptionAlreadyAdded("adding ignore underscore caused a name conflict with " + omatch);
248 }
249 }
250 } else {
251 ignore_underscore_ = value;
252 }
253 return this;
254}
255
256CLI11_INLINE Option *Option::multi_option_policy(MultiOptionPolicy value) {
257 if(value != multi_option_policy_) {
258 if(multi_option_policy_ == MultiOptionPolicy::Throw && expected_max_ == detail::expected_max_vector_size &&
259 expected_min_ > 1) { // this bizarre condition is to maintain backwards compatibility
260 // with the previous behavior of expected_ with vectors
262 }
263 multi_option_policy_ = value;
265 }
266 return this;
267}
268
269CLI11_NODISCARD CLI11_INLINE std::string
270Option::get_name(bool positional, bool all_options, bool disable_default_flag_values) const {
271 if(get_group().empty())
272 return {}; // Hidden
273
274 if(all_options) {
275
276 std::vector<std::string> name_list;
277
279 if((positional && (!pname_.empty())) || (snames_.empty() && lnames_.empty())) {
280 name_list.push_back(pname_);
281 }
282 if((get_items_expected() == 0) && (!fnames_.empty())) {
283 for(const std::string &sname : snames_) {
284 name_list.push_back("-" + sname);
285 if(!disable_default_flag_values && check_fname(sname)) {
286 name_list.back() += "{" + get_flag_value(sname, "") + "}";
287 }
288 }
289
290 for(const std::string &lname : lnames_) {
291 name_list.push_back("--" + lname);
292 if(!disable_default_flag_values && check_fname(lname)) {
293 name_list.back() += "{" + get_flag_value(lname, "") + "}";
294 }
295 }
296 } else {
297 for(const std::string &sname : snames_)
298 name_list.push_back("-" + sname);
299
300 for(const std::string &lname : lnames_)
301 name_list.push_back("--" + lname);
302 }
303
304 return detail::join(name_list);
305 }
306
307 // This returns the positional name no matter what
308 if(positional)
309 return pname_;
310
311 // Prefer long name
312 if(!lnames_.empty())
313 return std::string(2, '-') + lnames_[0];
314
315 // Or short name if no long name
316 if(!snames_.empty())
317 return std::string(1, '-') + snames_[0];
318
319 // If positional is the only name, it's okay to use that
320 return pname_;
321}
322
323CLI11_INLINE void Option::run_callback() {
324 bool used_default_str = false;
325 if(force_callback_ && results_.empty()) {
326 used_default_str = true;
328 }
330 _validate_results(results_);
332 }
333
335 _reduce_results(proc_results_, results_);
336 }
337
339 if(callback_) {
340 const results_t &send_results = proc_results_.empty() ? results_ : proc_results_;
341 if(send_results.empty()) {
342 return;
343 }
344 bool local_result = callback_(send_results);
345 if(used_default_str) {
346 // we only clear the results if the callback was actually used
347 // otherwise the callback is the storage of the default
348 results_.clear();
349 proc_results_.clear();
350 }
351 if(!local_result)
353 }
354}
355
356CLI11_NODISCARD CLI11_INLINE const std::string &Option::matching_name(const Option &other) const {
357 static const std::string estring;
358 bool bothConfigurable = configurable_ && other.configurable_;
359 for(const std::string &sname : snames_) {
360 if(other.check_sname(sname))
361 return sname;
362 if(bothConfigurable && other.check_lname(sname))
363 return sname;
364 }
365 for(const std::string &lname : lnames_) {
366 if(other.check_lname(lname))
367 return lname;
368 if(lname.size() == 1 && bothConfigurable) {
369 if(other.check_sname(lname)) {
370 return lname;
371 }
372 }
373 }
374 if(bothConfigurable && snames_.empty() && lnames_.empty() && !pname_.empty()) {
375 if(other.check_sname(pname_) || other.check_lname(pname_) || pname_ == other.pname_)
376 return pname_;
377 }
378 if(bothConfigurable && other.snames_.empty() && other.fnames_.empty() && !other.pname_.empty()) {
379 if(check_sname(other.pname_) || check_lname(other.pname_) || (pname_ == other.pname_))
380 return other.pname_;
381 }
382 if(ignore_case_ ||
383 ignore_underscore_) { // We need to do the inverse, in case we are ignore_case or ignore underscore
384 for(const std::string &sname : other.snames_)
385 if(check_sname(sname))
386 return sname;
387 for(const std::string &lname : other.lnames_)
388 if(check_lname(lname))
389 return lname;
390 }
391 return estring;
392}
393
394CLI11_NODISCARD CLI11_INLINE bool Option::check_name(const std::string &name) const {
395
396 if(name.length() > 2 && name[0] == '-' && name[1] == '-')
397 return check_lname(name.substr(2));
398 if(name.length() > 1 && name.front() == '-')
399 return check_sname(name.substr(1));
400 if(!pname_.empty()) {
401 std::string local_pname = pname_;
402 std::string local_name = name;
404 local_pname = detail::remove_underscore(local_pname);
405 local_name = detail::remove_underscore(local_name);
406 }
407 if(ignore_case_) {
408 local_pname = detail::to_lower(local_pname);
409 local_name = detail::to_lower(local_name);
410 }
411 if(local_name == local_pname) {
412 return true;
413 }
414 }
415
416 if(!envname_.empty()) {
417 // this needs to be the original since envname_ shouldn't match on case insensitivity
418 return (name == envname_);
419 }
420 return false;
421}
422
423CLI11_NODISCARD CLI11_INLINE std::string Option::get_flag_value(const std::string &name,
424 std::string input_value) const {
425 static const std::string trueString{"true"};
426 static const std::string falseString{"false"};
427 static const std::string emptyString{"{}"};
428 // check for disable flag override_
430 if(!((input_value.empty()) || (input_value == emptyString))) {
431 auto default_ind = detail::find_member(name, fnames_, ignore_case_, ignore_underscore_);
432 if(default_ind >= 0) {
433 // We can static cast this to std::size_t because it is more than 0 in this block
434 if(default_flag_values_[static_cast<std::size_t>(default_ind)].second != input_value) {
435 if(input_value == default_str_ && force_callback_) {
436 return input_value;
437 }
438 throw(ArgumentMismatch::FlagOverride(name));
439 }
440 } else {
441 if(input_value != trueString) {
442 throw(ArgumentMismatch::FlagOverride(name));
443 }
444 }
445 }
446 }
447 auto ind = detail::find_member(name, fnames_, ignore_case_, ignore_underscore_);
448 if((input_value.empty()) || (input_value == emptyString)) {
449 if(flag_like_) {
450 return (ind < 0) ? trueString : default_flag_values_[static_cast<std::size_t>(ind)].second;
451 }
452 return (ind < 0) ? default_str_ : default_flag_values_[static_cast<std::size_t>(ind)].second;
453 }
454 if(ind < 0) {
455 return input_value;
456 }
457 if(default_flag_values_[static_cast<std::size_t>(ind)].second == falseString) {
458 errno = 0;
459 auto val = detail::to_flag_value(input_value);
460 if(errno != 0) {
461 errno = 0;
462 return input_value;
463 }
464 return (val == 1) ? falseString : (val == (-1) ? trueString : std::to_string(-val));
465 }
466 return input_value;
467}
468
469CLI11_INLINE Option *Option::add_result(std::string s) {
470 _add_result(std::move(s), results_);
472 return this;
473}
474
475CLI11_INLINE Option *Option::add_result(std::string s, int &results_added) {
476 results_added = _add_result(std::move(s), results_);
478 return this;
479}
480
481CLI11_INLINE Option *Option::add_result(std::vector<std::string> s) {
483 for(auto &str : s) {
484 _add_result(std::move(str), results_);
485 }
486 return this;
487}
488
489CLI11_NODISCARD CLI11_INLINE results_t Option::reduced_results() const {
491 results_t res = (parsing || proc_results_.empty()) ? results_ : proc_results_;
493 if(parsing) {
494 _validate_results(res);
495 }
496 if(!res.empty()) {
497 results_t extra;
498 _reduce_results(extra, res);
499 if(!extra.empty()) {
500 res = std::move(extra);
501 }
502 }
503 }
504 return res;
505}
506
507CLI11_INLINE Option *Option::type_size(int option_type_size) {
508 if(option_type_size < 0) {
509 // this section is included for backwards compatibility
510 type_size_max_ = -option_type_size;
511 type_size_min_ = -option_type_size;
512 expected_max_ = detail::expected_max_vector_size;
513 } else {
514 type_size_max_ = option_type_size;
515 if(type_size_max_ < detail::expected_max_vector_size) {
516 type_size_min_ = option_type_size;
517 } else {
518 inject_separator_ = true;
519 }
520 if(type_size_max_ == 0)
521 required_ = false;
522 }
523 return this;
524}
525
526CLI11_INLINE Option *Option::type_size(int option_type_size_min, int option_type_size_max) {
527 if(option_type_size_min < 0 || option_type_size_max < 0) {
528 // this section is included for backwards compatibility
529 expected_max_ = detail::expected_max_vector_size;
530 option_type_size_min = (std::abs)(option_type_size_min);
531 option_type_size_max = (std::abs)(option_type_size_max);
532 }
533
534 if(option_type_size_min > option_type_size_max) {
535 type_size_max_ = option_type_size_min;
536 type_size_min_ = option_type_size_max;
537 } else {
538 type_size_min_ = option_type_size_min;
539 type_size_max_ = option_type_size_max;
540 }
541 if(type_size_max_ == 0) {
542 required_ = false;
543 }
544 if(type_size_max_ >= detail::expected_max_vector_size) {
545 inject_separator_ = true;
546 }
547 return this;
548}
549
550CLI11_NODISCARD CLI11_INLINE std::string Option::get_type_name() const {
551 std::string full_type_name = type_name_();
552 if(!validators_.empty()) {
553 for(const auto &validator : validators_) {
554 std::string vtype = validator->get_description();
555 if(!vtype.empty()) {
556 full_type_name += ":" + vtype;
557 }
558 }
559 }
560 return full_type_name;
561}
562
563CLI11_INLINE void Option::_validate_results(results_t &res) const {
564 // Run the Validators (can change the string)
565 if(!validators_.empty()) {
566 if(type_size_max_ > 1) { // in this context index refers to the index in the type
567 int index = 0;
568 if(get_items_expected_max() < static_cast<int>(res.size()) &&
569 (multi_option_policy_ == CLI::MultiOptionPolicy::TakeLast ||
570 multi_option_policy_ == CLI::MultiOptionPolicy::Reverse)) {
571 // create a negative index for the earliest ones
572 index = get_items_expected_max() - static_cast<int>(res.size());
573 }
574
575 for(std::string &result : res) {
576 if(detail::is_separator(result) && type_size_max_ != type_size_min_ && index >= 0) {
577 index = 0; // reset index for variable size chunks
578 continue;
579 }
580 auto err_msg = _validate(result, (index >= 0) ? (index % type_size_max_) : index);
581 if(!err_msg.empty())
582 throw ValidationError(get_name(), err_msg);
583 ++index;
584 }
585 } else {
586 int index = 0;
587 if(expected_max_ < static_cast<int>(res.size()) &&
588 (multi_option_policy_ == CLI::MultiOptionPolicy::TakeLast ||
589 multi_option_policy_ == CLI::MultiOptionPolicy::Reverse)) {
590 // create a negative index for the earliest ones
591 index = expected_max_ - static_cast<int>(res.size());
592 }
593 for(std::string &result : res) {
594 auto err_msg = _validate(result, index);
595 ++index;
596 if(!err_msg.empty())
597 throw ValidationError(get_name(), err_msg);
598 }
599 }
600 }
601}
602
603CLI11_INLINE void Option::_reduce_results(results_t &out, const results_t &original) const {
604
605 // max num items expected or length of vector, always at least 1
606 // Only valid for a trimming policy
607
608 out.clear();
609 // Operation depends on the policy setting
610 switch(multi_option_policy_) {
611 case MultiOptionPolicy::TakeAll:
612 break;
613 case MultiOptionPolicy::TakeLast: {
614 // Allow multi-option sizes (including 0)
615 std::size_t trim_size = std::min<std::size_t>(
616 static_cast<std::size_t>(std::max<int>(get_items_expected_max(), 1)), original.size());
617 if(original.size() != trim_size) {
618 out.assign(original.end() - static_cast<results_t::difference_type>(trim_size), original.end());
619 }
620 } break;
621 case MultiOptionPolicy::Reverse: {
622 // Allow multi-option sizes (including 0)
623 std::size_t trim_size = std::min<std::size_t>(
624 static_cast<std::size_t>(std::max<int>(get_items_expected_max(), 1)), original.size());
625 if(original.size() != trim_size || trim_size > 1) {
626 out.assign(original.end() - static_cast<results_t::difference_type>(trim_size), original.end());
627 }
628 std::reverse(out.begin(), out.end());
629 } break;
630 case MultiOptionPolicy::TakeFirst: {
631 std::size_t trim_size = std::min<std::size_t>(
632 static_cast<std::size_t>(std::max<int>(get_items_expected_max(), 1)), original.size());
633 if(original.size() != trim_size) {
634 out.assign(original.begin(), original.begin() + static_cast<results_t::difference_type>(trim_size));
635 }
636 } break;
637 case MultiOptionPolicy::Join:
638 if(original.size() > 1) {
639 out.push_back(detail::join(original, std::string(1, (delimiter_ == '\0') ? '\n' : delimiter_)));
640 }
641 break;
642 case MultiOptionPolicy::Sum:
643 out.push_back(detail::sum_string_vector(original));
644 break;
645 case MultiOptionPolicy::Throw:
646 default: {
647 auto num_min = static_cast<std::size_t>(get_items_expected_min());
648 auto num_max = static_cast<std::size_t>(get_items_expected_max());
649 if(num_min == 0) {
650 num_min = 1;
651 }
652 if(num_max == 0) {
653 num_max = 1;
654 }
655 if(original.size() < num_min) {
656 throw ArgumentMismatch::AtLeast(get_name(), static_cast<int>(num_min), original.size());
657 }
658 if(original.size() > num_max) {
659 if(original.size() == 2 && num_max == 1 && original[1] == "%%" && original[0] == "{}") {
660 // this condition is a trap for the following empty indicator check on config files, it may not be used
661 // anymore
662 out = original; // LCOV_EXCL_LINE
663 } else {
664 throw ArgumentMismatch::AtMost(get_name(), static_cast<int>(num_max), original.size());
665 }
666 }
667 break;
668 }
669 }
670 // this check is to allow an empty vector in certain circumstances but not if expected is not zero.
671 // {} is the indicator for an empty container
672 if(out.empty()) {
673 if(original.size() == 1 && original[0] == "{}" && get_items_expected_min() > 0) {
674 out.emplace_back("{}");
675 out.emplace_back("%%");
676 }
677 } else if(out.size() == 1 && out[0] == "{}" && get_items_expected_min() > 0) {
678 out.emplace_back("%%");
679 }
680}
681
682CLI11_INLINE std::string Option::_validate(std::string &result, int index) const {
683 std::string err_msg;
684 if(result.empty() && expected_min_ == 0) {
685 // an empty with nothing expected is allowed
686 return err_msg;
687 }
688 for(const auto &vali : validators_) {
689 auto v = vali->get_application_index();
690 if(v == -1 || v == index) {
691 try {
692 err_msg = (*vali)(result);
693 } catch(const ValidationError &err) {
694 err_msg = err.what();
695 }
696 if(!err_msg.empty())
697 break;
698 }
699 }
700
701 return err_msg;
702}
703
704CLI11_INLINE int Option::_add_result(std::string &&result, std::vector<std::string> &res) const {
705 int result_count = 0;
706
707 // Handle the vector escape possibility all characters duplicated and starting with [[ ending with ]]
708 // this is always a single result
709 if(result.size() >= 4 && result[0] == '[' && result[1] == '[' && result.back() == ']' &&
710 (*(result.end() - 2) == ']')) {
711 // this is an escape clause for odd strings
712 std::string nstrs{'['};
713 bool duplicated{true};
714 for(std::size_t ii = 2; ii < result.size() - 2; ii += 2) {
715 if(result[ii] == result[ii + 1]) {
716 nstrs.push_back(result[ii]);
717 } else {
718 duplicated = false;
719 break;
720 }
721 }
722 if(duplicated) {
723 nstrs.push_back(']');
724 res.push_back(std::move(nstrs));
725 ++result_count;
726 return result_count;
727 }
728 }
729
730 if((allow_extra_args_ || get_expected_max() > 1 || get_type_size() > 1) && !result.empty() &&
731 result.front() == '[' &&
732 result.back() == ']') { // this is now a vector string likely from the default or user entry
733
734 result.pop_back();
735 result.erase(result.begin());
736 for(auto &var : CLI::detail::split_up(result, ',')) {
737 if(!var.empty()) {
738 result_count += _add_result(std::move(var), res);
739 }
740 }
741 return result_count;
742 }
743 if(delimiter_ == '\0') {
744 res.push_back(std::move(result));
745 ++result_count;
746 } else {
747 if((result.find_first_of(delimiter_) != std::string::npos)) {
748 for(const auto &var : CLI::detail::split(result, delimiter_)) {
749 if(!var.empty()) {
750 res.push_back(var);
751 ++result_count;
752 }
753 }
754 } else {
755 res.push_back(std::move(result));
756 ++result_count;
757 }
758 }
759 return result_count;
760}
761// [CLI11:option_inl_hpp:end]
762} // namespace CLI
Thrown when conversion call back fails, such as when an int fails to coerce to a string.
Definition Error.hpp:206
Thrown when an option is set to conflicting values (non-vector and multi args, for example).
Definition Error.hpp:97
Thrown when an option already exists.
Definition Error.hpp:145
bool always_capture_default_
Automatically capture default value.
Definition Option.hpp:94
MultiOptionPolicy multi_option_policy_
Policy for handling multiple arguments beyond the expected Max.
Definition Option.hpp:97
bool ignore_case_
Ignore the case when matching (option, not value).
Definition Option.hpp:79
bool configurable_
Allow this option to be given in a configuration file.
Definition Option.hpp:85
CallbackPriority callback_priority_
Priority of callback.
Definition Option.hpp:100
bool disable_flag_override_
Disable overriding flag values with '=value'.
Definition Option.hpp:88
bool required_
True if this is a required option.
Definition Option.hpp:76
char delimiter_
Specify a delimiter character for vector arguments.
Definition Option.hpp:91
std::string group_
The group membership.
Definition Option.hpp:73
bool ignore_underscore_
Ignore underscores when matching (option, not value).
Definition Option.hpp:82
CLI11_NODISCARD const std::string & get_group() const
Definition Option.hpp:134
void copy_to(T *other) const
Copy the contents to another similar class (one based on OptionBase).
Definition Option_inl.hpp:26
Definition Option.hpp:259
Option * type_size(int option_type_size)
Set a custom option size.
Definition Option_inl.hpp:507
Option * expected(int value)
Set the number of expected arguments.
Definition Option_inl.hpp:39
Option * check(Validator_p validator)
Adds a shared validator.
Definition Option_inl.hpp:79
std::string default_str_
A human readable default value, either manually set, captured, or captured by default.
Definition Option.hpp:294
CLI11_NODISCARD bool check_name(const std::string &name) const
Check a name. Requires "-" or "--" for short / long, supports positional name.
Definition Option_inl.hpp:394
std::function< std::string()> type_name_
Definition Option.hpp:302
@ reduced
a subset of results has been generated
Definition Option.hpp:353
@ callback_run
the callback has been executed
Definition Option.hpp:354
@ validated
the results have been validated
Definition Option.hpp:352
@ parsing
The option is currently collecting parsed results.
Definition Option.hpp:351
option_state current_option_state_
Whether the callback has run (needed for INI parsing).
Definition Option.hpp:357
int type_size_min_
The minimum number of arguments an option should be expecting.
Definition Option.hpp:315
CLI11_NODISCARD results_t reduced_results() const
Get a copy of the results.
Definition Option_inl.hpp:489
CLI11_NODISCARD std::string get_type_name() const
Get the full typename for this option.
Definition Option_inl.hpp:550
CLI11_NODISCARD bool check_fname(std::string name) const
Requires "--" to be removed from string.
Definition Option.hpp:697
std::string pname_
A positional name.
Definition Option.hpp:281
int expected_min_
The minimum number of expected values.
Definition Option.hpp:318
Option * transform(Validator_p validator)
Adds a shared Validator.
Definition Option_inl.hpp:108
Option * ignore_case(bool value=true)
Definition Option_inl.hpp:215
std::set< Option * > needs_
A list of options that are required with this option.
Definition Option.hpp:326
void run_callback()
Process the callback.
Definition Option_inl.hpp:323
CLI11_NODISCARD std::string get_name(bool positional=false, bool all_options=false, bool disable_default_flag_values=false) const
Gets a comma separated list of names. Will include / prefer the positional name if positional is true...
Definition Option_inl.hpp:270
CLI11_NODISCARD bool check_sname(std::string name) const
Requires "-" to be removed from string.
Definition Option.hpp:687
bool flag_like_
Specify that the option should act like a flag vs regular option.
Definition Option.hpp:361
std::set< Option * > excludes_
A list of options that are excluded with this option.
Definition Option.hpp:329
bool force_callback_
flag indicating that the option should force the callback regardless if any results present
Definition Option.hpp:369
std::vector< std::string > fnames_
a list of flag names with specified default values;
Definition Option.hpp:278
Option(std::string option_name, std::string option_description, callback_t callback, App *parent, bool allow_non_standard=false)
Making an option by hand is not defined, it must be made by the App class.
Definition Option.hpp:372
CLI11_NODISCARD int get_items_expected_min() const
The total min number of expected string values to be used.
Definition Option.hpp:621
CLI11_NODISCARD const std::string & matching_name(const Option &other) const
If options share any of the same names, find it.
Definition Option_inl.hpp:356
CLI11_NODISCARD bool check_lname(std::string name) const
Requires "--" to be removed from string.
Definition Option.hpp:692
CLI11_NODISCARD int get_items_expected_max() const
Get the maximum number of items expected to be returned and used for the callback.
Definition Option.hpp:624
std::vector< std::string > snames_
A list of the short names (-a) without the leading dashes.
Definition Option.hpp:268
results_t proc_results_
results after reduction
Definition Option.hpp:348
bool remove_excludes(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list.
Definition Option_inl.hpp:205
Option * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times (or another policy).
Definition Option_inl.hpp:256
std::vector< Validator_p > validators_
A list of Validators to run on each value parsed.
Definition Option.hpp:323
Option * excludes(Option *opt)
Sets excluded options.
Definition Option_inl.hpp:190
App * parent_
link back up to the parent App for fallthrough
Definition Option.hpp:336
int expected_max_
The maximum number of expected values.
Definition Option.hpp:320
CLI11_NODISCARD std::string get_flag_value(const std::string &name, std::string input_value) const
Definition Option_inl.hpp:423
CLI11_NODISCARD int get_items_expected() const
The total min number of expected string values to be used.
Definition Option.hpp:629
bool inject_separator_
flag indicating a separator needs to be injected after each argument call
Definition Option.hpp:365
Validator * get_validator(const std::string &validator_name="")
Get a named Validator.
Definition Option_inl.hpp:160
callback_t callback_
Options store a callback to do all the work.
Definition Option.hpp:339
CLI11_NODISCARD bool empty() const
True if the option was not passed.
Definition Option.hpp:392
CLI11_NODISCARD int get_expected_max() const
The max number of times the option expects to be included.
Definition Option.hpp:618
CLI11_NODISCARD int get_type_size() const
The number of arguments the option expects.
Definition Option.hpp:566
std::string envname_
If given, check the environment for this option.
Definition Option.hpp:284
Option * ignore_underscore(bool value=true)
Definition Option_inl.hpp:235
std::vector< std::pair< std::string, std::string > > default_flag_values_
Definition Option.hpp:275
int type_size_max_
Definition Option.hpp:313
bool allow_extra_args_
Specify that extra args beyond type_size_max should be allowed.
Definition Option.hpp:359
std::vector< std::string > lnames_
A list of the long names (--long) without the leading dashes.
Definition Option.hpp:271
Option * add_result(std::string s)
Puts a result at the end.
Definition Option_inl.hpp:469
bool remove_needs(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list.
Definition Option_inl.hpp:180
Option * each(const std::function< void(std::string)> &func)
Adds a user supplied function to run on each item passed in (communicate though lambda capture).
Definition Option_inl.hpp:149
results_t results_
complete Results of parsing
Definition Option.hpp:346
Thrown when counting a nonexistent option.
Definition Error.hpp:352
Some validators that are provided.
Definition Validators.hpp:54
Validator & non_modifying(bool no_modify=true)
Specify whether the Validator can be modifying or not.
Definition Validators.hpp:139