-//$$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 {
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.
*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
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;
}
{
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:
}
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 );
CDS_CXX11_ATOMIC_END_NAMESPACE
//@endcond
-#endif // #ifndef __CDS_DETAILS_MARKED_PTR_H
+#endif // #ifndef CDSLIB_DETAILS_MARKED_PTR_H