From 7ae8e8a4db222e3284b679b2433f45ec892ec7ea Mon Sep 17 00:00:00 2001
From: Botond Ballo <botond.ballo@gmail.com>
Date: Fri, 18 Nov 2011 23:56:07 -0500
Subject: [PATCH] C++11 move constructor/assignment operator for socket_t and context_t

Added a C++11 move constructor and move assignment operator to zmq::socket_t
and zmq::context_t. These functions are only enabled if the compiler supports
C++11 rvalue references. Currently the code can detect rvalue reference
support for the following compilers: GCC, MSVC, clang.

Signed-off-by: Botond Ballo <botond.ballo@gmail.com>
---
 include/zmq.hpp |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/include/zmq.hpp b/include/zmq.hpp
index e147b0e..5ca2091 100644
--- a/include/zmq.hpp
+++ b/include/zmq.hpp
@@ -27,6 +27,19 @@
 #include <cstring>
 #include <exception>
 
+// Detect whether the compiler supports C++11 rvalue references.
+#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
+    #define ZMQ_HAS_RVALUE_REFS
+#endif
+#if (defined(__clang__))
+    #if __has_feature(cxx_rvalue_references)
+        #define ZMQ_HAS_RVALUE_REFS
+    #endif
+#endif
+#if (defined(_MSC_VER) && (_MSC_VER >= 1600))
+    #define ZMQ_HAS_RVALUE_REFS
+#endif
+
 namespace zmq
 {
 
@@ -184,8 +197,22 @@ namespace zmq
                 throw error_t ();
         }
 
+        #ifdef ZMQ_HAS_RVALUE_REFS
+        inline context_t(context_t&& rhs) : ptr(rhs.ptr)
+        {
+            rhs.ptr = NULL;
+        }
+        inline context_t& operator=(context_t&& rhs)
+        {
+            std::swap(ptr, rhs.ptr);
+            return *this;
+        }
+        #endif
+
         inline ~context_t ()
         {
+            if (ptr == NULL)
+                return;
             int rc = zmq_term (ptr);
             assert (rc == 0);
         }
@@ -217,6 +244,18 @@ namespace zmq
                 throw error_t ();
         }
 
+        #ifdef ZMQ_HAS_RVALUE_REFS
+        inline socket_t(socket_t&& rhs) : ptr(rhs.ptr)
+        {
+            rhs.ptr = NULL;
+        }
+        inline socket_t& operator=(socket_t&& rhs)
+        {
+            std::swap(ptr, rhs.ptr);
+            return *this;
+        }
+        #endif
+
         inline ~socket_t ()
         {
             close();
-- 
1.7.0.4

