timebuf.hh revision 1060
1/* 2 * Copyright (c) 2004 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#ifndef __BASE_TIMEBUF_HH__ 30#define __BASE_TIMEBUF_HH__ 31 32#include <vector> 33 34using namespace std; 35 36template <class T> 37class TimeBuffer 38{ 39 protected: 40 int past; 41 int future; 42 int size; 43 44 char *data; 45 vector<char *> index; 46 int base; 47 48 void valid(int idx) 49 { 50 assert (idx >= -past && idx <= future); 51 } 52 53 public: 54 friend class wire; 55 class wire 56 { 57 friend class TimeBuffer; 58 protected: 59 TimeBuffer<T> *buffer; 60 int index; 61 62 void set(int idx) 63 { 64 buffer->valid(idx); 65 index = idx; 66 } 67 68 wire(TimeBuffer<T> *buf, int i) 69 : buffer(buf), index(i) 70 { } 71 72 public: 73 wire() 74 { } 75 76 wire(const wire &i) 77 : buffer(i.buffer), index(i.index) 78 { } 79 80 const wire &operator=(const wire &i) 81 { 82 buffer = i.buffer; 83 set(i.index); 84 return *this; 85 } 86 87 const wire &operator=(int idx) 88 { 89 set(idx); 90 return *this; 91 } 92 93 const wire &operator+=(int offset) 94 { 95 set(index + offset); 96 return *this; 97 } 98 99 const wire &operator-=(int offset) 100 { 101 set(index - offset); 102 return *this; 103 } 104 105 wire &operator++() 106 { 107 set(index + 1); 108 return *this; 109 } 110 111 wire &operator++(int) 112 { 113 int i = index; 114 set(index + 1); 115 return wire(this, i); 116 } 117 118 wire &operator--() 119 { 120 set(index - 1); 121 return *this; 122 } 123 124 wire &operator--(int) 125 { 126 int i = index; 127 set(index - 1); 128 return wire(this, i); 129 } 130 T &operator*() const { return *buffer->access(index); } 131 T *operator->() const { return buffer->access(index); } 132 }; 133 134 135 public: 136 TimeBuffer(int p, int f) 137 : past(p), future(f), size(past + future + 1), 138 data(new char[size * sizeof(T)]), index(size), base(0) 139 { 140 assert(past >= 0 && future >= 0); 141 char *ptr = data; 142 for (int i = 0; i < size; i++) { 143 index[i] = ptr; 144 memset(ptr, 0, sizeof(T)); 145 new (ptr) T; 146 ptr += sizeof(T); 147 } 148 } 149 150 TimeBuffer() 151 : data(NULL) 152 { 153 } 154 155 ~TimeBuffer() 156 { 157 for (int i = 0; i < size; ++i) 158 (reinterpret_cast<T *>(index[i]))->~T(); 159 delete [] data; 160 } 161 162 void 163 advance() 164 { 165 if (++base >= size) 166 base = 0; 167 168 int ptr = base + future; 169 if (ptr >= size) 170 ptr -= size; 171 (reinterpret_cast<T *>(index[ptr]))->~T(); 172 memset(index[ptr], 0, sizeof(T)); 173 new (index[ptr]) T; 174 } 175 176 T *access(int idx) 177 { 178 //Need more complex math here to calculate index. 179 valid(idx); 180 181 int vector_index = idx + base; 182 if (vector_index >= size) { 183 vector_index -= size; 184 } else if (vector_index < 0) { 185 vector_index += size; 186 } 187 188 return reinterpret_cast<T *>(index[vector_index]); 189 } 190 191 T &operator[](int idx) 192 { 193 //Need more complex math here to calculate index. 194 valid(idx); 195 196 int vector_index = idx + base; 197 if (vector_index >= size) { 198 vector_index -= size; 199 } else if (vector_index < 0) { 200 vector_index += size; 201 } 202 203 return reinterpret_cast<T &>(*index[vector_index]); 204 } 205 206 wire getWire(int idx) 207 { 208 valid(idx); 209 210 return wire(this, idx); 211 } 212 213 wire zero() 214 { 215 return wire(this, 0); 216 } 217}; 218 219#endif // __BASE_TIMEBUF_HH__ 220 221