I want to parse a command line using boost.program_options
. Most of my command line arguments will be intervals, which I could implement as something like --x-min=2000
and --x-max=2500
.
However, I thought about adding a class that can be written to/read from streams that allows me to handle an option of that reads --x=2000:2500
. The following code seems to work fine, but I'm not sure if this "range" approach is advisable at all:
#include <iostream>
template<typename T>
struct Interval
{
/** sep should not be specific to each template instantiation, should it? **/
static const char sep = ':';
T lowest;
T highest;
};
template<typename T>
std::ostream& operator<<(std::ostream& o, const Interval<T>& t)
{
o << t.lowest << Interval<T>::sep << t.highest;
return o;
}
template<typename T>
std::istream& operator>>(std::istream& i, Interval<T>& t)
{
// don't read from failed stream
if(i.fail())
{
return i;
}
// read value left of separator
T l;
i >> l;
// read separator
char c;
i >> c;
if (c != Interval<T>::sep)
{
i.setstate(std::ios::failbit);
return i;
}
// read value right of separator
T r;
i >> r;
// prefer less-than comparison over >=
if (r < l)
{
i.setstate(std::ios::failbit);
return i;
}
// set given Interval's members
t.lowest = l;
t.highest = r;
return i;
}
using namespace std;
int main()
{
Interval<double> i;
i.lowest = 0;
i.highest = 10;
cout << "range is " << i << endl << "enter new range: ";
cin >> i;
cout << "new range is " << i << endl;
return 0;
}
This code uses available stream operators for T
, which simplifies things, and it looks clean enough so that I think it can't be too wrong.
One potential problem I see is that I cannot constrain one end of x, which would work with individual --x-min
and --x-max
options. Such an implementation of Interval
would need to accept --x=:2500
and --x=2000:
. I'd have to add handling of optional values, which could get messy.
- Are there any serious pitfalls in my current implementation?
- Would you advise to use such a command line format at all?
A possible extension of this could be used to create regularly spaced lists of values, like Matlab's linspace
and logspace
functions do: --x=0:100:101
and --x=10:1000:20,log
.