RefPtr: a reference counted pointer class
authoralpar
Tue, 21 Feb 2006 12:37:00 +0000
changeset 19778ef02f0c4245
parent 1976 a71f388045f9
child 1978 ef2d00e46897
RefPtr: a reference counted pointer class
lemon/Makefile.am
lemon/refptr.h
test/Makefile.am
test/refptr_test.cc
     1.1 --- a/lemon/Makefile.am	Tue Feb 21 08:48:11 2006 +0000
     1.2 +++ b/lemon/Makefile.am	Tue Feb 21 12:37:00 2006 +0000
     1.3 @@ -68,6 +68,7 @@
     1.4  	prim.h \
     1.5  	radix_heap.h \
     1.6  	radix_sort.h \
     1.7 +	refptr.h \
     1.8  	simann.h \
     1.9  	smart_graph.h \
    1.10  	sub_graph.h \
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/lemon/refptr.h	Tue Feb 21 12:37:00 2006 +0000
     2.3 @@ -0,0 +1,146 @@
     2.4 +/* -*- C++ -*-
     2.5 + *
     2.6 + * This file is a part of LEMON, a generic C++ optimization library
     2.7 + *
     2.8 + * Copyright (C) 2003-2006
     2.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    2.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    2.11 + *
    2.12 + * Permission to use, modify and distribute this software is granted
    2.13 + * provided that this copyright notice appears in all copies. For
    2.14 + * precise terms see the accompanying LICENSE file.
    2.15 + *
    2.16 + * This software is provided "AS IS" with no warranty of any kind,
    2.17 + * express or implied, and with no claim as to its suitability for any
    2.18 + * purpose.
    2.19 + *
    2.20 + */
    2.21 +
    2.22 +#ifndef LEMON_REFPTR_H
    2.23 +#define LEMON_REFPTR_H
    2.24 +
    2.25 +///\ingroup misc
    2.26 +///\file
    2.27 +///\brief A reference counted pointer implementation.
    2.28 +///
    2.29 +///\todo Undocumented
    2.30 +
    2.31 +
    2.32 +namespace lemon {
    2.33 +
    2.34 +  
    2.35 +  ///Reference counted pointer
    2.36 +
    2.37 +  ///This is a simple implementation of a reference counted pointer.
    2.38 +  ///
    2.39 +  ///\warning Current implementation is far from being thread-safe.
    2.40 +  template<class T>
    2.41 +  class RefPtr 
    2.42 +  {
    2.43 +    mutable RefPtr *prev, *next;
    2.44 +    T *ref;
    2.45 +
    2.46 +    void lock() {}
    2.47 +    void unlock() {}
    2.48 +    
    2.49 +    void attach(RefPtr &r) 
    2.50 +    {
    2.51 +      prev=&r; next=r.next; ref=r.ref;
    2.52 +      r.next=this;
    2.53 +    }
    2.54 +    void attach(const T *p) 
    2.55 +    {
    2.56 +      prev=0; next=0; ref=p;
    2.57 +    }
    2.58 +    void release() 
    2.59 +    {
    2.60 +      if(ref) {
    2.61 +	bool fr=true;
    2.62 +	if(prev) { fr=false; prev->next=next; }
    2.63 +	if(next) { fr=false; next->prev=prev; }
    2.64 +	if(fr) delete ref;
    2.65 +	ref=0;
    2.66 +      }
    2.67 +    }
    2.68 +  
    2.69 +  public:
    2.70 +    ///\e
    2.71 +    RefPtr() : ref(0) {}
    2.72 +
    2.73 +    ///\e
    2.74 +    RefPtr(const RefPtr &r) {
    2.75 +      lock();
    2.76 +      attach(const_cast<RefPtr&>(r));
    2.77 +      unlock();
    2.78 +    }
    2.79 +
    2.80 +    ///\e
    2.81 +    RefPtr(T *p) : prev(0), next(0), ref(p) {}
    2.82 +
    2.83 +    ///\e
    2.84 +    ~RefPtr() {
    2.85 +      lock();
    2.86 +      release();
    2.87 +      unlock();
    2.88 +    }
    2.89 +
    2.90 +    ///\e
    2.91 +    const RefPtr &operator=(const RefPtr &r) { 
    2.92 +      if(ref!=r.ref) {
    2.93 +	lock();
    2.94 +	release(); attach(const_cast<RefPtr&>(r));
    2.95 +	unlock();
    2.96 +      }
    2.97 +      return *this;
    2.98 +    }
    2.99 +  
   2.100 +    ///\e
   2.101 +    const RefPtr &operator=(const T* &p) { 
   2.102 +      if(ref!=p) { lock(); release(); attach(p); unlock(); }
   2.103 +      return *this;
   2.104 +    }
   2.105 +  
   2.106 +    ///\e
   2.107 +    void swap(RefPtr &r) {
   2.108 +      RefPtr *p;
   2.109 +      T *tp;
   2.110 +      lock();
   2.111 +      p=prev; prev=r.prev; r.prev=p;
   2.112 +      p=next; next=r.next; r.next=p;
   2.113 +      tp=ref; ref=r.ref; r.ref=tp;
   2.114 +      unlock();
   2.115 +    }
   2.116 +
   2.117 +    ///\e
   2.118 +    void clear() { lock(); release(); unlock(); }
   2.119 +
   2.120 +    ///\e
   2.121 +    T * operator->() { return ref; }
   2.122 +    ///\e
   2.123 +    const T * operator->() const { return ref; }
   2.124 +    ///\e
   2.125 +    operator T *() { return ref; }
   2.126 +    ///\e
   2.127 +    operator const T *() const { return ref; }
   2.128 +    
   2.129 +    ///\e
   2.130 +    bool operator<(const RefPtr &r) const { return this->ref < r.ref; }
   2.131 +    ///\e
   2.132 +    bool operator<=(const RefPtr &r) const { return this->ref <= r.ref; }
   2.133 +    ///\e
   2.134 +    bool operator==(const RefPtr &r) const { return this->ref == r.ref; }
   2.135 +    ///\e
   2.136 +    bool operator>=(const RefPtr &r) const { return this->ref >= r.ref; }
   2.137 +    ///\e
   2.138 +    bool operator>(const RefPtr &r) const { return this->ref > r.ref; }
   2.139 +    ///\e
   2.140 +    bool operator!=(const RefPtr &r) const { return this->ref != r.ref; }
   2.141 +    
   2.142 +    ///\e
   2.143 +    operator bool() const { return ref; }
   2.144 +
   2.145 +  };  //END OF CLASS REFPTR
   2.146 +  
   2.147 +} //END OF NAMESPACE LEMON
   2.148 +
   2.149 +#endif
     3.1 --- a/test/Makefile.am	Tue Feb 21 08:48:11 2006 +0000
     3.2 +++ b/test/Makefile.am	Tue Feb 21 12:37:00 2006 +0000
     3.3 @@ -30,6 +30,7 @@
     3.4  	path_test \
     3.5  	preflow_test \
     3.6  	radix_sort_test \
     3.7 +	refptr_test \
     3.8  	test_tools_fail \
     3.9  	test_tools_pass \
    3.10  	time_measure_test \
    3.11 @@ -67,6 +68,7 @@
    3.12  suurballe_test_SOURCES = suurballe_test.cc
    3.13  path_test_SOURCES = path_test.cc
    3.14  radix_sort_test_SOURCES = radix_sort_test.cc
    3.15 +refptr_test_SOURCES = refptr_test.cc
    3.16  preflow_test_SOURCES = preflow_test.cc
    3.17  time_measure_test_SOURCES = time_measure_test.cc
    3.18  test_tools_fail_SOURCES = test_tools_fail.cc
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/refptr_test.cc	Tue Feb 21 12:37:00 2006 +0000
     4.3 @@ -0,0 +1,61 @@
     4.4 +/* -*- C++ -*-
     4.5 + *
     4.6 + * This file is a part of LEMON, a generic C++ optimization library
     4.7 + *
     4.8 + * Copyright (C) 2003-2006
     4.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    4.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    4.11 + *
    4.12 + * Permission to use, modify and distribute this software is granted
    4.13 + * provided that this copyright notice appears in all copies. For
    4.14 + * precise terms see the accompanying LICENSE file.
    4.15 + *
    4.16 + * This software is provided "AS IS" with no warranty of any kind,
    4.17 + * express or implied, and with no claim as to its suitability for any
    4.18 + * purpose.
    4.19 + *
    4.20 + */
    4.21 +
    4.22 +#include<lemon/refptr.h>
    4.23 +#include "test_tools.h"
    4.24 +#include <iostream>
    4.25 +
    4.26 +class Test 
    4.27 +{
    4.28 +  int &_counter;
    4.29 +public:
    4.30 +  Test(int &co) : _counter(co)
    4.31 +  {
    4.32 +    std::cerr << "Init\n";
    4.33 +    _counter++;
    4.34 +  }
    4.35 +  ~Test()
    4.36 +  {
    4.37 +    std::cerr << "Destroy\n";
    4.38 +    _counter--;
    4.39 +  }
    4.40 +  int &counter() { return _counter; }
    4.41 +  
    4.42 +};
    4.43 +
    4.44 +int main()
    4.45 +{
    4.46 +  int c=0;
    4.47 +  
    4.48 +  {
    4.49 +    RefPtr<Test> a = new Test(c);
    4.50 +    check(a->counter() == 1, "Wrong number of initialization");
    4.51 +    {
    4.52 +      RefPtr<Test> b = a;
    4.53 +      check((*b).counter() == 1, "Wrong number of initialization");
    4.54 +      b=a;
    4.55 +      a=b;
    4.56 +      check((*a).counter() == 1, "Wrong number of initialization");
    4.57 +    }
    4.58 +    check(a->counter() == 1, "Wrong number of initialization");
    4.59 +  }
    4.60 +  check(c == 0, "Wrong number of initialization");
    4.61 +
    4.62 +  return 0;
    4.63 +}
    4.64 +