[libcxx-commits] [PATCH] D128146: [libc++] Use uninitialized algorithms for vector
Louis Dionne via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jul 7 08:37:06 PDT 2022
ldionne added inline comments.
================
Comment at: libcxx/include/__memory/uninitialized_algorithms.h:358
// Destroys every element in the range [first, last) FROM RIGHT TO LEFT using allocator
// destruction. If elements are themselves C-style arrays, they are recursively destroyed
----------------
Can you please add a TODO to switch this to a normal left-to-right algorithm and to use `reverse_iterator` from callers?
================
Comment at: libcxx/include/__memory/uninitialized_algorithms.h:504-505
+template <class _Alloc, class _Iter, class _Sent>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void
+__allocator_destroy(_Alloc& __alloc, _Iter __first, _Sent __last) {
+ for (; __first != __last; ++__first)
----------------
Please comment on what this function does.
================
Comment at: libcxx/include/__memory/uninitialized_algorithms.h:512
+// that __first2 can hold at least distance(__first1, __last1) uninitialized elements. If an exception is thrown the
+// already copied elements are destroyed in order of their construction.
+template <class _Alloc, class _Iter1, class _Sent1, class _Iter2>
----------------
We should destroy in reverse order of construction, it's usually what's expected. Applies everywhere.
================
Comment at: libcxx/include/__memory/uninitialized_algorithms.h:517-518
+ auto __destruct_first = __first2;
+ auto __guard =
+ std::__make_cxx03_transaction(&__allocator_destroy<_Alloc, _Iter2, _Iter2>, __alloc, __destruct_first, __first2);
+ while (__first1 != __last1) {
----------------
Instead of creating a separate `__transaction` class for C++03, I would do this:
```
template <class _Alloc, class _Iter>
struct _AllocatorDestroyRange {
_LIBCPP_CONSTEXPR_AFTER_CXX11 void operator()() const {
std::__allocator_destroy(__alloc_, __first, __last);
}
_Alloc& __alloc_;
_Iter& __first;
_Iter& __last;
};
```
And then I'd use this from the `__uninitialized_FOO` functions as:
```
__transaction<_AllocatorDestroyRange<_Alloc, _Iter1> > __guard(_AllocatorDestroyRange<_Alloc, _Iter1>(__allloc, __destruct_first, __first2));
```
Basically, I don't like that we are creating our own local emulation of `std::bind`/`std::bind_back` just for `__transaction`.
Another option would be something like
```
auto __guard = std::__make_transaction(std::bind_back(&__allocator_destroy<_Alloc, _Iter2, _Iter2>, __alloc, __destruct_first, __first2));
```
However, `bind_back` is not available in C++03 and I'm not 100% sure it would be a good idea to drag in that dependency.
================
Comment at: libcxx/include/__memory/uninitialized_algorithms.h:528-532
+template <class _Alloc, class _Type>
+struct __allocator_has_trivial_construct : _Not<__has_construct<_Alloc, _Type*, const _Type&> > {};
+
+template <class _Type>
+struct __allocator_has_trivial_construct<allocator<_Type>, _Type> : true_type {};
----------------
Perhaps this should be called `__allocator_has_trivial_copy_construct` instead?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D128146/new/
https://reviews.llvm.org/D128146
More information about the libcxx-commits
mailing list