args-parser 6.3.6
Loading...
Searching...
No Matches
help_printer.hpp
Go to the documentation of this file.
1
2/*
3 SPDX-FileCopyrightText: 2026 Igor Mironchik <igor.mironchik@gmail.com>
4 SPDX-License-Identifier: MIT
5*/
6
7#ifndef ARGS__HELP_PRINTER_HPP__INCLUDED
8#define ARGS__HELP_PRINTER_HPP__INCLUDED
9
10// C++ include.
11#include <algorithm>
12#include <functional>
13#include <vector>
14
15// Args include.
16#include "cmd_line.hpp"
17#include "command.hpp"
18#include "exceptions.hpp"
19#include "group_iface.hpp"
20#include "groups.hpp"
22#include "types.hpp"
23#include "utils.hpp"
24
25namespace Args
26{
27
28class CmdLine;
29class ArgIface;
30
31//
32// HelpPrinter
33//
34
39{
40public:
42 using ArgPtr = std::unique_ptr<ArgIface, details::Deleter<ArgIface>>;
43
45
46 virtual ~HelpPrinter();
47
49 void print(
51 OutStreamType &to) override;
52
54 void print(
56 const String &name,
58 OutStreamType &to,
60 Command *parent = nullptr) override;
61
63 void setExecutable(const String &exe) override;
64
66 void setAppDescription(const String &desc) override;
67
69 void setCmdLine(CmdLine *cmd) override;
70
72 void setLineLength(String::size_type length) override;
73
75 ArgIface *findArgument(const String &name) override
76 {
77 return m_cmdLine->findArgument(name);
78 }
79
80private:
82 StringList createUsageString(ArgIface *arg,
83 bool required) const;
85 StringList splitToWords(const String &s) const;
87 void printString(OutStreamType &to,
88 const StringList &words,
89 String::size_type currentPos,
90 String::size_type leftMargin,
91 String::size_type rightMargin) const;
93 void print(ArgIface *arg,
94 OutStreamType &to) const;
96 void printDefaultValue(ArgIface *arg,
97 OutStreamType &to,
98 String::size_type currentPos,
99 String::size_type leftMargin,
100 String::size_type rightMargin) const;
102 void sortArg(const ArgPtr &arg,
103 std::vector<Command *> &commands,
104 std::vector<ArgIface *> &required,
105 std::vector<ArgIface *> &optional,
106 String::size_type &maxFlag,
107 String::size_type &maxName,
108 String::size_type &maxCommand,
109 bool requiredAllOfGroup = false) const;
111 void printOnlyFor(ArgIface *arg,
112 OutStreamType &to,
113 String::size_type beforeDescription,
114 String::size_type maxFlag) const;
115
116private:
118
119
120 String m_exeName;
122 String m_appDescription;
124 CmdLine *m_cmdLine;
126 String::size_type m_lineLength;
127}; // class HelpPrinter
128
129static const String c_positional = SL("[positional]");
130
131static const String c_commands = SL("<command>");
132
133static const String c_options = SL("<options>");
134
135//
136// HelpPrinter
137//
138
140 : m_cmdLine(0)
141 , m_lineLength(79)
142{
143}
144
146{
147}
148
149static inline void printOffset(OutStreamType &to,
150 String::size_type &currentPos,
151 String::size_type leftMargin)
152{
153 if (currentPos < leftMargin) {
154 to << String(leftMargin - currentPos, ' ');
155 currentPos = leftMargin;
156 }
157}
158
159static inline void calcMaxFlagAndName(ArgIface *arg,
160 String::size_type &maxFlag,
161 String::size_type &maxName)
162{
163 String::size_type f = 1;
164 String::size_type n = (!arg->argumentName().empty() ? arg->argumentName().length()
165 : (arg->flag().empty() ? arg->name().length() : 0));
166
167 if (arg->isWithValue()) {
168 if (n > 0) {
169 n += 3 + arg->valueSpecifier().length();
170 } else {
171 f += 3 + arg->valueSpecifier().length();
172 }
173 }
174
175 if (f > maxFlag) {
176 maxFlag = f;
177 }
178
179 if (n > maxName) {
180 maxName = n;
181 }
182}
183
184inline void HelpPrinter::sortArg(const ArgPtr &arg,
185 std::vector<Command *> &commands,
186 std::vector<ArgIface *> &required,
187 std::vector<ArgIface *> &optional,
188 String::size_type &maxFlag,
189 String::size_type &maxName,
190 String::size_type &maxCommand,
191 bool requiredAllOfGroup) const
192{
193 GroupIface *g = dynamic_cast<GroupIface *>(arg.get());
194
195 if (arg->type() == ArgType::Command) {
196 Command *cmd = static_cast<Command *>(arg.get());
197
198 commands.push_back(cmd);
199
200 String::size_type length = cmd->name().length() + (cmd->isWithValue() ? 3 + cmd->valueSpecifier().length() : 0);
201
202 if (length > maxCommand) {
203 maxCommand = length;
204 }
205 } else if (g) {
206 if (g->isRequired() && g->type() == ArgType::AllOfGroup) {
207 requiredAllOfGroup = true;
208 } else {
209 requiredAllOfGroup = false;
210 }
211
212 auto f = std::bind(&HelpPrinter::sortArg,
213 this,
214 std::placeholders::_1,
215 std::ref(commands),
216 std::ref(required),
217 std::ref(optional),
218 std::ref(maxFlag),
219 std::ref(maxName),
220 std::ref(maxCommand),
221 requiredAllOfGroup);
222
223 std::for_each(g->children().cbegin(), g->children().cend(), f);
224 } else {
225 if (arg->isRequired() || requiredAllOfGroup) {
226 required.push_back(arg.get());
227 } else {
228 optional.push_back(arg.get());
229 }
230
231 calcMaxFlagAndName(arg.get(), maxFlag, maxName);
232 }
233}
234
235inline void HelpPrinter::printOnlyFor(ArgIface *arg,
236 OutStreamType &to,
237 String::size_type beforeDescription,
238 String::size_type) const
239{
240 String::size_type pos = 0;
241
242 if (!arg->flag().empty()) {
243 to << ' ';
244 ++pos;
245 to << '-' << arg->flag();
246 pos += arg->flag().length() + 1;
247
248 if (!arg->argumentName().empty()) {
249 to << ',';
250 ++pos;
251 } else if (arg->isWithValue()) {
252 to << " <" << arg->valueSpecifier() << '>';
253 pos += arg->valueSpecifier().length() + 3;
254 }
255 } else {
256 printOffset(to, pos, 4);
257 pos = 4;
258 }
259
260 if (!arg->argumentName().empty()) {
261 to << ' ';
262 ++pos;
263 to << "--" << arg->argumentName();
264 pos += arg->argumentName().length() + 2;
265
266 if (arg->isWithValue()) {
267 to << " <" << arg->valueSpecifier() << '>';
268 pos += arg->valueSpecifier().length() + 3;
269 }
270 } else if (arg->flag().empty() && arg->argumentName().empty()) {
271 to << ' ';
272 ++pos;
273 to << arg->name();
274 pos += arg->name().length();
275
276 if (arg->isWithValue()) {
277 to << " <" << arg->valueSpecifier() << '>';
278 pos += arg->valueSpecifier().length() + 3;
279 }
280 }
281
282 printString(to, splitToWords(arg->description()), pos, beforeDescription, 0);
283
284 to << "\n" << "\n";
285
286 printDefaultValue(arg, to, 0, beforeDescription, 0);
287
288 to.flush();
289}
290
291namespace details
292{
293
294template<typename T>
295bool argNameLess(const T &a1,
296 const T &a2)
297{
298 static const Char dash = SL('-');
299
300 if (!a1->name().empty() && !a2->name().empty()) {
301 if (*(a1->name().cbegin()) != dash && *(a2->name().cbegin()) == dash) {
302 return true;
303 } else if (*(a1->name().cbegin()) == dash && *(a2->name().cbegin()) != dash) {
304 return false;
305 } else if (a1->argumentName().empty() && !a2->argumentName().empty()) {
306 return true;
307 } else if (!a1->argumentName().empty() && a2->argumentName().empty()) {
308 return false;
309 } else {
310 return (a1->name() < a2->name());
311 }
312 } else {
313 return (a1->name() < a2->name());
314 }
315}
316
317} /* namespace details */
318
320{
321 std::vector<ArgIface *> required;
322 std::vector<ArgIface *> optional;
323 std::vector<Command *> commands;
324
325 String::size_type maxFlag = 0;
326 String::size_type maxName = 0;
327 String::size_type maxCommand = 0;
328
329 bool requiredAllOfGroup = false;
330
331 auto f = std::bind(&HelpPrinter::sortArg,
332 this,
333 std::placeholders::_1,
334 std::ref(commands),
335 std::ref(required),
336 std::ref(optional),
337 std::ref(maxFlag),
338 std::ref(maxName),
339 std::ref(maxCommand),
340 requiredAllOfGroup);
341
342 std::for_each(m_cmdLine->arguments().cbegin(), m_cmdLine->arguments().cend(), f);
343
344 // Sort arguments by name.
345 std::sort(required.begin(), required.end(), [](const auto &a1, const auto &a2) {
346 return details::argNameLess(a1, a2);
347 });
348
349 std::sort(optional.begin(), optional.end(), [](const auto &a1, const auto &a2) {
350 return details::argNameLess(a1, a2);
351 });
352
353 std::sort(commands.begin(), commands.end(), [](const auto &c1, const auto &c2) {
354 return details::argNameLess(c1, c2);
355 });
356
357 maxFlag += 2;
358 maxName += 2;
359 maxCommand += 2;
360
361 printString(to, splitToWords(m_appDescription), 0, 0, 0);
362
363 to << "\n" << "\n";
364
365 if (commands.empty()) {
366 StringList usage;
367
368 usage.push_back(m_exeName);
369
370 bool requiredFlag = true;
371
372 std::function<void(ArgIface *)> createUsageAndAppend = [&](ArgIface *arg) {
373 const StringList words = createUsageString(arg, requiredFlag);
374
375 for (const auto &w : details::asConst(words)) {
376 usage.push_back(w);
377 }
378 };
379
380 std::for_each(required.cbegin(), required.cend(), createUsageAndAppend);
381
382 requiredFlag = false;
383
384 std::for_each(optional.cbegin(), optional.cend(), createUsageAndAppend);
385
386 to << "USAGE: ";
387
388 if (m_cmdLine->parserOptions() & CmdLine::HandlePositionalArguments) {
389 usage.push_back(m_cmdLine->positionalDescription().empty() ? c_positional
390 : m_cmdLine->positionalDescription());
391 }
392
393 printString(to, usage, 7, 7, 1);
394
395 to << "\n" << "\n";
396 } else {
397 StringList usage;
398
399 usage.push_back(m_exeName);
400 usage.push_back(c_commands);
401
402 if (!optional.empty() || !required.empty()) {
403 usage.push_back(c_options);
404 }
405
406 if (m_cmdLine->parserOptions() & CmdLine::HandlePositionalArguments) {
407 usage.push_back(m_cmdLine->positionalDescription().empty() ? c_positional
408 : m_cmdLine->positionalDescription());
409 }
410
411 to << "USAGE: ";
412
413 printString(to, usage, 7, 7, 1);
414
415 to << "\n" << "\n";
416
417 std::for_each(commands.cbegin(), commands.cend(), [&](Command *cmd) {
418 String::size_type pos = 2;
419
420 to << " " << cmd->name();
421
422 pos += cmd->name().length();
423
424 if (cmd->isWithValue()) {
425 to << " <" << cmd->valueSpecifier() << ">";
426
427 pos += 3 + cmd->valueSpecifier().length();
428 }
429
430 printString(to, splitToWords(cmd->description()), pos, maxCommand + 1, 0);
431
432 to << "\n";
433 });
434
435 to << "\n";
436 }
437
438 auto printArg = std::bind(&HelpPrinter::printOnlyFor,
439 this,
440 std::placeholders::_1,
441 std::ref(to),
442 (maxFlag == 1 ? maxName + 6 : (maxName + 6 > maxFlag + 1 ? maxName + 6 : maxFlag + 1)),
443 maxFlag);
444
445 if (!required.empty()) {
446 to << "REQUIRED:" << "\n";
447
448 std::for_each(required.cbegin(), required.cend(), printArg);
449 }
450
451 if (!optional.empty()) {
452 to << "OPTIONAL:" << "\n";
453
454 std::for_each(optional.cbegin(), optional.cend(), printArg);
455 }
456
457 to.flush();
458}
459
460inline void HelpPrinter::print(const String &name,
461 OutStreamType &to,
462 Command *parent)
463{
464 auto *arg = (parent ? parent->findChild(name) : m_cmdLine->findArgument(name));
465
466 if (parent && !arg) {
467 arg = m_cmdLine->findArgument(name);
468 }
469
470 if (arg && arg->type() == ArgType::Command) {
471 Command *cmd = static_cast<Command *>(arg);
472
473 // Prepare global arguments.
474 std::vector<ArgIface *> grequired;
475 std::vector<ArgIface *> goptional;
476 std::vector<Command *> gcommands;
477
478 String::size_type gmaxFlag = 0;
479 String::size_type gmaxName = 0;
480 String::size_type gmaxCommand = 0;
481
482 bool requiredAllOfGroup = false;
483
484 auto gf = std::bind(&HelpPrinter::sortArg,
485 this,
486 std::placeholders::_1,
487 std::ref(gcommands),
488 std::ref(grequired),
489 std::ref(goptional),
490 std::ref(gmaxFlag),
491 std::ref(gmaxName),
492 std::ref(gmaxCommand),
493 requiredAllOfGroup);
494
495 std::for_each(m_cmdLine->arguments().cbegin(), m_cmdLine->arguments().cend(), gf);
496
497 // Sort global arguments by name.
498 std::sort(grequired.begin(), grequired.end(), [](const auto &a1, const auto &a2) {
499 return details::argNameLess(a1, a2);
500 });
501
502 std::sort(goptional.begin(), goptional.end(), [](const auto &a1, const auto &a2) {
503 return details::argNameLess(a1, a2);
504 });
505
506 gmaxFlag += 2;
507 gmaxName += 2;
508
509 // Prepare arguments of command.
510 std::vector<ArgIface *> required;
511 std::vector<ArgIface *> optional;
512 std::vector<Command *> commands;
513
514 String::size_type maxFlag = 0;
515 String::size_type maxName = 0;
516 String::size_type maxCommand = 0;
517
518 requiredAllOfGroup = false;
519
520 auto f = std::bind(&HelpPrinter::sortArg,
521 this,
522 std::placeholders::_1,
523 std::ref(commands),
524 std::ref(required),
525 std::ref(optional),
526 std::ref(maxFlag),
527 std::ref(maxName),
528 std::ref(maxCommand),
529 requiredAllOfGroup);
530
531 std::for_each(cmd->children().cbegin(), cmd->children().cend(), f);
532
533 // Sort arguments by name.
534 std::sort(required.begin(), required.end(), [](const auto &a1, const auto &a2) {
535 return details::argNameLess(a1, a2);
536 });
537
538 std::sort(optional.begin(), optional.end(), [](const auto &a1, const auto &a2) {
539 return details::argNameLess(a1, a2);
540 });
541
542 std::sort(commands.begin(), commands.end(), [](const auto &c1, const auto &c2) {
543 return details::argNameLess(c1, c2);
544 });
545
546 maxFlag += 2;
547 maxName += 2;
548 maxCommand += 2;
549
550 // Print.
551 printString(to, splitToWords(cmd->longDescription()), 0, 0, 0);
552
553 to << "\n\n";
554
555 if (commands.empty()) {
556 to << "USAGE: " << name;
557
558 if (cmd->isWithValue()) {
559 to << " <" << cmd->valueSpecifier() << ">";
560 }
561
562 if (!grequired.empty() || !goptional.empty() || !required.empty() || !optional.empty()) {
563 to << " <options>";
564 }
565
566 to << "\n\n";
567 } else {
568 to << "USAGE: " << name << " <command>";
569
570 if (!optional.empty() || !required.empty()) {
571 to << " <options>";
572 }
573
574 to << "\n\n";
575
576 std::for_each(commands.cbegin(), commands.cend(), [&](Command *c) {
577 String::size_type pos = 2;
578
579 to << " " << c->name();
580
581 pos += c->name().length();
582
583 if (c->isWithValue()) {
584 to << " <" << c->valueSpecifier() << ">";
585
586 pos += 3 + c->valueSpecifier().length();
587 }
588
589 printString(to, splitToWords(c->description()), pos, maxCommand + 1, 0);
590
591 to << "\n";
592 });
593
594 to << "\n";
595 }
596
597 // Print command's arguments.
598 auto printArg =
599 std::bind(&HelpPrinter::printOnlyFor,
600 this,
601 std::placeholders::_1,
602 std::ref(to),
603 (maxFlag == 1 ? maxName + 6 : (maxName + 6 > maxFlag + 1 ? maxName + 6 : maxFlag + 1)),
604 maxFlag);
605
606 if (!required.empty()) {
607 to << "REQUIRED:" << "\n";
608
609 std::for_each(required.cbegin(), required.cend(), printArg);
610 }
611
612 if (!optional.empty()) {
613 to << "OPTIONAL:" << "\n";
614
615 std::for_each(optional.cbegin(), optional.cend(), printArg);
616 }
617
618 // Print global arguments.
619 if (!grequired.empty() || !goptional.empty()) {
620 auto printGlobalArg =
621 std::bind(&HelpPrinter::printOnlyFor,
622 this,
623 std::placeholders::_1,
624 std::ref(to),
625 (gmaxFlag == 1 ? gmaxName + 6 : (gmaxName + 6 > gmaxFlag + 1 ? gmaxName + 6 : gmaxFlag + 1)),
626 gmaxFlag);
627
628 if (!grequired.empty()) {
629 to << "GLOBAL REQUIRED:" << "\n";
630
631 std::for_each(grequired.cbegin(), grequired.cend(), printGlobalArg);
632 }
633
634 if (!goptional.empty()) {
635 to << "GLOBAL OPTIONAL:" << "\n";
636
637 std::for_each(goptional.cbegin(), goptional.cend(), printGlobalArg);
638 }
639 }
640
641 to.flush();
642 } else if (arg) {
643 print(arg, to);
644 } else {
645 print(to);
646 }
647}
648
649inline void HelpPrinter::printDefaultValue(ArgIface *arg,
650 OutStreamType &to,
651 String::size_type currentPos,
652 String::size_type leftMargin,
653 String::size_type rightMargin) const
654{
655 if (!arg->defaultValue().empty()) {
656 StringList words;
657 words.push_back(String("Default"));
658 words.push_back(String("value:"));
659 words.push_back(arg->defaultValue());
660
661 if (arg->valueSpecifier() != SL("arg")) {
662 words.push_back(arg->valueSpecifier());
663 }
664
665 printString(to, words, currentPos, leftMargin, rightMargin);
666
667 to << "\n" << "\n";
668 }
669}
670
671inline void HelpPrinter::print(ArgIface *arg,
672 OutStreamType &to) const
673{
674 StringList usage = createUsageString(arg, arg->isRequired());
675
676 to << "USAGE: ";
677
678 std::for_each(usage.cbegin(), usage.cend(), [&](const String &s) {
679 to << s << ' ';
680 });
681
682 to << "\n" << "\n";
683
684 printString(to, splitToWords(arg->longDescription()), 0, 7, 7);
685
686 to << "\n" << "\n";
687
688 printDefaultValue(arg, to, 0, 7, 7);
689
690 to.flush();
691}
692
693inline void HelpPrinter::setExecutable(const String &exe)
694{
695 m_exeName = exe;
696}
697
699{
700 m_appDescription = desc;
701}
702
704{
705 m_cmdLine = cmd;
706}
707
708inline void HelpPrinter::setLineLength(String::size_type length)
709{
710 if (length > 40) {
711 m_lineLength = length;
712 } else {
713 m_lineLength = 40;
714 }
715}
716
717inline StringList HelpPrinter::createUsageString(ArgIface *arg,
718 bool required) const
719{
720 StringList result;
721
722 String usage;
723
724 if (!required) {
725 usage.append(SL("[ "));
726 }
727
728 if (!arg->flag().empty()) {
729 usage.append(SL("-"));
730 usage.append(arg->flag());
731
732 if (!arg->argumentName().empty()) {
733 usage.append(SL(","));
734
735 result.push_back(usage);
736
737 usage.clear();
738 }
739 }
740
741 if (!arg->argumentName().empty()) {
742 usage.append(SL("--"));
743 usage.append(arg->argumentName());
744 } else if (arg->flag().empty() && arg->argumentName().empty()) {
745 usage.append(arg->name());
746 }
747
748 if (arg->isWithValue()) {
749 usage.append(SL(" <"));
750 usage.append(arg->valueSpecifier());
751 usage.append(SL(">"));
752 }
753
754 if (!required) {
755 usage.append(SL(" ]"));
756 }
757
758 result.push_back(usage);
759
760 return result;
761}
762
763static inline bool isSpaceChar(const Char &c)
764{
765 static const String spaceChars = SL(" \t");
766
767 return (spaceChars.find(c) != String::npos);
768}
769
770inline StringList HelpPrinter::splitToWords(const String &s) const
771{
772 String word;
773 StringList result;
774
775 const auto pushWord = [&word, &result]() {
776 if (!word.empty()) {
777 result.push_back(word);
778 }
779
780 word.clear();
781 };
782
783 std::for_each(s.cbegin(), s.cend(), [&](const Char &c) {
784 if (isSpaceChar(c)) {
785 pushWord();
786 } else {
787 if (c == '\n') {
788 pushWord();
789
790 result.push_back(String(1, c));
791 } else {
792 word.append(1, c);
793 }
794 }
795 });
796
797 pushWord();
798
799 return result;
800}
801
802inline void HelpPrinter::printString(OutStreamType &to,
803 const StringList &words,
804 String::size_type currentPos,
805 String::size_type leftMargin,
806 String::size_type rightMargin) const
807{
808 String::size_type maxLineLength = (rightMargin < m_lineLength ? m_lineLength - rightMargin : 0);
809
810 if (maxLineLength - leftMargin < 20) {
811 to << "\n\n";
812
813 maxLineLength = m_lineLength;
814
815 currentPos = 0;
816 leftMargin = 20;
817 rightMargin = 0;
818 }
819
820 String::size_type length = 0;
821
822 bool makeOffset = (currentPos < leftMargin);
823
824 const auto moveToNewLine = [&]() {
825 currentPos = 0;
826
827 to << "\n";
828
829 printOffset(to, currentPos, leftMargin);
830
831 length = leftMargin;
832 };
833
834 std::function<void(const String &)> printWord;
835
836 printWord = [&](const String &word) {
837 const auto print = [&]() {
838 length += word.length();
839
840 to << word;
841
842 if (length < maxLineLength) {
843 ++length;
844 to << ' ';
845 }
846 };
847
848 if (length + word.length() < maxLineLength) {
849 print();
850 } else {
851 if (length != leftMargin) {
852 moveToNewLine();
853 }
854
855 const auto available = maxLineLength - length;
856
857 if (available < word.length()) {
858 to << word.substr(0, available);
859 length += available;
860
861 printWord(word.substr(available));
862 } else {
863 print();
864 }
865 }
866 };
867
868 std::for_each(words.cbegin(), words.cend(), [&](const String &word) {
869 if (makeOffset) {
870 printOffset(to, currentPos, leftMargin);
871
872 length = leftMargin;
873
874 makeOffset = false;
875 }
876
877 if (word == "\n") {
878 moveToNewLine();
879 moveToNewLine();
880 } else {
881 printWord(word);
882 }
883 });
884}
885
886} /* namespace Args */
887
888#endif // ARGS__HELP_PRINTER_HPP__INCLUDED
Interface for arguments.
Definition arg_iface.hpp:29
virtual ArgIface * findArgument(const String &name)=0
virtual const String & valueSpecifier() const =0
virtual String name() const =0
virtual const String & argumentName() const =0
virtual bool isWithValue() const =0
virtual const String & flag() const =0
CmdLine is class that holds all rguments and parse command line arguments in the correspondence with ...
Definition cmd_line.hpp:98
@ HandlePositionalArguments
Handle positional arguments.
Definition cmd_line.hpp:112
Command in the command line interface.
Definition command.hpp:28
ArgIface * findChild(const String &name)
Definition command.hpp:292
bool isWithValue() const override
Definition command.hpp:86
const String & longDescription() const override
Definition command.hpp:123
const String & description() const override
Definition command.hpp:111
const String & valueSpecifier() const override
Definition command.hpp:99
const Arguments & children() const
HelpPrinter is a class that prints help.
std::unique_ptr< ArgIface, details::Deleter< ArgIface > > ArgPtr
Smart pointer to the argument.
void setCmdLine(CmdLine *cmd) override
Set command line.
void setExecutable(const String &exe) override
Set executable name.
ArgIface * findArgument(const String &name) override
void setLineLength(String::size_type length) override
Set line length for the help.
void setAppDescription(const String &desc) override
Set description for the application.
void print(OutStreamType &to) override
Print help for all arguments.
constexpr std::add_const< T >::type & asConst(T &t) noexcept
Adds const to non-const objects.
Definition utils.hpp:45
bool argNameLess(const T &a1, const T &a2)
Definition api.hpp:18
std::ostream OutStreamType
Out stream type.
Definition types.hpp:320
std::string String
String type.
Definition types.hpp:314
@ AllOfGroup
"All of" group.
Definition enums.hpp:42
@ Command
Command.
Definition enums.hpp:34
String::value_type Char
Char type.
Definition types.hpp:317
std::vector< String > StringList
List of strings.
Definition types.hpp:336
#define SL(str)
Definition types.hpp:328
#define DISABLE_COPY(Class)
Macro for disabling copy.
Definition utils.hpp:25