1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-09 07:46:32 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
#define BOOST_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.
//
// 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/atomic_count.hpp>
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED

View File

@@ -0,0 +1,22 @@
#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
#define BOOST_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
//
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED

View File

@@ -0,0 +1,26 @@
#ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
#define BOOST_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 <boost/smart_ptr/detail/lightweight_thread.hpp>
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED

View File

@@ -0,0 +1,23 @@
#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/quick_allocator.hpp
//
// Copyright (c) 2003 David Abrahams
// Copyright (c) 2003 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/quick_allocator.hpp>
#endif // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED

View File

@@ -0,0 +1,18 @@
#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
//
// enable_shared_from_this.hpp
//
// Copyright (c) 2002 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/enable_shared_from_this.hpp>
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED

View File

@@ -0,0 +1,18 @@
#ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
#define BOOST_INTRUSIVE_PTR_HPP_INCLUDED
//
// intrusive_ptr.hpp
//
// Copyright (c) 2001, 2002 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/intrusive_ptr.hpp>
#endif // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,16 @@
#ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
#define BOOST_MAKE_SHARED_HPP_INCLUDED
// make_shared.hpp
//
// Copyright (c) 2007, 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
//
// See http://www.boost.org/libs/smart_ptr/ for documentation.
#include <boost/smart_ptr/make_shared.hpp>
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED

View File

@@ -0,0 +1,13 @@
/*
Copyright 2014 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_MAKE_UNIQUE_HPP_INCLUDED
#define BOOST_MAKE_UNIQUE_HPP_INCLUDED
#include <boost/smart_ptr/make_unique.hpp>
#endif

View File

@@ -0,0 +1,122 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005.
// 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)
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_POINTER_CAST_HPP
#define BOOST_POINTER_CAST_HPP
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
namespace boost {
//static_pointer_cast overload for raw pointers
template<class T, class U>
inline T* static_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT
{
return static_cast<T*>(ptr);
}
//dynamic_pointer_cast overload for raw pointers
template<class T, class U>
inline T* dynamic_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT
{
return dynamic_cast<T*>(ptr);
}
//const_pointer_cast overload for raw pointers
template<class T, class U>
inline T* const_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT
{
return const_cast<T*>(ptr);
}
//reinterpret_pointer_cast overload for raw pointers
template<class T, class U>
inline T* reinterpret_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT
{
return reinterpret_cast<T*>(ptr);
}
} // namespace boost
#if !defined( BOOST_NO_CXX11_SMART_PTR )
#include <boost/type_traits/has_virtual_destructor.hpp>
#include <boost/static_assert.hpp>
#include <memory>
namespace boost {
//static_pointer_cast overload for std::shared_ptr
using std::static_pointer_cast;
//dynamic_pointer_cast overload for std::shared_ptr
using std::dynamic_pointer_cast;
//const_pointer_cast overload for std::shared_ptr
using std::const_pointer_cast;
//reinterpret_pointer_cast overload for std::shared_ptr
template<class T, class U> std::shared_ptr<T> reinterpret_pointer_cast(const std::shared_ptr<U> & r ) BOOST_SP_NOEXCEPT
{
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
typedef typename std::shared_ptr<T>::element_type E;
E * p = reinterpret_cast< E* >( r.get() );
return std::shared_ptr<T>( r, p );
}
//static_pointer_cast overload for std::unique_ptr
template<class T, class U> std::unique_ptr<T> static_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) static_cast< T* >( static_cast< U* >( 0 ) );
typedef typename std::unique_ptr<T>::element_type E;
return std::unique_ptr<T>( static_cast<E*>( r.release() ) );
}
//dynamic_pointer_cast overload for std::unique_ptr
template<class T, class U> std::unique_ptr<T> dynamic_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
BOOST_STATIC_ASSERT_MSG( boost::has_virtual_destructor<T>::value, "The target of dynamic_pointer_cast must have a virtual destructor." );
T * p = dynamic_cast<T*>( r.get() );
if( p ) r.release();
return std::unique_ptr<T>( p );
}
//const_pointer_cast overload for std::unique_ptr
template<class T, class U> std::unique_ptr<T> const_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) const_cast< T* >( static_cast< U* >( 0 ) );
typedef typename std::unique_ptr<T>::element_type E;
return std::unique_ptr<T>( const_cast<E*>( r.release() ) );
}
//reinterpret_pointer_cast overload for std::unique_ptr
template<class T, class U> std::unique_ptr<T> reinterpret_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
typedef typename std::unique_ptr<T>::element_type E;
return std::unique_ptr<T>( reinterpret_cast<E*>( r.release() ) );
}
} // namespace boost
#endif // #if !defined( BOOST_NO_CXX11_SMART_PTR )
#endif //BOOST_POINTER_CAST_HPP

View File

@@ -0,0 +1,55 @@
#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
#define BOOST_POINTER_TO_OTHER_HPP_INCLUDED
//
// pointer_to_other.hpp
//
// (C) Copyright Ion Gaztanaga 2005.
// Copyright (c) 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)
//
// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
namespace boost
{
// Defines the same pointer type (raw or smart) to another pointee type
template<class T, class U>
struct pointer_to_other;
template<class T, class U,
template<class> class Sp>
struct pointer_to_other< Sp<T>, U >
{
typedef Sp<U> type;
};
template<class T, class T2, class U,
template<class, class> class Sp>
struct pointer_to_other< Sp<T, T2>, U >
{
typedef Sp<U, T2> type;
};
template<class T, class T2, class T3, class U,
template<class, class, class> class Sp>
struct pointer_to_other< Sp<T, T2, T3>, U >
{
typedef Sp<U, T2, T3> type;
};
template<class T, class U>
struct pointer_to_other< T*, U >
{
typedef U* type;
};
} // namespace boost
#endif // #ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED

View File

@@ -0,0 +1,15 @@
#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
#define BOOST_SCOPED_ARRAY_HPP_INCLUDED
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 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/scoped_array.hpp>
#endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED

View File

@@ -0,0 +1,15 @@
#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
#define BOOST_SCOPED_PTR_HPP_INCLUDED
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 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/scoped_ptr.hpp>
#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,19 @@
#ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
#define BOOST_SHARED_ARRAY_HPP_INCLUDED
//
// shared_array.hpp
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 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/shared_array.hpp>
#endif // #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED

View File

@@ -0,0 +1,19 @@
#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
#define BOOST_SHARED_PTR_HPP_INCLUDED
//
// shared_ptr.hpp
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001-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)
//
// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <boost/smart_ptr/shared_ptr.hpp>
#endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,26 @@
#ifndef BOOST_SMART_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_HPP_INCLUDED
//
// smart_ptr.hpp
//
// For convenience, this header includes the rest of the smart
// pointer library headers.
//
// Copyright (c) 2003 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/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#endif // #ifndef BOOST_SMART_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,178 @@
/*
Copyright 2017-2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
#include <boost/smart_ptr/allocate_shared_array.hpp>
#include <boost/smart_ptr/local_shared_ptr.hpp>
namespace boost {
namespace detail {
class BOOST_SYMBOL_VISIBLE lsp_array_base
: public local_counted_base {
public:
void set(sp_counted_base* base) BOOST_SP_NOEXCEPT {
count_ = shared_count(base);
}
void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
shared_count().swap(count_);
}
shared_count local_cb_get_shared_count() const
BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return count_;
}
private:
shared_count count_;
};
template<class A>
class lsp_array_state
: public sp_array_state<A> {
public:
template<class U>
lsp_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
: sp_array_state<A>(other, size) { }
lsp_array_base& base() BOOST_SP_NOEXCEPT {
return base_;
}
private:
lsp_array_base base_;
};
template<class A, std::size_t N>
class lsp_size_array_state
: public sp_size_array_state<A, N> {
public:
template<class U>
lsp_size_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
: sp_size_array_state<A, N>(other, size) { }
lsp_array_base& base() BOOST_SP_NOEXCEPT {
return base_;
}
private:
lsp_array_base base_;
};
} /* detail */
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator)
{
enum {
count = extent<T>::value
};
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_size_array_state<other, count> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator, std::size_t count,
const typename remove_extent<T>::type& value)
{
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator,
const typename remove_extent<T>::type& value)
{
enum {
count = extent<T>::value
};
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_size_array_state<other, count> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator, std::size_t count)
{
return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator),
count);
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator)
{
return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator));
}
} /* boost */
#endif

View File

@@ -0,0 +1,352 @@
/*
Copyright 2012-2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#include <boost/core/allocator_access.hpp>
#include <boost/core/alloc_construct.hpp>
#include <boost/core/first_scalar.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/extent.hpp>
#include <boost/type_traits/is_bounded_array.hpp>
#include <boost/type_traits/is_unbounded_array.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
namespace boost {
namespace detail {
template<class T>
struct sp_array_element {
typedef typename boost::remove_cv<typename
boost::remove_extent<T>::type>::type type;
};
template<class T>
struct sp_array_count {
enum {
value = 1
};
};
template<class T, std::size_t N>
struct sp_array_count<T[N]> {
enum {
value = N * sp_array_count<T>::value
};
};
template<std::size_t N, std::size_t M>
struct sp_max_size {
enum {
value = N < M ? M : N
};
};
template<std::size_t N, std::size_t M>
struct sp_align_up {
enum {
value = (N + M - 1) & ~(M - 1)
};
};
template<class T>
BOOST_CONSTEXPR inline std::size_t
sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
{
return (size + sizeof(T) - 1) / sizeof(T);
}
template<class A>
class sp_array_state {
public:
typedef A type;
template<class U>
sp_array_state(const U& _allocator, std::size_t _size) BOOST_SP_NOEXCEPT
: allocator_(_allocator),
size_(_size) { }
A& allocator() BOOST_SP_NOEXCEPT {
return allocator_;
}
std::size_t size() const BOOST_SP_NOEXCEPT {
return size_;
}
private:
A allocator_;
std::size_t size_;
};
template<class A, std::size_t N>
class sp_size_array_state {
public:
typedef A type;
template<class U>
sp_size_array_state(const U& _allocator, std::size_t) BOOST_SP_NOEXCEPT
: allocator_(_allocator) { }
A& allocator() BOOST_SP_NOEXCEPT {
return allocator_;
}
BOOST_CONSTEXPR std::size_t size() const BOOST_SP_NOEXCEPT {
return N;
}
private:
A allocator_;
};
template<class T, class U>
struct sp_array_alignment {
enum {
value = sp_max_size<boost::alignment_of<T>::value,
boost::alignment_of<U>::value>::value
};
};
template<class T, class U>
struct sp_array_offset {
enum {
value = sp_align_up<sizeof(T), sp_array_alignment<T, U>::value>::value
};
};
template<class U, class T>
inline U*
sp_array_start(T* base) BOOST_SP_NOEXCEPT
{
enum {
size = sp_array_offset<T, U>::value
};
return reinterpret_cast<U*>(reinterpret_cast<char*>(base) + size);
}
template<class A, class T>
class sp_array_creator {
typedef typename A::value_type element;
enum {
offset = sp_array_offset<T, element>::value
};
typedef typename boost::type_with_alignment<sp_array_alignment<T,
element>::value>::type type;
public:
template<class U>
sp_array_creator(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
: other_(other),
size_(sp_objects<type>(offset + sizeof(element) * size)) { }
T* create() {
return reinterpret_cast<T*>(other_.allocate(size_));
}
void destroy(T* base) {
other_.deallocate(reinterpret_cast<type*>(base), size_);
}
private:
typename boost::allocator_rebind<A, type>::type other_;
std::size_t size_;
};
template<class T>
class BOOST_SYMBOL_VISIBLE sp_array_base
: public sp_counted_base {
typedef typename T::type allocator;
public:
typedef typename allocator::value_type type;
template<class A>
sp_array_base(const A& other, type* start, std::size_t size)
: state_(other, size) {
boost::alloc_construct_n(state_.allocator(),
boost::first_scalar(start),
state_.size() * sp_array_count<type>::value);
}
template<class A, class U>
sp_array_base(const A& other, type* start, std::size_t size, const U& list)
: state_(other, size) {
enum {
count = sp_array_count<type>::value
};
boost::alloc_construct_n(state_.allocator(),
boost::first_scalar(start), state_.size() * count,
boost::first_scalar(&list), count);
}
T& state() BOOST_SP_NOEXCEPT {
return state_;
}
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
boost::alloc_destroy_n(state_.allocator(),
boost::first_scalar(sp_array_start<type>(this)),
state_.size() * sp_array_count<type>::value);
}
void destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
sp_array_creator<allocator, sp_array_base> other(state_.allocator(),
state_.size());
this->~sp_array_base();
other.destroy(this);
}
void* get_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return 0;
}
void* get_local_deleter(const sp_typeinfo_&)
BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return 0;
}
void* get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return 0;
}
private:
T state_;
};
template<class A, class T>
struct sp_array_result {
public:
template<class U>
sp_array_result(const U& other, std::size_t size)
: creator_(other, size),
result_(creator_.create()) { }
~sp_array_result() {
if (result_) {
creator_.destroy(result_);
}
}
T* get() const BOOST_SP_NOEXCEPT {
return result_;
}
void release() BOOST_SP_NOEXCEPT {
result_ = 0;
}
private:
sp_array_result(const sp_array_result&);
sp_array_result& operator=(const sp_array_result&);
sp_array_creator<A, T> creator_;
T* result_;
};
} /* detail */
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator)
{
enum {
count = extent<T>::value
};
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_size_array_state<other, extent<T>::value> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count,
const typename remove_extent<T>::type& value)
{
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator,
const typename remove_extent<T>::type& value)
{
enum {
count = extent<T>::value
};
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_size_array_state<other, extent<T>::value> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator, std::size_t count)
{
return boost::allocate_shared<T>(boost::noinit_adapt(allocator), count);
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator)
{
return boost::allocate_shared<T>(boost::noinit_adapt(allocator));
}
} /* boost */
#endif

View File

