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