@@ -297,6 +297,41 @@ class Switch : public Value<bool>
297297
298298
299299
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+
300335using Option_ptr = std::shared_ptr<Option>;
301336
302337// / OptionParser manages all Options
@@ -394,6 +429,7 @@ class invalid_option : public std::invalid_argument
394429 missing_argument,
395430 invalid_argument,
396431 too_many_arguments,
432+ argument_out_of_bound,
397433 missing_option
398434 };
399435
@@ -830,7 +866,31 @@ inline Argument Switch::argument_type() const
830866 return Argument::no;
831867}
832868
869+ // / BoundedValue implementation /////////////////////////////////
833870
871+ template <class T >
872+ BoundedValue<T>::BoundedValue(const std::string& short_name, const std::string& long_name, const std::string& description, Predicate predicate)
873+ : Value<T>(short_name, long_name, description), predicate_(predicate)
874+ {
875+
876+ }
877+
878+ template <class T >
879+ 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)
880+ : Value<T>(short_name, long_name, description, default_val, assign_to), predicate_(predicate)
881+ {
882+
883+ }
884+
885+ template <class T >
886+ inline void BoundedValue<T>::parse(OptionName what_name, const char * value)
887+ {
888+ Value<T>::parse (what_name, value);
889+ for ( const auto & v : this ->values_ )
890+ if ( !predicate_ ( v))
891+ throw invalid_option (this , invalid_option::Error::argument_out_of_bound, what_name, value,
892+ " argument is out of bound for " + this ->name (what_name, true ) + " : '" + value + " '" );
893+ }
834894
835895// / OptionParser implementation /////////////////////////////////
836896
0 commit comments