C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::sizeof_minus_trailing_padding

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Mon, 4 Dec 2023 07:08:07 +0000
On Mon, Dec 4, 2023 at 3:02 AM Arthur O'Dwyer wrote:
>
> What I think Thiago meant, and certainly what I mean, is that it's
> wrong to use [[no_unique_address]] on the `value` member of
> an `optional` or `expected`.


I think it's fine so long as you make it very obvious that you're not
allowed to use 'memcpy' or 'memset'. Maybe call it something like:

    class optional_compacted_no_memset { . . . };

I was also thinking of writing something along the lines of an
'array_compacted' which would be the same as an 'std::array' except
that the elements have no padding between them, which would be very
useful for minimising Flash usage on a microcontroller -- something
like:

    #include <cassert> // assert
    #include <cstddef> // size_t
    #include <cstdint> // uintptr_t
    #include <cstring> // memcpy

    template<typename T, std::size_t const len>
    class array_compacted {
        char unsigned buf[ __datasizeof(T) * len ];
        class Manipulator {
            void *const p;
        public:
            Manipulator(void *const arg) : p(arg) {};
            void get(T *const arg) const noexcept
            {
                assert( 0u == (reinterpret_cast<std::uintptr_t>(arg) %
alignof(T)) );
                std::memcpy(arg,p,__datasizeof(T));
            }
            void set(T const *const arg) noexcept
            {
                assert( 0u == (reinterpret_cast<std::uintptr_t>(arg) %
alignof(T)) );
                std::memcpy(p,arg,__datasizeof(T));
            }
        };
    public:
        void Reset(void) { std::memset(buf,0,sizeof buf); }
        Manipulator const operator[](std::size_t const i) const noexcept
        {
            assert( i < len );
            return Manipulator{buf + __datasizeof(T)*i};
        }
        Manipulator operator[](std::size_t const i) noexcept
        {
            assert( i < len );
            return Manipulator{buf + __datasizeof(T)*i};
        }
    };

    struct Monkey {
        long double a;
        char b;
    };

    int main(void)
    {
        array_compacted<Monkey,256u> ac;
        ac.Reset();
        Monkey m;
        ac[0u].get(&m);
        m.b = 7;
        ac[9u].set(&m);
    }

Received on 2023-12-04 07:08:19