[PATCH] D48753: [libcxx] Use custom allocator's `construct` in C++03 when available.
Louis Dionne via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 7 08:01:39 PST 2018
ldionne requested changes to this revision.
ldionne added a comment.
This revision now requires changes to proceed.
Herald added a subscriber: jkorous.
1. Just to make sure I understand; this patch has nothing to do with https://reviews.llvm.org/D48342, they are entirely orthogonal. Is this correct?
2. Also, before this patch, the allocator's `construct` and `destroy` were NEVER called in C++03, but were called when available in C++11. After this patch, they are called when available in C++03 and in C++11. Is this correct?
If (2) is true, then I believe this patch is a worthwhile improvement in terms of quality-of-implementation, even though it's not mandated by the spec. People do have custom allocators, and this behavior change between C++03 and C++11 is quite subtle and surprising.
================
Comment at: libcxx/include/memory:1466
+template <class _Alloc, class _Pointer, class _Tp>
+struct __has_construct<_Alloc, _Pointer, _Tp, typename enable_if<
+ is_same
----------------
You can just say
```
template <class _Alloc, class _Pointer, class _Tp>
struct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t<
decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>()))
>::type> : std::true_type { };
```
================
Comment at: libcxx/include/memory:1482
+ <
+ decltype((_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>()), void())),
+ void
----------------
Here,
```
template <class _Alloc, class _Pointer>
struct __has_destroy<_Alloc, _Pointer, typename __void_t<
decltype(_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>()))
>::type> : std::true_type { };
```
================
Comment at: libcxx/include/memory:1726
+#else // _LIBCPP_HAS_NO_VARIADICS
+ template <class _Tp, class _A0>
+ _LIBCPP_INLINE_VISIBILITY
----------------
Here,
```
template <class _Tp, class _A0, class = typename enable_if<__has_construct<allocator_type, _Tp*, _A0 const&>::value>::type>
static void __construct(...);
```
and then below
```
template <class _Tp, class _A0, class = typename enable_if<!__has_construct<allocator_type, _Tp*, _A0 const&>::value>::type>
static void __construct(...);
```
This way you don't have to call `__has_construct` at the point of call and `__construct` is slightly more reusable.
================
Comment at: libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp:122
+ {
+ typedef std::vector<int, cpp03_allocator<int> > C;
+ typedef C::allocator_type Alloc;
----------------
These tests are specific to libc++ because C++03 does not mandate this behavior. Please either move them into `test/libcxx` or guard them with `_LIBCPP_VERSION`. I think the former is what we normally do in these cases and should be preferred.
================
Comment at: libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp:135
+ {
+ typedef std::vector<int, cpp03_allocator<int> > C;
+ typedef C::allocator_type Alloc;
----------------
Same as above, this is libc++ specific.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D48753/new/
https://reviews.llvm.org/D48753
More information about the cfe-commits
mailing list