Date: Fri, 8 Dec 2023 20:43:21 +0000
On Thursday, December 7, 2023, Lénárd Szolnoki wrote:
> On Thu, 2023-12-07 at 10:09 +0000, Gašper Ažman wrote:
> > The implementation is a reasonable start but unaligned<trivial> needs
> > to itself be trivial (to allow composition of structs containing
> > unaligned members inside other unaligned<> ), so it gets just a tad
> > more interesting.
>
> It is trivial, isn't it?
>
> https://godbolt.org/z/ddT6Mb65n
>
> Specifically it needs to be trivially copyable.
Just to see if we're all singing from the same hymn sheet . . . Would we
start out something like the following?
#include <cstring> // memcpy
#include <type_traits> // is_trivial
#include <utility> // forward
template<typename T>
requires std::is_trivial_v<T>
class unaligned {
char unsigned buf[sizeof(T)]; // or maybe '__datasizeof' ?
public:
#define OP(op) \
template<typename U> \
unaligned &operator op (U &&u) \
{ \
T tmp; \
std::memcpy(&tmp,buf,sizeof tmp); \
tmp op std::forward<U>(u); \
std::memcpy(buf,&tmp,sizeof tmp); \
return *this; \
}
OP(+=)
OP(-=)
OP(*=)
OP(/=)
OP(%=)
OP(<<=)
OP(>>=)
OP(|=)
OP(&=)
OP(^=)
unaligned &operator++(void)
{
T tmp;
std::memcpy(&tmp,buf,sizeof tmp);
++tmp;
std::memcpy(buf,&tmp,sizeof tmp);
return *this;
}
unaligned &operator++(int) = delete;
#define UOP(uop) \
T operator uop (void) const \
{ \
T tmp; \
std::memcpy(&tmp,buf,sizeof tmp); \
return uop tmp; \
}
UOP( + )
UOP( - )
UOP( ! )
UOP( ~ )
};
int main(void)
{
unaligned<double> obj;
obj += 42.6f;
!obj;
}
> On Thu, 2023-12-07 at 10:09 +0000, Gašper Ažman wrote:
> > The implementation is a reasonable start but unaligned<trivial> needs
> > to itself be trivial (to allow composition of structs containing
> > unaligned members inside other unaligned<> ), so it gets just a tad
> > more interesting.
>
> It is trivial, isn't it?
>
> https://godbolt.org/z/ddT6Mb65n
>
> Specifically it needs to be trivially copyable.
Just to see if we're all singing from the same hymn sheet . . . Would we
start out something like the following?
#include <cstring> // memcpy
#include <type_traits> // is_trivial
#include <utility> // forward
template<typename T>
requires std::is_trivial_v<T>
class unaligned {
char unsigned buf[sizeof(T)]; // or maybe '__datasizeof' ?
public:
#define OP(op) \
template<typename U> \
unaligned &operator op (U &&u) \
{ \
T tmp; \
std::memcpy(&tmp,buf,sizeof tmp); \
tmp op std::forward<U>(u); \
std::memcpy(buf,&tmp,sizeof tmp); \
return *this; \
}
OP(+=)
OP(-=)
OP(*=)
OP(/=)
OP(%=)
OP(<<=)
OP(>>=)
OP(|=)
OP(&=)
OP(^=)
unaligned &operator++(void)
{
T tmp;
std::memcpy(&tmp,buf,sizeof tmp);
++tmp;
std::memcpy(buf,&tmp,sizeof tmp);
return *this;
}
unaligned &operator++(int) = delete;
#define UOP(uop) \
T operator uop (void) const \
{ \
T tmp; \
std::memcpy(&tmp,buf,sizeof tmp); \
return uop tmp; \
}
UOP( + )
UOP( - )
UOP( ! )
UOP( ~ )
};
int main(void)
{
unaligned<double> obj;
obj += 42.6f;
!obj;
}
Received on 2023-12-08 20:43:23