1 |
#ifndef INC_CircularQueue_hpp__ |
2 |
#define INC_CircularQueue_hpp__ |
3 |
|
4 |
/* ANTLR Translator Generator |
5 |
* Project led by Terence Parr at http://www.jGuru.com |
6 |
* Software rights: http://www.antlr.org/license.html |
7 |
* |
8 |
* $Id$ |
9 |
*/ |
10 |
|
11 |
#include <antlr/config.hpp> |
12 |
#include <antlr/Token.hpp> |
13 |
#include <vector> |
14 |
#include <cassert> |
15 |
|
16 |
#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE |
17 |
namespace antlr { |
18 |
#endif |
19 |
|
20 |
// Resize every 5000 items |
21 |
#define OFFSET_MAX_RESIZE 5000 |
22 |
|
23 |
template <class T> |
24 |
class ANTLR_API CircularQueue { |
25 |
public: |
26 |
CircularQueue() |
27 |
: storage() |
28 |
, m_offset(0) |
29 |
{ |
30 |
} |
31 |
~CircularQueue() |
32 |
{ |
33 |
} |
34 |
|
35 |
/// Clear the queue |
36 |
inline void clear( void ) |
37 |
{ |
38 |
m_offset = 0; |
39 |
storage.clear(); |
40 |
} |
41 |
|
42 |
/// @todo this should use at or should have a check |
43 |
inline T elementAt( size_t idx ) const |
44 |
{ |
45 |
return storage[idx+m_offset]; |
46 |
} |
47 |
void removeFirst() |
48 |
{ |
49 |
if (m_offset >= OFFSET_MAX_RESIZE) |
50 |
{ |
51 |
storage.erase( storage.begin(), storage.begin() + m_offset + 1 ); |
52 |
m_offset = 0; |
53 |
} |
54 |
else |
55 |
++m_offset; |
56 |
} |
57 |
inline void removeItems( size_t nb ) |
58 |
{ |
59 |
// it would be nice if we would not get called with nb > entries |
60 |
// (or to be precise when entries() == 0) |
61 |
// This case is possible when lexer/parser::recover() calls |
62 |
// consume+consumeUntil when the queue is empty. |
63 |
// In recover the consume says to prepare to read another |
64 |
// character/token. Then in the subsequent consumeUntil the |
65 |
// LA() call will trigger |
66 |
// syncConsume which calls this method *before* the same queue |
67 |
// has been sufficiently filled. |
68 |
if( nb > entries() ) |
69 |
nb = entries(); |
70 |
|
71 |
if (m_offset >= OFFSET_MAX_RESIZE) |
72 |
{ |
73 |
storage.erase( storage.begin(), storage.begin() + m_offset + nb ); |
74 |
m_offset = 0; |
75 |
} |
76 |
else |
77 |
m_offset += nb; |
78 |
} |
79 |
inline void append(const T& t) |
80 |
{ |
81 |
storage.push_back(t); |
82 |
} |
83 |
inline size_t entries() const |
84 |
{ |
85 |
return storage.size() - m_offset; |
86 |
} |
87 |
|
88 |
private: |
89 |
ANTLR_USE_NAMESPACE(std)vector<T> storage; |
90 |
size_t m_offset; |
91 |
|
92 |
CircularQueue(const CircularQueue&); |
93 |
const CircularQueue& operator=(const CircularQueue&); |
94 |
}; |
95 |
|
96 |
#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE |
97 |
} |
98 |
#endif |
99 |
|
100 |
#endif //INC_CircularQueue_hpp__ |