Relocation (= move+destroy)

Marc Glisse marc.glisse@inria.fr
Tue Oct 23 21:17:00 GMT 2018


On Tue, 23 Oct 2018, Jonathan Wakely wrote:

> CCing gcc-patches

It seems to have disappeared somehow during the discussion, sorry.

> The tricky stuff in <bits/stl_vector.h> all looks right, I only have
> some comments on the __relocate_a functions ...
>
>
>> Index: libstdc++-v3/include/bits/stl_uninitialized.h
>> ===================================================================
>> --- libstdc++-v3/include/bits/stl_uninitialized.h	(revision 265289)
>> +++ libstdc++-v3/include/bits/stl_uninitialized.h	(working copy)
>> @@ -872,14 +872,75 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>     uninitialized_move_n(_InputIterator __first, _Size __count,
>> 			 _ForwardIterator __result)
>>     {
>>       auto __res = std::__uninitialized_copy_n_pair
>> 	(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
>> 	 __count, __result);
>>       return {__res.first.base(), __res.second};
>>     }
>> #endif
>> 
>> +#if __cplusplus >= 201402L
>
> What depends on C++14 here? Just enable_if_t? Because we have
> __enable_if_t for use in C++11.
>
> Both GCC and Clang will allow constexpr-if and static_assert with no
> message in C++11.

Probably it can be enabled in C++11 if you think that matters. I'll admit 
that I personally don't care at all about C++11, and the main motivation 
would be to enable a cleanup if we stop supporting C++03 (I am not very 
optimistic).

>> +  template<typename _Tp, typename _Up, typename _Allocator>
>> +    inline void
>> +    __relocate_a(_Tp* __dest, _Up* __orig, _Allocator& __alloc)
>
> I find it a little surprising that this overload for single objects
> using the memmove argument ordering (dest, source) but the range overload
> below uses the STL ordering (source_begin, source_end, dest).
>
> But I wouldn't be surprised if we're already doing that somewhere that
> I've forgotten about.
>
> WOuld it make sense to either rename this overload, or to use
> consistent argument ordering for the two __relocate_a overloads?

The functions were not meant as overloads, it just happened that I arrived 
at the same name for both, but it would make perfect sense to give them 
different names. I started from __relocate(dest, source) for one element, 
and later added an allocator to it. The other one corresponds to 
__uninitialized_move_a, and naming it __uninitialized_relocate_a would be 
silly since "uninitialized" is included in the definition of relocate.

I think I'd rather rename than change the order. Do you have suggestions? 
__relocate_range_a?

>> + 
>> noexcept(noexcept(__gnu_cxx::__alloc_traits<_Allocator>::construct(__alloc,
>
> Since this is C++14 (or maybe C++11) you could just use
> std::allocator_traits directly. __gnu_cxx::__alloc_traits is to
> provide equivalent functionality in C++98 code.

Thanks, I was wondering what it was for.

>> +			 __dest, std::move(*__orig)))
>> +	     && noexcept(__gnu_cxx::__alloc_traits<_Allocator>::destroy(
>> +			    __alloc, std::__addressof(*__orig))))
>> +    {
>> +      typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
>> +      __traits::construct(__alloc, __dest, std::move(*__orig));
>> +      __traits::destroy(__alloc, std::__addressof(*__orig));
>> +    }
>> +
>> +  template<typename _Tp>
>> +    struct __is_trivially_relocatable
>> +    : is_trivial<_Tp> { };
>
> It might be worth adding a comment that this type might be specialized
> in future, so that I don't forget and simplify it to an alias template
> later :-)

Ok.

-- 
Marc Glisse



More information about the Libstdc++ mailing list