Alan wrote:
"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:O9********************@speakeasy.net...
The spirit of this arguably pointless exercise, is that the
numeric_limits<T> class could be replaced with a totally generic
template of compile-time, template computed constants.
The problem is that it takes a *long* time to compile and the "long
[snip]
I don't know anything about templates (yet) but this DMC
(Digital Mars) compiler complains that static members should
initialised outside of the structures. I may not be the smartest
of C++ programers but I seem to remember that this is also
the way with 'ordinary' classes ;-)
OK - here is a version that might work for you:
#include <iostream>
#include <limits>
template <typename T, int N>
struct pow_m
{
static const T value;
static const T valuep1;
};
template <typename T, int N>
const T pow_m<T,N>::value =
( ( pow_m<T, N-1>::value * 2 ) + static_cast<T>( 1 ) ) -
static_cast<T>( 1 )
== ( pow_m<T, N-1>::value * 2 )
? ( pow_m<T, N-1>::value * 2 ) + static_cast<T>( 1 )
: ( pow_m<T, N-1>::value * 2 );
template <typename T, int N>
const T pow_m<T,N>::valuep1 = ( value * 2 );
template <typename T>
struct pow_m<T, 0>
{
static const T value;
static const T valuep1;
};
template <typename T>
const T pow_m<T, 0>::value = static_cast<T>( 1 );
template <typename T>
const T pow_m<T, 0>::valuep1 = ( value * 2 ) + static_cast<T>( 1 );
template <typename T, int N, bool v> struct max_f;
template <typename T, int N>
struct max_f<T,N,true>
{
static const T max_value;
static const int max_exponent;
};
template <typename T, int N>
const T max_f<T,N,true>::max_value = pow_m<T,N-1>::value;
template <typename T, int N>
const int max_f<T,N,true>::max_exponent = N-1;
template <typename T, int N>
struct eval_f
{
static const bool at_limit = ( pow_m<T, N+1>::value == pow_m<T,
N+1>::valuep1 );
};
template <typename T, int N, bool v>
struct max_f : max_f<T, N+1, eval_f<T,N>::at_limit >
{
};
template <typename T, int N>
struct pow_nm
{
static const T value;
static const T valuep1;
};
template <typename T, int N>
const T pow_nm<T,N>::value =
( ( pow_nm<T, N-1>::value * 2 ) + static_cast<T>( -1 ) ) -
static_cast<T>( -1 )
== ( pow_nm<T, N-1>::value * 2 )
? ( pow_nm<T, N-1>::value * 2 ) + static_cast<T>( -1 )
: ( pow_nm<T, N-1>::value * 2 );
template <typename T, int N>
const T pow_nm<T,N>::valuep1 = ( value * 2 );
template <typename T>
struct pow_nm<T, 0>
{
static const T value;
static const T valuep1;
};
template <typename T>
const T pow_nm<T, 0>::value = static_cast<T>( -1 );
template <typename T>
const T pow_nm<T, 0>::valuep1 = ( value * 2 ) + static_cast<T>( -1 );
template <typename T, int N, bool v> struct max_nm;
template <typename T, int N>
struct max_nm<T,N,true>
{
static const T max_value;
static const int max_exponent;
};
template <typename T, int N>
const T max_nm<T,N,true>::max_value = pow_nm<T,N-1>::value;
template <typename T, int N>
const int max_nm<T,N,true>::max_exponent = N-1;
template <typename T, int N>
struct eval_nm
{
static const bool at_limit = ( pow_nm<T, N+1>::value == pow_nm<T,
N+1>::valuep1 );
};
template <typename T, int N, bool v>
struct max_nm : max_nm<T, N+1, eval_nm<T,N>::at_limit >
{
};
template<typename T>
struct max_limit
{
static const int max_exponent;
static const T max_value;
static const int neg_max_exponent;
static const T neg_max_value;
};
template<typename T>
const int max_limit<T>::max_exponent = max_f<T,0,false>::max_exponent;
template<typename T>
const T max_limit<T>::max_value = max_f<T,0,false>::max_value;
template<typename T>
const int max_limit<T>::neg_max_exponent =
max_nm<T,0,false>::max_exponent;
template<typename T>
const T max_limit<T>::neg_max_value = max_nm<T,0,false>::max_value;
int main()
{
std::cout << "Positive maximum\n";
std::cout << "Float\n";
std::cout << max_limit< float >::max_exponent << "\n";
std::cout << max_limit< float >::max_value << "\n";
std::cout << "Double\n";
std::cout << max_limit< double >::max_exponent << "\n";
std::cout << max_limit< double >::max_value << "\n";
std::cout << "limits max says " <<
std::numeric_limits<double>::max() << "\n";
std::cout << "limits/template diff " << (
std::numeric_limits<double>::max() - max_limit< double >::max_value ) <<
"\n";
std::cout << "Negative maximum\n";
std::cout << "Float\n";
std::cout << max_limit< float >::neg_max_exponent << "\n";
std::cout << max_limit< float >::neg_max_value << "\n";
std::cout << "Double\n";
std::cout << max_limit< double >::neg_max_exponent << "\n";
std::cout << max_limit< double >::neg_max_value << "\n";
/*
std::cout << "Long Double\n";
std::cout << max_limit< long double >::max_exponent << "\n";
std::cout << max_limit< long double >::max_value << "\n";
*/
}