This commit is contained in:
2026-03-23 20:54:41 +08:00
commit e13b3650e9
4596 changed files with 1015768 additions and 0 deletions

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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