lemon/refptr.h
author deba
Wed, 01 Mar 2006 10:17:25 +0000
changeset 1990 15fb7a4ea6be
child 2151 38ec4a930c05
permissions -rw-r--r--
Some classes assumed that the GraphMaps should be inherited
from an ObserverBase. These classes parents replaced with
DefaultMap which cause that the graph maps should not be
inherited from the ObserverBase.
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@1977
    48
      prev=&r; next=r.next; ref=r.ref;
alpar@1977
    49
      r.next=this;
alpar@1977
    50
    }
alpar@1977
    51
    void attach(const T *p) 
alpar@1977
    52
    {
alpar@1977
    53
      prev=0; next=0; ref=p;
alpar@1977
    54
    }
alpar@1977
    55
    void release() 
alpar@1977
    56
    {
alpar@1977
    57
      if(ref) {
alpar@1977
    58
	bool fr=true;
alpar@1977
    59
	if(prev) { fr=false; prev->next=next; }
alpar@1977
    60
	if(next) { fr=false; next->prev=prev; }
alpar@1977
    61
	if(fr) delete ref;
alpar@1977
    62
	ref=0;
alpar@1977
    63
      }
alpar@1977
    64
    }
alpar@1977
    65
  
alpar@1977
    66
  public:
alpar@1977
    67
    ///\e
alpar@1977
    68
    RefPtr() : ref(0) {}
alpar@1977
    69
alpar@1977
    70
    ///\e
alpar@1977
    71
    RefPtr(const RefPtr &r) {
alpar@1977
    72
      lock();
alpar@1977
    73
      attach(const_cast<RefPtr&>(r));
alpar@1977
    74
      unlock();
alpar@1977
    75
    }
alpar@1977
    76
alpar@1977
    77
    ///\e
alpar@1977
    78
    RefPtr(T *p) : prev(0), next(0), ref(p) {}
alpar@1977
    79
alpar@1977
    80
    ///\e
alpar@1977
    81
    ~RefPtr() {
alpar@1977
    82
      lock();
alpar@1977
    83
      release();
alpar@1977
    84
      unlock();
alpar@1977
    85
    }
alpar@1977
    86
alpar@1977
    87
    ///\e
alpar@1977
    88
    const RefPtr &operator=(const RefPtr &r) { 
alpar@1977
    89
      if(ref!=r.ref) {
alpar@1977
    90
	lock();
alpar@1977
    91
	release(); attach(const_cast<RefPtr&>(r));
alpar@1977
    92
	unlock();
alpar@1977
    93
      }
alpar@1977
    94
      return *this;
alpar@1977
    95
    }
alpar@1977
    96
  
alpar@1977
    97
    ///\e
alpar@1977
    98
    const RefPtr &operator=(const T* &p) { 
alpar@1977
    99
      if(ref!=p) { lock(); release(); attach(p); unlock(); }
alpar@1977
   100
      return *this;
alpar@1977
   101
    }
alpar@1977
   102
  
alpar@1977
   103
    ///\e
alpar@1977
   104
    void swap(RefPtr &r) {
alpar@1977
   105
      RefPtr *p;
alpar@1977
   106
      T *tp;
alpar@1977
   107
      lock();
alpar@1977
   108
      p=prev; prev=r.prev; r.prev=p;
alpar@1977
   109
      p=next; next=r.next; r.next=p;
alpar@1977
   110
      tp=ref; ref=r.ref; r.ref=tp;
alpar@1977
   111
      unlock();
alpar@1977
   112
    }
alpar@1977
   113
alpar@1977
   114
    ///\e
alpar@1977
   115
    void clear() { lock(); release(); unlock(); }
alpar@1977
   116
alpar@1977
   117
    ///\e
alpar@1977
   118
    T * operator->() { return ref; }
alpar@1977
   119
    ///\e
alpar@1977
   120
    const T * operator->() const { return ref; }
alpar@1977
   121
    ///\e
alpar@1977
   122
    operator T *() { return ref; }
alpar@1977
   123
    ///\e
alpar@1977
   124
    operator const T *() const { return ref; }
alpar@1977
   125
    
alpar@1977
   126
    ///\e
alpar@1977
   127
    bool operator<(const RefPtr &r) const { return this->ref < r.ref; }
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
    
alpar@1977
   139
    ///\e
alpar@1977
   140
    operator bool() const { return ref; }
alpar@1977
   141
alpar@1977
   142
  };  //END OF CLASS REFPTR
alpar@1977
   143
  
alpar@1977
   144
} //END OF NAMESPACE LEMON
alpar@1977
   145
alpar@1977
   146
#endif