lemon/refptr.h
author klao
Fri, 03 Mar 2006 21:49:39 +0000
changeset 1997 b7a70cdb5520
child 2151 38ec4a930c05
permissions -rw-r--r--
Bugfix: an ugly artefact of the 'id' -> 'label' renaming
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