This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
bug
- To: gcc-bugs at gcc dot gnu dot org
- Subject: bug
- From: Thomas Rudlof <Thomas dot Rudlof at mchp dot siemens dot de>
- Date: Fri, 18 Aug 2000 08:31:16 +0200
- Organization: Siemens AG
> #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> &)