[libcxx] r268829 - Add <experimental/memory_resource>
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Fri May 6 18:04:56 PDT 2016
Author: ericwf
Date: Fri May 6 20:04:55 2016
New Revision: 268829
URL: http://llvm.org/viewvc/llvm-project?rev=268829&view=rev
Log:
Add <experimental/memory_resource>
Reviewers: mclow.lists, EricWF
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D20007
Added:
libcxx/trunk/include/experimental/__memory
libcxx/trunk/include/experimental/memory_resource
libcxx/trunk/src/experimental/memory_resource.cpp
libcxx/trunk/test/libcxx/experimental/memory/
libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/
libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/
libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/db_deallocate.pass.cpp
libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/max_size.pass.cpp
libcxx/trunk/test/libcxx/experimental/memory/memory.resource.adaptor/
libcxx/trunk/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/
libcxx/trunk/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp
libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/
libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.pass.cpp
libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.pass.cpp
libcxx/trunk/test/libcxx/experimental/memory/memory.resource.synop/
libcxx/trunk/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp
libcxx/trunk/test/std/experimental/memory/
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/
libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource.global/
libcxx/trunk/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource.synop/
libcxx/trunk/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/construct.fail.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.overview/
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.priv/
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp
libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp
libcxx/trunk/test/std/experimental/memory/nothing_to_do.pass.cpp
libcxx/trunk/test/support/test_memory_resource.hpp
libcxx/trunk/test/support/type_id.h
libcxx/trunk/test/support/uses_alloc_types.hpp
Removed:
libcxx/trunk/src/experimental/placeholder.cpp
Modified:
libcxx/trunk/include/exception
libcxx/trunk/include/experimental/__config
Modified: libcxx/trunk/include/exception
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/exception?rev=268829&r1=268828&r2=268829&view=diff
==============================================================================
--- libcxx/trunk/include/exception (original)
+++ libcxx/trunk/include/exception Fri May 6 20:04:55 2016
@@ -80,6 +80,10 @@ template <class E> void rethrow_if_neste
#include <__config>
#include <cstddef>
#include <type_traits>
+#if defined(_LIBCPP_HAS_NO_EXCEPTIONS)
+#include <cstdio>
+#include <cstdlib>
+#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -251,4 +255,19 @@ rethrow_if_nested(const _Ep&, typename e
} // std
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Exception>
+_LIBCPP_INLINE_VISIBILITY
+inline void __libcpp_throw(_Exception const& __e) {
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ throw __e;
+#else
+ _VSTD::fprintf(stderr, "%s\n", __e.what());
+ _VSTD::abort();
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
#endif // _LIBCPP_EXCEPTION
Modified: libcxx/trunk/include/experimental/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/__config?rev=268829&r1=268828&r2=268829&view=diff
==============================================================================
--- libcxx/trunk/include/experimental/__config (original)
+++ libcxx/trunk/include/experimental/__config Fri May 6 20:04:55 2016
@@ -25,6 +25,10 @@
#define _LIBCPP_END_NAMESPACE_LFTS } } }
#define _VSTD_LFTS _VSTD_EXPERIMENTAL::fundamentals_v1
+#define _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR _LIBCPP_BEGIN_NAMESPACE_LFTS namespace pmr {
+#define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS }
+#define _VSTD_LFTS_PMR _VSTD_LFTS::pmr
+
#define _LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS _LIBCPP_BEGIN_NAMESPACE_STD \
namespace chrono { namespace experimental { inline namespace fundamentals_v1 {
#define _LIBCPP_END_NAMESPACE_CHRONO_LFTS _LIBCPP_END_NAMESPACE_STD } } }
Added: libcxx/trunk/include/experimental/__memory
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/__memory?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/include/experimental/__memory (added)
+++ libcxx/trunk/include/experimental/__memory Fri May 6 20:04:55 2016
@@ -0,0 +1,90 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _LIBCPP_EXPERIMENTAL___MEMORY
+#define _LIBCPP_EXPERIMENTAL___MEMORY
+
+#include <experimental/__config>
+#include <experimental/utility> // for erased_type
+#include <__functional_base>
+#include <type_traits>
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
+template <
+ class _Tp, class _Alloc
+ , bool = uses_allocator<_Tp, _Alloc>::value
+ , bool = __has_allocator_type<_Tp>::value
+ >
+struct __lfts_uses_allocator : public false_type {};
+
+template <class _Tp, class _Alloc>
+struct __lfts_uses_allocator<_Tp, _Alloc, false, false> : public false_type {};
+
+template <class _Tp, class _Alloc, bool HasAlloc>
+struct __lfts_uses_allocator<_Tp, _Alloc, true, HasAlloc> : public true_type {};
+
+template <class _Tp, class _Alloc>
+struct __lfts_uses_allocator<_Tp, _Alloc, false, true>
+ : public integral_constant<bool
+ , is_convertible<_Alloc, typename _Tp::allocator_type>::value
+ || is_same<erased_type, typename _Tp::allocator_type>::value
+ >
+{};
+
+template <bool _UsesAlloc, class _Tp, class _Alloc, class ..._Args>
+struct __lfts_uses_alloc_ctor_imp
+{
+ static const int value = 0;
+};
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __lfts_uses_alloc_ctor_imp<true, _Tp, _Alloc, _Args...>
+{
+ static const bool __ic_first
+ = is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
+
+ static const bool __ic_second =
+ conditional<
+ __ic_first,
+ false_type,
+ is_constructible<_Tp, _Args..., _Alloc>
+ >::type::value;
+
+ static_assert(__ic_first || __ic_second,
+ "Request for uses allocator construction is ill-formed");
+
+ static const int value = __ic_first ? 1 : 2;
+};
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __lfts_uses_alloc_ctor
+ : integral_constant<int,
+ __lfts_uses_alloc_ctor_imp<
+ __lfts_uses_allocator<_Tp, _Alloc>::value
+ , _Tp, _Alloc, _Args...
+ >::value
+ >
+{};
+
+template <class _Tp, class _Alloc, class ..._Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __lfts_user_alloc_construct(
+ _Tp * __store, const _Alloc & __a, _Args &&... __args)
+{
+ _VSTD::__user_alloc_construct_impl(
+ typename __lfts_uses_alloc_ctor<_Tp, _Alloc, _Args...>::type()
+ , __store, __a, _VSTD::forward<_Args>(__args)...
+ );
+}
+
+_LIBCPP_END_NAMESPACE_LFTS
+
+#endif /* _LIBCPP_EXPERIMENTAL___MEMORY */
Added: libcxx/trunk/include/experimental/memory_resource
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/memory_resource?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/include/experimental/memory_resource (added)
+++ libcxx/trunk/include/experimental/memory_resource Fri May 6 20:04:55 2016
@@ -0,0 +1,422 @@
+// -*- C++ -*-
+//===------------------------ memory_resource -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE
+#define _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE
+
+/**
+ experimental/memory_resource synopsis
+
+// C++1y
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v1 {
+namespace pmr {
+
+ class memory_resource;
+
+ bool operator==(const memory_resource& a,
+ const memory_resource& b) noexcept;
+ bool operator!=(const memory_resource& a,
+ const memory_resource& b) noexcept;
+
+ template <class Tp> class polymorphic_allocator;
+
+ template <class T1, class T2>
+ bool operator==(const polymorphic_allocator<T1>& a,
+ const polymorphic_allocator<T2>& b) noexcept;
+ template <class T1, class T2>
+ bool operator!=(const polymorphic_allocator<T1>& a,
+ const polymorphic_allocator<T2>& b) noexcept;
+
+ // The name resource_adaptor_imp is for exposition only.
+ template <class Allocator> class resource_adaptor_imp;
+
+ template <class Allocator>
+ using resource_adaptor = resource_adaptor_imp<
+ allocator_traits<Allocator>::rebind_alloc<char>>;
+
+ // Global memory resources
+ memory_resource* new_delete_resource() noexcept;
+ memory_resource* null_memory_resource() noexcept;
+
+ // The default memory resource
+ memory_resource* set_default_resource(memory_resource* r) noexcept;
+ memory_resource* get_default_resource() noexcept;
+
+ // Standard memory resources
+ struct pool_options;
+ class synchronized_pool_resource;
+ class unsynchronized_pool_resource;
+ class monotonic_buffer_resource;
+
+} // namespace pmr
+} // namespace fundamentals_v1
+} // namespace experimental
+} // namespace std
+
+ */
+
+#include <experimental/__config>
+#include <experimental/__memory>
+#include <limits>
+#include <memory>
+#include <new>
+#include <stdexcept>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include <cstddef>
+#include <cstdlib>
+#include <__debug>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
+
+// Round __s up to next multiple of __a.
+inline _LIBCPP_INLINE_VISIBILITY
+size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT
+{
+ _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows");
+ return (__s + __a - 1) & ~(__a - 1);
+}
+
+// 8.5, memory.resource
+class _LIBCPP_TYPE_VIS_ONLY memory_resource
+{
+ static const size_t __max_align = alignof(max_align_t);
+
+// 8.5.2, memory.resource.public
+public:
+ virtual ~memory_resource() = default;
+
+ _LIBCPP_INLINE_VISIBILITY
+ void* allocate(size_t __bytes, size_t __align = __max_align)
+ { return do_allocate(__bytes, __align); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ void deallocate(void * __p, size_t __bytes, size_t __align = __max_align)
+ { do_deallocate(__p, __bytes, __align); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool is_equal(memory_resource const & __other) const _NOEXCEPT
+ { return do_is_equal(__other); }
+
+// 8.5.3, memory.resource.priv
+protected:
+ virtual void* do_allocate(size_t, size_t) = 0;
+ virtual void do_deallocate(void*, size_t, size_t) = 0;
+ virtual bool do_is_equal(memory_resource const &) const _NOEXCEPT = 0;
+};
+
+// 8.5.4, memory.resource.eq
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator==(memory_resource const & __lhs,
+ memory_resource const & __rhs) _NOEXCEPT
+{
+ return &__lhs == &__rhs || __lhs.is_equal(__rhs);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(memory_resource const & __lhs,
+ memory_resource const & __rhs) _NOEXCEPT
+{
+ return !(__lhs == __rhs);
+}
+
+_LIBCPP_FUNC_VIS
+memory_resource * new_delete_resource() _NOEXCEPT;
+
+_LIBCPP_FUNC_VIS
+memory_resource * null_memory_resource() _NOEXCEPT;
+
+_LIBCPP_FUNC_VIS
+memory_resource * get_default_resource() _NOEXCEPT;
+
+_LIBCPP_FUNC_VIS
+memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT;
+
+// 8.6, memory.polymorphic.allocator.class
+
+// 8.6.1, memory.polymorphic.allocator.overview
+template <class _ValueType>
+class _LIBCPP_TYPE_VIS_ONLY polymorphic_allocator
+{
+public:
+ typedef _ValueType value_type;
+
+ // 8.6.2, memory.polymorphic.allocator.ctor
+ _LIBCPP_INLINE_VISIBILITY
+ polymorphic_allocator() _NOEXCEPT
+ : __res_(_VSTD_LFTS_PMR::get_default_resource())
+ {}
+
+ _LIBCPP_INLINE_VISIBILITY
+ polymorphic_allocator(memory_resource * __r) _NOEXCEPT
+ : __res_(__r)
+ {}
+
+ polymorphic_allocator(polymorphic_allocator const &) = default;
+
+ template <class _Tp>
+ _LIBCPP_INLINE_VISIBILITY
+ polymorphic_allocator(polymorphic_allocator<_Tp> const & __other) _NOEXCEPT
+ : __res_(__other.resource())
+ {}
+
+ polymorphic_allocator &
+ operator=(polymorphic_allocator const &) = default;
+
+ // 8.6.3, memory.polymorphic.allocator.mem
+ _LIBCPP_INLINE_VISIBILITY
+ _ValueType* allocate(size_t __n) {
+ if (__n > max_size()) {
+ __libcpp_throw(length_error(
+ "std::experimental::pmr::polymorphic_allocator<T>::allocate(size_t n)"
+ " 'n' exceeds maximum supported size"));
+ }
+ return static_cast<_ValueType*>(
+ __res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType))
+ );
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
+ _LIBCPP_ASSERT(__n <= max_size(),
+ "deallocate called for size which exceeds max_size()");
+ __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
+ }
+
+ template <class _Tp, class ..._Ts>
+ _LIBCPP_INLINE_VISIBILITY
+ void construct(_Tp* __p, _Ts &&... __args)
+ {
+ _VSTD_LFTS::__lfts_user_alloc_construct(
+ __p, resource(), _VSTD::forward<_Ts>(__args)...
+ );
+ }
+
+ template <class _T1, class _T2, class ..._Args1, class ..._Args2>
+ _LIBCPP_INLINE_VISIBILITY
+ void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
+ tuple<_Args1...> __x, tuple<_Args2...> __y)
+ {
+ ::new ((void*)__p) pair<_T1, _T2>(piecewise_construct
+ , __transform_tuple(
+ typename __lfts_uses_alloc_ctor<
+ _T1, memory_resource*, _Args1...
+ >::type()
+ , _VSTD::move(__x)
+ , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
+ )
+ , __transform_tuple(
+ typename __lfts_uses_alloc_ctor<
+ _T2, memory_resource*, _Args2...
+ >::type()
+ , _VSTD::move(__y)
+ , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
+ )
+ );
+ }
+
+ template <class _T1, class _T2>
+ _LIBCPP_INLINE_VISIBILITY
+ void construct(pair<_T1, _T2>* __p) {
+ construct(__p, piecewise_construct, tuple<>(), tuple<>());
+ }
+
+ template <class _T1, class _T2, class _Up, class _Vp>
+ _LIBCPP_INLINE_VISIBILITY
+ void construct(pair<_T1, _T2> * __p, _Up && __u, _Vp && __v) {
+ construct(__p, piecewise_construct
+ , _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__u))
+ , _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__v)));
+ }
+
+ template <class _T1, class _T2, class _U1, class _U2>
+ _LIBCPP_INLINE_VISIBILITY
+ void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> const & __pr) {
+ construct(__p, piecewise_construct
+ , _VSTD::forward_as_tuple(__pr.first)
+ , _VSTD::forward_as_tuple(__pr.second));
+ }
+
+ template <class _T1, class _T2, class _U1, class _U2>
+ _LIBCPP_INLINE_VISIBILITY
+ void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> && __pr){
+ construct(__p, piecewise_construct
+ , _VSTD::forward_as_tuple(_VSTD::forward<_U1>(__pr.first))
+ , _VSTD::forward_as_tuple(_VSTD::forward<_U2>(__pr.second)));
+ }
+
+ template <class _Tp>
+ _LIBCPP_INLINE_VISIBILITY
+ void destroy(_Tp * __p) _NOEXCEPT
+ { __p->~_Tp(); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ size_t max_size() const _NOEXCEPT
+ { return numeric_limits<size_t>::max() / sizeof(value_type); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ polymorphic_allocator
+ select_on_container_copy_construction() const _NOEXCEPT
+ { return polymorphic_allocator(); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ memory_resource * resource() const _NOEXCEPT
+ { return __res_; }
+
+private:
+ template <class ..._Args, size_t ..._Idx>
+ _LIBCPP_INLINE_VISIBILITY
+ tuple<_Args&&...>
+ __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
+ __tuple_indices<_Idx...>) const
+ {
+ return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
+ }
+
+ template <class ..._Args, size_t ..._Idx>
+ _LIBCPP_INLINE_VISIBILITY
+ tuple<allocator_arg_t const&, memory_resource*, _Args&&...>
+ __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
+ __tuple_indices<_Idx...>) const
+ {
+ using _Tup = tuple<allocator_arg_t const&, memory_resource*, _Args&&...>;
+ return _Tup(allocator_arg, resource(),
+ _VSTD::get<_Idx>(_VSTD::move(__t))...);
+ }
+
+ template <class ..._Args, size_t ..._Idx>
+ _LIBCPP_INLINE_VISIBILITY
+ tuple<_Args&&..., memory_resource*>
+ __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
+ __tuple_indices<_Idx...>) const
+ {
+ using _Tup = tuple<_Args&&..., memory_resource*>;
+ return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., resource());
+ }
+
+ memory_resource * __res_;
+};
+
+// 8.6.4, memory.polymorphic.allocator.eq
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator==(polymorphic_allocator<_Tp> const & __lhs,
+ polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT
+{
+ return *__lhs.resource() == *__rhs.resource();
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(polymorphic_allocator<_Tp> const & __lhs,
+ polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT
+{
+ return !(__lhs == __rhs);
+}
+
+// 8.7, memory.resource.adaptor
+
+// 8.7.1, memory.resource.adaptor.overview
+template <class _CharAlloc>
+class _LIBCPP_TYPE_VIS_ONLY __resource_adaptor_imp
+ : public memory_resource
+{
+ using _CTraits = allocator_traits<_CharAlloc>;
+ static_assert(is_same<typename _CTraits::value_type, char>::value
+ && is_same<typename _CTraits::pointer, char*>::value
+ && is_same<typename _CTraits::void_pointer, void*>::value, "");
+
+ static const size_t _MaxAlign = alignof(max_align_t);
+
+ using _Alloc = typename _CTraits::template rebind_alloc<
+ typename aligned_storage<_MaxAlign, _MaxAlign>::type
+ >;
+
+ using _ValueType = typename _Alloc::value_type;
+
+ _Alloc __alloc_;
+
+public:
+ typedef _CharAlloc allocator_type;
+
+ __resource_adaptor_imp() = default;
+ __resource_adaptor_imp(__resource_adaptor_imp const &) = default;
+ __resource_adaptor_imp(__resource_adaptor_imp &&) = default;
+
+ // 8.7.2, memory.resource.adaptor.ctor
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __resource_adaptor_imp(allocator_type const & __a)
+ : __alloc_(__a)
+ {}
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __resource_adaptor_imp(allocator_type && __a)
+ : __alloc_(_VSTD::move(__a))
+ {}
+
+ __resource_adaptor_imp &
+ operator=(__resource_adaptor_imp const &) = default;
+
+ _LIBCPP_INLINE_VISIBILITY
+ allocator_type get_allocator() const
+ { return __alloc_; }
+
+// 8.7.3, memory.resource.adaptor.mem
+protected:
+ virtual void * do_allocate(size_t __bytes, size_t)
+ {
+ if (__bytes > __max_size()) {
+ __libcpp_throw(length_error(
+ "std::experimental::pmr::resource_adaptor<T>::do_allocate(size_t bytes, size_t align)"
+ " 'bytes' exceeds maximum supported size"));
+ }
+ size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign;
+ return __alloc_.allocate(__s);
+ }
+
+ virtual void do_deallocate(void * __p, size_t __bytes, size_t)
+ {
+ _LIBCPP_ASSERT(__bytes <= __max_size(),
+ "do_deallocate called for size which exceeds the maximum allocation size");
+ size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign;
+ __alloc_.deallocate((_ValueType*)__p, __s);
+ }
+
+ virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT {
+ __resource_adaptor_imp const * __p
+ = dynamic_cast<__resource_adaptor_imp const *>(&__other);
+ return __p ? __alloc_ == __p->__alloc_ : false;
+ }
+
+private:
+ _LIBCPP_INLINE_VISIBILITY
+ size_t __max_size() const _NOEXCEPT {
+ return numeric_limits<size_t>::max() - _MaxAlign;
+ }
+};
+
+template <class _Alloc>
+using resource_adaptor = __resource_adaptor_imp<
+ typename allocator_traits<_Alloc>::template rebind_alloc<char>
+ >;
+
+_LIBCPP_END_NAMESPACE_LFTS_PMR
+
+#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */
Added: libcxx/trunk/src/experimental/memory_resource.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/experimental/memory_resource.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/src/experimental/memory_resource.cpp (added)
+++ libcxx/trunk/src/experimental/memory_resource.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,129 @@
+//===------------------------ memory_resource.cpp -------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "experimental/memory_resource"
+
+#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
+#include "atomic"
+#else
+#include "mutex"
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
+
+// memory_resource
+
+//memory_resource::~memory_resource() {}
+
+// new_delete_resource()
+
+class _LIBCPP_TYPE_VIS_ONLY __new_delete_memory_resource_imp
+ : public memory_resource
+{
+public:
+ ~__new_delete_memory_resource_imp() = default;
+
+protected:
+ virtual void* do_allocate(size_t __size, size_t __align)
+ { return __allocate(__size); }
+
+ virtual void do_deallocate(void * __p, size_t, size_t)
+ { __deallocate(__p); }
+
+ virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
+ { return &__other == this; }
+};
+
+// null_memory_resource()
+
+class _LIBCPP_TYPE_VIS_ONLY __null_memory_resource_imp
+ : public memory_resource
+{
+public:
+ ~__null_memory_resource_imp() = default;
+
+protected:
+ virtual void* do_allocate(size_t, size_t) {
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ abort();
+#endif
+ }
+ virtual void do_deallocate(void *, size_t, size_t) {}
+ virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
+ { return &__other == this; }
+};
+
+union ResourceInitHelper {
+ struct {
+ __new_delete_memory_resource_imp new_delete_res;
+ __null_memory_resource_imp null_res;
+ } resources;
+ char dummy;
+ _LIBCPP_CONSTEXPR_AFTER_CXX11 ResourceInitHelper() : resources() {}
+ ~ResourceInitHelper() {}
+};
+// When compiled in C++14 this initialization should be a constant expression.
+// Only in C++11 is "init_priority" needed to ensure initialization order.
+ResourceInitHelper res_init __attribute__((init_priority (101)));
+
+memory_resource * new_delete_resource() _NOEXCEPT {
+ return &res_init.resources.new_delete_res;
+}
+
+memory_resource * null_memory_resource() _NOEXCEPT {
+ return &res_init.resources.null_res;
+}
+
+// default_memory_resource()
+
+static memory_resource *
+__default_memory_resource(bool set = false, memory_resource * new_res = nullptr) _NOEXCEPT
+{
+#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
+ static atomic<memory_resource*> __res =
+ ATOMIC_VAR_INIT(&res_init.resources.new_delete_res);
+ if (set) {
+ new_res = new_res ? new_res : new_delete_resource();
+ // TODO: Can a weaker ordering be used?
+ return _VSTD::atomic_exchange_explicit(
+ &__res, new_res, memory_order::memory_order_acq_rel);
+ }
+ else {
+ return _VSTD::atomic_load_explicit(
+ &__res, memory_order::memory_order_acquire);
+ }
+#else
+ static memory_resource * res = &res_init.resources.new_delete_res;
+ static mutex res_lock;
+ if (set) {
+ new_res = new_res ? new_res : new_delete_resource();
+ lock_guard<mutex> guard(res_lock);
+ memory_resource * old_res = res;
+ res = new_res;
+ return old_res;
+ } else {
+ lock_guard<mutex> guard(res_lock);
+ return res;
+ }
+#endif
+}
+
+memory_resource * get_default_resource() _NOEXCEPT
+{
+ return __default_memory_resource();
+}
+
+memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT
+{
+ return __default_memory_resource(true, __new_res);
+}
+
+_LIBCPP_END_NAMESPACE_LFTS_PMR
\ No newline at end of file
Removed: libcxx/trunk/src/experimental/placeholder.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/experimental/placeholder.cpp?rev=268828&view=auto
==============================================================================
--- libcxx/trunk/src/experimental/placeholder.cpp (original)
+++ libcxx/trunk/src/experimental/placeholder.cpp (removed)
@@ -1,14 +0,0 @@
-//===--------------------------- TODO.cpp ---------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-#include "experimental/__config"
-
-_LIBCPP_BEGIN_NAMESPACE_LFTS
-
-_LIBCPP_END_NAMESPACE_LFTS
Added: libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,178 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U1, class U2, class ...Args1, class ...Args2>
+// void polymorphic_allocator<T>::construct(pair<T1, T2>*, piecewise_construct_t
+// tuple<Args1...> x, tuple<Args2...>)
+
+// The stardard specifiers a tranformation to uses-allocator construction as
+// follows:
+// - If uses_allocator_v<T1,memory_resource*> is false and
+// is_constructible_v<T,Args1...> is true, then xprime is x.
+// - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and
+// is_constructible_v<T1,allocator_arg_t,memory_resource*,Args1...> is true,
+// then xprime is
+// tuple_cat(make_tuple(allocator_arg, this->resource()), std::move(x)).
+// - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and
+// is_constructible_v<T1,Args1...,memory_resource*> is true, then xprime is
+// tuple_cat(std::move(x), make_tuple(this->resource())).
+// - Otherwise the program is ill formed.
+//
+// The use of "xprime = tuple_cat(..., std::move(x), ...)" causes all of the
+// objects in 'x' to be copied into 'xprime'. If 'x' contains any types which
+// are stored by value this causes an unessary copy to occur. To prevent this
+// libc++ changes this call into
+// "xprime = forward_as_tuple(..., std::get<Idx>(std::move(x))..., ...)".
+// 'xprime' contains references to the values in 'x' instead of copying them.
+
+// This test checks the number of copies incurred to the elements in
+// 'tuple<Args1...>' and 'tuple<Args2...>'.
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+template <class T>
+struct TestHarness {
+ TestResource R;
+ ex::memory_resource * M = &R;
+ ex::polymorphic_allocator<T> A = M;
+ bool constructed = false;
+ T * ptr;
+
+ TestHarness() : ptr(A.allocate(1)) {}
+
+ template <class ...Args>
+ void construct(Args&&... args) {
+ A.construct(ptr, std::forward<Args>(args)...);
+ constructed = true;
+ }
+
+ ~TestHarness() {
+ if (constructed) A.destroy(ptr);
+ A.deallocate(ptr, 1);
+ }
+};
+
+struct CountCopies {
+ int count;
+ CountCopies() : count(0) {}
+ CountCopies(CountCopies const& o) : count(o.count + 1) {}
+};
+
+struct CountCopiesAllocV1 {
+ typedef ex::memory_resource* allocator_type;
+ allocator_type alloc;
+ int count;
+ CountCopiesAllocV1() : alloc(nullptr), count(0) {}
+ CountCopiesAllocV1(std::allocator_arg_t, allocator_type const& a,
+ CountCopiesAllocV1 const& o) : alloc(a), count(o.count + 1)
+ {}
+
+ CountCopiesAllocV1(CountCopiesAllocV1 const& o) : count(o.count + 1) {}
+};
+
+
+struct CountCopiesAllocV2 {
+ typedef ex::memory_resource* allocator_type;
+ allocator_type alloc;
+ int count;
+ CountCopiesAllocV2() : alloc(nullptr), count(0) {}
+ CountCopiesAllocV2(CountCopiesAllocV2 const& o, allocator_type const& a)
+ : alloc(a), count(o.count + 1)
+ { }
+
+ CountCopiesAllocV2(CountCopiesAllocV2 const& o) : count(o.count + 1) {}
+};
+
+
+int main()
+{
+ using PMR = ex::memory_resource*;
+ using PMA = ex::polymorphic_allocator<char>;
+
+ {
+ using T = CountCopies;
+ using U = CountCopiesAllocV1;
+ using P = std::pair<T, U>;
+ using TH = TestHarness<P>;
+
+ std::tuple<T> t1;
+ std::tuple<U> t2;
+
+ TestHarness<P> h;
+ h.construct(std::piecewise_construct, t1, t2);
+ P const& p = *h.ptr;
+ assert(p.first.count == 2);
+ assert(p.second.count == 2);
+ assert(p.second.alloc == h.M);
+ }
+ {
+ using T = CountCopiesAllocV1;
+ using U = CountCopiesAllocV2;
+ using P = std::pair<T, U>;
+ using TH = TestHarness<P>;
+
+ std::tuple<T> t1;
+ std::tuple<U> t2;
+
+ TestHarness<P> h;
+ h.construct(std::piecewise_construct, std::move(t1), std::move(t2));
+ P const& p = *h.ptr;
+ assert(p.first.count == 2);
+ assert(p.first.alloc == h.M);
+ assert(p.second.count == 2);
+ assert(p.second.alloc == h.M);
+ }
+ {
+ using T = CountCopiesAllocV2;
+ using U = CountCopiesAllocV1;
+ using P = std::pair<T, U>;
+ using TH = TestHarness<P>;
+
+ std::tuple<T> t1;
+ std::tuple<U> t2;
+
+ TestHarness<P> h;
+ h.construct(std::piecewise_construct, std::move(t1), std::move(t2));
+ P const& p = *h.ptr;
+ assert(p.first.count == 2);
+ assert(p.first.alloc == h.M);
+ assert(p.second.count == 2);
+ assert(p.second.alloc == h.M);
+ }
+ {
+ using T = CountCopiesAllocV2;
+ using U = CountCopies;
+ using P = std::pair<T, U>;
+ using TH = TestHarness<P>;
+
+ std::tuple<T> t1;
+ std::tuple<U> t2;
+
+ TestHarness<P> h;
+ h.construct(std::piecewise_construct, t1, t2);
+ P const& p = *h.ptr;
+ assert(p.first.count == 2);
+ assert(p.first.alloc == h.M);
+ assert(p.second.count == 2);
+ }
+}
Added: libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/db_deallocate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/db_deallocate.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/db_deallocate.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/db_deallocate.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// T* polymorphic_allocator<T>::deallocate(T*, size_t size)
+
+int AssertCount = 0;
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (void)::AssertCount++)
+#define _LIBCPP_DEBUG 0
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ using Alloc = ex::polymorphic_allocator<int>;
+ using Traits = std::allocator_traits<Alloc>;
+ NullResource R;
+ Alloc a(&R);
+ const std::size_t maxSize = Traits::max_size(a);
+
+ a.deallocate(nullptr, maxSize);
+ assert(AssertCount == 0);
+ a.deallocate(nullptr, maxSize + 1);
+ assert(AssertCount == 1);
+}
Added: libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/max_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/max_size.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/max_size.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/max_size.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// EXTENSION
+// std::size_t polymorphic_allocator<T>::max_size() const noexcept
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+template <std::size_t S>
+std::size_t getMaxSize() {
+ using T = typename std::aligned_storage<S>::type;
+ static_assert(sizeof(T) == S, "Required for test");
+ return ex::polymorphic_allocator<T>{}.max_size();
+}
+
+template <std::size_t S, std::size_t A>
+std::size_t getMaxSize() {
+ using T = typename std::aligned_storage<S, A>::type;
+ static_assert(sizeof(T) == S, "Required for test");
+ return ex::polymorphic_allocator<T>{}.max_size();
+}
+
+int main()
+{
+ {
+ using Alloc = ex::polymorphic_allocator<int>;
+ using Traits = std::allocator_traits<Alloc>;
+ const Alloc a;
+ static_assert(std::is_same<decltype(a.max_size()), Traits::size_type>::value, "");
+ static_assert(noexcept(a.max_size()), "");
+ }
+ {
+ constexpr std::size_t Max = std::numeric_limits<std::size_t>::max();
+ assert(getMaxSize<1>() == Max);
+ assert(getMaxSize<2>() == Max / 2);
+ assert(getMaxSize<4>() == Max / 4);
+ assert(getMaxSize<8>() == Max / 8);
+ assert(getMaxSize<16>() == Max / 16);
+ assert(getMaxSize<32>() == Max / 32);
+ assert(getMaxSize<64>() == Max / 64);
+ assert(getMaxSize<1024>() == Max / 1024);
+
+ assert((getMaxSize<6, 2>() == Max / 6));
+ assert((getMaxSize<12, 4>() == Max / 12));
+ }
+}
Added: libcxx/trunk/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// T* polymorphic_allocator<T>::deallocate(T*, size_t size)
+
+int AssertCount = 0;
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (void)::AssertCount++)
+#define _LIBCPP_DEBUG 0
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ using Alloc = NullAllocator<char>;
+ using R = ex::resource_adaptor<Alloc>;
+ AllocController P;
+ ex::resource_adaptor<Alloc> r(Alloc{P});
+ ex::memory_resource & m1 = r;
+
+ std::size_t maxSize = std::numeric_limits<std::size_t>::max()
+ - alignof(std::max_align_t);
+
+ m1.deallocate(nullptr, maxSize);
+ assert(AssertCount == 0);
+ m1.deallocate(nullptr, maxSize + 1);
+ assert(AssertCount >= 1);
+}
Added: libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// memory_resource * new_delete_resource()
+
+// The lifetime of the value returned by 'new_delete_resource()' should
+// never end, even very late into program termination. This test constructs
+// attempts to use 'new_delete_resource()' very late in program termination
+// to detect lifetime issues.
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+namespace ex = std::experimental::pmr;
+
+struct POSType {
+ ex::memory_resource* res = nullptr;
+ void* ptr = nullptr;
+ int n = 0;
+ POSType() {}
+ POSType(ex::memory_resource* r, void* p, int s) : res(r), ptr(p), n(s) {}
+ ~POSType() {
+ if (ptr) {
+ if (!res) res = ex::get_default_resource();
+ res->deallocate(ptr, n);
+ }
+ }
+};
+
+void swap(POSType & L, POSType & R) {
+ std::swap(L.res, R.res);
+ std::swap(L.ptr, R.ptr);
+ std::swap(L.n, R.n);
+}
+
+POSType constructed_before_resources;
+POSType constructed_before_resources2;
+
+// Constructs resources
+ex::memory_resource* resource = ex::get_default_resource();
+
+POSType constructed_after_resources(resource, resource->allocate(1024), 1024);
+POSType constructed_after_resources2(nullptr, resource->allocate(1024), 1024);
+
+int main()
+{
+ swap(constructed_after_resources, constructed_before_resources);
+ swap(constructed_before_resources2, constructed_after_resources2);
+}
Added: libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// memory_resource * new_delete_resource()
+
+// The lifetime of the value returned by 'new_delete_resource()' should
+// never end, even very late into program termination. This test constructs
+// attempts to use 'new_delete_resource()' very late in program termination
+// to detect lifetime issues.
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+namespace ex = std::experimental::pmr;
+
+struct POSType {
+ ex::memory_resource* res = nullptr;
+ void* ptr = nullptr;
+ int n = 0;
+ POSType() {res = ex::new_delete_resource(); ptr = res->allocate(42); n = 42; }
+ POSType(ex::memory_resource* r, void* p, int s) : res(r), ptr(p), n(s) {}
+ ~POSType() { if (ptr) res->deallocate(ptr, n); }
+};
+
+void swap(POSType & L, POSType & R) {
+ std::swap(L.res, R.res);
+ std::swap(L.ptr, R.ptr);
+ std::swap(L.n, R.n);
+}
+
+POSType constructed_before_resources;
+
+// Constructs resources
+ex::memory_resource* resource = ex::new_delete_resource();
+
+POSType constructed_after_resources(resource, resource->allocate(1024), 1024);
+
+int main()
+{
+ swap(constructed_after_resources, constructed_before_resources);
+}
Added: libcxx/trunk/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+#include <experimental/memory_resource>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator operator=(polymorphic_allocator const &) = delete
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef ex::polymorphic_allocator<void> T;
+ static_assert(std::is_copy_assignable<T>::value, "");
+ static_assert(std::is_move_assignable<T>::value, "");
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator const &);
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef ex::polymorphic_allocator<void> A1;
+ {
+ static_assert(
+ std::is_copy_constructible<A1>::value, ""
+ );
+ static_assert(
+ std::is_move_constructible<A1>::value, ""
+ );
+ }
+ // copy
+ {
+ A1 const a((ex::memory_resource*)42);
+ A1 const a2(a);
+ assert(a.resource() == a2.resource());
+ }
+ // move
+ {
+ A1 a((ex::memory_resource*)42);
+ A1 a2(std::move(a));
+ assert(a.resource() == a2.resource());
+ assert(a2.resource() == (ex::memory_resource*)42);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator<T>::polymorphic_allocator() noexcept
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ {
+ static_assert(
+ std::is_nothrow_default_constructible<ex::polymorphic_allocator<void>>::value
+ , "Must me nothrow default constructible"
+ );
+ }
+ {
+ // test that the allocator gets its resource from get_default_resource
+ TestResource R1(42);
+ ex::set_default_resource(&R1);
+
+ typedef ex::polymorphic_allocator<void> A;
+ A const a;
+ assert(a.resource() == &R1);
+
+ ex::set_default_resource(nullptr);
+ A const a2;
+ assert(a.resource() == &R1);
+ assert(a2.resource() == ex::new_delete_resource());
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator<T>::polymorphic_allocator(memory_resource *)
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ {
+ typedef ex::polymorphic_allocator<void> A;
+ static_assert(
+ std::is_convertible<decltype(nullptr), A>::value
+ , "Must be convertible"
+ );
+ static_assert(
+ std::is_convertible<ex::memory_resource *, A>::value
+ , "Must be convertible"
+ );
+ }
+ {
+ typedef ex::polymorphic_allocator<void> A;
+ TestResource R;
+ A const a(&R);
+ assert(a.resource() == &R);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp Fri May 6 20:04:55 2016
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U>
+// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator<U> const &);
+
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef ex::polymorphic_allocator<void> A1;
+ typedef ex::polymorphic_allocator<char> A2;
+ { // Test that the conversion is implicit and noexcept.
+ static_assert(
+ std::is_convertible<A1 const &, A2>::value, ""
+ );
+ static_assert(
+ std::is_convertible<A2 const &, A1>::value, ""
+ );
+ static_assert(
+ std::is_nothrow_constructible<A1, A2 const &>::value, ""
+ );
+ static_assert(
+ std::is_nothrow_constructible<A2, A1 const &>::value, ""
+ );
+ }
+ // copy other type
+ {
+ A1 const a((ex::memory_resource*)42);
+ A2 const a2(a);
+ assert(a.resource() == a2.resource());
+ assert(a2.resource() == (ex::memory_resource*)42);
+ }
+ {
+ A1 a((ex::memory_resource*)42);
+ A2 const a2(std::move(a));
+ assert(a.resource() == a2.resource());
+ assert(a2.resource() == (ex::memory_resource*)42);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator;
+
+// template <class T, class U>
+// bool operator==(
+// polymorphic_allocator<T> const &
+// , polymorphic_allocator<U> const &) noexcept
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef ex::polymorphic_allocator<void> A1;
+ typedef ex::polymorphic_allocator<int> A2;
+ // check return types
+ {
+ A1 const a1;
+ A2 const a2;
+ static_assert(std::is_same<decltype(a1 == a2), bool>::value, "");
+ static_assert(noexcept(a1 == a2), "");
+ }
+ // equal same type (different resource)
+ {
+ TestResource d1(1);
+ TestResource d2(1);
+ A1 const a1(&d1);
+ A1 const a2(&d2);
+
+ assert(a1 == a2);
+ assert(d1.checkIsEqualCalledEq(1));
+ assert(d2.checkIsEqualCalledEq(0));
+
+ d1.reset();
+
+ assert(a2 == a1);
+ assert(d1.checkIsEqualCalledEq(0));
+ assert(d2.checkIsEqualCalledEq(1));
+ }
+ // equal same type (same resource)
+ {
+ TestResource d1;
+ A1 const a1(&d1);
+ A1 const a2(&d1);
+
+ assert(a1 == a2);
+ assert(d1.checkIsEqualCalledEq(0));
+
+ assert(a2 == a1);
+ assert(d1.checkIsEqualCalledEq(0));
+ }
+ // equal different type (different resource)
+ {
+ TestResource d1(42);
+ TestResource d2(42);
+ A1 const a1(&d1);
+ A2 const a2(&d2);
+
+ assert(a1 == a2);
+ assert(d1.checkIsEqualCalledEq(1));
+ assert(d2.checkIsEqualCalledEq(0));
+
+ assert(a2 == a1);
+ assert(d1.checkIsEqualCalledEq(1));
+ assert(d2.checkIsEqualCalledEq(1));
+
+ }
+ // equal different type (same resource)
+ {
+ TestResource d1(42);
+ A1 const a1(&d1);
+ A2 const a2(&d1);
+
+ assert(a1 == a2);
+ assert(d1.checkIsEqualCalledEq(0));
+
+ assert(a2 == a1);
+ assert(d1.checkIsEqualCalledEq(0));
+
+ }
+ // not equal same type
+ {
+ TestResource d1(1);
+ TestResource d2(2);
+ A1 const a1(&d1);
+ A1 const a2(&d2);
+
+ assert(!(a1 == a2));
+ assert(d1.checkIsEqualCalledEq(1));
+ assert(d2.checkIsEqualCalledEq(0));
+
+ d1.reset();
+
+ assert(!(a2 == a1));
+ assert(d1.checkIsEqualCalledEq(0));
+ assert(d2.checkIsEqualCalledEq(1));
+
+ }
+ // not equal different types
+ {
+ TestResource d1;
+ TestResource1 d2;
+ A1 const a1(&d1);
+ A2 const a2(&d2);
+
+ assert(!(a1 == a2));
+ assert(d1.checkIsEqualCalledEq(1));
+ assert(d2.checkIsEqualCalledEq(0));
+
+ d1.reset();
+
+ assert(!(a2 == a1));
+ assert(d1.checkIsEqualCalledEq(0));
+ assert(d2.checkIsEqualCalledEq(1));
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator;
+
+// template <class T>
+// bool operator!=(
+// polymorphic_allocator<T> const &
+// , polymorphic_allocator<T> const &) noexcept
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef ex::polymorphic_allocator<void> A1;
+ typedef ex::polymorphic_allocator<int> A2;
+ // check return types
+ {
+ A1 const a1;
+ A2 const a2;
+ static_assert(std::is_same<decltype(a1 != a2), bool>::value, "");
+ static_assert(noexcept(a1 != a2), "");
+ }
+ // not equal same type (different resource)
+ {
+ TestResource d1(1);
+ TestResource d2(2);
+ A1 const a1(&d1);
+ A1 const a2(&d2);
+
+ assert(a1 != a2);
+ assert(d1.checkIsEqualCalledEq(1));
+ assert(d2.checkIsEqualCalledEq(0));
+
+ d1.reset();
+
+ assert(a2 != a1);
+ assert(d1.checkIsEqualCalledEq(0));
+ assert(d2.checkIsEqualCalledEq(1));
+ }
+ // equal same type (same resource)
+ {
+ TestResource d1;
+ A1 const a1(&d1);
+ A1 const a2(&d1);
+
+ assert(!(a1 != a2));
+ assert(d1.checkIsEqualCalledEq(0));
+
+ assert(!(a2 != a1));
+ assert(d1.checkIsEqualCalledEq(0));
+ }
+ // equal same type
+ {
+ TestResource d1(1);
+ TestResource d2(1);
+ A1 const a1(&d1);
+ A1 const a2(&d2);
+
+ assert(!(a1 != a2));
+ assert(d1.checkIsEqualCalledEq(1));
+ assert(d2.checkIsEqualCalledEq(0));
+
+ d1.reset();
+
+ assert(!(a2 != a1));
+ assert(d1.checkIsEqualCalledEq(0));
+ assert(d2.checkIsEqualCalledEq(1));
+
+ }
+ // not equal different types
+ {
+ TestResource d1;
+ TestResource1 d2;
+ A1 const a1(&d1);
+ A2 const a2(&d2);
+
+ assert(a1 != a2);
+ assert(d1.checkIsEqualCalledEq(1));
+ assert(d2.checkIsEqualCalledEq(0));
+
+ d1.reset();
+
+ assert(a2 != a1);
+ assert(d1.checkIsEqualCalledEq(0));
+ assert(d2.checkIsEqualCalledEq(1));
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// T* polymorphic_allocator<T>::allocate(size_t n)
+
+#include <experimental/memory_resource>
+#include <limits>
+#include <memory>
+#include <exception>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+template <size_t S, size_t Align>
+void testForSizeAndAlign() {
+ using T = typename std::aligned_storage<S, Align>::type;
+ TestResource R;
+ ex::polymorphic_allocator<T> a(&R);
+
+ for (int N = 1; N <= 5; ++N) {
+ auto ret = a.allocate(N);
+ assert(R.checkAlloc(ret, N * sizeof(T), alignof(T)));
+
+ a.deallocate(ret, N);
+ R.reset();
+ }
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+template <size_t S>
+void testAllocForSizeThrows() {
+ using T = typename std::aligned_storage<S>::type;
+ using Alloc = ex::polymorphic_allocator<T>;
+ using Traits = std::allocator_traits<Alloc>;
+ NullResource R;
+ Alloc a(&R);
+
+ // Test that allocating exactly the max size does not throw.
+ size_t maxSize = Traits::max_size(a);
+ try {
+ a.allocate(maxSize);
+ } catch (...) {
+ assert(false);
+ }
+
+ size_t sizeTypeMax = std::numeric_limits<std::size_t>::max();
+ if (maxSize != sizeTypeMax)
+ {
+ // Test that allocating size_t(~0) throws bad alloc.
+ try {
+ a.allocate(sizeTypeMax);
+ assert(false);
+ } catch (std::exception const&) {
+ }
+
+ // Test that allocating even one more than the max size does throw.
+ size_t overSize = maxSize + 1;
+ try {
+ a.allocate(overSize);
+ assert(false);
+ } catch (std::exception const&) {
+ }
+ }
+}
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+int main()
+{
+ {
+ ex::polymorphic_allocator<int> a;
+ static_assert(std::is_same<decltype(a.allocate(0)), int*>::value, "");
+ static_assert(!noexcept(a.allocate(0)), "");
+ }
+ {
+ constexpr std::size_t MA = alignof(std::max_align_t);
+ testForSizeAndAlign<1, 1>();
+ testForSizeAndAlign<1, 2>();
+ testForSizeAndAlign<1, MA>();
+ testForSizeAndAlign<2, 2>();
+ testForSizeAndAlign<73, alignof(void*)>();
+ testForSizeAndAlign<73, MA>();
+ testForSizeAndAlign<13, MA>();
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ testAllocForSizeThrows<1>();
+ testAllocForSizeThrows<2>();
+ testAllocForSizeThrows<4>();
+ testAllocForSizeThrows<8>();
+ testAllocForSizeThrows<16>();
+ testAllocForSizeThrows<73>();
+ testAllocForSizeThrows<13>();
+ }
+#endif
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U1, class U2>
+// void polymorphic_allocator<T>::construct(pair<U1, U2>*)
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int constructed = 0;
+
+struct default_constructible
+{
+ default_constructible() : x(42) { ++constructed; }
+ int x{0};
+};
+
+int main()
+{
+ // pair<default_constructible, default_constructible> as T()
+ {
+ typedef default_constructible T;
+ typedef std::pair<T, T> P;
+ typedef ex::polymorphic_allocator<void> A;
+ P * ptr = (P*)std::malloc(sizeof(P));
+ A a;
+ a.construct(ptr);
+ assert(constructed == 2);
+ assert(ptr->first.x == 42);
+ assert(ptr->second.x == 42);
+ std::free(ptr);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class P1, class P2, class U1, class U2>
+// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> const&)
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+
+namespace ex = std::experimental::pmr;
+
+
+template <class UA1, class UA2, class TT, class UU>
+bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect,
+ std::pair<TT, UU> const& p)
+{
+ using P = std::pair<UA1, UA2>;
+ TestResource R;
+ ex::memory_resource * M = &R;
+ ex::polymorphic_allocator<P> A(M);
+ P * ptr = (P*)std::malloc(sizeof(P));
+ P * ptr2 = (P*)std::malloc(sizeof(P));
+
+ // UNDER TEST //
+ A.construct(ptr, p);
+
+ A.construct(ptr2, std::piecewise_construct,
+ std::forward_as_tuple(p.first),
+ std::forward_as_tuple(p.second));
+ // ------- //
+
+ bool tres = checkConstruct<decltype((p.first))>(ptr->first, TExpect, M) &&
+ checkConstructionEquiv(ptr->first, ptr2->first);
+
+ bool ures = checkConstruct<decltype((p.second))>(ptr->second, UExpect, M) &&
+ checkConstructionEquiv(ptr->second, ptr2->second);
+
+ A.destroy(ptr);
+ std::free(ptr);
+ A.destroy(ptr2);
+ std::free(ptr2);
+ return tres && ures;
+
+}
+
+template <class Alloc, class TT, class UU>
+void test_pmr_uses_allocator(std::pair<TT, UU> const& p)
+{
+ {
+ using T = NotUsesAllocator<Alloc, 1>;
+ using U = NotUsesAllocator<Alloc, 1>;
+ assert((doTest<T, U>(UA_None, UA_None, p)));
+ }
+ {
+ using T = UsesAllocatorV1<Alloc, 1>;
+ using U = UsesAllocatorV2<Alloc, 1>;
+ assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, p)));
+ }
+ {
+ using T = UsesAllocatorV2<Alloc, 1>;
+ using U = UsesAllocatorV3<Alloc, 1>;
+ assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, p)));
+ }
+ {
+ using T = UsesAllocatorV3<Alloc, 1>;
+ using U = NotUsesAllocator<Alloc, 1>;
+ assert((doTest<T, U>(UA_AllocArg, UA_None, p)));
+ }
+}
+template <class Tp>
+struct Print;
+
+int main()
+{
+ using ERT = std::experimental::erased_type;
+ using PMR = ex::memory_resource*;
+ using PMA = ex::polymorphic_allocator<char>;
+ {
+ int x = 42;
+ int y = 42;
+ const std::pair<int, int&> p(x, y);
+ test_pmr_uses_allocator<ERT>(p);
+ test_pmr_uses_allocator<PMR>(p);
+ test_pmr_uses_allocator<PMA>(p);
+ }
+ {
+ int x = 42;
+ int y = 42;
+ const std::pair<int&, int&&> p(x, std::move(y));
+ test_pmr_uses_allocator<ERT>(p);
+ test_pmr_uses_allocator<PMR>(p);
+ test_pmr_uses_allocator<PMA>(p);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class P1, class P2, class U1, class U2>
+// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> &&)
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+
+namespace ex = std::experimental::pmr;
+
+
+
+template <class UA1, class UA2, class TT, class UU>
+bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect,
+ std::pair<TT, UU>&& p)
+{
+ using P = std::pair<UA1, UA2>;
+ TestResource R;
+ ex::memory_resource * M = &R;
+ ex::polymorphic_allocator<P> A(M);
+ P * ptr = A.allocate(2);
+ P * ptr2 = ptr + 1;
+
+ // UNDER TEST //
+ A.construct(ptr, std::move(p));
+
+ A.construct(ptr2, std::piecewise_construct,
+ std::forward_as_tuple(std::forward<TT>(p.first)),
+ std::forward_as_tuple(std::forward<UU>(p.second)));
+ // ------- //
+
+ bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) &&
+ checkConstructionEquiv(ptr->first, ptr2->first);
+
+ bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) &&
+ checkConstructionEquiv(ptr->second, ptr2->second);
+
+ A.destroy(ptr);
+ A.destroy(ptr2);
+ A.deallocate(ptr, 2);
+ return tres && ures;
+}
+
+template <class Alloc, class TT, class UU>
+void test_pmr_uses_allocator(std::pair<TT, UU>&& p)
+{
+ {
+ using T = NotUsesAllocator<Alloc, 1>;
+ using U = NotUsesAllocator<Alloc, 1>;
+ assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
+ }
+ {
+ using T = UsesAllocatorV1<Alloc, 1>;
+ using U = UsesAllocatorV2<Alloc, 1>;
+ assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, std::move(p))));
+ }
+ {
+ using T = UsesAllocatorV2<Alloc, 1>;
+ using U = UsesAllocatorV3<Alloc, 1>;
+ assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, std::move(p))));
+ }
+ {
+ using T = UsesAllocatorV3<Alloc, 1>;
+ using U = NotUsesAllocator<Alloc, 1>;
+ assert((doTest<T, U>(UA_AllocArg, UA_None, std::move(p))));
+ }
+}
+
+int main()
+{
+ using ERT = std::experimental::erased_type;
+ using PMR = ex::memory_resource*;
+ using PMA = ex::polymorphic_allocator<char>;
+ {
+ int x = 42;
+ int y = 42;
+ std::pair<int&, int&&> p(x, std::move(y));
+ test_pmr_uses_allocator<ERT>(std::move(p));
+ test_pmr_uses_allocator<PMR>(std::move(p));
+ test_pmr_uses_allocator<PMA>(std::move(p));
+ }
+ {
+ int x = 42;
+ int y = 42;
+ std::pair<int&&, int&> p(std::move(x), y);
+ test_pmr_uses_allocator<ERT>(std::move(p));
+ test_pmr_uses_allocator<PMR>(std::move(p));
+ test_pmr_uses_allocator<PMA>(std::move(p));
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class P1, class P2, class U1, class U2>
+// void polymorphic_allocator<T>::construct(pair<P1, P2>*, U1&&, U2&&)
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+
+namespace ex = std::experimental::pmr;
+
+
+template <class UA1, class UA2, class TT, class UU>
+bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect,
+ TT&& t, UU&& u)
+{
+ using P = std::pair<UA1, UA2>;
+ TestResource R;
+ ex::memory_resource * M = &R;
+ ex::polymorphic_allocator<P> A(M);
+ P * ptr = (P*)std::malloc(sizeof(P));
+ P * ptr2 = (P*)std::malloc(sizeof(P));
+
+ // UNDER TEST //
+ A.construct(ptr, std::forward<TT>(t), std::forward<UU>(u));
+ A.construct(ptr2, std::piecewise_construct,
+ std::forward_as_tuple(std::forward<TT>(t)),
+ std::forward_as_tuple(std::forward<UU>(u)));
+ // ------- //
+
+ bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) &&
+ checkConstructionEquiv(ptr->first, ptr2->first);
+
+ bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) &&
+ checkConstructionEquiv(ptr->second, ptr2->second);
+
+ A.destroy(ptr);
+ A.destroy(ptr2);
+ std::free(ptr);
+ std::free(ptr2);
+ return tres && ures;
+}
+
+template <class Alloc, class TT, class UU>
+void test_pmr_uses_allocator(TT&& t, UU&& u)
+{
+ {
+ using T = NotUsesAllocator<Alloc, 1>;
+ using U = NotUsesAllocator<Alloc, 1>;
+ assert((doTest<T, U>(UA_None, UA_None,
+ std::forward<TT>(t), std::forward<UU>(u))));
+ }
+ {
+ using T = UsesAllocatorV1<Alloc, 1>;
+ using U = UsesAllocatorV2<Alloc, 1>;
+ assert((doTest<T, U>(UA_AllocArg, UA_AllocLast,
+ std::forward<TT>(t), std::forward<UU>(u))));
+ }
+ {
+ using T = UsesAllocatorV2<Alloc, 1>;
+ using U = UsesAllocatorV3<Alloc, 1>;
+ assert((doTest<T, U>(UA_AllocLast, UA_AllocArg,
+ std::forward<TT>(t), std::forward<UU>(u))));
+ }
+ {
+ using T = UsesAllocatorV3<Alloc, 1>;
+ using U = NotUsesAllocator<Alloc, 1>;
+ assert((doTest<T, U>(UA_AllocArg, UA_None,
+ std::forward<TT>(t), std::forward<UU>(u))));
+ }
+}
+
+int main()
+{
+ using ERT = std::experimental::erased_type;
+ using PMR = ex::memory_resource*;
+ using PMA = ex::polymorphic_allocator<char>;
+ {
+ int x = 42;
+ int y = 42;
+ test_pmr_uses_allocator<ERT>(x, std::move(y));
+ test_pmr_uses_allocator<PMR>(x, std::move(y));
+ test_pmr_uses_allocator<PMA>(x, std::move(y));
+ }
+ {
+ int x = 42;
+ const int y = 42;
+ test_pmr_uses_allocator<ERT>(std::move(x), y);
+ test_pmr_uses_allocator<PMR>(std::move(x), y);
+ test_pmr_uses_allocator<PMA>(std::move(x), y);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,129 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U1, class U2, class ...Args1, class ...Args2>
+// void polymorphic_allocator<T>::construct(pair<U1, U2>*, piecewise_construct_t
+// tuple<Args1...>, tuple<Args2...>)
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "test_allocator.h"
+
+namespace ex = std::experimental::pmr;
+
+template <class T, class U, class ...TTuple, class ...UTuple>
+bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect,
+ std::tuple<TTuple...> ttuple, std::tuple<UTuple...> utuple)
+{
+ using P = std::pair<T, U>;
+ TestResource R;
+ ex::memory_resource * M = &R;
+ ex::polymorphic_allocator<P> A(M);
+ P * ptr = A.allocate(1);
+
+ // UNDER TEST //
+ A.construct(ptr, std::piecewise_construct, std::move(ttuple), std::move(utuple));
+ // ------- //
+ bool tres = checkConstruct<TTuple&&...>(ptr->first, TExpect, M);
+ bool ures = checkConstruct<UTuple&&...>(ptr->second, UExpect, M);
+
+ A.destroy(ptr);
+ A.deallocate(ptr, 1);
+ return tres && ures;
+}
+
+template <class Alloc, class ...TTypes, class ...UTypes>
+void test_pmr_uses_allocator(std::tuple<TTypes...> ttuple, std::tuple<UTypes...> utuple)
+{
+ {
+ using T = NotUsesAllocator<Alloc, sizeof...(TTypes)>;
+ using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>;
+ assert((doTest<T, U>(UA_None, UA_None,
+ std::move(ttuple), std::move(utuple))));
+ }
+ {
+ using T = UsesAllocatorV1<Alloc, sizeof...(TTypes)>;
+ using U = UsesAllocatorV2<Alloc, sizeof...(UTypes)>;
+ assert((doTest<T, U>(UA_AllocArg, UA_AllocLast,
+ std::move(ttuple), std::move(utuple))));
+ }
+ {
+ using T = UsesAllocatorV2<Alloc, sizeof...(TTypes)>;
+ using U = UsesAllocatorV3<Alloc, sizeof...(UTypes)>;
+ assert((doTest<T, U>(UA_AllocLast, UA_AllocArg,
+ std::move(ttuple), std::move(utuple))));
+ }
+ {
+ using T = UsesAllocatorV3<Alloc, sizeof...(TTypes)>;
+ using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>;
+ assert((doTest<T, U>(UA_AllocArg, UA_None,
+ std::move(ttuple), std::move(utuple))));
+ }
+}
+
+int main()
+{
+ using ERT = std::experimental::erased_type;
+ using PMR = ex::memory_resource*;
+ using PMA = ex::polymorphic_allocator<char>;
+ {
+ std::tuple<> t1;
+ test_pmr_uses_allocator<ERT>(t1, t1);
+ test_pmr_uses_allocator<PMR>(t1, t1);
+ test_pmr_uses_allocator<PMA>(t1, t1);
+ }
+ {
+ std::tuple<int> t1(42);
+ std::tuple<> t2;
+ test_pmr_uses_allocator<ERT>(t1, t2);
+ test_pmr_uses_allocator<ERT>(t2, t1);
+ test_pmr_uses_allocator<PMR>(t1, t2);
+ test_pmr_uses_allocator<PMR>(t2, t1);
+ test_pmr_uses_allocator<PMA>(t1, t2);
+ test_pmr_uses_allocator<PMA>(t2, t1);
+ }
+ {
+ std::tuple<int> t1(42);
+ int x = 55;
+ double dx = 42.42;
+ std::tuple<int&, double&&> t2(x, std::move(dx));
+ test_pmr_uses_allocator<ERT>( t1, std::move(t2));
+ test_pmr_uses_allocator<ERT>(std::move(t2), t1);
+ test_pmr_uses_allocator<PMR>( t1, std::move(t2));
+ test_pmr_uses_allocator<PMR>(std::move(t2), t1);
+ test_pmr_uses_allocator<PMA>( t1, std::move(t2));
+ test_pmr_uses_allocator<PMA>(std::move(t2), t1);
+ }
+ {
+ void* xptr = nullptr;
+ long y = 4242;
+ std::tuple<int, long const&, void*&> t1(42, y, xptr);
+ int x = 55;
+ double dx = 42.42;
+ const char* s = "hello World";
+ std::tuple<int&, double&&, const char*> t2(x, std::move(dx), s);
+ test_pmr_uses_allocator<ERT>( t1, std::move(t2));
+ test_pmr_uses_allocator<ERT>(std::move(t2), t1);
+ test_pmr_uses_allocator<PMR>( t1, std::move(t2));
+ test_pmr_uses_allocator<PMR>(std::move(t2), t1);
+ test_pmr_uses_allocator<PMA>( t1, std::move(t2));
+ test_pmr_uses_allocator<PMA>(std::move(t2), t1);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,189 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U, class ...Args>
+// void polymorphic_allocator<T>::construct(U *, Args &&...)
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "test_allocator.h"
+
+namespace ex = std::experimental::pmr;
+
+template <class T>
+struct PMATest {
+ TestResource R;
+ ex::polymorphic_allocator<T> A;
+ T* ptr;
+ bool constructed;
+
+ PMATest() : A(&R), ptr(A.allocate(1)), constructed(false) {}
+
+ template <class ...Args>
+ void construct(Args&&... args) {
+ A.construct(ptr, std::forward<Args>(args)...);
+ constructed = true;
+ }
+
+ ~PMATest() {
+ if (constructed) A.destroy(ptr);
+ A.deallocate(ptr, 1);
+ }
+};
+
+template <class T, class ...Args>
+bool doTest(UsesAllocatorType UAExpect, Args&&... args)
+{
+ PMATest<T> TH;
+ // UNDER TEST //
+ TH.construct(std::forward<Args>(args)...);
+ return checkConstruct<Args&&...>(*TH.ptr, UAExpect, &TH.R);
+ // ------- //
+}
+
+
+template <class T, class ...Args>
+bool doTestUsesAllocV0(Args&&... args)
+{
+ PMATest<T> TH;
+ // UNDER TEST //
+ TH.construct(std::forward<Args>(args)...);
+ return checkConstruct<Args&&...>(*TH.ptr, UA_None);
+ // -------- //
+}
+
+
+template <class T, class EAlloc, class ...Args>
+bool doTestUsesAllocV1(EAlloc const& ealloc, Args&&... args)
+{
+ PMATest<T> TH;
+ // UNDER TEST //
+ TH.construct(std::allocator_arg, ealloc, std::forward<Args>(args)...);
+ return checkConstruct<Args&&...>(*TH.ptr, UA_AllocArg, ealloc);
+ // -------- //
+}
+
+template <class T, class EAlloc, class ...Args>
+bool doTestUsesAllocV2(EAlloc const& ealloc, Args&&... args)
+{
+ PMATest<T> TH;
+ // UNDER TEST //
+ TH.construct(std::forward<Args>(args)..., ealloc);
+ return checkConstruct<Args&&...>(*TH.ptr, UA_AllocLast, ealloc);
+ // -------- //
+}
+
+template <class Alloc, class ...Args>
+void test_pmr_uses_alloc(Args&&... args)
+{
+ TestResource R(12435);
+ ex::memory_resource* M = &R;
+ {
+ // NotUsesAllocator provides valid signatures for each uses-allocator
+ // construction but does not supply the required allocator_type typedef.
+ // Test that we can call these constructors manually without
+ // polymorphic_allocator interfering.
+ using T = NotUsesAllocator<Alloc, sizeof...(Args)>;
+ assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+ assert((doTestUsesAllocV1<T>(M, std::forward<Args>(args)...)));
+ assert((doTestUsesAllocV2<T>(M, std::forward<Args>(args)...)));
+ }
+ {
+ // Test T(std::allocator_arg_t, Alloc const&, Args...) construction
+ using T = UsesAllocatorV1<Alloc, sizeof...(Args)>;
+ assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...)));
+ }
+ {
+ // Test T(Args..., Alloc const&) construction
+ using T = UsesAllocatorV2<Alloc, sizeof...(Args)>;
+ assert((doTest<T>(UA_AllocLast, std::forward<Args>(args)...)));
+ }
+ {
+ // Test that T(std::allocator_arg_t, Alloc const&, Args...) construction
+ // is prefered when T(Args..., Alloc const&) is also available.
+ using T = UsesAllocatorV3<Alloc, sizeof...(Args)>;
+ assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...)));
+ }
+}
+
+// Test that polymorphic_allocator does not prevent us from manually
+// doing non-pmr uses-allocator construction.
+template <class Alloc, class AllocObj, class ...Args>
+void test_non_pmr_uses_alloc(AllocObj const& A, Args&&... args)
+{
+ {
+ using T = NotUsesAllocator<Alloc, sizeof...(Args)>;
+ assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+ assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...)));
+ assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...)));
+ }
+ {
+ using T = UsesAllocatorV1<Alloc, sizeof...(Args)>;
+ assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+ assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...)));
+ }
+ {
+ using T = UsesAllocatorV2<Alloc, sizeof...(Args)>;
+ assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+ assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...)));
+ }
+ {
+ using T = UsesAllocatorV3<Alloc, sizeof...(Args)>;
+ assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+ assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...)));
+ assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...)));
+ }
+}
+
+int main()
+{
+ using ET = std::experimental::erased_type;
+ using PMR = ex::memory_resource*;
+ using PMA = ex::polymorphic_allocator<void>;
+ using STDA = std::allocator<char>;
+ using TESTA = test_allocator<char>;
+
+ int value = 42;
+ const int cvalue = 43;
+ {
+ test_pmr_uses_alloc<ET>();
+ test_pmr_uses_alloc<PMR>();
+ test_pmr_uses_alloc<PMA>();
+ test_pmr_uses_alloc<ET>(value);
+ test_pmr_uses_alloc<PMR>(value);
+ test_pmr_uses_alloc<PMA>(value);
+ test_pmr_uses_alloc<ET>(cvalue);
+ test_pmr_uses_alloc<PMR>(cvalue);
+ test_pmr_uses_alloc<PMA>(cvalue);
+ test_pmr_uses_alloc<ET>(cvalue, std::move(value));
+ test_pmr_uses_alloc<PMR>(cvalue, std::move(value));
+ test_pmr_uses_alloc<PMA>(cvalue, std::move(value));
+ }
+ {
+ STDA std_alloc;
+ TESTA test_alloc(42);
+ test_non_pmr_uses_alloc<STDA>(std_alloc);
+ test_non_pmr_uses_alloc<TESTA>(test_alloc);
+ test_non_pmr_uses_alloc<STDA>(std_alloc, value);
+ test_non_pmr_uses_alloc<TESTA>(test_alloc, value);
+ test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue);
+ test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue);
+ test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue, std::move(value));
+ test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue, std::move(value));
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// T* polymorphic_allocator<T>::deallocate(T*, size_t size)
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+template <size_t S, size_t Align>
+void testForSizeAndAlign() {
+ using T = typename std::aligned_storage<S, Align>::type;
+
+ TestResource R;
+ ex::polymorphic_allocator<T> a(&R);
+
+ for (int N = 1; N <= 5; ++N) {
+ auto ret = a.allocate(N);
+ assert(R.checkAlloc(ret, N * sizeof(T), alignof(T)));
+
+ a.deallocate(ret, N);
+ assert(R.checkDealloc(ret, N * sizeof(T), alignof(T)));
+
+ R.reset();
+ }
+}
+
+int main()
+{
+ {
+ ex::polymorphic_allocator<int> a;
+ static_assert(
+ std::is_same<decltype(a.deallocate(nullptr, 0)), void>::value, "");
+ }
+ {
+ constexpr std::size_t MA = alignof(std::max_align_t);
+ testForSizeAndAlign<1, 1>();
+ testForSizeAndAlign<1, 2>();
+ testForSizeAndAlign<1, MA>();
+ testForSizeAndAlign<2, 2>();
+ testForSizeAndAlign<73, alignof(void*)>();
+ testForSizeAndAlign<73, MA>();
+ testForSizeAndAlign<13, MA>();
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U>
+// void polymorphic_allocator<T>::destroy(U * ptr);
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <new>
+#include <cassert>
+#include <cstdlib>
+
+namespace ex = std::experimental::pmr;
+
+int count = 0;
+
+struct destroyable
+{
+ destroyable() { ++count; }
+ ~destroyable() { --count; }
+};
+
+int main()
+{
+ typedef ex::polymorphic_allocator<double> A;
+ {
+ A a;
+ static_assert(
+ std::is_same<decltype(a.destroy((destroyable*)nullptr)), void>::value,
+ "");
+ }
+ {
+ destroyable * ptr = ::new (std::malloc(sizeof(destroyable))) destroyable();
+ assert(count == 1);
+ A{}.destroy(ptr);
+ assert(count == 0);
+ std::free(ptr);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// memory_resource *
+// polymorphic_allocator<T>::resource() const
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef ex::polymorphic_allocator<void> A;
+ {
+ A const a;
+ static_assert(
+ std::is_same<decltype(a.resource()), ex::memory_resource*>::value
+ , ""
+ );
+ }
+ {
+ ex::memory_resource * mptr = (ex::memory_resource*)42;
+ A const a(mptr);
+ assert(a.resource() == mptr);
+ }
+ {
+ A const a(nullptr);
+ assert(a.resource() == nullptr);
+ assert(a.resource() == nullptr);
+ }
+ {
+ A const a;
+ assert(a.resource() == ex::get_default_resource());
+ }
+ {
+ ex::memory_resource * mptr = (ex::memory_resource*)42;
+ ex::set_default_resource(mptr);
+ A const a;
+ assert(a.resource() == mptr);
+ assert(a.resource() == ex::get_default_resource());
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator
+// polymorphic_allocator<T>::select_on_container_copy_construction() const
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef ex::polymorphic_allocator<void> A;
+ {
+ A const a;
+ static_assert(
+ std::is_same<decltype(a.select_on_container_copy_construction()), A>::value,
+ "");
+ }
+ {
+ ex::memory_resource * mptr = (ex::memory_resource*)42;
+ A const a(mptr);
+ assert(a.resource() == mptr);
+ A const other = a.select_on_container_copy_construction();
+ assert(other.resource() == ex::get_default_resource());
+ assert(a.resource() == mptr);
+ }
+ {
+ ex::memory_resource * mptr = (ex::memory_resource*)42;
+ ex::set_default_resource(mptr);
+ A const a(nullptr);
+ assert(a.resource() == nullptr);
+ A const other = a.select_on_container_copy_construction();
+ assert(other.resource() == ex::get_default_resource());
+ assert(other.resource() == mptr);
+ assert(a.resource() == nullptr);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,10 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main () {}
Added: libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,10 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main () {}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class Alloc> class resource_adaptor_imp;
+
+// resource_adaptor_imp<Alloc>::resource_adaptor_imp(Alloc const &)
+
+#include <experimental/memory_resource>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef CountingAllocator<char> AllocT;
+ typedef ex::resource_adaptor<AllocT> R;
+ {
+ AllocController P;
+ AllocT const a(P);
+ R const r(a);
+ assert(P.copy_constructed == 1);
+ assert(P.move_constructed == 0);
+ assert(r.get_allocator() == a);
+ }
+ {
+ AllocController P;
+ AllocT a(P);
+ R const r(a);
+ assert(P.copy_constructed == 1);
+ assert(P.move_constructed == 0);
+ assert(r.get_allocator() == a);
+ }
+ {
+ AllocController P;
+ AllocT const a(P);
+ R const r(std::move(a));
+ assert(P.copy_constructed == 1);
+ assert(P.move_constructed == 0);
+ assert(r.get_allocator() == a);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class Alloc> class resource_adaptor_imp;
+
+// resource_adaptor_imp<Alloc>::resource_adaptor_imp(Alloc &&)
+
+#include <experimental/memory_resource>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef CountingAllocator<char> AllocT;
+ typedef ex::resource_adaptor<AllocT> R;
+ {
+ AllocController P;
+ AllocT a(P);
+ R const r(std::move(a));
+ assert(P.copy_constructed == 0);
+ assert(P.move_constructed == 1);
+ assert(r.get_allocator() == a);
+ }
+ {
+ AllocController P;
+ R const r(AllocT{P});
+ assert(P.copy_constructed == 0);
+ assert(P.move_constructed == 1);
+ assert(r.get_allocator() == AllocT{P});
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class Alloc> class resource_adaptor_imp;
+
+// resource_adaptor_imp<Alloc>::resource_adaptor_imp() = default;
+
+#include <experimental/memory_resource>
+#include <memory>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ {
+ typedef CountingAllocator<char> AllocT; // Not default constructible
+ typedef ex::resource_adaptor<AllocT> R;
+ static_assert(!std::is_default_constructible<R>::value, "");
+ }
+ {
+ typedef std::allocator<char> AllocT; // Is default constructible
+ typedef ex::resource_adaptor<AllocT> R;
+ static_assert(std::is_default_constructible<R>::value, "");
+ R r; ((void)r);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp Fri May 6 20:04:55 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
+
+// <experimental/memory_resource>
+
+// template <class Alloc> class resource_adaptor_imp;
+
+// void * do_allocate(size_t size, size_t align)
+// void do_deallocate(void*, size_t, size_t)
+
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <memory>
+#include <exception>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+template <class Alloc>
+void check_allocate_deallocate()
+{
+ typedef ex::resource_adaptor<Alloc> R1;
+ const std::size_t max_align = alignof(std::max_align_t);
+
+ for (std::size_t s = 0; s < 5012; ++s)
+ {
+ for(std::size_t align_req = 1; align_req <= (max_align * 2); align_req *= 2)
+ {
+ const std::size_t align_exp = align_req > max_align
+ ? max_align : align_req;
+ AllocController P;
+ R1 r{Alloc(P)};
+ ex::memory_resource & m1 = r;
+
+ void * const ret = m1.allocate(s, align_req);
+ assert(P.alive == 1);
+ assert(P.alloc_count == 1);
+ assert(P.checkAllocAtLeast(ret, s, align_exp));
+
+ assert(((std::size_t)ret % align_exp) == 0);
+
+ m1.deallocate(ret, s, align_req);
+ assert(P.alive == 0);
+ assert(P.dealloc_count == 1);
+ assert(P.checkDeallocMatchesAlloc());
+ }
+ }
+}
+
+void check_alloc_max_size() {
+ using Alloc = NullAllocator<char>;
+ using R1 = ex::resource_adaptor<Alloc>;
+ const std::size_t max_align = alignof(std::max_align_t);
+
+ auto check = [=](std::size_t s, std::size_t align_req) {
+ const std::size_t align_exp = align_req > max_align
+ ? max_align : align_req;
+ AllocController P;
+ R1 r{Alloc(P)};
+ ex::memory_resource & m1 = r;
+
+ void * const ret = m1.allocate(s, align_req);
+ assert(P.alive == 1);
+ assert(P.alloc_count == 1);
+ assert(P.checkAllocAtLeast(ret, s, align_exp));
+
+ m1.deallocate(ret, s, align_req);
+ assert(P.alive == 0);
+ assert(P.dealloc_count == 1);
+ assert(P.checkDeallocMatchesAlloc());
+ };
+
+ const std::size_t sizeTypeMax = ~0;
+ const std::size_t testSizeStart = sizeTypeMax - (max_align * 3);
+ const std::size_t testSizeEnd = sizeTypeMax - max_align;
+
+ for (std::size_t size = testSizeStart; size <= testSizeEnd; ++size) {
+ for (std::size_t align=1; align <= (max_align * 2); align *= 2) {
+ check(size, align);
+ }
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ for (std::size_t size = sizeTypeMax; size > testSizeEnd; --size) {
+ AllocController P;
+ R1 r{Alloc(P)};
+ ex::memory_resource & m1 = r;
+
+ try {
+ m1.allocate(size);
+ assert(false);
+ } catch (std::exception const&) {
+ }
+ }
+#endif
+}
+
+int main()
+{
+ check_allocate_deallocate<CountingAllocator<char>>();
+ check_allocate_deallocate<MinAlignedAllocator<char>>();
+ check_alloc_max_size();
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class Alloc> class resource_adaptor_imp;
+
+// bool do_is_equal(memory_resource const &) const noexcept;
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <memory>
+#include <cassert>
+#include "test_memory_resource.hpp"
+
+using std::size_t;
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+
+ typedef CountingAllocator<char> Alloc1;
+ typedef CountingAllocator<int> RAlloc1;
+ typedef ex::resource_adaptor<Alloc1> R1;
+ typedef ex::resource_adaptor<RAlloc1> RR1;
+ static_assert(std::is_same<R1, RR1>::value, "");
+
+ typedef std::allocator<char> Alloc2;
+ typedef ex::resource_adaptor<Alloc2> R2;
+ static_assert(!std::is_same<R1, R2>::value, "");
+
+ // equal same type
+ {
+ AllocController C;
+ Alloc1 a1(C);
+ R1 const r1(a1);
+ ex::memory_resource const & m1 = r1;
+
+ Alloc1 a2(C);
+ R1 const r2(a2);
+ ex::memory_resource const & m2 = r2;
+
+ assert(m1.is_equal(m2));
+ assert(m2.is_equal(m1));
+ }
+ // not equal same type
+ {
+ AllocController C;
+ Alloc1 a1(C);
+ R1 const r1(a1);
+ ex::memory_resource const & m1 = r1;
+
+ AllocController C2;
+ Alloc1 a2(C2);
+ R1 const r2(a2);
+ ex::memory_resource const & m2 = r2;
+
+ assert(!m1.is_equal(m2));
+ assert(!m2.is_equal(m1));
+ }
+ // different allocator types
+ {
+ AllocController C;
+ Alloc1 a1(C);
+ R1 const r1(a1);
+ ex::memory_resource const & m1 = r1;
+
+ Alloc2 a2;
+ R2 const r2(a2);
+ ex::memory_resource const & m2 = r2;
+
+ assert(!m1.is_equal(m2));
+ assert(!m2.is_equal(m1));
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// template <class Alloc> class resource_adaptor_imp;
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <memory>
+#include <cassert>
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ typedef ex::resource_adaptor<std::allocator<void>> R;
+ typedef ex::resource_adaptor<std::allocator<long>> R2;
+ static_assert(std::is_same<R, R2>::value, "");
+ {
+ static_assert(std::is_base_of<ex::memory_resource, R>::value, "");
+ static_assert(std::is_same<R::allocator_type, std::allocator<char>>::value, "");
+ }
+ {
+ static_assert(std::is_default_constructible<R>::value, "");
+ static_assert(std::is_copy_constructible<R>::value, "");
+ static_assert(std::is_move_constructible<R>::value, "");
+ static_assert(std::is_copy_assignable<R>::value, "");
+ static_assert(std::is_move_assignable<R>::value, "");
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+//-----------------------------------------------------------------------------
+// TESTING memory_resource * get_default_resource() noexcept;
+// memory_resource * set_default_resource(memory_resource*) noexcept;
+//
+// Concerns:
+// A) 'get_default_resource()' returns a non-null memory_resource pointer.
+// B) 'get_default_resource()' returns the value set by the last call to
+// 'set_default_resource(...)' and 'new_delete_resource()' if no call
+// to 'set_default_resource(...)' has occurred.
+// C) 'set_default_resource(...)' returns the previous value of the default
+// resource.
+// D) 'set_default_resource(T* p)' for a non-null 'p' sets the default resource
+// to be 'p'.
+// E) 'set_default_resource(null)' sets the default resource to
+// 'new_delete_resource()'.
+// F) 'get_default_resource' and 'set_default_resource' are noexcept.
+
+
+#include <experimental/memory_resource>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+using namespace std::experimental::pmr;
+
+int main() {
+ TestResource R;
+ { // Test (A) and (B)
+ memory_resource* p = get_default_resource();
+ assert(p != nullptr);
+ assert(p == new_delete_resource());
+ assert(p == get_default_resource());
+ }
+ { // Test (C) and (D)
+ memory_resource *expect = &R;
+ memory_resource *old = set_default_resource(expect);
+ assert(old != nullptr);
+ assert(old == new_delete_resource());
+
+ memory_resource *p = get_default_resource();
+ assert(p != nullptr);
+ assert(p == expect);
+ assert(p == get_default_resource());
+ }
+ { // Test (E)
+ memory_resource* old = set_default_resource(nullptr);
+ assert(old == &R);
+ memory_resource* p = get_default_resource();
+ assert(p != nullptr);
+ assert(p == new_delete_resource());
+ assert(p == get_default_resource());
+ }
+ { // Test (F)
+ static_assert(noexcept(get_default_resource()),
+ "get_default_resource() must be noexcept");
+
+ static_assert(noexcept(set_default_resource(nullptr)),
+ "set_default_resource() must be noexcept");
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// memory_resource * new_delete_resource()
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "count_new.hpp"
+
+namespace ex = std::experimental::pmr;
+
+struct assert_on_compare : public ex::memory_resource
+{
+protected:
+ virtual void * do_allocate(size_t, size_t)
+ { assert(false); }
+
+ virtual void do_deallocate(void *, size_t, size_t)
+ { assert(false); }
+
+ virtual bool do_is_equal(ex::memory_resource const &) const noexcept
+ { assert(false); }
+};
+
+void test_return()
+{
+ {
+ static_assert(std::is_same<
+ decltype(ex::new_delete_resource()), ex::memory_resource*
+ >::value, "");
+ }
+ // assert not null
+ {
+ assert(ex::new_delete_resource());
+ }
+ // assert same return value
+ {
+ assert(ex::new_delete_resource() == ex::new_delete_resource());
+ }
+}
+
+void test_equality()
+{
+ // Same object
+ {
+ ex::memory_resource & r1 = *ex::new_delete_resource();
+ ex::memory_resource & r2 = *ex::new_delete_resource();
+ // check both calls returned the same object
+ assert(&r1 == &r2);
+ // check for proper equality semantics
+ assert(r1 == r2);
+ assert(r2 == r1);
+ assert(!(r1 != r2));
+ assert(!(r2 != r1));
+ }
+ // Different types
+ {
+ ex::memory_resource & r1 = *ex::new_delete_resource();
+ assert_on_compare c;
+ ex::memory_resource & r2 = c;
+ assert(r1 != r2);
+ assert(!(r1 == r2));
+ }
+}
+
+void test_allocate_deallocate()
+{
+ ex::memory_resource & r1 = *ex::new_delete_resource();
+
+ globalMemCounter.reset();
+
+ void *ret = r1.allocate(50);
+ assert(ret);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(globalMemCounter.checkLastNewSizeEq(50));
+
+ r1.deallocate(ret, 1);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(globalMemCounter.checkDeleteCalledEq(1));
+
+}
+
+int main()
+{
+ static_assert(noexcept(ex::new_delete_resource()), "Must be noexcept");
+ test_return();
+ test_equality();
+ test_allocate_deallocate();
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp Fri May 6 20:04:55 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
+
+// <experimental/memory_resource>
+
+// memory_resource * null_memory_resource()
+
+#include <experimental/memory_resource>
+#include <new>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+
+namespace ex = std::experimental::pmr;
+
+struct assert_on_compare : public ex::memory_resource
+{
+protected:
+ virtual void * do_allocate(size_t, size_t)
+ { assert(false); }
+
+ virtual void do_deallocate(void *, size_t, size_t)
+ { assert(false); }
+
+ virtual bool do_is_equal(ex::memory_resource const &) const noexcept
+ { assert(false); }
+};
+
+void test_return()
+{
+ {
+ static_assert(std::is_same<
+ decltype(ex::null_memory_resource()), ex::memory_resource*
+ >::value, "");
+ }
+ // Test that the returned value is not null
+ {
+ assert(ex::null_memory_resource());
+ }
+ // Test the same value is returned by repeated calls.
+ {
+ assert(ex::null_memory_resource() == ex::null_memory_resource());
+ }
+}
+
+void test_equality()
+{
+ // Same object
+ {
+ ex::memory_resource & r1 = *ex::null_memory_resource();
+ ex::memory_resource & r2 = *ex::null_memory_resource();
+ // check both calls returned the same object
+ assert(&r1 == &r2);
+ // check for proper equality semantics
+ assert(r1 == r2);
+ assert(r2 == r1);
+ assert(!(r1 != r2));
+ assert(!(r2 != r1));
+ // check the is_equal method
+ assert(r1.is_equal(r2));
+ assert(r2.is_equal(r1));
+ }
+ // Different types
+ {
+ ex::memory_resource & r1 = *ex::null_memory_resource();
+ assert_on_compare c;
+ ex::memory_resource & r2 = c;
+ assert(r1 != r2);
+ assert(!(r1 == r2));
+ assert(!r1.is_equal(r2));
+ }
+}
+
+void test_allocate()
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ DisableAllocationGuard g; // null_memory_resource shouldn't allocate.
+ try {
+ ex::null_memory_resource()->allocate(1);
+ assert(false);
+ } catch (std::bad_alloc const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+#endif
+}
+
+void test_deallocate()
+{
+ globalMemCounter.reset();
+
+ int x = 42;
+ ex::null_memory_resource()->deallocate(nullptr, 0);
+ ex::null_memory_resource()->deallocate(&x, 0);
+
+ assert(globalMemCounter.checkDeleteCalledEq(0));
+ assert(globalMemCounter.checkDeleteArrayCalledEq(0));
+}
+
+int main()
+{
+ test_return();
+ test_equality();
+ test_allocate();
+ test_deallocate();
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,13 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource/construct.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource/construct.fail.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource/construct.fail.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource/construct.fail.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// Check that memory_resource is not constructible
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ ex::memory_resource m; // expected-error {{variable type 'ex::memory_resource' is an abstract class}}
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// bool operator==(memory_resource const &, memory_resource const &) noexcept;
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ // check return types
+ {
+ ex::memory_resource const * mr1(nullptr);
+ ex::memory_resource const * mr2(nullptr);
+ static_assert(std::is_same<decltype(*mr1 == *mr2), bool>::value, "");
+ static_assert(noexcept(*mr1 == *mr2), "");
+ }
+ // equal
+ {
+ TestResource r1(1);
+ TestResource r2(1);
+ ex::memory_resource const & mr1 = r1;
+ ex::memory_resource const & mr2 = r2;
+
+ assert(mr1 == mr2);
+ assert(r1.checkIsEqualCalledEq(1));
+ assert(r2.checkIsEqualCalledEq(0));
+
+ assert(mr2 == mr1);
+ assert(r1.checkIsEqualCalledEq(1));
+ assert(r2.checkIsEqualCalledEq(1));
+ }
+ // equal same object
+ {
+ TestResource r1(1);
+ ex::memory_resource const & mr1 = r1;
+ ex::memory_resource const & mr2 = r1;
+
+ assert(mr1 == mr2);
+ assert(r1.checkIsEqualCalledEq(0));
+
+ assert(mr2 == mr1);
+ assert(r1.checkIsEqualCalledEq(0));
+ }
+ // not equal
+ {
+ TestResource r1(1);
+ TestResource r2(2);
+ ex::memory_resource const & mr1 = r1;
+ ex::memory_resource const & mr2 = r2;
+
+ assert(!(mr1 == mr2));
+ assert(r1.checkIsEqualCalledEq(1));
+ assert(r2.checkIsEqualCalledEq(0));
+
+ assert(!(mr2 == mr1));
+ assert(r1.checkIsEqualCalledEq(1));
+ assert(r2.checkIsEqualCalledEq(1));
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// bool operator!=(memory_resource const &, memory_resource const &) noexcept;
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+namespace ex = std::experimental::pmr;
+
+int main()
+{
+ // check return types
+ {
+ ex::memory_resource const * mr1(nullptr);
+ ex::memory_resource const * mr2(nullptr);
+ static_assert(std::is_same<decltype(*mr1 != *mr2), bool>::value, "");
+ static_assert(noexcept(*mr1 != *mr2), "");
+ }
+ // not equal
+ {
+ TestResource r1(1);
+ TestResource r2(2);
+ ex::memory_resource const & mr1 = r1;
+ ex::memory_resource const & mr2 = r2;
+
+ assert(mr1 != mr2);
+ assert(r1.checkIsEqualCalledEq(1));
+ assert(r2.checkIsEqualCalledEq(0));
+
+ assert(mr2 != mr1);
+ assert(r1.checkIsEqualCalledEq(1));
+ assert(r2.checkIsEqualCalledEq(1));
+ }
+ // equal
+ {
+ TestResource r1(1);
+ TestResource r2(1);
+ ex::memory_resource const & mr1 = r1;
+ ex::memory_resource const & mr2 = r2;
+
+ assert(!(mr1 != mr2));
+ assert(r1.checkIsEqualCalledEq(1));
+ assert(r2.checkIsEqualCalledEq(0));
+
+ assert(!(mr2 != mr1));
+ assert(r1.checkIsEqualCalledEq(1));
+ assert(r2.checkIsEqualCalledEq(1));
+ }
+ // equal same object
+ {
+ TestResource r1(1);
+ ex::memory_resource const & mr1 = r1;
+ ex::memory_resource const & mr2 = r1;
+
+ assert(!(mr1 != mr2));
+ assert(r1.checkIsEqualCalledEq(0));
+
+ assert(!(mr2 != mr1));
+ assert(r1.checkIsEqualCalledEq(0));
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,10 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main () {}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+// memory_resource::do_allocate(size_t, size_t); /* protected */
+// memory_resource::do_deallocate(void*, size_t, size_t); /* protected */
+// memory_resource::do_is_equal(memory_resource const&); /* protected */
+
+#include <experimental/memory_resource>
+
+namespace ex = std::experimental::pmr;
+
+int main() {
+ ex::memory_resource *m = ex::new_delete_resource();
+ m->do_allocate(0, 0); // expected-error{{'do_allocate' is a protected member}}
+ m->do_deallocate(nullptr, 0, 0); // expected-error{{'do_deallocate' is a protected member}}
+ m->do_is_equal(*m); // expected-error{{'do_is_equal' is a protected member}}
+}
\ No newline at end of file
Added: libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/memory_resource>
+
+// UNSUPPORTED: c++98, c++03
+
+//------------------------------------------------------------------------------
+// TESTING void * memory_resource::allocate(size_t, size_t = max_align)
+//
+// Concerns:
+// A) 'memory_resource' contains a member 'allocate' with the required
+// signature, including the default alignment parameter.
+// B) The return type of 'allocate' is 'void*'.
+// C) 'allocate' is not marked as 'noexcept'.
+// D) Invoking 'allocate' invokes 'do_allocate' with the same arguments.
+// E) If 'do_allocate' throws then 'allocate' propagates that exception.
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cstddef>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_memory_resource.hpp"
+
+using std::experimental::pmr::memory_resource;
+
+int main()
+{
+ TestResource R(42);
+ auto& P = R.getController();
+ memory_resource& M = R;
+ {
+ static_assert(
+ std::is_same<decltype(M.allocate(0, 0)), void*>::value
+ , "Must be void*"
+ );
+ static_assert(
+ std::is_same<decltype(M.allocate(0)), void*>::value
+ , "Must be void*"
+ );
+ }
+ {
+ static_assert(
+ ! noexcept(M.allocate(0, 0))
+ , "Must not be noexcept."
+ );
+ static_assert(
+ ! noexcept(M.allocate(0))
+ , "Must not be noexcept."
+ );
+ }
+ {
+ int s = 42;
+ int a = 64;
+ void* p = M.allocate(s, a);
+ assert(P.alloc_count == 1);
+ assert(P.checkAlloc(p, s, a));
+
+ s = 128;
+ a = MaxAlignV;
+ p = M.allocate(s);
+ assert(P.alloc_count == 2);
+ assert(P.checkAlloc(p, s, a));
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ TestResource R2;
+ auto& P = R2.getController();
+ P.throw_on_alloc = true;
+ memory_resource& M2 = R2;
+ try {
+ M2.allocate(42);
+ assert(false);
+ } catch (TestException const&) {
+ // do nothing.
+ } catch (...) {
+ assert(false);
+ }
+ }
+#endif
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp Fri May 6 20:04:55 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/memory_resource>
+
+// UNSUPPORTED: c++98, c++03
+
+//------------------------------------------------------------------------------
+// TESTING void * memory_resource::deallocate(void *, size_t, size_t = max_align)
+//
+// Concerns:
+// A) 'memory_resource' contains a member 'deallocate' with the required
+// signature, including the default alignment parameter.
+// B) The return type of 'deallocate' is 'void'.
+// C) 'deallocate' is not marked as 'noexcept'.
+// D) Invoking 'deallocate' invokes 'do_deallocate' with the same arguments.
+
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cstddef>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+using std::experimental::pmr::memory_resource;
+
+int main()
+{
+ NullResource R(42);
+ auto& P = R.getController();
+ memory_resource& M = R;
+ {
+ static_assert(
+ std::is_same<decltype(M.deallocate(nullptr, 0, 0)), void>::value
+ , "Must be void"
+ );
+ static_assert(
+ std::is_same<decltype(M.deallocate(nullptr, 0)), void>::value
+ , "Must be void"
+ );
+ }
+ {
+ static_assert(
+ ! noexcept(M.deallocate(nullptr, 0, 0))
+ , "Must not be noexcept."
+ );
+ static_assert(
+ ! noexcept(M.deallocate(nullptr, 0))
+ , "Must not be noexcept."
+ );
+ }
+ {
+ int s = 100;
+ int a = 64;
+ void* p = reinterpret_cast<void*>(640);
+ M.deallocate(p, s, a);
+ assert(P.dealloc_count == 1);
+ assert(P.checkDealloc(p, s, a));
+
+ s = 128;
+ a = alignof(std::max_align_t);
+ p = reinterpret_cast<void*>(12800);
+ M.deallocate(p, s);
+ assert(P.dealloc_count == 2);
+ assert(P.checkDealloc(p, s, a));
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+//------------------------------------------------------------------------------
+// TESTING virtual ~memory_resource()
+//
+// Concerns:
+// A) 'memory_resource' is destructible.
+// B) The destructor is implicitly marked noexcept.
+// C) The destructor is marked virtual.
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_memory_resource.hpp"
+
+using std::experimental::pmr::memory_resource;
+
+int main()
+{
+ static_assert(
+ std::has_virtual_destructor<memory_resource>::value
+ , "Must have virtual destructor"
+ );
+ static_assert(
+ std::is_nothrow_destructible<memory_resource>::value,
+ "Must be nothrow destructible"
+ );
+ static_assert(
+ std::is_abstract<memory_resource>::value
+ , "Must be abstract"
+ );
+ // Check that the destructor of `TestResource` is called when
+ // it is deleted as a pointer to `memory_resource`
+ {
+ using TR = TestResource;
+ memory_resource* M = new TR(42);
+ assert(TR::resource_alive == 1);
+ assert(TR::resource_constructed == 1);
+ assert(TR::resource_destructed == 0);
+
+ delete M;
+
+ assert(TR::resource_alive == 0);
+ assert(TR::resource_constructed == 1);
+ assert(TR::resource_destructed == 1);
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/memory_resource>
+
+//------------------------------------------------------------------------------
+// TESTING virtual bool is_equal(memory_resource const &) const noexcept
+//
+// Concerns:
+// A) 'memory_resource' provides a function 'is_equal' with the required
+// signature.
+// B) 'is_equal' is noexcept.
+// C) 'do_is_equal' is called using the same arguments passed to 'is_equal'
+// and the resulting value is returned.
+// D) 'do_is_equal' is called on the LHS object and not the RHS object.
+
+#include <experimental/memory_resource>
+#include <type_traits>
+#include <cassert>
+#include "test_memory_resource.hpp"
+
+using std::experimental::pmr::memory_resource;
+
+int main()
+{
+ {
+ memory_resource const* r1 = nullptr;
+ memory_resource const* r2 = nullptr;
+ static_assert(
+ noexcept(r1->is_equal(*r2))
+ , "is_equal must be noexcept"
+ );
+ }
+ {
+ TestResource1 R1(1);
+ auto& P1 = R1.getController();
+ memory_resource const& M1 = R1;
+
+ TestResource2 R2(1);
+ auto& P2 = R2.getController();
+ memory_resource const& M2 = R2;
+
+ assert(M1.is_equal(M2) == false);
+ assert(P1.checkIsEqualCalledEq(1));
+ assert(P2.checkIsEqualCalledEq(0));
+
+ assert(M2.is_equal(M1) == false);
+ assert(P2.checkIsEqualCalledEq(1));
+ assert(P1.checkIsEqualCalledEq(1));
+ }
+ {
+ TestResource1 R1(1);
+ auto& P1 = R1.getController();
+ memory_resource const& M1 = R1;
+
+ TestResource1 R2(2);
+ auto& P2 = R2.getController();
+ memory_resource const& M2 = R2;
+
+ assert(M1.is_equal(M2) == false);
+ assert(P1.checkIsEqualCalledEq(1));
+ assert(P2.checkIsEqualCalledEq(0));
+
+ assert(M2.is_equal(M1) == false);
+ assert(P2.checkIsEqualCalledEq(1));
+ assert(P1.checkIsEqualCalledEq(1));
+ }
+ {
+ TestResource1 R1(1);
+ auto& P1 = R1.getController();
+ memory_resource const& M1 = R1;
+
+ TestResource1 R2(1);
+ auto& P2 = R2.getController();
+ memory_resource const& M2 = R2;
+
+ assert(M1.is_equal(M2) == true);
+ assert(P1.checkIsEqualCalledEq(1));
+ assert(P2.checkIsEqualCalledEq(0));
+
+ assert(M2.is_equal(M1) == true);
+ assert(P2.checkIsEqualCalledEq(1));
+ assert(P1.checkIsEqualCalledEq(1));
+ }
+}
Added: libcxx/trunk/test/std/experimental/memory/nothing_to_do.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/memory/nothing_to_do.pass.cpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/memory/nothing_to_do.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/memory/nothing_to_do.pass.cpp Fri May 6 20:04:55 2016
@@ -0,0 +1,13 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
Added: libcxx/trunk/test/support/test_memory_resource.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/test_memory_resource.hpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/support/test_memory_resource.hpp (added)
+++ libcxx/trunk/test/support/test_memory_resource.hpp Fri May 6 20:04:55 2016
@@ -0,0 +1,506 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_MEMORY_RESOURCE_HPP
+#define SUPPORT_TEST_MEMORY_RESOURCE_HPP
+
+#include <experimental/memory_resource>
+#include <memory>
+#include <type_traits>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <cassert>
+#include "test_macros.h"
+
+struct AllocController;
+ // 'AllocController' is a concrete type that instruments and controls the
+ // behavior of of test allocators.
+
+template <class T>
+class CountingAllocator;
+ // 'CountingAllocator' is an basic implementation of the 'Allocator'
+ // requirements that use the 'AllocController' interface.
+
+template <class T>
+class MinAlignAllocator;
+ // 'MinAlignAllocator' is an instrumented test type which implements the
+ // 'Allocator' requirements. 'MinAlignAllocator' ensures that it *never*
+ // returns a pointer to over-aligned storage. For example
+ // 'MinAlignPointer<char>{}.allocate(...)' will never a 2-byte aligned
+ // pointer.
+
+template <class T>
+class NullAllocator;
+ // 'NullAllocator' is an instrumented test type which implements the
+ // 'Allocator' requirements except that 'allocator' and 'deallocate' are
+ // nops.
+
+
+#define DISALLOW_COPY(Type) \
+ Type(Type const&) = delete; \
+ Type& operator=(Type const&) = delete
+
+constexpr std::size_t MaxAlignV = alignof(std::max_align_t);
+
+struct TestException {};
+
+struct AllocController {
+ int copy_constructed = 0;
+ int move_constructed = 0;
+
+ int alive = 0;
+ int alloc_count = 0;
+ int dealloc_count = 0;
+ int is_equal_count = 0;
+
+ std::size_t alive_size;
+ std::size_t allocated_size;
+ std::size_t deallocated_size;
+
+ std::size_t last_size = 0;
+ std::size_t last_align = 0;
+ void * last_pointer = 0;
+
+ std::size_t last_alloc_size = 0;
+ std::size_t last_alloc_align = 0;
+ void * last_alloc_pointer = nullptr;
+
+ std::size_t last_dealloc_size = 0;
+ std::size_t last_dealloc_align = 0;
+ void * last_dealloc_pointer = nullptr;
+
+ bool throw_on_alloc = false;
+
+ AllocController() = default;
+
+ void countAlloc(void* p, size_t s, size_t a) {
+ ++alive;
+ ++alloc_count;
+ alive_size += s;
+ allocated_size += s;
+ last_pointer = last_alloc_pointer = p;
+ last_size = last_alloc_size = s;
+ last_align = last_alloc_align = a;
+ }
+
+ void countDealloc(void* p, size_t s, size_t a) {
+ --alive;
+ ++dealloc_count;
+ alive_size -= s;
+ deallocated_size += s;
+ last_pointer = last_dealloc_pointer = p;
+ last_size = last_dealloc_size = s;
+ last_align = last_dealloc_align = a;
+ }
+
+ void reset() { std::memset(this, 0, sizeof(*this)); }
+
+public:
+ bool checkAlloc(void* p, size_t s, size_t a) const {
+ return p == last_alloc_pointer &&
+ s == last_alloc_size &&
+ a == last_alloc_align;
+ }
+
+ bool checkAlloc(void* p, size_t s) const {
+ return p == last_alloc_pointer &&
+ s == last_alloc_size;
+ }
+
+ bool checkAllocAtLeast(void* p, size_t s, size_t a) const {
+ return p == last_alloc_pointer &&
+ s <= last_alloc_size &&
+ a <= last_alloc_align;
+ }
+
+ bool checkAllocAtLeast(void* p, size_t s) const {
+ return p == last_alloc_pointer &&
+ s <= last_alloc_size;
+ }
+
+ bool checkDealloc(void* p, size_t s, size_t a) const {
+ return p == last_dealloc_pointer &&
+ s == last_dealloc_size &&
+ a == last_dealloc_align;
+ }
+
+ bool checkDealloc(void* p, size_t s) const {
+ return p == last_dealloc_pointer &&
+ s == last_dealloc_size;
+ }
+
+ bool checkDeallocMatchesAlloc() const {
+ return last_dealloc_pointer == last_alloc_pointer &&
+ last_dealloc_size == last_alloc_size &&
+ last_dealloc_align == last_alloc_align;
+ }
+
+ void countIsEqual() {
+ ++is_equal_count;
+ }
+
+ bool checkIsEqualCalledEq(int n) const {
+ return is_equal_count == n;
+ }
+private:
+ DISALLOW_COPY(AllocController);
+};
+
+template <class T>
+class CountingAllocator
+{
+public:
+ typedef T value_type;
+ typedef T* pointer;
+ CountingAllocator() = delete;
+ explicit CountingAllocator(AllocController& PP) : P(&PP) {}
+
+ CountingAllocator(CountingAllocator const& other) : P(other.P) {
+ P->copy_constructed += 1;
+ }
+
+ CountingAllocator(CountingAllocator&& other) : P(other.P) {
+ P->move_constructed += 1;
+ }
+
+ template <class U>
+ CountingAllocator(CountingAllocator<U> const& other) TEST_NOEXCEPT : P(other.P) {
+ P->copy_constructed += 1;
+ }
+
+ template <class U>
+ CountingAllocator(CountingAllocator<U>&& other) TEST_NOEXCEPT : P(other.P) {
+ P->move_constructed += 1;
+ }
+
+ T* allocate(std::size_t n)
+ {
+ void* ret = ::operator new(n*sizeof(T));
+ P->countAlloc(ret, n*sizeof(T), alignof(T));
+ return static_cast<T*>(ret);
+ }
+
+ void deallocate(T* p, std::size_t n)
+ {
+ void* vp = static_cast<void*>(p);
+ P->countDealloc(vp, n*sizeof(T), alignof(T));
+ ::operator delete(vp);
+ }
+
+ AllocController& getController() const { return *P; }
+
+private:
+ template <class Tp> friend class CountingAllocator;
+ AllocController *P;
+};
+
+template <class T, class U>
+inline bool operator==(CountingAllocator<T> const& x,
+ CountingAllocator<U> const& y) {
+ return &x.getController() == &y.getController();
+}
+
+template <class T, class U>
+inline bool operator!=(CountingAllocator<T> const& x,
+ CountingAllocator<U> const& y) {
+ return !(x == y);
+}
+
+template <class T>
+class MinAlignedAllocator
+{
+public:
+ typedef T value_type;
+ typedef T* pointer;
+
+ MinAlignedAllocator() = delete;
+
+ explicit MinAlignedAllocator(AllocController& R) : P(&R) {}
+
+ MinAlignedAllocator(MinAlignedAllocator const& other) : P(other.P) {
+ P->copy_constructed += 1;
+ }
+
+ MinAlignedAllocator(MinAlignedAllocator&& other) : P(other.P) {
+ P->move_constructed += 1;
+ }
+
+ template <class U>
+ MinAlignedAllocator(MinAlignedAllocator<U> const& other) TEST_NOEXCEPT : P(other.P) {
+ P->copy_constructed += 1;
+ }
+
+ template <class U>
+ MinAlignedAllocator(MinAlignedAllocator<U>&& other) TEST_NOEXCEPT : P(other.P) {
+ P->move_constructed += 1;
+ }
+
+ T* allocate(std::size_t n) {
+ char* aligned_ptr = (char*)::operator new(alloc_size(n*sizeof(T)));
+ assert(is_max_aligned(aligned_ptr));
+
+ char* unaligned_ptr = aligned_ptr + alignof(T);
+ assert(is_min_aligned(unaligned_ptr));
+
+ P->countAlloc(unaligned_ptr, n * sizeof(T), alignof(T));
+
+ return ((T*)unaligned_ptr);
+ }
+
+ void deallocate(T* p, std::size_t n) {
+ assert(is_min_aligned(p));
+
+ char* aligned_ptr = ((char*)p) - alignof(T);
+ assert(is_max_aligned(aligned_ptr));
+
+ P->countDealloc(p, n*sizeof(T), alignof(T));
+
+ return ::operator delete(static_cast<void*>(aligned_ptr));
+ }
+
+ AllocController& getController() const { return *P; }
+
+private:
+ static const std::size_t BlockSize = alignof(std::max_align_t);
+
+ static std::size_t alloc_size(std::size_t s) {
+ std::size_t bytes = (s + BlockSize - 1) & ~(BlockSize - 1);
+ bytes += BlockSize;
+ assert(bytes % BlockSize == 0);
+ return bytes / BlockSize;
+ }
+
+ static bool is_max_aligned(void* p) {
+ return reinterpret_cast<std::size_t>(p) % BlockSize == 0;
+ }
+
+ static bool is_min_aligned(void* p) {
+ if (alignof(T) == BlockSize) {
+ return is_max_aligned(p);
+ } else {
+ return reinterpret_cast<std::size_t>(p) % BlockSize == alignof(T);
+ }
+ }
+
+ template <class Tp> friend class MinAlignedAllocator;
+ mutable AllocController *P;
+};
+
+
+template <class T, class U>
+inline bool operator==(MinAlignedAllocator<T> const& x,
+ MinAlignedAllocator<U> const& y) {
+ return &x.getController() == &y.getController();
+}
+
+template <class T, class U>
+inline bool operator!=(MinAlignedAllocator<T> const& x,
+ MinAlignedAllocator<U> const& y) {
+ return !(x == y);
+}
+
+template <class T>
+class NullAllocator
+{
+public:
+ typedef T value_type;
+ typedef T* pointer;
+ NullAllocator() = delete;
+ explicit NullAllocator(AllocController& PP) : P(&PP) {}
+
+ NullAllocator(NullAllocator const& other) : P(other.P) {
+ P->copy_constructed += 1;
+ }
+
+ NullAllocator(NullAllocator&& other) : P(other.P) {
+ P->move_constructed += 1;
+ }
+
+ template <class U>
+ NullAllocator(NullAllocator<U> const& other) TEST_NOEXCEPT : P(other.P) {
+ P->copy_constructed += 1;
+ }
+
+ template <class U>
+ NullAllocator(NullAllocator<U>&& other) TEST_NOEXCEPT : P(other.P) {
+ P->move_constructed += 1;
+ }
+
+ T* allocate(std::size_t n)
+ {
+ P->countAlloc(nullptr, n*sizeof(T), alignof(T));
+ return nullptr;
+ }
+
+ void deallocate(T* p, std::size_t n)
+ {
+ void* vp = static_cast<void*>(p);
+ P->countDealloc(vp, n*sizeof(T), alignof(T));
+ }
+
+ AllocController& getController() const { return *P; }
+
+private:
+ template <class Tp> friend class NullAllocator;
+ AllocController *P;
+};
+
+template <class T, class U>
+inline bool operator==(NullAllocator<T> const& x,
+ NullAllocator<U> const& y) {
+ return &x.getController() == &y.getController();
+}
+
+template <class T, class U>
+inline bool operator!=(NullAllocator<T> const& x,
+ NullAllocator<U> const& y) {
+ return !(x == y);
+}
+
+
+
+template <class ProviderT, int = 0>
+class TestResourceImp : public std::experimental::pmr::memory_resource
+{
+public:
+ static int resource_alive;
+ static int resource_constructed;
+ static int resource_destructed;
+
+ static void resetStatics() {
+ assert(resource_alive == 0);
+ resource_alive = 0;
+ resource_constructed = 0;
+ resource_destructed = 0;
+ }
+
+ using memory_resource = std::experimental::pmr::memory_resource;
+ using Provider = ProviderT;
+
+ int value;
+
+ explicit TestResourceImp(int val = 0) : value(val) {
+ ++resource_alive;
+ ++resource_constructed;
+ }
+
+ ~TestResourceImp() noexcept {
+ --resource_alive;
+ ++resource_destructed;
+ }
+
+ void reset() { C.reset(); P.reset(); }
+ AllocController& getController() { return C; }
+
+ bool checkAlloc(void* p, std::size_t s, std::size_t a) const
+ { return C.checkAlloc(p, s, a); }
+
+ bool checkDealloc(void* p, std::size_t s, std::size_t a) const
+ { return C.checkDealloc(p, s, a); }
+
+ bool checkIsEqualCalledEq(int n) const { return C.checkIsEqualCalledEq(n); }
+
+protected:
+ virtual void * do_allocate(std::size_t s, std::size_t a) {
+ if (C.throw_on_alloc) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ throw TestException{};
+#else
+ assert(false);
+#endif
+ }
+ void* ret = P.allocate(s, a);
+ C.countAlloc(ret, s, a);
+ return ret;
+ }
+
+ virtual void do_deallocate(void * p, std::size_t s, std::size_t a) {
+ C.countDealloc(p, s, a);
+ P.deallocate(p, s, a);
+ }
+
+ virtual bool do_is_equal(memory_resource const & other) const noexcept {
+ C.countIsEqual();
+ TestResourceImp const * o = dynamic_cast<TestResourceImp const *>(&other);
+ return o && o->value == value;
+ }
+private:
+ mutable AllocController C;
+ mutable Provider P;
+ DISALLOW_COPY(TestResourceImp);
+};
+
+template <class Provider, int N>
+int TestResourceImp<Provider, N>::resource_alive = 0;
+
+template <class Provider, int N>
+int TestResourceImp<Provider, N>::resource_constructed = 0;
+
+template <class Provider, int N>
+int TestResourceImp<Provider, N>::resource_destructed = 0;
+
+
+struct NullProvider {
+ NullProvider() {}
+ void* allocate(size_t, size_t) { return nullptr; }
+ void deallocate(void*, size_t, size_t) {}
+ void reset() {}
+private:
+ DISALLOW_COPY(NullProvider);
+};
+
+struct NewDeleteProvider {
+ NewDeleteProvider() {}
+ void* allocate(size_t s, size_t) { return ::operator new(s); }
+ void deallocate(void* p, size_t, size_t) { ::operator delete(p); }
+ void reset() {}
+private:
+ DISALLOW_COPY(NewDeleteProvider);
+};
+
+template <size_t Size = 4096 * 10> // 10 pages worth of memory.
+struct BufferProvider {
+ char buffer[Size];
+ void* next = &buffer;
+ size_t space = Size;
+
+ BufferProvider() {}
+
+ void* allocate(size_t s, size_t a) {
+ void* ret = std::align(s, a, next, space);
+ if (ret == nullptr) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ assert(false);
+#endif
+ }
+
+ return ret;
+ }
+
+ void deallocate(void*, size_t, size_t) {}
+
+ void reset() {
+ next = &buffer;
+ space = Size;
+ }
+private:
+ DISALLOW_COPY(BufferProvider);
+};
+
+using NullResource = TestResourceImp<NullProvider, 0>;
+using NewDeleteResource = TestResourceImp<NewDeleteProvider, 0>;
+using TestResource = TestResourceImp<BufferProvider<>, 0>;
+using TestResource1 = TestResourceImp<BufferProvider<>, 1>;
+using TestResource2 = TestResourceImp<BufferProvider<>, 2>;
+
+
+#endif /* SUPPORT_TEST_MEMORY_RESOURCE_HPP */
Added: libcxx/trunk/test/support/type_id.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/type_id.h?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/support/type_id.h (added)
+++ libcxx/trunk/test/support/type_id.h Fri May 6 20:04:55 2016
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+#ifndef SUPPORT_TYPE_ID_H
+#define SUPPORT_TYPE_ID_H
+
+#include <functional>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER < 11
+#error This header requires C++11 or greater
+#endif
+
+// TypeID - Represent a unique identifier for a type. TypeID allows equality
+// comparisons between different types.
+struct TypeID {
+ friend bool operator==(TypeID const& LHS, TypeID const& RHS)
+ {return LHS.m_id == RHS.m_id; }
+ friend bool operator!=(TypeID const& LHS, TypeID const& RHS)
+ {return LHS.m_id != RHS.m_id; }
+private:
+ explicit constexpr TypeID(const int* xid) : m_id(xid) {}
+
+ TypeID(const TypeID&) = delete;
+ TypeID& operator=(TypeID const&) = delete;
+
+ const int* const m_id;
+ template <class T> friend TypeID const& makeTypeID();
+
+};
+
+// makeTypeID - Return the TypeID for the specified type 'T'.
+template <class T>
+inline TypeID const& makeTypeID() {
+ static int dummy;
+ static const TypeID id(&dummy);
+ return id;
+}
+
+template <class ...Args>
+struct ArgumentListID {};
+
+// makeArgumentID - Create and return a unique identifier for a given set
+// of arguments.
+template <class ...Args>
+inline TypeID const& makeArgumentID() {
+ return makeTypeID<ArgumentListID<Args...>>();
+}
+
+#endif // SUPPORT_TYPE_ID_H
Added: libcxx/trunk/test/support/uses_alloc_types.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/uses_alloc_types.hpp?rev=268829&view=auto
==============================================================================
--- libcxx/trunk/test/support/uses_alloc_types.hpp (added)
+++ libcxx/trunk/test/support/uses_alloc_types.hpp Fri May 6 20:04:55 2016
@@ -0,0 +1,298 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 USES_ALLOC_TYPES_HPP
+#define USES_ALLOC_TYPES_HPP
+
+# include <experimental/memory_resource>
+# include <experimental/utility>
+# include <memory>
+# include <cassert>
+
+#include "test_memory_resource.hpp"
+#include "type_id.h"
+
+// There are two forms of uses-allocator construction:
+// (1) UA_AllocArg: 'T(allocator_arg_t, Alloc const&, Args&&...)'
+// (2) UA_AllocLast: 'T(Args&&..., Alloc const&)'
+// 'UA_None' represents non-uses allocator construction.
+enum class UsesAllocatorType {
+ UA_None = 0,
+ UA_AllocArg = 2,
+ UA_AllocLast = 4
+};
+constexpr UsesAllocatorType UA_None = UsesAllocatorType::UA_None;
+constexpr UsesAllocatorType UA_AllocArg = UsesAllocatorType::UA_AllocArg;
+constexpr UsesAllocatorType UA_AllocLast = UsesAllocatorType::UA_AllocLast;
+
+template <class Alloc, std::size_t N>
+class UsesAllocatorV1;
+ // Implements form (1) of uses-allocator construction from the specified
+ // 'Alloc' type and exactly 'N' additional arguments. It also provides
+ // non-uses allocator construction from 'N' arguments. This test type
+ // blows up when form (2) of uses-allocator is even considered.
+
+template <class Alloc, std::size_t N>
+class UsesAllocatorV2;
+ // Implements form (2) of uses-allocator construction from the specified
+ // 'Alloc' type and exactly 'N' additional arguments. It also provides
+ // non-uses allocator construction from 'N' arguments.
+
+template <class Alloc, std::size_t N>
+class UsesAllocatorV3;
+ // Implements both form (1) and (2) of uses-allocator construction from
+ // the specified 'Alloc' type and exactly 'N' additional arguments. It also
+ // provides non-uses allocator construction from 'N' arguments.
+
+template <class Alloc, std::size_t>
+class NotUsesAllocator;
+ // Implements both form (1) and (2) of uses-allocator construction from
+ // the specified 'Alloc' type and exactly 'N' additional arguments. It also
+ // provides non-uses allocator construction from 'N' arguments. However
+ // 'NotUsesAllocator' never provides a 'allocator_type' typedef so it is
+ // never automatically uses-allocator constructed.
+
+
+template <class ...ArgTypes, class TestType>
+bool checkConstruct(TestType& value, UsesAllocatorType form,
+ typename TestType::CtorAlloc const& alloc)
+ // Check that 'value' was constructed using the specified 'form' of
+ // construction and with the specified 'ArgTypes...'. Additionally
+ // check that 'value' was constructed using the specified 'alloc'.
+{
+ if (form == UA_None) {
+ return value.template checkConstruct<ArgTypes&&...>(form);
+ } else {
+ return value.template checkConstruct<ArgTypes&&...>(form, alloc);
+ }
+}
+
+
+template <class ...ArgTypes, class TestType>
+bool checkConstruct(TestType& value, UsesAllocatorType form) {
+ return value.template checkConstruct<ArgTypes&&...>(form);
+}
+
+template <class TestType>
+bool checkConstructionEquiv(TestType& T, TestType& U)
+ // check that 'T' and 'U' where initialized in the exact same manner.
+{
+ return T.checkConstructEquiv(U);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace detail {
+
+template <bool IsZero, size_t N, class ArgList, class ...Args>
+struct TakeNImp;
+
+template <class ArgList, class ...Args>
+struct TakeNImp<true, 0, ArgList, Args...> {
+ typedef ArgList type;
+};
+
+template <size_t N, class ...A1, class F, class ...R>
+struct TakeNImp<false, N, ArgumentListID<A1...>, F, R...>
+ : TakeNImp<N-1 == 0, N - 1, ArgumentListID<A1..., F>, R...> {};
+
+template <size_t N, class ...Args>
+struct TakeNArgs : TakeNImp<N == 0, N, ArgumentListID<>, Args...> {};
+
+template <class T>
+struct Identity { typedef T type; };
+
+template <class T>
+using IdentityT = typename Identity<T>::type;
+
+template <bool Value>
+using EnableIfB = typename std::enable_if<Value, bool>::type;
+
+} // end namespace detail
+
+using detail::EnableIfB;
+
+struct AllocLastTag {};
+
+template <class Alloc>
+struct UsesAllocatorTestBase {
+public:
+ using CtorAlloc = typename std::conditional<
+ std::is_same<Alloc, std::experimental::erased_type>::value,
+ std::experimental::pmr::memory_resource*,
+ Alloc
+ >::type;
+
+ template <class ...ArgTypes>
+ bool checkConstruct(UsesAllocatorType expectType) const {
+ return expectType == constructor_called &&
+ makeArgumentID<ArgTypes...>() == *args_id;
+ }
+
+ template <class ...ArgTypes>
+ bool checkConstruct(UsesAllocatorType expectType,
+ CtorAlloc const& expectAlloc) const {
+ return expectType == constructor_called &&
+ makeArgumentID<ArgTypes...>() == *args_id &&
+ expectAlloc == allocator;
+ }
+
+ bool checkConstructEquiv(UsesAllocatorTestBase& O) const {
+ return constructor_called == O.constructor_called
+ && *args_id == *O.args_id
+ && allocator == O.allocator;
+ }
+
+protected:
+ explicit UsesAllocatorTestBase(const TypeID* aid)
+ : args_id(aid), constructor_called(UA_None), allocator()
+ {}
+
+ template <class ...Args>
+ UsesAllocatorTestBase(std::allocator_arg_t, CtorAlloc const& a, Args&&...)
+ : args_id(&makeArgumentID<Args&&...>()),
+ constructor_called(UA_AllocArg),
+ allocator(a)
+ {}
+
+ template <class ...Args>
+ UsesAllocatorTestBase(AllocLastTag, Args&&... args)
+ : args_id(nullptr),
+ constructor_called(UA_AllocLast)
+ {
+ typedef typename detail::TakeNArgs<sizeof...(Args) - 1, Args&&...>::type
+ ArgIDL;
+ args_id = &makeTypeID<ArgIDL>();
+ getAllocatorFromPack(ArgIDL{}, std::forward<Args>(args)...);
+ }
+
+private:
+ template <class ...LArgs, class ...Args>
+ void getAllocatorFromPack(ArgumentListID<LArgs...>, Args&&... args) {
+ getAllocatorFromPackImp<LArgs const&...>(args...);
+ }
+
+ template <class ...LArgs>
+ void getAllocatorFromPackImp(typename detail::Identity<LArgs>::type..., CtorAlloc const& alloc) {
+ allocator = alloc;
+ }
+
+ const TypeID* args_id;
+ UsesAllocatorType constructor_called = UA_None;
+ CtorAlloc allocator;
+};
+
+template <class Alloc, size_t Arity>
+class UsesAllocatorV1 : public UsesAllocatorTestBase<Alloc>
+{
+public:
+ typedef Alloc allocator_type;
+
+ using Base = UsesAllocatorTestBase<Alloc>;
+ using CtorAlloc = typename Base::CtorAlloc;
+
+ UsesAllocatorV1() : Base(&makeArgumentID<>()) {}
+
+ // Non-Uses Allocator Ctor
+ template <class ...Args, EnableIfB<sizeof...(Args) == Arity> = false>
+ UsesAllocatorV1(Args&&... args) : Base(&makeArgumentID<Args&&...>()) {};
+
+ // Uses Allocator Arg Ctor
+ template <class ...Args>
+ UsesAllocatorV1(std::allocator_arg_t tag, CtorAlloc const & a, Args&&... args)
+ : Base(tag, a, std::forward<Args>(args)...)
+ { }
+
+ // BLOWS UP: Uses Allocator Last Ctor
+ template <class _First, class ...Args, EnableIfB<sizeof...(Args) == Arity> _Dummy = false>
+ constexpr UsesAllocatorV1(_First&& __first, Args&&... args)
+ {
+ static_assert(!std::is_same<_First, _First>::value, "");
+ }
+};
+
+
+template <class Alloc, size_t Arity>
+class UsesAllocatorV2 : public UsesAllocatorTestBase<Alloc>
+{
+public:
+ typedef Alloc allocator_type;
+
+ using Base = UsesAllocatorTestBase<Alloc>;
+ using CtorAlloc = typename Base::CtorAlloc;
+
+ UsesAllocatorV2() : Base(&makeArgumentID<>()) {}
+
+ // Non-Uses Allocator Ctor
+ template <class ...Args, EnableIfB<sizeof...(Args) == Arity> = false>
+ UsesAllocatorV2(Args&&... args) : Base(&makeArgumentID<Args&&...>()) {};
+
+ // Uses Allocator Last Ctor
+ template <class ...Args, EnableIfB<sizeof...(Args) == Arity + 1> = false>
+ UsesAllocatorV2(Args&&... args)
+ : Base(AllocLastTag{}, std::forward<Args>(args)...)
+ {}
+};
+
+template <class Alloc, size_t Arity>
+class UsesAllocatorV3 : public UsesAllocatorTestBase<Alloc>
+{
+public:
+ typedef Alloc allocator_type;
+
+ using Base = UsesAllocatorTestBase<Alloc>;
+ using CtorAlloc = typename Base::CtorAlloc;
+
+ UsesAllocatorV3() : Base(&makeArgumentID<>()) {}
+
+ // Non-Uses Allocator Ctor
+ template <class ...Args, EnableIfB<sizeof...(Args) == Arity> = false>
+ UsesAllocatorV3(Args&&... args) : Base(&makeArgumentID<Args&&...>()) {};
+
+ // Uses Allocator Arg Ctor
+ template <class ...Args>
+ UsesAllocatorV3(std::allocator_arg_t tag, CtorAlloc const& alloc, Args&&... args)
+ : Base(tag, alloc, std::forward<Args>(args)...)
+ {}
+
+ // Uses Allocator Last Ctor
+ template <class ...Args, EnableIfB<sizeof...(Args) == Arity + 1> = false>
+ UsesAllocatorV3(Args&&... args)
+ : Base(AllocLastTag{}, std::forward<Args>(args)...)
+ {}
+};
+
+template <class Alloc, size_t Arity>
+class NotUsesAllocator : public UsesAllocatorTestBase<Alloc>
+{
+public:
+ // no allocator_type typedef provided
+
+ using Base = UsesAllocatorTestBase<Alloc>;
+ using CtorAlloc = typename Base::CtorAlloc;
+
+ NotUsesAllocator() : Base(&makeArgumentID<>()) {}
+
+ // Non-Uses Allocator Ctor
+ template <class ...Args, EnableIfB<sizeof...(Args) == Arity> = false>
+ NotUsesAllocator(Args&&... args) : Base(&makeArgumentID<Args&&...>()) {};
+
+ // Uses Allocator Arg Ctor
+ template <class ...Args>
+ NotUsesAllocator(std::allocator_arg_t tag, CtorAlloc const& alloc, Args&&... args)
+ : Base(tag, alloc, std::forward<Args>(args)...)
+ {}
+
+ // Uses Allocator Last Ctor
+ template <class ...Args, EnableIfB<sizeof...(Args) == Arity + 1> = false>
+ NotUsesAllocator(Args&&... args)
+ : Base(AllocLastTag{}, std::forward<Args>(args)...)
+ {}
+};
+
+#endif /* USES_ALLOC_TYPES_HPP */
More information about the cfe-commits
mailing list