Fixed VC 2017 warning
[libcds.git] / cds / details / marked_ptr.h
index 3645e052fa73beef56f69bcc63d9517e65e7a574..2a53c34cfec2ee153cef87659d730e0e7ca20d26 100644 (file)
@@ -1,9 +1,37 @@
-//$$CDS-header$$
+/*
+    This file is a part of libcds - Concurrent Data Structures library
 
-#ifndef __CDS_DETAILS_MARKED_PTR_H
-#define __CDS_DETAILS_MARKED_PTR_H
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
 
-#include <cds/cxx11_atomic.h>
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSLIB_DETAILS_MARKED_PTR_H
+#define CDSLIB_DETAILS_MARKED_PTR_H
+
+#include <cds/algo/atomic.h>
 
 namespace cds {
     namespace details {
@@ -22,18 +50,18 @@ namespace cds {
         template <typename T, int Bitmask>
         class marked_ptr
         {
-            T *     m_ptr   ;   ///< pointer and its mark bits
+            T *         m_ptr   ;   ///< pointer and its mark bits
 
         public:
             typedef T       value_type      ;       ///< type of value the class points to
             typedef T *     pointer_type    ;       ///< type of pointer
-            static CDS_CONSTEXPR_CONST uintptr_t bitmask = Bitmask  ;   ///< bitfield bitmask
-            static CDS_CONSTEXPR_CONST uintptr_t pointer_bitmask = ~bitmask ; ///< pointer bitmask
+            static CDS_CONSTEXPR const uintptr_t bitmask = Bitmask;   ///< bitfield bitmask
+            static CDS_CONSTEXPR const uintptr_t pointer_bitmask = ~bitmask; ///< pointer bitmask
 
         public:
             /// Constructs null marked pointer. The flag is cleared.
             CDS_CONSTEXPR marked_ptr() CDS_NOEXCEPT
-                : m_ptr( null_ptr<pointer_type>() )
+                : m_ptr( nullptr )
             {}
 
             /// Constructs marked pointer with \p ptr value. The least bit(s) of \p ptr is the flag.
@@ -52,43 +80,36 @@ namespace cds {
                 *this |= nMask;
             }
 
-#   ifdef CDS_CXX11_EXPLICITLY_DEFAULTED_FUNCTION_SUPPORT
             /// Copy constructor
-            marked_ptr( marked_ptr const& src ) CDS_NOEXCEPT_DEFAULTED = default;
+            marked_ptr( marked_ptr const& src ) CDS_NOEXCEPT = default;
             /// Copy-assignment operator
-            marked_ptr& operator =( marked_ptr const& p ) CDS_NOEXCEPT_DEFAULTED = default;
-#       if defined(CDS_MOVE_SEMANTICS_SUPPORT) && !defined(CDS_DISABLE_DEFAULT_MOVE_CTOR)
+            marked_ptr& operator =( marked_ptr const& p ) CDS_NOEXCEPT = default;
+#       if !defined(CDS_DISABLE_DEFAULT_MOVE_CTOR)
             //@cond
-            marked_ptr( marked_ptr&& src ) CDS_NOEXCEPT_DEFAULTED = default;
-            marked_ptr& operator =( marked_ptr&& p ) CDS_NOEXCEPT_DEFAULTED = default;
+            marked_ptr( marked_ptr&& src ) CDS_NOEXCEPT = default;
+            marked_ptr& operator =( marked_ptr&& p ) CDS_NOEXCEPT = default;
             //@endcond
 #       endif
-#   else
-            /// Copy constructor
-            marked_ptr( marked_ptr const& src ) CDS_NOEXCEPT
-                : m_ptr( src.m_ptr )
-            {}
-
-            /// Copy-assignment operator
-            marked_ptr& operator =( marked_ptr const& p ) CDS_NOEXCEPT
-            {
-                m_ptr = p.m_ptr;
-                return *this;
-            }
-#   endif
 
             //TODO: make move ctor
 
         private:
             //@cond
+            union pointer_cast {
+                T *       ptr;
+                uintptr_t n;
+
+                pointer_cast(T * p) : ptr(p) {}
+                pointer_cast(uintptr_t i) : n(i) {}
+            };
             static uintptr_t   to_int( value_type * p ) CDS_NOEXCEPT
             {
-                return reinterpret_cast<uintptr_t>( p );
+                return pointer_cast(p).n;
             }
 
             static value_type * to_ptr( uintptr_t n ) CDS_NOEXCEPT
             {
-                return reinterpret_cast< value_type *>( n );
+                return pointer_cast(n).ptr;
             }
 
             uintptr_t   to_int() const CDS_NOEXCEPT
@@ -141,7 +162,7 @@ namespace cds {
             marked_ptr& operator &=( int nBits ) CDS_NOEXCEPT
             {
                 assert( (nBits & pointer_bitmask) == 0 );
-                m_ptr = to_ptr( to_int() & (pointer_bitmask | nBits) );
+                m_ptr = to_ptr( to_int() & (pointer_bitmask | nBits));
                 return *this;
             }
 
@@ -257,7 +278,7 @@ CDS_CXX11_ATOMIC_BEGIN_NAMESPACE
     {
     private:
         typedef cds::details::marked_ptr<T, Bitmask> marked_ptr;
-        typedef CDS_ATOMIC::atomic<T *>  atomic_impl;
+        typedef atomics::atomic<T *>  atomic_impl;
 
         atomic_impl m_atomic;
     public:
@@ -340,27 +361,28 @@ CDS_CXX11_ATOMIC_BEGIN_NAMESPACE
         }
 
         CDS_CONSTEXPR atomic() CDS_NOEXCEPT
-            : m_atomic( cds::null_ptr<T *>() )
+            : m_atomic( nullptr )
         {}
 
         CDS_CONSTEXPR explicit atomic(marked_ptr val) CDS_NOEXCEPT
-            : m_atomic( val.all() )
+            : m_atomic( val.all())
         {}
         CDS_CONSTEXPR explicit atomic(T * p) CDS_NOEXCEPT
             : m_atomic( p )
         {}
 
-#   ifdef CDS_CXX11_DELETE_DEFINITION_SUPPORT
         atomic(const atomic&) = delete;
         atomic& operator=(const atomic&) = delete;
-        atomic& operator=(const atomic&) volatile = delete;
-#   endif
 
+#if !(CDS_COMPILER == CDS_COMPILER_MSVC && CDS_COMPILER_VERSION <= CDS_COMPILER_MSVC14_1)
+        // MSVC12, MSVC14, MSVC14.1: warning C4522: multiple assignment operators specified
+        atomic& operator=(const atomic&) volatile = delete;
         marked_ptr operator=(marked_ptr val) volatile CDS_NOEXCEPT
         {
             store( val );
             return val;
         }
+#endif
         marked_ptr operator=(marked_ptr val) CDS_NOEXCEPT
         {
             store( val );
@@ -371,4 +393,4 @@ CDS_CXX11_ATOMIC_BEGIN_NAMESPACE
 CDS_CXX11_ATOMIC_END_NAMESPACE
 //@endcond
 
-#endif  // #ifndef __CDS_DETAILS_MARKED_PTR_H
+#endif  // #ifndef CDSLIB_DETAILS_MARKED_PTR_H