-//$$CDS-header$$
+/*
+ This file is a part of libcds - Concurrent Data Structures library
+
+ (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+ 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_CONTAINER_DETAILS_MAKE_SKIP_LIST_SET_H
#define CDSLIB_CONTAINER_DETAILS_MAKE_SKIP_LIST_SET_H
//atomic_marked_ptr m_arrTower[] ; // allocated together with node_type in single memory block
template <typename Q>
- node_type( unsigned int nHeight, atomic_marked_ptr * pTower, Q const& v )
- : m_Value(v)
+ node_type( unsigned int nHeight, atomic_marked_ptr * pTower, Q&& v )
+ : m_Value( std::forward<Q>( v ))
{
- if ( nHeight > 1 ) {
- new (pTower) atomic_marked_ptr[ nHeight - 1 ];
- base_class::make_tower( nHeight, pTower );
- }
+ init_tower( nHeight, pTower );
}
template <typename Q, typename... Args>
node_type( unsigned int nHeight, atomic_marked_ptr * pTower, Q&& q, Args&&... args )
: m_Value( std::forward<Q>(q), std::forward<Args>(args)... )
+ {
+ init_tower( nHeight, pTower );
+ }
+
+ node_type() = delete;
+
+ private:
+ void init_tower( unsigned nHeight, atomic_marked_ptr* pTower )
{
if ( nHeight > 1 ) {
- new (pTower) atomic_marked_ptr[ nHeight - 1 ];
+ // TSan: make_tower() issues atomic_thread_fence( release )
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
+ new ( pTower ) atomic_marked_ptr[nHeight - 1];
base_class::make_tower( nHeight, pTower );
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
}
}
-
- private:
- node_type() ; // no default ctor
};
typedef skip_list::details::node_allocator< node_type, traits> node_allocator;