Imported Upstream version 0.12.7
[bowtie.git] / SeqAn-1.1 / seqan / basic / basic_volatile_ptr.h
1  /*==========================================================================
2                 SeqAn - The Library for Sequence Analysis
3                           http://www.seqan.de 
4  ============================================================================
5   Copyright (C) 2007
6
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public
9   License as published by the Free Software Foundation; either
10   version 3 of the License, or (at your option) any later version.
11
12   This library is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   Lesser General Public License for more details.
16
17  ============================================================================
18   $Id: basic_volatile_ptr.h,v 1.1 2008/08/25 16:20:01 langmead Exp $
19  ==========================================================================*/
20
21 #ifndef SEQAN_HEADER_BASIC_VOLATILE_PTR_H
22 #define SEQAN_HEADER_BASIC_VOLATILE_PTR_H
23
24 //////////////////////////////////////////////////////////////////////////////
25
26 namespace SEQAN_NAMESPACE_MAIN
27 {
28
29         //////////////////////////////////////////////////////////////////////////////
30         // volatile pointer
31         // allows you to handle volatile data (used by ext. string during swapping)
32     //
33         // imagine volatile pointers as nodes in an undirected graph
34     // when you assign one to another then they are connected
35     // all pointers in a connection component points to the same value
36     // by calling nukeCopies you can destroy the component and set all pointers to NULL
37
38         template < typename Type >
39         struct VolatilePtr
40         {
41                 typedef VolatilePtr             _Self;
42                 typedef VolatilePtr*    _SelfPtr;
43                 typedef VolatilePtr&    _SelfRef;
44
45                 typedef Type&                   reference;
46                 typedef const Type&             const_reference;
47                 typedef Type*                   pointer;
48
49                 pointer                 ptr;
50                 _SelfPtr                next;                   // prev == NULL means this is the master node
51                 _SelfPtr                prev;                   // prev == NULL means this is the master node
52
53         VolatilePtr() {     // volatile pinters behave like normal pointers
54             prev = this;    // and are not initialized (ptr) per default
55             next = this;
56         };
57
58         VolatilePtr(const pointer _p) {
59                         ptr = _p;
60                         prev = this;
61                         next = this;
62         }
63
64         VolatilePtr(const _Self& _vp) {
65                         ptr = _vp.ptr;
66                         prev = this;
67                         next = this;
68         }
69
70         VolatilePtr(_SelfRef _vp) {
71                         ptr = _vp.ptr;
72                         prev = this;
73                         next = this;
74                         if (ptr) hangOn(_vp);
75                 }
76
77                 ~VolatilePtr() {
78                         hangOff();
79                 }
80         
81         template <typename size_type>
82                 inline reference operator[] (size_type offset) {
83                         return ptr[offset];
84                 }
85
86         template <typename size_type>
87                 inline const_reference operator[] (size_type offset) const {
88                         return ptr[offset];
89                 }
90
91                 inline _Self& operator=(_Self const &_Right) {
92                         hangOff();
93                         ptr = _Right.ptr;
94             if (ptr) hangOn(const_cast<_Self&>(_Right));
95                         return *this;
96                 }
97
98                 inline _Self& operator=(pointer const _Right) {
99                         hangOff();
100                         ptr = _Right;
101                         return *this;
102                 }
103
104         inline bool isLonely() {
105             return next == this;
106         }
107
108                 inline void nukeCopies() {
109                         _SelfPtr p = next;
110                         while (p != this) {
111                                 _SelfPtr tmp = p->next;
112                                 p->ptr = NULL;
113                                 p->prev = p;
114                                 p->next = p;
115                                 p = tmp;
116                         }
117             prev = this;
118                         next = this;
119                 }
120
121                 inline bool operator== (const _Self &I) const {
122                         return ptr == I.ptr;
123                 }
124
125                 inline bool operator!= (const _Self &I) const {
126                         return ptr != I.ptr;
127                 }
128
129                 inline operator pointer () const {
130                         return ptr;
131                 }
132
133         private:
134
135                 inline void hangOn(_SelfRef _prev) {
136                         // hang on between _prev and _prev.next
137                         prev = &_prev;
138                         next = _prev.next;
139                         _prev.next = this;
140                         next->prev = this;
141                 }
142
143                 inline void hangOff() {
144                         next->prev = prev;
145                         prev->next = next;
146             next = this;
147             prev = this;
148                 }
149         };
150
151     template <typename TValue>
152     inline void nukeCopies(TValue* &) {}
153
154     template <typename TValue>
155     inline void nukeCopies(VolatilePtr<TValue> &ptr) { ptr.nukeCopies(); }
156
157 }
158
159 #endif