Commit 51a395ec9fd6341fdca3d7728e34b48c58730c94

Authored by christos
Committed by Henry Schreiner
1 parent a8d597da

Handle float type in positive number (CLIUtils#328) (#342)

* fix https://github.com/CLIUtils/CLI11/issues/328

 * use same assumptions about the size (ie double is enough) as in Number validator

* fix spelling in error message

* fix class description comment

* PositiveNumber accepts now >0 while NonNegative >=0

* update README for PositiveNumber and NonNegativeNumber

* spelling
README.md
... ... @@ -381,7 +381,8 @@ CLI11 has several Validators built-in that perform some common checks
381 381 - `CLI::NonexistentPath`: Requires that the path does not exist.
382 382 - `CLI::Range(min,max)`: Requires that the option be between min and max (make sure to use floating point if needed). Min defaults to 0.
383 383 - `CLI::Bounded(min,max)`: ๐Ÿ†• Modify the input such that it is always between min and max (make sure to use floating point if needed). Min defaults to 0. Will produce an error if conversion is not possible.
384   -- `CLI::PositiveNumber`: ๐Ÿ†• Requires the number be greater or equal to 0
  384 +- `CLI::PositiveNumber`: ๐Ÿ†• Requires the number be greater than 0
  385 +- `CLI::NonNegativeNumber`: ๐Ÿ†• Requires the number be greater or equal to 0
385 386 - `CLI::Number`: ๐Ÿ†• Requires the input be a number.
386 387 - `CLI::ValidIPV4`: ๐Ÿ†• Requires that the option be a valid IPv4 string e.g. `'255.255.255.255'`, `'10.1.1.7'`.
387 388  
... ... @@ -404,7 +405,7 @@ will produce a check to ensure a value is between 0 and 10 or 20 and 30.
404 405 ->check(!CLI::PositiveNumber);
405 406 ```
406 407  
407   -will produce a check for a number less than 0.
  408 +will produce a check for a number less than or equal to 0.
408 409  
409 410 ##### Transforming Validators
410 411 There are a few built in Validators that let you transform values if used with the `transform` function. If they also do some checks then they can be used `check` but some may do nothing in that case.
... ...
include/CLI/Validators.hpp
... ... @@ -391,24 +391,40 @@ class IPV4Validator : public Validator {
391 391 }
392 392 };
393 393  
394   -/// Validate the argument is a number and greater than or equal to 0
  394 +/// Validate the argument is a number and greater than 0
395 395 class PositiveNumber : public Validator {
396 396 public:
397 397 PositiveNumber() : Validator("POSITIVE") {
398 398 func_ = [](std::string &number_str) {
399   - int number;
  399 + double number;
  400 + if(!detail::lexical_cast(number_str, number)) {
  401 + return "Failed parsing number: (" + number_str + ')';
  402 + }
  403 + if(number <= 0) {
  404 + return "Number less or equal to 0: (" + number_str + ')';
  405 + }
  406 + return std::string();
  407 + };
  408 + }
  409 +};
  410 +/// Validate the argument is a number and greater than or equal to 0
  411 +class NonNegativeNumber : public Validator {
  412 + public:
  413 + NonNegativeNumber() : Validator("NONNEGATIVE") {
  414 + func_ = [](std::string &number_str) {
  415 + double number;
400 416 if(!detail::lexical_cast(number_str, number)) {
401 417 return "Failed parsing number: (" + number_str + ')';
402 418 }
403 419 if(number < 0) {
404   - return "Number less then 0: (" + number_str + ')';
  420 + return "Number less than 0: (" + number_str + ')';
405 421 }
406 422 return std::string();
407 423 };
408 424 }
409 425 };
410 426  
411   -/// Validate the argument is a number and greater than or equal to 0
  427 +/// Validate the argument is a number
412 428 class Number : public Validator {
413 429 public:
414 430 Number() : Validator("NUMBER") {
... ... @@ -444,6 +460,9 @@ const detail::IPV4Validator ValidIPV4;
444 460 /// Check for a positive number
445 461 const detail::PositiveNumber PositiveNumber;
446 462  
  463 +/// Check for a non-negative number
  464 +const detail::NonNegativeNumber NonNegativeNumber;
  465 +
447 466 /// Check for a number
448 467 const detail::Number Number;
449 468  
... ...
tests/HelpersTest.cpp
... ... @@ -311,13 +311,36 @@ TEST(Validators, PositiveValidator) {
311 311 num = "10000";
312 312 EXPECT_TRUE(CLI::PositiveNumber(num).empty());
313 313 num = "0";
  314 + EXPECT_FALSE(CLI::PositiveNumber(num).empty());
  315 + num = "+0.5";
314 316 EXPECT_TRUE(CLI::PositiveNumber(num).empty());
315 317 num = "-1";
316 318 EXPECT_FALSE(CLI::PositiveNumber(num).empty());
  319 + num = "-1.5";
  320 + EXPECT_FALSE(CLI::PositiveNumber(num).empty());
317 321 num = "a";
318 322 EXPECT_FALSE(CLI::PositiveNumber(num).empty());
319 323 }
320 324  
  325 +TEST(Validators, NonNegativeValidator) {
  326 + std::string num = "1.1.1.1";
  327 + EXPECT_FALSE(CLI::NonNegativeNumber(num).empty());
  328 + num = "1";
  329 + EXPECT_TRUE(CLI::NonNegativeNumber(num).empty());
  330 + num = "10000";
  331 + EXPECT_TRUE(CLI::NonNegativeNumber(num).empty());
  332 + num = "0";
  333 + EXPECT_TRUE(CLI::NonNegativeNumber(num).empty());
  334 + num = "+0.5";
  335 + EXPECT_TRUE(CLI::NonNegativeNumber(num).empty());
  336 + num = "-1";
  337 + EXPECT_FALSE(CLI::NonNegativeNumber(num).empty());
  338 + num = "-1.5";
  339 + EXPECT_FALSE(CLI::NonNegativeNumber(num).empty());
  340 + num = "a";
  341 + EXPECT_FALSE(CLI::NonNegativeNumber(num).empty());
  342 +}
  343 +
321 344 TEST(Validators, NumberValidator) {
322 345 std::string num = "1.1.1.1";
323 346 EXPECT_FALSE(CLI::Number(num).empty());
... ...