Actually it would make more sense to add a validator to arguments but for this example code i want to validate one or two arguments in the argument list after it was parsed.
My questions:
* how to find the argument in the argument list?
* how to read the value after i have the right argument?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm not 100% sure about what the validate function should do but I can give you some general comments that might help.
1) You can access the argument list through the member function getArgList of CmdLine object.
2) The CmdLine objecte does NOT copy the arguments but simply keeps a reference to them. This means that the CmdLine object is only valid as long as all the Args added to it is still in scope.
3) One way to do it would perhaps be to have a std::map in you validator class that keeps a map from the name of the argument to a pointer to that argument and adding all the Args to that map (so that you can find them by name).
4) You should also have a look at the Vistor interface, which might be an easier way to do things
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
<quote>
I'm not 100% sure about what the validate function should do but I can give you some general comments that might help.
</quote>
Example for an argument validation: my integer argument is only valid if it is > 0. It should throw an exception if this is not the case.
ad 1) yes, but when i have an argument, how do i access the value - unless using dynamic_cast - which is a "bad".
ad 2) good to know.
ad 3) yes, but this leads to the problem in 1). Accessing the value will be tricky. I have no idea how a template function could look like to access the value in the argument map.
Problem with 4) is that the visitor needs a reference to its argument to validate its value. And this reference can't be given to the validator because it does not exit at the time when the validator is created.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ah, a third solution would be the mapping. You would map from names to Arg*s but since each arg has a unique name you would "know" the type and could cast to the correct type without trying all of them. This is a hack of-course, but whatever gets you through your day...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK, now we are getting somewhere. First of all for your example you could simply use an unsigned type for the template argument and everything will happen for you automagically. Given that you want to do something more complicated you could:
1) Write a new type i.e. an object that overloads operator>> which gets called when the object is matched on the command line and to the validation there. For example I did this with files so that the object checked that the file existed an otherwise throwed an exception. (let me know if you want the code for that and I can send it to you). You would then create a ValueArg<T> where T is your new type.
2) You could use dynamic cast or typeinfo. However as you point out it's maybe not so nice and the problem stems from using two different programming paradigms, templates and inheretance. If it is just a special case I would say that this in an acceptable solution.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Check out the Constraint interface that is now in CVS. I think that might provide exactly the kind of validation you're looking for. Let me know if it doesn't.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Is there an easy way to access argument values from the CmdLine after it was parsed, when the is no access to the arguments anymore?
My code splits the the command line parsing into r steps:
1.) definition of the command line arguments
2.) pasring
3.) Validation
Somthing like that:
class ValidatorInterface {
ValidatorInterface(TCLAP::CmdLine& cmdlp) : { }
virtual void validate() throw (TCLAP::ArgException) = 0;
private:
TCLAP::CmdLine& cmdlp_;
};
Actually it would make more sense to add a validator to arguments but for this example code i want to validate one or two arguments in the argument list after it was parsed.
My questions:
* how to find the argument in the argument list?
* how to read the value after i have the right argument?
I'm not 100% sure about what the validate function should do but I can give you some general comments that might help.
1) You can access the argument list through the member function getArgList of CmdLine object.
2) The CmdLine objecte does NOT copy the arguments but simply keeps a reference to them. This means that the CmdLine object is only valid as long as all the Args added to it is still in scope.
3) One way to do it would perhaps be to have a std::map in you validator class that keeps a map from the name of the argument to a pointer to that argument and adding all the Args to that map (so that you can find them by name).
4) You should also have a look at the Vistor interface, which might be an easier way to do things
<quote>
I'm not 100% sure about what the validate function should do but I can give you some general comments that might help.
</quote>
Example for an argument validation: my integer argument is only valid if it is > 0. It should throw an exception if this is not the case.
ad 1) yes, but when i have an argument, how do i access the value - unless using dynamic_cast - which is a "bad".
ad 2) good to know.
ad 3) yes, but this leads to the problem in 1). Accessing the value will be tricky. I have no idea how a template function could look like to access the value in the argument map.
Problem with 4) is that the visitor needs a reference to its argument to validate its value. And this reference can't be given to the validator because it does not exit at the time when the validator is created.
Ah, a third solution would be the mapping. You would map from names to Arg*s but since each arg has a unique name you would "know" the type and could cast to the correct type without trying all of them. This is a hack of-course, but whatever gets you through your day...
OK, now we are getting somewhere. First of all for your example you could simply use an unsigned type for the template argument and everything will happen for you automagically. Given that you want to do something more complicated you could:
1) Write a new type i.e. an object that overloads operator>> which gets called when the object is matched on the command line and to the validation there. For example I did this with files so that the object checked that the file existed an otherwise throwed an exception. (let me know if you want the code for that and I can send it to you). You would then create a ValueArg<T> where T is your new type.
2) You could use dynamic cast or typeinfo. However as you point out it's maybe not so nice and the problem stems from using two different programming paradigms, templates and inheretance. If it is just a special case I would say that this in an acceptable solution.
Check out the Constraint interface that is now in CVS. I think that might provide exactly the kind of validation you're looking for. Let me know if it doesn't.