epoc32/include/stdapis/boost/ptr_container/detail/static_move_ptr.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
williamr@2
     1
// (C) Copyright Thorsten Ottosen 2005.
williamr@2
     2
// (C) Copyright Jonathan Turkanis 2004.
williamr@2
     3
// (C) Copyright Daniel Wallin 2004.
williamr@2
     4
// Distributed under the Boost Software License, Version 1.0. (See accompanying
williamr@2
     5
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
williamr@2
     6
williamr@2
     7
// Implementation of the move_ptr from the "Move Proposal" 
williamr@2
     8
// (http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm) 
williamr@2
     9
// enhanced to support custom deleters and safe boolean conversions.
williamr@2
    10
//
williamr@2
    11
// The implementation is based on an implementation by Daniel Wallin, at
williamr@2
    12
// "http://aspn.activestate.com/ASPN/Mail/Message/Attachments/boost/
williamr@2
    13
// 400DC271.1060903@student.umu.se/move_ptr.hpp". The current was adapted 
williamr@2
    14
// by Jonathan Turkanis to incorporating ideas of Howard Hinnant and 
williamr@2
    15
// Rani Sharoni. 
williamr@2
    16
williamr@2
    17
#ifndef BOOST_STATIC_MOVE_PTR_HPP_INCLUDED
williamr@2
    18
#define BOOST_STATIC_MOVE_PTR_HPP_INCLUDED
williamr@2
    19
williamr@2
    20
#include <boost/config.hpp> // Member template friends, put size_t in std.
williamr@2
    21
#include <algorithm>        // swap.
williamr@2
    22
#include <cstddef>          // size_t
williamr@2
    23
#include <boost/compressed_pair.hpp> 
williamr@2
    24
#include <boost/ptr_container/detail/default_deleter.hpp>       
williamr@2
    25
#include <boost/ptr_container/detail/is_convertible.hpp>       
williamr@2
    26
#include <boost/ptr_container/detail/move.hpp>       
williamr@2
    27
#include <boost/static_assert.hpp>
williamr@2
    28
#include <boost/type_traits/add_reference.hpp>
williamr@2
    29
#include <boost/type_traits/is_array.hpp>
williamr@2
    30
williamr@2
    31
#if defined(BOOST_MSVC)
williamr@2
    32
#pragma warning(push)
williamr@2
    33
#pragma warning(disable:4521)        // Multiple copy constuctors.
williamr@2
    34
#endif
williamr@2
    35
williamr@2
    36
