forked from boostorg/smart_ptr
60
include/boost/detail/sp_convertible.hpp
Normal file
60
include/boost/detail/sp_convertible.hpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||||
|
#define BOOST_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>
|
||||||
|
|
||||||
|
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( (Y*)0 ) ) == sizeof(yes) };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sp_empty
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template< bool > struct sp_enable_if_convertible_impl;
|
||||||
|
|
||||||
|
template<> struct sp_enable_if_convertible_impl<true>
|
||||||
|
{
|
||||||
|
typedef sp_empty type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct sp_enable_if_convertible_impl<false>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
@ -23,8 +23,19 @@
|
|||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_SFINAE )
|
||||||
|
#include <boost/detail/sp_convertible.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <functional> // for std::less
|
#include <functional> // for std::less
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_IOSTREAM)
|
||||||
|
#if !defined(BOOST_NO_IOSFWD)
|
||||||
#include <iosfwd> // for std::basic_ostream
|
#include <iosfwd> // for std::basic_ostream
|
||||||
|
#else
|
||||||
|
#include <ostream>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
@ -66,9 +77,19 @@ public:
|
|||||||
|
|
||||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||||
|
|
||||||
template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
|
template<class U>
|
||||||
|
#if !defined( BOOST_NO_SFINAE )
|
||||||
|
|
||||||
|
intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
intrusive_ptr( intrusive_ptr<U> const & rhs )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
: p_( rhs.get() )
|
||||||
{
|
{
|
||||||
if(p_ != 0) intrusive_ptr_add_ref(p_);
|
if( p_ != 0 ) intrusive_ptr_add_ref( p_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -246,7 +267,9 @@ template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U
|
|||||||
|
|
||||||
// operator<<
|
// operator<<
|
||||||
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
#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)
|
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
|
||||||
{
|
{
|
||||||
@ -275,6 +298,8 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
|||||||
|
|
||||||
#endif // __GNUC__ < 3
|
#endif // __GNUC__ < 3
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_NO_IOSTREAM)
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
#ifdef BOOST_MSVC
|
||||||
|
@ -32,6 +32,10 @@
|
|||||||
#include <boost/detail/shared_count.hpp>
|
#include <boost/detail/shared_count.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_SFINAE )
|
||||||
|
#include <boost/detail/sp_convertible.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
||||||
#include <boost/detail/spinlock_pool.hpp>
|
#include <boost/detail/spinlock_pool.hpp>
|
||||||
#include <boost/memory_order.hpp>
|
#include <boost/memory_order.hpp>
|
||||||
@ -224,11 +228,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
|
#if !defined( BOOST_NO_SFINAE )
|
||||||
|
|
||||||
|
shared_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
shared_ptr( shared_ptr<Y> const & r )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
: px( r.px ), pn( r.pn ) // never throws
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr(detail::shared_count const & c, T * p): px(p), pn(c) // never throws
|
shared_ptr( detail::shared_count const & c, T * p ): px( p ), pn( c ) // never throws
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,13 +61,31 @@ public:
|
|||||||
//
|
//
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
|
#if !defined( BOOST_NO_SFINAE )
|
||||||
|
|
||||||
|
weak_ptr( weak_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
weak_ptr( weak_ptr<Y> const & r )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
: pn(r.pn) // never throws
|
||||||
{
|
{
|
||||||
px = r.lock().get();
|
px = r.lock().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
|
#if !defined( BOOST_NO_SFINAE )
|
||||||
|
|
||||||
|
weak_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
weak_ptr( shared_ptr<Y> const & r )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
: px( r.px ), pn( r.pn ) // never throws
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,5 +46,8 @@ import testing ;
|
|||||||
[ run sp_accept_owner_test.cpp ]
|
[ run sp_accept_owner_test.cpp ]
|
||||||
[ run sp_atomic_test.cpp ]
|
[ run sp_atomic_test.cpp ]
|
||||||
[ run make_shared_test.cpp ]
|
[ run make_shared_test.cpp ]
|
||||||
|
[ run sp_convertible_test.cpp ]
|
||||||
|
[ run wp_convertible_test.cpp ]
|
||||||
|
[ run ip_convertible_test.cpp ]
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
54
test/ip_convertible_test.cpp
Normal file
54
test/ip_convertible_test.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
// wp_convertible_test.cpp
|
||||||
|
//
|
||||||
|
// 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/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/intrusive_ptr.hpp>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
struct W
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
void intrusive_ptr_add_ref( W* )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void intrusive_ptr_release( W* )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
struct X: public virtual W
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y: public virtual W
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Z: public X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int f( boost::intrusive_ptr<X> )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int f( boost::intrusive_ptr<Y> )
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST( 1 == f( boost::intrusive_ptr<Z>() ) );
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
66
test/sp_convertible_test.cpp
Normal file
66
test/sp_convertible_test.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
// sp_convertible_test.cpp
|
||||||
|
//
|
||||||
|
// 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/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
class incomplete;
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Z: public X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int f( boost::shared_ptr<void const> )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int f( boost::shared_ptr<int> )
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int f( boost::shared_ptr<incomplete> )
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int g( boost::shared_ptr<X> )
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int g( boost::shared_ptr<Y> )
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
int g( boost::shared_ptr<incomplete> )
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST( 1 == f( boost::shared_ptr<double>() ) );
|
||||||
|
BOOST_TEST( 4 == g( boost::shared_ptr<Z>() ) );
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
68
test/wp_convertible_test.cpp
Normal file
68
test/wp_convertible_test.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
// wp_convertible_test.cpp
|
||||||
|
//
|
||||||
|
// 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/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
class incomplete;
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Z: public X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int f( boost::weak_ptr<void const> )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int f( boost::weak_ptr<int> )
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int f( boost::weak_ptr<incomplete> )
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int g( boost::weak_ptr<X> )
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int g( boost::weak_ptr<Y> )
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
int g( boost::weak_ptr<incomplete> )
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST( 1 == f( boost::weak_ptr<double>() ) );
|
||||||
|
BOOST_TEST( 1 == f( boost::shared_ptr<double>() ) );
|
||||||
|
BOOST_TEST( 4 == g( boost::weak_ptr<Z>() ) );
|
||||||
|
BOOST_TEST( 4 == g( boost::shared_ptr<Z>() ) );
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
Reference in New Issue
Block a user