[libcxx-commits] [PATCH] D61761: P1144 "Trivially relocatable" (1/3): is_trivially_relocatable, relocate_at, and uninitialized_relocate

Zoe Carver via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon May 13 11:31:51 PDT 2019


zoecarver added inline comments.


================
Comment at: include/memory:3518
+_ForwardIt2
+__uninitialized_relocate_impl(_ForwardIt1 __first, _ForwardIt1 __last,
+                              _ForwardIt2 __result,
----------------
Quuxplusone wrote:
> zoecarver wrote:
> > Quuxplusone wrote:
> > > zoecarver wrote:
> > > > I don't think this overload is necessary in addition to the below one.
> > > I think this overload would never really be useful in practice, but since it does something different from the below one (element-wise memcpy in a loop, instead of one big memcpy), I figured I should implement it.
> > > 
> > > However, since P1144R3 adds `relocate_at`, I can refactor this overload and the one //above// into a single overload that does `relocate_at`-in-a-loop! Will do.
> > > 
> > > In the process of rewriting this code, I realized that whereas `uninitialized_relocate` copies `uninitialized_move` in not requiring the two iterator types to have the same `value_type`, `relocate_at` requires the exact same type `_Tp *` for both `__source` and `__dest`. I have added an internal version `__relocate_at2(_Sp *__source, _Dp *__dest)`, and am ambivalently considering adding it to the proposal P1144R4. That would require some kind of change to the word "homogeneous" in P1144R3, though. Feel free to comment on this idea here and/or by email.
> > IMVHO I think it would be better to have them be one type and let the user `static_cast` the pointer if they want something different. 
> > 
> > If the difference is meaningful, maybe another overload should be added in P1144R3. Otherwise, I think combining them and using `relocate_at` is a good idea.
> I think I don't understand what you thought I meant. :)
> By "homogeneous" `relocate_at`, I mean it can only relocate from `T` to that same type `T` (not even with different cv-qualifiers). As opposed to `uninitialized_relocate`, which is heterogeneous just like `uninitialized_move` and `std::copy`. For example:
> 
>     long *src;
>     double *dest;
>     std::uninitialized_relocate(src, src+n, dest);  // OK
>     std::relocate_at(src, dest);  // not OK, because the types differ
>     std::__relocate_at2(src, dest);  // OK
> 
> The above case uses a non-trivial relocation operation.
> 
>     int *src;
>     std::unique_ptr<int> *dest;
>     std::uninitialized_relocate(src, src+n, dest);  // OK
>     std::relocate_at(src, dest);  // not OK, because the types differ
>     std::__relocate_at2(src, dest);  // OK
> 
> The above case is functionally equivalent to `memcpy`, although this patch won't go so far as to actually make it use `memcpy`.
I understand what you meant. I think it is important that (for the most part) pointer functions are "homogeneous", especially the ones that rely on `sizeof`. 

Here is an example of what I mean:
```
template<class T>
void cpy(T* dst, T* src)
{
	std::memcpy(dst, src, sizeof(T));
}

int main()
{
	int x = 42;
	int* iptr = &x;
	void* vptr = &x;
	cpy(iptr, vptr); // fails
	cpy(iptr, static_cast<int*>(vptr)); // works
}
```

The above function will prevent easy run time out of bounds errors from differently sized types. 


Repository:
  rCXX libc++

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61761/new/

https://reviews.llvm.org/D61761





More information about the libcxx-commits mailing list