namespace boost { namespace ptr_container_detail {
williamr@2
    37
williamr@2
    38
    
williamr@2
    39
template< typename T, 
williamr@2
    40
          typename Deleter = 
williamr@2
    41
              move_ptrs::default_deleter<T> >
williamr@2
    42
class static_move_ptr 
williamr@2
    43
{
williamr@2
    44
public:
williamr@2
    45
williamr@2
    46
    typedef typename remove_bounds<T>::type             element_type;
williamr@2
    47
    typedef Deleter                                     deleter_type;
williamr@2
    48
williamr@2
    49
private:
williamr@2
    50
    
williamr@2
    51
    struct safe_bool_helper { int x; };
williamr@2
    52
    typedef int safe_bool_helper::* safe_bool;
williamr@2
    53
    typedef boost::compressed_pair<element_type*, Deleter> impl_type;
williamr@2
    54
williamr@2
    55
public:
williamr@2
    56
    typedef typename impl_type::second_reference        deleter_reference;
williamr@2
    57
    typedef typename impl_type::second_const_reference  deleter_const_reference;
williamr@2
    58
williamr@2
    59
        // Constructors
williamr@2
    60
williamr@2
    61
    static_move_ptr() : impl_(0) { }
williamr@2
    62
williamr@2
    63
    static_move_ptr(const static_move_ptr& p)
williamr@2
    64
        : impl_(p.get(), p.get_deleter())    
williamr@2
    65
        { 
williamr@2
    66
            const_cast<static_move_ptr&>(p).release();
williamr@2
    67
        }
williamr@2
    68
williamr@2
    69
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))    
williamr@2
    70
    static_move_ptr( const move_ptrs::move_source<static_move_ptr<T,Deleter> >& src )
williamr@2
    71
#else
williamr@2
    72
    static_move_ptr( const move_ptrs::move_source<static_move_ptr>& src )
williamr@2
    73
#endif    
williamr@2
    74
            : impl_(src.ptr().get(), src.ptr().get_deleter())
williamr@2
    75
            {
williamr@2
    76
                src.ptr().release();
williamr@2
    77
            }
williamr@2
    78
    
williamr@2
    79
    template<typename TT>
williamr@2
    80
    explicit static_move_ptr(TT* tt) 
williamr@2
    81
        : impl_(tt, Deleter()) 
williamr@2
    82
        { }
williamr@2
    83
williamr@2
    84
        // Destructor
williamr@2
    85
williamr@2
    86
    ~static_move_ptr() { if (ptr()) get_deleter()(ptr()); }
williamr@2
    87
williamr@2
    88
        // Assignment
williamr@2
    89
williamr@2
    90
    static_move_ptr& operator=(static_move_ptr rhs)
williamr@2
    91
        {
williamr@2
    92
            rhs.swap(*this);
williamr@2
    93
            return *this;
williamr@2
    94
        }
williamr@2
    95
williamr@2
    96
        // Smart pointer interface
williamr@2
    97
williamr@2
    98
    element_type* get() const { return ptr(); }
williamr@2
    99
williamr@2
   100
    element_type& operator*() 
williamr@2
   101
        { 
williamr@2
   102
            /*BOOST_STATIC_ASSERT(!is_array);*/ return *ptr(); 
williamr@2
   103
        }
williamr@2
   104
williamr@2
   105
    const element_type& operator*() const 
williamr@2
   106
        { 
williamr@2
   107
            /*BOOST_STATIC_ASSERT(!is_array);*/ return *ptr(); 
williamr@2
   108
        }
williamr@2
   109
williamr@2
   110
    element_type* operator->()  
williamr@2
   111
        { 
williamr@2
   112
            /*BOOST_STATIC_ASSERT(!is_array);*/ return ptr(); 
williamr@2
   113
        }    
williamr@2
   114
williamr@2
   115
    const element_type* operator->() const 
williamr@2
   116
        { 
williamr@2
   117
            /*BOOST_STATIC_ASSERT(!is_array);*/ return ptr(); 
williamr@2
   118
        }    
williamr@2
   119
williamr@2
   120
williamr@2
   121
    element_type* release()
williamr@2
   122
        {
williamr@2
   123
            element_type* result = ptr();
williamr@2
   124
            ptr() = 0;
williamr@2
   125
            return result;
williamr@2
   126
        }
williamr@2
   127
williamr@2
   128
    void reset()
williamr@2
   129
        {
williamr@2
   130
            if (ptr()) get_deleter()(ptr());
williamr@2
   131
            ptr() = 0;
williamr@2
   132
        }
williamr@2
   133
williamr@2
   134
    template<typename TT>
williamr@2
   135
    void reset(TT* tt) 
williamr@2
   136
        {
williamr@2
   137
            static_move_ptr(tt).swap(*this);
williamr@2
   138
        }
williamr@2
   139
williamr@2
   140
    template<typename TT, typename DD>
williamr@2
   141
    void reset(TT* tt, DD dd) 
williamr@2
   142
        {
williamr@2
   143
            static_move_ptr(tt, dd).swap(*this);
williamr@2
   144
        }
williamr@2
   145
williamr@2
   146
    operator safe_bool() const { return ptr() ? &safe_bool_helper::x : 0; }
williamr@2
   147
williamr@2
   148
    void swap(static_move_ptr& p) { impl_.swap(p.impl_); }
williamr@2
   149
williamr@2
   150
    deleter_reference get_deleter() { return impl_.second(); }
williamr@2
   151
williamr@2
   152
    deleter_const_reference get_deleter() const { return impl_.second(); }
williamr@2
   153
private:
williamr@2
   154
    template<typename TT, typename DD>
williamr@2
   155
    void check(const static_move_ptr<TT, DD>& ptr)
williamr@2
   156
        {
williamr@2
   157
            typedef move_ptrs::is_smart_ptr_convertible<TT, T> convertible;
williamr@2
   158
            BOOST_STATIC_ASSERT(convertible::value);
williamr@2
   159
        }   
williamr@2
   160
williamr@2
   161
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || defined(BOOST_NO_SFINAE)
williamr@2
   162
// give up on this behavior
williamr@2
   163
#else 
williamr@2
   164
williamr@2
   165
    template<typename Ptr> struct cant_move_from_const;
williamr@2
   166
williamr@2
   167
    template<typename TT, typename DD> 
williamr@2
   168
    struct cant_move_from_const< const static_move_ptr<TT, DD> > { 
williamr@2
   169
        typedef typename static_move_ptr<TT, DD>::error type; 
williamr@2
   170
    };
williamr@2
   171
williamr@2
   172
    template<typename Ptr> 
williamr@2
   173
    static_move_ptr(Ptr&, typename cant_move_from_const<Ptr>::type = 0);
williamr@2
   174
williamr@2
   175
williamr@2
   176
public:
williamr@2
   177
    static_move_ptr(static_move_ptr&);
williamr@2
   178
williamr@2
   179
    
williamr@2
   180
private:
williamr@2
   181
    template<typename TT, typename DD>
williamr@2
   182
    static_move_ptr( static_move_ptr<TT, DD>&,
williamr@2
   183
                     typename 
williamr@2
   184
                     move_ptrs::enable_if_convertible<
williamr@2
   185
                         TT, T, static_move_ptr&
williamr@2
   186
                     >::type::type* = 0 );
williamr@2
   187
williamr@2
   188
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING || BOOST_NO_SFINAE
williamr@2
   189
williamr@2
   190
//#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
williamr@2
   191
//    template<typename TT, typename DD>
williamr@2
   192
//    friend class static_move_ptr;
williamr@2
   193
//#else
williamr@2
   194
    public:
williamr@2
   195
//#endif
williamr@2
   196
    typename impl_type::first_reference 
williamr@2
   197
    ptr() { return impl_.first(); } 
williamr@2
   198
williamr@2
   199
    typename impl_type::first_const_reference 
williamr@2
   200
    ptr() const { return impl_.first(); }
williamr@2
   201
williamr@2
   202
    impl_type impl_;
williamr@2
   203
};
williamr@2
   204
williamr@2
   205
} // namespace ptr_container_detail
williamr@2
   206
} // End namespace boost.
williamr@2
   207
williamr@2
   208
#if defined(BOOST_MSVC)
williamr@2
   209
#pragma warning(pop) // #pragma warning(disable:4251)
williamr@2
   210
#endif
williamr@2
   211
williamr@2
   212
#endif      // #ifndef BOOST_STATIC_MOVE_PTR_HPP_INCLUDED