Boost logo

Boost :

Subject: Re: [boost] Boost.Endian - endian_buffer requirements
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2017-01-25 21:18:23


Le 26/01/2017 à 01:05, Vicente J. Botet Escriba a écrit :
> Le 26/01/2017 à 00:04, Vicente J. Botet Escriba a écrit :
>>
>> Hi,
>>
>> I wanted to put an Int wrapper inside a endian_buffer and I have some
>> compiler errors depending on whether it is aligned ort not.
>>
>> http://melpon.org/wandbox/permlink/k52wH2A7yagL2vMP
>>
>> I was expecting that the endian_buffer would make abstraction of the
>> wrapped type and consider it just as a sequence of bytes, but it
>> seems that it instead works only for some builtin integral.
>>
>> Am I missing something?
>> Was this restriction intended?
>> Could this restriction be removed and if yes, how?
>>
>>
>>
> I have reached to fix the aligned case adding the customization
>
> Int endian_reverse(Int x)
> {
> using boost::endian::endian_reverse;
> return Int {endian_reverse(x.value)};
> }
>
> However for the unaligned case there is yet the shift error
>
>
> prog.cc:30:28: required from here
> /usr/local/boost-1.61.0/include/boost/endian/buffers.hpp:231:26: error: invalid static_cast from type 'Int' to type 'char'
> *(bytes - 1) = static_cast<char>(value);
> ^~~~~~~~~~~~~~~~~~~~~~~~
> /usr/local/boost-1.61.0/include/boost/endian/buffers.hpp:232:59: error: no match for 'operator>>' (operand types are 'Int' and 'int')
> next::store_big(bytes - 1, static_cast<T>(value >> 8));
> ~~~~~~^~~~
> /usr/local/boost-1.61.0/include/boost/endian/buffers.hpp:202:5: note: candidate: template<class charT, class traits, boost::endian::order Order, class T, long unsigned int n_bits, boost::endian::align A> std::basic_istream<charT, traits>& boost::endian::operator>>(std::basic_istream<charT, traits>&, boost::endian::endian_buffer<Order, T, n_bits, A>&)
> operator>>(std::basic_istream<charT, traits>& is,
> ^~~~~~~~
>
>
> http://melpon.org/wandbox/permlink/iPwgdVBV91wsRxeC

I have added whatever was missing

struct Int {
     int value;

     // Needed by unaligned
     Int() = default;
     Int(int i) : value (i) {}
     explicit operator char() { return value; }
     int operator >>(int n) { return value >> n; }
     int operator <<(int n) { return value << n; }

     friend Int endian_reverse(Int x)
     {
         using boost::endian::endian_reverse;
         return Int {endian_reverse(x.value)};
     }

};

http://melpon.org/wandbox/permlink/erLEWpc1oaR64iMW

While

     Int() = default;
     explicit Int(int i) : value (i) {}

are natural on a wrapped opaque int, the implicit conversion is less
desirable as well as the conversions to char and the shift operations.

     Int(int i) : value (i) {}
     explicit operator char() { return value; }
     int operator >>(int n) { return value >> n; }
     int operator <<(int n) { return value << n; }

I believe that the conversion could be explicit and that the
implementation could use reinterpret_cast instead of static_cast, as we
are reinterpreting the bits.
IMHO, the shift shouldn't be required. It should be an implementation
detail.

BTW, is there any reason endian_buffer doesn't define equality operators?

Vicente


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