// Copyright {Jagger Software Limited} 2003 #if !defined AST_SYMBOL_INCLUDED || \ defined AST_SYMBOL_TEMPLATE_INCLUDED #error "ast/symbol-template.hpp" #included directly #endif #define AST_SYMBOL_TEMPLATE_INCLUDED #include "container/for_all.hpp" #include "contract/pre_condition.hpp" #include "ownership/deleter.hpp" #include namespace ast // symbol - 'tors { template symbol::symbol ( const ::grammar::symbol_definition & source, iterator position ) : definition(source) , from(position) , until(position) , symbols() { } template symbol::symbol ( const ::grammar::symbol_definition & source, iterator start, iterator finish ) : definition(source) , from(start) , until(finish) , symbols() { PRE_CONDITION(start != finish); } template symbol::~symbol() { clear(); } } namespace ast // symbol - attributes { template bool symbol::is_terminal() const { return from != until; } } namespace ast // symbol - end points { template iterator symbol::begin() const { return from; } template iterator symbol::end() const { return symbols.empty() ? until : symbols.back()->end(); } } namespace ast // symbol - capacity { template size_t symbol::size() const { return symbols.size(); } template bool symbol::empty() const { return size() == 0; } template void symbol::clear() { ::container::for_all(symbols, ownership::deleter()); symbols.clear(); } } namespace ast // symbol - subscripting { template const symbol & symbol::operator[](size_t at) const { range_check(at); return *symbols[at]; } } namespace ast // symbol - tree manipulation { template symbol * symbol::back() const { PRE_CONDITION(!is_terminal()); PRE_CONDITION(!symbols.empty()); return symbols.back(); } template void symbol::push_back(symbol * pushed) { PRE_CONDITION(!is_terminal()); PRE_CONDITION(pushed != 0); symbols.push_back(pushed); } template void symbol::pop_back() { PRE_CONDITION(!is_terminal()); PRE_CONDITION(!symbols.empty()); return symbols.pop_back(); } } namespace ast // symbol - validation { template void symbol::range_check(size_t at) const { if (at >= size()) { throw ::std::out_of_range("symbol[at]"); } } }