Index: include/experimental/any =================================================================== --- /dev/null +++ include/experimental/any @@ -0,0 +1,596 @@ +// -*- C++ -*- +//===------------------------------ any -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_ANY +#define _LIBCPP_EXPERIMENTAL_ANY + +/* + experimental/any synopsis + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { + + class bad_any_cast : public bad_cast + { + public: + virtual const char* what() const noexcept; + }; + + class any + { + public: + + // 6.3.1 any construct/destruct + any() noexcept; + + any(const any& other); + any(any&& other) noexcept; + + template + any(ValueType&& value); + + ~any(); + + // 6.3.2 any assignments + any& operator=(const any& rhs); + any& operator=(any&& rhs) noexcept; + + template + any& operator=(ValueType&& rhs); + + // 6.3.3 any modifiers + void clear() noexcept; + void swap(any& rhs) noexcept; + + // 6.3.4 any observers + bool empty() const noexcept; + const type_info& type() const noexcept; + }; + + // 6.4 Non-member functions + void swap(any& x, any& y) noexcept; + + template + ValueType any_cast(const any& operand); + template + ValueType any_cast(any& operand); + template + ValueType any_cast(any&& operand); + + template + const ValueType* any_cast(const any* operand) noexcept; + template + ValueType* any_cast(any* operand) noexcept; + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + +*/ + +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast +{ +public: + _LIBCPP_FUNC_VIS + virtual const char* what() const _NOEXCEPT; +}; + +_LIBCPP_END_NAMESPACE_LFTS + + +#if _LIBCPP_STD_VER > 11 + +#include +#include +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +_LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE +inline void __throw_bad_any_cast() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_any_cast(); +#else + _VSTD::abort(); +#endif +} + +// Forward declarations +class any; + +template +typename add_pointer::type>::type +any_cast(any const *) _NOEXCEPT; + +template +typename add_pointer<_ValueType>::type +any_cast(any *) _NOEXCEPT; + +namespace __any_imp +{ + typedef typename aligned_storage<3*sizeof(void*), alignment_of::value>::type + _Buffer; + + template + struct _IsSmallObject + : public integral_constant::value + % alignment_of<_Tp>::value == 0 + && is_nothrow_move_constructible<_Tp>::value + > + {}; + + enum class _Action + { + _Destroy, + _Copy, + _Move, + _Get, + _TypeInfo + }; + + template + struct _SmallHandler; + + template + struct _LargeHandler; + + template + using _Handler = typename conditional<_IsSmallObject<_Tp>::value + , _SmallHandler<_Tp> + , _LargeHandler<_Tp> + >::type; + template + using _EnableIfNotAny = typename + enable_if< + !is_same::type, any>::value + >::type; + +} // namespace __any_imp + +class any +{ +public: + // 6.3.1 any construct/destruct + _LIBCPP_INLINE_VISIBILITY + any() _NOEXCEPT : __h(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + any(any const & __other) : __h(nullptr) + { + if (__other.__h) __other.__call(_Action::_Copy, this); + } + + _LIBCPP_INLINE_VISIBILITY + any(any && __other) _NOEXCEPT : __h(nullptr) + { + if (__other.__h) __other.__call(_Action::_Move, this); + } + + template < + class _ValueType + , class = __any_imp::_EnableIfNotAny<_ValueType> + > + any(_ValueType && __value); + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + ~any() + { + this->clear(); + } + + // 6.3.2 any assignments + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + any & operator=(any const & __rhs) + { + any(__rhs).swap(*this); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + any & operator=(any && __rhs) _NOEXCEPT + { + any(_VSTD::move(__rhs)).swap(*this); + return *this; + } + + template < + class _ValueType + , class = __any_imp::_EnableIfNotAny<_ValueType> + > + any & operator=(_ValueType && __rhs); + + // 6.3.3 any modifiers + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT + { + if (__h) this->__call(_Action::_Destroy); + } + + void swap(any & __rhs) _NOEXCEPT; + + // 6.3.4 any observers + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + bool empty() const _NOEXCEPT + { + return __h == nullptr; + } + +#if !defined(_LIBCPP_NO_RTTI) + _LIBCPP_INLINE_VISIBILITY + const type_info & type() const _NOEXCEPT + { + if (__h) { + return *static_cast(this->__call(_Action::_TypeInfo)); + } else { + return typeid(void); + } + } +#endif + +private: + typedef __any_imp::_Action _Action; + + typedef void* (*_HandleFuncPtr)(_Action, any const *, any *, const type_info *); + + union _Storage + { + void * __ptr; + __any_imp::_Buffer __buf; + }; + + _LIBCPP_ALWAYS_INLINE + void * __call(_Action __a, any * __other = nullptr, + type_info const * __info = nullptr) const + { + return __h(__a, this, __other, __info); + } + + _LIBCPP_ALWAYS_INLINE + void * __call(_Action __a, any * __other = nullptr, + type_info const * __info = nullptr) + { + return __h(__a, this, __other, __info); + } + + template + friend struct __any_imp::_SmallHandler; + template + friend struct __any_imp::_LargeHandler; + + template + friend typename add_pointer::type>::type + any_cast(any const *) _NOEXCEPT; + + template + friend typename add_pointer<_ValueType>::type + any_cast(any *) _NOEXCEPT; + + _HandleFuncPtr __h; + _Storage __s; +}; + +namespace __any_imp +{ + + template + struct _LIBCPP_TYPE_VIS_ONLY _SmallHandler + { + _LIBCPP_INLINE_VISIBILITY + static void* __handle(_Action __act, any const * __this, any * __other, + type_info const * __info) + { + switch (__act) + { + case _Action::_Destroy: + __destroy(const_cast(*__this)); + return nullptr; + case _Action::_Copy: + __copy(*__this, *__other); + return nullptr; + case _Action::_Move: + __move(const_cast(*__this), *__other); + return nullptr; + case _Action::_Get: + return __get(const_cast(*__this), __info); + case _Action::_TypeInfo: + return __type_info(); + } + } + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static void __create(any & __dest, _Up && __v) + { + ::new (static_cast(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Up>(__v)); + __dest.__h = &_SmallHandler::__handle; + } + + private: + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __destroy(any & __this) + { + _Tp & __value = *static_cast<_Tp *>(static_cast(&__this.__s.__buf)); + __value.~_Tp(); + __this.__h = nullptr; + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __copy(any const & __this, any & __dest) + { + _SmallHandler::__create(__dest, *static_cast<_Tp const *>( + static_cast(&__this.__s.__buf))); + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __move(any & __this, any & __dest) + { + _SmallHandler::__create(__dest, _VSTD::move( + *static_cast<_Tp*>(static_cast(&__this.__s.__buf)))); + __destroy(__this); + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void* __get(any & __this, type_info const * __info) + { +#if !defined(_LIBCPP_NO_RTTI) + if (typeid(_Tp) == *__info) { + return static_cast(&__this.__s.__buf); + } + return nullptr; +#else + return static_cast(&__this.__s.__buf); +#endif + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void* __type_info() + { +#if !defined(_LIBCPP_NO_RTTI) + return const_cast(static_cast(&typeid(_Tp))); +#else + return nullptr; +#endif + } + }; + + template + struct _LIBCPP_TYPE_VIS_ONLY _LargeHandler + { + _LIBCPP_INLINE_VISIBILITY + static void* __handle(_Action __act, any const * __this, any * __other, + type_info const * __info) + { + switch (__act) + { + case _Action::_Destroy: + __destroy(const_cast(*__this)); + return nullptr; + case _Action::_Copy: + __copy(*__this, *__other); + return nullptr; + case _Action::_Move: + __move(const_cast(*__this), *__other); + return nullptr; + case _Action::_Get: + return __get(const_cast(*__this), __info); + case _Action::_TypeInfo: + return __type_info(); + } + } + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static void __create(any & __dest, _Up && __v) + { + typedef allocator<_Tp> _Alloc; + typedef __allocator_destructor<_Alloc> _Dp; + _Alloc __a; + unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Up>(__v)); + __dest.__s.__ptr = __hold.release(); + __dest.__h = &_LargeHandler::__handle; + } + + private: + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __destroy(any & __this) + { + delete static_cast<_Tp*>(__this.__s.__ptr); + __this.__h = nullptr; + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __copy(any const & __this, any & __dest) + { + _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr)); + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __move(any & __this, any & __dest) + { + __dest.__s.__ptr = __this.__s.__ptr; + __dest.__h = &_LargeHandler::__handle; + __this.__h = nullptr; + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void* __get(any & __this, type_info const * __info) + { +#if !defined(_LIBCPP_NO_RTTI) + if (typeid(_Tp) == *__info) { + return static_cast(__this.__s.__ptr); + } + return nullptr; +#else + return static_cast(__this.__s.__ptr); +#endif + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void* __type_info() + { +#if !defined(_LIBCPP_NO_RTTI) + return const_cast(static_cast(&typeid(_Tp))); +#else + return nullptr; +#endif + } + }; + +} // namespace __any_imp + + +template +_LIBCPP_INLINE_VISIBILITY +any::any(_ValueType && __v) : __h(nullptr) +{ + typedef typename decay<_ValueType>::type _Tp; + static_assert(is_copy_constructible<_Tp>::value, + "_ValueType must be CopyConstructible."); + typedef __any_imp::_Handler<_Tp> _HandlerType; + _HandlerType::__create(*this, _VSTD::forward<_ValueType>(__v)); +} + +template +_LIBCPP_INLINE_VISIBILITY +any & any::operator=(_ValueType && __v) +{ + typedef typename decay<_ValueType>::type _Tp; + static_assert(is_copy_constructible<_Tp>::value, + "_ValueType must be CopyConstructible."); + any(_VSTD::forward<_ValueType>(__v)).swap(*this); + return *this; +} + +inline _LIBCPP_INLINE_VISIBILITY +void any::swap(any & __rhs) _NOEXCEPT +{ + if (__h && __rhs.__h) { + any __tmp; + __rhs.__call(_Action::_Move, &__tmp); + this->__call(_Action::_Move, &__rhs); + __tmp.__call(_Action::_Move, this); + } + else if (__h) { + this->__call(_Action::_Move, &__rhs); + } + else if (__rhs.__h) { + __rhs.__call(_Action::_Move, this); + } +} + +// 6.4 Non-member functions + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE +void swap(any & __lhs, any & __rhs) _NOEXCEPT +{ + __lhs.swap(__rhs); +} + +template +_LIBCPP_INLINE_VISIBILITY +_ValueType any_cast(any const & __v) +{ + static_assert( + is_reference<_ValueType>::value + || is_copy_constructible<_ValueType>::value, + "_ValueType is required to be a reference or a CopyConstructible type."); + typedef typename add_const::type>::type + _Tp; + _Tp * __tmp = any_cast<_Tp>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return *__tmp; +} + +template +_LIBCPP_INLINE_VISIBILITY +_ValueType any_cast(any & __v) +{ + static_assert( + is_reference<_ValueType>::value + || is_copy_constructible<_ValueType>::value, + "_ValueType is required to be a reference or a CopyConstructible type."); + typedef typename remove_reference<_ValueType>::type _Tp; + _Tp * __tmp = any_cast<_Tp>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return *__tmp; +} + +template +_LIBCPP_INLINE_VISIBILITY +_ValueType any_cast(any && __v) +{ + static_assert( + is_reference<_ValueType>::value + || is_copy_constructible<_ValueType>::value, + "_ValueType is required to be a reference or a CopyConstructible type."); + typedef typename remove_reference<_ValueType>::type _Tp; + _Tp * __tmp = any_cast<_Tp>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return *__tmp; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE +typename add_pointer::type>::type +any_cast(any const * __any) _NOEXCEPT +{ + static_assert(!is_reference<_ValueType>::value, + "_ValueType may not be a reference."); + return any_cast<_ValueType>(const_cast(__any)); +} + +template +_LIBCPP_INLINE_VISIBILITY +typename add_pointer<_ValueType>::type +any_cast(any * __any) _NOEXCEPT +{ + using __any_imp::_Action; + static_assert(!is_reference<_ValueType>::value, + "_ValueType may not be a reference."); + typedef typename add_pointer<_ValueType>::type _ReturnType; + if (__any && __any->__h) { + + return static_cast<_ReturnType>( + __any->__call(_Action::_Get, nullptr, +#if !defined(_LIBCPP_NO_RTTI) + &typeid(_ValueType) +#else + nullptr +#endif + )); + + } + return nullptr; +} + +_LIBCPP_END_NAMESPACE_LFTS + +#endif // _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_EXPERIMENTAL_ANY Index: src/any.cpp =================================================================== --- /dev/null +++ src/any.cpp @@ -0,0 +1,19 @@ +//===---------------------------- any.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/any" + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +const char* bad_any_cast::what() const _NOEXCEPT +{ + return "bad any cast"; +} + +_LIBCPP_END_NAMESPACE_LFTS Index: test/libcxx/experimental/any/any.class/any.assign/copy_large_throws.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/copy_large_throws.pass.cpp @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any const &); + +// Test throwing from a stored values copy constructor during copy assignment. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + any const a2((large_throws_on_copy())); + assert(large_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(!a2.empty()); + assert(a2.type() == typeid(large_throws_on_copy)); + + assert(large_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large_throws_on_copy::count == 0); + globalMemCounter.delete_called = 0; + // const lvalue to small + { + small const s(1); + any a(s); + any const a2((large_throws_on_copy())); + assert(large_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(!a2.empty()); + assert(a2.type() == typeid(large_throws_on_copy)); + assert(large_throws_on_copy::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(small::count == 0); + assert(large_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + // const lvalue to large + { + large const s(1); + any a(s); + any const a2((large_throws_on_copy())); + assert(large_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(!a2.empty()); + assert(a2.type() == typeid(large_throws_on_copy)); + assert(large_throws_on_copy::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(2)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(large::count == 0); + assert(large_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.assign/copy_self.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/copy_self.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any const &); + +// Test self copy assignment. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any a; + a = a; + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small + { + small const s(1); + any a(s); + a = a; + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large + { + large const s(1); + any a(s); + a = a; + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.assign/copy_small_throws.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/copy_small_throws.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// + +// any& operator=(any const &); + +// Test throwing from a "small" values copy constructor during copy assignment. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + any const a2((small_throws_on_copy())); + assert(small_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(!a2.empty()); + assert(a2.type() == typeid(small_throws_on_copy)); + + assert(small_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(small_throws_on_copy::count == 0); + globalMemCounter.delete_called = 0; + // const lvalue to small + { + small const s(1); + any a(s); + any const a2((small_throws_on_copy())); + assert(small_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(!a2.empty()); + assert(a2.type() == typeid(small_throws_on_copy)); + assert(small_throws_on_copy::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(0)); + } + assert(small::count == 0); + assert(small_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + // const lvalue to large + { + large const s(1); + any a(s); + any const a2((small_throws_on_copy())); + assert(small_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(!a2.empty()); + assert(a2.type() == typeid(small_throws_on_copy)); + assert(small_throws_on_copy::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(0)); + } + assert(large::count == 0); + assert(small_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + +} Index: test/libcxx/experimental/any/any.class/any.assign/copy_to_empty.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/copy_to_empty.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any const &); + +// Test copy assignment to an empty any. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any a; + any const a2; + a = a2; + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small + { + any a; + small const s(1); + any const a2(s); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2) == s); + + assert(small::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large + { + any a; + large const s(1); + any const a2(s); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + + assert(!a2.empty()); + assert(a2.type() == typeid(large)); + assert(any_cast(a2) == s); + + assert(large::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(2)); + } + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.assign/copy_to_large.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/copy_to_large.pass.cpp @@ -0,0 +1,94 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any const &); + +// Test copy assignment to an any instance storing a large value. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + large1 const s1(1); + any a(s1); + any const a2; + + a = a2; + + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + + assert(large1::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small + { + large1 const s1(1); + any a(s1); + small const s2(2); + any const a2(s2); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s2); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2) == s2); + + assert(large1::count == 1); + assert(small::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(large1::count == 0); + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + // large + { + large1 const s1(1); + any a(s1); + large2 const l(1); + any const a2(l); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(large2)); + assert(any_cast(a) == l); + + assert(!a2.empty()); + assert(a2.type() == typeid(large2)); + assert(any_cast(a2) == l); + + assert(large1::count == 1); + assert(large2::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(2)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(large1::count == 0); + assert(large2::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.assign/copy_to_small.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/copy_to_small.pass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any const &); + +// Test copy assignment to an any instance storing a small value. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + small1 const s1(1); + any a(s1); + any const a2; + + a = a2; + + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + + assert(small1::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small + { + small1 const s1(1); + any a(s1); + small2 const s2(2); + any const a2(s2); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(small2)); + assert(any_cast(a) == s2); + + assert(!a2.empty()); + assert(a2.type() == typeid(small2)); + assert(any_cast(a2) == s2); + + assert(small1::count == 1); + assert(small2::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small1::count == 0); + assert(small2::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large + { + small1 const s1(1); + any a(s1); + large const l(1); + any const a2(l); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + + assert(!a2.empty()); + assert(a2.type() == typeid(large)); + assert(any_cast(a2) == l); + + assert(small1::count == 1); + assert(large::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(2)); + } + assert(small1::count == 0); + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.assign/large_value_copy_throws.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/large_value_copy_throws.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value&&); + +// Test throwing an exception during value copy assignment of a "large" value. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + large_throws_on_copy v; + assert(large_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(large_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large_throws_on_copy::count == 0); + globalMemCounter.delete_called = 0; + // const lvalue to small + { + small const s(1); + any a(s); + large_throws_on_copy v; + assert(large_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(large_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(small::count == 0); + assert(large_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + // const lvalue to large + { + large const s(1); + any a(s); + large_throws_on_copy v; + assert(large_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(large_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(large::count == 0); + assert(large_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + +} Index: test/libcxx/experimental/any/any.class/any.assign/move_self.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/move_self.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any &&); + +// Test self move assignment + +#include +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any a; + a = std::move(a); + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small + { + small const s(1); + any a(s); + a = std::move(a); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + + assert(small::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large + { + large const s(1); + any a(s); + + a = std::move(a); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + + assert(large::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + +} Index: test/libcxx/experimental/any/any.class/any.assign/move_to_empty.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/move_to_empty.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// + +// any& operator=(any &&); + +// Test move assignment to an empty any object. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any a; + any a2; + + a = std::move(a2); + + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small + { + any a; + small const s(1); + any a2(s); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + + assert(small::count == 2 || small::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large + { + any a; + large const s(1); + any a2(s); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + + assert(large::count == 2 || large::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + +} Index: test/libcxx/experimental/any/any.class/any.assign/move_to_large.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/move_to_large.pass.cpp @@ -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, c++11 + +// + +// any& operator=(any &&) noexcept + +// Test move assignment to an any instance storing a large value. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + large1 const s1(1); + any a(s1); + any a2; + + a = std::move(a2); + + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(large1::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small + { + large1 const s1(1); + any a(s1); + small const s2(2); + any a2(s2); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s2); + + assert(large1::count == 1); + assert(small::count == 2 || small::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(large1::count == 0); + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + // large + { + large1 const s1(1); + any a(s1); + large2 const l(1); + any a2(l); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(large2)); + assert(any_cast(a) == l); + + assert(large1::count == 1); + assert(large2::count == 2 || large2::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(large1::count == 0); + assert(large2::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.assign/move_to_small.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/move_to_small.pass.cpp @@ -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, c++11 + +// + +// any& operator=(any &&) noexcept + +// Test move assignment to an any instance storing a small value. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + small1 const s1(1); + any a(s1); + any a2; + + a = std::move(a2); + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(small1::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small + { + small1 const s1(1); + any a(s1); + small2 const s2(2); + any a2(s2); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(small2)); + assert(any_cast(a) == s2); + + assert(small1::count == 1); + assert(small2::count == 2 || small2::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small1::count == 0); + assert(small2::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large + { + small1 const s1(1); + any a(s1); + large const l(1); + any a2(l); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + + assert(small1::count == 1); + assert(large::count == 2 || large::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(small1::count == 0); + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + +} Index: test/libcxx/experimental/any/any.class/any.assign/small_value_copy_throws.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/small_value_copy_throws.pass.cpp @@ -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, c++11 + +// + +// template +// any& operator=(Value&&); + +// Test throwing during the value copy assignment of a "small" object. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + small_throws_on_copy v; + assert(small_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(small_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(small_throws_on_copy::count == 0); + globalMemCounter.delete_called = 0; + // const lvalue to small + { + small const s(1); + any a(s); + small_throws_on_copy v; + assert(small_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(small_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(0)); + } + assert(small::count == 0); + assert(small_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + // const lvalue to large + { + large const s(1); + any a(s); + small_throws_on_copy v; + assert(small_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(small_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(0)); + } + assert(large::count == 0); + assert(small_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; +} Index: test/libcxx/experimental/any/any.class/any.assign/value_move_throws.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/value_move_throws.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value&&); + +// Test throwing an exception during value move assignment. + +#include +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + throws_on_move v; + assert(throws_on_move::count == 1); + + try { + a = std::move(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(throws_on_move::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(throws_on_move::count == 0); + globalMemCounter.delete_called = 0; + // const lvalue to small + { + small const s(1); + any a(s); + throws_on_move v; + assert(throws_on_move::count == 1); + + try { + a = std::move(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(throws_on_move::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(small::count == 0); + assert(throws_on_move::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + // const lvalue to large + { + large const s(1); + any a(s); + throws_on_move v; + assert(throws_on_move::count == 1); + + try { + a = std::move(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(throws_on_move::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(large::count == 0); + assert(throws_on_move::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; +} Index: test/libcxx/experimental/any/any.class/any.assign/value_to_empty.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/value_to_empty.pass.cpp @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value &&); + +// Test value assignment into an empty any instance. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small const lvalue + { + any a; + small const s(1); + + a = s; + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small non-const rvalue + { + any a; + small s(1); + + a = std::move(s); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a).value == 1); + + assert(s.value == 0); + + assert(small::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large const lvalue + { + any a; + large const s(1); + + a = s; + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + + assert(large::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large non-const rvalue + { + any a; + large s(1); + + a = std::move(s); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a).value == 1); + + assert(s.value == 0); + + assert(large::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.assign/value_to_large.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/value_to_large.pass.cpp @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value&&); + +// Test value assignment into an any object storing an instance of a "large" +// object. + + +#include +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small const lvalue + { + large1 const s1(1); + any a(s1); + small const s2(2); + + a = s2; + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s2); + + assert(large1::count == 1); + assert(small::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + // small non-const rvalue + { + large1 const s1(1); + any a(s1); + small s2(2); + + a = std::move(s2); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a).value == 2); + + assert(s2.value == 0); + + assert(large1::count == 1); + assert(small::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(large1::count == 0); + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + // large const lvalue + { + large1 const s1(1); + any a(s1); + large2 const l(1); + + a = l; + + assert(!a.empty()); + assert(a.type() == typeid(large2)); + assert(any_cast(a) == l); + + assert(large1::count == 1); + assert(large2::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(large1::count == 0); + assert(large2::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; + // large non-const rvalue + { + large1 const s1(1); + any a(s1); + large2 l(1); + + a = std::move(l); + + assert(!a.empty()); + assert(a.type() == typeid(large2)); + assert(any_cast(a).value == 1); + + assert(l.value == 0); + + assert(large1::count == 1); + assert(large2::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(large1::count == 0); + assert(large2::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + globalMemCounter.delete_called = 0; +} Index: test/libcxx/experimental/any/any.class/any.assign/value_to_small.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.assign/value_to_small.pass.cpp @@ -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, c++11 + +// + +// template +// any & operator=(Value &&); + +// Test value assignment into an any object storing an instance of a "small" +// object. + +#include +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small const lvalue + { + small1 const s1(1); + any a(s1); + small2 const s2(2); + + a = s2; + + assert(!a.empty()); + assert(a.type() == typeid(small2)); + assert(any_cast(a) == s2); + + assert(small1::count == 1); + assert(small2::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small1::count == 0); + assert(small2::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small non-const rvalue + { + small1 const s1(1); + any a(s1); + small2 s2(2); + + a = std::move(s2); + + assert(!a.empty()); + assert(a.type() == typeid(small2)); + assert(any_cast(a).value == 2); + + assert(s2.value == 0); + + assert(small1::count == 1); + assert(small2::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small1::count == 0); + assert(small2::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large const lvalue + { + small1 const s1(1); + any a(s1); + large const l(2); + + a = l; + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + + assert(small1::count == 1); + assert(large::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(small1::count == 0); + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large non-const rvalue + { + small1 const s1(1); + any a(s1); + large l(2); + + a = std::move(l); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a).value == 2); + + assert(l.value == 0); + + assert(small1::count == 1); + assert(large::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(small1::count == 0); + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + +} Index: test/libcxx/experimental/any/any.class/any.cons/copy.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.cons/copy.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// + +// any(any const &); + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any const a1; + + any const a2(a1); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small value + { + small const s(1); + any const a(s); + + any a2(a); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2) == s); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + + assert(small::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large value + { + large const l(1); + any const a(l); + + any a2(a); + + assert(!a2.empty()); + assert(a2.type() == typeid(large)); + assert(any_cast(a2) == l); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + + assert(large::count == 3); + assert(globalMemCounter.checkOutstandingNewEq(2)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.cons/copy_throws.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.cons/copy_throws.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template any(any const &); + +// Test throwing an exception during copy construction. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + { + any const a((small_throws_on_copy())); + assert(small_throws_on_copy::count == 1); + try { + any const a2(a); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(small_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + + // check that we didn't try and allocate. + assert(globalMemCounter.checkNewCalledEq(0)); + } + assert(small_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + { + any const a((large_throws_on_copy())); + assert(large_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + try { + any const a2(a); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(large_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large_throws_on_copy::count == 0); +} Index: test/libcxx/experimental/any/any.class/any.cons/move.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.cons/move.pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any(any &&) noexcept; + +#include +#include +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // noexcept test + { + static_assert( + std::is_nothrow_move_constructible::value + , "any must be nothrow move constructible" + ); + } + // empty object + { + any a1; + + any a2(std::move(a1)); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small object + { + small s(1); + any a1(s); + + any a2(std::move(a1)); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2) == s); + assert(small::copied == 1); + assert(small::moved == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large object + { + large l(1); + any a1(l); + + any a2(std::move(a1)); + + assert(!a2.empty()); + assert(a2.type() == typeid(large)); + assert(any_cast(a2) == l); + // NOTE: We cannot check the count of large + // since we just do a pointer swap + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.cons/move_throws.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.cons/move_throws.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// + +// any(any &&) noexcept + +// Test throwing an exception during move construction. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + { + throws_on_move v; + any a(v); + assert(throws_on_move::count == 2); + + // Check that we put a throws-on-move type on the heap. + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkNewCalledEq(1)); + + // Moves are always noexcept. + try { + any const a2(std::move(a)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(a2.type() == typeid(throws_on_move)); + } catch (...) { + assert(false); + } + + // Assert that we didn't allocate again. + assert(globalMemCounter.checkNewCalledEq(1)); + } + assert(throws_on_move::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.cons/value.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.cons/value.pass.cpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template any(Value &&) + +// Test construction from a value. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small const lvalue + { + small const s(1); + any const a(s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + assert(small::copied == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + small::copied = 0; + small::moved = 0; + // small non-const lvalue + { + small s(1); + any const a(s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + assert(small::copied == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + small::copied = 0; + small::moved = 0; + // small non-const rvalue + { + small s(1); + any const a(static_cast(s)); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(s.value == 0); + assert(any_cast(a).value == 1); + assert(small::count == 2); + assert(small::copied == 0); + assert(small::moved == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(small::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + small::copied = 0; + small::moved = 0; + // large const lvalue + { + large const l(1); + any const a(l); + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(large::copied == 1); + assert(large::moved == 0); + } + assert(large::count == 0); + large::moved = 0; + large::copied = 0; + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large non-const lvalue + { + large l(1); + any const a(l); + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(large::copied == 1); + assert(large::moved == 0); + } + assert(large::count == 0); + large::moved = 0; + large::copied = 0; + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large non-const rvalue + { + large l(1); + any const a(static_cast(l)); + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(l.value == 0); + assert(any_cast(a).value == 1); + assert(large::count == 2); + assert(large::moved == 1); + assert(large::copied == 0); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.cons/value_copy_throws.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.cons/value_copy_throws.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template any(Value &&); + +// Test throwing an exception while copying a value. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + + +int main() +{ + using std::experimental::any; + { + small_throws_on_copy v; + assert(small_throws_on_copy::count == 1); + try { + any const a(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(small_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + + // check that we didn't try and allocate. + assert(globalMemCounter.checkNewCalledEq(0)); + } + assert(small_throws_on_copy::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + { + large_throws_on_copy v; + assert(large_throws_on_copy::count == 1); + try { + any const a(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(large_throws_on_copy::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // Check that we did try and allocate and we deleted it. + assert(globalMemCounter.checkNewCalledEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large_throws_on_copy::count == 0); +} Index: test/libcxx/experimental/any/any.class/any.cons/value_move_throws.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.cons/value_move_throws.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// + +// template any(Value &&) + +// Test throwing an exception while moving a value. + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + { + throws_on_move v; + assert(throws_on_move::count == 1); + try { + any const a(std::move(v)); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(throws_on_move::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // check that we tried to allocate since throws_on_move should not be a + // small object. + assert(globalMemCounter.checkNewCalledEq(1)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + } + assert(throws_on_move::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + +} Index: test/libcxx/experimental/any/any.class/any.modifiers/clear.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.modifiers/clear.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::clear() noexcept + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any a; + + // noexcept check + static_assert( + noexcept(a.clear()) + , "any.clear() must be noexcept" + ); + + a.clear(); + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // small object + { + small const s(1); + any a(s); + + a.clear(); + + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(any_cast(&a) == nullptr); + assert(small::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large object + { + large const l(1); + any a(l); + + a.clear(); + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(any_cast(&a) == nullptr); + assert(large::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.modifiers/swap_empty_empty.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.modifiers/swap_empty_empty.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::swap(any &) noexcept + +// Test swap(empty, empty) + +#include +#include +#include "count_new.hpp" + +int main() +{ + using std::experimental::any; + { + any a1; + any a2; + + a1.swap(a2); + + assert(a1.empty()); + assert(a1.type() == typeid(void)); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.modifiers/swap_empty_large.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.modifiers/swap_empty_large.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::swap(any &) noexcept + +// test swap(empty, large) and swap(large, empty) + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty.swap(large) + { + any a1; + any a2(large{1}); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(large)); + assert(any_cast(a1).value == 1); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(large::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 0); + // large.swap(empty) + { + any a1; + any a2(large{1}); + + a2.swap(a1); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + + assert(!a1.empty()); + assert(a1.type() == typeid(large)); + assert(any_cast(a1).value == 1); + assert(large::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 0); +} Index: test/libcxx/experimental/any/any.class/any.modifiers/swap_empty_small.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.modifiers/swap_empty_small.pass.cpp @@ -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, c++11 + +// + +// any::swap(any &) noexcept + +// Test swap(empty, small) and swap(small, empty) + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty.swap(small) + { + any a1; + any a2(small{1}); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(small)); + assert(any_cast(a1).value == 1); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(small::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(small::count == 0); + // small.swap(empty) + { + any a1; + any a2(small{1}); + + a2.swap(a1); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(!a1.empty()); + assert(a1.type() == typeid(small)); + assert(any_cast(a1).value == 1); + assert(small::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(small::count == 0); +} Index: test/libcxx/experimental/any/any.class/any.modifiers/swap_large_large.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.modifiers/swap_large_large.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::swap(any &) noexcept + +// Test swap(large, large) + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // large1.swap(large2) + { + any a1((large1(1))); + any a2((large2(2))); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(large2)); + assert(any_cast(a1).value == 2); + assert(large2::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(large1)); + assert(any_cast(a2).value == 1); + assert(large1::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(2)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large1::count == 0); + assert(large2::count == 0); + // large2.swap(large1) + { + any a1((large1(1))); + any a2((large2(2))); + + a2.swap(a1); + + assert(!a1.empty()); + assert(a1.type() == typeid(large2)); + assert(any_cast(a1).value == 2); + assert(large2::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(large1)); + assert(any_cast(a2).value == 1); + assert(large1::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(2)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large1::count == 0); + assert(large2::count == 0); +} Index: test/libcxx/experimental/any/any.class/any.modifiers/swap_large_small.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.modifiers/swap_large_small.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::swap(any &) noexcept + +// Test swap(large, small) and swap(small, large) + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small.swap(large) + { + any a1((small(1))); + any a2(large{2}); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(large)); + assert(any_cast(a1).value == 2); + assert(large::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2).value == 1); + assert(small::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(small::count == 0); + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + // large.swap(small) + { + any a1((small(1))); + any a2((large(2))); + + a2.swap(a1); + + assert(!a1.empty()); + assert(a1.type() == typeid(large)); + assert(any_cast(a1).value == 2); + assert(large::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2).value == 1); + assert(small::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(1)); + } + assert(small::count == 0); + assert(large::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/libcxx/experimental/any/any.class/any.modifiers/swap_small_small.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.modifiers/swap_small_small.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::swap(any &) noexcept + +// Test swap(small, small) + +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small1.swap(small2) + { + any a1((small1(1))); + any a2((small2(2))); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(small2)); + assert(any_cast(a1).value == 2); + assert(small2::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(small1)); + assert(any_cast(a2).value == 1); + assert(small1::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(small1::count == 0); + assert(small2::count == 0); + // small2.swap(small1) + { + any a1((small1(1))); + any a2((small2(2))); + + a2.swap(a1); + + assert(!a1.empty()); + assert(a1.type() == typeid(small2)); + assert(any_cast(a1).value == 2); + assert(small2::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(small1)); + assert(any_cast(a2).value == 1); + assert(small1::count == 1); + + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(small1::count == 0); + assert(small2::count == 0); +} Index: test/libcxx/experimental/any/any.class/any.observers/nothing_to_do.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/any.observers/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +int main () {} Index: test/libcxx/experimental/any/any.class/nothing_to_do.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.class/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +int main () {} Index: test/libcxx/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/nothing_to_do.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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() +{ +} Index: test/libcxx/experimental/any/any.nonmembers/any.cast/any.cast.throws/nothing_to_do.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.nonmembers/any.cast/any.cast.throws/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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() +{ +} Index: test/libcxx/experimental/any/any.nonmembers/any.cast/nothing_to_do.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/any.nonmembers/any.cast/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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() +{ +} Index: test/libcxx/experimental/any/size_and_alignment.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/size_and_alignment.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// Check that the size and alignment of any are what we expect. + +#include + +int main() +{ + using std::experimental::any; + static_assert(sizeof(any) == sizeof(void*)*4, ""); + static_assert(alignof(any) == alignof(void*), ""); +} Index: test/libcxx/experimental/any/small_type.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/small_type.pass.cpp @@ -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, c++11 + +// + +// Check that the size and alignment of any are what we expect. + +#include +#include "any_types.hpp" + +class SmallThrowsDtor +{ +public: + SmallThrowsDtor() {} + SmallThrowsDtor(SmallThrowsDtor const &) noexcept {} + SmallThrowsDtor(SmallThrowsDtor &&) noexcept {} + ~SmallThrowsDtor() noexcept(false) {} +}; + +int main() +{ + using std::experimental::any; + using std::experimental::__any_imp::_IsSmallObject; + static_assert(_IsSmallObject::value, ""); + static_assert(_IsSmallObject::value, ""); + static_assert(!_IsSmallObject::value, ""); + static_assert(!_IsSmallObject::value, ""); + // long double is over aligned. + static_assert(alignof(long double) > alignof(void*), ""); + static_assert(!_IsSmallObject::value, ""); +} Index: test/libcxx/experimental/any/version.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/experimental/any/version.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} Index: test/std/experimental/any/any.class/any.assign/copy_large_throws.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/copy_large_throws.pass.cpp @@ -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, c++11 + +// + +// any& operator=(any const &); + +// Test throwing from a stored values copy constructor during copy assignment. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + any const a2((large_throws_on_copy())); + assert(large_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(!a2.empty()); + assert(a2.type() == typeid(large_throws_on_copy)); + + assert(large_throws_on_copy::count == 1); + } + assert(large_throws_on_copy::count == 0); + // const lvalue to small + { + small const s(1); + any a(s); + any const a2((large_throws_on_copy())); + assert(large_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(!a2.empty()); + assert(a2.type() == typeid(large_throws_on_copy)); + assert(large_throws_on_copy::count == 1); + } + assert(small::count == 0); + assert(large_throws_on_copy::count == 0); + // const lvalue to large + { + large const s(1); + any a(s); + any const a2((large_throws_on_copy())); + assert(large_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(!a2.empty()); + assert(a2.type() == typeid(large_throws_on_copy)); + assert(large_throws_on_copy::count == 1); + } + assert(large::count == 0); + assert(large_throws_on_copy::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/copy_self.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/copy_self.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any const &); + +// Test self copy assignment. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any a; + a = a; + assert(a.empty()); + assert(a.type() == typeid(void)); + } + // small + { + small const s(1); + any a(s); + a = a; + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + } + assert(small::count == 0); + // large + { + large const s(1); + any a(s); + a = a; + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + } + assert(large::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/copy_small_throws.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/copy_small_throws.pass.cpp @@ -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, c++11 + +// + +// any& operator=(any const &); + +// Test throwing from a "small" values copy constructor during copy assignment. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + any const a2((small_throws_on_copy())); + assert(small_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(!a2.empty()); + assert(a2.type() == typeid(small_throws_on_copy)); + + assert(small_throws_on_copy::count == 1); + } + assert(small_throws_on_copy::count == 0); + // const lvalue to small + { + small const s(1); + any a(s); + any const a2((small_throws_on_copy())); + assert(small_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(!a2.empty()); + assert(a2.type() == typeid(small_throws_on_copy)); + assert(small_throws_on_copy::count == 1); + } + assert(small::count == 0); + assert(small_throws_on_copy::count == 0); + // const lvalue to large + { + large const s(1); + any a(s); + any const a2((small_throws_on_copy())); + assert(small_throws_on_copy::count == 1); + + try { + a = a2; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(!a2.empty()); + assert(a2.type() == typeid(small_throws_on_copy)); + assert(small_throws_on_copy::count == 1); + } + assert(large::count == 0); + assert(small_throws_on_copy::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/copy_to_empty.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/copy_to_empty.pass.cpp @@ -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, c++11 + +// + +// any& operator=(any const &); + +// Test copy assignment to an empty any. + +#include +#include +#include "any_types.hpp" + + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any a; + any const a2; + a = a2; + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + } + // small + { + any a; + small const s(1); + any const a2(s); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2) == s); + + assert(small::count == 3); + } + assert(small::count == 0); + // large + { + any a; + large const s(1); + any const a2(s); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + + assert(!a2.empty()); + assert(a2.type() == typeid(large)); + assert(any_cast(a2) == s); + + assert(large::count == 3); + } + assert(large::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/copy_to_large.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/copy_to_large.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any const &); + +// Test copy assignment to an any instance storing a large value. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + large1 const s1(1); + any a(s1); + any const a2; + + a = a2; + + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + + assert(large1::count == 1); + } + // small + { + large1 const s1(1); + any a(s1); + small const s2(2); + any const a2(s2); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s2); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2) == s2); + + assert(large1::count == 1); + assert(small::count == 3); + } + assert(large1::count == 0); + assert(small::count == 0); + // large + { + large1 const s1(1); + any a(s1); + large2 const l(1); + any const a2(l); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(large2)); + assert(any_cast(a) == l); + + assert(!a2.empty()); + assert(a2.type() == typeid(large2)); + assert(any_cast(a2) == l); + + assert(large1::count == 1); + assert(large2::count == 3); + } + assert(large1::count == 0); + assert(large2::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/copy_to_small.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/copy_to_small.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any const &); + +// Test copy assignment to an any instance storing a small value. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + small1 const s1(1); + any a(s1); + any const a2; + + a = a2; + + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + + assert(small1::count == 1); + } + // small + { + small1 const s1(1); + any a(s1); + small2 const s2(2); + any const a2(s2); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(small2)); + assert(any_cast(a) == s2); + + assert(!a2.empty()); + assert(a2.type() == typeid(small2)); + assert(any_cast(a2) == s2); + + assert(small1::count == 1); + assert(small2::count == 3); + } + assert(small1::count == 0); + assert(small2::count == 0); + // large + { + small1 const s1(1); + any a(s1); + large const l(1); + any const a2(l); + + a = a2; + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + + assert(!a2.empty()); + assert(a2.type() == typeid(large)); + assert(any_cast(a2) == l); + + assert(small1::count == 1); + assert(large::count == 3); + } + assert(small1::count == 0); + assert(large::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/large_value_copy.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/large_value_copy.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value&&); + +// Test throwing an exception during value copy assignment of a "large" value. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + large_throws_on_copy v; + assert(large_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(large_throws_on_copy::count == 1); + } + assert(large_throws_on_copy::count == 0); + // const lvalue to small + { + small const s(1); + any a(s); + large_throws_on_copy v; + assert(large_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(large_throws_on_copy::count == 1); + } + assert(small::count == 0); + assert(large_throws_on_copy::count == 0); + // const lvalue to large + { + large const s(1); + any a(s); + large_throws_on_copy v; + assert(large_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(large_throws_on_copy::count == 1); + } + assert(large::count == 0); + assert(large_throws_on_copy::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/move_noexcept.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/move_noexcept.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any &&) noexcept; + +#include +#include + +int main() +{ + using std::experimental::any; + any a1; + any a2; + static_assert( + noexcept(a1 = std::move(a2)) + , "any & operator=(any &&) must be noexcept" + ); +} Index: test/std/experimental/any/any.class/any.assign/move_to_empty.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/move_to_empty.pass.cpp @@ -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, c++11 + +// + +// any& operator=(any &&); + +// Test move assignment to an empty any object. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any a; + any a2; + + a = std::move(a2); + + assert(a.empty()); + assert(a.type() == typeid(void)); + } + // small + { + any a; + small const s(1); + any a2(s); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + } + // large + { + any a; + large const s(1); + any a2(s); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + } +} Index: test/std/experimental/any/any.class/any.assign/move_to_large.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/move_to_large.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any &&) noexcept + +// Test move assignment to an any instance storing a large value. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + large1 const s1(1); + any a(s1); + any a2; + + a = std::move(a2); + + assert(a.empty()); + assert(a.type() == typeid(void)); + } + // small + { + large1 const s1(1); + any a(s1); + small const s2(2); + any a2(s2); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s2); + } + // large + { + large1 const s1(1); + any a(s1); + large2 const l(1); + any a2(l); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(large2)); + assert(any_cast(a) == l); + } +} Index: test/std/experimental/any/any.class/any.assign/move_to_small.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/move_to_small.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any& operator=(any &&) noexcept + +// Test move assignment to an any instance storing a small value. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + small1 const s1(1); + any a(s1); + any a2; + + a = std::move(a2); + + assert(a.empty()); + assert(a.type() == typeid(void)); + } + // small + { + small1 const s1(1); + any a(s1); + small2 const s2(2); + any a2(s2); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(small2)); + assert(any_cast(a) == s2); + } + // large + { + small1 const s1(1); + any a(s1); + large const l(1); + any a2(l); + + a = std::move(a2); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + } +} Index: test/std/experimental/any/any.class/any.assign/small_value_copy_throws.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/small_value_copy_throws.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value&&); + +// Test throwing during the value copy assignment of a "small" object. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + small_throws_on_copy v; + assert(small_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(small_throws_on_copy::count == 1); + } + assert(small_throws_on_copy::count == 0); + // const lvalue to small + { + small const s(1); + any a(s); + small_throws_on_copy v; + assert(small_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(small_throws_on_copy::count == 1); + } + assert(small::count == 0); + assert(small_throws_on_copy::count == 0); + // const lvalue to large + { + large const s(1); + any a(s); + small_throws_on_copy v; + assert(small_throws_on_copy::count == 1); + + try { + a = v; + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(small_throws_on_copy::count == 1); + } + assert(large::count == 0); + assert(small_throws_on_copy::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/value_move_throws.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/value_move_throws.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value&&); + +// Test throwing an exception during value move assignment. + +#include +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // const lvalue to empty + { + any a; + throws_on_move v; + assert(throws_on_move::count == 1); + + try { + a = std::move(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + + assert(throws_on_move::count == 1); + } + // const lvalue to small + { + small const s(1); + any a(s); + throws_on_move v; + assert(throws_on_move::count == 1); + + try { + a = std::move(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + + assert(throws_on_move::count == 1); + } + assert(small::count == 0); + assert(throws_on_move::count == 0); + // const lvalue to large + { + large const s(1); + any a(s); + throws_on_move v; + assert(throws_on_move::count == 1); + + try { + a = std::move(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + assert(large::count == 2); + + assert(throws_on_move::count == 1); + } + assert(large::count == 0); + assert(throws_on_move::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/value_non_copyable_assign.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/value_non_copyable_assign.fail.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value &&); + +// Instantiate the value assignment operator with a non-copyable type. + +#include + +class non_copyable +{ + non_copyable(non_copyable const &); + +public: + non_copyable() {} + non_copyable(non_copyable &&) {} +}; + +int main() +{ + using std::experimental::any; + non_copyable nc; + any a; + a = static_cast(nc); +} Index: test/std/experimental/any/any.class/any.assign/value_to_empty.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/value_to_empty.pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value &&); + +// Test value assignment into an empty any instance. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small const lvalue + { + any a; + small const s(1); + + a = s; + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + } + assert(small::count == 0); + // small non-const rvalue + { + any a; + small s(1); + + a = std::move(s); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a).value == 1); + + assert(s.value == 0); + + assert(small::count == 2); + } + assert(small::count == 0); + // large const lvalue + { + any a; + large const s(1); + + a = s; + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == s); + + assert(large::count == 2); + } + assert(large::count == 0); + // large non-const rvalue + { + any a; + large s(1); + + a = std::move(s); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a).value == 1); + + assert(s.value == 0); + + assert(large::count == 2); + } + assert(large::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/value_to_large.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/value_to_large.pass.cpp @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// any& operator=(Value&&); + +// Test value assignment into an any object storing an instance of a "large" +// object. + + +#include +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small const lvalue + { + large1 const s1(1); + any a(s1); + + small const s2(2); + a = s2; + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s2); + + assert(large1::count == 1); + assert(small::count == 2); + } + // small non-const rvalue + { + large1 const s1(1); + any a(s1); + + small s2(2); + a = std::move(s2); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a).value == 2); + + assert(s2.value == 0); + + assert(large1::count == 1); + assert(small::count == 2); + } + assert(large1::count == 0); + assert(small::count == 0); + // large const lvalue + { + large1 const s1(1); + any a(s1); + large2 const l(1); + + a = l; + + assert(!a.empty()); + assert(a.type() == typeid(large2)); + assert(any_cast(a) == l); + + assert(large1::count == 1); + assert(large2::count == 2); + } + assert(large1::count == 0); + assert(large2::count == 0); + // large non-const rvalue + { + large1 const s1(1); + any a(s1); + large2 l(1); + + a = std::move(l); + + assert(!a.empty()); + assert(a.type() == typeid(large2)); + assert(any_cast(a).value == 1); + + assert(l.value == 0); + + assert(large1::count == 1); + assert(large2::count == 2); + } + assert(large1::count == 0); + assert(large2::count == 0); +} Index: test/std/experimental/any/any.class/any.assign/value_to_small.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.assign/value_to_small.pass.cpp @@ -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, c++11 + +// + +// template +// any & operator=(Value &&); + +// Test value assignment into an any object storing an instance of a "small" +// object. + +#include +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small const lvalue + { + small1 const s1(1); + any a(s1); + + small2 const s2(2); + a = s2; + + assert(!a.empty()); + assert(a.type() == typeid(small2)); + assert(any_cast(a) == s2); + + assert(small1::count == 1); + assert(small2::count == 2); + } + assert(small1::count == 0); + assert(small2::count == 0); + // small non-const rvalue + { + small1 const s1(1); + any a(s1); + small2 s2(2); + + a = std::move(s2); + + assert(!a.empty()); + assert(a.type() == typeid(small2)); + assert(any_cast(a).value == 2); + + assert(s2.value == 0); + + assert(small1::count == 1); + assert(small2::count == 2); + } + assert(small1::count == 0); + assert(small2::count == 0); + // large const lvalue + { + small1 const s1(1); + any a(s1); + + large const l(2); + a = l; + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + + assert(small1::count == 1); + assert(large::count == 2); + } + assert(small1::count == 0); + assert(large::count == 0); + // large non-const rvalue + { + small1 const s1(1); + any a(s1); + + large l(2); + a = std::move(l); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a).value == 2); + + assert(l.value == 0); + + assert(small1::count == 1); + assert(large::count == 2); + } + assert(small1::count == 0); + assert(large::count == 0); +} Index: test/std/experimental/any/any.class/any.cons/copy.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.cons/copy.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any(any const &); + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any const a1; + any const a2(a1); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + } + // small value + { + small const s(1); + any const a(s); + + any a2(a); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2) == s); + + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + + assert(small::count == 3); + } + // large value + { + large const l(1); + any const a(l); + + any a2(a); + + assert(!a2.empty()); + assert(a2.type() == typeid(large)); + assert(any_cast(a2) == l); + + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + + assert(large::count == 3); + } +} Index: test/std/experimental/any/any.class/any.cons/copy_throws.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.cons/copy_throws.pass.cpp @@ -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, c++11 + +// + +// template any(any const &); + +// Test throwing an exception during copy construction. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + { + any const a((small_throws_on_copy())); + assert(small_throws_on_copy::count == 1); + try { + any const a2(a); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(small_throws_on_copy::count == 1); + } + assert(small_throws_on_copy::count == 0); + { + any const a((large_throws_on_copy())); + assert(large_throws_on_copy::count == 1); + try { + any const a2(a); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(large_throws_on_copy::count == 1); + } + assert(large_throws_on_copy::count == 0); +} Index: test/std/experimental/any/any.class/any.cons/default.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.cons/default.pass.cpp @@ -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, c++11 + +// + +// any() noexcept; + +#include +#include +#include +#include "count_new.hpp" + + +int main() +{ + using std::experimental::any; + { + static_assert( + std::is_nothrow_default_constructible::value + , "Must be default constructible" + ); + } + { + assert(globalMemCounter.checkOutstandingNewEq(0)); + any const a; + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); +} Index: test/std/experimental/any/any.class/any.cons/move.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.cons/move.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any(any &&) noexcept; + +#include +#include +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // noexcept test + { + static_assert( + std::is_nothrow_move_constructible::value + , "any must be nothrow move constructible" + ); + } + // empty object + { + any a1; + any a2(std::move(a1)); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + } + // small object + { + small s(1); + any a1(s); + + any a2(std::move(a1)); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2) == s); + } + assert(small::count == 0); + // large object + { + large l(1); + any a1(l); + + any a2(std::move(a1)); + + assert(!a2.empty()); + assert(a2.type() == typeid(large)); + assert(any_cast(a2) == l); + } + assert(large::count == 0); +} Index: test/std/experimental/any/any.class/any.cons/move_throws.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.cons/move_throws.pass.cpp @@ -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, c++11 + +// + +// any(any &&) noexcept + +// Test throwing an exception during move construction. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + { + throws_on_move v; + any a(v); + assert(throws_on_move::count == 2); + + // Moves are always noexcept. + try { + any const a2(std::move(a)); + assert(a2.type() == typeid(throws_on_move)); + } catch (...) { + assert(false); + } + } + assert(throws_on_move::count == 0); +} Index: test/std/experimental/any/any.class/any.cons/non_copyable_value.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.cons/non_copyable_value.fail.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::any(Value &&) + +// Attempt to construct any with a non-copyable type. + +#include + +class non_copyable +{ + non_copyable(non_copyable const &); + +public: + non_copyable() {} + non_copyable(non_copyable &&) {} +}; + +int main() +{ + using std::experimental::any; + non_copyable nc; + any a(static_cast(nc)); +} Index: test/std/experimental/any/any.class/any.cons/value.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.cons/value.pass.cpp @@ -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, c++11 + +// + +// template any(Value &&) + +// Test construction from a value. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small const lvalue + { + small const s(1); + any const a(s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + assert(small::copied == 1); + } + assert(small::count == 0); + small::copied = 0; + small::moved = 0; + // small non-const lvalue + { + small s(1); + any const a(s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(any_cast(a) == s); + assert(small::count == 2); + assert(small::copied == 1); + } + assert(small::count == 0); + small::copied = 0; + small::moved = 0; + // small non-const rvalue + { + small s(1); + any const a(std::move(s)); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(s.value == 0); + assert(any_cast(a).value == 1); + assert(small::count == 2); + assert(small::copied == 0); + assert(small::moved == 1); + } + assert(small::count == 0); + small::copied = 0; + small::moved = 0; + // large const lvalue + { + large const l(1); + any const a(l); + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + assert(large::count == 2); + assert(large::copied == 1); + assert(large::moved == 0); + } + assert(large::count == 0); + large::moved = 0; + large::copied = 0; + // large non-const lvalue + { + large l(1); + any const a(l); + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(any_cast(a) == l); + assert(large::count == 2); + assert(large::copied == 1); + assert(large::moved == 0); + } + assert(large::count == 0); + large::moved = 0; + large::copied = 0; + // large non-const rvalue + { + large l(1); + any const a(std::move(l)); + assert(!a.empty()); + assert(a.type() == typeid(large)); + assert(l.value == 0); + assert(any_cast(a).value == 1); + assert(large::count == 2); + assert(large::moved == 1); + assert(large::copied == 0); + } + assert(large::count == 0); +} Index: test/std/experimental/any/any.class/any.cons/value_copy_throws.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.cons/value_copy_throws.pass.cpp @@ -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, c++11 + +// + +// template any(Value &&); + +// Test throwing an exception while copying a value. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + { + small_throws_on_copy v; + assert(small_throws_on_copy::count == 1); + try { + any const a(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(small_throws_on_copy::count == 1); + } + assert(small_throws_on_copy::count == 0); + { + large_throws_on_copy v; + assert(large_throws_on_copy::count == 1); + try { + any const a(v); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(large_throws_on_copy::count == 1); + } + assert(large_throws_on_copy::count == 0); +} Index: test/std/experimental/any/any.class/any.cons/value_move_throws.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.cons/value_move_throws.pass.cpp @@ -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, c++11 + +// + +// template any(Value &&) + +// Test throwing an exception while moving a value. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + { + throws_on_move v; + assert(throws_on_move::count == 1); + try { + any const a(std::move(v)); + assert(false); + } catch (my_any_exception const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(throws_on_move::count == 1); + } + assert(throws_on_move::count == 0); +} Index: test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp @@ -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, c++11 + +// + +// any::clear() noexcept + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty + { + any a; + + // noexcept check + static_assert( + noexcept(a.clear()) + , "any.clear() must be noexcept" + ); + + a.clear(); + assert(a.empty()); + assert(a.type() == typeid(void)); + } + // small object + { + small const s(1); + any a(s); + + a.clear(); + + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(any_cast(&a) == nullptr); + assert(small::count == 1); + } + // large object + { + large const l(1); + any a(l); + + a.clear(); + assert(a.empty()); + assert(a.type() == typeid(void)); + assert(any_cast(&a) == nullptr); + assert(large::count == 1); + } +} Index: test/std/experimental/any/any.class/any.modifiers/swap_empty_empty.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.modifiers/swap_empty_empty.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::swap(any &) noexcept + +// Test swap(empty, empty) + +#include +#include + +int main() +{ + using std::experimental::any; + { + any a1; + any a2; + + a1.swap(a2); + + assert(a1.empty()); + assert(a1.type() == typeid(void)); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + } +} Index: test/std/experimental/any/any.class/any.modifiers/swap_empty_large.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.modifiers/swap_empty_large.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::swap(any &) noexcept + +// test swap(empty, large) and swap(large, empty) + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty.swap(large) + { + any a1; + any a2(large{1}); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(large)); + assert(any_cast(a1).value == 1); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(large::count == 1); + } + assert(large::count == 0); + // large.swap(empty) + { + any a1; + any a2(large{1}); + + a2.swap(a1); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + + assert(!a1.empty()); + assert(a1.type() == typeid(large)); + assert(any_cast(a1).value == 1); + assert(large::count == 1); + } + assert(large::count == 0); +} Index: test/std/experimental/any/any.class/any.modifiers/swap_empty_small.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.modifiers/swap_empty_small.pass.cpp @@ -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, c++11 + +// + +// any::swap(any &) noexcept + +// Test swap(empty, small) and swap(small, empty) + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // empty.swap(small) + { + any a1; + any a2(small{1}); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(small)); + assert(any_cast(a1).value == 1); + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(small::count == 1); + } + assert(small::count == 0); + // small.swap(empty) + { + any a1; + any a2(small{1}); + + a2.swap(a1); + + assert(a2.empty()); + assert(a2.type() == typeid(void)); + assert(!a1.empty()); + assert(a1.type() == typeid(small)); + assert(any_cast(a1).value == 1); + assert(small::count == 1); + } + assert(small::count == 0); +} Index: test/std/experimental/any/any.class/any.modifiers/swap_large_large.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.modifiers/swap_large_large.pass.cpp @@ -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, c++11 + +// + +// any::swap(any &) noexcept + +// Test swap(large, large) + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // large1.swap(large2) + { + any a1((large1(1))); + any a2((large2(2))); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(large2)); + assert(any_cast(a1).value == 2); + assert(large2::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(large1)); + assert(any_cast(a2).value == 1); + assert(large1::count == 1); + } + assert(large1::count == 0); + assert(large2::count == 0); + // large2.swap(large1) + { + any a1((large1(1))); + any a2((large2(2))); + + a2.swap(a1); + + assert(!a1.empty()); + assert(a1.type() == typeid(large2)); + assert(any_cast(a1).value == 2); + assert(large2::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(large1)); + assert(any_cast(a2).value == 1); + assert(large1::count == 1); + } + assert(large1::count == 0); + assert(large2::count == 0); +} Index: test/std/experimental/any/any.class/any.modifiers/swap_large_small.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.modifiers/swap_large_small.pass.cpp @@ -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, c++11 + +// + +// any::swap(any &) noexcept + +// Test swap(large, small) and swap(small, large) + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small.swap(large) + { + any a1((small(1))); + any a2(large{2}); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(large)); + assert(any_cast(a1).value == 2); + assert(large::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2).value == 1); + assert(small::count == 1); + } + assert(small::count == 0); + assert(large::count == 0); + // large.swap(small) + { + any a1((small(1))); + any a2((large(2))); + + a2.swap(a1); + + assert(!a1.empty()); + assert(a1.type() == typeid(large)); + assert(any_cast(a1).value == 2); + assert(large::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2).value == 1); + assert(small::count == 1); +} + assert(small::count == 0); + assert(large::count == 0); +} Index: test/std/experimental/any/any.class/any.modifiers/swap_noexcept.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.modifiers/swap_noexcept.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// any::swap(any &) noexcept + +#include + +int main() +{ + using std::experimental::any; + + any a1; + any a2; + static_assert( + noexcept(a1.swap(a2)) + , "any::swap(any&) must be noexcept" + ); +} Index: test/std/experimental/any/any.class/any.modifiers/swap_small_small.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.modifiers/swap_small_small.pass.cpp @@ -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, c++11 + +// + +// any::swap(any &) noexcept + +// Test swap(small, small) + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + // small1.swap(small2) + { + any a1((small1(1))); + any a2((small2(2))); + + a1.swap(a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(small2)); + assert(any_cast(a1).value == 2); + assert(small2::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(small1)); + assert(any_cast(a2).value == 1); + assert(small1::count == 1); + } + assert(small1::count == 0); + assert(small2::count == 0); + // small2.swap(small1) + { + any a1((small1(1))); + any a2((small2(2))); + + a2.swap(a1); + + assert(!a1.empty()); + assert(a1.type() == typeid(small2)); + assert(any_cast(a1).value == 2); + assert(small2::count == 1); + + assert(!a2.empty()); + assert(a2.type() == typeid(small1)); + assert(any_cast(a2).value == 1); + assert(small1::count == 1); + } + assert(small1::count == 0); + assert(small2::count == 0); +} Index: test/std/experimental/any/any.class/any.observers/empty.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.observers/empty.pass.cpp @@ -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, c++11 + +// + +// any::empty() noexcept + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + // empty + { + any const a; + assert(a.empty()); + + static_assert( + noexcept(a.empty()) + , "any::empty() must be noexcept" + ); + } + // small object + { + small const s(1); + any const a(s); + assert(!a.empty()); + } + // large object + { + large const l(1); + any const a(l); + assert(!a.empty()); + } +} Index: test/std/experimental/any/any.class/any.observers/type.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/any.observers/type.pass.cpp @@ -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, c++11 + +// + +// any::type() noexcept + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + { + any const a; + assert(a.type() == typeid(void)); + static_assert(noexcept(a.type()), "any::type() must be noexcept"); + } + { + small s(1); + any const a(s); + assert(a.type() == typeid(small)); + + } + { + large l(1); + any const a(l); + assert(a.type() == typeid(large)); + } +} Index: test/std/experimental/any/any.class/nothing_to_do.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.class/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +int main () {} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/bad_type.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/bad_type.pass.cpp @@ -0,0 +1,235 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +// Test casting to a bad type. + +#include +#include +#include "any_types.hpp" + +using std::experimental::any; +using std::experimental::any_cast; + +void non_const_test() +{ + small const s(42); + { + any a(s); + using T = void; + using Expect = void*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any a(s); + using T = void const; + using Expect = void const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any a(s); + using T = int; + using Expect = int*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any a(s); + using T = int const; + using Expect = int const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any a(s); + using T = large; + using Expect = large*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any a(s); + using T = large const; + using Expect = large const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } +} + +void const_test() +{ + small const s(42); + { + any const a(s); + using T = void; + using Expect = void const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any const a(s); + using T = void const; + using Expect = void const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any const a(s); + using T = int; + using Expect = int const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any const a(s); + using T = int const; + using Expect = int const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any const a(s); + using T = large; + using Expect = large const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } + { + any const a(s); + using T = large const; + using Expect = large const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + Ret ret = any_cast(&a); + assert(ret == nullptr); + + small const* obj = any_cast(&a); + assert(obj); + assert(*obj == s); + } +} + +int main() +{ + non_const_test(); + const_test(); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/const_reference.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/const_reference.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include + +using std::experimental::any; +using std::experimental::any_cast; + +int main() +{ + any a(1); + any_cast(&a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/const_reference2.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/const_reference2.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include + +using std::experimental::any; +using std::experimental::any_cast; + +int main() +{ + any const a(1); + any_cast(&a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/const_rvalue_reference.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/const_rvalue_reference.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include + +using std::experimental::any; +using std::experimental::any_cast; + +int main() +{ + any a(1); + any_cast(&a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/const_rvalue_reference2.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/const_rvalue_reference2.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include + +using std::experimental::any; +using std::experimental::any_cast; + +int main() +{ + any const a(1); + any_cast(&a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/empty.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/empty.pass.cpp @@ -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, c++11 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +// Test casting an empty object. + +#include +#include + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + { + any a; + assert(nullptr == any_cast(&a)); + assert(nullptr == any_cast(&a)); + } + { + any const a; + assert(nullptr == any_cast(&a)); + } + +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/large_value.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/large_value.pass.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +// Test casting an any object storing a "large" value. + +#include +#include +#include +#include "any_types.hpp" + +using std::experimental::any; +using std::experimental::any_cast; + +void non_const_test() +{ + large const s(42); + + // const large + { + any a(s); + using T = large const; + using Expect = large const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + + Expect ptr1 = any_cast(&a); + assert(ptr1); + assert(*ptr1 == s); + + Expect ptr2 = any_cast(&a); + assert(ptr1 == ptr2); + } + // non-const large + { + any a(s); + using T = large; + using Expect = large*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + + Expect ptr1 = any_cast(&a); + assert(ptr1); + assert(*ptr1 == s); + + Expect ptr2 = any_cast(&a); + assert(ptr1 == ptr2); + + ptr1->value = 12; + assert(ptr2->value == 12); + } +} + +void const_test() +{ + large const s(42); + + // const large + { + any const a(s); + using T = large const; + using Expect = large const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + + Expect ptr1 = any_cast(&a); + assert(ptr1); + assert(*ptr1 == s); + + Expect ptr2 = any_cast(&a); + assert(ptr1 == ptr2); + } +} + +int main() +{ + non_const_test(); + const_test(); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/noexcept.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/noexcept.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + { + any a; + static_assert( + noexcept(any_cast(&a)) + , "any_cast(any*) must be noexcept" + ); + } + { + any const a; + static_assert( + noexcept(any_cast(&a)) + , "any_cast(any const *) must be noexcept" + ); + } + +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/nullptr.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/nullptr.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + + assert(nullptr == any_cast(static_cast(nullptr))); + assert(nullptr == any_cast(static_cast(nullptr))); + assert(nullptr == any_cast(static_cast(nullptr))); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/reference.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/reference.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include + +using std::experimental::any; +using std::experimental::any_cast; + +int main() +{ + any a(1); + any_cast(&a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/reference2.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/reference2.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include + +using std::experimental::any; +using std::experimental::any_cast; + +int main() +{ + any const a(1); + any_cast(&a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/rvalue_reference.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/rvalue_reference.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include + +using std::experimental::any; +using std::experimental::any_cast; + +int main() +{ + any a(1); + any_cast(&a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/rvalue_reference2.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/rvalue_reference2.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +#include + +using std::experimental::any; +using std::experimental::any_cast; + +int main() +{ + any const a(1); + any_cast(&a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/small_value.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/small_value.pass.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType const* any_cast(any const *) noexcept; +// +// template +// ValueType * any_cast(any *) noexcept; + +// Test casting an any object storing a "small" value. + +#include +#include +#include +#include "any_types.hpp" + +using std::experimental::any; +using std::experimental::any_cast; +using namespace std; + +void non_const_test() +{ + small const s(42); + + // const small + { + any a(s); + using T = small const; + using Expect = small const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + + Expect ptr1 = any_cast(&a); + assert(ptr1); + assert(*ptr1 == s); + + Expect ptr2 = any_cast(&a); + assert(ptr1 == ptr2); + } + // non-const small + { + any a(s); + using T = small; + using Expect = small*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + + Expect ptr1 = any_cast(&a); + assert(ptr1); + assert(*ptr1 == s); + + Expect ptr2 = any_cast(&a); + assert(ptr1 == ptr2); + + ptr1->value = 12; + assert(ptr2->value == 12); + } +} + +void const_test() +{ + small const s(42); + any const a(s); + // const small + { + using T = small const; + using Expect = small const*; + using Ret = decltype(any_cast(&a)); + static_assert( + std::is_same::value + , "Expected return type does not match actual return type" + ); + + Expect ptr1 = any_cast(&a); + assert(ptr1); + assert(*ptr1 == s); + + Expect ptr2 = any_cast(&a); + assert(ptr1 == ptr2); + } +} + +int main() +{ + non_const_test(); + const_test(); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/const_lvalue_cast_const_correctness.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/const_lvalue_cast_const_correctness.fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType any_cast(any const &); + +// Try and cast away const. + +#include + +struct dummy_t {}; + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + + any const a(dummy_t{}); + any_cast(a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/const_lvalue_cast_not_copy_constructible.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/const_lvalue_cast_not_copy_constructible.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType any_cast(any const &); + +// Test instantiating the const lvalue any cast with a non-copyable type. + + +#include + +struct no_copy +{ + no_copy() {} + no_copy(no_copy &&) {} + +private: + no_copy(no_copy const &); +}; + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + + any const a; + any_cast(a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/empty.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/empty.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType any_cast(any const &); +// +// template +// ValueType any_cast(any &); +// +// template +// ValueType any_cast(any &&); + +// Test casting an empty object. + +#include +#include +#include "count_new.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + + // const lvalue + { + any const a; + try { + any_cast(a); + assert(false); + } catch (bad_any_cast const &) { + // do nothing + } catch (...) { + assert(false); + } + + assert(a.empty()); + assert(a.type() == typeid(void)); + } + // non-const lvalue + { + any a; + try { + any_cast(a); + assert(false); + } catch (bad_any_cast const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(a.empty()); + assert(a.type() == typeid(void)); + } + // rvalue + { + any a; + try { + any_cast(static_cast(a)); + assert(false); + } catch (bad_any_cast const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(a.empty()); + assert(a.type() == typeid(void)); + } + assert(globalMemCounter.checkNewCalledEq(0)); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/large.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/large.pass.cpp @@ -0,0 +1,328 @@ +////===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType any_cast(any const &); +// +// template +// ValueType any_cast(any &); +// +// template +// ValueType any_cast(any &&); + +// Test casting an any instance storing a "large" object. + +#include +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +void const_lvalue_test() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + { + large const s(42); + any const a((s)); + assert(large::count == 2); + assert(globalMemCounter.checkOutstandingNewEq(1)); + // no qualifiers + { + using T = large; + using Expect = large; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large cp = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 3); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + } + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + // const qualifiers + { + using T = large const; + using Expect = large const; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large cp = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 3); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + } + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + // const reference qualifiers + { + using T = large const &; + using Expect = large const &; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large const & cp = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + + large const & cp2 = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp2 == s); + assert(&cp2 == &cp); + } + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 0); +} + +void lvalue_test() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + large const s(42); + assert(large::count == 1); + // no qualifiers + { + any a((s)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + using T = large; + using Expect = large; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large cp = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 3); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 1); + // const qualifiers + { + any a((s)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + using T = large const; + using Expect = large const; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large cp = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 3); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 1); + // const reference qualifiers + { + any a((s)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + using T = large const &; + using Expect = large const &; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large const & cp = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + + large const & cp2 = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp2 == s); + assert(&cp2 == &cp); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 1); + // lvalue reference qualifiers + { + any a((s)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + using T = large &; + using Expect = large &; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large & cp = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + + large & cp2 = any_cast(a); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp2 == s); + assert(&cp2 == &cp); + + cp.value = 10; + assert(cp2.value == 10); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 1); +} + +void rvalue_test() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + large const s(42); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 1); + // no qualifiers + { + any a((s)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + using T = large; + using Expect = large; + using Ret = decltype(any_cast(std::move(a))); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large cp = any_cast(std::move(a)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 3); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 1); + // const qualifiers + { + any a((s)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + using T = large const; + using Expect = large const; + using Ret = decltype(any_cast(std::move(a))); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large cp = any_cast(std::move(a)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 3); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 1); + // const reference qualifiers + { + any a((s)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + using T = large const &; + using Expect = large const &; + using Ret = decltype(any_cast(std::move(a))); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large const & cp = any_cast(std::move(a)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + + large const & cp2 = any_cast(std::move(a)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp2 == s); + assert(&cp2 == &cp); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 1); + // lvalue reference qualifiers + { + any a((s)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + using T = large &; + using Expect = large &; + using Ret = decltype(any_cast(std::move(a))); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + large & cp = any_cast(std::move(a)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(large)); + + large & cp2 = any_cast(std::move(a)); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(large::count == 2); + assert(cp2 == s); + assert(&cp2 == &cp); + + cp.value = 10; + assert(cp2.value == 10); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(large::count == 1); +} + +int main() +{ + const_lvalue_test(); + lvalue_test(); + rvalue_test(); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/lvalue_cast_not_copy_constructible.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/lvalue_cast_not_copy_constructible.fail.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType any_cast(any &); + +// Test instantiating the lvalue any_cast with a non-copyable type. + +#include + +struct no_copy +{ + no_copy() {} + no_copy(no_copy &&) {} + +private: + no_copy(no_copy const &); +}; + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + + any a; + any_cast(a); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/non_copy_ref.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/non_copy_ref.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType any_cast(any const &); +// +// template +// ValueType any_cast(any &); +// +// template +// ValueType any_cast(any &&); + + +#include +#include + +struct no_copy +{ + no_copy() {} + no_copy(no_copy &&) {} + +private: + no_copy(no_copy const &); +}; + +// Even though you can't get a non-copyable class into std::any +// the standard requires that these overloads compile and function. +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + // const lvalue + { + any const a; + try { + any_cast(a); + assert(false); + } catch (bad_any_cast const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(a.empty()); + assert(a.type() == typeid(void)); + } + // lvalue + { + any a; + try { + any_cast(a); + assert(false); + } catch (bad_any_cast const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(a.empty()); + assert(a.type() == typeid(void)); + } + // rvalue + { + any a; + try { + any_cast(static_cast(a)); + assert(false); + } catch (bad_any_cast const &) { + // do nothing + } catch (...) { + assert(false); + } + assert(a.empty()); + assert(a.type() == typeid(void)); + } +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/rvalue_cast_not_copy_constructible.fail.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/rvalue_cast_not_copy_constructible.fail.cpp @@ -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, c++11 + +// + +// template +// ValueType any_cast(any &&); + +// Instantiate the rvalue any cast with a non-copyable type. + + +#include +#include + +struct no_copy +{ + no_copy() {} + no_copy(no_copy &&) {} + +private: + no_copy(no_copy const &); +}; + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + + any a; + any_cast(std::move(a)); +} Index: test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/small.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/any.cast.throws/small.pass.cpp @@ -0,0 +1,290 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// ValueType any_cast(any const &); +// +// template +// ValueType any_cast(any &); +// +// template +// ValueType any_cast(any &&); + +// Test casting an any instance storing a "small" object. + + +#include +#include +#include +#include "count_new.hpp" +#include "any_types.hpp" + +void const_lvalue_test() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + small const s(42); + any const a((s)); + assert(small::count == 2); + // no qualifiers + { + using T = small; + using Expect = small; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small cp = any_cast(a); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 3); + } + assert(small::count == 2); + // const qualifiers + { + using T = small const; + using Expect = small const; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small cp = any_cast(a); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 3); + } + assert(small::count == 2); + // const reference qualifiers + { + using T = small const &; + using Expect = small const &; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small const & cp = any_cast(a); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 2); + + small const & cp2 = any_cast(a); + assert(cp2 == s); + assert(&cp2 == &cp); + assert(small::count == 2); + } + assert(small::count == 2); + assert(globalMemCounter.checkNewCalledEq(0)); +} + +void lvalue_test() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + small const s(42); + // no qualifiers + { + any a((s)); + assert(small::count == 2); + using T = small; + using Expect = small; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small cp = any_cast(a); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 3); + } + assert(small::count == 1); + // const qualifiers + { + any a((s)); + assert(small::count == 2); + using T = small const; + using Expect = small const; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small cp = any_cast(a); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 3); + } + assert(small::count == 1); + // const reference qualifiers + { + any a((s)); + assert(small::count == 2); + using T = small const &; + using Expect = small const &; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small const & cp = any_cast(a); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 2); + + small const & cp2 = any_cast(a); + assert(cp2 == s); + assert(&cp2 == &cp); + assert(small::count == 2); + } + assert(small::count == 1); + // lvalue reference qualifiers + { + any a((s)); + assert(small::count == 2); + using T = small &; + using Expect = small &; + using Ret = decltype(any_cast(a)); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small & cp = any_cast(a); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 2); + + small & cp2 = any_cast(a); + assert(cp2 == s); + assert(&cp2 == &cp); + assert(small::count == 2); + + cp.value = 10; + assert(cp2.value == 10); + } + assert(small::count == 1); + assert(globalMemCounter.checkNewCalledEq(0)); +} + +void rvalue_test() +{ + using std::experimental::any; + using std::experimental::any_cast; + using std::experimental::bad_any_cast; + small const s(42); + assert(small::count == 1); + // no qualifiers + { + any a((s)); + assert(small::count == 2); + using T = small; + using Expect = small; + using Ret = decltype(any_cast(std::move(a))); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small cp = any_cast(std::move(a)); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 3); + } + assert(small::count == 1); + // const qualifiers + { + any a((s)); + assert(small::count == 2); + using T = small const; + using Expect = small const; + using Ret = decltype(any_cast(std::move(a))); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small cp = any_cast(std::move(a)); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 3); + } + assert(small::count == 1); + // const reference qualifiers + { + any a((s)); + assert(small::count == 2); + using T = small const &; + using Expect = small const &; + using Ret = decltype(any_cast(std::move(a))); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small const & cp = any_cast(std::move(a)); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 2); + + small const & cp2 = any_cast(std::move(a)); + assert(cp2 == s); + assert(&cp2 == &cp); + assert(small::count == 2); + } + assert(small::count == 1); + // lvalue reference qualifiers + { + any a((s)); + assert(small::count == 2); + using T = small &; + using Expect = small &; + using Ret = decltype(any_cast(std::move(a))); + static_assert( + std::is_same::value + , "Return type unexpected" + ); + small & cp = any_cast(std::move(a)); + assert(cp == s); + assert(!a.empty()); + assert(a.type() == typeid(small)); + assert(small::count == 2); + + small & cp2 = any_cast(std::move(a)); + assert(cp2 == s); + assert(&cp2 == &cp); + assert(small::count == 2); + + cp.value = 10; + assert(cp2.value == 10); + } + assert(small::count == 1); + assert(globalMemCounter.checkNewCalledEq(0)); +} + +int main() +{ + const_lvalue_test(); + lvalue_test(); + rvalue_test(); +} Index: test/std/experimental/any/any.nonmembers/any.cast/nothing_to_do.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/any.cast/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +int main () {} Index: test/std/experimental/any/any.nonmembers/swap.pass.cpp =================================================================== --- /dev/null +++ test/std/experimental/any/any.nonmembers/swap.pass.cpp @@ -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, c++11 + +// + +// void swap(any &, any &) noexcept + +// swap(...) just wraps any::swap(...). That function is tested elsewhere. + +#include +#include +#include "any_types.hpp" + +int main() +{ + using std::experimental::any; + using std::experimental::any_cast; + { + small const s(1); + any a1(s); + assert(!a1.empty()); + assert(a1.type() == typeid(small)); + assert(any_cast(a1) == s); + assert(small::count == 2); + + large const l(2); + any a2(l); + assert(!a2.empty()); + assert(a2.type() == typeid(large)); + assert(large::count == 2); + + static_assert( + noexcept(swap(a1, a2)) + , "swap(any&, any&) must be noexcept" + ); + + swap(a1, a2); + + assert(!a1.empty()); + assert(a1.type() == typeid(large)); + assert(any_cast(a1) == l); + assert(large::count == 2); + + assert(!a2.empty()); + assert(a2.type() == typeid(small)); + assert(any_cast(a2) == s); + assert(small::count == 2); + } + assert(small::count == 0); + assert(large::count == 0); +} Index: test/support/any_types.hpp =================================================================== --- /dev/null +++ test/support/any_types.hpp @@ -0,0 +1,218 @@ +#ifndef SUPPORT_ANY_TYPES_HPP +#define SUPPORT_ANY_TYPES_HPP + + +template +struct small_type +{ + static int count; + static int copied; + static int moved; + + static void reset() { + small_type::copied = 0; + small_type::moved = 0; + } + + char value; + + small_type(char val) + : value(val) + { + ++count; + } + + small_type(small_type const & other) throw() + { + value = other.value; + ++count; + ++copied; + } + + small_type(small_type && other) throw() + { + value = other.value; + other.value = 0; + ++count; + ++moved; + } + + ~small_type() + { + value = 0; + --count; + } +}; + +template +int small_type::count = 0; + +template +int small_type::copied = 0; + +template +int small_type::moved = 0; + +template +inline bool operator==(small_type const & lhs, small_type const & rhs) +{ + return lhs.value == rhs.value; +} + +template +inline bool operator!=(small_type const & lhs, small_type const & rhs) +{ + return lhs.value != rhs.value; +} + +typedef small_type<> small; +typedef small_type<1> small1; +typedef small_type<2> small2; + +template +struct large_type +{ + static int count; + static int copied; + static int moved; + + static void reset() { + large_type::copied = 0; + large_type::moved = 0; + } + + char value; + + large_type(char val) : value(val) + { + ++count; + data[0] = 0; + } + + large_type(large_type const & other) + { + value = other.value; + ++count; + ++copied; + } + + large_type(large_type && other) + { + value = other.value; + other.value = 0; + ++count; + ++moved; + } + + ~large_type() + { + value = 0; + --count; + } +private: + int data[10]; +}; + +template +int large_type::count = 0; + +template +int large_type::copied = 0; + +template +int large_type::moved = 0; + + +template +inline bool operator==(large_type const & lhs, large_type const & rhs) +{ + return lhs.value == rhs.value; +} + +template +inline bool operator!=(large_type const & lhs, large_type const & rhs) +{ + return lhs.value != rhs.value; +} + +typedef large_type<> large; +typedef large_type<1> large1; +typedef large_type<2> large2; + +struct my_any_exception {}; + +struct small_throws_on_copy +{ + static int count; + + small_throws_on_copy() { ++count; } + + small_throws_on_copy(small_throws_on_copy const &) + { + throw my_any_exception(); + } + + small_throws_on_copy(small_throws_on_copy &&) throw() + { + ++count; + } + + ~small_throws_on_copy() { --count; } +}; + +int small_throws_on_copy::count = 0; + + +struct large_throws_on_copy +{ + static int count; + + large_throws_on_copy() + { + data[0] = 0; + ++count; + } + + large_throws_on_copy(large_throws_on_copy const &) + { + throw my_any_exception(); + } + + large_throws_on_copy(large_throws_on_copy &&) throw() + { + ++count; + } + + ~large_throws_on_copy() { --count; } + +private: + int data[10]; +}; + +int large_throws_on_copy::count = 0; + + + +struct throws_on_move +{ + static int count; + + throws_on_move() { ++count; } + + throws_on_move(throws_on_move const &) + { + ++count; + } + + throws_on_move(throws_on_move &&) + { + throw my_any_exception(); + } + + ~throws_on_move() { --count; } +}; + +int throws_on_move::count = 0; + + +#endif // SUPPORT_ANY_TYPES_HPP