Implement P0032R3, Homogeneous interface for variant, any and optional,

for the parts concerning any and optional.
	* include/std/any (_Storage()): Make constexpr and have it
	initialize _M_ptr.
	(any()): Make constexpr.
	(any(const any&)): Adjust.
	(any(any&&)): Likewise.
	(__any_constructible_t): New.
	(any(_ValueType&&)): Constrain.
	(any(in_place_type_t<_Tp>, _Args&&...)): New.
	(any(in_place_type_t<_Tp>, initializer_list<_Up>, _Args&&...)):
	Likewise.
	(~any()): Adjust.
	(operator=(const any&)): Likewise.
	(operator=(any&&)): Likewise.
	(operator=(_ValueType&&)): Constrain.
	(emplace(_Args&&...)): New.
	(emplace(initializer_list<_Up>, _Args&&...)): Likewise.
	(clear()): Remove.
	(reset()): New.
	(swap(any&)): Adjust.
	(empty()): Remove.
	(has_value()): New.
	(type()): Adjust.
	(_Manager_internal::_S_create(_Storage&, _Args&&...)): New.
	(_Manager_external::_S_create(_Storage&, _Args&&...)): Likewise.
	(make_any(_Args&&...)): Likewise.
	(make_any(initializer_list<_Up>, _Args&&...)): Likewise.
	* include/std/optional (in_place_t, in_place): Remove.
	(bad_optional_access): Add a comment referring to LEWG 72.
	(emplace(_Args&&...)): Constrain.
	(has_value()): New.
	(reset()): Likewise.
	(make_optional(_Args&&...)): Likewise.
	(make_optional(initializer_list<_Up>, _Args&&...)): Likewise.
	* include/std/utility (in_place_tag): New.
	(__in_place, __in_place_type, __in_place_index): Likewise.
	(in_place_t, in_place_type_t, in_place_index_t): Likewise.
	(in_place(__in_place*)): Likewise.
	(in_place(__in_place_type<_Tp>*)): Likewise.
	(in_place(__in_place_index<_Idx>*)): Likewise.
	* testsuite/20_util/any/assign/1.cc: Adjust.
	* testsuite/20_util/any/assign/emplace.cc: New.
	* testsuite/20_util/any/assign/self.cc: Adjust.
	* testsuite/20_util/any/cons/1.cc: Likewise.
	* testsuite/20_util/any/cons/in_place.cc: New.
	* testsuite/20_util/any/make_any.cc: Likewise.
	* testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.
	* testsuite/20_util/any/misc/swap.cc: Likewise.
	* testsuite/20_util/any/modifiers/1.cc: Likewise.
	* testsuite/20_util/any/requirements.cc: New.
	* testsuite/20_util/in_place/requirements.cc: Likewise.
	* testsuite/20_util/optional/constexpr/in_place.cc: Adjust.
	* testsuite/20_util/optional/in_place.cc: Likewise.
	* testsuite/20_util/optional/make_optional.cc: Add tests for
	the new overloads of make_optional.

From-SVN: r238329
This commit is contained in:
Ville Voutilainen 2016-07-14 12:10:05 +03:00 committed by Ville Voutilainen
parent c0d31471ba
commit 25a69162c9
18 changed files with 538 additions and 89 deletions

View File

