[prev in list] [next in list] [prev in thread] [next in thread] 

List:       boost
Subject:    Re: [boost] Boost.Endian - endian_buffer requirements
From:       "Vicente J. Botet Escriba" <vicente.botet () wanadoo ! fr>
Date:       2017-01-26 2:18:23
Message-ID: c218965c-4f0e-d302-b6f7-d9af47342c0c () wanadoo ! fr
[Download RAW message or body]

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

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic