|
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