@@ -0,0 +1,491 @@
/*
Copyright 2019-2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_ALLOCATE_UNIQUE_HPP
#define BOOST_SMART_PTR_ALLOCATE_UNIQUE_HPP
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/alloc_construct.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/core/first_scalar.hpp>
#include <boost/core/noinit_adaptor.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/extent.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_bounded_array.hpp>
#include <boost/type_traits/is_unbounded_array.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/config.hpp>
#include <memory>
#include <utility>
namespace boost {
namespace detail {
template<class T>
struct sp_alloc_size {
BOOST_STATIC_CONSTEXPR std::size_t value = 1;
};
template<class T>
struct sp_alloc_size<T[]> {
BOOST_STATIC_CONSTEXPR std::size_t value = sp_alloc_size<T>::value;
};
template<class T, std::size_t N>
struct sp_alloc_size<T[N]> {
BOOST_STATIC_CONSTEXPR std::size_t value = N * sp_alloc_size<T>::value;
};
template<class T>
struct sp_alloc_result {
typedef T type;
};
template<class T, std::size_t N>
struct sp_alloc_result<T[N]> {
typedef T type[];
};
template<class T>
struct sp_alloc_value {
typedef typename boost::remove_cv<typename
boost::remove_extent<T>::type>::type type;
};
template<class T, class P>
class sp_alloc_ptr {
public:
typedef T element_type;
sp_alloc_ptr() BOOST_SP_NOEXCEPT
: p_() { }
#if defined(BOOST_MSVC) && BOOST_MSVC == 1600
sp_alloc_ptr(T* p) BOOST_SP_NOEXCEPT
: p_(const_cast<typename boost::remove_cv<T>::type*>(p)) { }
#endif
sp_alloc_ptr(std::size_t, P p) BOOST_SP_NOEXCEPT
: p_(p) { }
#if !defined(BOOST_NO_CXX11_NULLPTR)
sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
: p_() { }
#endif
T& operator*() const {
return *p_;
}
T* operator->() const BOOST_SP_NOEXCEPT {
return boost::to_address(p_);
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
explicit operator bool() const BOOST_SP_NOEXCEPT {
return !!p_;
}
#endif
bool operator!() const BOOST_SP_NOEXCEPT {
return !p_;
}
P ptr() const BOOST_SP_NOEXCEPT {
return p_;
}
BOOST_STATIC_CONSTEXPR std::size_t size() BOOST_SP_NOEXCEPT {
return 1;
}
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
static sp_alloc_ptr pointer_to(T& v) {
return sp_alloc_ptr(1,
std::pointer_traits<P>::pointer_to(const_cast<typename
boost::remove_cv<T>::type&>(v)));
}
#endif
private:
P p_;
};
template<class T, class P>
class sp_alloc_ptr<T[], P> {
public:
typedef T element_type;
sp_alloc_ptr() BOOST_SP_NOEXCEPT
: p_() { }
sp_alloc_ptr(std::size_t n, P p) BOOST_SP_NOEXCEPT
: p_(p)
, n_(n) { }
#if !defined(BOOST_NO_CXX11_NULLPTR)
sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
: p_() { }
#endif
T& operator[](std::size_t i) const {
return p_[i];
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
explicit operator bool() const BOOST_SP_NOEXCEPT {
return !!p_;
}
#endif
bool operator!() const BOOST_SP_NOEXCEPT {
return !p_;
}
P ptr() const BOOST_SP_NOEXCEPT {
return p_;
}
std::size_t size() const BOOST_SP_NOEXCEPT {
return n_;
}
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
static sp_alloc_ptr pointer_to(T& v) {
return sp_alloc_ptr(n_,
std::pointer_traits<P>::pointer_to(const_cast<typename
boost::remove_cv<T>::type&>(v)));
}
#endif
private:
P p_;
std::size_t n_;
};
template<class T, std::size_t N, class P>
class sp_alloc_ptr<T[N], P> {
public:
typedef T element_type;
sp_alloc_ptr() BOOST_SP_NOEXCEPT
: p_() { }
sp_alloc_ptr(std::size_t, P p) BOOST_SP_NOEXCEPT
: p_(p) { }
#if !defined(BOOST_NO_CXX11_NULLPTR)
sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
: p_() { }
#endif
T& operator[](std::size_t i) const {
return p_[i];
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
explicit operator bool() const BOOST_SP_NOEXCEPT {
return !!p_;
}
#endif
bool operator!() const BOOST_SP_NOEXCEPT {
return !p_;
}
P ptr() const BOOST_SP_NOEXCEPT {
return p_;
}
BOOST_STATIC_CONSTEXPR std::size_t size() BOOST_SP_NOEXCEPT {
return N;
}
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
static sp_alloc_ptr pointer_to(T& v) {
return sp_alloc_ptr(N,
std::pointer_traits<P>::pointer_to(const_cast<typename
boost::remove_cv<T>::type&>(v)));
}
#endif
private:
P p_;
};
template<class T, class P>
inline bool
operator==(const sp_alloc_ptr<T, P>& lhs, const sp_alloc_ptr<T, P>& rhs)
{
return lhs.ptr() == rhs.ptr();
}
template<class T, class P>
inline bool
operator!=(const sp_alloc_ptr<T, P>& lhs, const sp_alloc_ptr<T, P>& rhs)
{
return !(lhs == rhs);
}
#if !defined(BOOST_NO_CXX11_NULLPTR)
template<class T, class P>
inline bool
operator==(const sp_alloc_ptr<T, P>& lhs,
detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
{
return !lhs.ptr();
}
template<class T, class P>
inline bool
operator==(detail::sp_nullptr_t,
const sp_alloc_ptr<T, P>& rhs) BOOST_SP_NOEXCEPT
{
return !rhs.ptr();
}
template<class T, class P>
inline bool
operator!=(const sp_alloc_ptr<T, P>& lhs,
detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
{
return !!lhs.ptr();
}
template<class T, class P>
inline bool
operator!=(detail::sp_nullptr_t,
const sp_alloc_ptr<T, P>& rhs) BOOST_SP_NOEXCEPT
{
return !!rhs.ptr();
}
#endif
template<class A>
inline void
sp_alloc_clear(A& a, typename boost::allocator_pointer<A>::type p, std::size_t,
boost::false_type)
{
boost::alloc_destroy(a, boost::to_address(p));
}
template<class A>
inline void
sp_alloc_clear(A& a, typename boost::allocator_pointer<A>::type p,
std::size_t n, boost::true_type)
{
#if defined(BOOST_MSVC) && BOOST_MSVC < 1800
if (!p) {
return;
}
#endif
boost::alloc_destroy_n(a, boost::first_scalar(boost::to_address(p)),
n * sp_alloc_size<typename A::value_type>::value);
}
} /* detail */
template<class T, class A>
class alloc_deleter
: empty_value<typename allocator_rebind<A,
typename detail::sp_alloc_value<T>::type>::type> {
typedef typename allocator_rebind<A,
typename detail::sp_alloc_value<T>::type>::type allocator;
typedef empty_value<allocator> base;
public:
typedef detail::sp_alloc_ptr<T,
typename allocator_pointer<allocator>::type> pointer;
explicit alloc_deleter(const allocator& a) BOOST_SP_NOEXCEPT
: base(empty_init_t(), a) { }
void operator()(pointer p) {
detail::sp_alloc_clear(base::get(), p.ptr(), p.size(), is_array<T>());
base::get().deallocate(p.ptr(), p.size());
}
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class T, class A>
using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A> >;
#endif
namespace detail {
template<class T, class A>
class sp_alloc_make {
public:
typedef typename boost::allocator_rebind<A,
typename sp_alloc_value<T>::type>::type allocator;
private:
typedef boost::alloc_deleter<T, A> deleter;
public:
typedef std::unique_ptr<typename sp_alloc_result<T>::type, deleter> type;
sp_alloc_make(const A& a, std::size_t n)
: a_(a)
, n_(n)
, p_(a_.allocate(n)) { }
~sp_alloc_make() {
if (p_) {
a_.deallocate(p_, n_);
}
}
typename allocator::value_type* get() const BOOST_SP_NOEXCEPT {
return boost::to_address(p_);
}
allocator& state() BOOST_SP_NOEXCEPT {
return a_;
}
type release() BOOST_SP_NOEXCEPT {
pointer p = p_;
p_ = pointer();
return type(typename deleter::pointer(n_, p), deleter(a_));
}
private:
typedef typename boost::allocator_pointer<allocator>::type pointer;
allocator a_;
std::size_t n_;
pointer p_;
};
} /* detail */
template<class T, class A>
inline typename enable_if_<!is_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc)
{
detail::sp_alloc_make<T, A> c(alloc, 1);
boost::alloc_construct(c.state(), c.get());
return c.release();
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class A, class... Args>
inline typename enable_if_<!is_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc, Args&&... args)
{
detail::sp_alloc_make<T, A> c(alloc, 1);
boost::alloc_construct(c.state(), c.get(), std::forward<Args>(args)...);
return c.release();
}
#endif
template<class T, class A>
inline typename enable_if_<!is_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc, typename type_identity<T>::type&& value)
{
detail::sp_alloc_make<T, A> c(alloc, 1);
boost::alloc_construct(c.state(), c.get(), std::move(value));
return c.release();
}
template<class T, class A>
inline typename enable_if_<!is_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A> > > >::type
allocate_unique_noinit(const A& alloc)
{
return boost::allocate_unique<T, noinit_adaptor<A> >(alloc);
}
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc, std::size_t size)
{
detail::sp_alloc_make<T, A> c(alloc, size);
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
size * detail::sp_alloc_size<T>::value);
return c.release();
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value,
std::unique_ptr<typename detail::sp_alloc_result<T>::type,
alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc)
{
detail::sp_alloc_make<T, A> c(alloc, extent<T>::value);
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
detail::sp_alloc_size<T>::value);
return c.release();
}
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A> > > >::type
allocate_unique_noinit(const A& alloc, std::size_t size)
{
return boost::allocate_unique<T, noinit_adaptor<A> >(alloc, size);
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value,
std::unique_ptr<typename detail::sp_alloc_result<T>::type,
alloc_deleter<T, noinit_adaptor<A> > > >::type
allocate_unique_noinit(const A& alloc)
{
return boost::allocate_unique<T, noinit_adaptor<A> >(alloc);
}
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc, std::size_t size,
const typename remove_extent<T>::type& value)
{
detail::sp_alloc_make<T, A> c(alloc, size);
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
size * detail::sp_alloc_size<T>::value, boost::first_scalar(&value),
detail::sp_alloc_size<typename remove_extent<T>::type>::value);
return c.release();
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value,
std::unique_ptr<typename detail::sp_alloc_result<T>::type,
alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc,
const typename remove_extent<T>::type& value)
{
detail::sp_alloc_make<T, A> c(alloc, extent<T>::value);
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
detail::sp_alloc_size<T>::value, boost::first_scalar(&value),
detail::sp_alloc_size<typename remove_extent<T>::type>::value);
return c.release();
}
template<class T, class U, class A>
inline typename allocator_pointer<typename allocator_rebind<A,
typename detail::sp_alloc_value<T>::type>::type>::type
get_allocator_pointer(const std::unique_ptr<T,
alloc_deleter<U, A> >& p) BOOST_NOEXCEPT
{
return p.get().ptr();
}
} /* boost */
#endif

View File

@@ -0,0 +1,238 @@
#ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
//
// atomic_shared_ptr.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/shared_ptr.hpp>
#include <boost/smart_ptr/detail/spinlock.hpp>
#include <cstring>
namespace boost
{
template<class T> class atomic_shared_ptr
{
private:
boost::shared_ptr<T> p_;
mutable boost::detail::spinlock l_;
atomic_shared_ptr(const atomic_shared_ptr&);
atomic_shared_ptr& operator=(const atomic_shared_ptr&);
private:
bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
{
l_.lock();
if( p_._internal_equiv( v ) )
{
p_.swap( w );
l_.unlock();
return true;
}
else
{
shared_ptr<T> tmp( p_ );
l_.unlock();
tmp.swap( v );
return false;
}
}
public:
#if !defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) && !defined( BOOST_NO_CXX11_CONSTEXPR )
constexpr atomic_shared_ptr() BOOST_SP_NOEXCEPT: l_ BOOST_DETAIL_SPINLOCK_INIT
{
}
atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
: p_( std::move( p ) ), l_ BOOST_DETAIL_SPINLOCK_INIT
{
}
#else
atomic_shared_ptr() BOOST_SP_NOEXCEPT
{
boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
std::memcpy( &l_, &init, sizeof( init ) );
}
atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
: p_( std::move( p ) )
#else
: p_( p )
#endif
{
boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
std::memcpy( &l_, &init, sizeof( init ) );
}
#endif
atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
return *this;
}
BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT
{
return false;
}
shared_ptr<T> load() const BOOST_SP_NOEXCEPT
{
boost::detail::spinlock::scoped_lock lock( l_ );
return p_;
}
template<class M> shared_ptr<T> load( M ) const BOOST_SP_NOEXCEPT
{
boost::detail::spinlock::scoped_lock lock( l_ );
return p_;
}
operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
{
boost::detail::spinlock::scoped_lock lock( l_ );
return p_;
}
void store( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
template<class M> void store( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
shared_ptr<T> exchange( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
{
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
return std::move( r );
#else
return r;
#endif
}
template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
{
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
return std::move( r );
#else
return r;
#endif
}
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, w );
}
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, w );
}
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, w );
}
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, w );
}
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, w );
}
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, w );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, std::move( w ) );
}
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, std::move( w ) );
}
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, std::move( w ) );
}
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, std::move( w ) );
}
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, std::move( w ) );
}
bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
{
return compare_exchange( v, std::move( w ) );
}
#endif
};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,70 @@
#ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/smart_ptr/bad_weak_ptr.hpp
//
// Copyright (c) 2001, 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)
//
#include <boost/config.hpp>
#include <exception>
#ifdef BOOST_BORLANDC
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
#endif
namespace boost
{
// The standard library that comes with Borland C++ 5.5.1, 5.6.4
// defines std::exception and its members as having C calling
// convention (-pc). When the definition of bad_weak_ptr
// is compiled with -ps, the compiler issues an error.
// Hence, the temporary #pragma option -pc below.
#if defined(BOOST_BORLANDC) && BOOST_BORLANDC <= 0x564
# pragma option push -pc
#endif
#if defined(BOOST_CLANG)
// Intel C++ on Mac defines __clang__ but doesn't support the pragma
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wweak-vtables"
#endif
class bad_weak_ptr: public std::exception
{
public:
char const * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
{
return "tr1::bad_weak_ptr";
}
};
#if defined(BOOST_CLANG)
# pragma clang diagnostic pop
#endif
#if defined(BOOST_BORLANDC) && BOOST_BORLANDC <= 0x564
# pragma option pop
#endif
} // namespace boost
#ifdef BOOST_BORLANDC
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
#endif
#endif // #ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,103 @@
#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/sp_has_gcc_intrinsics.hpp>
#include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp>
#include <boost/config.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_AC_USE_SPINLOCK )
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
#elif defined( BOOST_AC_USE_PTHREADS )
# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
#elif defined( BOOST_SP_DISABLE_THREADS )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
#elif defined( BOOST_SP_USE_STD_ATOMIC )
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
#elif defined( BOOST_SP_USE_SPINLOCK )
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
#elif defined( BOOST_SP_USE_PTHREADS )
# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
#elif defined( BOOST_SP_HAS_GCC_INTRINSICS )
# include <boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp>
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS )
# include <boost/smart_ptr/detail/atomic_count_sync.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ )
# include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
#elif !defined( BOOST_HAS_THREADS )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
#else
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED

View File

@@ -0,0 +1,79 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
//
// boost/detail/atomic_count_gcc.hpp
//
// atomic_count for GNU libstdc++ v3
//
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2002 Lars Gullik Bjønnes <larsbj@lyx.org>
// Copyright 2003-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)
//
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
# include <ext/atomicity.h>
#else
# include <bits/atomicity.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using libstdc++ atomic_count")
#endif
namespace boost
{
namespace detail
{
#if defined(__GLIBCXX__) // g++ 3.4+
using __gnu_cxx::__atomic_add;
using __gnu_cxx::__exchange_and_add;
#endif
class atomic_count
{
public:
explicit atomic_count( long v ) : value_( v ) {}
long operator++()
{
return __exchange_and_add( &value_, +1 ) + 1;
}
long operator--()
{
return __exchange_and_add( &value_, -1 ) - 1;
}
operator long() const
{
return __exchange_and_add( &value_, 0 );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
mutable _Atomic_word value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED

View File

@@ -0,0 +1,63 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED
// boost/detail/atomic_count_gcc_atomic.hpp
//
// atomic_count for g++ 4.7+
//
// Copyright 2007, 2020 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __atomic atomic_count")
#endif
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ): value_( static_cast< boost::int_least32_t >( v ) )
{
}
long operator++()
{
return __atomic_add_fetch( &value_, +1, __ATOMIC_ACQ_REL );
}
long operator--()
{
return __atomic_add_fetch( &value_, -1, __ATOMIC_ACQ_REL );
}
operator long() const
{
return __atomic_load_n( &value_, __ATOMIC_ACQUIRE );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
boost::int_least32_t value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED

View File

@@ -0,0 +1,88 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
//
// boost/detail/atomic_count_gcc_x86.hpp
//
// atomic_count for g++ on 486+/AMD64
//
// Copyright 2007 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_obsolete.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/x86 atomic_count")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
long operator++()
{
return atomic_exchange_and_add( &value_, +1 ) + 1;
}
long operator--()
{
return atomic_exchange_and_add( &value_, -1 ) - 1;
}
operator long() const
{
return atomic_exchange_and_add( &value_, 0 );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
mutable int value_;
private:
static int atomic_exchange_and_add( int * pw, int dv )
{
// int r = *pw;
// *pw += dv;
// return r;
int r;
__asm__ __volatile__
(
"lock\n\t"
"xadd %1, %0":
"+m"( *pw ), "=r"( r ): // outputs (%0, %1)
"1"( dv ): // inputs (%2 == %1)
"memory", "cc" // clobbers
);
return r;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_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,104 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
//
// boost/detail/atomic_count_pthreads.hpp
//
// Copyright (c) 2001, 2002 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)
//
#include <boost/assert.hpp>
#include <pthread.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using pthread_mutex atomic_count")
#endif
//
// The generic pthread_mutex-based implementation sometimes leads to
// inefficiencies. Example: a class with two atomic_count members
// can get away with a single mutex.
//
// Users can detect this situation by checking BOOST_AC_USE_PTHREADS.
//
namespace boost
{
namespace detail
{
class atomic_count
{
private:
class scoped_lock
{
public:
scoped_lock(pthread_mutex_t & m): m_(m)
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
}
~scoped_lock()
{
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
}
private:
pthread_mutex_t & m_;
};
public:
explicit atomic_count(long v): value_(v)
{
BOOST_VERIFY( pthread_mutex_init( &mutex_, 0 ) == 0 );
}
~atomic_count()
{
BOOST_VERIFY( pthread_mutex_destroy( &mutex_ ) == 0 );
}
long operator++()
{
scoped_lock lock(mutex_);
return ++value_;
}
long operator--()
{
scoped_lock lock(mutex_);
return --value_;
}
operator long() const
{
scoped_lock lock(mutex_);
return value_;
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
mutable pthread_mutex_t mutex_;
long value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED

View File

@@ -0,0 +1,69 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
//
// boost/detail/atomic_count_spin.hpp
//
// 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
//
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using spinlock-based atomic_count")
#endif
namespace boost
{
namespace detail
{
class atomic_count
{
private:
public:
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
spinlock_pool<0>::scoped_lock lock( &value_ );
return ++value_;
}
long operator--()
{
spinlock_pool<0>::scoped_lock lock( &value_ );
return --value_;
}
operator long() const
{
spinlock_pool<0>::scoped_lock lock( &value_ );
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_SPIN_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,72 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
//
// boost/detail/atomic_count_sync.hpp
//
// atomic_count for g++ 4.1+
//
// http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html
//
// Copyright 2007 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/cstdint.hpp>
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
# include <ia64intrin.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __sync atomic_count")
#endif
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ): value_( static_cast< boost::int_least32_t >( v ) )
{
}
long operator++()
{
return __sync_add_and_fetch( &value_, 1 );
}
long operator--()
{
return __sync_add_and_fetch( &value_, -1 );
}
operator long() const
{
return __sync_fetch_and_add( &value_, 0 );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
mutable boost::int_least32_t value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED

View File

@@ -0,0 +1,70 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/atomic_count_win32.hpp
//
// Copyright (c) 2001-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_interlocked.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Win32 atomic_count")
#endif
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
return BOOST_SP_INTERLOCKED_INCREMENT( &value_ );
}
long operator--()
{
return BOOST_SP_INTERLOCKED_DECREMENT( &value_ );
}
operator long() const
{
return static_cast<long const volatile &>( 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_WIN32_HPP_INCLUDED

View File

@@ -0,0 +1,39 @@
#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 maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX.
//
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_HDR_MUTEX )
# include <boost/smart_ptr/detail/lwm_std_mutex.hpp>
#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/lwm_win32_cs.hpp>
#else
# include <boost/smart_ptr/detail/lwm_pthreads.hpp>
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED

View File

@@ -0,0 +1,188 @@
#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 <boost/config.hpp>
#include <memory>
#include <cerrno>
#if defined( BOOST_HAS_PTHREADS )
#include <pthread.h>
namespace boost
{
namespace detail
{
typedef ::pthread_t lw_thread_t;
inline int lw_thread_create_( lw_thread_t* thread, const pthread_attr_t* attr, void* (*start_routine)( void* ), void* arg )
{
return ::pthread_create( thread, attr, start_routine, arg );
}
inline void lw_thread_join( lw_thread_t th )
{
::pthread_join( th, 0 );
}
} // namespace detail
} // namespace boost
#else // defined( BOOST_HAS_PTHREADS )
#include <windows.h>
#include <process.h>
namespace boost
{
namespace detail
{
typedef HANDLE lw_thread_t;
inline int lw_thread_create_( lw_thread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
{
HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
if( h != 0 )
{
*thread = h;
return 0;
}
else
{
return EAGAIN;
}
}
inline void lw_thread_join( lw_thread_t thread )
{
::WaitForSingleObject( thread, INFINITE );
::CloseHandle( thread );
}
} // namespace detail
} // namespace boost
#endif // defined( BOOST_HAS_PTHREADS )
namespace boost
{
namespace detail
{
class lw_abstract_thread
{
public:
virtual ~lw_abstract_thread() {}
virtual void run() = 0;
};
#if defined( BOOST_HAS_PTHREADS )
extern "C" void * lw_thread_routine( void * pv )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#else
std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#endif
pt->run();
return 0;
}
#else
unsigned __stdcall lw_thread_routine( void * pv )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#else
std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#endif
pt->run();
return 0;
}
#endif
template<class F> class lw_thread_impl: public lw_abstract_thread
{
public:
explicit lw_thread_impl( F f ): f_( f )
{
}
void run()
{
f_();
}
private:
F f_;
};
template<class F> int lw_thread_create( lw_thread_t & th, F f )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
#else
std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
#endif
int r = lw_thread_create_( &th, 0, lw_thread_routine, p.get() );
if( r == 0 )
{
p.release();
}
return r;
}
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED

View File

@@ -0,0 +1,148 @@
#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:
BOOST_CONSTEXPR local_counted_base() BOOST_SP_NOEXCEPT: local_use_count_( initial_ )
{
}
BOOST_CONSTEXPR local_counted_base( local_counted_base const & ) BOOST_SP_NOEXCEPT: local_use_count_( initial_ )
{
}
virtual ~local_counted_base() /*BOOST_SP_NOEXCEPT*/
{
}
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT = 0;
virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT = 0;
void add_ref() BOOST_SP_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() BOOST_SP_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 BOOST_SP_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 ) BOOST_SP_NOEXCEPT: pn_( pn )
{
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
explicit local_counted_impl( shared_count && pn ) BOOST_SP_NOEXCEPT: pn_( std::move(pn) )
{
}
#endif
void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
delete this;
}
boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return pn_;
}
};
class BOOST_SYMBOL_VISIBLE local_counted_impl_em: public local_counted_base
{
public:
shared_count pn_;
void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
shared_count().swap( pn_ );
}
boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return pn_;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED

View File

@@ -0,0 +1,91 @@
#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 ) BOOST_SP_NOEXCEPT: d_( d )
{
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
explicit local_sp_deleter( D&& d ) BOOST_SP_NOEXCEPT: d_( std::move(d) )
{
}
#endif
D& deleter() BOOST_SP_NOEXCEPT
{
return d_;
}
template<class Y> void operator()( Y* p ) BOOST_SP_NOEXCEPT
{
d_( p );
}
#if !defined( BOOST_NO_CXX11_NULLPTR )
void operator()( boost::detail::sp_nullptr_t p ) BOOST_SP_NOEXCEPT
{
d_( p );
}
#endif
};
template<> class local_sp_deleter<void>
{
};
template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT
{
return &p->deleter();
}
inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) BOOST_SP_NOEXCEPT
{
return 0;
}
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED

View File

@@ -0,0 +1,87 @@
#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/lwm_pthreads.hpp
//
// Copyright (c) 2002 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)
//
#include <boost/assert.hpp>
#include <pthread.h>
namespace boost
{
namespace detail
{
class lightweight_mutex
{
private:
pthread_mutex_t m_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
public:
lightweight_mutex()
{
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
#if defined(__hpux) && defined(_DECTHREADS_)
BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
#else
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
#endif
}
~lightweight_mutex()
{
BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
}
class scoped_lock;
friend class scoped_lock;
class scoped_lock
{
private:
pthread_mutex_t & m_;
scoped_lock(scoped_lock const &);
scoped_lock & operator=(scoped_lock const &);
public:
scoped_lock(lightweight_mutex & m): m_(m.m_)
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
}
~scoped_lock()
{
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
}
};
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_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,123 @@
#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/lwm_win32_cs.hpp
//
// Copyright (c) 2002, 2003 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)
//
#ifdef BOOST_USE_WINDOWS_H
#include <windows.h>
#else
struct _RTL_CRITICAL_SECTION;
#endif
namespace boost
{
namespace detail
{
#ifndef BOOST_USE_WINDOWS_H
struct critical_section
{
struct critical_section_debug * DebugInfo;
long LockCount;
long RecursionCount;
void * OwningThread;
void * LockSemaphore;
#if defined(_WIN64)
unsigned __int64 SpinCount;
#else
unsigned long SpinCount;
#endif
};
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *);
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *);
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *);
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *);
typedef ::_RTL_CRITICAL_SECTION rtl_critical_section;
#else // #ifndef BOOST_USE_WINDOWS_H
typedef ::CRITICAL_SECTION critical_section;
using ::InitializeCriticalSection;
using ::EnterCriticalSection;
using ::LeaveCriticalSection;
using ::DeleteCriticalSection;
typedef ::CRITICAL_SECTION rtl_critical_section;
#endif // #ifndef BOOST_USE_WINDOWS_H
class lightweight_mutex
{
private:
critical_section cs_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
public:
lightweight_mutex()
{
boost::detail::InitializeCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_));
}
~lightweight_mutex()
{
boost::detail::DeleteCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_));
}
class scoped_lock;
friend class scoped_lock;
class scoped_lock
{
private:
lightweight_mutex & m_;
scoped_lock(scoped_lock const &);
scoped_lock & operator=(scoped_lock const &);
public:
explicit scoped_lock(lightweight_mutex & m): m_(m)
{
boost::detail::EnterCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_));
}
~scoped_lock()
{
boost::detail::LeaveCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_));
}
};
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED

View File

@@ -0,0 +1,64 @@
// This header intentionally has no include guards.
//
// Copyright (c) 2001-2009, 2012 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_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )\
&& !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
explicit operator bool () const BOOST_SP_NOEXCEPT
{
return px != 0;
}
#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
operator bool () const BOOST_SP_NOEXCEPT
{
return px != 0;
}
#elif defined( _MANAGED )
static void unspecified_bool( this_type*** )
{
}
typedef void (*unspecified_bool_type)( this_type*** );
operator unspecified_bool_type() const BOOST_SP_NOEXCEPT
{
return px == 0? 0: unspecified_bool;
}
#elif \
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
typedef element_type * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const BOOST_SP_NOEXCEPT
{
return px == 0? 0: &this_type::get;
}
#else
typedef element_type * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const BOOST_SP_NOEXCEPT
{
return px == 0? 0: &this_type::px;
}
#endif
// operator! is redundant, but some compilers need it
bool operator! () const BOOST_SP_NOEXCEPT
{
return px == 0;
}

View File

@@ -0,0 +1,199 @@
#ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/quick_allocator.hpp
//
// Copyright (c) 2003 David Abrahams
// Copyright (c) 2003 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 <boost/smart_ptr/detail/lightweight_mutex.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <new> // ::operator new, ::operator delete
#include <cstddef> // std::size_t
namespace boost
{
namespace detail
{
template<unsigned size, unsigned align_> union freeblock
{
typedef typename boost::type_with_alignment<align_>::type aligner_type;
aligner_type aligner;
char bytes[size];
freeblock * next;
};
template<unsigned size, unsigned align_> struct allocator_impl
{
typedef freeblock<size, align_> block;
// It may seem odd to use such small pages.
//
// However, on a typical Windows implementation that uses
// the OS allocator, "normal size" pages interact with the
// "ordinary" operator new, slowing it down dramatically.
//
// 512 byte pages are handled by the small object allocator,
// and don't interfere with ::new.
//
// The other alternative is to use much bigger pages (1M.)
//
// It is surprisingly easy to hit pathological behavior by
// varying the page size. g++ 2.96 on Red Hat Linux 7.2,
// for example, passionately dislikes 496. 512 seems OK.
#if defined(BOOST_QA_PAGE_SIZE)
enum { items_per_page = BOOST_QA_PAGE_SIZE / size };
#else
enum { items_per_page = 512 / size }; // 1048560 / size
#endif
#ifdef BOOST_HAS_THREADS
static lightweight_mutex & mutex()
{
static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm;
static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
return *pm;
}
static lightweight_mutex * mutex_init;
#endif
static block * free;
static block * page;
static unsigned last;
static inline void * alloc()
{
#ifdef BOOST_HAS_THREADS
lightweight_mutex::scoped_lock lock( mutex() );
#endif
if(block * x = free)
{
free = x->next;
return x;
}
else
{
if(last == items_per_page)
{
// "Listen to me carefully: there is no memory leak"
// -- Scott Meyers, Eff C++ 2nd Ed Item 10
page = ::new block[items_per_page];
last = 0;
}
return &page[last++];
}
}
static inline void * alloc(std::size_t n)
{
if(n != size) // class-specific new called for a derived object
{
return ::operator new(n);
}
else
{
#ifdef BOOST_HAS_THREADS
lightweight_mutex::scoped_lock lock( mutex() );
#endif
if(block * x = free)
{
free = x->next;
return x;
}
else
{
if(last == items_per_page)
{
page = ::new block[items_per_page];
last = 0;
}
return &page[last++];
}
}
}
static inline void dealloc(void * pv)
{
if(pv != 0) // 18.4.1.1/13
{
#ifdef BOOST_HAS_THREADS
lightweight_mutex::scoped_lock lock( mutex() );
#endif
block * pb = static_cast<block *>(pv);
pb->next = free;
free = pb;
}
}
static inline void dealloc(void * pv, std::size_t n)
{
if(n != size) // class-specific delete called for a derived object
{
::operator delete(pv);
}
else if(pv != 0) // 18.4.1.1/13
{
#ifdef BOOST_HAS_THREADS
lightweight_mutex::scoped_lock lock( mutex() );
#endif
block * pb = static_cast<block *>(pv);
pb->next = free;
free = pb;
}
}
};
#ifdef BOOST_HAS_THREADS
template<unsigned size, unsigned align_>
lightweight_mutex * allocator_impl<size, align_>::mutex_init = &allocator_impl<size, align_>::mutex();
#endif
template<unsigned size, unsigned align_>
freeblock<size, align_> * allocator_impl<size, align_>::free = 0;
template<unsigned size, unsigned align_>
freeblock<size, align_> * allocator_impl<size, align_>::page = 0;
template<unsigned size, unsigned align_>
unsigned allocator_impl<size, align_>::last = allocator_impl<size, align_>::items_per_page;
template<class T>
struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of<T>::value >
{
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED

View File

@@ -0,0 +1,707 @@
#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)
//
#if defined(__BORLANDC__) && !defined(__clang__)
# pragma warn -8027 // Functions containing try are not expanded inline
#endif
#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/sp_noexcept.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/core/addressof.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/cstdint.hpp>
#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
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int const shared_count_id = 0x2C35F101;
int const weak_count_id = 0x298C38A4;
#endif
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 ) BOOST_NOEXCEPT
{
boost::uintptr_t v = reinterpret_cast<boost::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_;
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int id_;
#endif
friend class weak_count;
public:
BOOST_CONSTEXPR shared_count() BOOST_SP_NOEXCEPT: pi_(0)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
}
BOOST_CONSTEXPR explicit shared_count( sp_counted_base * pi ) BOOST_SP_NOEXCEPT: pi_( pi )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
}
template<class Y> explicit shared_count( Y * p ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#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
}
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
#else
template<class P, class D> shared_count( P p, D d ): pi_(0)
#endif
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
typedef Y* P;
#endif
#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
}
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#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
}
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
typedef sp_counted_impl_pda<P, D, A> impl_type;
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
#else
typedef typename A::template rebind< impl_type >::other A2;
#endif
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
}
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
typedef sp_counted_impl_pda< P, D, A > impl_type;
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
#else
typedef typename A::template rebind< impl_type >::other A2;
#endif
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
}
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
#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() ) )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#ifdef BOOST_NO_EXCEPTIONS
if( pi_ == 0 )
{
boost::throw_exception(std::bad_alloc());
}
#endif
r.release();
}
#endif
#if !defined( BOOST_NO_CXX11_SMART_PTR )
template<class Y, class D>
explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
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();
}
#endif
template<class Y, class D>
explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
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() /*BOOST_SP_NOEXCEPT*/
{
if( pi_ != 0 ) pi_->release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
id_ = 0;
#endif
}
shared_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if( pi_ != 0 ) pi_->add_ref_copy();
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
shared_count(shared_count && r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
r.pi_ = 0;
}
#endif
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 ) BOOST_SP_NOEXCEPT; // constructs an empty *this when r.use_count() == 0
shared_count & operator= (shared_count const & r) BOOST_SP_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) BOOST_SP_NOEXCEPT
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const BOOST_SP_NOEXCEPT
{
return pi_ != 0? pi_->use_count(): 0;
}
bool unique() const BOOST_SP_NOEXCEPT
{
return use_count() == 1;
}
bool empty() const BOOST_SP_NOEXCEPT
{
return pi_ == 0;
}
bool operator==( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return pi_ == r.pi_;
}
bool operator==( weak_count const & r ) const BOOST_SP_NOEXCEPT;
bool operator<( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
bool operator<( weak_count const & r ) const BOOST_SP_NOEXCEPT;
void * get_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pi_? pi_->get_deleter( ti ): 0;
}
void * get_local_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pi_? pi_->get_local_deleter( ti ): 0;
}
void * get_untyped_deleter() const BOOST_SP_NOEXCEPT
{
return pi_? pi_->get_untyped_deleter(): 0;
}
std::size_t hash_value() const BOOST_SP_NOEXCEPT
{
return sp_hash_pointer( pi_ );
}
};
class weak_count
{
private:
sp_counted_base * pi_;
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int id_;
#endif
friend class shared_count;
public:
BOOST_CONSTEXPR weak_count() BOOST_SP_NOEXCEPT: pi_(0)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
}
weak_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
if(pi_ != 0) pi_->weak_add_ref();
}
weak_count(weak_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
if(pi_ != 0) pi_->weak_add_ref();
}
// Move support
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
weak_count(weak_count && r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
r.pi_ = 0;
}
#endif
~weak_count() /*BOOST_SP_NOEXCEPT*/
{
if(pi_ != 0) pi_->weak_release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
id_ = 0;
#endif
}
weak_count & operator= (shared_count const & r) BOOST_SP_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) BOOST_SP_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) BOOST_SP_NOEXCEPT
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const BOOST_SP_NOEXCEPT
{
return pi_ != 0? pi_->use_count(): 0;
}
bool empty() const BOOST_SP_NOEXCEPT
{
return pi_ == 0;
}
bool operator==( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return pi_ == r.pi_;
}
bool operator==( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return pi_ == r.pi_;
}
bool operator<( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
bool operator<( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
std::size_t hash_value() const BOOST_SP_NOEXCEPT
{
return sp_hash_pointer( pi_ );
}
};
inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
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 ) BOOST_SP_NOEXCEPT: pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if( pi_ != 0 && !pi_->add_ref_lock() )
{
pi_ = 0;
}
}
inline bool shared_count::operator==( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return pi_ == r.pi_;
}
inline bool shared_count::operator<( weak_count const & r ) const BOOST_SP_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
#if defined(__BORLANDC__) && !defined(__clang__)
# pragma warn .8027 // Functions containing try are not expanded inline
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED

View File

@@ -0,0 +1,92 @@
#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>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_BORLANDC ) && ( BOOST_BORLANDC < 0x630 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
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 // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED

View File

@@ -0,0 +1,92 @@
#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/sp_has_gcc_intrinsics.hpp>
#include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp>
#include <boost/config.hpp>
#if defined( BOOST_SP_DISABLE_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_SP_USE_STD_ATOMIC )
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
#elif defined( BOOST_SP_USE_SPINLOCK )
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
#elif defined( BOOST_SP_USE_PTHREADS )
# include <boost/smart_ptr/detail/sp_counted_base_pt.hpp>
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_SP_HAS_GCC_INTRINSICS )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp>
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
#elif defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined( __SNC__ )
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
#elif defined(__HP_aCC) && defined(__ia64)
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
#elif defined( __IBMCPP__ ) && defined( __powerpc )
# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !defined( __mips16 )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
#elif defined( _AIX )
# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
#elif !defined( BOOST_HAS_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#else
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED

View File

@@ -0,0 +1,163 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
//
// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
//
// Copyright 2007 Baruch Zilber
// Copyright 2007 Boris Gubenko
//
// 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)
//
//
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#include <machine/sys/inline.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using HP aCC++/HP-UX/IA64 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
if (1 == r)
{
_Asm_mf();
}
return r - 1;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int v = *pw;
for (;;)
{
if (0 == v)
{
return 0;
}
_Asm_mov_to_ar(_AREG_CCV,
v,
(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
if (r == v)
{
return r + 1;
}
v = r;
}
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED

View File

@@ -0,0 +1,152 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
//
// detail/sp_counted_base_aix.hpp
// based on: detail/sp_counted_base_w32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
// Copyright 2006 Michael van der Westhuizen
//
// 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)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <builtins.h>
#include <sys/atomic_op.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using AIX sp_counted_base")
#endif
namespace boost
{
namespace detail
{
inline void atomic_increment( int32_t* pw )
{
// ++*pw;
fetch_and_add( pw, 1 );
}
inline int32_t atomic_decrement( int32_t * pw )
{
// return --*pw;
int32_t originalValue;
__lwsync();
originalValue = fetch_and_add( pw, -1 );
__isync();
return (originalValue - 1);
}
inline int32_t atomic_conditional_increment( int32_t * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int32_t tmp = fetch_and_add( pw, 0 );
for( ;; )
{
if( tmp == 0 ) return 0;
if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
}
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int32_t use_count_; // #shared
int32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED

View File

@@ -0,0 +1,183 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC
//
// 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)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using CodeWarrior/PowerPC sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
namespace detail
{
inline void atomic_increment( register long * pw )
{
register int a;
asm
{
loop:
lwarx a, 0, pw
addi a, a, 1
stwcx. a, 0, pw
bne- loop
}
}
inline long atomic_decrement( register long * pw )
{
register int a;
asm
{
sync
loop:
lwarx a, 0, pw
addi a, a, -1
stwcx. a, 0, pw
bne- loop
isync
}
return a;
}
inline long atomic_conditional_increment( register long * pw )
{
register int a;
asm
{
loop:
lwarx a, 0, pw
cmpwi a, 0
beq store
addi a, a, 1
store:
stwcx. a, 0, pw
bne- loop
}
return a;
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED

View File

@@ -0,0 +1,148 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_gcc_atomic.hpp - g++ 4.7+ __atomic intrinsics
//
// Copyright 2007, 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/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __atomic sp_counted_base")
#endif
namespace boost
{
namespace detail
{
inline void atomic_increment( boost::uint_least32_t * pw )
{
__atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
}
inline boost::uint_least32_t atomic_decrement( boost::uint_least32_t * pw )
{
return __atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
}
inline boost::uint_least32_t atomic_conditional_increment( boost::uint_least32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
boost::uint_least32_t r = __atomic_load_n( pw, __ATOMIC_RELAXED );
for( ;; )
{
if( r == 0 )
{
return r;
}
if( __atomic_compare_exchange_n( pw, &r, r + 1, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
{
return r;
}
}
}
inline boost::uint_least32_t atomic_load( boost::uint_least32_t const * pw )
{
return __atomic_load_n( pw, __ATOMIC_ACQUIRE );
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
boost::uint_least32_t use_count_; // #shared
boost::uint_least32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return atomic_load( &use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED

View File

@@ -0,0 +1,170 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
//
// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2006 Peter Dimov
// Copyright 2005 Ben Hutchings
//
// 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)
//
//
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/IA64 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
int tmp;
// No barrier is required here but fetchadd always has an acquire or
// release barrier associated with it. We choose release as it should be
// cheaper.
__asm__ ("fetchadd4.rel %0=%1,1" :
"=r"(tmp), "=m"(*pw) :
"m"( *pw ));
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int rv;
__asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
" cmp.eq p7,p0=1,%0 ;; \n"
"(p7) ld4.acq %0=%1 " :
"=&r"(rv), "=m"(*pw) :
"m"( *pw ) :
"p7");
return rv;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv, tmp, tmp2;
__asm__ ("0: ld4 %0=%3 ;; \n"
" cmp.eq p7,p0=0,%0 ;; \n"
"(p7) br.cond.spnt 1f \n"
" mov ar.ccv=%0 \n"
" add %1=1,%0 ;; \n"
" cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
" cmp.ne p7,p0=%0,%2 ;; \n"
"(p7) br.cond.spnt 0b \n"
" mov %0=%1 ;; \n"
"1:" :
"=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
"m"( *pw ) :
"ar.ccv", "p7");
return rv;
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED

View File

@@ -0,0 +1,200 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS
//
// Copyright (c) 2009, Spirent Communications, Inc.
//
// 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)
//
//
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/MIPS sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
int tmp;
__asm__ __volatile__
(
"0:\n\t"
".set push\n\t"
#if !defined(__mips_isa_rev) || (__mips_isa_rev < 6)
".set mips2\n\t"
#endif
"ll %0, %1\n\t"
"addiu %0, 1\n\t"
"sc %0, %1\n\t"
".set pop\n\t"
"beqz %0, 0b":
"=&r"( tmp ), "=m"( *pw ):
"m"( *pw )
);
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int rv, tmp;
__asm__ __volatile__
(
"0:\n\t"
".set push\n\t"
#if !defined(__mips_isa_rev) || (__mips_isa_rev < 6)
".set mips2\n\t"
#endif
"ll %1, %2\n\t"
"addiu %0, %1, -1\n\t"
"sc %0, %2\n\t"
".set pop\n\t"
"beqz %0, 0b\n\t"
"addiu %0, %1, -1":
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
"m"( *pw ):
"memory"
);
return rv;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv, tmp;
__asm__ __volatile__
(
"0:\n\t"
".set push\n\t"
#if !defined(__mips_isa_rev) || (__mips_isa_rev < 6)
".set mips2\n\t"
#endif
"ll %0, %2\n\t"
"beqz %0, 1f\n\t"
"addiu %1, %0, 1\n\t"
"sc %1, %2\n\t"
".set pop\n\t"
"beqz %1, 0b\n\t"
"addiu %0, %0, 1\n\t"
"1:":
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
"m"( *pw ):
"memory"
);
return rv;
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED

View File

@@ -0,0 +1,194 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC
//
// 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)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/PowerPC sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
int tmp;
__asm__
(
"0:\n\t"
"lwarx %1, 0, %2\n\t"
"addi %1, %1, 1\n\t"
"stwcx. %1, 0, %2\n\t"
"bne- 0b":
"=m"( *pw ), "=&b"( tmp ):
"r"( pw ), "m"( *pw ):
"cc"
);
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int rv;
__asm__ __volatile__
(
"sync\n\t"
"0:\n\t"
"lwarx %1, 0, %2\n\t"
"addi %1, %1, -1\n\t"
"stwcx. %1, 0, %2\n\t"
"bne- 0b\n\t"
"isync":
"=m"( *pw ), "=&b"( rv ):
"r"( pw ), "m"( *pw ):
"memory", "cc"
);
return rv;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv;
__asm__
(
"0:\n\t"
"lwarx %1, 0, %2\n\t"
"cmpwi %1, 0\n\t"
"beq 1f\n\t"
"addi %1, %1, 1\n\t"
"1:\n\t"
"stwcx. %1, 0, %2\n\t"
"bne- 0b":
"=m"( *pw ), "=&b"( rv ):
"r"( pw ), "m"( *pw ):
"cc"
);
return rv;
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED

View File

@@ -0,0 +1,179 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
//
// Copyright (c) 2006 Piotr Wyderski
// Copyright (c) 2006 Tomas Puverle
// Copyright (c) 2006 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
//
// Thanks to Michael van der Westhuizen
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#include <inttypes.h> // int32_t
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/Sparc sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
namespace detail
{
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
{
__asm__ __volatile__( "cas [%1], %2, %0"
: "+r" (swap_)
: "r" (dest_), "r" (compare_)
: "memory" );
return swap_;
}
inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
{
// long r = *pw;
// *pw += dv;
// return r;
for( ;; )
{
int32_t r = *pw;
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
{
return r;
}
}
}
inline void atomic_increment( int32_t * pw )
{
atomic_fetch_and_add( pw, 1 );
}
inline int32_t atomic_decrement( int32_t * pw )
{
return atomic_fetch_and_add( pw, -1 );
}
inline int32_t atomic_conditional_increment( int32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
for( ;; )
{
int32_t r = *pw;
if( r == 0 )
{
return r;
}
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
{
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 & );
int32_t use_count_; // #shared
int32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return const_cast< int32_t const volatile & >( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED

View File

@@ -0,0 +1,186 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64
//
// 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)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/x86 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
namespace detail
{
inline int atomic_exchange_and_add( int * pw, int dv )
{
// int r = *pw;
// *pw += dv;
// return r;
int r;
__asm__ __volatile__
(
"lock\n\t"
"xadd %1, %0":
"=m"( *pw ), "=r"( r ): // outputs (%0, %1)
"m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
"memory", "cc" // clobbers
);
return r;
}
inline void atomic_increment( int * pw )
{
//atomic_exchange_and_add( pw, 1 );
__asm__
(
"lock\n\t"
"incl %0":
"=m"( *pw ): // output (%0)
"m"( *pw ): // input (%1)
"cc" // clobbers
);
}
inline int atomic_conditional_increment( int * pw )
{
// int rv = *pw;
// if( rv != 0 ) ++*pw;
// return rv;
int rv, tmp;
__asm__
(
"movl %0, %%eax\n\t"
"0:\n\t"
"test %%eax, %%eax\n\t"
"je 1f\n\t"
"movl %%eax, %2\n\t"
"incl %2\n\t"
"lock\n\t"
"cmpxchgl %2, %0\n\t"
"jne 0b\n\t"
"1:":
"=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
"m"( *pw ): // input (%3)
"cc" // clobbers
);
return rv;
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED

View File

@@ -0,0 +1,119 @@
#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/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#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 & );
boost::int_least32_t use_count_; // #shared
boost::int_least32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() BOOST_SP_NOEXCEPT = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() BOOST_SP_NOEXCEPT // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() BOOST_SP_NOEXCEPT
{
++use_count_;
}
bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success
{
if( use_count_ == 0 ) return false;
++use_count_;
return true;
}
void release() BOOST_SP_NOEXCEPT
{
if( --use_count_ == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() BOOST_SP_NOEXCEPT
{
++weak_count_;
}
void weak_release() BOOST_SP_NOEXCEPT
{
if( --weak_count_ == 0 )
{
destroy();
}
}
long use_count() const BOOST_SP_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,147 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_pt.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/assert.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <pthread.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using pthread_mutex 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 & );
boost::int_least32_t use_count_; // #shared
boost::int_least32_t weak_count_; // #weak + (#shared != 0)
mutable pthread_mutex_t m_;
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
#if defined(__hpux) && defined(_DECTHREADS_)
BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
#else
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
#endif
}
virtual ~sp_counted_base() // nothrow
{
BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
++use_count_;
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
}
bool add_ref_lock() // true on success
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
bool r = use_count_ == 0? false: ( ++use_count_, true );
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
return r;
}
void release() // nothrow
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
boost::int_least32_t new_use_count = --use_count_;
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
if( new_use_count == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
++weak_count_;
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
}
void weak_release() // nothrow
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
boost::int_least32_t new_weak_count = --weak_count_;
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
if( new_weak_count == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
boost::int_least32_t r = use_count_;
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
return r;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED

View File

@@ -0,0 +1,174 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_gcc_snc_ps3.hpp - PS3 Cell
//
// Copyright (c) 2006 Piotr Wyderski
// Copyright (c) 2006 Tomas Puverle
// Copyright (c) 2006 Peter Dimov
// Copyright (c) 2011 Emil Dotchevski
//
// 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
//
// Thanks to Michael van der Westhuizen
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#include <inttypes.h> // uint32_t
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using PS3 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
namespace detail
{
inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
{
return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
}
inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
{
// long r = *pw;
// *pw += dv;
// return r;
for( ;; )
{
uint32_t r = *pw;
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
{
return r;
}
}
}
inline void atomic_increment( uint32_t * pw )
{
(void) __builtin_cellAtomicIncr32( pw );
}
inline uint32_t atomic_decrement( uint32_t * pw )
{
return __builtin_cellAtomicDecr32( pw );
}
inline uint32_t atomic_conditional_increment( uint32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
for( ;; )
{
uint32_t r = *pw;
if( r == 0 )
{
return r;
}
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
{
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 & );
uint32_t use_count_; // #shared
uint32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return const_cast< uint32_t const volatile & >( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED

View File

@@ -0,0 +1,141 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-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/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using spinlock-based sp_counted_base")
#endif
namespace boost
{
namespace detail
{
inline int atomic_exchange_and_add( int * pw, int dv )
{
spinlock_pool<1>::scoped_lock lock( pw );
int r = *pw;
*pw += dv;
return r;
}
inline void atomic_increment( int * pw )
{
spinlock_pool<1>::scoped_lock lock( pw );
++*pw;
}
inline int atomic_conditional_increment( int * pw )
{
spinlock_pool<1>::scoped_lock lock( pw );
int rv = *pw;
if( rv != 0 ) ++*pw;
return rv;
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
spinlock_pool<1>::scoped_lock lock( &use_count_ );
return use_count_;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED

View File

@@ -0,0 +1,147 @@
#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/smart_ptr/detail/sp_noexcept.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 ) BOOST_SP_NOEXCEPT
{
pw->fetch_add( 1, std::memory_order_relaxed );
}
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) BOOST_SP_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 ) BOOST_SP_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() BOOST_SP_NOEXCEPT: use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() BOOST_SP_NOEXCEPT = 0;
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() BOOST_SP_NOEXCEPT
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() BOOST_SP_NOEXCEPT
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() BOOST_SP_NOEXCEPT
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() BOOST_SP_NOEXCEPT
{
atomic_increment( &weak_count_ );
}
void weak_release() BOOST_SP_NOEXCEPT
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const BOOST_SP_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,165 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
//
// Copyright (c) 2007 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 <limits.h>
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
# include <ia64intrin.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __sync sp_counted_base")
#endif
namespace boost
{
namespace detail
{
#if INT_MAX >= 2147483647
typedef int sp_int32_t;
#else
typedef long sp_int32_t;
#endif
inline void atomic_increment( sp_int32_t * pw )
{
__sync_fetch_and_add( pw, 1 );
}
inline sp_int32_t atomic_decrement( sp_int32_t * pw )
{
return __sync_fetch_and_add( pw, -1 );
}
inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
sp_int32_t r = *pw;
for( ;; )
{
if( r == 0 )
{
return r;
}
sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
if( r2 == r )
{
return r;
}
else
{
r = r2;
}
}
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
sp_int32_t use_count_; // #shared
sp_int32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return const_cast< sp_int32_t const volatile & >( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED

View File

@@ -0,0 +1,163 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
//
// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
// based on: detail/sp_counted_base_w32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
// Copyright 2006 Michael van der Westhuizen
// Copyright 2012 IBM Corp.
//
// 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)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using xlC/PowerPC sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
extern "builtin" void __lwsync(void);
extern "builtin" void __isync(void);
extern "builtin" int __fetch_and_add(volatile int* addr, int val);
extern "builtin" int __compare_and_swap(volatile int*, int*, int);
namespace boost
{
namespace detail
{
inline void atomic_increment( int *pw )
{
// ++*pw;
__lwsync();
__fetch_and_add(pw, 1);
__isync();
}
inline int atomic_decrement( int *pw )
{
// return --*pw;
__lwsync();
int originalValue = __fetch_and_add(pw, -1);
__isync();
return (originalValue - 1);
}
inline int atomic_conditional_increment( int *pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
__lwsync();
int v = *const_cast<volatile int*>(pw);
for (;;)
// loop until state is known
{
if (v == 0) return 0;
if (__compare_and_swap(pw, &v, v + 1))
{
__isync(); return (v + 1);
}
}
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
char pad[64] __attribute__((__aligned__(64)));
// pad to prevent false sharing
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return *const_cast<volatile int*>(&use_count_);
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED

View File

@@ -0,0 +1,140 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_w32.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)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config/workaround.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Win32 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 & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
BOOST_SP_INTERLOCKED_INCREMENT( &use_count_ );
}
bool add_ref_lock() // true on success
{
for( ;; )
{
long tmp = static_cast< long const volatile& >( use_count_ );
if( tmp == 0 ) return false;
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
// work around a code generation bug
long tmp2 = tmp + 1;
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
#else
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
#endif
}
}
void release() // nothrow
{
if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
BOOST_SP_INTERLOCKED_INCREMENT( &weak_count_ );
}
void weak_release() // nothrow
{
if( BOOST_SP_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED

View File

@@ -0,0 +1,309 @@
#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)
//
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
#endif
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/checked_delete.hpp>
#include <boost/core/addressof.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#include <boost/smart_ptr/detail/quick_allocator.hpp>
#endif
#include <memory> // std::allocator, std::allocator_traits
#include <cstddef> // std::size_t
namespace boost
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
#endif
namespace detail
{
// get_local_deleter
template<class D> class local_sp_deleter;
template<class D> D * get_local_deleter( D * /*p*/ ) BOOST_SP_NOEXCEPT
{
return 0;
}
template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_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 )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px, sizeof(X), this );
#endif
}
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
#endif
boost::checked_delete( px_ );
}
void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return 0;
}
void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return 0;
}
void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return 0;
}
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new( std::size_t )
{
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
}
void operator delete( void * p )
{
std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
}
#endif
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
void * operator new( std::size_t )
{
return quick_allocator<this_type>::alloc();
}
void operator delete( void * p )
{
quick_allocator<this_type>::dealloc( p );
}
#endif
};
//
// Borland's Codeguard trips up over the -Vx- option here:
//
#ifdef __CODEGUARD__
# pragma option push -Vx-
#endif
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
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
sp_counted_impl_pd( P p, D & d ): ptr( p ), del( static_cast< D&& >( d ) )
{
}
#else
sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
{
}
#endif
sp_counted_impl_pd( P p ): ptr( p ), del()
{
}
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
del( ptr );
}
void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0;
}
void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
}
void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return &reinterpret_cast<char&>( del );
}
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new( std::size_t )
{
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
}
void operator delete( void * p )
{
std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
}
#endif
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
void * operator new( std::size_t )
{
return quick_allocator<this_type>::alloc();
}
void operator delete( void * p )
{
quick_allocator<this_type>::dealloc( p );
}
#endif
};
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
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( static_cast< D&& >( d ) ), a_( a )
{
}
#else
sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
{
}
#endif
sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
{
}
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
d_( p_ );
}
void destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
#else
typedef typename A::template rebind< this_type >::other A2;
#endif
A2 a2( a_ );
this->~this_type();
a2.deallocate( this, 1 );
}
void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0;
}
void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
}
void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return &reinterpret_cast<char&>( d_ );
}
};
#ifdef __CODEGUARD__
# pragma option pop
#endif
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_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,52 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_forward.hpp
//
// Copyright 2008,2012 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>
namespace boost
{
namespace detail
{
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
#if defined( BOOST_GCC ) && __GNUC__ * 100 + __GNUC_MINOR__ <= 404
// GCC 4.4 supports an outdated version of rvalue references and creates a copy of the forwarded object.
// This results in warnings 'returning reference to temporary'. Therefore we use a special version similar to std::forward.
template< class T > T&& sp_forward( T && t ) BOOST_NOEXCEPT
{
return t;
}
#else
template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
{
return static_cast< T&& >( t );
}
#endif
#endif
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED

View File

@@ -0,0 +1,27 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
//
// Defines the BOOST_SP_HAS_GCC_INTRINSICS macro if the __atomic_*
// intrinsics are available.
#if defined( __ATOMIC_RELAXED ) && defined( __ATOMIC_ACQUIRE ) && defined( __ATOMIC_RELEASE ) && defined( __ATOMIC_ACQ_REL )
# define BOOST_SP_HAS_GCC_INTRINSICS
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED

View File

@@ -0,0 +1,69 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp
//
// Copyright (c) 2008, 2009 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)
//
// Defines the BOOST_SP_HAS_SYNC_INTRINSICS macro if the __sync_* intrinsics
// are available.
//
#if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC )
#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) && !defined( __c2__ )
# define BOOST_SP_HAS_SYNC_INTRINSICS
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) && !defined( __COMPILER_VER__ )
# define BOOST_SP_HAS_SYNC_INTRINSICS
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __c2__ )
#define BOOST_SP_HAS_SYNC_INTRINSICS
#if defined( __arm__ ) || defined( __armel__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __hppa ) || defined( __hppa__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __m68k__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __sh__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __sparc__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#endif
#endif // #if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED

View File

@@ -0,0 +1,173 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/sp_interlocked.hpp
//
// Copyright 2005, 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/config.hpp>
// BOOST_SP_HAS_INTRIN_H
// VC9 has intrin.h, but it collides with <utility>
#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600
# define BOOST_SP_HAS_INTRIN_H
// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets.
#elif defined( __MINGW64_VERSION_MAJOR )
// MinGW-w64 provides intrin.h for both 32 and 64-bit targets.
# define BOOST_SP_HAS_INTRIN_H
#elif defined( __LP64__ )
// We have to use intrin.h on Cygwin 64
# define BOOST_SP_HAS_INTRIN_H
// Intel C++ on Windows on VC10+ stdlib
#elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520
# define BOOST_SP_HAS_INTRIN_H
// clang-cl on Windows on VC10+ stdlib
#elif defined( __clang__ ) && defined( _MSC_VER ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520
# define BOOST_SP_HAS_INTRIN_H
#endif
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
#elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_SP_HAS_INTRIN_H )
#include <intrin.h>
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
#elif defined( _WIN32_WCE )
#if _WIN32_WCE >= 0x600
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
#else
// under Windows CE we still have old-style Interlocked* functions
extern "C" long __cdecl InterlockedIncrement( long* );
extern "C" long __cdecl InterlockedDecrement( long* );
extern "C" long __cdecl InterlockedCompareExchange( long*, long, long );
extern "C" long __cdecl InterlockedExchange( long*, long );
extern "C" long __cdecl InterlockedExchangeAdd( long*, long );
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
#endif
#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN )
#if defined( __CLRCALL_PURE_OR_CDECL )
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * );
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * );
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long );
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long );
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long );
#else
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
# if defined( BOOST_MSVC ) && BOOST_MSVC == 1310
//From MSDN, Visual Studio .NET 2003 spedific: To declare one of the interlocked functions
//for use as an intrinsic, the function must be declared with the leading underscore and
//the new function must appear in a #pragma intrinsic statement.
# pragma intrinsic( _InterlockedIncrement )
# pragma intrinsic( _InterlockedDecrement )
# pragma intrinsic( _InterlockedCompareExchange )
# pragma intrinsic( _InterlockedExchange )
# pragma intrinsic( _InterlockedExchangeAdd )
# endif
#endif
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
namespace boost
{
namespace detail
{
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * );
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * );
extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long );
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long );
extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long );
} // namespace detail
} // namespace boost
# define BOOST_SP_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement
# define BOOST_SP_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd
#else
# error "Interlocked intrinsics not available"
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED

View File

@@ -0,0 +1,48 @@
#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
#include <boost/config.hpp>
// BOOST_SP_NOEXCEPT
#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1700 && BOOST_MSVC < 1900
# define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT_OR_NOTHROW
#else
# define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT
#endif
// BOOST_SP_NOEXCEPT_WITH_ASSERT
#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) )
# define BOOST_SP_NOEXCEPT_WITH_ASSERT BOOST_SP_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 BOOST_SP_NOEXCEPT
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED

View File

@@ -0,0 +1,45 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_nullptr_t.hpp
//
// 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 <boost/config.hpp>
#include <cstddef>
#if !defined( BOOST_NO_CXX11_NULLPTR )
namespace boost
{
namespace detail
{
#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
typedef decltype(nullptr) sp_nullptr_t;
#else
typedef std::nullptr_t sp_nullptr_t;
#endif
} // namespace detail
} // namespace boost
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED

View File

@@ -0,0 +1,32 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_OBSOLETE_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_OBSOLETE_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/smart_ptr/detail/sp_obsolete.hpp
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
//
// Defines the BOOST_SP_OBSOLETE macro that emits a deprecation
// message.
#include <boost/config/pragma_message.hpp>
#if !defined( BOOST_SP_NO_OBSOLETE_MESSAGE )
#define BOOST_SP_OBSOLETE() BOOST_PRAGMA_MESSAGE("This platform-specific implementation is presumed obsolete and is slated for removal. If you want it retained, please open an issue in https://github.com/boostorg/smart_ptr.")
#else
#define BOOST_SP_OBSOLETE()
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_OBSOLETE_HPP_INCLUDED

View File

@@ -0,0 +1,51 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/smart_ptr/detail/sp_thread_pause.hpp
//
// inline void bost::detail::sp_thread_pause();
//
// Emits a "pause" instruction.
//
// Copyright 2008, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) && !defined(__c2__)
extern "C" void _mm_pause();
#define BOOST_SP_PAUSE _mm_pause();
#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
#define BOOST_SP_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
#else
#define BOOST_SP_PAUSE
#endif
namespace boost
{
namespace detail
{
inline void sp_thread_pause()
{
BOOST_SP_PAUSE
}
} // namespace detail
} // namespace boost
#undef BOOST_SP_PAUSE
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED

View File

@@ -0,0 +1,104 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/smart_ptr/detail/sp_thread_sleep.hpp
//
// inline void bost::detail::sp_thread_sleep();
//
// Cease execution for a while to yield to other threads,
// as if by calling nanosleep() with an appropriate interval.
//
// Copyright 2008, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
BOOST_PRAGMA_MESSAGE("Using Sleep(1) in sp_thread_sleep")
#endif
#include <boost/smart_ptr/detail/sp_win32_sleep.hpp>
namespace boost
{
namespace detail
{
inline void sp_thread_sleep()
{
Sleep( 1 );
}
} // namespace detail
} // namespace boost
#elif defined(BOOST_HAS_NANOSLEEP)
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
BOOST_PRAGMA_MESSAGE("Using nanosleep() in sp_thread_sleep")
#endif
#include <time.h>
namespace boost
{
namespace detail
{
inline void sp_thread_sleep()
{
// g++ -Wextra warns on {} or {0}
struct timespec rqtp = { 0, 0 };
// POSIX says that timespec has tv_sec and tv_nsec
// But it doesn't guarantee order or placement
rqtp.tv_sec = 0;
rqtp.tv_nsec = 1000;
nanosleep( &rqtp, 0 );
}
} // namespace detail
} // namespace boost
#else
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
BOOST_PRAGMA_MESSAGE("Using sp_thread_yield() in sp_thread_sleep")
#endif
#include <boost/smart_ptr/detail/sp_thread_yield.hpp>
namespace boost
{
namespace detail
{
inline void sp_thread_sleep()
{
sp_thread_yield();
}
} // namespace detail
} // namespace boost
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED

View File

@@ -0,0 +1,100 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/smart_ptr/detail/sp_thread_yield.hpp
//
// inline void bost::detail::sp_thread_yield();
//
// Gives up the remainder of the time slice,
// as if by calling sched_yield().
//
// Copyright 2008, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
BOOST_PRAGMA_MESSAGE("Using Sleep(0) in sp_thread_yield")
#endif
#include <boost/smart_ptr/detail/sp_win32_sleep.hpp>
namespace boost
{
namespace detail
{
inline void sp_thread_yield()
{
Sleep( 0 );
}
} // namespace detail
} // namespace boost
#elif defined(BOOST_HAS_SCHED_YIELD)
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
BOOST_PRAGMA_MESSAGE("Using sched_yield() in sp_thread_yield")
#endif
#ifndef _AIX
# include <sched.h>
#else
// AIX's sched.h defines ::var which sometimes conflicts with Lambda's var
extern "C" int sched_yield(void);
#endif
namespace boost
{
namespace detail
{
inline void sp_thread_yield()
{
sched_yield();
}
} // namespace detail
} // namespace boost
#else
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
BOOST_PRAGMA_MESSAGE("Using sp_thread_pause() in sp_thread_yield")
#endif
#include <boost/smart_ptr/detail/sp_thread_pause.hpp>
namespace boost
{
namespace detail
{
inline void sp_thread_yield()
{
sp_thread_pause();
}
} // namespace detail
} // namespace boost
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_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,49 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/smart_ptr/detail/sp_win32_sleep.hpp
//
// Declares the Win32 Sleep() function.
//
// Copyright 2008, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0
// https://www.boost.org/LICENSE_1_0.txt
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
#endif
namespace boost
{
namespace detail
{
#if !defined( BOOST_USE_WINDOWS_H )
#if defined(__clang__) && defined(__x86_64__)
// clang x64 warns that __stdcall is ignored
# define BOOST_SP_STDCALL
#else
# define BOOST_SP_STDCALL __stdcall
#endif
#if defined(__LP64__) // Cygwin 64
extern "C" __declspec(dllimport) void BOOST_SP_STDCALL Sleep( unsigned int ms );
#else
extern "C" __declspec(dllimport) void BOOST_SP_STDCALL Sleep( unsigned long ms );
#endif
#undef BOOST_SP_STDCALL
#endif // !defined( BOOST_USE_WINDOWS_H )
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED

View File

@@ -0,0 +1,66 @@
#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/sp_has_gcc_intrinsics.hpp>
#include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp>
#include <boost/config.hpp>
#if defined( BOOST_SP_USE_STD_ATOMIC )
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
#elif defined( BOOST_SP_USE_PTHREADS )
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
#elif defined( BOOST_SP_HAS_GCC_INTRINSICS )
# include <boost/smart_ptr/detail/spinlock_gcc_atomic.hpp>
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
# include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS )
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/spinlock_w32.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
#elif !defined(BOOST_HAS_THREADS)
# include <boost/smart_ptr/detail/spinlock_nt.hpp>
#else
# error Unrecognized threading platform
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED

View File

@@ -0,0 +1,128 @@
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
//
// Copyright (c) 2008, 2011 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>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/ARM spinlock")
#endif
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
# define BOOST_SP_ARM_BARRIER "dmb"
# define BOOST_SP_ARM_HAS_LDREX
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
# define BOOST_SP_ARM_HAS_LDREX
#else
# define BOOST_SP_ARM_BARRIER ""
#endif
namespace boost
{
namespace detail
{
class spinlock
{
public:
int v_;
public:
bool try_lock()
{
int r;
#ifdef BOOST_SP_ARM_HAS_LDREX
__asm__ __volatile__(
"ldrex %0, [%2]; \n"
"cmp %0, %1; \n"
"strexne %0, %1, [%2]; \n"
BOOST_SP_ARM_BARRIER :
"=&r"( r ): // outputs
"r"( 1 ), "r"( &v_ ): // inputs
"memory", "cc" );
#else
__asm__ __volatile__(
"swp %0, %1, [%2];\n"
BOOST_SP_ARM_BARRIER :
"=&r"( r ): // outputs
"r"( 1 ), "r"( &v_ ): // inputs
"memory", "cc" );
#endif
return r == 0;
}
void lock()
{
for( unsigned k = 0; !try_lock(); ++k )
{
boost::detail::yield( k );
}
}
void unlock()
{
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
*const_cast< int volatile* >( &v_ ) = 0;
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
}
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}
#undef BOOST_SP_ARM_BARRIER
#undef BOOST_SP_ARM_HAS_LDREX
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED

View File

@@ -0,0 +1,85 @@
#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:
unsigned char v_;
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,96 @@
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// 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)
//
#include <boost/assert.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using single-threaded spinlock emulation")
#endif
namespace boost
{
namespace detail
{
class spinlock
{
public:
bool locked_;
public:
inline bool try_lock()
{
if( locked_ )
{
return false;
}
else
{
locked_ = true;
return true;
}
}
inline void lock()
{
BOOST_ASSERT( !locked_ );
locked_ = true;
}
inline void unlock()
{
BOOST_ASSERT( locked_ );
locked_ = false;
}
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 { false }
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_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,86 @@
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// 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)
//
#include <pthread.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using pthread_mutex spinlock emulation")
#endif
namespace boost
{
namespace detail
{
class spinlock
{
public:
pthread_mutex_t v_;
public:
bool try_lock()
{
return pthread_mutex_trylock( &v_ ) == 0;
}
void lock()
{
pthread_mutex_lock( &v_ );
}
void unlock()
{
pthread_mutex_unlock( &v_ );
}
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 { PTHREAD_MUTEX_INITIALIZER }
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED

View File

@@ -0,0 +1,91 @@
#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 <boost/config.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() BOOST_NOEXCEPT
{
return !v_.test_and_set( std::memory_order_acquire );
}
void lock() BOOST_NOEXCEPT
{
for( unsigned k = 0; !try_lock(); ++k )
{
boost::detail::yield( k );
}
}
void unlock() BOOST_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 ) BOOST_NOEXCEPT: sp_( sp )
{
sp.lock();
}
~scoped_lock() /*BOOST_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,94 @@
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// 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)
//
#include <boost/smart_ptr/detail/yield_k.hpp>
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
# include <ia64intrin.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __sync spinlock")
#endif
namespace boost
{
namespace detail
{
class spinlock
{
public:
unsigned char v_;
public:
bool try_lock()
{
int r = __sync_lock_test_and_set( &v_, 1 );
return r == 0;
}
void lock()
{
for( unsigned k = 0; !try_lock(); ++k )
{
boost::detail::yield( k );
}
}
void unlock()
{
__sync_lock_release( &v_ );
}
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_SYNC_HPP_INCLUDED

View File

@@ -0,0 +1,120 @@
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// 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)
//
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
#include <boost/smart_ptr/detail/yield_k.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Win32 spinlock")
#endif
// BOOST_COMPILER_FENCE
#if defined(__INTEL_COMPILER)
#define BOOST_COMPILER_FENCE __memory_barrier();
#elif defined( _MSC_VER ) && _MSC_VER >= 1310
extern "C" void _ReadWriteBarrier();
#pragma intrinsic( _ReadWriteBarrier )
#define BOOST_COMPILER_FENCE _ReadWriteBarrier();
#elif defined(__GNUC__)
#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
#else
#define BOOST_COMPILER_FENCE
#endif
//
namespace boost
{
namespace detail
{
class spinlock
{
public:
long v_;
public:
bool try_lock()
{
long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 );
BOOST_COMPILER_FENCE
return r == 0;
}
void lock()
{
for( unsigned k = 0; !try_lock(); ++k )
{
boost::detail::yield( k );
}
}
void unlock()
{
BOOST_COMPILER_FENCE
*const_cast< long volatile* >( &v_ ) = 0;
}
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_W32_HPP_INCLUDED

View File

@@ -0,0 +1,51 @@
#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/smart_ptr/detail/sp_thread_pause.hpp>
#include <boost/smart_ptr/detail/sp_thread_sleep.hpp>
#include <boost/config.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 == 0 )
{
sp_thread_pause();
}
else
{
sp_thread_sleep();
}
}
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED

View File

@@ -0,0 +1,41 @@
#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED
#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED
// enable_shared_from.hpp
//
// Copyright 2019, 2020 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/enable_shared_from_this.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
namespace boost
{
class enable_shared_from: public enable_shared_from_this<enable_shared_from>
{
private:
using enable_shared_from_this<enable_shared_from>::shared_from_this;
using enable_shared_from_this<enable_shared_from>::weak_from_this;
};
template<class T> shared_ptr<T> shared_from( T * p )
{
return shared_ptr<T>( p->enable_shared_from_this<enable_shared_from>::shared_from_this(), p );
}
template<class T> weak_ptr<T> weak_from( T * p ) BOOST_SP_NOEXCEPT
{
return weak_ptr<T>( p->enable_shared_from_this<enable_shared_from>::weak_from_this(), p );
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED

View File

@@ -0,0 +1,164 @@
#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
//
// enable_shared_from_raw.hpp
//
// Copyright 2002, 2009, 2014 Peter Dimov
// Copyright 2008-2009 Frank Mori Hess
//
// 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 <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/assert.hpp>
#include <boost/config/workaround.hpp>
namespace boost
{
template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
template<typename T> boost::weak_ptr<T> weak_from_raw(T *);
namespace detail
{
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
} // namespace detail
class enable_shared_from_raw
{
protected:
enable_shared_from_raw()
{
}
enable_shared_from_raw( enable_shared_from_raw const & )
{
}
enable_shared_from_raw & operator=( enable_shared_from_raw const & )
{
return *this;
}
~enable_shared_from_raw()
{
BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
}
private:
void init_if_expired() const
{
if( weak_this_.expired() )
{
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
weak_this_ = shared_this_;
}
}
void init_if_empty() const
{
if( weak_this_._empty() )
{
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
weak_this_ = shared_this_;
}
}
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
private:
template<class Y> friend class shared_ptr;
template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
template<typename T> friend boost::weak_ptr<T> weak_from_raw(T *);
template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
#endif
shared_ptr<void const volatile> shared_from_this() const
{
init_if_expired();
return shared_ptr<void const volatile>( weak_this_ );
}
shared_ptr<void const volatile> shared_from_this() const volatile
{
return const_cast< enable_shared_from_raw const * >( this )->shared_from_this();
}
weak_ptr<void const volatile> weak_from_this() const
{
init_if_empty();
return weak_this_;
}
weak_ptr<void const volatile> weak_from_this() const volatile
{
return const_cast< enable_shared_from_raw const * >( this )->weak_from_this();
}
// Note: invoked automatically by shared_ptr; do not call
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * ) const
{
BOOST_ASSERT( ppx != 0 );
if( weak_this_.expired() )
{
weak_this_ = *ppx;
}
else if( shared_this_.use_count() != 0 )
{
BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
BOOST_ASSERT( pd != 0 );
pd->set_deleter( *ppx );
ppx->reset( shared_this_, ppx->get() );
shared_this_.reset();
}
}
mutable weak_ptr<void const volatile> weak_this_;
private:
mutable shared_ptr<void const volatile> shared_this_;
};
template<typename T>
boost::shared_ptr<T> shared_from_raw(T *p)
{
BOOST_ASSERT(p != 0);
return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
}
template<typename T>
boost::weak_ptr<T> weak_from_raw(T *p)
{
BOOST_ASSERT(p != 0);
boost::weak_ptr<T> result(p->enable_shared_from_raw::weak_from_this(), p);
return result;
}
namespace detail
{
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe )
{
if( pe != 0 )
{
pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
}
}
} // namepsace detail
} // namespace boost
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED

View File

@@ -0,0 +1,90 @@
#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
//
// enable_shared_from_this.hpp
//
// Copyright 2002, 2009 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/weak_ptr.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
namespace boost
{
template<class T> class enable_shared_from_this
{
protected:
BOOST_CONSTEXPR enable_shared_from_this() BOOST_SP_NOEXCEPT
{
}
BOOST_CONSTEXPR enable_shared_from_this(enable_shared_from_this const &) BOOST_SP_NOEXCEPT
{
}
enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_SP_NOEXCEPT
{
return *this;
}
~enable_shared_from_this() BOOST_SP_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
{
}
public:
shared_ptr<T> shared_from_this()
{
shared_ptr<T> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
shared_ptr<T const> shared_from_this() const
{
shared_ptr<T const> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
weak_ptr<T> weak_from_this() BOOST_SP_NOEXCEPT
{
return weak_this_;
}
weak_ptr<T const> weak_from_this() const BOOST_SP_NOEXCEPT
{
return weak_this_;
}
public: // actually private, but avoids compiler template friendship issues
// Note: invoked automatically by shared_ptr; do not call
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const BOOST_SP_NOEXCEPT
{
if( weak_this_.expired() )
{
weak_this_ = shared_ptr<T>( *ppx, py );
}
}
private:
mutable weak_ptr<T> weak_this_;
};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED

View File

@@ -0,0 +1,407 @@
#ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
//
// intrusive_ptr.hpp
//
// Copyright (c) 2001, 2002 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/config.hpp>
#include <boost/assert.hpp>
#include <boost/config/workaround.hpp>
#include <boost/smart_ptr/detail/sp_convertible.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config/no_tr1/functional.hpp> // for std::less
#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
#include <iosfwd> // for std::basic_ostream
#else
#include <ostream>
#endif
#endif
namespace boost
{
//
// intrusive_ptr
//
// A smart pointer that uses intrusive reference counting.
//
// Relies on unqualified calls to
//
// void intrusive_ptr_add_ref(T * p);
// void intrusive_ptr_release(T * p);
//
// (p != 0)
//
// The object is responsible for destroying itself.
//
template<class T> class intrusive_ptr
{
private:
typedef intrusive_ptr this_type;
public:
typedef T element_type;
BOOST_CONSTEXPR intrusive_ptr() BOOST_SP_NOEXCEPT : px( 0 )
{
}
intrusive_ptr( T * p, bool add_ref = true ): px( p )
{
if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template<class U>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
#else
intrusive_ptr( intrusive_ptr<U> const & rhs )
#endif
: px( rhs.get() )
{
if( px != 0 ) intrusive_ptr_add_ref( px );
}
#endif
intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
{
if( px != 0 ) intrusive_ptr_add_ref( px );
}
~intrusive_ptr()
{
if( px != 0 ) intrusive_ptr_release( px );
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
#endif
// Move support
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
intrusive_ptr(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT : px( rhs.px )
{
rhs.px = 0;
}
intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT
{
this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
return *this;
}
template<class U> friend class intrusive_ptr;
template<class U>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
intrusive_ptr(intrusive_ptr<U> && rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty())
#else
intrusive_ptr(intrusive_ptr<U> && rhs)
#endif
: px( rhs.px )
{
rhs.px = 0;
}
template<class U>
intrusive_ptr & operator=(intrusive_ptr<U> && rhs) BOOST_SP_NOEXCEPT
{
this_type( static_cast< intrusive_ptr<U> && >( rhs ) ).swap(*this);
return *this;
}
#endif
intrusive_ptr & operator=(intrusive_ptr const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
intrusive_ptr & operator=(T * rhs)
{
this_type(rhs).swap(*this);
return *this;
}
void reset()
{
this_type().swap( *this );
}
void reset( T * rhs )
{
this_type( rhs ).swap( *this );
}
void reset( T * rhs, bool add_ref )
{
this_type( rhs, add_ref ).swap( *this );
}
T * get() const BOOST_SP_NOEXCEPT
{
return px;
}
T * detach() BOOST_SP_NOEXCEPT
{
T * ret = px;
px = 0;
return ret;
}
T & operator*() const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return *px;
}
T * operator->() const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
void swap(intrusive_ptr & rhs) BOOST_SP_NOEXCEPT
{
T * tmp = px;
px = rhs.px;
rhs.px = tmp;
}
private:
T * px;
};
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b) BOOST_SP_NOEXCEPT
{
return a.get() == b;
}
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b) BOOST_SP_NOEXCEPT
{
return a.get() != b;
}
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a == b.get();
}
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a != b.get();
}
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
// Resolve the ambiguity between our op!= and the one in rel_ops
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
#endif
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
#endif
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) BOOST_SP_NOEXCEPT
{
return std::less<T *>()(a.get(), b.get());
}
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) BOOST_SP_NOEXCEPT
{
lhs.swap(rhs);
}
// mem_fn support
template<class T> T * get_pointer(intrusive_ptr<T> const & p) BOOST_SP_NOEXCEPT
{
return p.get();
}
// pointer casts
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
{
return static_cast<T *>(p.get());
}
template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
{
return const_cast<T *>(p.get());
}
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
{
return dynamic_cast<T *>(p.get());
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class T, class U> intrusive_ptr<T> static_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
{
return intrusive_ptr<T>( static_cast<T*>( p.detach() ), false );
}
template<class T, class U> intrusive_ptr<T> const_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
{
return intrusive_ptr<T>( const_cast<T*>( p.detach() ), false );
}
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
{
T * p2 = dynamic_cast<T*>( p.get() );
intrusive_ptr<T> r( p2, false );
if( p2 ) p.detach();
return r;
}
#endif // defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// operator<<
#if !defined(BOOST_NO_IOSTREAM)
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
{
os << p.get();
return os;
}
#else
// in STLport's no-iostreams mode no iostream symbols can be used
#ifndef _STLP_NO_IOSTREAMS
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
using std::basic_ostream;
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
# else
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
# endif
{
os << p.get();
return os;
}
#endif // _STLP_NO_IOSTREAMS
#endif // __GNUC__ < 3
#endif // !defined(BOOST_NO_IOSTREAM)
// hash_value
template< class T > struct hash;
template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return boost::hash< T* >()( p.get() );
}
} // namespace boost
// std::hash
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
namespace std
{
template<class T> struct hash< ::boost::intrusive_ptr<T> >
{
std::size_t operator()( ::boost::intrusive_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return std::hash< T* >()( p.get() );
}
};
} // namespace std
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,188 @@
/*
* Copyright Andrey Semashev 2007 - 2013.
* 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)
*/
/*!
* \file intrusive_ref_counter.hpp
* \author Andrey Semashev
* \date 12.03.2009
*
* This header contains a reference counter class for \c intrusive_ptr.
*/
#ifndef BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
#define BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(_MSC_VER)
#pragma warning(push)
// This is a bogus MSVC warning, which is flagged by friend declarations of intrusive_ptr_add_ref and intrusive_ptr_release in intrusive_ref_counter:
// 'name' : the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
// Note that there is no inline specifier in the declarations.
#pragma warning(disable: 4396)
#endif
namespace boost {
namespace sp_adl_block {
/*!
* \brief Thread unsafe reference counter policy for \c intrusive_ref_counter
*
* The policy instructs the \c intrusive_ref_counter base class to implement
* a reference counter suitable for single threaded use only. Pointers to the same
* object with this kind of reference counter must not be used by different threads.
*/
struct thread_unsafe_counter
{
typedef unsigned int type;
static unsigned int load(unsigned int const& counter) BOOST_SP_NOEXCEPT
{
return counter;
}
static void increment(unsigned int& counter) BOOST_SP_NOEXCEPT
{
++counter;
}
static unsigned int decrement(unsigned int& counter) BOOST_SP_NOEXCEPT
{
return --counter;
}
};
/*!
* \brief Thread safe reference counter policy for \c intrusive_ref_counter
*
* The policy instructs the \c intrusive_ref_counter base class to implement
* a thread-safe reference counter, if the target platform supports multithreading.
*/
struct thread_safe_counter
{
typedef boost::detail::atomic_count type;
static unsigned int load(boost::detail::atomic_count const& counter) BOOST_SP_NOEXCEPT
{
return static_cast< unsigned int >(static_cast< long >(counter));
}
static void increment(boost::detail::atomic_count& counter) BOOST_SP_NOEXCEPT
{
++counter;
}
static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_SP_NOEXCEPT
{
return static_cast< unsigned int >(--counter);
}
};
template< typename DerivedT, typename CounterPolicyT = thread_safe_counter >
class intrusive_ref_counter;
template< typename DerivedT, typename CounterPolicyT >
void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT;
template< typename DerivedT, typename CounterPolicyT >
void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT;
/*!
* \brief A reference counter base class
*
* This base class can be used with user-defined classes to add support
* for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT.
* Upon releasing the last \c intrusive_ptr referencing the object
* derived from the \c intrusive_ref_counter class, operator \c delete
* is automatically called on the pointer to the object.
*
* The other template parameter, \c DerivedT, is the user's class that derives from \c intrusive_ref_counter.
*/
template< typename DerivedT, typename CounterPolicyT >
class intrusive_ref_counter
{
private:
//! Reference counter type
typedef typename CounterPolicyT::type counter_type;
//! Reference counter
mutable counter_type m_ref_counter;
public:
/*!
* Default constructor
*
* \post <tt>use_count() == 0</tt>
*/
intrusive_ref_counter() BOOST_SP_NOEXCEPT : m_ref_counter(0)
{
}
/*!
* Copy constructor
*
* \post <tt>use_count() == 0</tt>
*/
intrusive_ref_counter(intrusive_ref_counter const&) BOOST_SP_NOEXCEPT : m_ref_counter(0)
{
}
/*!
* Assignment
*
* \post The reference counter is not modified after assignment
*/
intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_SP_NOEXCEPT { return *this; }
/*!
* \return The reference counter
*/
unsigned int use_count() const BOOST_SP_NOEXCEPT
{
return CounterPolicyT::load(m_ref_counter);
}
protected:
/*!
* Destructor
*/
BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})
friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT;
friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT;
};
template< typename DerivedT, typename CounterPolicyT >
inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT
{
CounterPolicyT::increment(p->m_ref_counter);
}
template< typename DerivedT, typename CounterPolicyT >
inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT
{
if (CounterPolicyT::decrement(p->m_ref_counter) == 0)
delete static_cast< const DerivedT* >(p);
}
} // namespace sp_adl_block
using sp_adl_block::intrusive_ref_counter;
using sp_adl_block::thread_unsafe_counter;
using sp_adl_block::thread_safe_counter;
} // namespace boost
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_

View File

@@ -0,0 +1,710 @@
#ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
// local_shared_ptr.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/shared_ptr.hpp>
namespace boost
{
template<class T> class local_shared_ptr;
namespace detail
{
template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
{
boost::detail::sp_assert_convertible< Y, E >();
typedef boost::detail::local_sp_deleter< boost::checked_deleter<Y> > D;
boost::shared_ptr<E> p2( p, D() );
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2._internal_count();
pn = pd;
}
template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
{
boost::detail::sp_assert_convertible< Y[], E[] >();
typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
boost::shared_ptr<E[]> p2( p, D() );
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2._internal_count();
pn = pd;
}
template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[N] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
{
boost::detail::sp_assert_convertible< Y[N], E[N] >();
typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
boost::shared_ptr<E[N]> p2( p, D() );
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2._internal_count();
pn = pd;
}
template< class E, class P, class D > inline void lsp_deleter_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, boost::detail::local_counted_base * & pn )
{
typedef boost::detail::local_sp_deleter<D> D2;
boost::shared_ptr<E> p2( p, D2( d ) );
D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2._internal_count();
pn = pd;
}
template< class E, class P, class D, class A > inline void lsp_allocator_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, A const& a, boost::detail::local_counted_base * & pn )
{
typedef boost::detail::local_sp_deleter<D> D2;
boost::shared_ptr<E> p2( p, D2( d ), a );
D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2._internal_count();
pn = pd;
}
struct lsp_internal_constructor_tag
{
};
} // namespace detail
//
// local_shared_ptr
//
// as shared_ptr, but local to a thread.
// reference count manipulations are non-atomic.
//
template<class T> class local_shared_ptr
{
private:
typedef local_shared_ptr this_type;
public:
typedef typename boost::detail::sp_element<T>::type element_type;
private:
element_type * px;
boost::detail::local_counted_base * pn;
template<class Y> friend class local_shared_ptr;
public:
// destructor
~local_shared_ptr() BOOST_SP_NOEXCEPT
{
if( pn )
{
pn->release();
}
}
// constructors
BOOST_CONSTEXPR local_shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn( 0 )
{
}
#if !defined( BOOST_NO_CXX11_NULLPTR )
BOOST_CONSTEXPR local_shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn( 0 )
{
}
#endif
// internal constructor, used by make_shared
BOOST_CONSTEXPR local_shared_ptr( boost::detail::lsp_internal_constructor_tag, element_type * px_, boost::detail::local_counted_base * pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( pn_ )
{
}
template<class Y>
explicit local_shared_ptr( Y * p ): px( p ), pn( 0 )
{
boost::detail::lsp_pointer_construct( this, p, pn );
}
template<class Y, class D> local_shared_ptr( Y * p, D d ): px( p ), pn( 0 )
{
boost::detail::lsp_deleter_construct( this, p, d, pn );
}
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class D> local_shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( 0 )
{
boost::detail::lsp_deleter_construct( this, p, d, pn );
}
#endif
template<class Y, class D, class A> local_shared_ptr( Y * p, D d, A a ): px( p ), pn( 0 )
{
boost::detail::lsp_allocator_construct( this, p, d, a, pn );
}
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class D, class A> local_shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( 0 )
{
boost::detail::lsp_allocator_construct( this, p, d, a, pn );
}
#endif
// construction from shared_ptr
template<class Y> local_shared_ptr( shared_ptr<Y> const & r,
typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
: px( r.get() ), pn( 0 )
{
boost::detail::sp_assert_convertible< Y, T >();
if( r.use_count() != 0 )
{
pn = new boost::detail::local_counted_impl( r._internal_count() );
}
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y> local_shared_ptr( shared_ptr<Y> && r,
typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
: px( r.get() ), pn( 0 )
{
boost::detail::sp_assert_convertible< Y, T >();
if( r.use_count() != 0 )
{
pn = new boost::detail::local_counted_impl( r._internal_count() );
r.reset();
}
}
#endif
// construction from unique_ptr
#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template< class Y, class D >
local_shared_ptr( std::unique_ptr< Y, D > && r,
typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
: px( r.get() ), pn( 0 )
{
boost::detail::sp_assert_convertible< Y, T >();
if( px )
{
pn = new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) )._internal_count() );
}
}
#endif
template< class Y, class D >
local_shared_ptr( boost::movelib::unique_ptr< Y, D > r ); // !
// : px( r.get() ), pn( new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) ) ) )
//{
// boost::detail::sp_assert_convertible< Y, T >();
//}
// copy constructor
local_shared_ptr( local_shared_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
{
if( pn )
{
pn->add_ref();
}
}
// move constructor
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
local_shared_ptr( local_shared_ptr && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
{
r.px = 0;
r.pn = 0;
}
#endif
// converting copy constructor
template<class Y> local_shared_ptr( local_shared_ptr<Y> const & r,
typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() ) BOOST_SP_NOEXCEPT
: px( r.px ), pn( r.pn )
{
boost::detail::sp_assert_convertible< Y, T >();
if( pn )
{
pn->add_ref();
}
}
// converting move constructor
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y> local_shared_ptr( local_shared_ptr<Y> && r,
typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() ) BOOST_SP_NOEXCEPT
: px( r.px ), pn( r.pn )
{
boost::detail::sp_assert_convertible< Y, T >();
r.px = 0;
r.pn = 0;
}
#endif
// aliasing
template<class Y>
local_shared_ptr( local_shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
{
if( pn )
{
pn->add_ref();
}
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y>
local_shared_ptr( local_shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
{
r.px = 0;
r.pn = 0;
}
#endif
// assignment
local_shared_ptr & operator=( local_shared_ptr const & r ) BOOST_SP_NOEXCEPT
{
local_shared_ptr( r ).swap( *this );
return *this;
}
template<class Y> local_shared_ptr & operator=( local_shared_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
{
local_shared_ptr( r ).swap( *this );
return *this;
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
local_shared_ptr & operator=( local_shared_ptr && r ) BOOST_SP_NOEXCEPT
{
local_shared_ptr( std::move( r ) ).swap( *this );
return *this;
}
template<class Y>
local_shared_ptr & operator=( local_shared_ptr<Y> && r ) BOOST_SP_NOEXCEPT
{
local_shared_ptr( std::move( r ) ).swap( *this );
return *this;
}
#endif
#if !defined( BOOST_NO_CXX11_NULLPTR )
local_shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
local_shared_ptr().swap(*this);
return *this;
}
#endif
#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y, class D>
local_shared_ptr & operator=( std::unique_ptr<Y, D> && r )
{
local_shared_ptr( std::move(r) ).swap( *this );
return *this;
}
#endif
template<class Y, class D>
local_shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r ); // !
// reset
void reset() BOOST_SP_NOEXCEPT
{
local_shared_ptr().swap( *this );
}
template<class Y> void reset( Y * p ) // Y must be complete
{
local_shared_ptr( p ).swap( *this );
}
template<class Y, class D> void reset( Y * p, D d )
{
local_shared_ptr( p, d ).swap( *this );
}
template<class Y, class D, class A> void reset( Y * p, D d, A a )
{
local_shared_ptr( p, d, a ).swap( *this );
}
template<class Y> void reset( local_shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT
{
local_shared_ptr( r, p ).swap( *this );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y> void reset( local_shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT
{
local_shared_ptr( std::move( r ), p ).swap( *this );
}
#endif
// accessors
typename boost::detail::sp_dereference< T >::type operator* () const BOOST_SP_NOEXCEPT
{
return *px;
}
typename boost::detail::sp_member_access< T >::type operator-> () const BOOST_SP_NOEXCEPT
{
return px;
}
typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
}
element_type * get() const BOOST_SP_NOEXCEPT
{
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
long local_use_count() const BOOST_SP_NOEXCEPT
{
return pn? pn->local_use_count(): 0;
}
// conversions to shared_ptr, weak_ptr
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
template<class Y, class E = typename boost::detail::sp_enable_if_convertible<T,Y>::type> operator shared_ptr<Y>() const BOOST_SP_NOEXCEPT
#else
template<class Y> operator shared_ptr<Y>() const BOOST_SP_NOEXCEPT
#endif
{
boost::detail::sp_assert_convertible<T, Y>();
if( pn )
{
return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
}
else
{
return shared_ptr<Y>();
}
}
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
template<class Y, class E = typename boost::detail::sp_enable_if_convertible<T,Y>::type> operator weak_ptr<Y>() const BOOST_SP_NOEXCEPT
#else
template<class Y> operator weak_ptr<Y>() const BOOST_SP_NOEXCEPT
#endif
{
boost::detail::sp_assert_convertible<T, Y>();
if( pn )
{
return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
}
else
{
return weak_ptr<Y>();
}
}
// swap
void swap( local_shared_ptr & r ) BOOST_SP_NOEXCEPT
{
std::swap( px, r.px );
std::swap( pn, r.pn );
}
// owner_before
template<class Y> bool owner_before( local_shared_ptr<Y> const & r ) const BOOST_SP_NOEXCEPT
{
return std::less< boost::detail::local_counted_base* >()( pn, r.pn );
}
// owner_equals
template<class Y> bool owner_equals( local_shared_ptr<Y> const & r ) const BOOST_SP_NOEXCEPT
{
return pn == r.pn;
}
};
template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class T> inline bool operator==( local_shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( local_shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
#endif
template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=( local_shared_ptr<T> const & a, shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
template<class T, class U> inline bool operator==( shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=( shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
template<class T, class U> inline bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a.owner_before( b );
}
template<class T> inline void swap( local_shared_ptr<T> & a, local_shared_ptr<T> & b ) BOOST_SP_NOEXCEPT
{
a.swap( b );
}
template<class T, class U> local_shared_ptr<T> static_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
{
(void) static_cast< T* >( static_cast< U* >( 0 ) );
typedef typename local_shared_ptr<T>::element_type E;
E * p = static_cast< E* >( r.get() );
return local_shared_ptr<T>( r, p );
}
template<class T, class U> local_shared_ptr<T> const_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
{
(void) const_cast< T* >( static_cast< U* >( 0 ) );
typedef typename local_shared_ptr<T>::element_type E;
E * p = const_cast< E* >( r.get() );
return local_shared_ptr<T>( r, p );
}
template<class T, class U> local_shared_ptr<T> dynamic_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
{
(void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
typedef typename local_shared_ptr<T>::element_type E;
E * p = dynamic_cast< E* >( r.get() );
return p? local_shared_ptr<T>( r, p ): local_shared_ptr<T>();
}
template<class T, class U> local_shared_ptr<T> reinterpret_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
{
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
typedef typename local_shared_ptr<T>::element_type E;
E * p = reinterpret_cast< E* >( r.get() );
return local_shared_ptr<T>( r, p );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class T, class U> local_shared_ptr<T> static_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) static_cast< T* >( static_cast< U* >( 0 ) );
typedef typename local_shared_ptr<T>::element_type E;
E * p = static_cast< E* >( r.get() );
return local_shared_ptr<T>( std::move(r), p );
}
template<class T, class U> local_shared_ptr<T> const_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) const_cast< T* >( static_cast< U* >( 0 ) );
typedef typename local_shared_ptr<T>::element_type E;
E * p = const_cast< E* >( r.get() );
return local_shared_ptr<T>( std::move(r), p );
}
template<class T, class U> local_shared_ptr<T> dynamic_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
typedef typename local_shared_ptr<T>::element_type E;
E * p = dynamic_cast< E* >( r.get() );
return p? local_shared_ptr<T>( std::move(r), p ): local_shared_ptr<T>();
}
template<class T, class U> local_shared_ptr<T> reinterpret_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
typedef typename local_shared_ptr<T>::element_type E;
E * p = reinterpret_cast< E* >( r.get() );
return local_shared_ptr<T>( std::move(r), p );
}
#endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// get_pointer() enables boost::mem_fn to recognize local_shared_ptr
template<class T> inline typename local_shared_ptr<T>::element_type * get_pointer( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get();
}
// operator<<
#if !defined(BOOST_NO_IOSTREAM)
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< ( std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p )
{
os << p.get();
return os;
}
#endif // !defined(BOOST_NO_IOSTREAM)
// get_deleter
template<class D, class T> D * get_deleter( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return get_deleter<D>( shared_ptr<T>( p ) );
}
// hash_value
template< class T > struct hash;
template< class T > std::size_t hash_value( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return boost::hash< typename local_shared_ptr<T>::element_type* >()( p.get() );
}
} // namespace boost
// std::hash
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
namespace std
{
template<class T> struct hash< ::boost::local_shared_ptr<T> >
{
std::size_t operator()( ::boost::local_shared_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return std::hash< typename ::boost::local_shared_ptr<T>::element_type* >()( p.get() );
}
};
} // namespace std
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#endif // #ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,17 @@
#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_HPP_INCLUDED
#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_HPP_INCLUDED
// make_local_shared.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/make_local_shared_object.hpp>
#include <boost/smart_ptr/make_local_shared_array.hpp>
#endif // #ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_HPP_INCLUDED

View File

@@ -0,0 +1,74 @@
/*
Copyright 2017 Peter Dimov
Copyright 2017-2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP
#include <boost/core/default_allocator.hpp>
#include <boost/smart_ptr/allocate_local_shared_array.hpp>
namespace boost {
template<class T>
inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared()
{
return boost::allocate_local_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>());
}
template<class T>
inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared(const typename remove_extent<T>::type& value)
{
return boost::allocate_local_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), value);
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared(std::size_t size)
{
return boost::allocate_local_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size);
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared(std::size_t size,
const typename remove_extent<T>::type& value)
{
return boost::allocate_local_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size, value);
}
template<class T>
inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared_noinit()
{
return boost::allocate_local_shared_noinit<T>(boost::
default_allocator<typename detail::sp_array_element<T>::type>());
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared_noinit(std::size_t size)
{
return boost::allocate_local_shared_noinit<T>(boost::
default_allocator<typename detail::sp_array_element<T>::type>(), size);
}
} /* boost */
#endif

View File

@@ -0,0 +1,202 @@
#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_OBJECT_HPP_INCLUDED
#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_OBJECT_HPP_INCLUDED
// make_local_shared_object.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/local_shared_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/config.hpp>
#include <utility>
#include <cstddef>
namespace boost
{
namespace detail
{
// lsp_if_not_array
template<class T> struct lsp_if_not_array
{
typedef boost::local_shared_ptr<T> type;
};
template<class T> struct lsp_if_not_array<T[]>
{
};
template<class T, std::size_t N> struct lsp_if_not_array<T[N]>
{
};
// lsp_ms_deleter
template<class T, class A> class lsp_ms_deleter: public local_counted_impl_em
{
private:
typedef typename sp_aligned_storage<sizeof(T), ::boost::alignment_of<T>::value>::type storage_type;
storage_type storage_;
A a_;
bool initialized_;
private:
void destroy() BOOST_SP_NOEXCEPT
{
if( initialized_ )
{
T * p = reinterpret_cast< T* >( storage_.data_ );
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A>::destroy( a_, p );
#else
p->~T();
#endif
initialized_ = false;
}
}
public:
explicit lsp_ms_deleter( A const & a ) BOOST_SP_NOEXCEPT : a_( a ), initialized_( false )
{
}
// optimization: do not copy storage_
lsp_ms_deleter( lsp_ms_deleter const & r ) BOOST_SP_NOEXCEPT : a_( r.a_), initialized_( false )
{
}
~lsp_ms_deleter() BOOST_SP_NOEXCEPT
{
destroy();
}
void operator()( T * ) BOOST_SP_NOEXCEPT
{
destroy();
}
static void operator_fn( T* ) BOOST_SP_NOEXCEPT // operator() can't be static
{
}
void * address() BOOST_SP_NOEXCEPT
{
return storage_.data_;
}
void set_initialized() BOOST_SP_NOEXCEPT
{
initialized_ = true;
}
};
} // namespace detail
template<class T, class A, class... Args> typename boost::detail::lsp_if_not_array<T>::type allocate_local_shared( A const & a, Args&&... args )
{
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc<T> A2;
#else
typedef typename A::template rebind<T>::other A2;
#endif
A2 a2( a );
typedef boost::detail::lsp_ms_deleter<T, A2> D;
boost::shared_ptr<T> pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a2 );
D * pd = static_cast< D* >( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A2>::construct( a2, static_cast< T* >( pv ), std::forward<Args>( args )... );
#else
::new( pv ) T( std::forward<Args>( args )... );
#endif
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
pd->pn_ = pt._internal_count();
return boost::local_shared_ptr<T>( boost::detail::lsp_internal_constructor_tag(), pt2, pd );
}
template<class T, class A> typename boost::detail::lsp_if_not_array<T>::type allocate_local_shared_noinit( A const & a )
{
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc<T> A2;
#else
typedef typename A::template rebind<T>::other A2;
#endif
A2 a2( a );
typedef boost::detail::lsp_ms_deleter< T, std::allocator<T> > D;
boost::shared_ptr<T> pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a2 );
D * pd = static_cast< D* >( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T;
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
pd->pn_ = pt._internal_count();
return boost::local_shared_ptr<T>( boost::detail::lsp_internal_constructor_tag(), pt2, pd );
}
template<class T, class... Args> typename boost::detail::lsp_if_not_array<T>::type make_local_shared( Args&&... args )
{
typedef typename boost::remove_const<T>::type T2;
return boost::allocate_local_shared<T2>( std::allocator<T2>(), std::forward<Args>(args)... );
}
template<class T> typename boost::detail::lsp_if_not_array<T>::type make_local_shared_noinit()
{
typedef typename boost::remove_const<T>::type T2;
return boost::allocate_shared_noinit<T2>( std::allocator<T2>() );
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED

View File

@@ -0,0 +1,21 @@
#ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
#define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
// make_shared.hpp
//
// Copyright (c) 2007, 2008, 2012 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/make_shared_object.hpp>
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE )
# include <boost/smart_ptr/make_shared_array.hpp>
# include <boost/smart_ptr/allocate_shared_array.hpp>
#endif
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED

View File

@@ -0,0 +1,66 @@
/*
Copyright 2012-2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
#include <boost/core/default_allocator.hpp>
#include <boost/smart_ptr/allocate_shared_array.hpp>
namespace boost {
template<class T>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared()
{
return boost::allocate_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>());
}
template<class T>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared(const typename remove_extent<T>::type& value)
{
return boost::allocate_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), value);
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
make_shared(std::size_t size)
{
return boost::allocate_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size);
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
make_shared(std::size_t size, const typename remove_extent<T>::type& value)
{
return boost::allocate_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size, value);
}
template<class T>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared_noinit()
{
return boost::allocate_shared_noinit<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>());
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
make_shared_noinit(std::size_t size)
{
return boost::allocate_shared_noinit<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size);
}
} /* boost */
#endif

View File

@@ -0,0 +1,801 @@
#ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED
#define BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED
// make_shared_object.hpp
//
// Copyright (c) 2007, 2008, 2012 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/config.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/detail/sp_forward.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <cstddef>
#include <new>
namespace boost
{
namespace detail
{
template< std::size_t N, std::size_t A > struct sp_aligned_storage
{
union type
{
char data_[ N ];
typename boost::type_with_alignment< A >::type align_;
};
};
template< class T > class sp_ms_deleter
{
private:
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
bool initialized_;
storage_type storage_;
private:
void destroy() BOOST_SP_NOEXCEPT
{
if( initialized_ )
{
#if defined( __GNUC__ )
// fixes incorrect aliasing warning
T * p = reinterpret_cast< T* >( storage_.data_ );
p->~T();
#else
reinterpret_cast< T* >( storage_.data_ )->~T();
#endif
initialized_ = false;
}
}
public:
sp_ms_deleter() BOOST_SP_NOEXCEPT : initialized_( false )
{
}
template<class A> explicit sp_ms_deleter( A const & ) BOOST_SP_NOEXCEPT : initialized_( false )
{
}
// optimization: do not copy storage_
sp_ms_deleter( sp_ms_deleter const & ) BOOST_SP_NOEXCEPT : initialized_( false )
{
}
~sp_ms_deleter() BOOST_SP_NOEXCEPT
{
destroy();
}
void operator()( T * ) BOOST_SP_NOEXCEPT
{
destroy();
}
static void operator_fn( T* ) BOOST_SP_NOEXCEPT // operator() can't be static
{
}
void * address() BOOST_SP_NOEXCEPT
{
return storage_.data_;
}
void set_initialized() BOOST_SP_NOEXCEPT
{
initialized_ = true;
}
};
template< class T, class A > class sp_as_deleter
{
private:
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
storage_type storage_;
A a_;
bool initialized_;
private:
void destroy() BOOST_SP_NOEXCEPT
{
if( initialized_ )
{
T * p = reinterpret_cast< T* >( storage_.data_ );
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A>::destroy( a_, p );
#else
p->~T();
#endif
initialized_ = false;
}
}
public:
sp_as_deleter( A const & a ) BOOST_SP_NOEXCEPT : a_( a ), initialized_( false )
{
}
// optimization: do not copy storage_
sp_as_deleter( sp_as_deleter const & r ) BOOST_SP_NOEXCEPT : a_( r.a_), initialized_( false )
{
}
~sp_as_deleter() BOOST_SP_NOEXCEPT
{
destroy();
}
void operator()( T * ) BOOST_SP_NOEXCEPT
{
destroy();
}
static void operator_fn( T* ) BOOST_SP_NOEXCEPT // operator() can't be static
{
}
void * address() BOOST_SP_NOEXCEPT
{
return storage_.data_;
}
void set_initialized() BOOST_SP_NOEXCEPT
{
initialized_ = true;
}
};
template< class T > struct sp_if_not_array
{
typedef boost::shared_ptr< T > type;
};
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template< class T > struct sp_if_not_array< T[] >
{
};
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_if_not_array< T[N] >
{
};
#endif
#endif
} // namespace detail
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
# define BOOST_SP_MSD( T ) boost::detail::sp_inplace_tag< boost::detail::sp_ms_deleter< T > >()
#else
# define BOOST_SP_MSD( T ) boost::detail::sp_ms_deleter< T >()
#endif
// _noinit versions
template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared_noinit()
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T;
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared_noinit( A const & a )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T;
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// Variadic templates, rvalue reference
template< class T, class... Args > typename boost::detail::sp_if_not_array< T >::type make_shared( Args && ... args )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class... Args > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, Args && ... args )
{
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc<T> A2;
A2 a2( a );
typedef boost::detail::sp_as_deleter< T, A2 > D;
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a2 );
#else
typedef boost::detail::sp_ms_deleter< T > D;
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a );
#endif
D * pd = static_cast< D* >( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A2>::construct( a2, static_cast< T* >( pv ), boost::detail::sp_forward<Args>( args )... );
#else
::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
#endif
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
#else // !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// Common zero-argument versions
template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared()
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T();
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T();
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
// C++03 version
template< class T, class A1 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class A1 >
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A1, class A2 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class A1, class A2 >
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A1, class A2, class A3 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class A1, class A2, class A3 >
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A1, class A2, class A3, class A4 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class A1, class A2, class A3, class A4 >
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A1, class A2, class A3, class A4, class A5 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 ),
boost::forward<A6>( a6 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 ),
boost::forward<A6>( a6 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 ),
boost::forward<A6>( a6 ),
boost::forward<A7>( a7 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 ),
boost::forward<A6>( a6 ),
boost::forward<A7>( a7 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 ),
boost::forward<A6>( a6 ),
boost::forward<A7>( a7 ),
boost::forward<A8>( a8 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 ),
boost::forward<A6>( a6 ),
boost::forward<A7>( a7 ),
boost::forward<A8>( a8 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8, BOOST_FWD_REF(A9) a9 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 ),
boost::forward<A6>( a6 ),
boost::forward<A7>( a7 ),
boost::forward<A8>( a8 ),
boost::forward<A9>( a9 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8, BOOST_FWD_REF(A9) a9 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
::new( pv ) T(
boost::forward<A1>( a1 ),
boost::forward<A2>( a2 ),
boost::forward<A3>( a3 ),
boost::forward<A4>( a4 ),
boost::forward<A5>( a5 ),
boost::forward<A6>( a6 ),
boost::forward<A7>( a7 ),
boost::forward<A8>( a8 ),
boost::forward<A9>( a9 )
);
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
#endif // !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
#undef BOOST_SP_MSD
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED

View File

@@ -0,0 +1,69 @@
/*
Copyright 2012-2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_unbounded_array.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <memory>
#include <utility>
namespace boost {
template<class T>
inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
make_unique()
{
return std::unique_ptr<T>(new T());
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class... Args>
inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
#endif
template<class T>
inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
make_unique(typename remove_reference<T>::type&& value)
{
return std::unique_ptr<T>(new T(std::move(value)));
}
template<class T>
inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
make_unique_noinit()
{
return std::unique_ptr<T>(new T);
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value,
std::unique_ptr<T> >::type
make_unique(std::size_t size)
{
return std::unique_ptr<T>(new typename remove_extent<T>::type[size]());
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value,
std::unique_ptr<T> >::type
make_unique_noinit(std::size_t size)
{
return std::unique_ptr<T>(new typename remove_extent<T>::type[size]);
}
} /* boost */
#endif

View File

@@ -0,0 +1,27 @@
#ifndef BOOST_SMART_PTR_OWNER_EQUAL_TO_HPP_INCLUDED
#define BOOST_SMART_PTR_OWNER_EQUAL_TO_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/config.hpp>
namespace boost
{
template<class T = void> struct owner_equal_to
{
typedef bool result_type;
typedef T first_argument_type;
typedef T second_argument_type;
template<class U, class V> bool operator()( U const & u, V const & v ) const BOOST_NOEXCEPT
{
return u.owner_equals( v );
}
};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_OWNER_EQUAL_TO_HPP_INCLUDED

View File

@@ -0,0 +1,27 @@
#ifndef BOOST_SMART_PTR_OWNER_HASH_HPP_INCLUDED
#define BOOST_SMART_PTR_OWNER_HASH_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/config.hpp>
#include <cstddef>
namespace boost
{
template<class T> struct owner_hash
{
typedef std::size_t result_type;
typedef T argument_type;
std::size_t operator()( T const & t ) const BOOST_NOEXCEPT
{
return t.owner_hash_value();
}
};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_OWNER_HASH_HPP_INCLUDED

View File

@@ -0,0 +1,36 @@
#ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
#define BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
//
// owner_less.hpp
//
// Copyright (c) 2008 Frank Mori Hess
// Copyright (c) 2016 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/config.hpp>
namespace boost
{
template<class T = void> struct owner_less
{
typedef bool result_type;
typedef T first_argument_type;
typedef T second_argument_type;
template<class U, class V> bool operator()( U const & u, V const & v ) const BOOST_NOEXCEPT
{
return u.owner_before( v );
}
};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED

View File

@@ -0,0 +1,132 @@
#ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
#define BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 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/config.hpp>
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t
namespace boost
{
// Debug hooks
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_array_constructor_hook(void * p);
void sp_array_destructor_hook(void * p);
#endif
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
// is guaranteed, either on destruction of the scoped_array or via an explicit
// reset(). Use shared_array or std::vector if your needs are more complex.
template<class T> class scoped_array // noncopyable
{
private:
T * px;
scoped_array(scoped_array const &);
scoped_array & operator=(scoped_array const &);
typedef scoped_array<T> this_type;
void operator==( scoped_array const& ) const;
void operator!=( scoped_array const& ) const;
public:
typedef T element_type;
explicit scoped_array( T * p = 0 ) BOOST_SP_NOEXCEPT : px( p )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_array_constructor_hook( px );
#endif
}
~scoped_array() BOOST_SP_NOEXCEPT
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_array_destructor_hook( px );
#endif
boost::checked_array_delete( px );
}
void reset(T * p = 0) BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this);
}
T & operator[](std::ptrdiff_t i) const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
BOOST_ASSERT( i >= 0 );
return px[i];
}
T * get() const BOOST_SP_NOEXCEPT
{
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
void swap(scoped_array & b) BOOST_SP_NOEXCEPT
{
T * tmp = b.px;
b.px = px;
px = tmp;
}
};
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class T> inline bool operator==( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
#endif
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_SP_NOEXCEPT
{
a.swap(b);
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED

Some files were not shown because too many files have changed in this diff Show More