diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2014-06-14 17:00:56 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2014-06-14 17:00:56 +0100 |
commit | e8043fa674add9511ee418536ad48161bd206372 (patch) | |
tree | 9d7935f468918c9e14cc65c3229114e7e59bc17d /libstdc++-v3 | |
parent | ab938b4135eec5527d41a938b1052177015e3d35 (diff) | |
download | gcc-e8043fa674add9511ee418536ad48161bd206372.zip gcc-e8043fa674add9511ee418536ad48161bd206372.tar.gz gcc-e8043fa674add9511ee418536ad48161bd206372.tar.bz2 |
status_cxx2014.xml: Update Fundamentals TS status.
* doc/xml/manual/status_cxx2014.xml: Update Fundamentals TS status.
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/experimental/any: New.
* include/ext/aligned_buffer.h (__aligned_buffer(nullptr_t)): New
constructor.
* testsuite/experimental/any/assign/1.cc: New.
* testsuite/experimental/any/assign/2.cc: New.
* testsuite/experimental/any/cons/1.cc: New.
* testsuite/experimental/any/cons/2.cc: New.
* testsuite/experimental/any/cons/3.cc: New.
* testsuite/experimental/any/misc/any_cast.cc: New.
* testsuite/experimental/any/misc/any_cast_neg.cc: New.
* testsuite/experimental/any/misc/any_cast_no_rtti.cc: New.
* testsuite/experimental/any/misc/swap.cc: New.
* testsuite/experimental/any/modifiers/1.cc: New.
* testsuite/experimental/any/observers/type.cc: New.
From-SVN: r211669
Diffstat (limited to 'libstdc++-v3')
17 files changed, 1268 insertions, 2 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ee2f8ff..c44fad8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2014-06-14 Jonathan Wakely <jwakely@redhat.com> + + * doc/xml/manual/status_cxx2014.xml: Update Fundamentals TS status. + * include/Makefile.am: Add new header. + * include/Makefile.in: Regenerate. + * include/experimental/any: New. + * include/ext/aligned_buffer.h (__aligned_buffer(nullptr_t)): New + constructor. + * testsuite/experimental/any/assign/1.cc: New. + * testsuite/experimental/any/assign/2.cc: New. + * testsuite/experimental/any/cons/1.cc: New. + * testsuite/experimental/any/cons/2.cc: New. + * testsuite/experimental/any/cons/3.cc: New. + * testsuite/experimental/any/misc/any_cast.cc: New. + * testsuite/experimental/any/misc/any_cast_neg.cc: New. + * testsuite/experimental/any/misc/any_cast_no_rtti.cc: New. + * testsuite/experimental/any/misc/swap.cc: New. + * testsuite/experimental/any/modifiers/1.cc: New. + * testsuite/experimental/any/observers/type.cc: New. + 2014-06-11 Maciej W. Rozycki <macro@codesourcery.com> * testsuite/27_io/basic_ostream/inserters_arithmetic/wchar_t/4402.cc diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2014.xml b/libstdc++-v3/doc/xml/manual/status_cxx2014.xml index c6f89c9..82abd88 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2014.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2014.xml @@ -306,14 +306,13 @@ not in any particular release. </row> <row> - <?dbhtml bgcolor="#C8B0B0" ?> <entry> <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3804.html"> N3804 </link> </entry> <entry>Any library proposal</entry> - <entry>N</entry> + <entry>Y</entry> <entry>Library Fundamentals TS</entry> </row> diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index a079ff6..8fe82da 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -638,6 +638,7 @@ decimal_headers = \ experimental_srcdir = ${glibcxx_srcdir}/include/experimental experimental_builddir = ./experimental experimental_headers = \ + ${experimental_srcdir}/any \ ${experimental_srcdir}/optional \ ${experimental_srcdir}/string_view \ ${experimental_srcdir}/string_view.tcc diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 502f04e..51fde97 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -904,6 +904,7 @@ decimal_headers = \ experimental_srcdir = ${glibcxx_srcdir}/include/experimental experimental_builddir = ./experimental experimental_headers = \ + ${experimental_srcdir}/any \ ${experimental_srcdir}/optional \ ${experimental_srcdir}/string_view \ ${experimental_srcdir}/string_view.tcc diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any new file mode 100644 index 0000000..2839af1 --- /dev/null +++ b/libstdc++-v3/include/experimental/any @@ -0,0 +1,626 @@ +// <experimental/any> -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file experimental/any + * This is a TS C++ Library header. + */ + +#ifndef _GLIBCXX_EXPERIMENTAL_ANY +#define _GLIBCXX_EXPERIMENTAL_ANY 1 + +#pragma GCC system_header + +#if __cplusplus <= 201103L +# include <bits/c++14_warning.h> +#else + +#include <typeinfo> +#include <memory> +#include <utility> +#include <type_traits> +#include <bits/alloc_traits.h> +#include <bits/uses_allocator.h> +#include <bits/functexcept.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace experimental +{ +inline namespace any_v1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup any Type-safe container of any type + * @ingroup experimental + * + * A type-safe container for single values of value types, as + * described in n3804 "Any Library Proposal (Revision 3)". + * + * @{ + */ + + /** + * @brief Exception class thrown by a failed @c any_cast + * @ingroup exceptions + */ + class bad_any_cast : public bad_cast + { + public: + virtual const char* what() const noexcept { return "bad_any_cast"; } + }; + + [[gnu::noreturn]] inline void __throw_bad_any_cast() + { +#ifdef __EXCEPTIONS + throw bad_any_cast{}; +#else + __builtin_abort(); +#endif + } + + /** + * @brief A type-safe container of any type. + * + * An @c any object's state is either empty or it stores a contained object + * of CopyConstructible type. + */ + class any + { + // Holds either pointer to a heap object or the contained object itself. + union _Storage + { + void* _M_ptr; + std::aligned_storage<sizeof(_M_ptr), sizeof(_M_ptr)>::type _M_buffer; + }; + + template<typename _Tp, typename _Safe = is_nothrow_copy_constructible<_Tp>, + bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))> + using _Internal = std::integral_constant<bool, _Safe::value && _Fits>; + + template<typename _Tp> + struct _Manager_internal; // uses small-object optimization + + template<typename _Tp> + struct _Manager_external; // creates contained object on the heap + + template<typename _Tp> + using _Manager = conditional_t<_Internal<_Tp>::value, + _Manager_internal<_Tp>, + _Manager_external<_Tp>>; + +#ifdef __GXX_RTTI + // When RTTI is disabled __any_caster assumes the manager is either + // _Manager_internal or _Manager_external, so this type must not be used. + template<typename _Tp, typename _Alloc> + struct _Manager_alloc; // creates contained object using an allocator + + template<typename _Tp, typename _Alloc, typename _TpAlloc + = typename allocator_traits<_Alloc>::template rebind_alloc<_Tp>> + using _ManagerAlloc = conditional_t<_Internal<_Tp>::value, + _Manager_internal<_Tp>, + _Manager_alloc<_Tp, _TpAlloc>>; +#endif + + template<typename _Tp, typename _Decayed = decay_t<_Tp>> + using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>; + + public: + // construct/destruct + + /// Default constructor, creates an empty object. + any() noexcept : _M_manager(nullptr) { } + + /// Copy constructor, copies the state of @p __other + any(const any& __other) : _M_manager(__other._M_manager) + { + if (!__other.empty()) + { + _Arg __arg; + __arg._M_any = this; + _M_manager(_Op_clone, &__other, &__arg); + } + } + + /** + * @brief Move constructor, transfer the state from @p __other + * + * @post @c __other.empty() (not guaranteed for other implementations) + */ + any(any&& __other) noexcept + : _M_manager(__other._M_manager), + _M_storage(__other._M_storage) + { __other._M_manager = nullptr; } + + /// Construct with a copy of @p __value as the contained object. + template <typename _ValueType, typename _Tp = _Decay<_ValueType>, + typename _Mgr = _Manager<_Tp>> + any(_ValueType&& __value) + : _M_manager(&_Mgr::_S_manage), + _M_storage(_Mgr::_S_create(std::forward<_ValueType>(__value))) + { + static_assert(is_copy_constructible<_Tp>::value, + "The contained object must be CopyConstructible"); + } + + /// Allocator-extended default constructor (the allocator is ignored). + template <typename _Allocator> + any(allocator_arg_t, const _Allocator&) noexcept : any() { } + +#ifdef __GXX_RTTI + /// Construct with a copy of @p __value as the contained object. + template <typename _Allocator, typename _ValueType, + typename _Tp = _Decay<_ValueType>, + typename _Mgr = _ManagerAlloc<_Tp, _Allocator>> + any(allocator_arg_t, const _Allocator& __a, _ValueType&& __value) + : _M_manager(&_Mgr::_S_manage), + _M_storage(_Mgr::_S_alloc(__a, std::forward<_ValueType>(__value))) + { + static_assert(is_copy_constructible<_Tp>::value, + "The contained object must be CopyConstructible"); + } +#endif + + /* TODO: implement this somehow + /// Allocator-extended copy constructor. + template <class _Allocator> + any(allocator_arg_t, const _Allocator& __a, const any& __other); + */ + + /// Allocator-extended move constructor (the allocator is ignored). + template <typename _Allocator> + any(allocator_arg_t, const _Allocator&, any&& __other) noexcept + : any(std::move(__other)) { } + + /// Destructor, calls @c clear() + ~any() { clear(); } + + // assignments + + /// Copy the state of + any& operator=(const any& __rhs) + { + any(__rhs).swap(*this); + return *this; + } + + /** + * @brief Move assignment operator + * + * @post @c __rhs.empty() (not guaranteed for other implementations) + */ + any& operator=(any&& __rhs) noexcept + { + any(std::move(__rhs)).swap(*this); + return *this; + } + + /// Store a copy of @p __rhs as the contained object. + template<typename _ValueType> + any& operator=(_ValueType&& __rhs) + { + any(std::forward<_ValueType>(__rhs)).swap(*this); + return *this; + } + + // modifiers + + /// If not empty, destroy the contained object. + void clear() noexcept + { + if (!empty()) + { + _M_manager(_Op_destroy, this, nullptr); + _M_manager = nullptr; + } + } + + /// Exchange state with another object. + void swap(any& __rhs) noexcept + { + std::swap(_M_manager, __rhs._M_manager); + std::swap(_M_storage, __rhs._M_storage); + } + + // observers + + /// Reports whether there is a contained object or not. + bool empty() const noexcept { return _M_manager == nullptr; } + +#ifdef __GXX_RTTI + /// The @c typeid of the contained object, or @c typeid(void) if empty. + const type_info& type() const noexcept + { + if (empty()) + return typeid(void); + _Arg __arg; + _M_manager(_Op_get_type_info, this, &__arg); + return *__arg._M_typeinfo; + } +#endif + + template<typename _Tp> + static constexpr bool __is_valid_cast() + { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; } + + private: + enum _Op { _Op_access, _Op_get_type_info, _Op_clone, _Op_destroy }; + + union _Arg + { + void* _M_obj; + const std::type_info* _M_typeinfo; + any* _M_any; + }; + + void (*_M_manager)(_Op, const any*, _Arg*); + _Storage _M_storage; + + template<typename _Tp> + friend void* __any_caster(const any* __any) + { +#ifdef __GXX_RTTI + if (__any->type() != typeid(_Tp)) + return nullptr; +#else + if (__any->_M_manager != &_Manager<decay_t<_Tp>>::_S_manage) + return nullptr; +#endif + _Arg __arg; + __any->_M_manager(_Op_access, __any, &__arg); + return __arg._M_obj; + } + + // Manage in-place contained object. + template<typename _Tp> + struct _Manager_internal + { + static void + _S_manage(_Op __which, const any* __anyp, _Arg* __arg); + + template<typename _Up> + static _Storage + _S_create(_Up&& __value) + { + _Storage __storage; + void* __addr = &__storage._M_buffer; + ::new (__addr) _Tp(std::forward<_Up>(__value)); + return __storage; + } + + template<typename _Alloc, typename _Up> + static _Storage + _S_alloc(const _Alloc&, _Up&& __value) + { + return _S_create(std::forward<_Up>(__value)); + } + }; + + // Manage external contained object. + template<typename _Tp> + struct _Manager_external + { + static void + _S_manage(_Op __which, const any* __anyp, _Arg* __arg); + + template<typename _Up> + static _Storage + _S_create(_Up&& __value) + { + _Storage __storage; + __storage._M_ptr = new _Tp(std::forward<_Up>(__value)); + return __storage; + } + }; + +#ifdef __GXX_RTTI + // Manage external contained object using an allocator + template<typename _Tp, typename _Alloc> + struct _Manager_alloc + { + static_assert(std::is_same<_Tp, typename _Alloc::value_type>::value, + "Allocator's value_type is correct"); + + // Type that holds contained object and allocator + struct _Data; + + using _Traits = typename std::allocator_traits<_Alloc>::template + rebind_traits<_Data>; + + static void + _S_manage(_Op __which, const any* __anyp, _Arg* __arg); + + template<typename _Up> + static _Storage + _S_alloc(const _Alloc& __a, _Up&& __value); + }; +#endif + }; + + /// Exchange the states of two @c any objects. + inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); } + + /** + * @brief Access the contained object. + * + * @tparam _ValueType A const-reference or CopyConstructible type. + * @param __any The object to access. + * @return The contained object. + * @throw bad_any_cast If <code> + * __any.type() != typeid(remove_reference_t<_ValueType>) + * </code> + */ + template<typename _ValueType> + inline _ValueType any_cast(const any& __any) + { + static_assert(any::__is_valid_cast<_ValueType>(), + "Template argument must be a reference or CopyConstructible type"); + auto __p = any_cast<add_const_t<remove_reference_t<_ValueType>>>(&__any); + if (__p) + return *__p; + __throw_bad_any_cast(); + } + + /** + * @brief Access the contained object. + * + * @tparam _ValueType A reference or CopyConstructible type. + * @param __any The object to access. + * @return The contained object. + * @throw bad_any_cast If <code> + * __any.type() != typeid(remove_reference_t<_ValueType>) + * </code> + */ + template<typename _ValueType> + inline _ValueType any_cast(any& __any) + { + static_assert(any::__is_valid_cast<_ValueType>(), + "Template argument must be a reference or CopyConstructible type"); + auto __p = any_cast<remove_reference_t<_ValueType>>(&__any); + if (__p) + return *__p; + __throw_bad_any_cast(); + } + + /** + * @brief Access the contained object. + * + * @tparam _ValueType A reference or CopyConstructible type. + * @param __any The object to access. + * @return The contained object. + * @throw bad_any_cast If <code> + * __any.type() != typeid(remove_reference_t<_ValueType>) + * </code> + */ + template<typename _ValueType> + inline _ValueType any_cast(any&& __any) + { + static_assert(any::__is_valid_cast<_ValueType>(), + "Template argument must be a reference or CopyConstructible type"); + auto __p = any_cast<remove_reference_t<_ValueType>>(&__any); + if (__p) + return *__p; + __throw_bad_any_cast(); + } + + /** + * @brief Access the contained object. + * + * @tparam _ValueType The type of the contained object. + * @param __any A pointer to the object to access. + * @return The address of the contained object if <code> + * __any != nullptr && __any.type() == typeid(_ValueType) + * </code>, otherwise a null pointer. + */ + template<typename _ValueType> + inline const _ValueType* any_cast(const any* __any) noexcept + { + if (__any) + return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); + return nullptr; + } + + /** + * @brief Access the contained object. + * + * @tparam _ValueType The type of the contained object. + * @param __any A pointer to the object to access. + * @return The address of the contained object if <code> + * __any != nullptr && __any.type() == typeid(_ValueType) + * </code>, otherwise a null pointer. + */ + template<typename _ValueType> + inline _ValueType* any_cast(any* __any) noexcept + { + if (__any) + return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); + return nullptr; + } + +#ifdef __GXX_RTTI + template<typename _Tp, typename _Alloc> + struct any::_Manager_alloc<_Tp, _Alloc>::_Data + { + using _Traits = std::allocator_traits<_Alloc>; + + std::tuple<_Alloc, __gnu_cxx::__aligned_buffer<_Tp>> _M_data; + + _Alloc& _M_alloc() { return std::get<0>(_M_data); } + const _Alloc& _M_alloc() const { return std::get<0>(_M_data); } + + _Tp* _M_obj() { return std::get<1>(_M_data)._M_ptr(); } + const _Tp* _M_obj() const { return std::get<1>(_M_data)._M_ptr(); } + + template<typename _Up> + _Data(const _Alloc& __a, _Up&& __val) : _M_data(__a, nullptr) + { + this->_M_construct(std::__use_alloc<_Tp>(_M_alloc()), + std::forward<_Up>(__val)); + } + + ~_Data() { _Traits::destroy(_M_alloc(), _M_obj()); } + + template<typename _Up> + void + _M_construct(__uses_alloc0, _Up&& __val) + { + _Traits::construct(_M_alloc(), _M_obj(), + std::forward<_Up>(__val)); + } + + template<typename _Up> + void + _M_construct(__uses_alloc1<_Alloc> __a, _Up&& __val) + { + _Traits::construct(__a._M_a, _M_obj(), + std::allocator_arg, __a._M_a, + std::forward<_Up>(__val)); + } + + template<typename _Up> + void + _M_construct(__uses_alloc2<_Alloc> __a, _Up&& __val) + { + _Traits::construct(__a._M_a, _M_obj(), + std::forward<_Up>(__val), __a._M_a); + } + }; + + template<typename _Tp, typename _Alloc> + template<typename _Up> + any::_Storage + any::_Manager_alloc<_Tp, _Alloc>:: + _S_alloc(const _Alloc& __a, _Up&& __value) + { + typename _Traits::allocator_type __a2(__a); + auto __ptr = _Traits::allocate(__a2, 1); + __try + { + any::_Storage __storage; + __storage._M_ptr = std::__addressof(*__ptr); + ::new(__storage._M_ptr) _Data{__a, std::forward<_Up>(__value)}; + return __storage; + } + __catch(...) + { + _Traits::deallocate(__a2, __ptr, 1); + __throw_exception_again; + } + } +#endif + + template<typename _Tp> + void + any::_Manager_internal<_Tp>:: + _S_manage(_Op __which, const any* __any, _Arg* __arg) + { + // The contained object is in _M_storage._M_buffer + auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer); + switch (__which) + { + case _Op_access: + __arg->_M_obj = const_cast<_Tp*>(__ptr); + break; + case _Op_get_type_info: +#ifdef __GXX_RTTI + __arg->_M_typeinfo = &typeid(_Tp); +#endif + break; + case _Op_clone: + ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr); + break; + case _Op_destroy: + __ptr->~_Tp(); + break; + } + } + + template<typename _Tp> + void + any::_Manager_external<_Tp>:: + _S_manage(_Op __which, const any* __any, _Arg* __arg) + { + // The contained object is *_M_storage._M_ptr + auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr); + switch (__which) + { + case _Op_access: + __arg->_M_obj = const_cast<_Tp*>(__ptr); + break; + case _Op_get_type_info: +#ifdef __GXX_RTTI + __arg->_M_typeinfo = &typeid(_Tp); +#endif + break; + case _Op_clone: + __arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr); + break; + case _Op_destroy: + delete __ptr; + break; + } + } + +#ifdef __GXX_RTTI + template<typename _Tp, typename _Alloc> + void + any::_Manager_alloc<_Tp, _Alloc>:: + _S_manage(_Op __which, const any* __any, _Arg* __arg) + { + // The contained object is at _M_storage._M_ptr->_M_obj() + auto __ptr = static_cast<const _Data*>(__any->_M_storage._M_ptr); + switch (__which) + { + case _Op_access: + __arg->_M_obj = const_cast<_Tp*>(__ptr->_M_obj()); + break; + case _Op_get_type_info: + __arg->_M_typeinfo = &typeid(_Tp); + break; + case _Op_clone: + __arg->_M_any->_M_storage + = _S_alloc(__ptr->_M_alloc(), *__ptr->_M_obj()); + break; + case _Op_destroy: + { + using _PtrTr = pointer_traits<typename _Traits::pointer>; + typename _Traits::allocator_type __a(__ptr->_M_alloc()); + auto __alloc_ptr = _PtrTr::pointer_to(*const_cast<_Data*>(__ptr)); + __ptr->~_Data(); + _Traits::deallocate(__a, __alloc_ptr, 1); + } + break; + } + } +#endif + + // @} group any +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace any_v1 +} // namespace experimental +} // namespace std + +#endif // C++14 + +#endif // _GLIBCXX_EXPERIMENTAL_ANY diff --git a/libstdc++-v3/include/ext/aligned_buffer.h b/libstdc++-v3/include/ext/aligned_buffer.h index 861de5b..783a874 100644 --- a/libstdc++-v3/include/ext/aligned_buffer.h +++ b/libstdc++-v3/include/ext/aligned_buffer.h @@ -47,6 +47,11 @@ namespace __gnu_cxx std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>::type _M_storage; + __aligned_buffer() = default; + + // Can be used to avoid value-initialization + __aligned_buffer(std::nullptr_t) { } + void* _M_addr() noexcept { diff --git a/libstdc++-v3/testsuite/experimental/any/assign/1.cc b/libstdc++-v3/testsuite/experimental/any/assign/1.cc new file mode 100644 index 0000000..9845d5c --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/assign/1.cc @@ -0,0 +1,60 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <testsuite_hooks.h> + +using std::experimental::any; + +void test01() +{ + any x; + any y; + y = x; + VERIFY( x.empty() ); + VERIFY( y.empty() ); + + y = std::move(x); + VERIFY( x.empty() ); + VERIFY( y.empty() ); +} + +void test02() +{ + any x(1); + any y; + y = x; + VERIFY( !x.empty() ); + VERIFY( !y.empty() ); + + x = std::move(y); + VERIFY( !x.empty() ); + VERIFY( y.empty() ); + + x = y; + VERIFY( x.empty() ); + VERIFY( y.empty() ); +} + +int main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/experimental/any/assign/2.cc b/libstdc++-v3/testsuite/experimental/any/assign/2.cc new file mode 100644 index 0000000..1aa6f39 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/assign/2.cc @@ -0,0 +1,51 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <testsuite_hooks.h> + +using std::experimental::any; +using std::experimental::any_cast; + +struct X +{ + bool moved = false; + bool moved_from = false; + X() = default; + X(const X&) = default; + X(X&& x) : moved(true) { x.moved_from = true; } +}; + +void test01() +{ + X x; + any a1; + a1 = x; + VERIFY(x.moved_from == false); + any a2; + a2 = std::move(x); + VERIFY(x.moved_from == true); + VERIFY(any_cast<X&>(a2).moved == true ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/experimental/any/cons/1.cc b/libstdc++-v3/testsuite/experimental/any/cons/1.cc new file mode 100644 index 0000000..cc36980 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/cons/1.cc @@ -0,0 +1,58 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <testsuite_hooks.h> + +using std::experimental::any; + +void test01() +{ + any x; + VERIFY( x.empty() ); + + any y(x); + VERIFY( x.empty() ); + VERIFY( y.empty() ); + + any z(std::move(y)); + VERIFY( y.empty() ); + VERIFY( z.empty() ); +} + +void test02() +{ + any x(1); + VERIFY( !x.empty() ); + + any y(x); + VERIFY( !x.empty() ); + VERIFY( !y.empty() ); + + any z(std::move(y)); + VERIFY( y.empty() ); + VERIFY( !z.empty() ); +} + +int main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/experimental/any/cons/2.cc b/libstdc++-v3/testsuite/experimental/any/cons/2.cc new file mode 100644 index 0000000..c766edf --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/cons/2.cc @@ -0,0 +1,49 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <testsuite_hooks.h> + +using std::experimental::any; +using std::experimental::any_cast; + +struct X +{ + bool moved = false; + bool moved_from = false; + X() = default; + X(const X&) = default; + X(X&& x) : moved(true) { x.moved_from = true; } +}; + +void test01() +{ + X x; + any a1(x); + VERIFY(x.moved_from == false); + any a2(std::move(x)); + VERIFY(x.moved_from == true); + VERIFY(any_cast<X&>(a2).moved == true ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/experimental/any/cons/3.cc b/libstdc++-v3/testsuite/experimental/any/cons/3.cc new file mode 100644 index 0000000..671a178 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/cons/3.cc @@ -0,0 +1,83 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <testsuite_allocator.h> + +using std::experimental::any; +using __gnu_test::CustomPointerAlloc; +using __gnu_test::tracker_allocator; +using __gnu_test::tracker_allocator_counter; + +struct NotSmall { char c[64]; }; + +bool test [[gnu::unused]] = true; + +void test01() +{ + CustomPointerAlloc<int> alloc; + + any x(std::allocator_arg, alloc, 1); + VERIFY( !x.empty() ); + + any y(std::allocator_arg, alloc, std::move(x)); + VERIFY( x.empty() ); + VERIFY( !y.empty() ); +} + +void test02() +{ + tracker_allocator<int> alloc; + + any x(std::allocator_arg, alloc, 1); + auto allocated = tracker_allocator_counter::get_allocation_count(); + VERIFY( allocated == 0 ); // no allocation for small object + + any y(std::allocator_arg, alloc, std::move(x)); + VERIFY( tracker_allocator_counter::get_allocation_count() == 0 ); + + y = {}; + VERIFY( tracker_allocator_counter::get_deallocation_count() == 0 ); +} + +void test03() +{ + tracker_allocator<int> alloc; + + + any x(std::allocator_arg, alloc, NotSmall{}); + auto allocated = tracker_allocator_counter::get_allocation_count(); + __builtin_printf("ALLOCATED %lu\n", (unsigned long)allocated); + VERIFY( allocated >= sizeof(NotSmall) ); + + any y(std::allocator_arg, alloc, std::move(x)); + VERIFY( tracker_allocator_counter::get_allocation_count() == allocated ); + + y = {}; + VERIFY( tracker_allocator_counter::get_deallocation_count() == allocated ); +} + + +int main() +{ + test01(); + test02(); + test03(); +} diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc new file mode 100644 index 0000000..98de1bc6 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc @@ -0,0 +1,108 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <string> +#include <cstring> +#include <testsuite_hooks.h> + +using std::experimental::any; +using std::experimental::any_cast; + +void test01() +{ + using std::string; + using std::strcmp; + + // taken from example in N3804 proposal + + any x(5); // x holds int + VERIFY(any_cast<int>(x) == 5); // cast to value + any_cast<int&>(x) = 10; // cast to reference + VERIFY(any_cast<int>(x) == 10); + + x = "Meow"; // x holds const char* + VERIFY(strcmp(any_cast<const char*>(x), "Meow") == 0); + any_cast<const char*&>(x) = "Harry"; + VERIFY(strcmp(any_cast<const char*>(x), "Harry") == 0); + + x = string("Meow"); // x holds string + string s, s2("Jane"); + s = move(any_cast<string&>(x)); // move from any + VERIFY(s == "Meow"); + any_cast<string&>(x) = move(s2); // move to any + VERIFY(any_cast<const string&>(x) == "Jane"); + + string cat("Meow"); + const any y(cat); // const y holds string + VERIFY(any_cast<const string&>(y) == cat); +} + +void test02() +{ + using std::experimental::bad_any_cast; + any x(1); + auto p = any_cast<double>(&x); + VERIFY(p == nullptr); + + x = 1.0; + p = any_cast<double>(&x); + VERIFY(p != nullptr); + + x = any(); + p = any_cast<double>(&x); + VERIFY(p == nullptr); + + try { + any_cast<double>(x); + VERIFY(false); + } catch (const bad_any_cast&) { + } +} + +void test03() +{ + using std::experimental::bad_any_cast; + any x(std::allocator_arg, std::allocator<double>{}, 1); + auto p = any_cast<double>(&x); + VERIFY(p == nullptr); + + x = any(std::allocator_arg, std::allocator<int>{}, 1.0); + p = any_cast<double>(&x); + VERIFY(p != nullptr); + + x = any(std::allocator_arg, std::allocator<char>{}); + p = any_cast<double>(&x); + VERIFY(p == nullptr); + + try { + any_cast<double>(x); + VERIFY(false); + } catch (const bad_any_cast&) { + } +} + + +int main() +{ + test01(); + test02(); + test03(); +} diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc new file mode 100644 index 0000000..b93b039 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc @@ -0,0 +1,30 @@ +// { dg-options "-std=gnu++14" } +// { dg-do compile } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> + +void test01() +{ + using std::experimental::any; + using std::experimental::any_cast; + + const any y(1); + any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 381 } +} diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_no_rtti.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_no_rtti.cc new file mode 100644 index 0000000..4879e63 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_no_rtti.cc @@ -0,0 +1,54 @@ +// { dg-options "-std=gnu++14 -fno-rtti" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <string> +#include <cstring> +#include <testsuite_hooks.h> + +using std::experimental::any; +using std::experimental::any_cast; + +void test01() +{ + using std::experimental::bad_any_cast; + any x(1); + auto p = any_cast<double>(&x); + VERIFY(p == nullptr); + + x = 1.0; + p = any_cast<double>(&x); + VERIFY(p != nullptr); + + x = any(); + p = any_cast<double>(&x); + VERIFY(p == nullptr); + + try { + any_cast<double>(x); + VERIFY(false); + } catch (const bad_any_cast&) { + } +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/experimental/any/misc/swap.cc b/libstdc++-v3/testsuite/experimental/any/misc/swap.cc new file mode 100644 index 0000000..1faaee8 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/misc/swap.cc @@ -0,0 +1,38 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <testsuite_hooks.h> + +using std::experimental::any; + +void test01() +{ + any x(1); + any y; + swap(x, y); + VERIFY( x.empty() ); + VERIFY( !y.empty() ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/experimental/any/modifiers/1.cc b/libstdc++-v3/testsuite/experimental/any/modifiers/1.cc new file mode 100644 index 0000000..9e6c3ed --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/modifiers/1.cc @@ -0,0 +1,44 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <testsuite_hooks.h> + +using std::experimental::any; + +void test01() +{ + any x(1); + any y; + x.swap(y); + VERIFY( x.empty() ); + VERIFY( !y.empty() ); + x.swap(y); + VERIFY( !x.empty() ); + VERIFY( y.empty() ); + + x.clear(); + VERIFY( x.empty() ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/experimental/any/observers/type.cc b/libstdc++-v3/testsuite/experimental/any/observers/type.cc new file mode 100644 index 0000000..9784ca0 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/observers/type.cc @@ -0,0 +1,39 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <testsuite_hooks.h> + +using std::experimental::any; + +void test01() +{ + any x; + VERIFY( x.type() == typeid(void) ); + x = 1; + VERIFY( x.type() == typeid(int) ); + x = any(); + VERIFY( x.type() == typeid(void) ); +} + +int main() +{ + test01(); +} |