[libcxx] r300123 - Implement part of LWG#2857 - any/optional. Still to do - variant. Reviewed as https://reviews.llvm.org/D31956

Marshall Clow via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 12 15:51:27 PDT 2017


Author: marshall
Date: Wed Apr 12 17:51:27 2017
New Revision: 300123

URL: http://llvm.org/viewvc/llvm-project?rev=300123&view=rev
Log:
Implement part of LWG#2857 - any/optional. Still to do - variant. Reviewed as https://reviews.llvm.org/D31956

Modified:
    libcxx/trunk/include/any
    libcxx/trunk/include/optional
    libcxx/trunk/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp

Modified: libcxx/trunk/include/any
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/any?rev=300123&r1=300122&r2=300123&view=diff
==============================================================================
--- libcxx/trunk/include/any (original)
+++ libcxx/trunk/include/any Wed Apr 12 17:51:27 2017
@@ -45,6 +45,10 @@ namespace std {
       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 @@ namespace std {
   template<class ValueType>
     ValueType* any_cast(any* operand) noexcept;
 
-} // namespace fundamentals_v1
-} // namespace experimental
 } // namespace std
 
 */
@@ -258,7 +260,7 @@ public:
         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 @@ public:
         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 @@ namespace __any_imp
 
     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 @@ namespace __any_imp
 
     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 @@ any & any::operator=(_ValueType && __v)
 
 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

Modified: libcxx/trunk/include/optional
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/optional?rev=300123&r1=300122&r2=300123&view=diff
==============================================================================
--- libcxx/trunk/include/optional (original)
+++ libcxx/trunk/include/optional Wed Apr 12 17:51:27 2017
@@ -87,7 +87,7 @@ namespace std {
     constexpr optional() noexcept;
     constexpr optional(nullopt_t) noexcept;
     optional(const optional &);
-    optional(optional &&) noexcept(see below );
+    optional(optional &&) noexcept(see below);
     template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
     template <class U, class... Args>
       constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
@@ -108,9 +108,9 @@ namespace std {
     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 @@ public:
                       >
              >
     _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 @@ public:
                       >
              >
     _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

Modified: libcxx/trunk/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp?rev=300123&r1=300122&r2=300123&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp Wed Apr 12 17:51:27 2017
@@ -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 @@ void test_emplace_type() {
         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 @@ void test_emplace_type() {
         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 @@ void test_emplace_type() {
         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,14 +95,20 @@ void test_emplace_type_tracked() {
     {
         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);
     }
     {
         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 @@ void test_emplace_type_tracked() {
     {
         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 @@ void test_emplace_type_tracked() {
         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);
     }




More information about the cfe-commits mailing list