Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 1999-11-22 14:55:35


(Moving this thread to boost)

How about a partial specialization on base_ptr for when the Deleter is a
function pointer? We do get duplication of code, but the duplication
seems to be down at a low level class, that the higher classes can
blindly reuse. Here is a fragment that is printing out on my system:

4
8

template<typename T> class deleter
{
public:
 void operator()(T*& p) throw() { delete p; p = 0; };
};

template<typename T> class array_deleter
{
public:
 void operator()(T*& p) throw() { delete[] p; p = 0; };
};

template <typename Base, typename Member> struct base_opt : Base {
    Member m;
    base_opt(Base const& b, Member const& m) : Base(b), m(m) {}
 base_opt(const base_opt& rhs) throw() : Base(rhs) { m = rhs.m; }
};

template<typename T , typename Deleter = deleter<T> >
class base_ptr
{
public:
        typedef T element_type;

        T& operator*() const throw() { return *ptr(); }
        T* operator->() const throw() { return ptr(); }
        T* get() const throw() { return ptr(); }

protected:
        T*& ptr() { return deleter.m; }
        T* ptr() const { return deleter.m; }
        void del() { deleter.del(deleter.m); }
        void del(T* p) { deleter.del(p); };
        base_ptr(T* p,Deleter d) throw() : deleter(_Deleter(d),p) {};

private:
        base_opt< Deleter, T* > deleter;
};

template<typename T>
class base_ptr<T, void (*)(T*)>
{
public:
        typedef void (*Deleter)(T*);
        typedef T element_type;

        T& operator*() const throw() { return *ptr(); }
        T* operator->() const throw() { return ptr(); }
        T* get() const throw() { return ptr(); }

protected:
        T*& ptr() { return m; }
        T* ptr() const { return m; }
        void del() { deleter(m); }
        void del(T* p) { deleter(p); };
        base_ptr(T* p, Deleter d) throw() : deleter(d ,p) {};

private:
        Deleter deleter;
        T* m;
};

#include <iostream>

int main()
{
        std::cout << sizeof(base_ptr<int>) << '\n';
        std::cout << sizeof(base_ptr<int, void (*)(int*)>) << '\n';
}

-Howard

Michel André wrote on 11/22/99 1:13 PM
>Hello!
>
>Sorry for my slippery fingers!
>
>> > One fix is to wrap Deleter up in a nested wrapper class before you pass
>> > it to base_opt (much like std::map wraps Compare with value_compare).
>> > That ensures that base_opt sees a class, even if the user tosses in a
>> > function pointer. Hopefully the overhead of this wrapping will be nil


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