Kai-Uwe Bux posted:
I haven't gone over that in detail, so I'll take your word for it that it
works

. This can be achieved with just the *one* specialisation though.
(Let's assume that COMPASS is a compile-time assertion, and that the bit
quantity supplied to the template includes the sign-bit.)
Firstly, here's the max value:
#include <limits>
template<class T, unsigned bits>
struct IntMax {
/* COMPASS(std::numeric_limits<T>::digits >= bits); */
T const static MSBOnly = T(1) << bits - 1;
T const static val = MSBOnly | MSBOnly - 1;
};
The determination of the lowest value is slightly more complicated. First
thing though, we know that it will be 0 for unsigned types, so we can start
off with:
#include <limits>
template<class T, unsigned bits>
struct IntMin {
COMPASS(std::numeric_limits<T>::digits + 1 >= bits);
/* Note the "+ 1" */
T const static val_if_unsigned = 0;
};
Next, we must determine how to get the lowest value for a signed type --
but this will be dependant on the negative number system which is used. So,
first, let's determine the negative number system:
#define SIGNMAG 0
#define ONES 1
#define TWOS 2
#if -1 & 3 == 1
#define NUM_SYS SINGMAG
#elif -1 & 3 == 2
#define NUM_SYS ONES
#else
#define NUM_SYS TWOS
#endif
Next, let's see what the bit-pattern looks like for the min-value for each
number system. (Assuming 8-Bit numbers
SignMag: 1111 1111
Ones: 1000 0000
Twos: 1000 0001
Now we can put it together:
#include <limits>
#define SIGNMAG 0
#define ONES 1
#define TWOS 2
#if -1 & 3 == 1
#define NUM_SYS SIGNMAG
#elif -1 & 3 == 2
#define NUM_SYS ONES
#else
#define NUM_SYS TWOS #endif
template<class T, unsigned bits> struct IntMin {
typedef std::numeric_limits<T> Lim;
/* COMPASS(Lim::digits + 1 >= bits); */
/* Note the "+ 1" */
T const static val_if_unsigned = 0;
T const static signbit_only = T(1) << bits - 1;
/* Will this bit-shift work correctly? */
T const static val_if_ones = signbit_only;
T const static val_if_twos = signbit_only & 1;
T const static MSBonly = T(1) << bits - 2;
T const static val_if_signmag = signbit_only|MSBonly|MSBonly - 1;
T const static val_if_signed =
NUM_SYS == TWOS ? val_if_twos :
NUM_SYS == ONES ? val_if_ones : val_if_signmag;
T const static val = Lim::is_signed ? val_if_signed : val_if_unsigned;
};
--
Frederick Gotham