@ -1,3 +1,62 @@
2016-07-14 Ville Voutilainen <ville.voutilainen@gmail.com>
Implement P0032R3, Homogeneous interface for variant, any and optional,
for the parts concerning any and optional.
* include/std/any (_Storage()): Make constexpr and have it
initialize _M_ptr.
(any()): Make constexpr.
(any(const any&)): Adjust.
(any(any&&)): Likewise.
(__any_constructible_t): New.
(any(_ValueType&&)): Constrain.
(any(in_place_type_t<_Tp>, _Args&&...)): New.
(any(in_place_type_t<_Tp>, initializer_list<_Up>, _Args&&...)):
Likewise.
(~any()): Adjust.
(operator=(const any&)): Likewise.
(operator=(any&&)): Likewise.
(operator=(_ValueType&&)): Constrain.
(emplace(_Args&&...)): New.
(emplace(initializer_list<_Up>, _Args&&...)): Likewise.
(clear()): Remove.
(reset()): New.
(swap(any&)): Adjust.
(empty()): Remove.
(has_value()): New.
(type()): Adjust.
(_Manager_internal::_S_create(_Storage&, _Args&&...)): New.
(_Manager_external::_S_create(_Storage&, _Args&&...)): Likewise.
(make_any(_Args&&...)): Likewise.
(make_any(initializer_list<_Up>, _Args&&...)): Likewise.
* include/std/optional (in_place_t, in_place): Remove.
(bad_optional_access): Add a comment referring to LEWG 72.
(emplace(_Args&&...)): Constrain.
(has_value()): New.
(reset()): Likewise.
(make_optional(_Args&&...)): Likewise.
(make_optional(initializer_list<_Up>, _Args&&...)): Likewise.
* include/std/utility (in_place_tag): New.
(__in_place, __in_place_type, __in_place_index): Likewise.
(in_place_t, in_place_type_t, in_place_index_t): Likewise.
(in_place(__in_place*)): Likewise.
(in_place(__in_place_type<_Tp>*)): Likewise.
(in_place(__in_place_index<_Idx>*)): Likewise.
* testsuite/20_util/any/assign/1.cc: Adjust.
* testsuite/20_util/any/assign/emplace.cc: New.
* testsuite/20_util/any/assign/self.cc: Adjust.
* testsuite/20_util/any/cons/1.cc: Likewise.
* testsuite/20_util/any/cons/in_place.cc: New.
* testsuite/20_util/any/make_any.cc: Likewise.
* testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.
* testsuite/20_util/any/misc/swap.cc: Likewise.
* testsuite/20_util/any/modifiers/1.cc: Likewise.
* testsuite/20_util/any/requirements.cc: New.
* testsuite/20_util/in_place/requirements.cc: Likewise.
* testsuite/20_util/optional/constexpr/in_place.cc: Adjust.
* testsuite/20_util/optional/in_place.cc: Likewise.
* testsuite/20_util/optional/make_optional.cc: Add tests for
the new overloads of make_optional.
2016-07-13 Ville Voutilainen <ville.voutilainen@gmail.com>
Implement P0307R2, Making Optional Greater Equal Again.

View File

