#ifndef _BOUBBLE_HH_ #define _BOUBBLE_HH_ #include #include #include #include "thesymbols.hh" enum Dir {UP=0,DOWN=1,AT_TARGET=2}; // class BoubbleAction // { // public: // void apply() {}; // private: // }; class Boubble { public: Boubble() {}; Boubble(list u, list d, LongRel l, int s=-1, bool r=false); Boubble(const char* pathstr, const char* l, int s=-1, bool r=false); //Boubble(const Boubble& b) {_src=b._src; _upath=b._upath; _dpath=b._dpath; _rel=b._rel; _reverse=b._reverse; }; Dir dir() const; LongRel rel() const; int src() const; void src(int s); bool reverse() const; void reverse(bool b); Role next(); Boubble* step(Role r, Dir d); Boubble* reversed(); bool is_at_target() const; bool operator==(Boubble const& b) const; bool operator!=(Boubble const& b) const; bool operator<(Boubble const& b) const; void as_cstr(char* s); friend std::ostream& operator<<(std::ostream&, const Boubble&); private: int _src; list _upath; list _dpath; LongRel _rel; bool _reverse; }; //---------------------------------------------------------------------------------------------------- inline Boubble::Boubble(list u, list d, LongRel l, int s, bool r) : _upath(u), _dpath(d), _rel(l), _src(s), _reverse(r) {} //---------------------------------------------------------------------------------------------------- inline Boubble::Boubble(const char* pathstr, const char* l, int s, bool r) { Dir dir = UP; const char* p = pathstr; while(*p) { if(*p=='^') { dir = DOWN; p++; } else if(isalpha(*p)) { char buf[80]; sscanf(p,"%[a-zA-Z0-9_]",buf); dir == UP ? _upath.push_back(Role(buf)) : _dpath.push_back(Role(buf)); p += strlen(buf); } else p++; } _rel = LongRel(l); _src = s; _reverse = r; } //---------------------------------------------------------------------------------------------------- inline Dir Boubble::dir() const { if(!_upath.empty()) return UP; else if(!_dpath.empty()) return DOWN; else return AT_TARGET; } //---------------------------------------------------------------------------------------------------- inline LongRel Boubble::rel() const { return _rel; } //---------------------------------------------------------------------------------------------------- inline int Boubble::src() const { return _src; } //---------------------------------------------------------------------------------------------------- inline void Boubble::src(int s) { _src=s; } //---------------------------------------------------------------------------------------------------- inline bool Boubble::reverse() const { return _reverse; } //---------------------------------------------------------------------------------------------------- inline void Boubble::reverse(bool b) { _reverse=b; } //---------------------------------------------------------------------------------------------------- inline Role Boubble::next() { if(!_upath.empty()) return _upath.front(); else if(!_dpath.empty()) return _dpath.front(); else return Role("NULL"); } //---------------------------------------------------------------------------------------------------- inline Boubble* Boubble::step(Role r, Dir d) { if(d==UP && !_upath.empty() && _upath.front() == r) { Boubble* newboubble = new Boubble(_upath,_dpath,_rel,_src,_reverse); newboubble->_upath.pop_front(); return newboubble; } if(d==DOWN && _upath.empty() && !_dpath.empty() && _dpath.front() == r) { Boubble* newboubble = new Boubble(_upath,_dpath,_rel,_src,_reverse); newboubble->_dpath.pop_front(); return newboubble; } return NULL; } //---------------------------------------------------------------------------------------------------- inline Boubble* Boubble::reversed() { Boubble* newboubble = new Boubble(_dpath,_upath,_rel,-1,!_reverse); newboubble->_upath.reverse(); newboubble->_dpath.reverse(); // cout << *this << "-----" << *newboubble << endl; return newboubble; } //---------------------------------------------------------------------------------------------------- inline bool Boubble::is_at_target() const { return _upath.empty() && _dpath.empty(); } //---------------------------------------------------------------------------------------------------- inline bool Boubble::operator==(Boubble const& b) const { return _src==b._src && _upath==b._upath && _dpath==b._dpath && _rel==b._rel; } //---------------------------------------------------------------------------------------------------- inline bool Boubble::operator!=(Boubble const& b) const { return !(*this==b); } //---------------------------------------------------------------------------------------------------- inline bool Boubble::operator<(Boubble const& b) const { if(_src < b._src) return true; if(_rel < b._rel) return true; if(this < &b) return true; return false; } //---------------------------------------------------------------------------------------------------- inline std::ostream& operator<<(std::ostream& o, const Boubble& b) { o << "["; o << b._src << "|"; bool cont=false; for(list::const_iterator i = b._upath.begin(); i != b._upath.end(); ++i) { if(cont) o << ','; o << i->str(); cont = true; } o << '^'; cont=false; for(list::const_iterator i = b._dpath.begin(); i != b._dpath.end(); ++i) { if(cont) o << ','; o << i->str(); cont = true; } o << ':'; o << b._rel.str(); o << "]"; if(b.reverse()) o << "!"; return o; } //---------------------------------------------------------------------------------------------------- inline void Boubble::as_cstr(char* s) { stringstream oss; oss << *this; strcpy(s,oss.str().c_str()); } //==================================================================================================== #endif