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

Extract the core engine (and make a paper out of it?) #31

Open
brenoguim opened this issue Oct 27, 2021 · 3 comments
Open

Extract the core engine (and make a paper out of it?) #31

brenoguim opened this issue Oct 27, 2021 · 3 comments
Assignees

Comments

@brenoguim
Copy link
Owner

The fundamental building blocks of this library can be seen as:

template<class... Ts>
auto allocate_adjacent_arrays(std::integral auto... sizes) -> std::tuple<std::pair<Ts*, Ts*>...>;

This function would allocate a single block of memory that fits sizeof...(Ts) arrays which the sizes are given in sizes. The return value returns pointers to (non-constructed) objects inside this.

The second building block would be something like std::uninitialized_value_construct which support multiple begin/end iterators.

Then it should be very easy to build this library.

@brenoguim brenoguim self-assigned this Oct 27, 2021
@brenoguim
Copy link
Owner Author

brenoguim commented Oct 27, 2021

If we extract the more fundamental building block that creates the layout of the structure, and make that constexpr, it would be possible to implement a std::tuple without inheritance, and even avoid using space for empty components in the tuple. Not sure if that is undefined behavior though.

@brenoguim
Copy link
Owner Author

brenoguim commented Oct 29, 2021

This would be a much better low level engine: https://godbolt.org/z/xfzq97nKK

auto foo()
{
    int from[] = {1, 2, 3, 4, 5, 6};
    auto r = mynew(with<int, Copy>(5, from),
                   with<float, Fill>(10, 1.0f),
                   with<long, Default>(12),
                   with<char, Value>(5)
                   );
    mydestroy(r);
    return r;
}

This allocates the memory buffer for multiple arrays, initialize them with various configurations (inspired from uninitialized_default_construct, uninitialized_value_construct, uninitialized_copy and uninitialized_fill) and returns a tuple of handles to this array.

The whole structure can be destroyed (in reverse order) by passing in the same tuple of elements.

In the shared_ptr example, library writers could use this low level function to do:

auto arrays = mynew(with<ControlBlock, Default>(1), with<T, Default>(n));
_controlBlock = std::get<0>(arrays).begin();
_controlBlock->size = n;
_ts = std::get<1>(arrays);

however in the destructor, the structure has to be rebuilt:

std::tuple<rng<ControlBlock*>, rng<T*>> arrays { {_controlBlock, _controlBlock+1} , {_ts, _ts+_controlBlock->size} };
mydestroy(arrays);
operator delete(_controlBlock);

@brenoguim
Copy link
Owner Author

brenoguim commented Oct 29, 2021

Another implementation would be https://godbolt.org/z/nsMhd33ox . This seems to generate better code - using try/catch instead of destructors to ensure exception safety.
a bit of cleanup comes to this: https://godbolt.org/z/6zosWdeqb

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

1 participant