lemon/refptr.h
author deba
Wed, 06 Sep 2006 09:55:37 +0000
changeset 2199 1229af45cc69
parent 1977 8ef02f0c4245
child 2391 14a343be7a5a
permissions -rw-r--r--
Bug fix
alpar@1977
     1
/* -*- C++ -*-
alpar@1977
     2
 *
alpar@1977
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1977
     4
 *
alpar@1977
     5
 * Copyright (C) 2003-2006
alpar@1977
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1977
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@1977
     8
 *
alpar@1977
     9
 * Permission to use, modify and distribute this software is granted
alpar@1977
    10
 * provided that this copyright notice appears in all copies. For
alpar@1977
    11
 * precise terms see the accompanying LICENSE file.
alpar@1977
    12
 *
alpar@1977
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@1977
    14
 * express or implied, and with no claim as to its suitability for any
alpar@1977
    15
 * purpose.
alpar@1977
    16
 *
alpar@1977
    17
 */
alpar@1977
    18
alpar@1977
    19
#ifndef LEMON_REFPTR_H
alpar@1977
    20
#define LEMON_REFPTR_H
alpar@1977
    21
alpar@1977
    22
///\ingroup misc
alpar@1977
    23
///\file
alpar@1977
    24
///\brief A reference counted pointer implementation.
alpar@1977
    25
///
alpar@1977
    26
///\todo Undocumented
alpar@1977
    27
alpar@1977
    28
alpar@1977
    29
