Shape keeping movement is implemented, at last. Many thanks to Alpar.
8 #include <lemon/error.h>
19 void indent(int level) {
21 for(int i=0;i<level;i++) os << ' ';
23 void tag(const std::string &_tag) {
24 os << '<' << _tag << '>';
26 void etag(const std::string &_tag) {
27 os << "</" << _tag << '>';
29 void itag(const std::string &_tag) { indent();tag(_tag); }
30 void ietag(const std::string &_tag) { indent();etag(_tag); }
32 void beginTag(const std::string &_tag) {
36 void endTag(const std::string &_tag) {
45 if(level>=0) indent(level);
56 const std::string _tag;
62 ContTag(XmlWriter &_ix,const std::string &_t) :
67 ~ContTag() { ix.etag(_tag);}
73 const std::string _tag;
79 LineTag(XmlWriter &_ix,const std::string &_t) :
84 ~LineTag() { ix.etag(_tag);}
94 const std::string _tag;
100 Tag(XmlWriter &_ix,const std::string &_t) :
114 XmlWriter(std::ostream& _os) : os(_os),level(-1) {}
115 ~XmlWriter() { os<< std::endl; }
117 XmlWriter &operator()(int v)
122 XmlWriter &operator()(const std::string &_tag,int v)
124 LineTag t(*this,_tag);
128 XmlWriter &operator()(double v)
133 XmlWriter &operator()(const std::string &_tag,double v)
135 LineTag t(*this,_tag);
139 XmlWriter &operator()(const std::string &v)
141 for(std::string::const_iterator i=v.begin();i!=v.end();++i)
161 XmlWriter &operator()(const std::string &_tag,const std::string &v)
163 LineTag t(*this,_tag);
172 XmlWriter &operator()(const std::string &_tag,const V &v)
183 XmlWriter &operator()(const V &v)
190 //////////////////////////////////////////////////////////////////////
195 std::string next_tag;
198 void skipWhiteSpaces()
201 while (is.get(c) && std::isspace(c,is.getloc())) if(c=='\n') line_number++;
209 void useTag() {next_tag.clear();}
211 void useTag(const std::string &_tag) {
212 if(nextTag()==_tag) useTag();
213 else throw DataFormatError("",line_number,"Unexpected token name");
220 const std::string &nextTag()
222 if(next_tag.empty()) {
225 if(!is.get(c) || c!='<')
226 throw DataFormatError("",line_number,"Bad token");
228 while (is.get(c) && c!='>') next_tag.push_back(c);
230 throw DataFormatError("",line_number,"Bad token");
242 const std::string tag;
248 Tag(XmlReader &_ix,const std::string &_tag) :
254 if(!std::uncaught_exception())
263 XmlReader(std::istream& _is) : is(_is), line_number(1) {}
265 int operator()(const std::string &tag,int &v)
269 if(!(is >> v)) throw DataFormatError("",line_number,"Not an 'int'");
272 double operator()(const std::string &tag,double &v)
277 throw DataFormatError("",line_number,"Not a 'double'");
280 std::string &operator()(const std::string &tag,std::string &v)
285 while (is.get(c) && c!='<')
288 throw DataFormatError("",line_number,"Bad string");
298 if(c=='\n') line_number++;
302 throw DataFormatError("",line_number,"Unexpected eof");
311 V &operator()(const std::string &tag,V &v)
332 V load(const std::string &tag)
341 //////////////////////////////////////////////////////////////////////
344 void out(XmlWriter &x,const std::auto_ptr<A> &v)
350 void in(XmlReader &x,std::auto_ptr<A> &v)
356 //////////////////////////////
358 template<class A,class B>
359 void out(XmlWriter &x,const std::pair<A,B> &v)
362 x("second",v.second);
365 template<class A,class B>
366 void in(XmlReader &x,std::pair<A,B> &v)
369 x("second",v.second);
372 //////////////////////////////
375 void out(XmlWriter &x,const std::list<T> &v)
377 for(typename std::list<T>::const_iterator it=v.begin();
378 it!=v.end();++it) x("item",*it);
382 void in(XmlReader &x,std::list<T> &v)
384 while(x.nextTag()=="item")
391 //////////////////////////////
394 void out(XmlWriter &x,const std::vector<T> &v)
396 for(typename std::vector<T>::const_iterator it=v.begin();
397 it!=v.end();++it) x("item",*it);
401 void in(XmlReader &x,std::vector<T> &v)
403 while(x.nextTag()=="item")
410 //////////////////////////////
412 template<class K,class V>
413 void out(XmlWriter &x,const std::map<K,V> &v)
415 for(typename std::map<K,V>::const_iterator it=v.begin();
416 it!=v.end();++it) x("item",*it);
419 template<class K,class V>
420 void in(XmlReader &x,std::map<K,V> &v)
422 while(x.nextTag()=="item")
424 typename std::map<K,V>::value_type it;
430 //////////////////////////////
433 void out(XmlWriter &x,const lemon::xy<T> &v)
437 { XmlWriter::LineTag t(x,"x"); x(v.x); }
438 { XmlWriter::ContTag t(x,"y"); x(v.y); }
442 void in(XmlReader &x,lemon::xy<T> &v)
448 //////////////////////////////
451 void out(XmlWriter &x,const lemon::BoundingBox<T> &v)
454 x("point",v.bottomLeft());
455 if(v.bottomLeft()!=v.topRight()) x("point",v.topRight());
460 void in(XmlReader &x,lemon::BoundingBox<T> &v)
463 while(x.nextTag()=="point") {