4
\$\begingroup\$

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.

  1. Are there any serious pitfalls in my current implementation?
  2. 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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.