diff --git a/aegisub/libaegisub/include/libaegisub/cajun/elements.h b/aegisub/libaegisub/include/libaegisub/cajun/elements.h index bfe16d6df..4694bdab1 100644 --- a/aegisub/libaegisub/include/libaegisub/cajun/elements.h +++ b/aegisub/libaegisub/include/libaegisub/cajun/elements.h @@ -116,14 +116,10 @@ private: class Imp_T; class CastVisitor; - class ConstCastVisitor; template class CastVisitor_T; - template - class ConstCastVisitor_T; - template const ElementTypeT& CastTo() const; diff --git a/aegisub/libaegisub/include/libaegisub/cajun/elements.inl b/aegisub/libaegisub/include/libaegisub/cajun/elements.inl index 129777e2d..cc09076da 100644 --- a/aegisub/libaegisub/include/libaegisub/cajun/elements.inl +++ b/aegisub/libaegisub/include/libaegisub/cajun/elements.inl @@ -42,18 +42,16 @@ public: virtual bool Compare(const Imp& imp) const { - ConstCastVisitor_T castVisitor; + CastVisitor_T castVisitor; imp.Accept(castVisitor); - return castVisitor.m_pElement && - m_Element == *castVisitor.m_pElement; + return castVisitor.element && m_Element == *castVisitor.element; } private: ElementTypeT m_Element; }; - -class UnknownElement::ConstCastVisitor : public ConstVisitor +class UnknownElement::CastVisitor : public ConstVisitor { virtual void Visit(const Array&) {} virtual void Visit(const Object&) {} @@ -63,38 +61,17 @@ class UnknownElement::ConstCastVisitor : public ConstVisitor virtual void Visit(const Null&) {} }; -template -class UnknownElement::ConstCastVisitor_T : public ConstCastVisitor -{ -public: - ConstCastVisitor_T() : m_pElement(0) {} - virtual void Visit(const ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions - const ElementTypeT* m_pElement; -}; - - -class UnknownElement::CastVisitor : public Visitor -{ - virtual void Visit(Array&) {} - virtual void Visit(Object&) {} - virtual void Visit(Number&) {} - virtual void Visit(String&) {} - virtual void Visit(Boolean&) {} - virtual void Visit(Null&) {} -}; - template class UnknownElement::CastVisitor_T : public CastVisitor { public: - CastVisitor_T() : m_pElement(0) {} - virtual void Visit(ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions - ElementTypeT* m_pElement; + const ElementTypeT *element; + CastVisitor_T() : element(0) { } + + // we don't know what this is, but it overrides one of the base's no-op functions + void Visit(const ElementTypeT& element) { this->element = &element; } }; - - - inline UnknownElement::UnknownElement() : m_pImp( new Imp_T( Null() ) ) {} inline UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {} inline UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T(object) ) {} @@ -162,31 +139,27 @@ inline const UnknownElement& UnknownElement::operator[] (size_t index) const template const ElementTypeT& UnknownElement::CastTo() const { - ConstCastVisitor_T castVisitor; + CastVisitor_T castVisitor; m_pImp->Accept(castVisitor); - if (castVisitor.m_pElement == 0) + if (!castVisitor.element) throw Exception("Bad cast"); - return *castVisitor.m_pElement; + return *castVisitor.element; } - - template ElementTypeT& UnknownElement::ConvertTo() { CastVisitor_T castVisitor; - m_pImp->Accept(castVisitor); - if (castVisitor.m_pElement == 0) + Accept(castVisitor); + if (!castVisitor.element) { // we're not the right type. fix it & try again *this = ElementTypeT(); - m_pImp->Accept(castVisitor); } - return *castVisitor.m_pElement; + return *this; } - inline void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); } inline void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); } diff --git a/aegisub/libaegisub/include/libaegisub/cajun/reader.inl b/aegisub/libaegisub/include/libaegisub/cajun/reader.inl index b445ec6da..6f2cf36de 100644 --- a/aegisub/libaegisub/include/libaegisub/cajun/reader.inl +++ b/aegisub/libaegisub/include/libaegisub/cajun/reader.inl @@ -10,7 +10,7 @@ Author: Terry Caton #include #include -/* +/* TODO: * better documentation @@ -37,16 +37,31 @@ inline Reader::Location::Location() : ////////////////////// // Reader::InputStream -class Reader::InputStream // would be cool if we could inherit from std::istream & override "get" +// wrapper around istream to keep track of document/line offsets +class Reader::InputStream { + std::istream& m_iStr; + Location m_Location; public: - InputStream(std::istream& iStr) : - m_iStr(iStr) {} + InputStream(std::istream& iStr) : m_iStr(iStr) { } - // protect access to the input stream, so we can keeep track of document/line offsets - char Get(); // big, define outside - char Peek() { - assert(m_iStr.eof() == false); // enforce reading of only valid stream data + int Get() { + assert(!m_iStr.eof()); + int c = m_iStr.get(); + + ++m_Location.m_nDocOffset; + if (c == '\n') { + ++m_Location.m_nLine; + m_Location.m_nLineOffset = 0; + } + else { + ++m_Location.m_nLineOffset; + } + + return c; + } + int Peek() { + assert(!m_iStr.eof()); return m_iStr.peek(); } @@ -56,32 +71,8 @@ public: } const Location& GetLocation() const { return m_Location; } - -private: - std::istream& m_iStr; - Location m_Location; }; - -inline char Reader::InputStream::Get() -{ - assert(m_iStr.eof() == false); // enforce reading of only valid stream data - char c = m_iStr.get(); - - ++m_Location.m_nDocOffset; - if (c == '\n') { - ++m_Location.m_nLine; - m_Location.m_nLineOffset = 0; - } - else { - ++m_Location.m_nLineOffset; - } - - return c; -} - - - ////////////////////// // Reader::TokenStream @@ -96,23 +87,21 @@ public: { } const Token& Peek() { - assert(m_itCurrent != m_Tokens.end()); - return *(m_itCurrent); + assert(!EOS()); + return *m_itCurrent; } const Token& Get() { - assert(m_itCurrent != m_Tokens.end()); - return *(m_itCurrent++); + assert(!EOS()); + return *m_itCurrent++; } bool EOS() const { - return m_itCurrent == m_Tokens.end(); + return m_itCurrent == m_Tokens.end(); } }; /////////////////// // Reader (finally) - - inline void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); } inline void Reader::Read(Array& array, std::istream& istr) { Read_i(array, istr); } inline void Reader::Read(String& string, std::istream& istr) { Read_i(string, istr); } @@ -121,8 +110,7 @@ inline void Reader::Read(Boolean& boolean, std::istream& istr) { Re inline void Reader::Read(Null& null, std::istream& istr) { Read_i(null, istr); } inline void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); } - -template +template void Reader::Read_i(ElementTypeT& element, std::istream& istr) { Reader reader; @@ -134,18 +122,16 @@ void Reader::Read_i(ElementTypeT& element, std::istream& istr) TokenStream tokenStream(tokens); reader.Parse(element, tokenStream); - if (tokenStream.EOS() == false) + if (!tokenStream.EOS()) { const Token& token = tokenStream.Peek(); throw ParseException("Expected End of token stream; found " + token.sValue, token.locBegin, token.locEnd); } } - inline void Reader::Scan(Tokens& tokens, InputStream& inputStream) { - while (EatWhiteSpace(inputStream), // ignore any leading white space... - inputStream.EOS() == false) // ...before checking for EOS + while (EatWhiteSpace(inputStream), !inputStream.EOS()) { // if all goes well, we'll create a token each pass Token token; @@ -231,9 +217,8 @@ inline void Reader::Scan(Tokens& tokens, InputStream& inputStream) token.nType = Token::TOKEN_NULL; break; - default: { + default: throw ScanException("Unexpected character in stream: " + sChar, inputStream.GetLocation()); - } } token.locEnd = inputStream.GetLocation(); @@ -244,8 +229,7 @@ inline void Reader::Scan(Tokens& tokens, InputStream& inputStream) inline void Reader::EatWhiteSpace(InputStream& inputStream) { - while (inputStream.EOS() == false && - ::isspace(inputStream.Peek())) + while (!inputStream.EOS() && ::isspace(inputStream.Peek())) inputStream.Get(); } @@ -268,7 +252,7 @@ inline void Reader::MatchExpectedString(const std::string& sExpected, InputStrea inline void Reader::MatchString(std::string& string, InputStream& inputStream) { MatchExpectedString("\"", inputStream); - + while (inputStream.EOS() == false && inputStream.Peek() != '"') { @@ -317,7 +301,7 @@ inline void Reader::MatchNumber(std::string& sNumber, InputStream& inputStream) } -inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream) +inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream) { if (tokenStream.EOS()) { throw ParseException("Unexpected end of token stream", Location(), Location()); // nowhere to point to