/* streflop: STandalone REproducible FLOating-Point Copyright 2006 Nicolas Brodu 2012 Mark Vejvoda Code released according to the GNU Lesser General Public License Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. Uses SoftFloat too. Please read the history and copyright information in the documentation provided with the source code */ #ifndef STREFLOP_INTEGER_TYPES_H #define STREFLOP_INTEGER_TYPES_H // Given that: // - C++ template metaprogramming is Turing complete // - types are variables and integers are constants // - sizeof(type) is known by the C++ compiler and a constant // - sizeof(char) is 1 by definition, even if char != 8 bits // Then: It is possible to derive the sized ints at compile time in C++, unlike C // Note: This is NOT the same as the int32_t, etc from C99, in case char != 8 bits // For this reason, redefine the macro below if this is not the case for you // Note2: Even if char != 8 bits, it's still possible to define ints in terms of number of char! #define STREFLOP_INTEGER_TYPES_CHAR_BITS 8 // Avoid conflict with system types, if any namespace streflop { // Template meta-programming: this is the "program" which variables are types and constants are int template arguments // Algorithm: provide an expected size, and recursively increase the integer types till the size match template struct SizedTypeMaker { }; // start by long long to provide the recursion terminal condition // false : the expected_size does not exist: do not define a type, there will be a compilation error template struct SizedTypeMaker { // Error: Integer type with expected size does not exist }; // true: end recursion by defining the correct type to be long long template struct SizedTypeMaker { typedef long long final_type; }; // false : recurse by increasing the integer type till it reaches the expected size template struct SizedTypeMaker { typedef typename SizedTypeMaker::final_type final_type; }; // true: end recursion by defining the correct type to be long template struct SizedTypeMaker { typedef long final_type; }; // false : recurse by increasing the integer type till it reaches the expected size template struct SizedTypeMaker { typedef typename SizedTypeMaker::final_type final_type; }; // true: end recursion by defining the correct type to be int template struct SizedTypeMaker { typedef int final_type; }; // false : recurse by increasing the integer type till it reaches the expected size template struct SizedTypeMaker { typedef typename SizedTypeMaker::final_type final_type; }; // true: end recursion by defining the correct type to be short template struct SizedTypeMaker { typedef short final_type; }; // Do it again for unsigned types // false : the expected_size does not exist: do not define a type, there will be a compilation error template struct SizedTypeMaker { // Error: Integer type with expected size does not exist }; // true: end recursion by defining the correct type to be long long template struct SizedTypeMaker { typedef unsigned long long final_type; }; // false : recurse by increasing the integer type till it reaches the expected size template struct SizedTypeMaker { typedef typename SizedTypeMaker::final_type final_type; }; // true: end recursion by defining the correct type to be long template struct SizedTypeMaker { typedef unsigned long final_type; }; // false : recurse by increasing the integer type till it reaches the expected size template struct SizedTypeMaker { typedef typename SizedTypeMaker::final_type final_type; }; // true: end recursion by defining the correct type to be int template struct SizedTypeMaker { typedef unsigned int final_type; }; // false : recurse by increasing the integer type till it reaches the expected size template struct SizedTypeMaker { typedef typename SizedTypeMaker::final_type final_type; }; // true: end recursion by defining the correct type to be short template struct SizedTypeMaker { typedef unsigned short final_type; }; // Utility to get an int type with the selected size IN BITS template struct SizedInteger { typedef typename SizedTypeMaker::final_type Type; }; template struct SizedUnsignedInteger { typedef typename SizedTypeMaker::final_type Type; }; // Specialize for size = STREFLOP_INTEGER_TYPES_CHAR_BITS template<> struct SizedInteger { typedef char Type; }; template<> struct SizedUnsignedInteger { typedef unsigned char Type; }; } #endif