[libcxx] r268829 - Add <experimental/memory_resource>

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Tue May 10 09:24:16 PDT 2016


r269070.

Sorry about that and thanks for you patience.

/Eric

On Tue, May 10, 2016 at 10:20 AM, Pete Cooper <peter_cooper at apple.com>
wrote:

> Hi Eric
>
> Any chance you will be able to commit the fix soon?  Otherwise would you
> be able to disable the problematic tests?
>
> Thanks,
> Pete
>
> On May 9, 2016, at 1:53 PM, Pete Cooper <peter_cooper at apple.com> wrote:
>
> Hi Eric
>
> Thanks for the fix.  I just tested it and it works.
>
> Cheers,
> Pete
>
> On May 9, 2016, at 1:36 PM, Eric Fiselier <eric at efcs.ca> wrote:
>
> Hi Pete,
>
> That's definitely of some use. Those test try to use the global resources
> very early/late in program startup/termination.
>
> It would seem the global's aren't getting initialized as early as I had
> hoped. I believe this should be fixed when D19992 gets committed (
> http://reviews.llvm.org/D19992)
> If possible could you try the patch, which requires re-building
> libc++experimental, at let me know if it works?
>
> Otherwise I'll either disable the tests or commit a fix tonight.
>
> Thanks
>
> /Eric
>
> On Mon, May 9, 2016 at 2:02 PM, Pete Cooper <peter_cooper at apple.com>
> wrote:
>
>> Hi Eric
>>
>> We’ve getting a failure internally after this patch (we’re on ToT so I
>> assume this is after r268839 too).
>>
>> 2 tests fail:
>>     libc++ ::
>> libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.pass.cpp
>>     libc++ ::
>> libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.pass.cpp
>>
>> I stepped through new_delete_resource_lifetime.pass.cpp to see whats
>> going on.  All I got to was that we are in the global constructor for
>> PODType, which calls allocate, which then crashes.
>>
>> The stack trace is:
>> * thread #1: tid = 0x5ebc621, 0x0000000100000b94
>> new_delete_resource_lifetime.pass.cpp.exe`POSType::POSType()
>> [inlined] std::experimental::fundamentals_v1::pmr::memory_resource::allocate(this=0x0000000100001198,
>> __bytes=42, __align=16) + 3 at memory_resource:106, queue =
>> 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10)
>>   * frame #0: 0x0000000100000b94
>> new_delete_resource_lifetime.pass.cpp.exe`POSType::POSType()
>> [inlined] std::experimental::fundamentals_v1::pmr::memory_resource::allocate(this=0x0000000100001198,
>> __bytes=42, __align=16) + 3 at memory_resource:106
>>     frame #1: 0x0000000100000b91
>> new_delete_resource_lifetime.pass.cpp.exe`POSType::POSType(this=0x0000000100001160)
>> + 81 at new_delete_resource_lifetime.pass.cpp:31
>>     frame #2: 0x0000000100000ad5
>> new_delete_resource_lifetime.pass.cpp.exe`POSType::POSType(this=0x0000000100001160)
>> + 21 at new_delete_resource_lifetime.pass.cpp:31
>>     frame #3: 0x00000001000009b4
>> new_delete_resource_lifetime.pass.cpp.exe`::__cxx_global_var_init() + 20
>> at new_delete_resource_lifetime.pass.cpp:42
>>     frame #4:
>> 0x0000000100000aa9 new_delete_resource_lifetime.pass.cpp.exe`_GLOBAL__sub_I_new_delete_resource_lifetime.pass.cpp
>> + 9 at new_delete_resource_lifetime.pass.cpp:0
>>
>> And from the disassembly, it looks like we have successfully constructed
>> constructed ‘res’ in this line:
>>   POSType() {res = ex::new_delete_resource(); ptr = res->allocate(42); n
>> = 42; }
>>
>> We then load from ‘res' which works, but then loading from 16 bytes in to
>> that data fails.  From the disassembly:
>>
>>     0x100000b40 <+0>:   pushq  %rbp
>>     0x100000b41 <+1>:   movq   %rsp, %rbp
>>     0x100000b44 <+4>:   subq   $0x30, %rsp
>>     0x100000b48 <+8>:   movq   %rdi, -0x20(%rbp)
>>     0x100000b4c <+12>:  movq   -0x20(%rbp), %rdi
>>     0x100000b50 <+16>:  movq   $0x0, (%rdi)
>>     0x100000b57 <+23>:  movq   $0x0, 0x8(%rdi)
>>     0x100000b5f <+31>:  movl   $0x0, 0x10(%rdi)
>>     0x100000b66 <+38>:  movq   %rdi, -0x28(%rbp)
>>     0x100000b6a <+42>:  callq  0x100000cc0               ;
>> std::experimental::fundamentals_v1::pmr::new_delete_resource()
>> // $rax is now ‘res'
>>     0x100000b6f <+47>:  movq   -0x28(%rbp), %rdi
>>     0x100000b73 <+51>:  movq   %rax, (%rdi)
>>     0x100000b76 <+54>:  movq   (%rdi), %rax
>>     0x100000b79 <+57>:  movq   %rax, -0x8(%rbp)
>>     0x100000b7d <+61>:  movq   $0x2a, -0x10(%rbp)
>>     0x100000b85 <+69>:  movq   $0x10, -0x18(%rbp)
>>     0x100000b8d <+77>:  movq   -0x8(%rbp), %rax
>> // $rax is again ‘res'
>>     0x100000b91 <+81>:  movq   (%rax), %rcx
>> // $rcx is *res which is possibly the base address of a vtable
>> ->  0x100000b94 <+84>:  movq   0x10(%rcx), %rcx
>> // But the above line crashes as $rcx is null
>>     0x100000b98 <+88>:  movq   -0x10(%rbp), %rsi
>>     0x100000b9c <+92>:  movq   -0x18(%rbp), %rdx
>>     0x100000ba0 <+96>:  movq   %rax, %rdi
>>     0x100000ba3 <+99>:  callq  *%rcx
>>     0x100000ba5 <+101>: movq   -0x28(%rbp), %rcx
>>     0x100000ba9 <+105>: movq   %rax, 0x8(%rcx)
>>     0x100000bad <+109>: movl   $0x2a, 0x10(%rcx)
>>     0x100000bb4 <+116>: addq   $0x30, %rsp
>>     0x100000bb8 <+120>: popq   %rbp
>>     0x100000bb9 <+121>: retq
>>     0x100000bba <+122>: nopw   (%rax,%rax)
>>
>> I hope some of this is of use.  If its difficult to fix, would it be
>> possible to disable these tests, until you have a fix available?
>>
>> Thanks,
>> Pete
>>
>> On May 6, 2016, at 7:40 PM, Eric Fiselier via cfe-commits <
>> cfe-commits at lists.llvm.org> wrote:
>>
>> Sorry about that. Fixed in r268839.
>>
>> On Fri, May 6, 2016 at 8:32 PM, Vitaly Buka <vitalybuka at google.com>
>> wrote:
>>
>>>
>>> http://lab.llvm.org:8011/builders/libcxx-libcxxabi-x86_64-linux-debian-noexceptions/builds/198/ is
>>> broken because of this patch
>>>
>>> On Fri, May 6, 2016 at 6:10 PM Eric Fiselier via cfe-commits <
>>> cfe-commits at lists.llvm.org> wrote:
>>>
>>>> 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>
>>>
>>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>>
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160510/138d71d5/attachment-0001.html>


More information about the cfe-commits mailing list