1 // (C) Copyright Jonathan Turkanis 2004-2005. 2 // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) 4 5 // Contains the definition of move_ptrs::default_deleter, the default 6 // Deleter template argument to move_ptr. Uses a technique of Daniel 7 // Wallin to capture the type of a pointer at the time the deleter 8 // is constructed, so that move_ptrs can delete objects of incomplete 9 // type by default. 10 11 #ifndef BOOST_MOVE_PTR_DEFAULT_DELETER_HPP_INCLUDED 12 #define BOOST_MOVE_PTR_DEFAULT_DELETER_HPP_INCLUDED 13 14 #include <boost/checked_delete.hpp> 15 #include <boost/mpl/if.hpp> 16 #include <boost/type_traits/is_array.hpp> 17 #include <boost/type_traits/remove_bounds.hpp> 18 19 namespace boost { namespace ptr_container_detail { namespace move_ptrs { 20 21 namespace ptr_container_detail { 22 23 template<typename T> 24 struct deleter_base { 25 typedef void (*deleter)(T*); deleter_baseboost::ptr_container_detail::move_ptrs::ptr_container_detail::deleter_base26 deleter_base(deleter d) { delete_ = d; } operator ()boost::ptr_container_detail::move_ptrs::ptr_container_detail::deleter_base27 void operator() (T* t) const { delete_(t); } 28 static deleter delete_; 29 }; 30 31 template<class T> 32 typename deleter_base<T>::deleter 33 deleter_base<T>::delete_; 34 35 template<typename T> 36 struct scalar_deleter : deleter_base<T> { 37 typedef deleter_base<T> base; scalar_deleterboost::ptr_container_detail::move_ptrs::ptr_container_detail::scalar_deleter38 scalar_deleter() : base(do_delete) { } do_deleteboost::ptr_container_detail::move_ptrs::ptr_container_detail::scalar_deleter39 static void do_delete(T* t) { checked_delete(t); } 40 }; 41 42 template<typename T> 43 struct array_deleter 44 : deleter_base<typename remove_bounds<T>::type> 45 { 46 typedef typename remove_bounds<T>::type element_type; 47 typedef deleter_base<element_type> base; array_deleterboost::ptr_container_detail::move_ptrs::ptr_container_detail::array_deleter48 array_deleter() : base(do_delete) { } do_deleteboost::ptr_container_detail::move_ptrs::ptr_container_detail::array_deleter49 static void do_delete(element_type* t) { checked_array_delete(t); } 50 }; 51 52 } // End namespace ptr_container_detail. 53 54 template<typename T> 55 struct default_deleter 56 : mpl::if_< 57 is_array<T>, 58 ptr_container_detail::array_deleter<T>, 59 ptr_container_detail::scalar_deleter<T> 60 >::type 61 { default_deleterboost::ptr_container_detail::move_ptrs::default_deleter62 default_deleter() { } 63 template<typename TT> default_deleterboost::ptr_container_detail::move_ptrs::default_deleter64 default_deleter(default_deleter<TT>) { } 65 }; 66 67 } } } // End namespaces ptr_container_detail, move_ptrs, boost. 68 69 #endif // #ifndef BOOST_MOVE_PTR_DEFAULT_DELETER_HPP_INCLUDED 70