epoc32/include/stdapis/boost/intrusive_ptr.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
williamr@2
     1
#ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
williamr@2
     2
#define BOOST_INTRUSIVE_PTR_HPP_INCLUDED
williamr@2
     3
williamr@2
     4
//
williamr@2
     5
//  intrusive_ptr.hpp
williamr@2
     6
//
williamr@2
     7
//  Copyright (c) 2001, 2002 Peter Dimov
williamr@2
     8
//
williamr@2
     9
// Distributed under the Boost Software License, Version 1.0. (See
williamr@2
    10
// accompanying file LICENSE_1_0.txt or copy at
williamr@2
    11
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
    12
//
williamr@2
    13
//  See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
williamr@2
    14
//
williamr@2
    15
williamr@2
    16
#include <boost/config.hpp>
williamr@2
    17
williamr@2
    18
#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
williamr@2
    19
# pragma warning(push)
williamr@2
    20
# pragma warning(disable:4284) // odd return type for operator->
williamr@2
    21
#endif
williamr@2
    22
williamr@2
    23
#include <boost/assert.hpp>
williamr@2
    24
#include <boost/detail/workaround.hpp>
williamr@2
    25
williamr@2
    26
#include <functional>           // for std::less
williamr@2
    27
#include <iosfwd>               // for std::basic_ostream
williamr@2
    28
williamr@2
    29
williamr@2
    30
namespace boost
williamr@2
    31
{
williamr@2
    32
williamr@2
    33
//
williamr@2
    34
//  intrusive_ptr
williamr@2
    35
//
williamr@2
    36
//  A smart pointer that uses intrusive reference counting.
williamr@2
    37
//
williamr@2
    38
//  Relies on unqualified calls to
williamr@2
    39
//  
williamr@2
    40
//      void intrusive_ptr_add_ref(T * p);
williamr@2
    41
//      void intrusive_ptr_release(T * p);
williamr@2
    42
//
williamr@2
    43
//          (p != 0)
williamr@2
    44
//
williamr@2
    45
//  The object is responsible for destroying itself.
williamr@2
    46
//
williamr@2
    47
williamr@2
    48
template<class T> class intrusive_ptr
williamr@2
    49
{
williamr@2
    50
private:
williamr@2
    51
williamr@2
    52
    typedef intrusive_ptr this_type;
williamr@2
    53
williamr@2
    54
public:
williamr@2
    55
williamr@2
    56
    typedef T element_type;
williamr@2
    57
williamr@2
    58
    intrusive_ptr(): p_(0)
williamr@2
    59
    {
williamr@2
    60
    }
williamr@2
    61
williamr@2
    62
    intrusive_ptr(T * p, bool add_ref = true): p_(p)
williamr@2
    63
    {
williamr@2
    64
        if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_);
williamr@2
    65
    }
williamr@2
    66
williamr@2
    67
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
williamr@2
    68
williamr@2
    69
    template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
williamr@2
    70
    {
williamr@2
    71
        if(p_ != 0) intrusive_ptr_add_ref(p_);
williamr@2
    72
    }
williamr@2
    73
williamr@2
    74
#endif
williamr@2
    75
williamr@2
    76
    intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
williamr@2
    77
    {
williamr@2
    78
        if(p_ != 0) intrusive_ptr_add_ref(p_);
williamr@2
    79
    }
williamr@2
    80
williamr@2
    81
    ~intrusive_ptr()
williamr@2
    82
    {
williamr@2
    83
        if(p_ != 0) intrusive_ptr_release(p_);
williamr@2
    84
    }
williamr@2
    85
williamr@2
    86
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
williamr@2
    87
williamr@2
    88
    template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
williamr@2
    89
    {
williamr@2
    90
        this_type(rhs).swap(*this);
williamr@2
    91
        return *this;
williamr@2
    92
    }
williamr@2
    93
williamr@2
    94
#endif
williamr@2
    95
williamr@2
    96
    intrusive_ptr & operator=(intrusive_ptr const & rhs)
williamr@2
    97
    {
williamr@2
    98
        this_type(rhs).swap(*this);
williamr@2
    99
        return *this;
williamr@2
   100
    }
williamr@2
   101
williamr@2
   102
    intrusive_ptr & operator=(T * rhs)
williamr@2
   103
    {
williamr@2
   104
        this_type(rhs).swap(*this);
williamr@2
   105
        return *this;
williamr@2
   106
    }
williamr@2
   107
williamr@2
   108
    T * get() const
williamr@2
   109
    {
williamr@2
   110
        return p_;
williamr@2
   111
    }
williamr@2
   112
williamr@2
   113
    T & operator*() const
williamr@2
   114
    {
williamr@2
   115
        return *p_;
williamr@2
   116
    }
williamr@2
   117
williamr@2
   118
    T * operator->() const
williamr@2
   119
    {
williamr@2
   120
        return p_;
williamr@2
   121
    }
williamr@2
   122
williamr@2
   123
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
williamr@2
   124
williamr@2
   125
    operator bool () const
williamr@2
   126
    {
williamr@2
   127
        return p_ != 0;
williamr@2
   128
    }
williamr@2
   129
williamr@2
   130
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
williamr@2
   131
    typedef T * (this_type::*unspecified_bool_type)() const;
williamr@2
   132
    
williamr@2
   133
    operator unspecified_bool_type() const // never throws
williamr@2
   134
    {
williamr@2
   135
        return p_ == 0? 0: &this_type::get;
williamr@2
   136
    }
williamr@2
   137
williamr@2
   138
#else 
williamr@2
   139
williamr@2
   140
    typedef T * this_type::*unspecified_bool_type;
williamr@2
   141
williamr@2
   142
    operator unspecified_bool_type () const
williamr@2
   143
    {
williamr@2
   144
        return p_ == 0? 0: &this_type::p_;
williamr@2
   145
    }
williamr@2
   146
williamr@2
   147
#endif
williamr@2
   148
williamr@2
   149
    // operator! is a Borland-specific workaround
williamr@2
   150
    bool operator! () const
williamr@2
   151
    {
williamr@2
   152
        return p_ == 0;
williamr@2
   153
    }
williamr@2
   154
williamr@2
   155
    void swap(intrusive_ptr & rhs)
williamr@2
   156
    {
williamr@2
   157
        T * tmp = p_;
williamr@2
   158
        p_ = rhs.p_;
williamr@2
   159
        rhs.p_ = tmp;
williamr@2
   160
    }
williamr@2
   161
williamr@2
   162
private:
williamr@2
   163
williamr@2
   164
    T * p_;
williamr@2
   165
};
williamr@2
   166
