boostorg / core

Boost Core Utilities
132 stars 86 forks source link

bit_cast/padding_cast #147

Open gpeterhoff opened 1 year ago

gpeterhoff commented 1 year ago

*Problem In many cases a bit_cast is needed. However, it cannot be assumed that std::bit_cast is available. Therefore it would make sense to "rebuild" this in boost; my implementation: cast.hpp.txt

*Functionality

*padding_cast

thx Gero

pdimov commented 1 year ago

The current implementation is in boost/core/bit.hpp.

gpeterhoff commented 1 year ago

But the implementation for bit_cast is not constexpr if std::bit_cast/__builtin_bit_cast are available. I'm sure you can easily adapt that - then I would be happy already :-) But I need my padding_cast.

thx Gero

Lastique commented 1 year ago

It is not obvious as to what the behavior should be when the size of the source and target types are different. And such a behavior would likely be endian-dependent. I'm feeling skeptical about adding padding_cast, unless there is a strong case for one particular implementation and not any other.

pdimov commented 1 year ago

I don't think padding_cast, however specified, belongs here.

I'll make use of __builtin_bit_cast for constexpr reasons though, because I've already done some constexpr work on the rest of bit.hpp.

pdimov commented 1 year ago

What is the intended use of padding_cast?

gpeterhoff commented 1 year ago

I need this for some math/FP functions, especially for the type boost::float80_t. The memory size of this type (sizeof) can be 16, 12 or 10 bytes depending on the platform/compiler/etc (of course only 10 bytes are relevant). To cast boost::float80_t e.g. to __int128 and back padding_cast is helpful.

gpeterhoff commented 1 year ago

Hello Peter, I have seen that you have customized bit_cast (bit.hpp). But this is incomplete:

constexpr case You only check if __builtin_bit_cast is available. But it cannot be assumed that all compilers support this. Therefore you have to check additionally for std::bit_cast (__cpp_lib_bit_cast >= 201806L).

non constexpr case You only check the size (BOOST_STATIC_ASSERT(sizeof(To)==sizeof(From)), but bit_cast is subject to further restrictions: https://en.cppreference.com/w/cpp/numeric/bit_cast

thx & regards Gero

pdimov commented 1 year ago

At the moment all the compilers that have a constexpr std::bit_cast implement it via the intrinsic.

Checking the further restrictions requires type traits, but Core can't use TypeTraits (or <type_traits> because we still support C++03.)

gpeterhoff commented 1 year ago

You can use boost::type_traits ?