@@ -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,7 +429,8 @@ class invalid_option : public std::invalid_argument
394429 missing_argument,
395430 invalid_argument,
396431 too_many_arguments,
397- missing_option
432+ missing_option,
433+ argument_out_of_bound,
398434 };
399435
400436 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)
755791 this ->add_value (parsed_value);
756792}
757793
758-
759794template <class T >
760795inline void Value<T>::update_reference()
761796{
@@ -830,7 +865,31 @@ inline Argument Switch::argument_type() const
830865 return Argument::no;
831866}
832867
868+ // / BoundedValue implementation /////////////////////////////////
833869
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+ }
834893
835894// / OptionParser implementation /////////////////////////////////
836895
0 commit comments