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

Feature request: Make static_vector "trivially relocatable" when possible #258

Open
Quuxplusone opened this issue Nov 14, 2023 · 3 comments · May be fixed by #263
Open

Feature request: Make static_vector "trivially relocatable" when possible #258

Quuxplusone opened this issue Nov 14, 2023 · 3 comments · May be fixed by #263

Comments

@Quuxplusone
Copy link

It was recently discussed on the cpplang Slack that Boost implements a lot of class types that are "Platonically trivially relocatable" without being known to the compiler to be trivially relocatable.
In P1144R9 my go-to example was boost::movelib::unique_ptr<int>; but in the above discussion it was pointed out that boost::container::static_vector<int,10> would be a less archaic example, so P1144R10 might switch to that.

Executive summary: Wouldn't it be cool if we could write—

static_assert(__is_trivially_relocatable(boost::container::static_vector<int,10>));
static_assert(!__is_trivially_relocatable(boost::container::static_vector<std::list<int>,10>));

The __is_trivially_relocatable is available only on Clang so far, and the necessary std::is_trivially_relocatable_v/[[trivially_relocatable]] trait/attribute are available only in my fork of Clang/libc++; but both levels of support are detectable via the preprocessor (see Godbolt).

I propose to add an #ifdef so that static_vector and perhaps other containers will be recognized as trivially relocatable whenever the compiler/STL support that notion.

@psiha
Copy link

psiha commented Dec 21, 2023

upvote

@psiha
Copy link

psiha commented Jan 3, 2024

Actually aren't all Boost.Containers ('platonically') trivially relocatable (simply by the fact of not being self-referential)?

static_vector should in addition be fully trivial for all trivial Ts - yet it fails for example the std::is_trivially_move_constructible check for a trivial T.

@Quuxplusone
Copy link
Author

Actually aren't all Boost.Containers ('platonically') trivially relocatable (simply by the fact of not being self-referential)?

Yes, if their components are. For example,

  template<class T>
  using ShmAlloc = boost::interprocess::allocator<T, boost::interprocess::managed_shared_memory::segment_manager>;
  static_assert(!is_trivially_relocatable_v<boost::container::vector<int, ShmAlloc<int>>>);

because such a vector's move-construct-and-destroy needs more than memcpy — it needs to update the object representation of its interprocess::offset_ptr data member. So it's generally tricky to figure that out without a lot more machinery (one piece of which, ideally, would be STL support for std::is_trivially_relocatable — that's P1144).

Also, I'm taking your word for it that "all Boost.Containers" are "not self-referential." E.g. I know Microsoft's std::list<int> is trivially relocatable because it uses a "sentinel node" on the heap; libstdc++'s and libc++'s std::list<int> are non-trivially relocatable because they use a "dummy node" inside the list object itself; but I have no idea what boost::container::list does. Basically static_vector is the only one where I'm confident I understand (and can correctly implement) all of the icky innards involved with its relocatability.

I also agree that is_trivially_move_constructible_v<T> ought to imply is_trivially_move_constructible_v<static_vector<T,10>>, and is_trivially_copyable_v<T> ought to imply is_trivially_copyable_v<static_vector<T,10>>. But the latter (changing trivial copyability of a type) is an ABI break, and I don't know Boost's policies on ABI breaks. Adding the [[trivially_relocatable]] attribute definitely isn't an ABI break.

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