https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87106
--- Comment #10 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> --- > Still better than duplicating the whole class IMO. The `optional` example in P1144R0 Appendix B looks scarier than I should have. For one thing, I omitted all the boring user-facing API of `optional` (emplace, reset, has_value, operator bool, operator*, operator->, ...) which would be implemented in the top level and thus shared by everyone. For another thing, I showed the metaprogramming for BOTH trivially relocatable AND trivially constructible/destructible in the same example. Adding trivial relocatability to a library type doesn't involve any duplication of member function implementations. It's tedious for sure, but mechanical. Here's the commit where I trivially-relocatable-ized `std::deque`. 34 lines added, 18 more lines changed. There's some duplication, but it's not literally "duplicating the whole class." https://github.com/llvm-mirror/libcxx/commit/cccc6d330fba37852455a3905b402b1aabe05474#diff-38adc80cec663f2f29c22e9ffc0de912 > I was looking into using relocation in std::swap. ... Maybe types that are > trivially relocatable but not trivially movable and destructible? Or just > non-trivial? My commit for `std::swap` is here: https://github.com/Quuxplusone/libcxx/commit/4d89aa95a7da86d1671d3e4441967782399fc3f9#diff-d436eb0fd9de10b54a828ce6435f7e81 It's extremely naive. I just say, if the type is_trivially_relocatable, then we use memcpy --- EXCEPT, if the type is_empty, then we should NOT use memcpy, because that is highly likely to break real code. https://quuxplusone.github.io/blog/2018/07/13/trivially-copyable-corner-cases/ > For the array swap, I could use a large intermediate buffer on the side > (memcpy really shines on large regions), possibly as large as the full array, > but I would need to cap it to some safe size (hard to define). A couple of people have mentioned to me that libc is conspicuously missing a `memswap(void *a, void *b, size_t n)` primitive (such as would be used internally by `qsort`). If libc guaranteed us an efficient implementation of `memswap`, we wouldn't need to do so much micro-optimization at the C++ level. > By the way, when swapping ranges of a type that does not specialize/overload > swap, it seems wasteful to call swap on each element, because it creates a > new temporary object for each element instead of reusing the same one. I'm not sure I follow. Are you relying on the premise that move-constructing an object, and then destructing a moved-from object, is more expensive than move-assigning into a moved-from object? I would expect move-assigning to be *no cheaper* than move-constructing, and so constructing and destructing a new temporary for each element ought to be *no more expensive* (and possibly cheaper) than reusing the same one. But I have no actual benchmark numbers. Do you? Re detecting overloads/specializations of std::swap, I think both are impossible, but I'm curious what you're thinking of, BUT I bet it's off-topic for this issue, so maybe you could email me your idea? :)