@@ -297,6 +297,41 @@ class Switch : public Value<bool>
297
297
298
298
299
299
300
+ // / Bounded value option
301
+ /* *
302
+ * Bounded value option
303
+ * Checks if the value meets boundary predicate,
304
+ * for example ( x > 3 && x < 99 )
305
+ */
306
+ template <class T >
307
+ class BoundedValue : public Value <T>
308
+ {
309
+ public:
310
+ using Predicate = bool (*)(T);
311
+
312
+ // / Construct a BoundedValue Option
313
+ // / @param short_name the option's short name. Must be empty or one character.
314
+ // / @param long_name the option's long name. Can be empty.
315
+ // / @param description the Option's description that will be shown in the help message
316
+ // / @param predicate the option's correctness predicate, returns true if option is correct
317
+ BoundedValue (const std::string& short_name, const std::string& long_name, const std::string& description, Predicate predicate);
318
+
319
+ // / Construct a BoundedValue Option
320
+ // / @param short_name the option's short name. Must be empty or one character.
321
+ // / @param long_name the option's long name. Can be empty.
322
+ // / @param description the Option's description that will be shown in the help message
323
+ // / @param predicate the option's correctness predicate, returns true if option is correct
324
+ // / @param default_val the Option's default value
325
+ // / @param assign_to pointer to a variable to assign the parsed command line value to
326
+ BoundedValue (const std::string& short_name, const std::string& long_name, const std::string& description, Predicate predicate, const T& default_val, T* assign_to = nullptr );
327
+
328
+ protected:
329
+ void parse (OptionName what_name, const char * value) override ;
330
+
331
+ private:
332
+ Predicate predicate_;
333
+ };
334
+
300
335
using Option_ptr = std::shared_ptr<Option>;
301
336
302
337
// / OptionParser manages all Options
@@ -394,7 +429,8 @@ class invalid_option : public std::invalid_argument
394
429
missing_argument,
395
430
invalid_argument,
396
431
too_many_arguments,
397
- missing_option
432
+ missing_option,
433
+ argument_out_of_bound,
398
434
};
399
435
400
436
invalid_option (const Option* option, invalid_option::Error error, OptionName what_name, std::string value, const std::string& text)
@@ -755,7 +791,6 @@ inline void Value<T>::parse(OptionName what_name, const char* value)
755
791
this ->add_value (parsed_value);
756
792
}
757
793
758
-
759
794
template <class T >
760
795
inline void Value<T>::update_reference()
761
796
{
@@ -830,7 +865,31 @@ inline Argument Switch::argument_type() const
830
865
return Argument::no;
831
866
}
832
867
868
+ // / BoundedValue implementation /////////////////////////////////
833
869
870
+ template <class T >
871
+ BoundedValue<T>::BoundedValue(const std::string& short_name, const std::string& long_name, const std::string& description, Predicate predicate)
872
+ : Value<T>(short_name, long_name, description), predicate_(predicate)
873
+ {
874
+
875
+ }
876
+
877
+ template <class T >
878
+ BoundedValue<T>::BoundedValue(const std::string& short_name, const std::string& long_name, const std::string& description, Predicate predicate, const T& default_val, T* assign_to)
879
+ : Value<T>(short_name, long_name, description, default_val, assign_to), predicate_(predicate)
880
+ {
881
+
882
+ }
883
+
884
+ template <class T >
885
+ inline void BoundedValue<T>::parse(OptionName what_name, const char * value)
886
+ {
887
+ Value<T>::parse (what_name, value);
888
+ for ( const auto & v : this ->values_ )
889
+ if ( !predicate_ ( v))
890
+ throw invalid_option (this , invalid_option::Error::argument_out_of_bound, what_name, value,
891
+ " argument is out of bound for " + this ->name (what_name, true ) + " : '" + value + " '" );
892
+ }
834
893
835
894
// / OptionParser implementation /////////////////////////////////
836
895
0 commit comments