Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for bit-fields #80

Open
bgaifullin opened this issue May 18, 2021 · 3 comments
Open

add support for bit-fields #80

bgaifullin opened this issue May 18, 2021 · 3 comments

Comments

@bgaifullin
Copy link

Lets implement support for bit-fields for read-only mode.

@schaumb
Copy link

schaumb commented Mar 9, 2022

C++14 loophole and classic methods don't work constexpr time. So I'm focusing on the C++17 solution.


I created a branch, and some changes.

First, I modified the structure binding functions to return not the tuples of references, but getter and setter lambdas.
Getter has the option to get by reference or by value. So now the types can be returned without trying to get member references.

I tried to manage the has_bitfield_member<T> decision problem from 2 sides.

Has/Is bitfield member

a can_has_a_bitfield check which returns true, if the class can contain a bitfield. This is too wide currently, if a struct has any integral type, the function returns true.
(note: bitfield can only be integral type)


a clearly_has_a_bitfield check which returns true, if the class knowly contains a bitfield. This is not handling all the cases.

Missing parts:

  • packed structures (but can be static_assert)
  • if size equals to sequence_tuple::tuple<types...> (aka the bitfields use the same size as if they weren't bitfields) :
    • not trivial types. (This probably can be tightened for the types that contain any member that is not constexpr default initializable)
    • contains a bool member.
    • contains a bitfield with maximum wide, like char c: 8;

Bitfield offset and size

A bitfield size can be calculated with this trick (except for bool-s)

For the bitfield offset I can not come up with an idea with standard C++17, constexpr time.


C++20 has more opportunity to "guess" the type layout with the layout compatible type trait, and the bit cast. These help for the bitfield offset, but not all the cases; only for the standard_layout types.

@schaumb
Copy link

schaumb commented Mar 9, 2022

Probably can be managed to create not only "read-only" mode, but "proxy" mode too. So If integral types return with a proxy type like:

template<class Getter, class Setter>
struct Proxy {
    using type = std::invoke_result_t<Getter, /*no reference*/>;
    operator type() const {
      return getter(/* no reference */);
    }
    operator type&() const {
      return getter(/*reference*/);
    }
    template<class Any>
    Proxy& operator=(Any&& val) {
        setter(val);
        return *this;
    }
private:
    Getter getter;
    Setter setter;
};

This can be used for bitfield structs too.

@schaumb
Copy link

schaumb commented Jan 9, 2024

C++20 is helping. With consteval and layout_compatible it can be guessed the bit-field members and their sizes.

So the clearly_has_a_bitfield check cases can be solved.

Remaining limitation:

  • if size equals to sequence_tuple::tuple<types...> (aka the bitfields use the same size as if they weren't bitfields) AND it contains integral type AND
    • any member is non-copiable, non-movable and non-default-constructible
    • if the class is not standard layout type OR the compiler does not support __cpp_lib_is_layout_compatible (clang), and:
      • contains a bool member
      • contains a bitfield with maximum wide, like char c: 8;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants