vsapsai updated this revision to Diff 154912.
vsapsai added a comment.
- In C++03 call allocator's `destroy` when available.
- Rename `_Args` as it's not a variadic template pack.
https://reviews.llvm.org/D48753
Files:
libcxx/include/memory
libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
libcxx/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp
libcxx/test/support/min_allocator.h
Index: libcxx/test/support/min_allocator.h
===================================================================
--- libcxx/test/support/min_allocator.h
+++ libcxx/test/support/min_allocator.h
@@ -14,6 +14,7 @@
#include <cstdlib>
#include <cstddef>
#include <cassert>
+#include <climits>
#include "test_macros.h"
@@ -131,6 +132,59 @@
friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);}
};
+template <class T>
+struct cpp03_allocator : bare_allocator<T>
+{
+ typedef T value_type;
+ typedef value_type* pointer;
+
+ static bool construct_called;
+
+ // Returned value is not used but it's not prohibited.
+ pointer construct(pointer p, const value_type& val)
+ {
+ ::new(p) value_type(val);
+ construct_called = true;
+ return p;
+ }
+
+ std::size_t max_size() const
+ {
+ return UINT_MAX / sizeof(T);
+ }
+};
+template <class T> bool cpp03_allocator<T>::construct_called = false;
+
+template <class T>
+struct cpp03_overload_allocator : bare_allocator<T>
+{
+ typedef T value_type;
+ typedef value_type* pointer;
+
+ static bool construct_called;
+
+ void construct(pointer p, const value_type& val)
+ {
+ construct(p, val, std::is_class<T>());
+ }
+ void construct(pointer p, const value_type& val, std::true_type)
+ {
+ ::new(p) value_type(val);
+ construct_called = true;
+ }
+ void construct(pointer p, const value_type& val, std::false_type)
+ {
+ ::new(p) value_type(val);
+ construct_called = true;
+ }
+
+ std::size_t max_size() const
+ {
+ return UINT_MAX / sizeof(T);
+ }
+};
+template <class T> bool cpp03_overload_allocator<T>::construct_called = false;
+
#if TEST_STD_VER >= 11
Index: libcxx/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp
===================================================================
--- libcxx/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp
+++ libcxx/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp
@@ -73,7 +73,6 @@
std::aligned_storage<sizeof(VT)>::type store;
std::allocator_traits<Alloc>::destroy(a, (VT*)&store);
}
-#if TEST_STD_VER >= 11
{
A0::count = 0;
b_destroy = 0;
@@ -86,5 +85,4 @@
assert(A0::count == 1);
assert(b_destroy == 1);
}
-#endif
}
Index: libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
===================================================================
--- libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
+++ libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
@@ -129,9 +129,39 @@
}
void test_ctor_under_alloc() {
-#if TEST_STD_VER >= 11
int arr1[] = {42};
int arr2[] = {1, 101, 42};
+ {
+ typedef std::vector<int, cpp03_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ Alloc a;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1, a);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3, a);
+ assert(Alloc::construct_called);
+ }
+ }
+ {
+ typedef std::vector<int, cpp03_overload_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ Alloc a;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1, a);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3, a);
+ assert(Alloc::construct_called);
+ }
+ }
+#if TEST_STD_VER >= 11
{
using C = TCT::vector<>;
using T = typename C::value_type;
Index: libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
===================================================================
--- libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
+++ libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
@@ -116,9 +116,37 @@
}
void test_ctor_under_alloc() {
-#if TEST_STD_VER >= 11
int arr1[] = {42};
int arr2[] = {1, 101, 42};
+ {
+ typedef std::vector<int, cpp03_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3);
+ assert(Alloc::construct_called);
+ }
+ }
+ {
+ typedef std::vector<int, cpp03_overload_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3);
+ assert(Alloc::construct_called);
+ }
+ }
+#if TEST_STD_VER >= 11
{
using C = TCT::vector<>;
using T = typename C::value_type;
Index: libcxx/include/memory
===================================================================
--- libcxx/include/memory
+++ libcxx/include/memory
@@ -1459,29 +1459,30 @@
#else // _LIBCPP_CXX03_LANG
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
-template <class _Alloc, class _Pointer, class ..._Args>
-struct __has_construct
- : false_type
-{
-};
-
-#else // _LIBCPP_HAS_NO_VARIADICS
-
-template <class _Alloc, class _Pointer, class _Args>
-struct __has_construct
- : false_type
-{
-};
+template <class _Alloc, class _Pointer, class _Tp, class = void>
+struct __has_construct : std::false_type {};
+
+template <class _Alloc, class _Pointer, class _Tp>
+struct __has_construct<_Alloc, _Pointer, _Tp, typename enable_if<
+ is_same
+ <
+ decltype((_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(),
+ _VSTD::declval<_Tp>()), void())),
+ void
+ >::value
+>::type> : std::true_type {};
-#endif // _LIBCPP_HAS_NO_VARIADICS
+template <class _Alloc, class _Pointer, class = void>
+struct __has_destroy : false_type {};
template <class _Alloc, class _Pointer>
-struct __has_destroy
- : false_type
-{
-};
+struct __has_destroy<_Alloc, _Pointer, typename enable_if<
+ is_same
+ <
+ decltype((_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>()), void())),
+ void
+ >::value
+>::type> : std::true_type {};
template <class _Alloc>
struct __has_max_size
@@ -1570,9 +1571,10 @@
}
template <class _Tp, class _A0>
_LIBCPP_INLINE_VISIBILITY
- static void construct(allocator_type&, _Tp* __p, const _A0& __a0)
+ static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0)
{
- ::new ((void*)__p) _Tp(__a0);
+ __construct(__has_construct<allocator_type, _Tp*, const _A0&>(),
+ __a, __p, __a0);
}
template <class _Tp, class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
@@ -1720,6 +1722,19 @@
{
::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
}
+#else // _LIBCPP_HAS_NO_VARIADICS
+ template <class _Tp, class _A0>
+ _LIBCPP_INLINE_VISIBILITY
+ static void __construct(true_type, allocator_type& __a, _Tp* __p,
+ const _A0& __a0)
+ {__a.construct(__p, __a0);}
+ template <class _Tp, class _A0>
+ _LIBCPP_INLINE_VISIBILITY
+ static void __construct(false_type, allocator_type&, _Tp* __p,
+ const _A0& __a0)
+ {
+ ::new ((void*)__p) _Tp(__a0);
+ }
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp>
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits