any smart pointer alternative suggestions?

All, I'm loving the shared_ptr class, however we have one issue that doesn't seem to be addressed by any of boost's smart pointers, and I'm looking for a work-around/alternative. Any help? The issue is that the smart pointers assume the pointer type to be 'T*', which is fine on a 32-bit system, but means that we get a near doubling of run-time size on our application when we move to a 64-bit application. As a result, we're using the standard technique to have a custom heap, and use our own 'pointers' into that heap that are smaller (typically 32-bits). But of course our ClassOnHeapPtr type does not match a 'ClassOnHeap *', so a boost::shared_ptr<ClassOnHeap> won't work. Are there any other libraries you boosters would recommend? thanks for any info... TJ -- Trey Jackson tjackson@ichips.intel.com "This is gonna cost me." -- Homer

Trey Jackson wrote:
The issue is that the smart pointers assume the pointer type to be 'T*', which is fine on a 32-bit system, but means that we get a near doubling of run-time size on our application when we move to a 64-bit application.
far/near pointers model returns! ;-) -- Alexander Nasonov Independent Developer and Consultant

Trey Jackson <tjackson@ichips.intel.com> writes:
All,
I'm loving the shared_ptr class, however we have one issue that doesn't seem to be addressed by any of boost's smart pointers, and I'm looking for a work-around/alternative. Any help?
The issue is that the smart pointers assume the pointer type to be 'T*', which is fine on a 32-bit system, but means that we get a near doubling of run-time size on our application when we move to a 64-bit application.
As a result, we're using the standard technique to have a custom heap, and use our own 'pointers' into that heap that are smaller (typically 32-bits).
But of course our ClassOnHeapPtr type does not match a 'ClassOnHeap *', so a boost::shared_ptr<ClassOnHeap> won't work.
Are there any other libraries you boosters would recommend?
You might look at the policy-based smart_ptr implementation in the Boost sandbox. Maybe you could devise an appropriate policy for holding your "small pointer". -- Dave Abrahams Boost Consulting www.boost-consulting.com

Dave Abrahams wrote:
You might look at the policy-based smart_ptr implementation in the Boost sandbox. Maybe you could devise an appropriate policy for holding your "small pointer".
I grabbed the hourly release from boost-consulting (boost-04-02-11-2300), but was unable to find any mention of policy-based pointers in any of boost-04-02-11-2300/boost/*_ptr.hpp the only difference b/w the shared_ptr.hpp provided in that release and my copy (boost 1_30) was some use of: shared_ptr_traits<T>::reference I guess I could specialize ,---------------- | template<MyClass> struct shared_ptr_traits | { | typedef --some-reference-type-- reference; | }; `---------------- But this wouldn't apply at all to the pointer type, the member data for shared_ptr is still: (note 'T *') ,---------------- | T * px; // contained pointer | detail::shared_count pn; // reference counter `---------------- Should I be looking on a branch (not a boost-consulting hourly release)? thanks, TJ -- Trey Jackson tjackson@ichips.intel.com The world's longest escalator is in Hong Kong, and measures 2625 feet. -- random factoid

Trey Jackson wrote:
Dave Abrahams wrote:
You might look at the policy-based smart_ptr implementation in the Boost sandbox. Maybe you could devise an appropriate policy for ^^^^^^^^^^^^^ holding your "small pointer".
I grabbed the hourly release from boost-consulting (boost-04-02-11-2300), but was unable to find any mention of policy-based pointers in any of
boost-04-02-11-2300/boost/*_ptr.hpp <snip> Should I be looking on a branch (not a boost-consulting hourly release)?
http://sourceforge.net/projects/boost-sandbox -- Daniel Wallin

Trey wrote:
All,
I'm loving the shared_ptr class, however we have one issue that doesn't seem to be addressed by any of boost's smart pointers, and I'm looking for a work-around/alternative. Any help?
The issue is that the smart pointers assume the pointer type to be 'T*', which is fine on a 32-bit system, but means that we get a near doubling of run-time size on our application when we move to a 64-bit application.
As a result, we're using the standard technique to have a custom heap, and use our own 'pointers' into that heap that are smaller (typically 32-bits).
But of course our ClassOnHeapPtr type does not match a 'ClassOnHeap *', so a boost::shared_ptr<ClassOnHeap> won't work.
Are there any other libraries you boosters would recommend?
I wrote a naive implementation now, based on a "heap" where I encode the pointer to a pointer to the heap in compile-time. It gives me smart pointers only occupying enough bits to cover the heap, in my case 2 bytes. The code is appended below. One should, of course, use a generic smart pointer (e.g. Alexandrescu's SmartPtr) and form a policy that does the offsetting trick, as David Abrahams suggested. But till then, borrow some ideas from my crappy implementation below... PS You can copy and paste the code fragment, as is. Please do and compile and run. DS ---------------------------------------------------------------------------- ------------------------------------------ #include <memory> #include <iostream> namespace tj { // First a Concept description of PointerBase, which is often // a type-based implementation of a heap. // Yes, assuming a default constructor for PointerBase types is // not very nice... template<typename PointerBase> struct PointerBaseConcept { typedef typename PointerBase::diff_type diff_type; static void check() { // A pointer base should have '+' and '-' to convert from and to // offsets char* ptr = PointerBase() + static_cast<diff_type>(0); diff_type offset = ptr - PointerBase(); } }; // A simple Adapter type to char pointers, being a model // of PointerBase. It needs a (compile-time deducible) pointer // to the pointer to the beginning of the "heap." An extern // variable holding a pointer will do. template<char** baseHandle, typename OffsetType = size_t> struct simple_pointer_base { typedef OffsetType diff_type; template<char** anyBase, typename AnyOffsetType> friend char* operator+(simple_pointer_base, diff_type diff); template<char** anyBase, typename AnyOffsetType> friend diff_type operator-(char*, simple_pointer_base); }; template<char** baseHandle, typename OffsetType> inline typename simple_pointer_base<baseHandle, OffsetType>::diff_type operator-(char* base, simple_pointer_base<baseHandle, OffsetType>) { // Force the diff to be of the right type... return static_cast<typename simple_pointer_base<baseHandle, OffsetType>::diff_type>(base - *baseHandle); } template<char** baseHandle, typename OffsetType> inline char* operator+(simple_pointer_base<baseHandle, OffsetType>, typename simple_pointer_base<baseHandle, OffsetType>::diff_type diff) { return *baseHandle + diff; } // The offset_ptr smart ptr uses a PointerBase type template<typename T, typename PointerBase> class offset_ptr { public: typedef T* pointer; typedef T value_type; offset_ptr(pointer obj) : _offset(static_cast<char*>(static_cast<void*>(obj)) - PointerBase()) { // empty } operator pointer() const { return static_cast<pointer>(static_cast<void*>(PointerBase() + _offset)); } pointer operator->() const { return static_cast<pointer>(*this); } value_type& operator*() const { return *static_cast<pointer>(*this); } typename PointerBaseConcept<PointerBase>::diff_type _offset; }; } // end of namespace tj using namespace std; using namespace tj; // Test the offset pointers char* heap; typedef simple_pointer_base<&heap, short> MyPointerBase; int main(int argc, char* argv[]) { heap = new char[1000]; PointerBaseConcept<MyPointerBase>::check(); // We create a few primitive objects, manually placing them // in the "heap" char* nextPtr = heap; const int I1 = 35, I2 = 42; const double D1 = 66.7, D2 = 77.4; int *ip1 = new (nextPtr) int(I1); int *ip2 = new (nextPtr += sizeof(*ip1)) int(I2); double *dp1 = new (nextPtr += sizeof(*ip2)) double(D1); double *dp2 = new (nextPtr += sizeof(*dp1)) double(D2); // Output the sizes and referenced values of the pointers cout << "size(ip1)=" << sizeof(ip1) << ", *ip1=" << *ip1 << '\n'; cout << "size(ip2)=" << sizeof(ip2) << ", *ip2=" << *ip2 << '\n'; cout << "size(dp1)=" << sizeof(dp1) << ", *dp1=" << *dp1 << '\n'; cout << "size(dp2)=" << sizeof(dp2) << ", *dp2=" << *dp2 << '\n'; // Create the offset pointers typedef offset_ptr<int, MyPointerBase> MyIntOffsetPtr; MyIntOffsetPtr sip1(ip1); MyIntOffsetPtr sip2(ip2); typedef offset_ptr<double, MyPointerBase> MyDoubleOffsetPtr; MyDoubleOffsetPtr sdp1(dp1); MyDoubleOffsetPtr sdp2(dp2); // Output the sizes and referenced values of the pointers cout << "size(sip1)=" << sizeof(sip1) << ", *sip1=" << *sip1 << '\n'; cout << "size(sip2)=" << sizeof(sip2) << ", *sip2=" << *sip2 << '\n'; cout << "size(sdp1)=" << sizeof(sdp1) << ", *sdp1=" << *sdp1 << '\n'; cout << "size(sdp2)=" << sizeof(sdp2) << ", *sdp2=" << *sdp2 << '\n'; }
participants (5)
-
Alexander Nasonov
-
Daniel Wallin
-
David Abrahams
-
David Bergman
-
Trey Jackson