mclow.lists created this revision.

Implement the `optional` and `any` part of this issue.

This changes the return type of these functions.


https://reviews.llvm.org/D31956

Files:
  include/any
  include/optional
  test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
  
test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp

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
 // <optional>
 
-// template <class... Args> void optional<T>::emplace(Args&&... args);
+// template <class... Args> T& optional<T>::emplace(Args&&... args);
 
 #include <optional>
 #include <type_traits>
@@ -51,27 +51,35 @@
     using Opt = std::optional<T>;
     {
         Opt opt;
-        opt.emplace();
+        auto & v = opt.emplace();
+        static_assert( std::is_same_v<T&, decltype(v)>, "" );
         assert(static_cast<bool>(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<T&, decltype(v)>, "" );
         assert(static_cast<bool>(opt) == true);
         assert(*opt == T(1));
+        assert(&v == &*opt);
     }
     {
         Opt opt(2);
-        opt.emplace();
+        auto & v = opt.emplace();
+        static_assert( std::is_same_v<T&, decltype(v)>, "" );
         assert(static_cast<bool>(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<T&, decltype(v)>, "" );
         assert(static_cast<bool>(opt) == true);
         assert(*opt == T(1));
+        assert(&v == &*opt);
     }
 }
 
@@ -83,20 +91,26 @@
     using Opt = std::optional<T>;
     {
         Opt opt;
-        opt.emplace(101, 41);
+        auto &v = opt.emplace(101, 41);
+        static_assert( std::is_same_v<T&, decltype(v)>, "" );
         assert(static_cast<bool>(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<T&, decltype(v)>, "" );
         assert(static_cast<bool>(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<T&, decltype(v)>, "" );
         assert(static_cast<bool>(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<T&, decltype(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<bool>(opt) == true);
         assert(*opt == T());
+        assert(&v == &*opt);
     }
     {
         T::reset_constructors();
-        opt.emplace();
+        auto &v = opt.emplace();
+        static_assert( std::is_same_v<T&, decltype(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<bool>(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<T&, decltype(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<bool>(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<T&, decltype(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<bool>(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<T&, decltype(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<bool>(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<T&, decltype(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<bool>(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<T&, decltype(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<bool>(opt) == true);
         assert(*opt == T(4)); // size of the initializer list
+        assert(&v == &*opt);
     }
 }
 
@@ -210,8 +238,10 @@
     }
     {
         optional<const int> opt;
-        opt.emplace(42);
+        auto &v = opt.emplace(42);
+        static_assert( std::is_same_v<const int&, decltype(v)>, "" );
         assert(*opt == 42);
+        assert(   v == 42);
         opt.emplace();
         assert(*opt == 0);
     }
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 @@
 
 // <any>
 
-// template <class T, class ...Args> emplace(Args&&...);
+// template <class T, class ...Args> T& emplace(Args&&...);
 // template <class T, class U, class ...Args>
-// void emplace(initializer_list<U>, Args&&...);
+// T& emplace(initializer_list<U>, Args&&...);
 
 #include <any>
 #include <cassert>
@@ -42,7 +42,9 @@
         any a(std::in_place_type<Tracked>);
         assert(Tracked::count == 1);
 
-        a.emplace<Type>();
+        auto &v = a.emplace<Type>();
+        static_assert( std::is_same_v<Type&, decltype(v)>, "" );
+		assert(&v == std::any_cast<Type>(&a));
 
         assert(Tracked::count == 0);
         assert(Type::count == 1);
@@ -56,7 +58,9 @@
         any a(std::in_place_type<Tracked>);
         assert(Tracked::count == 1);
 
-        a.emplace<Type>(101);
+        auto &v = a.emplace<Type>(101);
+        static_assert( std::is_same_v<Type&, decltype(v)>, "" );
+		assert(&v == std::any_cast<Type>(&a));
 
         assert(Tracked::count == 0);
         assert(Type::count == 1);
@@ -70,7 +74,9 @@
         any a(std::in_place_type<Tracked>);
         assert(Tracked::count == 1);
 
-        a.emplace<Type>(-1, 42, -1);
+        auto &v = a.emplace<Type>(-1, 42, -1);
+        static_assert( std::is_same_v<Type&, decltype(v)>, "" );
+		assert(&v == std::any_cast<Type>(&a));
 
         assert(Tracked::count == 0);
         assert(Type::count == 1);
@@ -89,7 +95,10 @@
     {
         any a(std::in_place_type<Tracked>);
         assert(Tracked::count == 1);
-        a.emplace<Type>();
+        auto &v = a.emplace<Type>();
+        static_assert( std::is_same_v<Type&, decltype(v)>, "" );
+		assert(&v == std::any_cast<Type>(&a));
+
         assert(Tracked::count == 0);
         assertArgsMatch<Type>(a);
     }
@@ -96,7 +105,10 @@
     {
         any a(std::in_place_type<Tracked>);
         assert(Tracked::count == 1);
-        a.emplace<Type>(-1, 42, -1);
+        auto &v = a.emplace<Type>(-1, 42, -1);
+        static_assert( std::is_same_v<Type&, decltype(v)>, "" );
+		assert(&v == std::any_cast<Type>(&a));
+
         assert(Tracked::count == 0);
         assertArgsMatch<Type, int, int, int>(a);
     }
@@ -104,7 +116,10 @@
     {
         any a(std::in_place_type<Tracked>);
         assert(Tracked::count == 1);
-        a.emplace<Type>({-1, 42, -1});
+        auto &v = a.emplace<Type>({-1, 42, -1});
+        static_assert( std::is_same_v<Type&, decltype(v)>, "" );
+		assert(&v == std::any_cast<Type>(&a));
+
         assert(Tracked::count == 0);
         assertArgsMatch<Type, std::initializer_list<int>>(a);
     }
@@ -112,7 +127,10 @@
         int x = 42;
         any a(std::in_place_type<Tracked>);
         assert(Tracked::count == 1);
-        a.emplace<Type>({-1, 42, -1}, x);
+        auto &v = a.emplace<Type>({-1, 42, -1}, x);
+        static_assert( std::is_same_v<Type&, decltype(v)>, "" );
+		assert(&v == std::any_cast<Type>(&a));
+
         assert(Tracked::count == 0);
         assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
     }
Index: include/optional
===================================================================
--- include/optional
+++ include/optional
@@ -108,9 +108,9 @@
     template <class U = T> optional &operator=(U &&);
     template <class U> optional &operator=(const optional<U> &);
     template <class U> optional &operator=(optional<U> &&);
-    template <class... Args> void emplace(Args &&...);
+    template <class... Args> T& emplace(Args &&...);
     template <class U, class... Args>
-      void emplace(initializer_list<U>, Args &&...);
+      T& emplace(initializer_list<U>, 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 <class _Up, class... _Args,
@@ -743,11 +744,12 @@
                       >
              >
     _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: include/any
===================================================================
--- include/any
+++ include/any
@@ -45,6 +45,10 @@
       any& operator=(ValueType&& rhs);
 
     // 6.3.3 any modifiers
+    template <class ValueType, class... Args>
+      decay_t<ValueType>& emplace(Args&&... args);
+    template <class ValueType, class U, class... Args>
+      decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
     void reset() noexcept;
     void swap(any& rhs) noexcept;
 
@@ -73,8 +77,6 @@
   template<class ValueType>
     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 <class _ValueType, class _Up, class ..._Args,
     class _Tp = decay_t<_ValueType>,
@@ -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 <class ..._Args>
     _LIBCPP_INLINE_VISIBILITY
-    static void __create(any & __dest, _Args&&... __args) {
-        ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
+    static _Tp& __create(any & __dest, _Args&&... __args) {
+        _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
         __dest.__h = &_SmallHandler::__handle;
+        return *__ret;
     }
 
   private:
@@ -439,14 +442,15 @@
 
     template <class ..._Args>
     _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 <class _ValueType, class ..._Args, class _Tp, class>
 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 <class _ValueType, class _Up, class ..._Args, class _Tp, class>
 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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to