整理
This commit is contained in:
62
include/boost/smart_ptr/detail/atomic_count.hpp
Normal file
62
include/boost/smart_ptr/detail/atomic_count.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count.hpp - thread/SMP safe reference counter
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2013 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// typedef <implementation-defined> boost::detail::atomic_count;
|
||||
//
|
||||
// atomic_count a(n);
|
||||
//
|
||||
// (n is convertible to long)
|
||||
//
|
||||
// Effects: Constructs an atomic_count with an initial value of n
|
||||
//
|
||||
// a;
|
||||
//
|
||||
// Returns: (long) the current value of a
|
||||
// Memory Ordering: acquire
|
||||
//
|
||||
// ++a;
|
||||
//
|
||||
// Effects: Atomically increments the value of a
|
||||
// Returns: (long) the new value of a
|
||||
// Memory Ordering: acquire/release
|
||||
//
|
||||
// --a;
|
||||
//
|
||||
// Effects: Atomically decrements the value of a
|
||||
// Returns: (long) the new value of a
|
||||
// Memory Ordering: acquire/release
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/deprecated_macros.hpp>
|
||||
|
||||
#if defined( BOOST_AC_DISABLE_THREADS )
|
||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
|
||||
|
||||
#elif defined( BOOST_AC_USE_STD_ATOMIC )
|
||||
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_DISABLE_THREADS )
|
||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
|
||||
|
||||
#else
|
||||
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
66
include/boost/smart_ptr/detail/atomic_count_nt.hpp
Normal file
66
include/boost/smart_ptr/detail/atomic_count_nt.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_nt.hpp
|
||||
//
|
||||
// Trivial atomic_count for the single-threaded case
|
||||
//
|
||||
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
|
||||
//
|
||||
// Copyright 2013 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("Using single-threaded, non-atomic atomic_count")
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ): value_( v )
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return ++value_;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return --value_;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
|
||||
67
include/boost/smart_ptr/detail/atomic_count_std_atomic.hpp
Normal file
67
include/boost/smart_ptr/detail/atomic_count_std_atomic.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_std_atomic.hpp
|
||||
//
|
||||
// atomic_count for std::atomic
|
||||
//
|
||||
// Copyright 2013 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("Using std::atomic atomic_count")
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ): value_( static_cast< std::int_least32_t >( v ) )
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return value_.fetch_add( 1, std::memory_order_acq_rel ) + 1;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return value_.fetch_sub( 1, std::memory_order_acq_rel ) - 1;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return value_.load( std::memory_order_acquire );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
std::atomic_int_least32_t value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
|
||||
52
include/boost/smart_ptr/detail/deprecated_macros.hpp
Normal file
52
include/boost/smart_ptr/detail/deprecated_macros.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_DEPRECATED_MACROS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_DEPRECATED_MACROS_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_ENABLE_DEBUG_HOOKS has been deprecated in 1.87 and support for it was removed in 1.90.")
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_STD_ALLOCATOR has been deprecated in 1.87 and support for it was removed in 1.90.")
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_QUICK_ALLOCATOR has been deprecated in 1.87 and support for it was removed in 1.90.")
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_AC_USE_SPINLOCK)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_SPINLOCK has been deprecated in 1.87 and support for it was removed in 1.90.")
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_AC_USE_PTHREADS)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_PTHREADS has been deprecated in 1.87 and support for it was removed in 1.90.")
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_SPINLOCK)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_SPINLOCK has been deprecated in 1.87 and support for it was removed in 1.90.")
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_PTHREADS)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_PTHREADS has been deprecated in 1.87 and support for it was removed in 1.90.")
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_DEPRECATED_MACROS_HPP_INCLUDED
|
||||
31
include/boost/smart_ptr/detail/lightweight_mutex.hpp
Normal file
31
include/boost/smart_ptr/detail/lightweight_mutex.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lightweight_mutex.hpp - lightweight mutex
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// typedef <unspecified> boost::detail::lightweight_mutex;
|
||||
//
|
||||
// boost::detail::lightweight_mutex is a header-only implementation of
|
||||
// a subset of the Mutex concept requirements:
|
||||
//
|
||||
// http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex
|
||||
//
|
||||
// It's obsoleted by std::mutex.
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/lwm_std_mutex.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
56
include/boost/smart_ptr/detail/lightweight_thread.hpp
Normal file
56
include/boost/smart_ptr/detail/lightweight_thread.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/detail/lightweight_thread.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2008, 2018 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
//
|
||||
// typedef /*...*/ lw_thread_t; // as pthread_t
|
||||
// template<class F> int lw_thread_create( lw_thread_t & th, F f );
|
||||
// void lw_thread_join( lw_thread_t th );
|
||||
|
||||
#include <thread>
|
||||
#include <exception>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
using lw_thread_t = std::thread*;
|
||||
|
||||
template<class F> int lw_thread_create( lw_thread_t& th, F f )
|
||||
{
|
||||
try
|
||||
{
|
||||
th = new std::thread( f );
|
||||
return 0;
|
||||
}
|
||||
catch( std::exception const& )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void lw_thread_join( lw_thread_t th )
|
||||
{
|
||||
th->join();
|
||||
delete th;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
||||
144
include/boost/smart_ptr/detail/local_counted_base.hpp
Normal file
144
include/boost/smart_ptr/detail/local_counted_base.hpp
Normal file
@@ -0,0 +1,144 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/local_counted_base.hpp
|
||||
//
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/ for documentation.
|
||||
|
||||
#include <boost/smart_ptr/detail/shared_count.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE local_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
local_counted_base & operator= ( local_counted_base const & );
|
||||
|
||||
private:
|
||||
|
||||
// not 'int' or 'unsigned' to avoid aliasing and enable optimizations
|
||||
enum count_type { min_ = 0, initial_ = 1, max_ = 2147483647 };
|
||||
|
||||
count_type local_use_count_;
|
||||
|
||||
public:
|
||||
|
||||
constexpr local_counted_base() noexcept: local_use_count_( initial_ )
|
||||
{
|
||||
}
|
||||
|
||||
constexpr local_counted_base( local_counted_base const & ) noexcept: local_use_count_( initial_ )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~local_counted_base() /*noexcept*/
|
||||
{
|
||||
}
|
||||
|
||||
virtual void local_cb_destroy() noexcept = 0;
|
||||
|
||||
virtual boost::detail::shared_count local_cb_get_shared_count() const noexcept = 0;
|
||||
|
||||
void add_ref() noexcept
|
||||
{
|
||||
#if !defined(__NVCC__)
|
||||
#if defined( __has_builtin )
|
||||
# if __has_builtin( __builtin_assume )
|
||||
|
||||
__builtin_assume( local_use_count_ >= 1 );
|
||||
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
local_use_count_ = static_cast<count_type>( local_use_count_ + 1 );
|
||||
}
|
||||
|
||||
void release() noexcept
|
||||
{
|
||||
local_use_count_ = static_cast<count_type>( local_use_count_ - 1 );
|
||||
|
||||
if( local_use_count_ == 0 )
|
||||
{
|
||||
local_cb_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long local_use_count() const noexcept
|
||||
{
|
||||
return local_use_count_;
|
||||
}
|
||||
};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE local_counted_impl: public local_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
local_counted_impl( local_counted_impl const & );
|
||||
|
||||
private:
|
||||
|
||||
shared_count pn_;
|
||||
|
||||
public:
|
||||
|
||||
explicit local_counted_impl( shared_count const& pn ) noexcept: pn_( pn )
|
||||
{
|
||||
}
|
||||
|
||||
explicit local_counted_impl( shared_count && pn ) noexcept: pn_( std::move(pn) )
|
||||
{
|
||||
}
|
||||
|
||||
void local_cb_destroy() noexcept override
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
boost::detail::shared_count local_cb_get_shared_count() const noexcept override
|
||||
{
|
||||
return pn_;
|
||||
}
|
||||
};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE local_counted_impl_em: public local_counted_base
|
||||
{
|
||||
public:
|
||||
|
||||
shared_count pn_;
|
||||
|
||||
void local_cb_destroy() noexcept override
|
||||
{
|
||||
shared_count().swap( pn_ );
|
||||
}
|
||||
|
||||
boost::detail::shared_count local_cb_get_shared_count() const noexcept override
|
||||
{
|
||||
return pn_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
|
||||
83
include/boost/smart_ptr/detail/local_sp_deleter.hpp
Normal file
83
include/boost/smart_ptr/detail/local_sp_deleter.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/local_sp_deleter.hpp
|
||||
//
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/ for documentation.
|
||||
|
||||
#include <boost/smart_ptr/detail/local_counted_base.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class D> class local_sp_deleter: public local_counted_impl_em
|
||||
{
|
||||
private:
|
||||
|
||||
D d_;
|
||||
|
||||
public:
|
||||
|
||||
local_sp_deleter(): d_()
|
||||
{
|
||||
}
|
||||
|
||||
explicit local_sp_deleter( D const& d ) noexcept: d_( d )
|
||||
{
|
||||
}
|
||||
|
||||
explicit local_sp_deleter( D&& d ) noexcept: d_( std::move(d) )
|
||||
{
|
||||
}
|
||||
|
||||
D& deleter() noexcept
|
||||
{
|
||||
return d_;
|
||||
}
|
||||
|
||||
template<class Y> void operator()( Y* p ) noexcept
|
||||
{
|
||||
d_( p );
|
||||
}
|
||||
|
||||
void operator()( std::nullptr_t p ) noexcept
|
||||
{
|
||||
d_( p );
|
||||
}
|
||||
};
|
||||
|
||||
template<> class local_sp_deleter<void>
|
||||
{
|
||||
};
|
||||
|
||||
template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) noexcept
|
||||
{
|
||||
return &p->deleter();
|
||||
}
|
||||
|
||||
inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED
|
||||
62
include/boost/smart_ptr/detail/lwm_std_mutex.hpp
Normal file
62
include/boost/smart_ptr/detail/lwm_std_mutex.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_STD_MUTEX_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LWM_STD_MUTEX_HPP_INCLUDED
|
||||
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <mutex>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
std::mutex m_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
std::mutex & m_;
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
scoped_lock( lightweight_mutex & m ): m_( m.m_ )
|
||||
{
|
||||
m_.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
m_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_STD_MUTEX_HPP_INCLUDED
|
||||
63
include/boost/smart_ptr/detail/quick_allocator.hpp
Normal file
63
include/boost/smart_ptr/detail/quick_allocator.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
|
||||
// Copyright 2003 David Abrahams
|
||||
// Copyright 2003, 2025 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
#include <memory>
|
||||
#include <cstddef>
|
||||
|
||||
BOOST_HEADER_DEPRECATED("std::allocator or std::pmr::synchronized_pool_resource")
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T> struct quick_allocator
|
||||
{
|
||||
static void* alloc()
|
||||
{
|
||||
return std::allocator<T>().allocate( 1 );
|
||||
}
|
||||
|
||||
static void* alloc( std::size_t n )
|
||||
{
|
||||
if( n != sizeof(T) ) // class-specific delete called for a derived object
|
||||
{
|
||||
return ::operator new( n );
|
||||
}
|
||||
else
|
||||
{
|
||||
return alloc();
|
||||
}
|
||||
}
|
||||
|
||||
static void dealloc( void* p )
|
||||
{
|
||||
if( p != 0 ) // 18.4.1.1/13
|
||||
{
|
||||
std::allocator<T>().deallocate( static_cast<T*>( p ), 1 );
|
||||
}
|
||||
}
|
||||
|
||||
static void dealloc( void* p, std::size_t n )
|
||||
{
|
||||
if( n != sizeof(T) ) // class-specific delete called for a derived object
|
||||
{
|
||||
::operator delete( p );
|
||||
}
|
||||
else
|
||||
{
|
||||
dealloc( p );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
581
include/boost/smart_ptr/detail/shared_count.hpp
Normal file
581
include/boost/smart_ptr/detail/shared_count.hpp
Normal file
@@ -0,0 +1,581 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/shared_count.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/bad_weak_ptr.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
|
||||
#include <boost/smart_ptr/detail/deprecated_macros.hpp>
|
||||
#include <boost/core/checked_delete.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <cstdint>
|
||||
#include <memory> // std::auto_ptr
|
||||
#include <functional> // std::less
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
# include <new> // std::bad_alloc
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace movelib
|
||||
{
|
||||
|
||||
template< class T, class D > class unique_ptr;
|
||||
|
||||
} // namespace movelib
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct sp_nothrow_tag {};
|
||||
|
||||
template< class D > struct sp_inplace_tag
|
||||
{
|
||||
};
|
||||
|
||||
template< class T > class sp_reference_wrapper
|
||||
{
|
||||
public:
|
||||
|
||||
explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Y > void operator()( Y * p ) const
|
||||
{
|
||||
(*t_)( p );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * t_;
|
||||
};
|
||||
|
||||
template< class D > struct sp_convert_reference
|
||||
{
|
||||
typedef D type;
|
||||
};
|
||||
|
||||
template< class D > struct sp_convert_reference< D& >
|
||||
{
|
||||
typedef sp_reference_wrapper< D > type;
|
||||
};
|
||||
|
||||
template<class T> std::size_t sp_hash_pointer( T* p ) noexcept
|
||||
{
|
||||
std::uintptr_t v = reinterpret_cast<std::uintptr_t>( p );
|
||||
|
||||
// match boost::hash<T*>
|
||||
return static_cast<std::size_t>( v + ( v >> 3 ) );
|
||||
}
|
||||
|
||||
class weak_count;
|
||||
|
||||
class shared_count
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base * pi_;
|
||||
|
||||
friend class weak_count;
|
||||
|
||||
public:
|
||||
|
||||
constexpr shared_count() noexcept: pi_(0)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr explicit shared_count( sp_counted_base * pi ) noexcept: pi_( pi )
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y> explicit shared_count( Y * p ): pi_( 0 )
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_impl_p<Y>( p );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::checked_delete( p );
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_impl_p<Y>( p );
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::checked_delete( p );
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class P, class D> shared_count( P p, D d ): pi_(0)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_impl_pd<P, D>(p, d);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
d(p); // delete p
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_impl_pd<P, D>(p, d);
|
||||
|
||||
if(pi_ == 0)
|
||||
{
|
||||
d(p); // delete p
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_impl_pd< P, D >( p );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
D::operator_fn( p ); // delete p
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_impl_pd< P, D >( p );
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
D::operator_fn( p ); // delete p
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif // #ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
|
||||
{
|
||||
typedef sp_counted_impl_pda<P, D, A> impl_type;
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
|
||||
|
||||
A2 a2( a );
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = a2.allocate( 1 );
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
d( p );
|
||||
|
||||
if( pi_ != 0 )
|
||||
{
|
||||
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = a2.allocate( 1 );
|
||||
|
||||
if( pi_ != 0 )
|
||||
{
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
||||
}
|
||||
else
|
||||
{
|
||||
d( p );
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
|
||||
{
|
||||
typedef sp_counted_impl_pda< P, D, A > impl_type;
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
|
||||
|
||||
A2 a2( a );
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = a2.allocate( 1 );
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
D::operator_fn( p );
|
||||
|
||||
if( pi_ != 0 )
|
||||
{
|
||||
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = a2.allocate( 1 );
|
||||
|
||||
if( pi_ != 0 )
|
||||
{
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
||||
}
|
||||
else
|
||||
{
|
||||
D::operator_fn( p );
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif // #ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
// auto_ptr<Y> is special cased to provide the strong guarantee
|
||||
|
||||
template<class Y>
|
||||
explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
|
||||
{
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
r.release();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y, class D>
|
||||
explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
|
||||
{
|
||||
typedef typename sp_convert_reference<D>::type D2;
|
||||
|
||||
D2 d2( static_cast<D&&>( r.get_deleter() ) );
|
||||
pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
r.release();
|
||||
}
|
||||
|
||||
template<class Y, class D>
|
||||
explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 )
|
||||
{
|
||||
typedef typename sp_convert_reference<D>::type D2;
|
||||
|
||||
D2 d2( r.get_deleter() );
|
||||
pi_ = new sp_counted_impl_pd< typename boost::movelib::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
r.release();
|
||||
}
|
||||
|
||||
~shared_count() /*noexcept*/
|
||||
{
|
||||
if( pi_ != 0 ) pi_->release();
|
||||
}
|
||||
|
||||
shared_count(shared_count const & r) noexcept: pi_(r.pi_)
|
||||
{
|
||||
if( pi_ != 0 ) pi_->add_ref_copy();
|
||||
}
|
||||
|
||||
shared_count(shared_count && r) noexcept: pi_(r.pi_)
|
||||
{
|
||||
r.pi_ = 0;
|
||||
}
|
||||
|
||||
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
|
||||
shared_count( weak_count const & r, sp_nothrow_tag ) noexcept; // constructs an empty *this when r.use_count() == 0
|
||||
|
||||
shared_count & operator= (shared_count const & r) noexcept
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if( tmp != 0 ) tmp->add_ref_copy();
|
||||
if( pi_ != 0 ) pi_->release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(shared_count & r) noexcept
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
r.pi_ = pi_;
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
long use_count() const noexcept
|
||||
{
|
||||
return pi_ != 0? pi_->use_count(): 0;
|
||||
}
|
||||
|
||||
bool unique() const noexcept
|
||||
{
|
||||
return use_count() == 1;
|
||||
}
|
||||
|
||||
bool empty() const noexcept
|
||||
{
|
||||
return pi_ == 0;
|
||||
}
|
||||
|
||||
bool operator==( shared_count const & r ) const noexcept
|
||||
{
|
||||
return pi_ == r.pi_;
|
||||
}
|
||||
|
||||
bool operator==( weak_count const & r ) const noexcept;
|
||||
|
||||
bool operator<( shared_count const & r ) const noexcept
|
||||
{
|
||||
return std::less<sp_counted_base *>()( pi_, r.pi_ );
|
||||
}
|
||||
|
||||
bool operator<( weak_count const & r ) const noexcept;
|
||||
|
||||
void * get_deleter( sp_typeinfo_ const & ti ) const noexcept
|
||||
{
|
||||
return pi_? pi_->get_deleter( ti ): 0;
|
||||
}
|
||||
|
||||
void * get_local_deleter( sp_typeinfo_ const & ti ) const noexcept
|
||||
{
|
||||
return pi_? pi_->get_local_deleter( ti ): 0;
|
||||
}
|
||||
|
||||
void * get_untyped_deleter() const noexcept
|
||||
{
|
||||
return pi_? pi_->get_untyped_deleter(): 0;
|
||||
}
|
||||
|
||||
std::size_t hash_value() const noexcept
|
||||
{
|
||||
return sp_hash_pointer( pi_ );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class weak_count
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base * pi_;
|
||||
|
||||
friend class shared_count;
|
||||
|
||||
public:
|
||||
|
||||
constexpr weak_count() noexcept: pi_(0)
|
||||
{
|
||||
}
|
||||
|
||||
weak_count(shared_count const & r) noexcept: pi_(r.pi_)
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_add_ref();
|
||||
}
|
||||
|
||||
weak_count(weak_count const & r) noexcept: pi_(r.pi_)
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_add_ref();
|
||||
}
|
||||
|
||||
// Move support
|
||||
|
||||
weak_count(weak_count && r) noexcept: pi_(r.pi_)
|
||||
{
|
||||
r.pi_ = 0;
|
||||
}
|
||||
|
||||
~weak_count() /*noexcept*/
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
}
|
||||
|
||||
weak_count & operator= (shared_count const & r) noexcept
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
weak_count & operator= (weak_count const & r) noexcept
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(weak_count & r) noexcept
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
r.pi_ = pi_;
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
long use_count() const noexcept
|
||||
{
|
||||
return pi_ != 0? pi_->use_count(): 0;
|
||||
}
|
||||
|
||||
bool empty() const noexcept
|
||||
{
|
||||
return pi_ == 0;
|
||||
}
|
||||
|
||||
bool operator==( weak_count const & r ) const noexcept
|
||||
{
|
||||
return pi_ == r.pi_;
|
||||
}
|
||||
|
||||
bool operator==( shared_count const & r ) const noexcept
|
||||
{
|
||||
return pi_ == r.pi_;
|
||||
}
|
||||
|
||||
bool operator<( weak_count const & r ) const noexcept
|
||||
{
|
||||
return std::less<sp_counted_base *>()( pi_, r.pi_ );
|
||||
}
|
||||
|
||||
bool operator<( shared_count const & r ) const noexcept
|
||||
{
|
||||
return std::less<sp_counted_base *>()( pi_, r.pi_ );
|
||||
}
|
||||
|
||||
std::size_t hash_value() const noexcept
|
||||
{
|
||||
return sp_hash_pointer( pi_ );
|
||||
}
|
||||
};
|
||||
|
||||
inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
|
||||
{
|
||||
if( pi_ == 0 || !pi_->add_ref_lock() )
|
||||
{
|
||||
boost::throw_exception( boost::bad_weak_ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) noexcept: pi_( r.pi_ )
|
||||
{
|
||||
if( pi_ != 0 && !pi_->add_ref_lock() )
|
||||
{
|
||||
pi_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool shared_count::operator==( weak_count const & r ) const noexcept
|
||||
{
|
||||
return pi_ == r.pi_;
|
||||
}
|
||||
|
||||
inline bool shared_count::operator<( weak_count const & r ) const noexcept
|
||||
{
|
||||
return std::less<sp_counted_base *>()( pi_, r.pi_ );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||
76
include/boost/smart_ptr/detail/sp_convertible.hpp
Normal file
76
include/boost/smart_ptr/detail/sp_convertible.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_convertible.hpp
|
||||
//
|
||||
// Copyright 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< class Y, class T > struct sp_convertible
|
||||
{
|
||||
typedef char (&yes) [1];
|
||||
typedef char (&no) [2];
|
||||
|
||||
static yes f( T* );
|
||||
static no f( ... );
|
||||
|
||||
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
|
||||
};
|
||||
|
||||
template< class Y, class T > struct sp_convertible< Y, T[] >
|
||||
{
|
||||
enum _vt { value = false };
|
||||
};
|
||||
|
||||
template< class Y, class T > struct sp_convertible< Y[], T[] >
|
||||
{
|
||||
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
|
||||
};
|
||||
|
||||
template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
|
||||
{
|
||||
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
|
||||
};
|
||||
|
||||
struct sp_empty
|
||||
{
|
||||
};
|
||||
|
||||
template< bool > struct sp_enable_if_convertible_impl;
|
||||
|
||||
template<> struct sp_enable_if_convertible_impl<true>
|
||||
{
|
||||
typedef sp_empty type;
|
||||
};
|
||||
|
||||
template<> struct sp_enable_if_convertible_impl<false>
|
||||
{
|
||||
};
|
||||
|
||||
template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||
30
include/boost/smart_ptr/detail/sp_counted_base.hpp
Normal file
30
include/boost/smart_ptr/detail/sp_counted_base.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base.hpp
|
||||
//
|
||||
// Copyright 2005-2013 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/deprecated_macros.hpp>
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_THREADS )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
#else
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
118
include/boost/smart_ptr/detail/sp_counted_base_nt.hpp
Normal file
118
include/boost/smart_ptr/detail/sp_counted_base_nt.hpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_nt.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("Using single-threaded, non-atomic sp_counted_base")
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
std::int_least32_t use_count_; // #shared
|
||||
std::int_least32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base() noexcept: use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() /*noexcept*/
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() noexcept = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() noexcept // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo_ const & ti ) noexcept = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept = 0;
|
||||
virtual void * get_untyped_deleter() noexcept = 0;
|
||||
|
||||
void add_ref_copy() noexcept
|
||||
{
|
||||
++use_count_;
|
||||
}
|
||||
|
||||
bool add_ref_lock() noexcept // true on success
|
||||
{
|
||||
if( use_count_ == 0 ) return false;
|
||||
++use_count_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void release() noexcept
|
||||
{
|
||||
if( --use_count_ == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() noexcept
|
||||
{
|
||||
++weak_count_;
|
||||
}
|
||||
|
||||
void weak_release() noexcept
|
||||
{
|
||||
if( --weak_count_ == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const noexcept
|
||||
{
|
||||
return use_count_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
||||
146
include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
Normal file
146
include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_std_atomic.hpp - C++11 std::atomic
|
||||
//
|
||||
// Copyright (c) 2007, 2013 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("Using std::atomic sp_counted_base")
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( std::atomic_int_least32_t * pw ) noexcept
|
||||
{
|
||||
pw->fetch_add( 1, std::memory_order_relaxed );
|
||||
}
|
||||
|
||||
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) noexcept
|
||||
{
|
||||
return pw->fetch_sub( 1, std::memory_order_acq_rel );
|
||||
}
|
||||
|
||||
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) noexcept
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
std::int_least32_t r = pw->load( std::memory_order_relaxed );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
std::atomic_int_least32_t use_count_; // #shared
|
||||
std::atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base() noexcept: use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() /*noexcept*/
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() noexcept = 0;
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() noexcept
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo_ const & ti ) noexcept = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept = 0;
|
||||
virtual void * get_untyped_deleter() noexcept = 0;
|
||||
|
||||
void add_ref_copy() noexcept
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() noexcept // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() noexcept
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() noexcept
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() noexcept
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const noexcept
|
||||
{
|
||||
return use_count_.load( std::memory_order_acquire );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
|
||||
193
include/boost/smart_ptr/detail/sp_counted_impl.hpp
Normal file
193
include/boost/smart_ptr/detail/sp_counted_impl.hpp
Normal file
@@ -0,0 +1,193 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_impl.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
|
||||
#include <boost/smart_ptr/detail/deprecated_macros.hpp>
|
||||
#include <boost/core/checked_delete.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <memory> // std::allocator, std::allocator_traits
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// get_local_deleter
|
||||
|
||||
template<class D> class local_sp_deleter;
|
||||
|
||||
template<class D> D * get_local_deleter( D * /*p*/ ) noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) noexcept;
|
||||
|
||||
//
|
||||
|
||||
template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
X * px_;
|
||||
|
||||
sp_counted_impl_p( sp_counted_impl_p const & );
|
||||
sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
|
||||
|
||||
typedef sp_counted_impl_p<X> this_type;
|
||||
|
||||
public:
|
||||
|
||||
explicit sp_counted_impl_p( X * px ): px_( px )
|
||||
{
|
||||
}
|
||||
|
||||
void dispose() noexcept override
|
||||
{
|
||||
boost::checked_delete( px_ );
|
||||
}
|
||||
|
||||
void * get_deleter( sp_typeinfo_ const & ) noexcept override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void * get_local_deleter( sp_typeinfo_ const & ) noexcept override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void * get_untyped_deleter() noexcept override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
P ptr; // copy constructor must not throw
|
||||
D del; // copy/move constructor must not throw
|
||||
|
||||
sp_counted_impl_pd( sp_counted_impl_pd const & );
|
||||
sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
|
||||
|
||||
typedef sp_counted_impl_pd<P, D> this_type;
|
||||
|
||||
public:
|
||||
|
||||
// pre: d(p) must not throw
|
||||
|
||||
sp_counted_impl_pd( P p, D & d ): ptr( p ), del( static_cast< D&& >( d ) )
|
||||
{
|
||||
}
|
||||
|
||||
sp_counted_impl_pd( P p ): ptr( p ), del()
|
||||
{
|
||||
}
|
||||
|
||||
void dispose() noexcept override
|
||||
{
|
||||
del( ptr );
|
||||
}
|
||||
|
||||
void * get_deleter( sp_typeinfo_ const & ti ) noexcept override
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0;
|
||||
}
|
||||
|
||||
void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
|
||||
}
|
||||
|
||||
void * get_untyped_deleter() noexcept override
|
||||
{
|
||||
return &reinterpret_cast<char&>( del );
|
||||
}
|
||||
};
|
||||
|
||||
template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
P p_; // copy constructor must not throw
|
||||
D d_; // copy/move constructor must not throw
|
||||
A a_; // copy constructor must not throw
|
||||
|
||||
sp_counted_impl_pda( sp_counted_impl_pda const & );
|
||||
sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
|
||||
|
||||
typedef sp_counted_impl_pda<P, D, A> this_type;
|
||||
|
||||
public:
|
||||
|
||||
// pre: d( p ) must not throw
|
||||
|
||||
sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( static_cast< D&& >( d ) ), a_( a )
|
||||
{
|
||||
}
|
||||
|
||||
sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
|
||||
{
|
||||
}
|
||||
|
||||
void dispose() noexcept override
|
||||
{
|
||||
d_( p_ );
|
||||
}
|
||||
|
||||
void destroy() noexcept override
|
||||
{
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
|
||||
|
||||
A2 a2( a_ );
|
||||
|
||||
this->~this_type();
|
||||
|
||||
a2.deallocate( this, 1 );
|
||||
}
|
||||
|
||||
void * get_deleter( sp_typeinfo_ const & ti ) noexcept override
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0;
|
||||
}
|
||||
|
||||
void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
|
||||
}
|
||||
|
||||
void * get_untyped_deleter() noexcept override
|
||||
{
|
||||
return &reinterpret_cast<char&>( d_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
37
include/boost/smart_ptr/detail/sp_cxx20_constexpr.hpp
Normal file
37
include/boost/smart_ptr/detail/sp_cxx20_constexpr.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_noexcept.hpp
|
||||
//
|
||||
// Copyright 2025 Mathias Stearn
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
// This macro is used to mark functions as constexpr if the compiler supports
|
||||
// constexpr destructors. Since you can't have a constexpr smart pointer object,
|
||||
// everything except null constructors are guided behind this macro. Because
|
||||
// this also guards a use of dynamic_cast, we need to check for its availability
|
||||
// as well. It isn't worth splitting out since all known compilers that support
|
||||
// constexpr dynamic_cast also support constexpr destructors.
|
||||
//
|
||||
// WARNING: This does not check for changing active member of a union in
|
||||
// constant expressions which is allowed in C++20. If that is needed, we
|
||||
// need to raise the checked version to 202002L.
|
||||
#if defined(__cpp_constexpr_dynamic_alloc) && __cpp_constexpr_dynamic_alloc >= 201907L \
|
||||
&& defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
|
||||
#define BOOST_SP_CXX20_CONSTEXPR constexpr
|
||||
#else
|
||||
#define BOOST_SP_CXX20_CONSTEXPR
|
||||
#define BOOST_SP_NO_CXX20_CONSTEXPR
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED
|
||||
40
include/boost/smart_ptr/detail/sp_disable_deprecated.hpp
Normal file
40
include/boost/smart_ptr/detail/sp_disable_deprecated.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/smart_ptr/detail/sp_disable_deprecated.hpp
|
||||
//
|
||||
// Copyright 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( __GNUC__ ) && ( defined( __GXX_EXPERIMENTAL_CXX0X__ ) || ( __cplusplus >= 201103L ) )
|
||||
|
||||
# if defined( BOOST_GCC )
|
||||
|
||||
# if BOOST_GCC >= 40600
|
||||
# define BOOST_SP_DISABLE_DEPRECATED
|
||||
# endif
|
||||
|
||||
# elif defined( __clang__ ) && defined( __has_warning )
|
||||
|
||||
# if __has_warning( "-Wdeprecated-declarations" )
|
||||
# define BOOST_SP_DISABLE_DEPRECATED
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
|
||||
39
include/boost/smart_ptr/detail/sp_noexcept.hpp
Normal file
39
include/boost/smart_ptr/detail/sp_noexcept.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_noexcept.hpp
|
||||
//
|
||||
// Copyright 2016, 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
// BOOST_SP_NOEXCEPT (obsolete, only retained for compatibility)
|
||||
|
||||
#define BOOST_SP_NOEXCEPT noexcept
|
||||
|
||||
// BOOST_SP_NOEXCEPT_WITH_ASSERT (noexcept, unless a user assertion handler is present)
|
||||
|
||||
#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) )
|
||||
|
||||
# define BOOST_SP_NOEXCEPT_WITH_ASSERT noexcept
|
||||
|
||||
#elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) )
|
||||
|
||||
# define BOOST_SP_NOEXCEPT_WITH_ASSERT
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_SP_NOEXCEPT_WITH_ASSERT noexcept
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED
|
||||
23
include/boost/smart_ptr/detail/sp_thread_pause.hpp
Normal file
23
include/boost/smart_ptr/detail/sp_thread_pause.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/yield_primitives.hpp>
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
|
||||
BOOST_HEADER_DEPRECATED( "<boost/core/yield_primitives.hpp>" )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
using boost::core::sp_thread_pause;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED
|
||||
23
include/boost/smart_ptr/detail/sp_thread_sleep.hpp
Normal file
23
include/boost/smart_ptr/detail/sp_thread_sleep.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/yield_primitives.hpp>
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
|
||||
BOOST_HEADER_DEPRECATED( "<boost/core/yield_primitives.hpp>" )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
using boost::core::sp_thread_sleep;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED
|
||||
23
include/boost/smart_ptr/detail/sp_thread_yield.hpp
Normal file
23
include/boost/smart_ptr/detail/sp_thread_yield.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/yield_primitives.hpp>
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
|
||||
BOOST_HEADER_DEPRECATED( "<boost/core/yield_primitives.hpp>" )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
using boost::core::sp_thread_yield;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED
|
||||
55
include/boost/smart_ptr/detail/sp_type_traits.hpp
Normal file
55
include/boost/smart_ptr/detail/sp_type_traits.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_TYPE_TRAITS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_TYPE_TRAITS_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// std::is_bounded_array (C++20)
|
||||
|
||||
template<class T> struct sp_is_bounded_array: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, std::size_t N> struct sp_is_bounded_array< T[N] >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
// std::is_unbounded_array (C++20)
|
||||
|
||||
template<class T> struct sp_is_unbounded_array: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct sp_is_unbounded_array< T[] >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
// std::type_identity (C++20)
|
||||
|
||||
template<class T> struct sp_type_identity
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// boost::type_with_alignment
|
||||
|
||||
template<std::size_t A> struct sp_type_with_alignment
|
||||
{
|
||||
struct alignas(A) type
|
||||
{
|
||||
unsigned char padding[ A ];
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_TYPE_TRAITS_HPP_INCLUDED
|
||||
58
include/boost/smart_ptr/detail/sp_typeinfo_.hpp
Normal file
58
include/boost/smart_ptr/detail/sp_typeinfo_.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// smart_ptr/detail/sp_typeinfo_.hpp
|
||||
//
|
||||
// Copyright 2007, 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_NO_TYPEID ) || defined( BOOST_NO_STD_TYPEINFO )
|
||||
|
||||
#include <boost/core/typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef boost::core::typeinfo sp_typeinfo_;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_SP_TYPEID_(T) BOOST_CORE_TYPEID(T)
|
||||
|
||||
#else // defined( BOOST_NO_TYPEID ) || defined( BOOST_NO_STD_TYPEINFO )
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef std::type_info sp_typeinfo_;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_SP_TYPEID_(T) typeid(T)
|
||||
|
||||
#endif // defined( BOOST_NO_TYPEID ) || defined( BOOST_NO_STD_TYPEINFO )
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||
44
include/boost/smart_ptr/detail/spinlock.hpp
Normal file
44
include/boost/smart_ptr/detail/spinlock.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/spinlock.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// struct spinlock
|
||||
// {
|
||||
// void lock();
|
||||
// bool try_lock();
|
||||
// void unlock();
|
||||
//
|
||||
// class scoped_lock;
|
||||
// };
|
||||
//
|
||||
// #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/deprecated_macros.hpp>
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
// Old Clang versions have trouble with ATOMIC_FLAG_INIT
|
||||
# include <boost/smart_ptr/detail/spinlock_gcc_atomic.hpp>
|
||||
|
||||
#else
|
||||
|
||||
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||
94
include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp
Normal file
94
include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright 2008, 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("Using __atomic spinlock")
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
// `bool` alignment is required for Apple PPC32
|
||||
// https://github.com/boostorg/smart_ptr/issues/105
|
||||
// https://github.com/PurpleI2P/i2pd/issues/1726
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107590
|
||||
|
||||
union
|
||||
{
|
||||
unsigned char v_;
|
||||
bool align_;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
return __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ) == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
__atomic_clear( &v_, __ATOMIC_RELEASE );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {{0}}
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED
|
||||
91
include/boost/smart_ptr/detail/spinlock_pool.hpp
Normal file
91
include/boost/smart_ptr/detail/spinlock_pool.hpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/spinlock_pool.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// spinlock_pool<0> is reserved for atomic<>, when/if it arrives
|
||||
// spinlock_pool<1> is reserved for shared_ptr reference counts
|
||||
// spinlock_pool<2> is reserved for shared_ptr atomic access
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/spinlock.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< int M > class spinlock_pool
|
||||
{
|
||||
private:
|
||||
|
||||
static spinlock pool_[ 41 ];
|
||||
|
||||
public:
|
||||
|
||||
static spinlock & spinlock_for( void const * pv )
|
||||
{
|
||||
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
|
||||
std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
|
||||
#else
|
||||
std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
|
||||
#endif
|
||||
return pool_[ i ];
|
||||
}
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
|
||||
{
|
||||
sp_.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template< int M > spinlock spinlock_pool< M >::pool_[ 41 ] =
|
||||
{
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||
90
include/boost/smart_ptr/detail/spinlock_std_atomic.hpp
Normal file
90
include/boost/smart_ptr/detail/spinlock_std_atomic.hpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
#include <atomic>
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("Using std::atomic spinlock")
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
std::atomic_flag v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock() noexcept
|
||||
{
|
||||
return !v_.test_and_set( std::memory_order_acquire );
|
||||
}
|
||||
|
||||
void lock() noexcept
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock() noexcept
|
||||
{
|
||||
v_ .clear( std::memory_order_release );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ) noexcept: sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock() /*noexcept*/
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT }
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
||||
49
include/boost/smart_ptr/detail/yield_k.hpp
Normal file
49
include/boost/smart_ptr/detail/yield_k.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/smart_ptr/detail/yield_k.hpp
|
||||
//
|
||||
// Copyright 2008, 2020 Peter Dimov
|
||||
//
|
||||
// inline void boost::detail::yield( unsigned k );
|
||||
//
|
||||
// Typical use:
|
||||
// for( unsigned k = 0; !try_lock(); ++k ) yield( k );
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/yield_primitives.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void yield( unsigned k )
|
||||
{
|
||||
// Experiments on Windows and Fedora 32 show that a single pause,
|
||||
// followed by an immediate sp_thread_sleep(), is best.
|
||||
|
||||
if( k & 1 )
|
||||
{
|
||||
boost::core::sp_thread_sleep();
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::core::sp_thread_pause();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
||||
Reference in New Issue
Block a user