|
Boost : |
From: David B. Held (dheld_at_[hidden])
Date: 2003-02-06 21:42:01
I need a pointer that can store pointer or an ID. I thought maybe
I could make a policy set for smart_ptr, but that turns out to be
too tricky. I don't think this kind of thing is appropriate for a
smart pointer because of the interface, but I just wanted to get
some opinions on the technique, and see if there are any
improvements to be made.
#include <cstring> // std::memcpy()
#include <new> // placement new
#include <algorithm> // std::swap()
#include <stdexcept> // std::runtime_error
#include <boost/shared_ptr.hpp>
//--------------------------------------------------------------------------
-- namespace boost { //------------------------------------------------------------------------ template <typename T, typename Pointer = boost::shared_ptr<T> > class serial_ptr { private: // Types enum tag { t_id, t_pointer }; typedef Pointer pointer_type; typedef char storage_type[sizeof(pointer_type)]; public: // Structors serial_ptr(int id) : tag_(t_id) { new (value_) int(id); } serial_ptr(T* p) : tag_(t_pointer) { new (value_) pointer_type(p); } serial_ptr(pointer_type const& p) : tag_(t_pointer) { new (value_) pointer_type(p); } serial_ptr(serial_ptr const& p) : tag_(p.tag_) { if (tag_ == t_id) new (value_) int(p); else new (value_) pointer_type(p); } ~serial_ptr(void) { if (tag_ == t_pointer) { reinterpret_cast<pointer_type*>(value_)->~pointer_type(); } } public: // Operators serial_ptr& operator=(int id) { serial_ptr(id).swap(*this); return *this; } serial_ptr& operator=(pointer_type p) { serial_ptr(p).swap(*this); return *this; } serial_ptr& operator=(serial_ptr p) { swap(p); return *this; } operator int(void) const { if (tag_ != t_id) { throw std::runtime_error("Invalid serial_ptr conversion"); } return *reinterpret_cast<int const*>(value_); } operator pointer_type(void) const { if (tag_ != t_pointer) { throw std::runtime_error("Invalid serial_ptr conversion"); } return *reinterpret_cast<pointer_type const*>(value_); } T* operator->(void) const { return operator pointer_type().operator->(); } void swap(serial_ptr& p) { std::swap(tag_, p.tag_); storage_type Tmp; std::memcpy(Tmp, value_, sizeof(value_)); std::memcpy(value_, p.value_, sizeof(value_)); std::memcpy(p.value_, Tmp, sizeof(value_)); } private: // Implementation tag tag_; storage_type value_; }; //------------------------------------------------------------------------ } // namespace boost Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk