Boost logo

Boost :

Subject: Re: [boost] [boost::endian] Request for comments/interest
From: Terry Golubiewski (tjgolubi_at_[hidden])
Date: 2010-06-03 10:37:29


Terry wrote:

>> swap_in_place still needs a reinterpret_cast too to convert
>> from the 'char * buf' assembled from the hypothetical TCP stream.
>
Robert Stewart wrote:
> Not quite. As discussed in a separate post, a static_cast is sufficient
> and there's only one cast needed. That's still less ugly. (Since buf is
> a void * in the snipped code, static_cast would work for your casts, too.)

'buf' must be a pointer to "something". The void* is just masking what is
really analagous to a reinterpret_cast.
void* is just as ugly as reinterpret_cast. Maybe more so.

>> What bugs me is that 'buf' doesn't point to a 'T' yet. It
>> points to a half-baked 'T'. Only after one calls
>> swap_in_place() is the object really a 'T'.
>
> That would apply to floating point, certainly. However, for integer
> types, your statement is false. Before the swap, they are still integers,
> they just don't have the desired value.

I disagree. Physically, they are compatible, but logically, they are
different. I think the logical view matters more.

> Even in the object-based approach, the object isn't a proper T until you
> access it and the swap occurs. The implicit swap veneer just gives you
> the impression that it is already in the desired form.

An endian<X, T> is not the same as a T. Even endian<native, T> must be
converted to a T before you can operate on it. The veneer is important,
because it works like a T, without actually being a T. I think that subtle
distinction is important and is the primary motivation for type-based
endian. I object to your use of the word "swap" though. My type-based
approach does a reverse_copy, not a swap. This distinction is the
fundamental topic of this discussion.

When T is not integral, the distinction becomes more important. Although I
have found endian<big, double> to be useful in the past. I wouldn't
recommend that anyone actually do that (though I wouldn't prohibit it
either).
For production systems, would prefer that messages contain something like...

#pragma pack(push, 1)
template<endian_t E>
class ieee754::binary64 {
  // storage in ieee754 format.
public:
    binary64(); // 0.0 in ieee format
    binary64(double x); // converts from native double to ieee format
    operator double() const; convert ieee format to native double
    binary64& operator=(double x); // convert native double to ieee format
 };

struct Message {
  typedef interface::ieee754::binary64<big> Double;
  Double x, y, z;
};
#pragma pack(pop)

terry


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