[RFC PATCH] libstdc++: WIP on library side of C++26 P2786R13 - Trivial Relocatability
Jakub Jelinek
jakub@redhat.com
Mon Jun 16 18:54:20 GMT 2025
Hi!
Also, I wonder what calls need to be fully qualified,
all of trivially_relocate, uninitialized_move, destroy,
move?
And the paper says that for arrays it should
instead do in each loop
relocate(begin(first[i]), end(first[i]), *start_lifetime_as<T>(result + i));
-ish stuff, so that needs to be added as well.
On Mon, Jun 16, 2025 at 08:21:16PM +0200, Jakub Jelinek wrote:
> + template<typename _Tp>
> + constexpr _Tp*
> + relocate(_Tp* __first, _Tp* __last, _Tp* __result) noexcept
> + {
> + static_assert(is_nothrow_relocatable_v<_Tp> && !is_const_v<_Tp>);
> + if !consteval
> + {
> + if constexpr (is_trivially_relocatable_v<_Tp>)
> + return trivially_relocate(__first, __last, __result);
> + }
> + if (__first == __result)
> + return __last;
> + if (__first == __last)
> + return __result;
> +
> + size_t __n = __last - __first;
> + if constexpr (is_move_constructible_v<_Tp>)
> + {
> + if !consteval
> + {
> + // If there is no overlap, move everything first and then
> + // destruct.
> + if ((__UINTPTR_TYPE__)__last < (__UINTPTR_TYPE__)__result
> + || ((__UINTPTR_TYPE__)(__result + __n)
> + < (__UINTPTR_TYPE__)__first))
> + {
> + __result = uninitialized_move(__first, __last, __result);
> + destroy(__first, __last);
> + return __result;
> + }
> + }
> + }
> +
> + // FIXME: This won't work at constexpr time. std::less uses
> + // there just < without the cast which won't work either if
> + // __result and __first don't point into the same object.
> + if ((__UINTPTR_TYPE__)__result < (__UINTPTR_TYPE__)__first
> + || (__UINTPTR_TYPE__)__last < (__UINTPTR_TYPE__)__result)
> + {
> + for (; __first != __last; ++__first, ++__result)
> + {
> + ::new(__result) _Tp(move(*__first));
> + __first->~_Tp();
> + }
> + return __result;
> + }
> + else
> + {
> + _Tp *__ret = __result + __n;
> + for (__result = __ret; __last != __first; )
> + {
> + --__last;
> + --__result;
> + ::new(__result) _Tp(move(*__last));
> + __last->~_Tp();
> + }
> + return __ret;
> + }
> + // If at constand evaluation is_trivially_relocatable_v<_Tp>
> + // but not is_move_constructible_V<_Tp>, fail.
> + __builtin_unreachable();
> + }
Jakub
More information about the Libstdc++
mailing list