Boost logo

Boost :

From: David B. Held (dheld_at_[hidden])
Date: 2003-02-06 14:42:14


"Philippe A. Bouchard" <philippeb_at_[hidden]> wrote in message
news:b1tvp7$da3$1_at_main.gmane.org...
> [...]
> $100 Question:
> When I am looking at the "Storage Policy", p. 189, Modern C++ Design;
> the class must be initialized by a StoredType object while in my situation
> the StoredType is a shifted_object<T> and 'new (so) T' returns a pointer
> to T (member of shifted_boject<T>). What am I supposed to do if I want
> to keep it optimized and simple?

Step 1) Check out policy_ptr in the sandbox. Step 2) Use the template
c'tor in smart_ptr. Step 3) Make your storage policy take the appropriate
type.

Here's the "raw pointer c'tor":

        template <typename U>
        smart_ptr(U const& p)
        : base_type(p, detail::init_first_tag())
        { checking_policy::on_init(get_impl(*this)); }

Here's what your storage_policy might look like:

    template <typename T>
    class shifted_storage
    {
    public:
        typedef shifted_object<T>* stored_type; // the type of the
pointee_
        typedef shifted_object<T const>* const_stored_type; // object
        typedef T* pointer_type; // type returned by
operator->
        typedef T const* const_pointer_type;
        typedef add_reference<T>::type
                            reference_type; // type returned by
operator*
        typedef add_reference<T const>::type
                            const_reference_type;

        typedef shifted_storage type;
        typedef storage_policy_tag policy_category;

    protected:
        shifted_storage()
        : pointee_(default_value())
        { }

        template <typename U>
        shifted_storage(shifted_storage<U> const& rhs)
        : pointee_(default_value())
        { }

        shifted_storage(scalar_storage const&)
        : pointee_(default_value())
        { }

        shifted_storage(pointer_type p)
        : pointee_(static_cast<stored_type>(
            static_cast<char*>(static_cast<void*>(p)) -
sizeof(shifted_header)
        ))
        { }
        // I think the arithmetic above is valid, because we're dealing with
        // POD types, but IANALL, so take it with a grain of salt

        ~shifted_storage()
        { boost::checked_delete(pointee_); }

        void swap(scalar_storage& rhs)
        { std::swap(pointee_, rhs.pointee_); }

        pointer_type get_pointer() const
        { return &pointee_->m_object; }

        reference_type get_reference() const
        { return pointee_->m_object; }

        bool is_valid() const
        { return pointee_ != default_value(); }

    public:
        friend inline pointer_type get_impl(shifted_storage const& sp)
        { return &sp.pointee_->m_object; }

        friend inline stored_type& get_impl_ref(shifted_storage& sp)
        { return sp.pointee_; }

    protected:
        void release()
        { pointee_ = 0; }

        static stored_type default_value()
        { return 0; }

    private:
        stored_type pointee_;

    public:
        BOOST_MPL_AUX_LAMBDA_SUPPORT(1, shifted_storage, (T))
    };

#ifdef __BORLANDC__
    namespace mpl { BOOST_MPL_AUX_VOID_SPEC(1, shifted_storage) }
#endif

Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk