Topic: Templates for host types' independancy.


Author: Vlad Harchev <vladhar@imimail.ssau.ru>
Date: 1998/08/17
Raw View
 Here is a code that will be useful for porting libraries. I have implemented
 and tested the similar code, and here i try to reproduce it. Here, in the
 laboratory, i have no compiler installed, so i wasn't able to test it.
 I believe that there are no bugs here - may be some typos. Especially
 check the macro names like SHORT_MAX - may be i misspeled them.

 It seems to me that the similar things must go in standart.
 I be very pleased, if my name will be noticed in the  headers that provide
 the implementation of this template:
     "Based on the idea of Vlad Harchev, vladhar@imimail.ssau.ru"
=====================================================cut-here==============

#include <limits.h> //for type sizes like INT_MAX

typedef long bigest_int_t; //the largest integer type, allowed as non-type
//template parameter. On some compilers, it's twice as larger as long -
// __int64 on BCC. This should be signed.


  /* this template will never be used - it's specializations will be used
    instead. Each of them will define the typedef member named 'type' -
    the type, that suits such conditions.
  */
template struct __type_by_range_aux<bool is_signed,bool bigger_char,
              bool bigger_short,bool bigger_int>
{  };

#define _EXPL_SPEC template<>

_EXPL_SPEC struct __type_by_range_aux<false,false,false,false>
{ typedef unsigned char type; };

_EXPL_SPEC struct __type_by_range_aux<true,false,false,false>
{ typedef signed char type; };


_EXPL_SPEC struct __type_by_range_aux<false,true,false,false>
{ typedef unsigned short type; };

_EXPL_SPEC struct __type_by_range_aux<true,true,false,false>
{ typedef signed short type; };


_EXPL_SPEC struct __type_by_range_aux<false,true,true,false>
{ typedef unsigned int type; };

_EXPL_SPEC struct __type_by_range_aux<true,true,true,false>
{ typedef signed int type; };


_EXPL_SPEC struct __type_by_range_aux<false,true,true,true>
{ typedef unsigned long type; };

_EXPL_SPEC struct __type_by_range_aux<true,true,true,true>
{ typedef signed long type; };


/* the members of this template are designed in a special way in order
to
  avoid BCC enum bug. First parameter is the biggest value to hold, and
  saecond - the smallest.
*/
template <bigest_int_t U_, bigest_int_t L_=0>
struct type_by_range
{
 //these enums are temporary.
  enum {
    L1=L_, U1=U_, //avoids BCC enum bug
    L = L1 < U1 ? L1 : U1, U = L1 < U1 ? U1 : L1, //get the real max and min
    is_signed = (L < 0),
    abs_L = L < 0 ? -L : L,
    abs_U = U < 0 ? -U : U,
    max_abs_val = abs_L > abs_U ? abs_L : abs_U,
          //now we know, whether the type should be signed, and the max abs
   //value to represent.
    bigger_char = is_signed ?
             (max_abs_val/SCHAR_MAX > 0  ) :  (max_abs_val/UCHAR_MAX > 0  ),
    bigger_short = is_signed ?
             (max_abs_val/SHORT_MAX > 0  ) :  (max_abs_val/USHORT_MAX > 0  ),
    bigger_int = is_signed ?
             (max_abs_val/INT_MAX > 0  ) :  (max_abs_val/UINT_MAX > 0  )

       }
 typedef typename
 __type_by_range_aux<is_signed,bigger_char,bigger_short,bigger_int>::type
type;
};

//examples of usage:
typedef type_by_range<365>::type day_t;
typedef type_by_range<200,-300>::type some_type;


/*
     Ideas:
 *) put auxilary templates in some namespace to avoid polluting the
   global namespace or std::.

 *) To  add several type gates: for example:
   smallest_type_by_range, optimal_type_by_range.
     The second will be considered faster than first, but can be wider than
     first also. This is compiler-specific and may depend on command line
     options of compiler.

  *)  Template type_by_width can be added - returns type for the given width in
            bits. In this case, the special long integer templates can be
            introduced, that will provided the support for a types of arbitrary width.

         Some problems:
  According to draft, it's guaranteed, that the enum will be able to hold values
  of type 'int', and it haven't to be able to hold anything bigger.
  Most compilers overdone the draft in this way, so it seems there is no

  trouble. Another approach - to make the stuff 'static const bigest_int_t'
  members of the 'type_by_range' template and initiliaze it there. By it seems
  to me that more compilers do not support such standart feature, than those
  one that allow enum to hold something bigger than int.
*/




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Vlad Harchev <vladhar@imimail.ssau.ru>
Date: 1998/08/20
Raw View
If anybody is interested in it, here are the bugfixes in the send code:
The code for 'type_by_range' should be substituted with:

template <bigest_int_t U_, bigest_int_t L_=0>
struct type_by_range
{
 //these enums are temporary.
  enum {
    L1=L_, U1=U_, //avoids BCC enum bug
    L = L1 < U1 ? L1 : U1, U = L1 < U1 ? U1 : L1, //get the real max and min
    is_signed = (L < 0),
    abs_L = L < 0 ? -L : L,
    abs_U = U < 0 ? -U : U,
    depends_on_L  =  abs_L > abs_U,
    max_abs_val = abs_L > abs_U ? abs_L : abs_U,
          //now we know, whether the type should be signed, and the max abs
   //value to represent.
    bigger_char = is_signed ?
        (depends_on_L ? abs_L > -SCHAR_MIN : max_abs_val > SCHAR_MAX ) :  (max_abs_val >
UCHAR_MAX   ),
    bigger_short = is_signed ?
        (depends_on_L ? abs_L > -SHRT_MIN : max_abs_val > SHRT_MAX ) :  (max_abs_val >
USHRT_MAX   ),
    bigger_int = is_signed ?
        (depends_on_L ? abs_L > -INT_MIN : max_abs_val > INT_MAX ) :  (max_abs_val >
UINT_MAX   ),
       }
 typedef typename
 __type_by_range_aux<is_signed,bigger_char,bigger_short,bigger_int>::type type;
};

 Previous version of the code will suggest not the smalest type if the upper bound of the
range was bigger than
{ the  maximum value represented by that type minus 1} and if the lower bound of the range
has the value by 1 or 2
smaller than the minimum value representable by the type.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]