Index: include/any =================================================================== --- include/any +++ include/any @@ -45,6 +45,10 @@ any& operator=(ValueType&& rhs); // 6.3.3 any modifiers + template + decay_t& emplace(Args&&... args); + template + decay_t& emplace(initializer_list, Args&&...); void reset() noexcept; void swap(any& rhs) noexcept; @@ -73,8 +77,6 @@ template ValueType* any_cast(any* operand) noexcept; -} // namespace fundamentals_v1 -} // namespace experimental } // namespace std */ @@ -258,7 +260,7 @@ is_copy_constructible<_Tp>::value> > _LIBCPP_INLINE_VISIBILITY - void emplace(_Args&&... args); + _Tp& emplace(_Args&&... args); template , @@ -267,7 +269,7 @@ is_copy_constructible<_Tp>::value> > _LIBCPP_INLINE_VISIBILITY - void emplace(initializer_list<_Up>, _Args&&...); + _Tp& emplace(initializer_list<_Up>, _Args&&...); // 6.3.3 any modifiers _LIBCPP_INLINE_VISIBILITY @@ -364,9 +366,10 @@ template _LIBCPP_INLINE_VISIBILITY - static void __create(any & __dest, _Args&&... __args) { - ::new (static_cast(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...); + static _Tp& __create(any & __dest, _Args&&... __args) { + _Tp* __ret = ::new (static_cast(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...); __dest.__h = &_SmallHandler::__handle; + return *__ret; } private: @@ -439,14 +442,15 @@ template _LIBCPP_INLINE_VISIBILITY - static void __create(any & __dest, _Args&&... __args) { + static _Tp& __create(any & __dest, _Args&&... __args) { typedef allocator<_Tp> _Alloc; typedef __allocator_destructor<_Alloc> _Dp; _Alloc __a; unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...); + _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...); __dest.__s.__ptr = __hold.release(); __dest.__h = &_LargeHandler::__handle; + return *__ret; } private: @@ -519,16 +523,16 @@ template inline _LIBCPP_INLINE_VISIBILITY -void any::emplace(_Args&&... __args) { +_Tp& any::emplace(_Args&&... __args) { reset(); - __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); + return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); } template inline _LIBCPP_INLINE_VISIBILITY -void any::emplace(initializer_list<_Up> __il, _Args&&... __args) { +_Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) { reset(); - __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); + return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); } inline _LIBCPP_INLINE_VISIBILITY Index: include/optional =================================================================== --- include/optional +++ include/optional @@ -108,9 +108,9 @@ template optional &operator=(U &&); template optional &operator=(const optional &); template optional &operator=(optional &&); - template void emplace(Args &&...); + template T& emplace(Args &&...); template - void emplace(initializer_list, Args &&...); + T& emplace(initializer_list, Args &&...); // 20.6.3.4, swap void swap(optional &) noexcept(see below ); @@ -729,11 +729,12 @@ > > _LIBCPP_INLINE_VISIBILITY - void + _Tp & emplace(_Args&&... __args) { reset(); this->__construct(_VSTD::forward<_Args>(__args)...); + return this->__get(); } template > _LIBCPP_INLINE_VISIBILITY - void + _Tp & emplace(initializer_list<_Up> __il, _Args&&... __args) { reset(); this->__construct(__il, _VSTD::forward<_Args>(__args)...); + return this->__get(); } _LIBCPP_INLINE_VISIBILITY Index: test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp =================================================================== --- test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp +++ test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp @@ -11,9 +11,9 @@ // -// template emplace(Args&&...); +// template T& emplace(Args&&...); // template -// void emplace(initializer_list, Args&&...); +// T& emplace(initializer_list, Args&&...); #include #include @@ -42,7 +42,9 @@ any a(std::in_place_type); assert(Tracked::count == 1); - a.emplace(); + auto &v = a.emplace(); + static_assert( std::is_same_v, "" ); + assert(&v == std::any_cast(&a)); assert(Tracked::count == 0); assert(Type::count == 1); @@ -56,7 +58,9 @@ any a(std::in_place_type); assert(Tracked::count == 1); - a.emplace(101); + auto &v = a.emplace(101); + static_assert( std::is_same_v, "" ); + assert(&v == std::any_cast(&a)); assert(Tracked::count == 0); assert(Type::count == 1); @@ -70,7 +74,9 @@ any a(std::in_place_type); assert(Tracked::count == 1); - a.emplace(-1, 42, -1); + auto &v = a.emplace(-1, 42, -1); + static_assert( std::is_same_v, "" ); + assert(&v == std::any_cast(&a)); assert(Tracked::count == 0); assert(Type::count == 1); @@ -89,7 +95,10 @@ { any a(std::in_place_type); assert(Tracked::count == 1); - a.emplace(); + auto &v = a.emplace(); + static_assert( std::is_same_v, "" ); + assert(&v == std::any_cast(&a)); + assert(Tracked::count == 0); assertArgsMatch(a); } @@ -96,7 +105,10 @@ { any a(std::in_place_type); assert(Tracked::count == 1); - a.emplace(-1, 42, -1); + auto &v = a.emplace(-1, 42, -1); + static_assert( std::is_same_v, "" ); + assert(&v == std::any_cast(&a)); + assert(Tracked::count == 0); assertArgsMatch(a); } @@ -104,7 +116,10 @@ { any a(std::in_place_type); assert(Tracked::count == 1); - a.emplace({-1, 42, -1}); + auto &v = a.emplace({-1, 42, -1}); + static_assert( std::is_same_v, "" ); + assert(&v == std::any_cast(&a)); + assert(Tracked::count == 0); assertArgsMatch>(a); } @@ -112,7 +127,10 @@ int x = 42; any a(std::in_place_type); assert(Tracked::count == 1); - a.emplace({-1, 42, -1}, x); + auto &v = a.emplace({-1, 42, -1}, x); + static_assert( std::is_same_v, "" ); + assert(&v == std::any_cast(&a)); + assert(Tracked::count == 0); assertArgsMatch, int&>(a); } Index: test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp =================================================================== --- test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp +++ test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp @@ -10,7 +10,7 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 // -// template void optional::emplace(Args&&... args); +// template T& optional::emplace(Args&&... args); #include #include @@ -51,27 +51,35 @@ using Opt = std::optional; { Opt opt; - opt.emplace(); + auto & v = opt.emplace(); + static_assert( std::is_same_v, "" ); assert(static_cast(opt) == true); assert(*opt == T(0)); + assert(&v == &*opt); } { Opt opt; - opt.emplace(1); + auto & v = opt.emplace(1); + static_assert( std::is_same_v, "" ); assert(static_cast(opt) == true); assert(*opt == T(1)); + assert(&v == &*opt); } { Opt opt(2); - opt.emplace(); + auto & v = opt.emplace(); + static_assert( std::is_same_v, "" ); assert(static_cast(opt) == true); assert(*opt == T(0)); + assert(&v == &*opt); } { Opt opt(2); - opt.emplace(1); + auto & v = opt.emplace(1); + static_assert( std::is_same_v, "" ); assert(static_cast(opt) == true); assert(*opt == T(1)); + assert(&v == &*opt); } } @@ -83,20 +91,26 @@ using Opt = std::optional; { Opt opt; - opt.emplace(101, 41); + auto &v = opt.emplace(101, 41); + static_assert( std::is_same_v, "" ); assert(static_cast(opt) == true); + assert( v == T(101, 41)); assert(*opt == T(101, 41)); } { Opt opt; - opt.emplace({1, 2, 3, 4}); + auto &v = opt.emplace({1, 2, 3, 4}); + static_assert( std::is_same_v, "" ); assert(static_cast(opt) == true); - assert(*opt == T(4)); // T sets its value to the size of the init list + assert( v == T(4)); // T sets its value to the size of the init list + assert(*opt == T(4)); } { Opt opt; - opt.emplace({1, 2, 3, 4, 5}, 6); + auto &v = opt.emplace({1, 2, 3, 4, 5}, 6); + static_assert( std::is_same_v, "" ); assert(static_cast(opt) == true); + assert( v == T(5)); // T sets its value to the size of the init list assert(*opt == T(5)); // T sets its value to the size of the init list } } @@ -109,7 +123,8 @@ assert(T::alive == 0); { T::reset_constructors(); - opt.emplace(); + auto &v = opt.emplace(); + static_assert( std::is_same_v, "" ); assert(T::alive == 1); assert(T::constructed == 1); assert(T::default_constructed == 1); @@ -116,10 +131,12 @@ assert(T::destroyed == 0); assert(static_cast(opt) == true); assert(*opt == T()); + assert(&v == &*opt); } { T::reset_constructors(); - opt.emplace(); + auto &v = opt.emplace(); + static_assert( std::is_same_v, "" ); assert(T::alive == 1); assert(T::constructed == 1); assert(T::default_constructed == 1); @@ -126,10 +143,12 @@ assert(T::destroyed == 1); assert(static_cast(opt) == true); assert(*opt == T()); + assert(&v == &*opt); } { T::reset_constructors(); - opt.emplace(101); + auto &v = opt.emplace(101); + static_assert( std::is_same_v, "" ); assert(T::alive == 1); assert(T::constructed == 1); assert(T::value_constructed == 1); @@ -136,10 +155,12 @@ assert(T::destroyed == 1); assert(static_cast(opt) == true); assert(*opt == T(101)); + assert(&v == &*opt); } { T::reset_constructors(); - opt.emplace(-10, 99); + auto &v = opt.emplace(-10, 99); + static_assert( std::is_same_v, "" ); assert(T::alive == 1); assert(T::constructed == 1); assert(T::value_constructed == 1); @@ -146,10 +167,12 @@ assert(T::destroyed == 1); assert(static_cast(opt) == true); assert(*opt == T(-10, 99)); + assert(&v == &*opt); } { T::reset_constructors(); - opt.emplace(-10, 99); + auto &v = opt.emplace(-10, 99); + static_assert( std::is_same_v, "" ); assert(T::alive == 1); assert(T::constructed == 1); assert(T::value_constructed == 1); @@ -156,10 +179,12 @@ assert(T::destroyed == 1); assert(static_cast(opt) == true); assert(*opt == T(-10, 99)); + assert(&v == &*opt); } { T::reset_constructors(); - opt.emplace({-10, 99, 42, 1}); + auto &v = opt.emplace({-10, 99, 42, 1}); + static_assert( std::is_same_v, "" ); assert(T::alive == 1); assert(T::constructed == 1); assert(T::value_constructed == 1); @@ -166,10 +191,12 @@ assert(T::destroyed == 1); assert(static_cast(opt) == true); assert(*opt == T(4)); // size of the initializer list + assert(&v == &*opt); } { T::reset_constructors(); - opt.emplace({-10, 99, 42, 1}, 42); + auto &v = opt.emplace({-10, 99, 42, 1}, 42); + static_assert( std::is_same_v, "" ); assert(T::alive == 1); assert(T::constructed == 1); assert(T::value_constructed == 1); @@ -176,6 +203,7 @@ assert(T::destroyed == 1); assert(static_cast(opt) == true); assert(*opt == T(4)); // size of the initializer list + assert(&v == &*opt); } } @@ -210,8 +238,10 @@ } { optional opt; - opt.emplace(42); + auto &v = opt.emplace(42); + static_assert( std::is_same_v, "" ); assert(*opt == 42); + assert( v == 42); opt.emplace(); assert(*opt == 0); }