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