Author: ericwf Date: Sat Jul 23 22:51:39 2016 New Revision: 276544 URL: http://llvm.org/viewvc/llvm-project?rev=276544&view=rev Log: Implement P0040r3: Extending memory management tools
Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp libcxx/trunk/test/support/test_throw.h Modified: libcxx/trunk/include/memory libcxx/trunk/www/cxx1z_status.html Modified: libcxx/trunk/include/memory URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=276544&r1=276543&r2=276544&view=diff ============================================================================== --- libcxx/trunk/include/memory (original) +++ libcxx/trunk/include/memory Sat Jul 23 22:51:39 2016 @@ -180,6 +180,33 @@ template <class ForwardIterator, class S ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); +template <class T> +void destroy_at(T* location); + +template <class ForwardIterator> + void destroy(ForwardIterator first, ForwardIterator last); + +template <class ForwardIterator, class Size> + ForwardIterator destroy_n(ForwardIterator first, Size n); + +template <class InputIterator, class ForwardIterator> + ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); + +template <class InputIterator, class Size, class ForwardIterator> + pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); + +template <class ForwardIterator> + void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); + +template <class ForwardIterator, class Size> + ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); + +template <class ForwardIterator> + void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); + +template <class ForwardIterator, class Size> + ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); + template <class Y> struct auto_ptr_ref {}; template<class X> @@ -3671,6 +3698,87 @@ uninitialized_fill_n(_ForwardIterator __ return __f; } +#if _LIBCPP_STD_VER > 14 + +template <class _ForwardIterator> +inline _LIBCPP_INLINE_VISIBILITY +void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) { + using _Vt = typename iterator_traits<_ForwardIterator>::value_type; + for (; __first != __last; ++__first) + ::new((void*)_VSTD::addressof(*__first)) _Vt; +} + +template <class _ForwardIterator, class _Size> +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) { + using _Vt = typename iterator_traits<_ForwardIterator>::value_type; + for (; __n > 0; (void)++__first, --__n) + ::new((void*)_VSTD::addressof(*__first)) _Vt; + return __first; +} + + +template <class _ForwardIterator> +inline _LIBCPP_INLINE_VISIBILITY +void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) { + using _Vt = typename iterator_traits<_ForwardIterator>::value_type; + for (; __first != __last; ++__first) + ::new((void*)_VSTD::addressof(*__first)) _Vt(); +} + +template <class _ForwardIterator, class _Size> +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) { + using _Vt = typename iterator_traits<_ForwardIterator>::value_type; + for (; __n > 0; (void)++__first, --__n) + ::new((void*)_VSTD::addressof(*__first)) _Vt(); + return __first; +} + + +template <class _InputIt, class _ForwardIt> +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __res) { + using _Vt = typename iterator_traits<_ForwardIt>::value_type; + for (; __first != __last; (void)++__res, ++__first) + ::new((void*)_VSTD::addressof(*__res)) _Vt(std::move(*__first)); + return __res; +} + +template <class _InputIt, class _Size, class _ForwardIt> +inline _LIBCPP_INLINE_VISIBILITY +pair<_InputIt, _ForwardIt> +uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __res) { + using _Vt = typename iterator_traits<_ForwardIt>::value_type; + for (; __n > 0; ++__res, (void)++__first, --__n) + ::new((void*)_VSTD::addressof(*__res)) _Vt(std::move(*__first)); + return {__first, __res}; +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +void destroy_at(_Tp* __loc) { + _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at"); + __loc->~_Tp(); +} + +template <class _ForwardIterator> +inline _LIBCPP_INLINE_VISIBILITY +void destroy(_ForwardIterator __first, _ForwardIterator __last) { + for (; __first != __last; ++__first) + _VSTD::destroy_at(_VSTD::addressof(*__first)); +} + +template <class _ForwardIterator, class _Size> +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) { + for (; __n > 0; (void)++__first, --__n) + _VSTD::destroy_at(_VSTD::addressof(*__first)); + return __first; +} + +#endif // _LIBCPP_STD_VER > 14 + class _LIBCPP_EXCEPTION_ABI bad_weak_ptr : public std::exception { Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp Sat Jul 23 22:51:39 2016 @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void destroy(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" + +struct Counted { + static int count; + static void reset() { count = 0; } + Counted() { ++count; } + Counted(Counted const&) { ++count; } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; + +int main() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + std::uninitialized_fill(p, p+N, Counted()); + assert(Counted::count == 5); + std::destroy(p, p+1); + p += 1; + assert(Counted::count == 4); + std::destroy(It(p), It(p + 4)); + assert(Counted::count == 0); +} Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp Sat Jul 23 22:51:39 2016 @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class _Tp> +// void destroy_at(_Tp*); + +#include <memory> +#include <cstdlib> +#include <cassert> + +struct Counted { + static int count; + static void reset() { count = 0; } + Counted() { ++count; } + Counted(Counted const&) { ++count; } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; + +struct VCounted { + static int count; + static void reset() { count = 0; } + VCounted() { ++count; } + VCounted(VCounted const&) { ++count; } + virtual ~VCounted() { --count; } + friend void operator&(VCounted) = delete; +}; +int VCounted::count = 0; + +struct DCounted : VCounted { + friend void operator&(DCounted) = delete; +}; + +int main() +{ + { + void* mem1 = std::malloc(sizeof(Counted)); + void* mem2 = std::malloc(sizeof(Counted)); + assert(mem1 && mem2); + assert(Counted::count == 0); + Counted* ptr1 = ::new(mem1) Counted(); + Counted* ptr2 = ::new(mem2) Counted(); + assert(Counted::count == 2); + std::destroy_at(ptr1); + assert(Counted::count == 1); + std::destroy_at(ptr2); + assert(Counted::count == 0); + } + { + void* mem1 = std::malloc(sizeof(DCounted)); + void* mem2 = std::malloc(sizeof(DCounted)); + assert(mem1 && mem2); + assert(DCounted::count == 0); + DCounted* ptr1 = ::new(mem1) DCounted(); + DCounted* ptr2 = ::new(mem2) DCounted(); + assert(DCounted::count == 2); + assert(VCounted::count == 2); + std::destroy_at(ptr1); + assert(VCounted::count == 1); + std::destroy_at(ptr2); + assert(VCounted::count == 0); + } +} Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp Sat Jul 23 22:51:39 2016 @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt, class Size> +// ForwardIt destroy_n(ForwardIt, Size s); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" + +struct Counted { + static int count; + static void reset() { count = 0; } + Counted() { ++count; } + Counted(Counted const&) { ++count; } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; + +int main() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + std::uninitialized_fill(p, p+N, Counted()); + assert(Counted::count == 5); + Counted* np = std::destroy_n(p, 1); + assert(np == p+1); + assert(Counted::count == 4); + p += 1; + It it = std::destroy_n(It(p), 4); + assert(it == It(p+4)); + assert(Counted::count == 0); +} Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp Sat Jul 23 22:51:39 2016 @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void uninitialized_default_construct(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted() { ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; +int Counted::constructed = 0; + + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted() { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_default_construct(It(p), It(p+N)); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + std::uninitialized_default_construct(It(p), It(p+1)); + assert(Counted::count == 1); + assert(Counted::constructed = 1); + std::uninitialized_default_construct(It(p+1), It(p+N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +void test_value_initialized() +{ + using It = forward_iterator<int*>; + const int N = 5; + int pool[N] = {-1, -1, -1, -1, -1}; + int* p = pool; + std::uninitialized_default_construct(It(p), It(p+1)); + assert(pool[0] == -1); + assert(pool[1] == -1); + std::uninitialized_default_construct(It(p+1), It(p+N)); + assert(pool[1] == -1); + assert(pool[2] == -1); + assert(pool[3] == -1); + assert(pool[4] == -1); +} + +int main() +{ + test_counted(); + test_value_initialized(); + test_ctor_throws(); +} Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp Sat Jul 23 22:51:39 2016 @@ -0,0 +1,119 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void uninitialized_default_construct(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted() { ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; +int Counted::constructed = 0; + + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted() { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_default_construct_n(It(p), N); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + It e = std::uninitialized_default_construct_n(It(p), 1); + assert(e == It(p+1)); + assert(Counted::count == 1); + assert(Counted::constructed = 1); + e = std::uninitialized_default_construct_n(It(p+1), 4); + assert(e == It(p+N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +void test_value_initialized() +{ + using It = forward_iterator<int*>; + const int N = 5; + int pool[N] = {-1, -1, -1, -1, -1}; + int* p = pool; + auto e = std::uninitialized_default_construct_n(It(p), 1); + assert(e == It(p+1)); + assert(pool[0] == -1); + assert(pool[1] == -1); + e = std::uninitialized_default_construct_n(It(p+1), 4); + assert(e == It(p+N)); + assert(pool[1] == -1); + assert(pool[2] == -1); + assert(pool[3] == -1); + assert(pool[4] == -1); +} + + +int main() +{ + test_counted(); + test_value_initialized(); + test_ctor_throws(); +} Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp Sat Jul 23 22:51:39 2016 @@ -0,0 +1,114 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void uninitialized_value_construct(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted() { ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; +int Counted::constructed = 0; + + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted() { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_value_construct(It(p), It(p+N)); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + std::uninitialized_value_construct(It(p), It(p+1)); + assert(Counted::count == 1); + assert(Counted::constructed = 1); + std::uninitialized_value_construct(It(p+1), It(p+N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +void test_value_initialized() +{ + using It = forward_iterator<int*>; + const int N = 5; + int pool[N] = {-1, -1, -1, -1, -1}; + int* p = pool; + std::uninitialized_value_construct(It(p), It(p+1)); + assert(pool[0] == 0); + assert(pool[1] == -1); + std::uninitialized_value_construct(It(p+1), It(p+N)); + assert(pool[1] == 0); + assert(pool[2] == 0); + assert(pool[3] == 0); + assert(pool[4] == 0); +} + +int main() +{ + test_counted(); + test_value_initialized(); + test_ctor_throws(); +} Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp Sat Jul 23 22:51:39 2016 @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void uninitialized_value_construct(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted() { ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; +int Counted::constructed = 0; + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted() { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_value_construct_n(It(p), N); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + It e = std::uninitialized_value_construct_n(It(p), 1); + assert(e == It(p+1)); + assert(Counted::count == 1); + assert(Counted::constructed = 1); + e = std::uninitialized_value_construct_n(It(p+1), 4); + assert(e == It(p+N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +void test_value_initialized() +{ + using It = forward_iterator<int*>; + const int N = 5; + int pool[N] = {-1, -1, -1, -1, -1}; + int* p = pool; + It e = std::uninitialized_value_construct_n(It(p), 1); + assert(e == It(p+1)); + assert(pool[0] == 0); + assert(pool[1] == -1); + e = std::uninitialized_value_construct_n(It(p+1), 4); + assert(e == It(p+N)); + assert(pool[1] == 0); + assert(pool[2] == 0); + assert(pool[3] == 0); + assert(pool[4] == 0); +} + +int main() +{ + test_counted(); + test_value_initialized(); +} \ No newline at end of file Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp Sat Jul 23 22:51:39 2016 @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class InputIt, class ForwardIt> +// ForwardIt uninitialized_move(InputIt, InputIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; + int value; +}; +int Counted::count = 0; +int Counted::constructed = 0; + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted(int&& x) { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + x = 0; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + int values[N] = {1, 2, 3, 4, 5}; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_move(values, values + N, It(p)); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + assert(values[0] == 0); + assert(values[1] == 0); + assert(values[2] == 0); + assert(values[3] == 4); + assert(values[4] == 5); + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = input_iterator<int*>; + using FIt = forward_iterator<Counted*>; + const int N = 5; + int values[N] = {1, 2, 3, 4, 5}; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + auto ret = std::uninitialized_move(It(values), It(values + 1), FIt(p)); + assert(ret == FIt(p +1)); + assert(Counted::constructed = 1); + assert(Counted::count == 1); + assert(p[0].value == 1); + assert(values[0] == 0); + ret = std::uninitialized_move(It(values+1), It(values+N), FIt(p+1)); + assert(ret == FIt(p + N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + assert(p[1].value == 2); + assert(p[2].value == 3); + assert(p[3].value == 4); + assert(p[4].value == 5); + assert(values[1] == 0); + assert(values[2] == 0); + assert(values[3] == 0); + assert(values[4] == 0); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +int main() { + test_counted(); + test_ctor_throws(); +} \ No newline at end of file Added: libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp Sat Jul 23 22:51:39 2016 @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class InputIt, class Size, class ForwardIt> +// pair<InputIt, ForwardIt> uninitialized_move_n(InputIt, Size, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; + int value; +}; +int Counted::count = 0; +int Counted::constructed = 0; + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted(int&& x) { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + x = 0; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + int values[N] = {1, 2, 3, 4, 5}; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_move_n(values, N, It(p)); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + assert(values[0] == 0); + assert(values[1] == 0); + assert(values[2] == 0); + assert(values[3] == 4); + assert(values[4] == 5); + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = input_iterator<int*>; + using FIt = forward_iterator<Counted*>; + const int N = 5; + int values[N] = {1, 2, 3, 4, 5}; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + auto ret = std::uninitialized_move_n(It(values), 1, FIt(p)); + assert(ret.first == It(values +1)); + assert(ret.second == FIt(p +1)); + assert(Counted::constructed = 1); + assert(Counted::count == 1); + assert(p[0].value == 1); + assert(values[0] == 0); + ret = std::uninitialized_move_n(It(values+1), N-1, FIt(p+1)); + assert(ret.first == It(values+N)); + assert(ret.second == FIt(p + N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + assert(p[1].value == 2); + assert(p[2].value == 3); + assert(p[3].value == 4); + assert(p[4].value == 5); + assert(values[1] == 0); + assert(values[2] == 0); + assert(values[3] == 0); + assert(values[4] == 0); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +int main() +{ + test_counted(); + test_ctor_throws(); +} \ No newline at end of file Added: libcxx/trunk/test/support/test_throw.h URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/test_throw.h?rev=276544&view=auto ============================================================================== --- libcxx/trunk/test/support/test_throw.h (added) +++ libcxx/trunk/test/support/test_throw.h Sat Jul 23 22:51:39 2016 @@ -0,0 +1,27 @@ +// -*- C++ -*- +//===---------------------------- test_macros.h ---------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#ifndef SUPPORT_TEST_THROW_H +#define SUPPORT_TEST_THROW_H + +#include "test_macros.h" +#include <cstdlib> + +template <class Ex> +TEST_NORETURN +inline void test_throw() { +#ifndef TEST_HAS_NO_EXCEPTIONS + throw Ex(); +#else + std::abort(); +#endif +} + +#endif // SUPPORT_TEST_THROW_H Modified: libcxx/trunk/www/cxx1z_status.html URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=276544&r1=276543&r2=276544&view=diff ============================================================================== --- libcxx/trunk/www/cxx1z_status.html (original) +++ libcxx/trunk/www/cxx1z_status.html Sat Jul 23 22:51:39 2016 @@ -95,7 +95,7 @@ <tr><td><a href="http://wg21.link/P0077R2">P0077R2</a></td><td>LWG</td><td><tt>is_callable</tt>, the missing INVOKE related trait</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> <tr><td><a href="http://wg21.link/p0032r3">p0032r3</a></td><td>LWG</td><td>Homogeneous interface for variant, any and optional</td><td>Oulu</td><td></td><td></td></tr> - <tr><td><a href="http://wg21.link/p0040r3">p0040r3</a></td><td>LWG</td><td>Extending memory management tools</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0040r3">p0040r3</a></td><td>LWG</td><td>Extending memory management tools</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr> <tr><td><a href="http://wg21.link/p0063r3">p0063r3</a></td><td>LWG</td><td>C++17 should refer to C11 instead of C99</td><td>Oulu</td><td></td><td></td></tr> <tr><td><a href="http://wg21.link/p0067r3">p0067r3</a></td><td>LWG</td><td>Elementary string conversions</td><td>Oulu</td><td>Postponed to Issaquah</td><td></td></tr> <tr><td><a href="http://wg21.link/p0083r3">p0083r3</a></td><td>LWG</td><td>Splicing Maps and Sets</td><td>Oulu</td><td></td><td></td></tr> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits