This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

bug


> #include <cstdlib>
> #include <cassert>
> #include <functional>
> #include <iostream>
> 
> template<class V, class P = V*>
> class SmartPtr {
> public:
>         SmartPtr(const P& = P());
>         SmartPtr(const SmartPtr&);
>         ~SmartPtr();
> 
>         SmartPtr& operator=(const SmartPtr&);
>         V*        operator->() const { return *mP; }
>         V&        operator*() const { return &*mP; }
>         bool      operator==(const SmartPtr& a) const { return mP == a.mP; }
> protected:
>         P mP;
> };
> 
> template<class V, class P>
> SmartPtr<V,P>::SmartPtr(const P& p) : mP(p)
> {
>         if (mP != P()) {
>                 mP->incCount();
>         }
> }
> 
> template<class V, class P>
> SmartPtr<V,P>::SmartPtr(const SmartPtr& p) : mP(p)
> {
>         if (mP != P()) {
>                 mP->incCount();
>         }
> }
> 
> template<class V, class P>
> SmartPtr<V,P>::~SmartPtr()
> {
>         if (mP != P()) {
>                 mP->decCount();
>         }
> }
> 
> template<class V, class P>
> SmartPtr<V,P>& SmartPtr<V,P>::operator=(const SmartPtr& a)
> {
>         if (mP != P()) {
>                 mP->decCount();
>         }
>         if (a.mP != P()) {
>                 a.mP->incCount();
>         }
>         mP = a.mP;
>         return *this;
> }
> 
> template<class T>
> class TaggedPtr {
>         //! holds the value of the pointer and the tag
>         std::size_t mP;
> 
>         //! this constructor is for private use only ...
>         explicit TaggedPtr(std::size_t u) : mP(u) {}
> 
> public:
> 
>         //! the default constructor creates an untagged 0 pointer
>         TaggedPtr() : mP(0) {};
> 
> 
>         /*! a constructor taking a pointer whose lowest bit must be zero
>          *      and a boolean signaling whether the pointer shall be tagged
>          */
>         TaggedPtr(T* p, bool t = false)
>                 : mP(reinterpret_cast<std::size_t>(p) | (t ? std::size_t(1)
>
: std::size_t(0)))
>         {
>                 assert((reinterpret_cast<std::size_t>(p) & std::size_t(1)) == 0);
>         }
> 
>         //! the usual assigment operator
>         TaggedPtr& operator=(const TaggedPtr& p) {
>                 mP = p.mP;
>                 return *this;
>         }
> 
>         //! comparisons concern both values
>         bool operator==(const TaggedPtr& p) const { return mP == p.mP; }
> 
>         //! the opposite of the above
>         bool operator!=(const TaggedPtr& p) const { return !(*this == p); }
> 
>         //! default less operator
>         bool operator<(const TaggedPtr& p) const { return mP < p.mP; }
> 
>         //! returns the pointer with the tag inverted
>         TaggedPtr operator!() const { return mP ^ std::size_t(1); }
> 
>         //! like -> with respect to the pointer-value
>         T*       operator->() const { return pointer(); }
> 
>         //! like * with respect to the pointer-value
>         T&       operator*() const { return *pointer(); }
> 
>         //! checks wether pointer is tagged
>         bool tag() const { return (mP & std::size_t(1)) != 0; }
> 
>         //! changes the tag of the pointer
>         void tag(bool t) { mP = t ? mP | std::size_t(1) : mP & ~std::size_t(1);
> }
> 
>         //! flips the tag
>         void flip() { mP = mP & ~std::size_t(1) | std::size_t(1) & ~mP; }
> 
>         //! retuns the pointer's value
>         T* pointer() const { return reinterpret_cast<T*>(mP & ~std::size_t(1));
> }
> 
>         //! changes the pointer's value
>         void pointer(T* p) {
>                 mP = tag()
>                         ? reinterpret_cast<std::size_t>(p) | std::size_t(1)
>                         : reinterpret_cast<std::size_t>(p) & ~std::size_t(1);
>         }
> };
> 
> using namespace std;
> 
> struct C {
>         int i;
>         void incCount() { cout << (void*)this << ": incCount()" << endl; }
>         void decCount() { cout << (void*)this << ": decCount()" << endl; }
> };
> 
> int main()
> {
>         typedef SmartPtr<C>                SP;
>         typedef SmartPtr<C, TaggedPtr<C> > TSP;
> 
>         C c,d,e;
> 
>         SP  p1(&c);
>         TSP p2 = TaggedPtr<C>(&d);
>         TSP p3(&e);
> 
>         if (p2 == p3) { p1 = SmartPtr<C>(0); }
> }
> 
--------------------------------

compilation resulted in the following behaviour on a Linux 2.2.10:

schuette /home_local/thomas> g++ -v
Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/specs
gcc version 2.95.2 19991024 (release)
schuette /home_local/thomas> g++ bug.C
bug.C: In method `SmartPtr<C,TaggedPtr<C> >::SmartPtr(const
SmartPtr<C,TaggedPtr<C> > &)':
bug.C:143:   instantiated from here
bug.C:30: no matching function for call to `TaggedPtr<C>::TaggedPtr
(const SmartPtr<C,TaggedPtr<C> > &)'
bug.C:65: candidates are: TaggedPtr<C>::TaggedPtr(unsigned int)
bug.C:70:                 TaggedPtr<C>::TaggedPtr()
bug.C:77:                 TaggedPtr<C>::TaggedPtr(C *, bool = false)
bug.C:125:                 TaggedPtr<C>::TaggedPtr(const TaggedPtr<C> &)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]