forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			103 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			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.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
// UNSUPPORTED: c++98, c++03, c++11
 | 
						|
 | 
						|
// <experimental/any>
 | 
						|
 | 
						|
// any(any &&) noexcept;
 | 
						|
 | 
						|
#include <experimental/any>
 | 
						|
#include <utility>
 | 
						|
#include <type_traits>
 | 
						|
#include <cassert>
 | 
						|
 | 
						|
#include "experimental_any_helpers.h"
 | 
						|
#include "count_new.hpp"
 | 
						|
#include "test_macros.h"
 | 
						|
 | 
						|
using std::experimental::any;
 | 
						|
using std::experimental::any_cast;
 | 
						|
 | 
						|
// Moves are always noexcept. The throws_on_move object
 | 
						|
// must be stored dynamically so the pointer is moved and
 | 
						|
// not the stored object.
 | 
						|
void test_move_does_not_throw()
 | 
						|
{
 | 
						|
#if !defined(TEST_HAS_NO_EXCEPTIONS)
 | 
						|
    assert(throws_on_move::count == 0);
 | 
						|
    {
 | 
						|
        throws_on_move v(42);
 | 
						|
        any a(v);
 | 
						|
        assert(throws_on_move::count == 2);
 | 
						|
        // No allocations should be performed after this point.
 | 
						|
        DisableAllocationGuard g; ((void)g);
 | 
						|
        try {
 | 
						|
            any const a2(std::move(a));
 | 
						|
            assertEmpty(a);
 | 
						|
            assertContains<throws_on_move>(a2, 42);
 | 
						|
        } catch (...) {
 | 
						|
            assert(false);
 | 
						|
        }
 | 
						|
        assert(throws_on_move::count == 1);
 | 
						|
        assertEmpty(a);
 | 
						|
    }
 | 
						|
    assert(throws_on_move::count == 0);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void test_move_empty() {
 | 
						|
    DisableAllocationGuard g; ((void)g); // no allocations should be performed.
 | 
						|
 | 
						|
    any a1;
 | 
						|
    any a2(std::move(a1));
 | 
						|
 | 
						|
    assertEmpty(a1);
 | 
						|
    assertEmpty(a2);
 | 
						|
}
 | 
						|
 | 
						|
template <class Type>
 | 
						|
void test_move() {
 | 
						|
    assert(Type::count == 0);
 | 
						|
    Type::reset();
 | 
						|
    {
 | 
						|
        any a((Type(42)));
 | 
						|
        assert(Type::count == 1);
 | 
						|
        assert(Type::copied == 0);
 | 
						|
        assert(Type::moved == 1);
 | 
						|
 | 
						|
        // Moving should not perform allocations since it must be noexcept.
 | 
						|
        DisableAllocationGuard g; ((void)g);
 | 
						|
 | 
						|
        any a2(std::move(a));
 | 
						|
 | 
						|
        assert(Type::moved >= 1); // zero or more move operations can be performed.
 | 
						|
        assert(Type::copied == 0); // no copies can be performed.
 | 
						|
        assert(Type::count == 1);
 | 
						|
        assertEmpty(a); // Moves are always destructive.
 | 
						|
        assertContains<Type>(a2, 42);
 | 
						|
    }
 | 
						|
    assert(Type::count == 0);
 | 
						|
}
 | 
						|
 | 
						|
int main()
 | 
						|
{
 | 
						|
    // noexcept test
 | 
						|
    {
 | 
						|
        static_assert(
 | 
						|
            std::is_nothrow_move_constructible<any>::value
 | 
						|
          , "any must be nothrow move constructible"
 | 
						|
          );
 | 
						|
    }
 | 
						|
    test_move<small>();
 | 
						|
    test_move<large>();
 | 
						|
    test_move_empty();
 | 
						|
    test_move_does_not_throw();
 | 
						|
}
 |