Compile-time range check?

D

Daniel Pitts

I have a template:

template<typename c, unsigned size>
struct Vector {
c components[size];
template<unsigned index>
c &get() { return components[index]; }
};

Vector<double, 3> vect;
Is there a way to cause vect.get<3>() to fail at compile time. but
vect.get<2>() have compile successfully?
 
D

Daniel Pitts

Victor said:
Daniel said:
I have a template:

template<typename c, unsigned size>
struct Vector {
c components[size];
template<unsigned index>
c &get() { return components[index]; }
};

Vector<double, 3> vect;
Is there a way to cause vect.get<3>() to fail at compile time. but
vect.get<2>() have compile successfully?

Sure. Read up on compile-time asserts.

Here is what I could come up with (in five minutes or so it took to type
it up):

template<unsigned low, unsigned test, unsigned high>
struct is_seq {
static char _[low <= test && test <= high];
static const bool yes = sizeof(_);
};
...
template<unsigned index> c &get() {
return is_seq<0,index,size-1>::yes, components[index];
}

V
Thanks.
I can be more specific than that, because all I really care about is
0..max. I managed to come up with:

template<bool>
struct InvalidIndex{};

template<>
struct InvalidIndex<false>{ enum { isValid }; };

template<unsigned index, unsigned max>
struct ValidIndex {
enum { isValid = InvalidIndex<index >= max>::isValid };
};

Thanks for the reply.
 
F

Fei Liu

Daniel said:
I have a template:

template<typename c, unsigned size>
struct Vector {
c components[size];
template<unsigned index>
c &get() { return components[index]; }
};

Vector<double, 3> vect;
Is there a way to cause vect.get<3>() to fail at compile time. but
vect.get<2>() have compile successfully?
please check BOOST_STATIC_ASSERT.
 
N

Noah Roberts

Daniel said:
I have a template:

template<typename c, unsigned size>
struct Vector {
c components[size];
template<unsigned index>
c &get() { return components[index]; }
};

Vector<double, 3> vect;
Is there a way to cause vect.get<3>() to fail at compile time. but
vect.get<2>() have compile successfully?
Another alternative is to use boost::enable_if and mpl helpers.

#include <iostream>

#include <boost/mpl/and.hpp>
#include <boost/mpl/int.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/greater.hpp>
#include <boost/mpl/less.hpp>

namespace mpl = boost::mpl;

template < typename C, unsigned SIZE >
struct Vector
{
C components[SIZE];

template < unsigned I >
typename boost::enable_if
<
mpl::and_
<
mpl::int_<-1> > said:
> , C &
>::type get()
{
return components;
}
};

int main()
{
Vector<double, 3> v = { 42.3, 66.6, 0.1 };

std::cout << v.get<1>() << std::endl;
//std::cout << v.get<3>() << std::endl;

std::cin.get();
}

Of course, you'll probably wish to clean that up a bit by writing your
own range checking metafunction.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,187
Latest member
RosaDemko

Latest Threads

Top