Commit 5f696596d70cc59cf28d9f825d783a9cd29cf292
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
Showing
7 changed files
with
128 additions
and
98 deletions
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 <typename T> |
| 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< |
| 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< |
| 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<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<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<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<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 <typename T> struct classify_object<T, typename std::enable_if<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 <typename T, std::size_t I> |
| 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 &input, T &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 &input, T &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 &input, T &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 &input, T &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 &input, T &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 &input, T &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 &input, T &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 &input, T &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 &input, T &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 &input, T &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<std ::string> &strings, T &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 <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 <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<std ::string> &strings, T &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<std ::string> &strings, T &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 <class T, class XC, std::size_t I> |
| 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 &operator>>(std::istream &in, Unstreamable &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