Is it possible to check this:
template<class IntType,IntType value>
struct X{};
What I mean by this is, is it possible to check that value supplied by user will "fit" into IntType
(which can be any of std integer types) type? For example, I would like to detect something like this:
X<char,300> a;//here 300 is out of range and I would like to be able to detect that.
Now that you've changed X
's signature from the way it was in the original unedited question, it's easily implemented using Boost.Integer:
#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/integer_traits.hpp>
template<
typename IntType,
boost::uint64_t Value,
bool IsSigned = boost::integer_traits<IntType>::is_signed
>
struct validate_range;
template<typename IntType, boost::uint64_t Value>
struct validate_range<IntType, Value, true>
{
typedef boost::integer_traits<IntType> traits_t;
static bool const value =
static_cast<boost::int64_t>(Value) >= traits_t::const_min &&
static_cast<boost::int64_t>(Value) <= traits_t::const_max;
};
template<typename IntType, boost::uint64_t Value>
struct validate_range<IntType, Value, false>
{
typedef boost::integer_traits<IntType> traits_t;
static bool const value =
Value >= traits_t::const_min &&
Value <= traits_t::const_max;
};
template<typename IntType, boost::uint64_t Value>
struct X
{
BOOST_STATIC_ASSERT_MSG(
(validate_range<IntType, Value>::value),
"Value constant is out of range"
);
};
int main()
{
X<char, -2> x1; // fails iif char is unsigned by default
X<char, 2> x2; // fine
X<char, 255> x3; // fails iif char is signed by default
X<unsigned char, -2> x4; // fails
X<unsigned char, 255> x5; // fine
X<unsigned char, 300> x6; // fails
}