Why are the min and max values for a particular numeric type implemented as functions?

Discussion in 'C++' started by Vijai Kalyan, Mar 21, 2006.

  1. Vijai Kalyan

    Vijai Kalyan Guest

    Oops, maybe that is the standard. I don't have a copy unfortunately,
    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(int p_min, int p_max, int p_value)
    {
    std::stringstream strbuf;
    strbuf << "The value " << p_value << " is not in the
    range [" << p_min << ", " << p_max << "].";
    m_msg = strbuf.str();
    }

    out_of_range(out_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 IntegerValidator
    {
    bool IsInRange(int value)
    {
    return true;
    }
    };

    template
    <
    int t_Min,
    int t_Max
    > struct IntegerValidator<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 IntegerValidator<t_Min, t_Max, true, true> : public IntegerValidator<t_Min, t_Max, true, false>

    {
    bool IsInRange(int value)
    {
    if(!::IntegerValidator<t_Min, t_Max, true,
    false>::IsInRange(value))
    {
    throw exceptions::eek:ut_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 IntegerAttribute : public IntegerValidator<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:
    IntegerAttribute() : m_value(0), m_valid(true)
    {
    }

    explicit IntegerAttribute(int p_value) : m_value(0),
    m_valid(false)
    {
    SetValue(p_value);
    }

    IntegerAttribute const& operator = (int p_value)
    {
    SetValue(p_value);
    return *this;
    }

    IntegerAttribute const& operator = (IntegerAttribute const&
    p_src)
    {
    SetValue(p_src.m_value);
    }

    operator int () const
    {
    return m_value;
    }
    };

    #endif // end IntegerAttribute.h

    just for fun. Here are now a few particular instantiations that I
    tried:

    typedef IntegerAttribute<0> PositiveInteger;
    typedef IntegerAttribute<INT_MIN, 0> NegativeInteger;

    typedef IntegerAttribute<0, INT_MAX, true, true> PositiveIntegerEx;
    typedef IntegerAttribute<INT_MIN, 0, true, true> NegativeIntegerEx;

    IMHO, I had to mix C style type ranges with C++. Shouldn't I ideally,
    IMHO, have used

    typedef IntegerAttribute<0> PositiveInteger;
    typedef IntegerAttribute<std::numeric_limits<int>::min, 0>
    NegativeInteger;

    typedef IntegerAttribute<0, std::numeric_limits<int>::max, true, true>
    PositiveIntegerEx;
    typedef IntegerAttribute<std::numeric_limits<int>::min, 0, true, true>
    NegativeIntegerEx;

    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.
     
    Vijai Kalyan, Mar 21, 2006
    #1
    1. Advertising

  2. In article <>,
    "Vijai Kalyan" <> wrote:

    > typedef IntegerAttribute<0, std::numeric_limits<int>::max, true, true>
    > PositiveIntegerEx;
    > typedef IntegerAttribute<std::numeric_limits<int>::min, 0, true, true>
    > NegativeIntegerEx;
    >
    > 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?


    This is the unfortunate result of the fact that floating point constants
    can't be defined in a class the way integral constants can, and
    numeric_limits handles floating point types as well.

    Yes, your compiler reflects the standard.

    -Howard
     
    Howard Hinnant, Mar 21, 2006
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lois
    Replies:
    1
    Views:
    3,369
    Ryan Stewart
    Dec 27, 2004
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,129
    Smokey Grindel
    Dec 2, 2006
  3. Gary Wessle

    min and max running values

    Gary Wessle, Mar 5, 2007, in forum: C++
    Replies:
    41
    Views:
    1,084
    Pete Becker
    Mar 7, 2007
  4. Mithil

    Max and min values in DTD

    Mithil, Aug 27, 2007, in forum: XML
    Replies:
    5
    Views:
    1,017
    Joseph Kesselman
    Aug 28, 2007
  5. John [H2O]
    Replies:
    0
    Views:
    722
    John [H2O]
    Jul 7, 2011
Loading...

Share This Page