JimmidyJoo
JimmidyJoo

Reputation: 11331

Enforcing rules on "non-type" template parameters

I want to be able to enforce certain rules on the "non-type" template parameters of classes. Is this possible?

For example, consider a templated "Cycle" class that cycles through values of type "TYPE", between the values "MIN" and "MAX".

A basic first step might look something like this:

template <class TYPE, TYPE MIN, TYPE MAX>
class Cycle
{
public:
  Cycle() :
    m_value(MIN)
  {
  }

  const TYPE & value() const
  {
    return m_value;
  }

  void up()
  {
    if (m_value == m_max)
        m_value = m_min;
    else
      ++m_value;
  }

  void down()
  {
    if (m_value == m_min)
        m_value = m_max;
    else
      --m_value;
  }

private:
  TYPE m_value;

  static TYPE m_min;
  static TYPE m_max;
};

template <class TYPE, TYPE MIN, TYPE MAX>
TYPE Cycle<TYPE, MIN, MAX>::m_min = MIN;

template <class TYPE, TYPE MIN, TYPE MAX>
TYPE Cycle<TYPE, MIN, MAX>::m_max = MAX;

How would I change the above so that the rule MIN <= MAX always holds? I.e. How do I make sure a programmer using the line

Cycle<int, 0, 23> hoursInADay;

would be allowed, but a programmer using the line

Cycle<int, 23, 0> hoursInADay;

would be warned at compile-time that the declaration in unacceptable?

Upvotes: 2

Views: 168

Answers (1)

Kerrek SB
Kerrek SB

Reputation: 477358

You can add a static assertion:

static_assert(MIN <= MAX, "Invalid bounds");

Pre-C++11 you'll have to cook up your own construct that produces a compile-time error when invoked on a false bool; e.g. take Boost's version of static-assert.

Otherwise something like this:

template <bool B> struct i_must_be_true;     // no definition!
template <> struct i_must_be_true<true> { };

template <typename T, T MIN, T MAX> class Cycle
{
    i_must_be_true<MIN <= MAX> m_check;
    // ...
};

Upvotes: 6

Related Questions