timebuf.hh revision 2291
1/* 2 * Copyright (c) 2004-2005 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 34template <class T> 35class TimeBuffer 36{ 37 protected: 38 int past; 39 int future; 40 int size; 41 42 char *data; 43 std::vector<char *> index; 44 int base; 45 46 void valid(int idx) 47 { 48 assert (idx >= -past && idx <= future); 49 } 50 51 public: 52 friend class wire; 53 class wire 54 { 55 friend class TimeBuffer; 56 protected: 57 TimeBuffer<T> *buffer; 58 int index; 59 60 void set(int idx) 61 { 62 buffer->valid(idx); 63 index = idx; 64 } 65 66 wire(TimeBuffer<T> *buf, int i) 67 : buffer(buf), index(i) 68 { } 69 70 public: 71 wire() 72 { } 73 74 wire(const wire &i) 75 : buffer(i.buffer), index(i.index) 76 { } 77 78 const wire &operator=(const wire &i) 79 { 80 buffer = i.buffer; 81 set(i.index); 82 return *this; 83 } 84 85 const wire &operator=(int idx) 86 { 87 set(idx); 88 return *this; 89 } 90 91 const wire &operator+=(int offset) 92 { 93 set(index + offset); 94 return *this; 95 } 96 97 const wire &operator-=(int offset) 98 { 99 set(index - offset); 100 return *this; 101 } 102 103 wire &operator++() 104 { 105 set(index + 1); 106 return *this; 107 } 108 109 wire &operator++(int) 110 { 111 int i = index; 112 set(index + 1); 113 return wire(this, i); 114 } 115 116 wire &operator--() 117 { 118 set(index - 1); 119 return *this; 120 } 121 122 wire &operator--(int) 123 { 124 int i = index; 125 set(index - 1); 126 return wire(this, i); 127 } 128 T &operator*() const { return *buffer->access(index); } 129 T *operator->() const { return buffer->access(index); } 130 }; 131 132 133 public: 134 TimeBuffer(int p, int f) 135 : past(p), future(f), size(past + future + 1), 136 data(new char[size * sizeof(T)]), index(size), base(0) 137 { 138 assert(past >= 0 && future >= 0); 139 char *ptr = data; 140 for (int i = 0; i < size; i++) { 141 index[i] = ptr; 142 memset(ptr, 0, sizeof(T)); 143 new (ptr) T; 144 ptr += sizeof(T); 145 } 146 } 147 148 TimeBuffer() 149 : data(NULL) 150 { 151 } 152 153 ~TimeBuffer() 154 { 155 for (int i = 0; i < size; ++i) 156 (reinterpret_cast<T *>(index[i]))->~T(); 157 delete [] data; 158 } 159 160 void 161 advance() 162 { 163 if (++base >= size) 164 base = 0; 165 166 int ptr = base + future; 167 if (ptr >= size) 168 ptr -= size; 169 (reinterpret_cast<T *>(index[ptr]))->~T(); 170 memset(index[ptr], 0, sizeof(T)); 171 new (index[ptr]) T; 172 } 173 174 T *access(int idx) 175 { 176 //Need more complex math here to calculate index. 177 valid(idx); 178 179 int vector_index = idx + base; 180 if (vector_index >= size) { 181 vector_index -= size; 182 } else if (vector_index < 0) { 183 vector_index += size; 184 } 185 186 return reinterpret_cast<T *>(index[vector_index]); 187 } 188 189 T &operator[](int idx) 190 { 191 //Need more complex math here to calculate index. 192 valid(idx); 193 194 int vector_index = idx + base; 195 if (vector_index >= size) { 196 vector_index -= size; 197 } else if (vector_index < 0) { 198 vector_index += size; 199 } 200 201 return reinterpret_cast<T &>(*index[vector_index]); 202 } 203 204 wire getWire(int idx) 205 { 206 valid(idx); 207 208 return wire(this, idx); 209 } 210 211 wire zero() 212 { 213 return wire(this, 0); 214 } 215}; 216 217#endif // __BASE_TIMEBUF_HH__ 218 219