[libcxx] r276544 - Implement P0040r3: Extending memory management tools

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 23 20:51:40 PDT 2016


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>




More information about the cfe-commits mailing list