ANTLR Support Libraries 2.7.1+
|
00001 #ifndef INC_CircularQueue_hpp__ 00002 #define INC_CircularQueue_hpp__ 00003 00004 /* ANTLR Translator Generator 00005 * Project led by Terence Parr at http://www.jGuru.com 00006 * Software rights: http://www.antlr.org/license.html 00007 * 00008 * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CircularQueue.hpp#2 $ 00009 */ 00010 00011 #include <antlr/config.hpp> 00012 #include <antlr/Token.hpp> 00013 #include <vector> 00014 #include <cassert> 00015 00016 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE 00017 namespace antlr { 00018 #endif 00019 00020 // Resize every 5000 items 00021 #define OFFSET_MAX_RESIZE 5000 00022 00023 template <class T> 00024 class ANTLR_API CircularQueue { 00025 public: 00026 CircularQueue() 00027 : storage() 00028 , m_offset(0) 00029 { 00030 } 00031 ~CircularQueue() 00032 { 00033 } 00034 00036 inline void clear( void ) 00037 { 00038 m_offset = 0; 00039 storage.clear(); 00040 } 00041 00043 inline T elementAt( size_t idx ) const 00044 { 00045 return storage[idx+m_offset]; 00046 } 00047 void removeFirst() 00048 { 00049 if (m_offset >= OFFSET_MAX_RESIZE) 00050 { 00051 storage.erase( storage.begin(), storage.begin() + m_offset + 1 ); 00052 m_offset = 0; 00053 } 00054 else 00055 ++m_offset; 00056 } 00057 inline void removeItems( size_t nb ) 00058 { 00059 // it would be nice if we would not get called with nb > entries 00060 // (or to be precise when entries() == 0) 00061 // This case is possible when lexer/parser::recover() calls 00062 // consume+consumeUntil when the queue is empty. 00063 // In recover the consume says to prepare to read another 00064 // character/token. Then in the subsequent consumeUntil the 00065 // LA() call will trigger 00066 // syncConsume which calls this method *before* the same queue 00067 // has been sufficiently filled. 00068 if( nb > entries() ) 00069 nb = entries(); 00070 00071 if (m_offset >= OFFSET_MAX_RESIZE) 00072 { 00073 storage.erase( storage.begin(), storage.begin() + m_offset + nb ); 00074 m_offset = 0; 00075 } 00076 else 00077 m_offset += nb; 00078 } 00079 inline void append(const T& t) 00080 { 00081 storage.push_back(t); 00082 } 00083 inline size_t entries() const 00084 { 00085 return storage.size() - m_offset; 00086 } 00087 00088 private: 00089 ANTLR_USE_NAMESPACE(std)vector<T> storage; 00090 size_t m_offset; 00091 00092 CircularQueue(const CircularQueue&); 00093 const CircularQueue& operator=(const CircularQueue&); 00094 }; 00095 00096 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE 00097 } 00098 #endif 00099 00100 #endif //INC_CircularQueue_hpp__