// (C) Copyright Jonathan Turkanis 2004. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) // Disclaimer: Not a Boost library. // reinterpret_cast is eliminable here; it is used to simplify the // implementation. #ifndef BOOST_IDL_UNIQUE_OBJ_HPP_INCLUDED #define BOOST_IDL_UNIQUE_OBJ_HPP_INCLUDED #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include // swap. #include #include #include #include #include #include #include #include #include #include #include #include #include #include // BOOST_MSVC. #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable:4521) // Multiple copy constuctors. #endif namespace boost { namespace interfaces { namespace detail { template class unique_obj_impl { public: static fixed_view* get(const unique_obj& obj) { return access::get_interface_pointer(obj) ? const_cast*>( static_cast*>(&obj) ) : 0; } static void reset(unique_obj& obj) { if (const void* pv = access::get_interface_pointer(obj)) { get_deleter(obj)(pv); access::set_interface_pointer(obj, 0); access::set_interface_table(obj, 0); } } template static void reset(unique_obj& obj, T* t) { BOOST_ASSERT(t && t != access::get_interface_pointer(obj)); unique_obj temp(t); interfaces::swap(obj, temp); } static manual_ptr release(unique_obj& obj) { manual_ptr result = *reinterpret_cast*>(&obj); access::set_interface_pointer(obj, 0); access::set_interface_table(obj, 0); return result; } }; } // End namespace detail. template class unique_obj : public fixed_view { public: BOOST_IDL_BEFRIEND_TEMPLATE_CLASS(unique_obj, 1, T) friend class access; // Constructors unique_obj() { } unique_obj(const unique_obj& obj) : fixed_view( reinterpret_cast(obj) ) { access::set_interface_pointer(obj, 0); access::set_interface_table(obj, 0); } template unique_obj(const unique_obj& obj) : fixed_view( reinterpret_cast(obj) ) { access::set_interface_pointer(obj, 0); access::set_interface_table(obj, 0); } template unique_obj(move_source< unique_obj > src) : fixed_view( reinterpret_cast(src.ptr()) ) { access::set_interface_pointer(src.ptr(), 0); access::set_interface_table(src.ptr(), 0); } template explicit unique_obj(T* t) { access::set_interface_pointer(*this, t); access::set_interface_table( *this, detail::initialize_deleter(*t) ); } // Destructor ~unique_obj() { if (const void* pv = access::get_interface_pointer(*this)) detail::get_deleter(*this)(pv); } // Assignment unique_obj& operator=(unique_obj rhs) { boost::interfaces::swap(*this, rhs); return *this; } template unique_obj& operator=(unique_obj p) { // Slightly more efficient version is cumbersome to express. unique_obj temp(move(p)); boost::interfaces::swap(*this, temp); return *this; } BOOST_IDL_PRIVATE: BOOST_IDL_MOVE_SUPPORT(unique_obj) }; template fixed_view* get(const unique_obj& obj) { return detail::unique_obj_impl::get(obj); } template void reset(unique_obj& obj) { detail::unique_obj_impl::reset(obj); } template void reset(unique_obj& obj, T* t) { detail::unique_obj_impl::reset(obj, t); } template manual_ptr release(unique_obj& obj) { return detail::unique_obj_impl::release(obj); } } } // End namespace interfaces, boost. #if defined(BOOST_MSVC) #pragma warning(pop) // #pragma warning(disable:4251) #endif #endif // #ifndef BOOST_IDL_UNIQUE_OBJ_HPP_INCLUDED