Commit 5f696596d70cc59cf28d9f825d783a9cd29cf292

Authored by Philip Top
Committed by Henry Schreiner
1 parent d621658e

fix some warnings generated from klocwork static analyzer (#350)

* fix some warnings generated from klocwork static analyzer

* Some more visual studio static analyzer and clang-tidy fixes

* some formatting updates
include/CLI/App.hpp
... ... @@ -751,10 +751,11 @@ class App {
751 751 std::string flag_description = "") {
752 752  
753 753 CLI::callback_t fun = [function](const CLI::results_t &res) {
754   - bool trigger;
  754 + bool trigger{false};
755 755 auto result = CLI::detail::lexical_cast(res[0], trigger);
756   - if(trigger)
  756 + if(result && trigger) {
757 757 function();
  758 + }
758 759 return result;
759 760 };
760 761 return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
... ...
include/CLI/TypeTools.hpp
... ... @@ -311,7 +311,7 @@ template <typename T> struct expected_count<T, typename std::enable_if<is_vector
311 311 };
312 312  
313 313 // Enumeration of the different supported categorizations of objects
314   -enum objCategory : int {
  314 +enum class object_category : int {
315 315 integral_value = 2,
316 316 unsigned_integral = 4,
317 317 enumeration = 6,
... ... @@ -330,14 +330,16 @@ enum objCategory : int {
330 330 };
331 331  
332 332 /// some type that is not otherwise recognized
333   -template <typename T, typename Enable = void> struct classify_object { static constexpr objCategory value{other}; };
  333 +template <typename T, typename Enable = void> struct classify_object {
  334 + static constexpr object_category value{object_category::other};
  335 +};
334 336  
335 337 /// Set of overloads to classify an object according to type
336 338 template <typename T>
337 339 struct classify_object<T,
338 340 typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value &&
339 341 !is_bool<T>::value && !std::is_enum<T>::value>::type> {
340   - static constexpr objCategory value{integral_value};
  342 + static constexpr object_category value{object_category::integral_value};
341 343 };
342 344  
343 345 /// Unsigned integers
... ... @@ -345,17 +347,17 @@ template &lt;typename T&gt;
345 347 struct classify_object<
346 348 T,
347 349 typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value && !is_bool<T>::value>::type> {
348   - static constexpr objCategory value{unsigned_integral};
  350 + static constexpr object_category value{object_category::unsigned_integral};
349 351 };
350 352  
351 353 /// Boolean values
352 354 template <typename T> struct classify_object<T, typename std::enable_if<is_bool<T>::value>::type> {
353   - static constexpr objCategory value{boolean_value};
  355 + static constexpr object_category value{object_category::boolean_value};
354 356 };
355 357  
356 358 /// Floats
357 359 template <typename T> struct classify_object<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
358   - static constexpr objCategory value{floating_point};
  360 + static constexpr object_category value{object_category::floating_point};
359 361 };
360 362  
361 363 /// String and similar direct assignment
... ... @@ -364,7 +366,7 @@ struct classify_object&lt;
364 366 T,
365 367 typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
366 368 std::is_assignable<T &, std::string>::value && !is_vector<T>::value>::type> {
367   - static constexpr objCategory value{string_assignable};
  369 + static constexpr object_category value{object_category::string_assignable};
368 370 };
369 371  
370 372 /// String and similar constructible and copy assignment
... ... @@ -374,12 +376,12 @@ struct classify_object&lt;
374 376 typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
375 377 !std::is_assignable<T &, std::string>::value &&
376 378 std::is_constructible<T, std::string>::value && !is_vector<T>::value>::type> {
377   - static constexpr objCategory value{string_constructible};
  379 + static constexpr object_category value{object_category::string_constructible};
378 380 };
379 381  
380 382 /// Enumerations
381 383 template <typename T> struct classify_object<T, typename std::enable_if<std::is_enum<T>::value>::type> {
382   - static constexpr objCategory value{enumeration};
  384 + static constexpr object_category value{object_category::enumeration};
383 385 };
384 386  
385 387 /// Handy helper to contain a bunch of checks that rule out many common types (integers, string like, floating point,
... ... @@ -400,7 +402,7 @@ struct classify_object&lt;T,
400 402 typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
401 403 is_direct_constructible<T, double>::value &&
402 404 is_direct_constructible<T, int>::value>::type> {
403   - static constexpr objCategory value{number_constructible};
  405 + static constexpr object_category value{object_category::number_constructible};
404 406 };
405 407  
406 408 /// Assignable from int
... ... @@ -409,7 +411,7 @@ struct classify_object&lt;T,
409 411 typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
410 412 !is_direct_constructible<T, double>::value &&
411 413 is_direct_constructible<T, int>::value>::type> {
412   - static constexpr objCategory value{integer_constructible};
  414 + static constexpr object_category value{object_category::integer_constructible};
413 415 };
414 416  
415 417 /// Assignable from double
... ... @@ -418,7 +420,7 @@ struct classify_object&lt;T,
418 420 typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
419 421 is_direct_constructible<T, double>::value &&
420 422 !is_direct_constructible<T, int>::value>::type> {
421   - static constexpr objCategory value{double_constructible};
  423 + static constexpr object_category value{object_category::double_constructible};
422 424 };
423 425  
424 426 /// Tuple type
... ... @@ -428,12 +430,12 @@ struct classify_object&lt;T,
428 430 (is_tuple_like<T>::value && uncommon_type<T>::value &&
429 431 !is_direct_constructible<T, double>::value &&
430 432 !is_direct_constructible<T, int>::value)>::type> {
431   - static constexpr objCategory value{tuple_value};
  433 + static constexpr object_category value{object_category::tuple_value};
432 434 };
433 435  
434 436 /// Vector type
435 437 template <typename T> struct classify_object<T, typename std::enable_if<is_vector<T>::value>::type> {
436   - static constexpr objCategory value{vector_value};
  438 + static constexpr object_category value{object_category::vector_value};
437 439 };
438 440  
439 441 // Type name print
... ... @@ -443,48 +445,53 @@ template &lt;typename T&gt; struct classify_object&lt;T, typename std::enable_if&lt;is_vecto
443 445 /// But this is cleaner and works better in this case
444 446  
445 447 template <typename T,
446   - enable_if_t<classify_object<T>::value == integral_value || classify_object<T>::value == integer_constructible,
  448 + enable_if_t<classify_object<T>::value == object_category::integral_value ||
  449 + classify_object<T>::value == object_category::integer_constructible,
447 450 detail::enabler> = detail::dummy>
448 451 constexpr const char *type_name() {
449 452 return "INT";
450 453 }
451 454  
452   -template <typename T, enable_if_t<classify_object<T>::value == unsigned_integral, detail::enabler> = detail::dummy>
  455 +template <typename T,
  456 + enable_if_t<classify_object<T>::value == object_category::unsigned_integral, detail::enabler> = detail::dummy>
453 457 constexpr const char *type_name() {
454 458 return "UINT";
455 459 }
456 460  
457   -template <
458   - typename T,
459   - enable_if_t<classify_object<T>::value == floating_point || classify_object<T>::value == number_constructible ||
460   - classify_object<T>::value == double_constructible,
461   - detail::enabler> = detail::dummy>
  461 +template <typename T,
  462 + enable_if_t<classify_object<T>::value == object_category::floating_point ||
  463 + classify_object<T>::value == object_category::number_constructible ||
  464 + classify_object<T>::value == object_category::double_constructible,
  465 + detail::enabler> = detail::dummy>
462 466 constexpr const char *type_name() {
463 467 return "FLOAT";
464 468 }
465 469  
466 470 /// Print name for enumeration types
467   -template <typename T, enable_if_t<classify_object<T>::value == enumeration, detail::enabler> = detail::dummy>
  471 +template <typename T,
  472 + enable_if_t<classify_object<T>::value == object_category::enumeration, detail::enabler> = detail::dummy>
468 473 constexpr const char *type_name() {
469 474 return "ENUM";
470 475 }
471 476  
472 477 /// Print name for enumeration types
473   -template <typename T, enable_if_t<classify_object<T>::value == boolean_value, detail::enabler> = detail::dummy>
  478 +template <typename T,
  479 + enable_if_t<classify_object<T>::value == object_category::boolean_value, detail::enabler> = detail::dummy>
474 480 constexpr const char *type_name() {
475 481 return "BOOLEAN";
476 482 }
477 483  
478 484 /// Print for all other types
479   -template <typename T, enable_if_t<classify_object<T>::value >= string_assignable, detail::enabler> = detail::dummy>
  485 +template <typename T,
  486 + enable_if_t<classify_object<T>::value >= object_category::string_assignable, detail::enabler> = detail::dummy>
480 487 constexpr const char *type_name() {
481 488 return "TEXT";
482 489 }
483 490  
484 491 /// Print name for single element tuple types
485   -template <
486   - typename T,
487   - enable_if_t<classify_object<T>::value == tuple_value && type_count<T>::value == 1, detail::enabler> = detail::dummy>
  492 +template <typename T,
  493 + enable_if_t<classify_object<T>::value == object_category::tuple_value && type_count<T>::value == 1,
  494 + detail::enabler> = detail::dummy>
488 495 inline std::string type_name() {
489 496 return type_name<typename std::tuple_element<0, T>::type>();
490 497 }
... ... @@ -505,9 +512,9 @@ template &lt;typename T, std::size_t I&gt;
505 512 }
506 513  
507 514 /// Print type name for tuples with 2 or more elements
508   -template <
509   - typename T,
510   - enable_if_t<classify_object<T>::value == tuple_value && type_count<T>::value >= 2, detail::enabler> = detail::dummy>
  515 +template <typename T,
  516 + enable_if_t<classify_object<T>::value == object_category::tuple_value && type_count<T>::value >= 2,
  517 + detail::enabler> = detail::dummy>
511 518 std::string type_name() {
512 519 auto tname = std::string(1, '[') + tuple_name<T, 0>();
513 520 tname.push_back(']');
... ... @@ -515,7 +522,8 @@ std::string type_name() {
515 522 }
516 523  
517 524 /// This one should not be used normally, since vector types print the internal type
518   -template <typename T, enable_if_t<classify_object<T>::value == vector_value, detail::enabler> = detail::dummy>
  525 +template <typename T,
  526 + enable_if_t<classify_object<T>::value == object_category::vector_value, detail::enabler> = detail::dummy>
519 527 inline std::string type_name() {
520 528 return type_name<typename T::value_type>();
521 529 }
... ... @@ -566,7 +574,8 @@ inline int64_t to_flag_value(std::string val) {
566 574 }
567 575  
568 576 /// Signed integers
569   -template <typename T, enable_if_t<classify_object<T>::value == integral_value, detail::enabler> = detail::dummy>
  577 +template <typename T,
  578 + enable_if_t<classify_object<T>::value == object_category::integral_value, detail::enabler> = detail::dummy>
570 579 bool lexical_cast(const std::string &input, T &output) {
571 580 try {
572 581 size_t n = 0;
... ... @@ -581,7 +590,8 @@ bool lexical_cast(const std::string &amp;input, T &amp;output) {
581 590 }
582 591  
583 592 /// Unsigned integers
584   -template <typename T, enable_if_t<classify_object<T>::value == unsigned_integral, detail::enabler> = detail::dummy>
  593 +template <typename T,
  594 + enable_if_t<classify_object<T>::value == object_category::unsigned_integral, detail::enabler> = detail::dummy>
585 595 bool lexical_cast(const std::string &input, T &output) {
586 596 if(!input.empty() && input.front() == '-')
587 597 return false; // std::stoull happily converts negative values to junk without any errors.
... ... @@ -599,7 +609,8 @@ bool lexical_cast(const std::string &amp;input, T &amp;output) {
599 609 }
600 610  
601 611 /// Boolean values
602   -template <typename T, enable_if_t<classify_object<T>::value == boolean_value, detail::enabler> = detail::dummy>
  612 +template <typename T,
  613 + enable_if_t<classify_object<T>::value == object_category::boolean_value, detail::enabler> = detail::dummy>
603 614 bool lexical_cast(const std::string &input, T &output) {
604 615 try {
605 616 auto out = to_flag_value(input);
... ... @@ -616,7 +627,8 @@ bool lexical_cast(const std::string &amp;input, T &amp;output) {
616 627 }
617 628  
618 629 /// Floats
619   -template <typename T, enable_if_t<classify_object<T>::value == floating_point, detail::enabler> = detail::dummy>
  630 +template <typename T,
  631 + enable_if_t<classify_object<T>::value == object_category::floating_point, detail::enabler> = detail::dummy>
620 632 bool lexical_cast(const std::string &input, T &output) {
621 633 try {
622 634 size_t n = 0;
... ... @@ -630,21 +642,25 @@ bool lexical_cast(const std::string &amp;input, T &amp;output) {
630 642 }
631 643  
632 644 /// String and similar direct assignment
633   -template <typename T, enable_if_t<classify_object<T>::value == string_assignable, detail::enabler> = detail::dummy>
  645 +template <typename T,
  646 + enable_if_t<classify_object<T>::value == object_category::string_assignable, detail::enabler> = detail::dummy>
634 647 bool lexical_cast(const std::string &input, T &output) {
635 648 output = input;
636 649 return true;
637 650 }
638 651  
639 652 /// String and similar constructible and copy assignment
640   -template <typename T, enable_if_t<classify_object<T>::value == string_constructible, detail::enabler> = detail::dummy>
  653 +template <
  654 + typename T,
  655 + enable_if_t<classify_object<T>::value == object_category::string_constructible, detail::enabler> = detail::dummy>
641 656 bool lexical_cast(const std::string &input, T &output) {
642 657 output = T(input);
643 658 return true;
644 659 }
645 660  
646 661 /// Enumerations
647   -template <typename T, enable_if_t<classify_object<T>::value == enumeration, detail::enabler> = detail::dummy>
  662 +template <typename T,
  663 + enable_if_t<classify_object<T>::value == object_category::enumeration, detail::enabler> = detail::dummy>
648 664 bool lexical_cast(const std::string &input, T &output) {
649 665 typename std::underlying_type<T>::type val;
650 666 bool retval = detail::lexical_cast(input, val);
... ... @@ -656,7 +672,9 @@ bool lexical_cast(const std::string &amp;input, T &amp;output) {
656 672 }
657 673  
658 674 /// Assignable from double or int
659   -template <typename T, enable_if_t<classify_object<T>::value == number_constructible, detail::enabler> = detail::dummy>
  675 +template <
  676 + typename T,
  677 + enable_if_t<classify_object<T>::value == object_category::number_constructible, detail::enabler> = detail::dummy>
660 678 bool lexical_cast(const std::string &input, T &output) {
661 679 int val;
662 680 if(lexical_cast(input, val)) {
... ... @@ -673,7 +691,9 @@ bool lexical_cast(const std::string &amp;input, T &amp;output) {
673 691 }
674 692  
675 693 /// Assignable from int
676   -template <typename T, enable_if_t<classify_object<T>::value == integer_constructible, detail::enabler> = detail::dummy>
  694 +template <
  695 + typename T,
  696 + enable_if_t<classify_object<T>::value == object_category::integer_constructible, detail::enabler> = detail::dummy>
677 697 bool lexical_cast(const std::string &input, T &output) {
678 698 int val;
679 699 if(lexical_cast(input, val)) {
... ... @@ -684,7 +704,9 @@ bool lexical_cast(const std::string &amp;input, T &amp;output) {
684 704 }
685 705  
686 706 /// Assignable from double
687   -template <typename T, enable_if_t<classify_object<T>::value == double_constructible, detail::enabler> = detail::dummy>
  707 +template <
  708 + typename T,
  709 + enable_if_t<classify_object<T>::value == object_category::double_constructible, detail::enabler> = detail::dummy>
688 710 bool lexical_cast(const std::string &input, T &output) {
689 711 double val;
690 712 if(lexical_cast(input, val)) {
... ... @@ -695,7 +717,7 @@ bool lexical_cast(const std::string &amp;input, T &amp;output) {
695 717 }
696 718  
697 719 /// Non-string parsable by a stream
698   -template <typename T, enable_if_t<classify_object<T>::value == other, detail::enabler> = detail::dummy>
  720 +template <typename T, enable_if_t<classify_object<T>::value == object_category::other, detail::enabler> = detail::dummy>
699 721 bool lexical_cast(const std::string &input, T &output) {
700 722 static_assert(is_istreamable<T>::value,
701 723 "option object type must have a lexical cast overload or streaming input operator(>>) defined, if it "
... ... @@ -704,11 +726,12 @@ bool lexical_cast(const std::string &amp;input, T &amp;output) {
704 726 }
705 727  
706 728 /// Assign a value through lexical cast operations
707   -template <typename T,
708   - typename XC,
709   - enable_if_t<std::is_same<T, XC>::value && (classify_object<T>::value == string_assignable ||
710   - classify_object<T>::value == string_constructible),
711   - detail::enabler> = detail::dummy>
  729 +template <
  730 + typename T,
  731 + typename XC,
  732 + enable_if_t<std::is_same<T, XC>::value && (classify_object<T>::value == object_category::string_assignable ||
  733 + classify_object<T>::value == object_category::string_constructible),
  734 + detail::enabler> = detail::dummy>
712 735 bool lexical_assign(const std::string &input, T &output) {
713 736 return lexical_cast(input, output);
714 737 }
... ... @@ -716,8 +739,8 @@ bool lexical_assign(const std::string &amp;input, T &amp;output) {
716 739 /// Assign a value through lexical cast operations
717 740 template <typename T,
718 741 typename XC,
719   - enable_if_t<std::is_same<T, XC>::value && classify_object<T>::value != string_assignable &&
720   - classify_object<T>::value != string_constructible,
  742 + enable_if_t<std::is_same<T, XC>::value && classify_object<T>::value != object_category::string_assignable &&
  743 + classify_object<T>::value != object_category::string_constructible,
721 744 detail::enabler> = detail::dummy>
722 745 bool lexical_assign(const std::string &input, T &output) {
723 746 if(input.empty()) {
... ... @@ -774,7 +797,7 @@ bool lexical_conversion(const std::vector&lt;std ::string&gt; &amp;strings, T &amp;output) {
774 797 typename std::tuple_element<1, XC>::type v2;
775 798 bool retval = lexical_assign<decltype(v1), decltype(v1)>(strings[0], v1);
776 799 if(strings.size() > 1) {
777   - retval &= lexical_assign<decltype(v2), decltype(v2)>(strings[1], v2);
  800 + retval = retval && lexical_assign<decltype(v2), decltype(v2)>(strings[1], v2);
778 801 }
779 802 if(retval) {
780 803 output = T{v1, v2};
... ... @@ -789,15 +812,17 @@ template &lt;class T,
789 812 expected_count<XC>::value == expected_max_vector_size && type_count<XC>::value == 1,
790 813 detail::enabler> = detail::dummy>
791 814 bool lexical_conversion(const std::vector<std ::string> &strings, T &output) {
792   - bool retval = true;
793 815 output.clear();
794 816 output.reserve(strings.size());
795 817 for(const auto &elem : strings) {
796 818  
797 819 output.emplace_back();
798   - retval &= lexical_assign<typename T::value_type, typename XC::value_type>(elem, output.back());
  820 + bool retval = lexical_assign<typename T::value_type, typename XC::value_type>(elem, output.back());
  821 + if(!retval) {
  822 + return false;
  823 + }
799 824 }
800   - return (!output.empty()) && retval;
  825 + return (!output.empty());
801 826 }
802 827  
803 828 /// Lexical conversion of a vector types with type size of two
... ... @@ -807,15 +832,14 @@ template &lt;class T,
807 832 expected_count<XC>::value == expected_max_vector_size && type_count<XC>::value == 2,
808 833 detail::enabler> = detail::dummy>
809 834 bool lexical_conversion(const std::vector<std ::string> &strings, T &output) {
810   - bool retval = true;
811 835 output.clear();
812 836 for(size_t ii = 0; ii < strings.size(); ii += 2) {
813 837  
814 838 typename std::tuple_element<0, typename XC::value_type>::type v1;
815 839 typename std::tuple_element<1, typename XC::value_type>::type v2;
816   - retval = lexical_assign<decltype(v1), decltype(v1)>(strings[ii], v1);
  840 + bool retval = lexical_assign<decltype(v1), decltype(v1)>(strings[ii], v1);
817 841 if(strings.size() > ii + 1) {
818   - retval &= lexical_assign<decltype(v2), decltype(v2)>(strings[ii + 1], v2);
  842 + retval = retval && lexical_assign<decltype(v2), decltype(v2)>(strings[ii + 1], v2);
819 843 }
820 844 if(retval) {
821 845 output.emplace_back(v1, v2);
... ... @@ -823,7 +847,7 @@ bool lexical_conversion(const std::vector&lt;std ::string&gt; &amp;strings, T &amp;output) {
823 847 return false;
824 848 }
825 849 }
826   - return (!output.empty()) && retval;
  850 + return (!output.empty());
827 851 }
828 852  
829 853 /// Conversion to a vector type using a particular single type as the conversion type
... ... @@ -839,7 +863,7 @@ bool lexical_conversion(const std::vector&lt;std ::string&gt; &amp;strings, T &amp;output) {
839 863 for(const auto &elem : strings) {
840 864  
841 865 output.emplace_back();
842   - retval &= lexical_assign<typename T::value_type, XC>(elem, output.back());
  866 + retval = retval && lexical_assign<typename T::value_type, XC>(elem, output.back());
843 867 }
844 868 return (!output.empty()) && retval;
845 869 }
... ... @@ -873,12 +897,12 @@ template &lt;class T, class XC, std::size_t I&gt;
873 897 I<type_count<T>::value, bool>::type tuple_conversion(const std::vector<std::string> &strings, T &output) {
874 898 bool retval = true;
875 899 if(strings.size() > I) {
876   - retval &= lexical_assign<
877   - typename std::tuple_element<I, T>::type,
878   - typename std::conditional<is_tuple_like<XC>::value, typename std::tuple_element<I, XC>::type, XC>::type>(
879   - strings[I], std::get<I>(output));
  900 + retval = retval && lexical_assign<typename std::tuple_element<I, T>::type,
  901 + typename std::conditional<is_tuple_like<XC>::value,
  902 + typename std::tuple_element<I, XC>::type,
  903 + XC>::type>(strings[I], std::get<I>(output));
880 904 }
881   - retval &= tuple_conversion<T, XC, I + 1>(strings, output);
  905 + retval = retval && tuple_conversion<T, XC, I + 1>(strings, output);
882 906 return retval;
883 907 }
884 908  
... ...
include/CLI/Validators.hpp
... ... @@ -373,17 +373,16 @@ class IPV4Validator : public Validator {
373 373 func_ = [](std::string &ip_addr) {
374 374 auto result = CLI::detail::split(ip_addr, '.');
375 375 if(result.size() != 4) {
376   - return "Invalid IPV4 address must have four parts (" + ip_addr + ')';
  376 + return std::string("Invalid IPV4 address must have four parts (") + ip_addr + ')';
377 377 }
378 378 int num;
379   - bool retval = true;
380 379 for(const auto &var : result) {
381   - retval &= detail::lexical_cast(var, num);
  380 + bool retval = detail::lexical_cast(var, num);
382 381 if(!retval) {
383   - return "Failed parsing number (" + var + ')';
  382 + return std::string("Failed parsing number (") + var + ')';
384 383 }
385 384 if(num < 0 || num > 255) {
386   - return "Each IP number must be between 0 and 255 " + var;
  385 + return std::string("Each IP number must be between 0 and 255 ") + var;
387 386 }
388 387 }
389 388 return std::string();
... ... @@ -398,10 +397,10 @@ class PositiveNumber : public Validator {
398 397 func_ = [](std::string &number_str) {
399 398 double number;
400 399 if(!detail::lexical_cast(number_str, number)) {
401   - return "Failed parsing number: (" + number_str + ')';
  400 + return std::string("Failed parsing number: (") + number_str + ')';
402 401 }
403 402 if(number <= 0) {
404   - return "Number less or equal to 0: (" + number_str + ')';
  403 + return std::string("Number less or equal to 0: (") + number_str + ')';
405 404 }
406 405 return std::string();
407 406 };
... ... @@ -414,10 +413,10 @@ class NonNegativeNumber : public Validator {
414 413 func_ = [](std::string &number_str) {
415 414 double number;
416 415 if(!detail::lexical_cast(number_str, number)) {
417   - return "Failed parsing number: (" + number_str + ')';
  416 + return std::string("Failed parsing number: (") + number_str + ')';
418 417 }
419 418 if(number < 0) {
420   - return "Number less than 0: (" + number_str + ')';
  419 + return std::string("Number less than 0: (") + number_str + ')';
421 420 }
422 421 return std::string();
423 422 };
... ... @@ -431,7 +430,7 @@ class Number : public Validator {
431 430 func_ = [](std::string &number_str) {
432 431 double number;
433 432 if(!detail::lexical_cast(number_str, number)) {
434   - return "Failed parsing as a number (" + number_str + ')';
  433 + return std::string("Failed parsing as a number (") + number_str + ')';
435 434 }
436 435 return std::string();
437 436 };
... ... @@ -482,7 +481,8 @@ class Range : public Validator {
482 481 T val;
483 482 bool converted = detail::lexical_cast(input, val);
484 483 if((!converted) || (val < min || val > max))
485   - return "Value " + input + " not in range " + std::to_string(min) + " to " + std::to_string(max);
  484 + return std::string("Value ") + input + " not in range " + std::to_string(min) + " to " +
  485 + std::to_string(max);
486 486  
487 487 return std::string();
488 488 };
... ... @@ -508,7 +508,7 @@ class Bound : public Validator {
508 508 T val;
509 509 bool converted = detail::lexical_cast(input, val);
510 510 if(!converted) {
511   - return "Value " + input + " could not be converted";
  511 + return std::string("Value ") + input + " could not be converted";
512 512 }
513 513 if(val < min)
514 514 input = detail::to_string(min);
... ... @@ -943,7 +943,8 @@ class AsNumberWithUnit : public Validator {
943 943  
944 944 bool converted = detail::lexical_cast(input, num);
945 945 if(!converted) {
946   - throw ValidationError("Value " + input + " could not be converted to " + detail::type_name<Number>());
  946 + throw ValidationError(std::string("Value ") + input + " could not be converted to " +
  947 + detail::type_name<Number>());
947 948 }
948 949  
949 950 if(unit.empty()) {
... ... @@ -991,7 +992,8 @@ class AsNumberWithUnit : public Validator {
991 992 for(auto &kv : mapping) {
992 993 auto s = detail::to_lower(kv.first);
993 994 if(lower_mapping.count(s)) {
994   - throw ValidationError("Several matching lowercase unit representations are found: " + s);
  995 + throw ValidationError(std::string("Several matching lowercase unit representations are found: ") +
  996 + s);
995 997 }
996 998 lower_mapping[detail::to_lower(kv.first)] = kv.second;
997 999 }
... ...
tests/AppTest.cpp
... ... @@ -294,7 +294,7 @@ TEST_F(TApp, OneStringEqualVersionSingleString) {
294 294 TEST_F(TApp, OneStringEqualVersionSingleStringQuoted) {
295 295 std::string str;
296 296 app.add_option("-s,--string", str);
297   - app.parse("--string=\"this is my quoted string\"");
  297 + app.parse(R"raw(--string="this is my quoted string")raw");
298 298 EXPECT_EQ(1u, app.count("-s"));
299 299 EXPECT_EQ(1u, app.count("--string"));
300 300 EXPECT_EQ(str, "this is my quoted string");
... ... @@ -305,7 +305,7 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultiple) {
305 305 app.add_option("-s,--string", str);
306 306 app.add_option("-t,--tstr", str2);
307 307 app.add_option("-m,--mstr", str3);
308   - app.parse("--string=\"this is my quoted string\" -t 'qstring 2' -m=`\"quoted string\"`");
  308 + app.parse(R"raw(--string="this is my quoted string" -t 'qstring 2' -m=`"quoted string"`)raw");
309 309 EXPECT_EQ(str, "this is my quoted string");
310 310 EXPECT_EQ(str2, "qstring 2");
311 311 EXPECT_EQ(str3, "\"quoted string\"");
... ... @@ -316,12 +316,12 @@ TEST_F(TApp, OneStringEqualVersionSingleStringEmbeddedEqual) {
316 316 app.add_option("-s,--string", str);
317 317 app.add_option("-t,--tstr", str2);
318 318 app.add_option("-m,--mstr", str3);
319   - app.parse("--string=\"app=\\\"test1 b\\\" test2=\\\"frogs\\\"\" -t 'qstring 2' -m=`\"quoted string\"`");
  319 + app.parse(R"raw(--string="app=\"test1 b\" test2=\"frogs\"" -t 'qstring 2' -m=`"quoted string"`)raw");
320 320 EXPECT_EQ(str, "app=\"test1 b\" test2=\"frogs\"");
321 321 EXPECT_EQ(str2, "qstring 2");
322 322 EXPECT_EQ(str3, "\"quoted string\"");
323 323  
324   - app.parse("--string=\"app='test1 b' test2='frogs'\" -t 'qstring 2' -m=`\"quoted string\"`");
  324 + app.parse(R"raw(--string="app='test1 b' test2='frogs'" -t 'qstring 2' -m=`"quoted string"`)raw");
325 325 EXPECT_EQ(str, "app='test1 b' test2='frogs'");
326 326 EXPECT_EQ(str2, "qstring 2");
327 327 EXPECT_EQ(str3, "\"quoted string\"");
... ... @@ -333,12 +333,12 @@ TEST_F(TApp, OneStringEqualVersionSingleStringEmbeddedEqualWindowsStyle) {
333 333 app.add_option("-t,--tstr", str2);
334 334 app.add_option("--mstr", str3);
335 335 app.allow_windows_style_options();
336   - app.parse("/string:\"app:\\\"test1 b\\\" test2:\\\"frogs\\\"\" /t 'qstring 2' /mstr:`\"quoted string\"`");
  336 + app.parse(R"raw(/string:"app:\"test1 b\" test2:\"frogs\"" /t 'qstring 2' /mstr:`"quoted string"`)raw");
337 337 EXPECT_EQ(str, "app:\"test1 b\" test2:\"frogs\"");
338 338 EXPECT_EQ(str2, "qstring 2");
339 339 EXPECT_EQ(str3, "\"quoted string\"");
340 340  
341   - app.parse("/string:\"app:'test1 b' test2:'frogs'\" /t 'qstring 2' /mstr:`\"quoted string\"`");
  341 + app.parse(R"raw(/string:"app:'test1 b' test2:'frogs'" /t 'qstring 2' /mstr:`"quoted string"`)raw");
342 342 EXPECT_EQ(str, "app:'test1 b' test2:'frogs'");
343 343 EXPECT_EQ(str2, "qstring 2");
344 344 EXPECT_EQ(str3, "\"quoted string\"");
... ... @@ -350,7 +350,7 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultipleMixedStyle) {
350 350 app.add_option("-t,--tstr", str2);
351 351 app.add_option("-m,--mstr", str3);
352 352 app.allow_windows_style_options();
353   - app.parse("/string:\"this is my quoted string\" /t 'qstring 2' -m=`\"quoted string\"`");
  353 + app.parse(R"raw(/string:"this is my quoted string" /t 'qstring 2' -m=`"quoted string"`)raw");
354 354 EXPECT_EQ(str, "this is my quoted string");
355 355 EXPECT_EQ(str2, "qstring 2");
356 356 EXPECT_EQ(str3, "\"quoted string\"");
... ... @@ -361,7 +361,7 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultipleInMiddle) {
361 361 app.add_option("-s,--string", str);
362 362 app.add_option("-t,--tstr", str2);
363 363 app.add_option("-m,--mstr", str3);
364   - app.parse(R"raw(--string="this is my quoted string" -t "qst\"ring 2" -m=`"quoted string"`")raw");
  364 + app.parse(R"raw(--string="this is my quoted string" -t "qst\"ring 2" -m=`"quoted string"`)raw");
365 365 EXPECT_EQ(str, "this is my quoted string");
366 366 EXPECT_EQ(str2, "qst\"ring 2");
367 367 EXPECT_EQ(str3, "\"quoted string\"");
... ... @@ -384,7 +384,7 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultipleWithEqual) {
384 384 app.add_option("-t,--tstr", str2);
385 385 app.add_option("-m,--mstr", str3);
386 386 app.add_option("-j,--jstr", str4);
387   - app.parse("--string=\"this is my quoted string\" -t 'qstring 2' -m=`\"quoted string\"` --jstr=Unquoted");
  387 + app.parse(R"raw(--string="this is my quoted string" -t 'qstring 2' -m=`"quoted string"` --jstr=Unquoted)raw");
388 388 EXPECT_EQ(str, "this is my quoted string");
389 389 EXPECT_EQ(str2, "qstring 2");
390 390 EXPECT_EQ(str3, "\"quoted string\"");
... ... @@ -397,8 +397,9 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultipleWithEqualAndProgram)
397 397 app.add_option("-t,--tstr", str2);
398 398 app.add_option("-m,--mstr", str3);
399 399 app.add_option("-j,--jstr", str4);
400   - app.parse("program --string=\"this is my quoted string\" -t 'qstring 2' -m=`\"quoted string\"` --jstr=Unquoted",
401   - true);
  400 + app.parse(
  401 + R"raw(program --string="this is my quoted string" -t 'qstring 2' -m=`"quoted string"` --jstr=Unquoted)raw",
  402 + true);
402 403 EXPECT_EQ(str, "this is my quoted string");
403 404 EXPECT_EQ(str2, "qstring 2");
404 405 EXPECT_EQ(str3, "\"quoted string\"");
... ...
tests/CreationTest.cpp
... ... @@ -704,7 +704,7 @@ class Unstreamable {
704 704 int x_ = -1;
705 705  
706 706 public:
707   - Unstreamable() {}
  707 + Unstreamable() = default;
708 708 int get_x() const { return x_; }
709 709 void set_x(int x) { x_ = x; }
710 710 };
... ... @@ -719,7 +719,8 @@ std::istream &amp;operator&gt;&gt;(std::istream &amp;in, Unstreamable &amp;value) {
719 719 return in;
720 720 }
721 721 // these need to be different classes otherwise the definitions conflict
722   -static_assert(CLI::detail::is_istreamable<Unstreamable>::value, "Unstreamable type is still unstreamable");
  722 +static_assert(CLI::detail::is_istreamable<Unstreamable>::value,
  723 + "Unstreamable type is still unstreamable and it should be");
723 724  
724 725 TEST_F(TApp, MakeUnstreamableOptions) {
725 726 Unstreamable value;
... ...
tests/HelpersTest.cpp
... ... @@ -859,7 +859,7 @@ TEST(Types, TypeName) {
859 859 EXPECT_EQ("FLOAT", vector_name);
860 860  
861 861 static_assert(CLI::detail::classify_object<std::pair<int, std::string>>::value ==
862   - CLI::detail::objCategory::tuple_value,
  862 + CLI::detail::object_category::tuple_value,
863 863 "pair<int,string> does not read like a tuple");
864 864  
865 865 std::string pair_name = CLI::detail::type_name<std::vector<std::pair<int, std::string>>>();
... ... @@ -869,16 +869,16 @@ TEST(Types, TypeName) {
869 869 EXPECT_EQ("UINT", vector_name);
870 870  
871 871 auto vclass = CLI::detail::classify_object<std::vector<std::vector<unsigned char>>>::value;
872   - EXPECT_EQ(vclass, CLI::detail::objCategory::vector_value);
  872 + EXPECT_EQ(vclass, CLI::detail::object_category::vector_value);
873 873  
874 874 auto tclass = CLI::detail::classify_object<std::tuple<double>>::value;
875   - EXPECT_EQ(tclass, CLI::detail::objCategory::number_constructible);
  875 + EXPECT_EQ(tclass, CLI::detail::object_category::number_constructible);
876 876  
877 877 std::string tuple_name = CLI::detail::type_name<std::tuple<double>>();
878 878 EXPECT_EQ("FLOAT", tuple_name);
879 879  
880 880 static_assert(CLI::detail::classify_object<std::tuple<int, std::string>>::value ==
881   - CLI::detail::objCategory::tuple_value,
  881 + CLI::detail::object_category::tuple_value,
882 882 "tuple<int,string> does not read like a tuple");
883 883 tuple_name = CLI::detail::type_name<std::tuple<int, std::string>>();
884 884 EXPECT_EQ("[INT,TEXT]", tuple_name);
... ... @@ -906,8 +906,8 @@ TEST(Types, TypeName) {
906 906 EXPECT_EQ("ENUM", enum_name);
907 907  
908 908 vclass = CLI::detail::classify_object<std::tuple<test>>::value;
909   - EXPECT_EQ(vclass, CLI::detail::objCategory::tuple_value);
910   - static_assert(CLI::detail::classify_object<std::tuple<test>>::value == CLI::detail::objCategory::tuple_value,
  909 + EXPECT_EQ(vclass, CLI::detail::object_category::tuple_value);
  910 + static_assert(CLI::detail::classify_object<std::tuple<test>>::value == CLI::detail::object_category::tuple_value,
911 911 "tuple<test> does not classify as a tuple");
912 912 std::string enum_name2 = CLI::detail::type_name<std::tuple<test>>();
913 913 EXPECT_EQ("ENUM", enum_name2);
... ...
tests/NewParseTest.cpp
... ... @@ -198,6 +198,7 @@ TEST_F(TApp, BuiltinComplexSingleImag) {
198 198 EXPECT_DOUBLE_EQ(0, comp.imag());
199 199 }
200 200  
  201 +/// Simple class containing two strings useful for testing lexical cast and conversions
201 202 class spair {
202 203 public:
203 204 spair() = default;
... ...