williamr@2
   167
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
williamr@2
   168
{
williamr@2
   169
    return a.get() == b.get();
williamr@2
   170
}
williamr@2
   171
williamr@2
   172
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
williamr@2
   173
{
williamr@2
   174
    return a.get() != b.get();
williamr@2
   175
}
williamr@2
   176
williamr@2
   177
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
williamr@2
   178
{
williamr@2
   179
    return a.get() == b;
williamr@2
   180
}
williamr@2
   181
williamr@2
   182
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
williamr@2
   183
{
williamr@2
   184
    return a.get() != b;
williamr@2
   185
}
williamr@2
   186
williamr@2
   187
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
williamr@2
   188
{
williamr@2
   189
    return a == b.get();
williamr@2
   190
}
williamr@2
   191
williamr@2
   192
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
williamr@2
   193
{
williamr@2
   194
    return a != b.get();
williamr@2
   195
}
williamr@2
   196
williamr@2
   197
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
williamr@2
   198
williamr@2
   199
// Resolve the ambiguity between our op!= and the one in rel_ops
williamr@2
   200
williamr@2
   201
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
williamr@2
   202
{
williamr@2
   203
    return a.get() != b.get();
williamr@2
   204
}
williamr@2
   205
williamr@2
   206
#endif
williamr@2
   207
williamr@2
   208
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
williamr@2
   209
{
williamr@2
   210
    return std::less<T *>()(a.get(), b.get());
williamr@2
   211
}
williamr@2
   212
williamr@2
   213
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
williamr@2
   214
{
williamr@2
   215
    lhs.swap(rhs);
williamr@2
   216
}
williamr@2
   217
williamr@2
   218
// mem_fn support
williamr@2
   219
williamr@2
   220
template<class T> T * get_pointer(intrusive_ptr<T> const & p)
williamr@2
   221
{
williamr@2
   222
    return p.get();
williamr@2
   223
}
williamr@2
   224
williamr@2
   225
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
williamr@2
   226
{
williamr@2
   227
    return static_cast<T *>(p.get());
williamr@2
   228
}
williamr@2
   229
williamr@2
   230
template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
williamr@2
   231
{
williamr@2
   232
    return const_cast<T *>(p.get());
williamr@2
   233
}
williamr@2
   234
williamr@2
   235
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
williamr@2
   236
{
williamr@2
   237
    return dynamic_cast<T *>(p.get());
williamr@2
   238
}
williamr@2
   239
williamr@2
   240
// operator<<
williamr@2
   241
williamr@2
   242
#if defined(__GNUC__) &&  (__GNUC__ < 3)
williamr@2
   243
williamr@2
   244
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
williamr@2
   245
{
williamr@2
   246
    os << p.get();
williamr@2
   247
    return os;
williamr@2
   248
}
williamr@2
   249
williamr@2
   250
#else
williamr@2
   251
williamr@2
   252
// in STLport's no-iostreams mode no iostream symbols can be used
williamr@2
   253
#ifndef _STLP_NO_IOSTREAMS
williamr@2
   254
williamr@2
   255
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
williamr@2
   256
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
williamr@2
   257
using std::basic_ostream;
williamr@2
   258
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
williamr@2
   259
# else
williamr@2
   260
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
williamr@2
   261
# endif 
williamr@2
   262
{
williamr@2
   263
    os << p.get();
williamr@2
   264
    return os;
williamr@2
   265
}
williamr@2
   266
williamr@2
   267
#endif // _STLP_NO_IOSTREAMS
williamr@2
   268
williamr@2
   269
#endif // __GNUC__ < 3
williamr@2
   270
williamr@2
   271
} // namespace boost
williamr@2
   272
williamr@2
   273
#ifdef BOOST_MSVC
williamr@2
   274
# pragma warning(pop)
williamr@2
   275
#endif    
williamr@2
   276
williamr@2
   277
#endif  // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED