This revision was automatically updated to reflect the committed changes. Closed by commit rL349676: [libcxx] Use custom allocator's `construct` in C++03 when available. (authored by vsapsai, committed by ). Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D48753?vs=177803&id=178939#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D48753/new/ https://reviews.llvm.org/D48753 Files: libcxx/trunk/include/memory libcxx/trunk/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp libcxx/trunk/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp libcxx/trunk/test/support/min_allocator.h
Index: libcxx/trunk/test/support/min_allocator.h =================================================================== --- libcxx/trunk/test/support/min_allocator.h +++ libcxx/trunk/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/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp =================================================================== --- libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp +++ libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp @@ -73,7 +73,7 @@ std::aligned_storage<sizeof(VT)>::type store; std::allocator_traits<Alloc>::destroy(a, (VT*)&store); } -#if TEST_STD_VER >= 11 +#if defined(_LIBCPP_VERSION) || TEST_STD_VER >= 11 { A0::count = 0; b_destroy = 0; Index: libcxx/trunk/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp =================================================================== --- libcxx/trunk/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ libcxx/trunk/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <vector> + +// template <class InputIter> vector(InputIter first, InputIter last); + +#include <vector> +#include <cassert> + +#include "min_allocator.h" + +void test_ctor_under_alloc() { + 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); + } + } +} + +int main() { + test_ctor_under_alloc(); +} Index: libcxx/trunk/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp =================================================================== --- libcxx/trunk/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp +++ libcxx/trunk/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <vector> + +// template <class InputIter> vector(InputIter first, InputIter last, +// const allocator_type& a); + +#include <vector> +#include <cassert> + +#include "min_allocator.h" + +void test_ctor_under_alloc() { + 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); + } + } +} + +int main() { + test_ctor_under_alloc(); +} Index: libcxx/trunk/include/memory =================================================================== --- libcxx/trunk/include/memory +++ libcxx/trunk/include/memory @@ -1460,29 +1460,21 @@ #else // _LIBCPP_CXX03_LANG -#ifndef _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 {}; -#else // _LIBCPP_HAS_NO_VARIADICS +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 {}; -template <class _Alloc, class _Pointer, class _Args> -struct __has_construct - : false_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 __void_t< + decltype(_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>())) +>::type> : std::true_type {}; template <class _Alloc> struct __has_max_size @@ -1571,9 +1563,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 @@ -1721,6 +1714,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 cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits