but here goes. I was experimenting and wrote the following code:
#include <limits.h>
#include <stdexcept>
#include <sstream>
namespace exceptions
{
class out_of_range : public std::exception
{
std::string m_msg;
protected:
out_of_range const& operator = (out_of_range const&);
public:
out_of_range(in t p_min, int p_max, int p_value)
{
std::stringstre am strbuf;
strbuf << "The value " << p_value << " is not in the
range [" << p_min << ", " << p_max << "].";
m_msg = strbuf.str();
}
out_of_range(ou t_of_range const& src)
{
m_msg = src.m_msg;
}
char const* what() const
{
return m_msg.c_str();
}
};
};
template
<
int t_Min,
int t_Max,
bool t_Validate,
bool t_useExceptions
struct IntegerValidato r
{
bool IsInRange(int value)
{
return true;
}
};
template
<
int t_Min,
int t_Max struct IntegerValidato r<t_Min, t_Max, true, false> {
bool IsInRange(int value)
{
return ((value <= t_Max) && (value >= t_Min));
}
};
template
<
int t_Min,
int t_Max struct IntegerValidato r<t_Min, t_Max, true, true> : public IntegerValidato r<t_Min, t_Max, true, false> {
bool IsInRange(int value)
{
if(!::IntegerVa lidator<t_Min, t_Max, true,
false>::IsInRan ge(value))
{
throw exceptions::out _of_range(t_Min , t_Max, value);
}
return true;
}
};
template
<
int t_Min = INT_MIN,
int t_Max = INT_MAX,
bool t_Validate = true,
bool t_useExceptions = false
class IntegerAttribut e : public IntegerValidato r<t_Min, t_Max,
t_Validate, t_useExceptions >
{
int m_value;
bool m_valid;
protected:
void SetValue(int p_value)
{
if(IsInRange(p_ value))
{
m_value = p_value;
m_valid = true;
}
}
public:
IntegerAttribut e() : m_value(0), m_valid(true)
{
}
explicit IntegerAttribut e(int p_value) : m_value(0),
m_valid(false)
{
SetValue(p_valu e);
}
IntegerAttribut e const& operator = (int p_value)
{
SetValue(p_valu e);
return *this;
}
IntegerAttribut e const& operator = (IntegerAttribu te const&
p_src)
{
SetValue(p_src. m_value);
}
operator int () const
{
return m_value;
}
};
#endif // end IntegerAttribut e.h
just for fun. Here are now a few particular instantiations that I
tried:
typedef IntegerAttribut e<0> PositiveInteger ;
typedef IntegerAttribut e<INT_MIN, 0> NegativeInteger ;
typedef IntegerAttribut e<0, INT_MAX, true, true> PositiveInteger Ex;
typedef IntegerAttribut e<INT_MIN, 0, true, true> NegativeInteger Ex;
IMHO, I had to mix C style type ranges with C++. Shouldn't I ideally,
IMHO, have used
typedef IntegerAttribut e<0> PositiveInteger ;
typedef IntegerAttribut e<std::numeric_ limits<int>::mi n, 0>
NegativeInteger ;
typedef IntegerAttribut e<0, std::numeric_li mits<int>::max, true, true>
PositiveInteger Ex;
typedef IntegerAttribut e<std::numeric_ limits<int>::mi n, 0, true, true>
NegativeInteger Ex;
instead. I cannot however do that because the above instantiations
require a compile time constant and min and max actually are functions.
Is this good? (Not from a style perspective, but from a usability
perspective.) Or am I missing something here?
Ultimately, anyway, in the particular compiler I am using the functions
min () and max() are anyway implemented as follows:
static _Ty (__CRTDECL min)() _THROW0()
{ // return minimum value
return (INT_MIN);
}
static _Ty (__CRTDECL max)() _THROW0()
{ // return maximum value
return (INT_MAX);
}
regards,
-vijai.