lemon/refptr.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 1977 8ef02f0c4245
child 2391 14a343be7a5a
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
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