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
+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.
// 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;
// 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
{
/**
* @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
{
}
}
+ 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;
/**
* @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;
/// 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;
/// 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;
}
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);
// 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);
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.
{
__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.
*
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
*/
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) { }
}
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)
{
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&
{
? std::move(this->_M_get())
: static_cast<_Tp>(std::forward<_Up>(__u));
}
+ void reset() { this->_M_reset(); }
};
template<typename _Tp>
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>>
#include <bits/move.h>
#include <initializer_list>
+#if __cplusplus > 201402L
+#include <exception>
+#endif
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_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
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()
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()
--- /dev/null
+// { 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 );
+}
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() );
}
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() );
}
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() );
}
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()
--- /dev/null
+// { 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 );
+}
--- /dev/null
+// { 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 );
+}
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 }
}
any x(1);
any y;
swap(x, y);
- VERIFY( x.empty() );
- VERIFY( !y.empty() );
+ VERIFY( !x.has_value() );
+ VERIFY( y.has_value() );
}
int main()
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()
--- /dev/null
+// { 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);
+
--- /dev/null
+// { 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);
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, "" );
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 );
#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()
{
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 );
}