@ -79,8 +79,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Holds either pointer to a heap object or the contained object itself.
union _Storage
{
// This constructor intentionally doesn't initialize anything.
_Storage() = default;
constexpr _Storage() : _M_ptr{nullptr} {}
// Prevent trivial copies of this type, buffer might hold a non-POD.
_Storage(const _Storage&) = delete;
@ -113,12 +112,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// construct/destruct
/// Default constructor, creates an empty object.
any() noexcept : _M_manager(nullptr) { }
constexpr any() noexcept : _M_manager(nullptr) { }
/// Copy constructor, copies the state of @p __other
any(const any& __other)
{
if (__other.empty())
if (!__other.has_value())
_M_manager = nullptr;
else
{
@ -131,11 +130,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Move constructor, transfer the state from @p __other
*
* @post @c __other.empty() (this postcondition is a GNU extension)
* @post @c !__other.has_value() (this postcondition is a GNU extension)
*/
any(any&& __other) noexcept
{
if (__other.empty())
if (!__other.has_value())
_M_manager = nullptr;
else
{
@ -145,45 +144,71 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
template <typename _Tp, typename... _Args>
using __any_constructible_t =
enable_if_t<__and_<is_copy_constructible<_Tp>,
is_constructible<_Tp, _Args...>>::value,
bool>;
/// Construct with a copy of @p __value as the contained object.
template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
typename _Mgr = _Manager<_Tp>,
typename enable_if<is_constructible<_Tp, _ValueType&&>::value,
bool>::type = true>
__any_constructible_t<_Tp, _ValueType&&> = true>
any(_ValueType&& __value)
: _M_manager(&_Mgr::_S_manage)
{
_Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value));
static_assert(is_copy_constructible<_Tp>::value,
"The contained object must be CopyConstructible");
}
/// Construct with a copy of @p __value as the contained object.
template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
typename _Mgr = _Manager<_Tp>,
typename enable_if<!is_constructible<_Tp, _ValueType&&>::value,
bool>::type = false>
enable_if_t<__and_<is_copy_constructible<_Tp>,
__not_<
is_constructible<_Tp,
_ValueType&&>>>::value,
bool> = false>
any(_ValueType&& __value)
: _M_manager(&_Mgr::_S_manage)
{
_Mgr::_S_create(_M_storage, __value);
static_assert(is_copy_constructible<_Tp>::value,
"The contained object must be CopyConstructible");
}
/// Destructor, calls @c clear()
~any() { clear(); }
/// Construct with an object created from @p __args as the contained object.
template <typename _Tp, typename... _Args,
typename _Mgr = _Manager<_Tp>,
__any_constructible_t<_Tp, _Args&&...> = false>
any(in_place_type_t<_Tp>, _Args&&... __args)
: _M_manager(&_Mgr::_S_manage)
{
_Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
}
/// Construct with an object created from @p __il and @p __args as
/// the contained object.
template <typename _Tp, typename _Up, typename... _Args,
typename _Mgr = _Manager<_Tp>,
__any_constructible_t<_Tp, initializer_list<_Up>,
_Args&&...> = false>
any(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args)
: _M_manager(&_Mgr::_S_manage)
{
_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
}
/// Destructor, calls @c reset()
~any() { reset(); }
// assignments
/// Copy the state of another object.
any& operator=(const any& __rhs)
{
if (__rhs.empty())
clear();
if (!__rhs.has_value())
reset();
else if (this != &__rhs)
{
if (!empty())
if (has_value())
_M_manager(_Op_destroy, this, nullptr);
_Arg __arg;
__arg._M_any = this;
@ -195,15 +220,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Move assignment operator
*
* @post @c __rhs.empty() (not guaranteed for other implementations)
* @post @c !__rhs.has_value() (not guaranteed for other implementations)
*/
any& operator=(any&& __rhs) noexcept
{
if (__rhs.empty())
clear();
if (!__rhs.has_value())
reset();
else if (this != &__rhs)
{
if (!empty())
if (has_value())
_M_manager(_Op_destroy, this, nullptr);
_Arg __arg;
__arg._M_any = this;
@ -214,19 +239,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Store a copy of @p __rhs as the contained object.
template<typename _ValueType>
enable_if_t<!is_same<any, decay_t<_ValueType>>::value, any&>
enable_if_t<__and_<__not_<is_same<any, decay_t<_ValueType>>>,
is_copy_constructible<_ValueType>>::value, any&>
operator=(_ValueType&& __rhs)
{
*this = any(std::forward<_ValueType>(__rhs));
return *this;
}
/// Emplace with an object created from @p __args as the contained object.
template <typename _Tp, typename... _Args,
typename _Mgr = _Manager<_Tp>,
__any_constructible_t<_Tp, _Args&&...> = false>
void emplace(_Args&&... __args)
{
reset();
_M_manager = &_Mgr::_S_manage;
_Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
}
/// Emplace with an object created from @p __il and @p __args as
/// the contained object.
template <typename _Tp, typename _Up, typename... _Args,
typename _Mgr = _Manager<_Tp>,
__any_constructible_t<_Tp, initializer_list<_Up>,
_Args&&...> = false>
void emplace(initializer_list<_Up> __il, _Args&&... __args)
{
reset();
_M_manager = &_Mgr::_S_manage;
_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
}
// modifiers
/// If not empty, destroy the contained object.
void clear() noexcept
void reset() noexcept
{
if (!empty())
if (has_value())
{
_M_manager(_Op_destroy, this, nullptr);
_M_manager = nullptr;
@ -236,10 +286,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Exchange state with another object.
void swap(any& __rhs) noexcept
{
if (empty() && __rhs.empty())
if (!has_value() && !__rhs.has_value())
return;
if (!empty() && !__rhs.empty())
if (has_value() && __rhs.has_value())
{
if (this == &__rhs)
return;
@ -255,8 +305,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
else
{
any* __empty = empty() ? this : &__rhs;
any* __full = empty() ? &__rhs : this;
any* __empty = !has_value() ? this : &__rhs;
any* __full = !has_value() ? &__rhs : this;
_Arg __arg;
__arg._M_any = __empty;
__full->_M_manager(_Op_xfer, __full, &__arg);
@ -266,13 +316,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// observers
/// Reports whether there is a contained object or not.
bool empty() const noexcept { return _M_manager == nullptr; }
bool has_value() const noexcept { return _M_manager != nullptr; }
#if __cpp_rtti
/// The @c typeid of the contained object, or @c typeid(void) if empty.
const type_info& type() const noexcept
{
if (empty())
if (!has_value())
return typeid(void);
_Arg __arg;
_M_manager(_Op_get_type_info, this, &__arg);
@ -316,6 +366,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void* __addr = &__storage._M_buffer;
::new (__addr) _Tp(std::forward<_Up>(__value));
}
template<typename... _Args>
static void
_S_create(_Storage& __storage, _Args&&... __args)
{
void* __addr = &__storage._M_buffer;
::new (__addr) _Tp(std::forward<_Args>(__args)...);
}
};
// Manage external contained object.
@ -331,12 +389,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
__storage._M_ptr = new _Tp(std::forward<_Up>(__value));
}
template<typename... _Args>
static void
_S_create(_Storage& __storage, _Args&&... __args)
{
__storage._M_ptr = new _Tp(std::forward<_Args>(__args)...);
}
};
};
/// Exchange the states of two @c any objects.
inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); }
/// Create an any holding a @c _Tp constructed from @c __args.
template <typename _Tp, typename... _Args>
any make_any(_Args&&... __args)
{
return any(in_place<_Tp>, std::forward<_Args>(__args)...);
}
/// Create an any holding a @c _Tp constructed from @c __il and @c __args.
template <typename _Tp, typename _Up, typename... _Args>
any make_any(initializer_list<_Up> __il, _Args&&... __args)
{
return any(in_place<_Tp>, __il, std::forward<_Args>(__args)...);
}
/**
* @brief Access the contained object.
*

View File

@ -57,13 +57,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
class optional;
// [X.Y.5]
/// Tag type for in-place construction.
struct in_place_t { };
/// Tag for in-place construction.
constexpr in_place_t in_place { };
// [X.Y.6]
/// Tag type to disengage optional objects.
struct nullopt_t
@ -91,9 +84,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
class bad_optional_access : public logic_error
{
// XXX See LEWG 72, https://issues.isocpp.org/show_bug.cgi?id=72
public:
bad_optional_access() : logic_error("bad optional access") { }
// XXX This constructor is non-standard. Should not be inline
explicit bad_optional_access(const char* __arg) : logic_error(__arg) { }
@ -641,18 +634,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename... _Args>
void
enable_if_t<is_constructible<_Tp, _Args&&...>::value>
emplace(_Args&&... __args)
{
static_assert(is_constructible<_Tp, _Args&&...>(),
"Cannot emplace value type from arguments");
this->_M_reset();
this->_M_construct(std::forward<_Args>(__args)...);
}
template<typename _Up, typename... _Args>
enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
_Args&&...>::value>
emplace(initializer_list<_Up> __il, _Args&&... __args)
{
@ -712,6 +702,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr explicit operator bool() const noexcept
{ return this->_M_is_engaged(); }
constexpr bool has_value() const noexcept
{ return this->_M_is_engaged(); }
constexpr const _Tp&
value() const&
{
@ -777,6 +770,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
? std::move(this->_M_get())
: static_cast<_Tp>(std::forward<_Up>(__u));
}
void reset() { this->_M_reset(); }
};
template<typename _Tp>
@ -980,6 +974,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
make_optional(_Tp&& __t)
{ return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
template<typename _Tp, typename ..._Args>
constexpr optional<_Tp>
make_optional(_Args&&... __args)
{ return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
template<typename _Tp, typename _Up, typename ..._Args>
constexpr optional<_Tp>
make_optional(initializer_list<_Up> __il, _Args&&... __args)
{ return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
// [X.Y.12]
template<typename _Tp>
struct hash<optional<_Tp>>

View File

@ -75,6 +75,10 @@
#include <bits/move.h>
#include <initializer_list>
#if __cplusplus > 201402L
#include <exception>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@ -330,6 +334,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
#endif
#if __cplusplus > 201402L
struct in_place_tag {
in_place_tag() = delete;
};
struct __in_place;
template<typename _Tp> struct __in_place_type;
template<size_t _Idx> struct __in_place_index;
using in_place_t = in_place_tag(&)(__in_place*);
template <class _Tp>
using in_place_type_t = in_place_tag(&)(__in_place_type<_Tp>*);
template <int _Idx>
using in_place_index_t = in_place_tag(&)(__in_place_index<_Idx>*);
inline in_place_tag in_place(__in_place*) {terminate();}
template <class _Tp>
in_place_tag in_place(__in_place_type<_Tp>*) {terminate();}
template <size_t _Idx>
in_place_tag in_place(__in_place_index<_Idx>*) {terminate();}
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

View File

@ -28,12 +28,12 @@ void test01()
any x;
any y;
y = x;
VERIFY( x.empty() );
VERIFY( y.empty() );
VERIFY( !x.has_value() );
VERIFY( !y.has_value() );
y = std::move(x);
VERIFY( x.empty() );
VERIFY( y.empty() );
VERIFY( !x.has_value() );
VERIFY( !y.has_value() );
}
void test02()
@ -41,16 +41,16 @@ void test02()
any x(1);
any y;
y = x;
VERIFY( !x.empty() );
VERIFY( !y.empty() );
VERIFY( x.has_value() );
VERIFY( y.has_value() );
x = std::move(y);
VERIFY( !x.empty() );
VERIFY( y.empty() );
VERIFY( x.has_value() );
VERIFY( !y.has_value() );
x = y;
VERIFY( x.empty() );
VERIFY( y.empty() );
VERIFY( !x.has_value() );
VERIFY( !y.has_value() );
}
int main()

View File

@ -0,0 +1,62 @@
// { dg-options "-std=gnu++17" }
// { dg-do run }
// Copyright (C) 2016 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 moved_to of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <any>
#include <testsuite_hooks.h>
#include <vector>
#include <tuple>
struct combined {
std::vector<int> v;
std::tuple<int, int> t;
template<class... Args>
combined(std::initializer_list<int> il, Args&&... args)
: v(il), t(std::forward<Args>(args)...)
{
}
};
int main()
{
const int i = 42;
std::any o;
o.emplace<int>(i);
int& i2 = std::any_cast<int&>(o);
VERIFY( i2 == 42 );
VERIFY( &i2 != &i );
std::any o2;
o2.emplace<std::tuple<int, int>>(1, 2);
std::tuple<int, int>& t = std::any_cast<std::tuple<int, int>&>(o2);
VERIFY( std::get<0>(t) == 1 && std::get<1>(t) == 2);
std::any o3;
o3.emplace<std::vector<int>>({42, 666});
std::vector<int>& v = std::any_cast<std::vector<int>&>(o3);
VERIFY(v[0] == 42 && v[1] == 666);
std::any o4;
o4.emplace<combined>({42, 666});
combined& c = std::any_cast<combined&>(o4);
VERIFY(c.v[0] == 42 && c.v[1] == 666
&& std::get<0>(c.t) == 0 && std::get<1>(c.t) == 0 );
std::any o5;
o5.emplace<combined>({1, 2}, 3, 4);
combined& c2 = std::any_cast<combined&>(o5);
VERIFY(c2.v[0] == 1 && c2.v[1] == 2
&& std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 );
}

View File

@ -36,13 +36,13 @@ test01()
any a;
a = a;
VERIFY( a.empty() );
VERIFY( !a.has_value() );
a = A{};
a = a;
VERIFY( !a.empty() );
VERIFY( a.has_value() );
a.clear();
a.reset();
VERIFY( live_objects.empty() );
}
@ -57,13 +57,13 @@ test02()
X x;
std::swap(x, x); // results in "self-move-assignment" of X::a
VERIFY( x.a.empty() );
VERIFY( !x.a.has_value() );
x.a = A{};
std::swap(x, x); // results in "self-move-assignment" of X::a
VERIFY( !x.a.empty() );
VERIFY( x.a.has_value() );
x.a.clear();
x.a.reset();
VERIFY( live_objects.empty() );
}
@ -74,13 +74,13 @@ test03()
any a;
a.swap(a);
VERIFY( a.empty() );
VERIFY( !a.has_value() );
a = A{};
a.swap(a);
VERIFY( !a.empty() );
VERIFY( a.has_value() );
a.clear();
a.reset();
VERIFY( live_objects.empty() );
}

View File

@ -26,29 +26,29 @@ using std::any;
void test01()
{
any x;
VERIFY( x.empty() );
VERIFY( !x.has_value() );
any y(x);
VERIFY( x.empty() );
VERIFY( y.empty() );
VERIFY( !x.has_value() );
VERIFY( !y.has_value() );
any z(std::move(y));
VERIFY( y.empty() );
VERIFY( z.empty() );
VERIFY( !y.has_value() );
VERIFY( !z.has_value() );
}
void test02()
{
any x(1);
VERIFY( !x.empty() );
VERIFY( x.has_value() );
any y(x);
VERIFY( !x.empty() );
VERIFY( !y.empty() );
VERIFY( x.has_value() );
VERIFY( y.has_value() );
any z(std::move(y));
VERIFY( y.empty() );
VERIFY( !z.empty() );
VERIFY( !y.has_value() );
VERIFY( z.has_value() );
}
int main()

View File

@ -0,0 +1,57 @@
// { dg-options "-std=gnu++17" }
// { dg-do run }
// Copyright (C) 2016 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 moved_to of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <any>
#include <testsuite_hooks.h>
#include <vector>
#include <tuple>
struct combined {
std::vector<int> v;
std::tuple<int, int> t;
template<class... Args>
combined(std::initializer_list<int> il, Args&&... args)
: v(il), t(std::forward<Args>(args)...)
{
}
};
int main()
{
const int i = 42;
std::any o(std::in_place<int>, i);
int& i2 = std::any_cast<int&>(o);
VERIFY( i2 == 42 );
VERIFY( &i2 != &i );
std::any o2(std::in_place<std::tuple<int, int>>, 1, 2);
std::tuple<int, int>& t = std::any_cast<std::tuple<int, int>&>(o2);
VERIFY( std::get<0>(t) == 1 && std::get<1>(t) == 2);
std::any o3(std::in_place<std::vector<int>>, {42, 666});
std::vector<int>& v = std::any_cast<std::vector<int>&>(o3);
VERIFY(v[0] == 42 && v[1] == 666);
std::any o4(std::in_place<combined>, {42, 666});
combined& c = std::any_cast<combined&>(o4);
VERIFY(c.v[0] == 42 && c.v[1] == 666
&& std::get<0>(c.t) == 0 && std::get<1>(c.t) == 0 );
std::any o5(std::in_place<combined>, {1, 2}, 3, 4);
combined& c2 = std::any_cast<combined&>(o5);
VERIFY(c2.v[0] == 1 && c2.v[1] == 2
&& std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 );
}

View File

@ -0,0 +1,57 @@
// { dg-options "-std=gnu++17" }
// { dg-do run }
// Copyright (C) 2016 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 moved_to of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <any>
#include <testsuite_hooks.h>
#include <vector>
#include <tuple>
struct combined {
std::vector<int> v;
std::tuple<int, int> t;
template<class... Args>
combined(std::initializer_list<int> il, Args&&... args)
: v(il), t(std::forward<Args>(args)...)
{
}
};
int main()
{
const int i = 42;
auto o = std::make_any<int>(i);
int& i2 = std::any_cast<int&>(o);
VERIFY( i2 == 42 );
VERIFY( &i2 != &i );
auto o2 = std::make_any<std::tuple<int, int>>(1, 2);
std::tuple<int, int>& t = std::any_cast<std::tuple<int, int>&>(o2);
VERIFY( std::get<0>(t) == 1 && std::get<1>(t) == 2);
auto o3 = std::make_any<std::vector<int>>({42, 666});
std::vector<int>& v = std::any_cast<std::vector<int>&>(o3);
VERIFY(v[0] == 42 && v[1] == 666);
auto o4 = std::make_any<combined>({42, 666});
combined& c = std::any_cast<combined&>(o4);
VERIFY(c.v[0] == 42 && c.v[1] == 666
&& std::get<0>(c.t) == 0 && std::get<1>(c.t) == 0 );
auto o5 = std::make_any<combined>({1, 2}, 3, 4);
combined& c2 = std::any_cast<combined&>(o5);
VERIFY(c2.v[0] == 1 && c2.v[1] == 2
&& std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 );
}

View File

@ -26,5 +26,5 @@ void test01()
using std::any_cast;
const any y(1);
any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 357 }
any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 435 }
}

View File

@ -28,8 +28,8 @@ void test01()
any x(1);
any y;
swap(x, y);
VERIFY( x.empty() );
VERIFY( !y.empty() );
VERIFY( !x.has_value() );
VERIFY( y.has_value() );
}
int main()

View File

@ -28,14 +28,14 @@ void test01()
any x(1);
any y;
x.swap(y);
VERIFY( x.empty() );
VERIFY( !y.empty() );
VERIFY( !x.has_value() );
VERIFY( y.has_value() );
x.swap(y);
VERIFY( !x.empty() );
VERIFY( y.empty() );
VERIFY( x.has_value() );
VERIFY( !y.has_value() );
x.clear();
VERIFY( x.empty() );
x.reset();
VERIFY( !x.has_value() );
}
int main()

View File

@ -0,0 +1,33 @@
// { dg-options "-std=gnu++17" }
// { dg-do compile }
// Copyright (C) 2016 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 moved_to of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <any>
#include <testsuite_hooks.h>
#include <memory>
using std::any;
using std::unique_ptr;
static_assert(std::is_assignable<any&, int>::value);
static_assert(!std::is_assignable<any&, unique_ptr<int>>::value);
static_assert(std::is_constructible<any, int>::value);
static_assert(!std::is_constructible<any, unique_ptr<int>>::value);

View File

@ -0,0 +1,47 @@
// { dg-options "-std=gnu++17" }
// { dg-do compile }
// Copyright (C) 2016 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 moved_to of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <utility>
#include <type_traits>
#include <testsuite_hooks.h>
using std::in_place_t;
using std::in_place_type_t;
using std::in_place_index_t;
float f(in_place_type_t<float>);
double f(in_place_type_t<double>);
char f(in_place_index_t<0>);
unsigned int f(in_place_index_t<1>);
int f(in_place_t);
static_assert(std::is_same<decltype(f(in_place_t(std::in_place))), int>::value);
static_assert(std::is_same<decltype(f(std::in_place<float>)), float>::value);
static_assert(std::is_same<decltype(f(std::in_place<double>)), double>::value);
static_assert(std::is_same<decltype(f(std::in_place<0>)), char>::value);
static_assert(std::is_same<decltype(f(std::in_place<1>)), unsigned int>::value);
template <class T, class... Args> float h(in_place_type_t<T>, Args&&...);
template <size_t N, class... Args> int h(in_place_index_t<N>, Args&&...);
template <class T> double h(in_place_t, T&&);
static_assert(std::is_same<decltype(h(std::in_place, 1)), double>::value);
static_assert(std::is_same<decltype(h(std::in_place<float>, 1)), float>::value);
static_assert(std::is_same<decltype(h(std::in_place<0>, 1)), int>::value);

View File

@ -24,9 +24,6 @@
int main()
{
// [20.5.5] In-place construction
static_assert( std::is_same<decltype(std::in_place), const std::in_place_t>(), "" );
static_assert( std::is_empty<std::in_place_t>(), "" );
{
constexpr std::optional<int> o { std::in_place };
static_assert( o, "" );

View File

@ -26,9 +26,6 @@
int main()
{
// [20.5.5] In-place construction
static_assert( std::is_same<decltype(std::in_place), const std::in_place_t>(), "" );
static_assert( std::is_empty<std::in_place_t>(), "" );
{
std::optional<int> o { std::in_place };
VERIFY( o );

View File

@ -20,6 +20,18 @@
#include <optional>
#include <testsuite_hooks.h>
#include <vector>
#include <tuple>
struct combined {
std::vector<int> v;
std::tuple<int, int> t;
template<class... Args>
combined(std::initializer_list<int> il, Args&&... args)
: v(il), t(std::forward<Args>(args)...)
{
}
};
int main()
{
@ -28,4 +40,22 @@ int main()
static_assert( std::is_same<decltype(o), std::optional<int>>(), "" );
VERIFY( o && *o == 42 );
VERIFY( &*o != &i );
auto o2 = std::make_optional<std::tuple<int, int>>(1, 2);
static_assert( std::is_same<decltype(o2),
std::optional<std::tuple<int, int>>>(), "" );
VERIFY( o2 && std::get<0>(*o2) == 1 && std::get<1>(*o2) == 2);
auto o3 = std::make_optional<std::vector<int>>({42, 666});
static_assert( std::is_same<decltype(o3),
std::optional<std::vector<int>>>(), "" );
VERIFY(o3 && (*o3)[0] == 42 && (*o3)[1] == 666);
auto o4 = std::make_optional<combined>({42, 666});
static_assert( std::is_same<decltype(o4),
std::optional<combined>>(), "" );
VERIFY(o4 && (o4->v)[0] == 42 && (o4->v)[1] == 666
&& std::get<0>(o4->t) == 0 && std::get<1>(o4->t) == 0 );
auto o5 = std::make_optional<combined>({1, 2}, 3, 4);
static_assert( std::is_same<decltype(o5),
std::optional<combined>>(), "" );
VERIFY(o4 && (o5->v)[0] == 1 && (o5->v)[1] == 2
&& std::get<0>(o5->t) == 3 && std::get<1>(o5->t) == 4 );
}