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