Boost logo

Boost :

From: Tomas Puverle (Tomas.Puverle_at_[hidden])
Date: 2006-06-07 12:13:25


> A refresh of the .zip file for the Endian library, based on comments
> received so far, is available at
> http://mysite.verizon.net/~beman/endian-0.2.zip
>
> The docs are online at
> http://mysite.verizon.net/~beman/endian-0.2/libs/endian/index.html

I was very interested in this library/thread but unfortunately didn't have the
time to read the old thread and this one until now.

I'd like to put up a few suggestions for consideration:

1) There is some mention of supporting custom swapping routines. This is
fairly important, as the 3 architectures that I use the most (x86, x86-64 and
sparc) all support some harware primitives to perform endian swapping. x86's
have a bswap instruction. sparc allows you to load/store memory operands as
either little or big endian. Other architectures I occasionaly touch have
similar capabilities. I would like to be able to take advantage of this.

2) Could the library include functionality to make it more useful with other
types? This suggestion is not a replacement for what you are doing, it's more
like a supplement. It's useful when you need to do a fair amount of
processing on your data after you read it in but before you write it back to
the stream/storage etc.
This is how I've implemented similar things in the past:

template<typename T>
struct endian_swapper
{
  static void swap_in_place(T&);
};

The class is specialised for builtin types and arrays, where the member does
the obvious thing. There is also an inline template free function with the
same signature as the member, which just does "return
endian_swapper<T>::swap_in_place(t);"

Now consider a struct, e.g. some sort of network message:

struct A
{
   char k;
   int i;
   float x;
};

BOOST_IMPLEMENT_ENDIAN(A, (k)(i)(x));

The macro expands to a specialisation of endian_swapper<A> with swap_in_place
just calls the free function swap_in_place:

template<>
struct endian_swapper<A>
{
     void swap_in_place(A& t_)
     {
        swap_in_place(t_.(&A::k));
        swap_in_place(t_.(&A::i));
        swap_in_place(t_.(&A::x));
     }
};

You can see how this also recursively works for structs/arrays inside other
structs/arrays.

Final piece is the free function swap, which gives you back a swapped copy of
the original:

template<class T>
T swap(const T & t_)
{
   T temp(t_)
   swap_in_place(temp);
   return temp;
}

I just tried to outline the general idea here but I hope I managed to get the
point across.

It would be even nicer if it could also understand the native/little/big
endian semantics you've already discussed but I thought trying to work that
into the examples would just make them too complicated.

Thanks for the good work.

Tom


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk