SOLVED: Function overloading and base types

G

Gordon Schumacher

I found a clever way to solve this issue: I used a variant of the code
at http://www.flipcode.com/cgi-bin/fcarticles.cgi?show=64171. On one
hand, this code is fairly arcane, and I realize that it's not a
solution if you're unfortunate enough to be stuck using Microsoft VC6
(or earlier!) but on the other hand it did solve the issue at hand
without littering the entire codebase with preprocessor directives.

In addition to the typelists he defined, I added a list of *my* sized
types:
typedef TL_4(int8_t, int16_t, int32_t, int64_t) signed_sizes;
typedef TL_4(uint8_t, uint16_t, uint32_t, uint64_t) unsigned_sizes;

Now I can convert a base type to one of my types as follows:
template < typename T > T ByteSwap(const T val)
{ return static_cast<T> (static_cast < typename
select_type_size<sizeof(T), unsigned_sizes>::result_type > (val)); }

But wait, it gets better...

The above only works if you know whether your variable is signed or
unsigned. So we added this to John Martin's code:

// used to choose signedness at compile time (signed cases)
template <class U>
struct select_sign
{
enum {result_sign = true};
};

// unsigned cases
template <>
struct select_sign<unsigned char>
{
enum {result_sign = false};
};
template <>
struct select_sign<unsigned short>
{
enum {result_sign = false};
};
template <>
struct select_sign<unsigned int>
{
enum {result_sign = false};
};
template <>
struct select_sign<unsigned long>
{
enum {result_sign = false};
};
template <>
struct select_sign<unsigned LLTYPE>
{
enum {result_sign = false};
};

// choose a type based both on size of original type and signedness
template <class T, class UnsignedList, class SignedList>
struct select_type_sign;

template <typename T, class U, class V, class W, class X>
struct select_type_sign<T, typelist<U, V>, typelist<W, X> >
{
typedef typename select_type
<
select_sign<T>::result_sign,
typename select_type_size<sizeof(T), typelist<U,
V> >::result_type,
typename select_type_size<sizeof(T), typelist<W,
X> >::result_type
>::result_type result_type;
};


Now, I can get the correct equivalent from my lists of types of a given
type:
typename select_type_sign<T, unsigned_sizes,
signed_sizes>::result_type mytype;


Just Like Magic(tm)!
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top