From 9d6ede610648dbab95ef5755f103ffabf2d0ad15 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 17 May 2010 15:13:22 -0400 Subject: [PATCH] added refptr into tmpl/parser.h, added Node and Token classes to be generated --- tmpl/parser.cc | 14 ++++++ tmpl/parser.h | 121 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/tmpl/parser.cc b/tmpl/parser.cc index 3e15416..dd62b03 100644 --- a/tmpl/parser.cc +++ b/tmpl/parser.cc @@ -121,6 +121,20 @@ bool I_CLASSNAME::parse(istream & i) } } +refptr Node::operator[](int index) +{ + return (0 <= index && index < m_indexed_children.size()) + ? m_indexed_children[index] + : NULL; +} + +refptr Node::operator[](const std::string & index) +{ + return (m_named_children.find(index) != m_named_children.end()) + ? m_named_children[index] + : NULL; +} + #ifdef I_NAMESPACE }; #endif diff --git a/tmpl/parser.h b/tmpl/parser.h index 1aff233..6aa8cac 100644 --- a/tmpl/parser.h +++ b/tmpl/parser.h @@ -3,11 +3,113 @@ #define IMBECILE_PARSER_HEADER #include +#include +#include #ifdef I_NAMESPACE namespace I_NAMESPACE { #endif +#ifndef REFPTR_H +#define REFPTR_H REFPTR_H + +/* Author: Josh Holtrop + * Purpose: Provide a reference-counting pointer-like first order + * C++ object that will free the object it is pointing to when + * all references to it have been destroyed. + * This implementation does not solve the circular reference problem. + * I was not concerned with that when developing this class. + */ +#include /* NULL */ + +template +class refptr +{ + public: + refptr(); + refptr(T * ptr); + refptr(const refptr & orig); + refptr & operator=(const refptr & orig); + refptr & operator=(T * ptr); + ~refptr(); + T & operator*() const { return *m_ptr; } + T * operator->() const { return m_ptr; } + bool isNull() const { return m_ptr == NULL; } + + private: + void cloneFrom(const refptr & orig); + void destroy(); + + T * m_ptr; + int * m_refCount; +}; + +template refptr::refptr() +{ + m_ptr = NULL; + m_refCount = NULL; +} + +template refptr::refptr(T * ptr) +{ + m_ptr = ptr; + m_refCount = new int; + *m_refCount = 1; +} + +template refptr::refptr(const refptr & orig) +{ + cloneFrom(orig); +} + +template refptr & refptr::operator=(const refptr & orig) +{ + destroy(); + cloneFrom(orig); + return *this; +} + +template refptr & refptr::operator=(T * ptr) +{ + destroy(); + m_ptr = ptr; + m_refCount = new int; + *m_refCount = 1; + return *this; +} + +template void refptr::cloneFrom(const refptr & orig) +{ + this->m_ptr = orig.m_ptr; + this->m_refCount = orig.m_refCount; + if (m_refCount != NULL) + (*m_refCount)++; +} + +template refptr::~refptr() +{ + destroy(); +} + +template void refptr::destroy() +{ + if (m_refCount != NULL) + { + if (*m_refCount <= 1) + { + delete m_ptr; + delete m_refCount; + } + else + { + (*m_refCount)--; + } + } +} + +#endif + + class I_CLASSNAME { public: @@ -19,6 +121,25 @@ class I_CLASSNAME const char * m_errstr; }; +class Node +{ + public: + refptr operator[](int index); + refptr operator[](const std::string & index); + + protected: + std::map< std::string, refptr > m_named_children; + std::vector< refptr > m_indexed_children; +}; + +typedef refptr NodeRef; + +class Token : public Node +{ + public: + protected: +}; + #ifdef I_NAMESPACE }; #endif