sl@0: // Copyright David Abrahams 2002.
sl@0: // Distributed under the Boost Software License, Version 1.0. (See
sl@0: // accompanying file LICENSE_1_0.txt or copy at
sl@0: // http://www.boost.org/LICENSE_1_0.txt)
sl@0: #ifndef DESTROY_DWA2002221_HPP
sl@0: # define DESTROY_DWA2002221_HPP
sl@0: 
sl@0: # include <boost/type_traits/is_array.hpp>
sl@0: # include <boost/detail/workaround.hpp>
sl@0: # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
sl@0: #  include <boost/type_traits/is_enum.hpp>
sl@0: # endif 
sl@0: namespace boost { namespace python { namespace detail { 
sl@0: 
sl@0: template <
sl@0:     bool array
sl@0: # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
sl@0:   , bool enum_  // vc7 has a problem destroying enums
sl@0: # endif 
sl@0:     > struct value_destroyer;
sl@0:     
sl@0: template <>
sl@0: struct value_destroyer<
sl@0:     false
sl@0: # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
sl@0:   , false
sl@0: # endif 
sl@0:     >
sl@0: {
sl@0:     template <class T>
sl@0:     static void execute(T const volatile* p)
sl@0:     {
sl@0:         p->T::~T();
sl@0:     }
sl@0: };
sl@0: 
sl@0: template <>
sl@0: struct value_destroyer<
sl@0:     true
sl@0: # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
sl@0:   , false
sl@0: # endif 
sl@0:     >
sl@0: {
sl@0:     template <class A, class T>
sl@0:     static void execute(A*, T const volatile* const first)
sl@0:     {
sl@0:         for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p)
sl@0:         {
sl@0:             value_destroyer<
sl@0:                 boost::is_array<T>::value
sl@0: # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
sl@0:               , boost::is_enum<T>::value
sl@0: # endif 
sl@0:             >::execute(p);
sl@0:         }
sl@0:     }
sl@0:     
sl@0:     template <class T>
sl@0:     static void execute(T const volatile* p)
sl@0:     {
sl@0:         execute(p, *p);
sl@0:     }
sl@0: };
sl@0: 
sl@0: # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
sl@0: template <>
sl@0: struct value_destroyer<true,true>
sl@0: {
sl@0:     template <class T>
sl@0:     static void execute(T const volatile*)
sl@0:     {
sl@0:     }
sl@0: };
sl@0: 
sl@0: template <>
sl@0: struct value_destroyer<false,true>
sl@0: {
sl@0:     template <class T>
sl@0:     static void execute(T const volatile*)
sl@0:     {
sl@0:     }
sl@0: };
sl@0: # endif 
sl@0: template <class T>
sl@0: inline void destroy_referent_impl(void* p, T& (*)())
sl@0: {
sl@0:     // note: cv-qualification needed for MSVC6
sl@0:     // must come *before* T for metrowerks
sl@0:     value_destroyer<
sl@0:          (boost::is_array<T>::value)
sl@0: # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
sl@0:        , (boost::is_enum<T>::value)
sl@0: # endif 
sl@0:     >::execute((const volatile T*)p);
sl@0: }
sl@0: 
sl@0: template <class T>
sl@0: inline void destroy_referent(void* p, T(*)() = 0)
sl@0: {
sl@0:     destroy_referent_impl(p, (T(*)())0);
sl@0: }
sl@0: 
sl@0: }}} // namespace boost::python::detail
sl@0: 
sl@0: #endif // DESTROY_DWA2002221_HPP