namespace lemon {
alpar@1977
    30
alpar@1977
    31
  
alpar@1977
    32
  ///Reference counted pointer
alpar@1977
    33
alpar@1977
    34
  ///This is a simple implementation of a reference counted pointer.
alpar@1977
    35
  ///
alpar@1977
    36
  ///\warning Current implementation is far from being thread-safe.
alpar@1977
    37
  template<class T>
alpar@1977
    38
  class RefPtr 
alpar@1977
    39
  {
alpar@1977
    40
    mutable RefPtr *prev, *next;
alpar@1977
    41
    T *ref;
alpar@1977
    42
alpar@1977
    43
    void lock() {}
alpar@1977
    44
    void unlock() {}
alpar@1977
    45
    
alpar@1977
    46
    void attach(RefPtr &r) 
alpar@1977
    47
    {
alpar@2151
    48
      if(r.ref) {
alpar@2151
    49
	prev=&r; next=r.next; ref=r.ref;
alpar@2151
    50
	r.next=this;
alpar@2151
    51
      }
alpar@1977
    52
    }
alpar@1977
    53
    void attach(const T *p) 
alpar@1977
    54
    {
alpar@1977
    55
      prev=0; next=0; ref=p;
alpar@1977
    56
    }
alpar@1977
    57
    void release() 
alpar@1977
    58
    {
alpar@1977
    59
      if(ref) {
alpar@1977
    60
	bool fr=true;
alpar@1977
    61
	if(prev) { fr=false; prev->next=next; }
alpar@1977
    62
	if(next) { fr=false; next->prev=prev; }
alpar@1977
    63
	if(fr) delete ref;
alpar@1977
    64
	ref=0;
alpar@1977
    65
      }
alpar@1977
    66
    }
alpar@1977
    67
  
alpar@1977
    68
  public:
alpar@1977
    69
    ///\e
alpar@1977
    70
    RefPtr() : ref(0) {}
alpar@1977
    71
alpar@1977
    72
    ///\e
alpar@1977
    73
    RefPtr(const RefPtr &r) {
alpar@1977
    74
      lock();
alpar@1977
    75
      attach(const_cast<RefPtr&>(r));
alpar@1977
    76
      unlock();
alpar@1977
    77
    }
alpar@1977
    78
alpar@1977
    79
    ///\e
alpar@1977
    80
    RefPtr(T *p) : prev(0), next(0), ref(p) {}
alpar@1977
    81
alpar@1977
    82
    ///\e
alpar@1977
    83
    ~RefPtr() {
alpar@1977
    84
      lock();
alpar@1977
    85
      release();
alpar@1977
    86
      unlock();
alpar@1977
    87
    }
alpar@1977
    88
alpar@1977
    89
    ///\e
alpar@1977
    90
    const RefPtr &operator=(const RefPtr &r) { 
alpar@1977
    91
      if(ref!=r.ref) {
alpar@1977
    92
	lock();
alpar@1977
    93
	release(); attach(const_cast<RefPtr&>(r));
alpar@1977
    94
	unlock();
alpar@1977
    95
      }
alpar@1977
    96
      return *this;
alpar@1977
    97
    }
alpar@1977
    98
  
alpar@1977
    99
    ///\e
alpar@1977
   100
    const RefPtr &operator=(const T* &p) { 
alpar@1977
   101
      if(ref!=p) { lock(); release(); attach(p); unlock(); }
alpar@1977
   102
      return *this;
alpar@1977
   103
    }
alpar@1977
   104
  
alpar@1977
   105
    ///\e
alpar@1977
   106
    void swap(RefPtr &r) {
alpar@1977
   107
      RefPtr *p;
alpar@1977
   108
      T *tp;
alpar@1977
   109
      lock();
alpar@1977
   110
      p=prev; prev=r.prev; r.prev=p;
alpar@1977
   111
      p=next; next=r.next; r.next=p;
alpar@1977
   112
      tp=ref; ref=r.ref; r.ref=tp;
alpar@1977
   113
      unlock();
alpar@1977
   114
    }
alpar@1977
   115
alpar@1977
   116
    ///\e
alpar@1977
   117
    void clear() { lock(); release(); unlock(); }
alpar@1977
   118
alpar@1977
   119
    ///\e
alpar@1977
   120
    T * operator->() { return ref; }
alpar@1977
   121
    ///\e
alpar@1977
   122
    const T * operator->() const { return ref; }
alpar@1977
   123
    ///\e
alpar@1977
   124
    operator T *() { return ref; }
alpar@1977
   125
    ///\e
alpar@1977
   126
    operator const T *() const { return ref; }
alpar@1977
   127
    
alpar@1977
   128
    ///\e
alpar@1977
   129
    bool operator<(const RefPtr &r) const { return this->ref < r.ref; }
alpar@1977
   130
    ///\e
alpar@1977
   131
    bool operator<=(const RefPtr &r) const { return this->ref <= r.ref; }
alpar@1977
   132
    ///\e
alpar@1977
   133
    bool operator==(const RefPtr &r) const { return this->ref == r.ref; }
alpar@1977
   134
    ///\e
alpar@1977
   135
    bool operator>=(const RefPtr &r) const { return this->ref >= r.ref; }
alpar@1977
   136
    ///\e
alpar@1977
   137
    bool operator>(const RefPtr &r) const { return this->ref > r.ref; }
alpar@1977
   138
    ///\e
alpar@1977
   139
    bool operator!=(const RefPtr &r) const { return this->ref != r.ref; }
alpar@1977
   140
    
alpar@1977
   141
    ///\e
alpar@1977
   142
    operator bool() const { return ref; }
alpar@1977
   143
alpar@2151
   144
    ///\e
alpar@2151
   145
    const RefPtr &borrow(const T* &p) { 
alpar@2151
   146
      lock();
alpar@2151
   147
      if(ref==p) {
alpar@2151
   148
	if(prev) prev->next=next;
alpar@2151
   149
	if(next) next->prev=prev;
alpar@2151
   150
      }
alpar@2151
   151
      else release();
alpar@2151
   152
      ref=p;
alpar@2151
   153
      next=prev=this;
alpar@2151
   154
      unlock();
alpar@2151
   155
      return *this;
alpar@2151
   156
    }
alpar@2151
   157
    
alpar@2151
   158
    ///\e
alpar@2151
   159
    const RefPtr &borrow() { 
alpar@2151
   160
      lock();
alpar@2151
   161
      if(prev) prev->next=next;
alpar@2151
   162
      if(next) next->prev=prev;
alpar@2151
   163
      next=prev=this;
alpar@2151
   164
      unlock();
alpar@2151
   165
      return *this;
alpar@2151
   166
    }
alpar@2151
   167
    
alpar@1977
   168
  };  //END OF CLASS REFPTR
alpar@1977
   169
  
alpar@1977
   170
} //END OF NAMESPACE LEMON
alpar@1977
   171
alpar@1977
   172
#endif