1.1 --- a/gui/xml.h Tue Jul 26 13:15:13 2005 +0000
1.2 +++ b/gui/xml.h Tue Jul 26 14:31:29 2005 +0000
1.3 @@ -5,438 +5,466 @@
1.4 #include <vector>
1.5 #include <list>
1.6 #include <map>
1.7 +#include <lemon/error.h>
1.8 #include <lemon/xy.h>
1.9
1.10 -class XmlWriter
1.11 -{
1.12 - std::ostream& os;
1.13 - int level;
1.14 +namespace lemon {
1.15
1.16 -protected:
1.17 - void indent(int level) {
1.18 - os << std::endl;
1.19 - for(int i=0;i<level;i++) os << ' ';
1.20 - }
1.21 - void tag(const std::string &_tag) {
1.22 - os << '<' << _tag << '>';
1.23 - }
1.24 - void etag(const std::string &_tag) {
1.25 - os << "</" << _tag << '>';
1.26 - }
1.27 - void itag(const std::string &_tag) { indent();tag(_tag); }
1.28 - void ietag(const std::string &_tag) { indent();etag(_tag); }
1.29 + class XmlWriter
1.30 + {
1.31 + std::ostream& os;
1.32 + int level;
1.33
1.34 - void beginTag(const std::string &_tag) {
1.35 - itag(_tag);
1.36 - level++;
1.37 - }
1.38 - void endTag(const std::string &_tag) {
1.39 - level--;
1.40 - ietag(_tag);
1.41 - }
1.42 + protected:
1.43 + void indent(int level) {
1.44 + os << std::endl;
1.45 + for(int i=0;i<level;i++) os << ' ';
1.46 + }
1.47 + void tag(const std::string &_tag) {
1.48 + os << '<' << _tag << '>';
1.49 + }
1.50 + void etag(const std::string &_tag) {
1.51 + os << "</" << _tag << '>';
1.52 + }
1.53 + void itag(const std::string &_tag) { indent();tag(_tag); }
1.54 + void ietag(const std::string &_tag) { indent();etag(_tag); }
1.55
1.56 -public:
1.57 + void beginTag(const std::string &_tag) {
1.58 + itag(_tag);
1.59 + level++;
1.60 + }
1.61 + void endTag(const std::string &_tag) {
1.62 + level--;
1.63 + ietag(_tag);
1.64 + }
1.65
1.66 - void indent()
1.67 - {
1.68 - if(level>=0) indent(level);
1.69 - else level=0;
1.70 - }
1.71 + public:
1.72 +
1.73 + void indent()
1.74 + {
1.75 + if(level>=0) indent(level);
1.76 + else level=0;
1.77 + }
1.78
1.79 - ///\e
1.80 + ///\e
1.81
1.82 - ///\e
1.83 - ///
1.84 - class ContTag
1.85 - {
1.86 - XmlWriter &ix;
1.87 - const std::string _tag;
1.88 - public:
1.89 - ///\e
1.90 + ///\e
1.91 + ///
1.92 + class ContTag
1.93 + {
1.94 + XmlWriter &ix;
1.95 + const std::string _tag;
1.96 + public:
1.97 + ///\e
1.98
1.99 - ///\e
1.100 - ///
1.101 - ContTag(XmlWriter &_ix,const std::string &_t) :
1.102 - ix(_ix), _tag(_t)
1.103 + ///\e
1.104 + ///
1.105 + ContTag(XmlWriter &_ix,const std::string &_t) :
1.106 + ix(_ix), _tag(_t)
1.107 + {
1.108 + ix.tag(_tag);
1.109 + }
1.110 + ~ContTag() { ix.etag(_tag);}
1.111 + };
1.112 +
1.113 + class LineTag
1.114 {
1.115 - ix.tag(_tag);
1.116 + XmlWriter &ix;
1.117 + const std::string _tag;
1.118 + public:
1.119 + ///\e
1.120 +
1.121 + ///\e
1.122 + ///
1.123 + LineTag(XmlWriter &_ix,const std::string &_t) :
1.124 + ix(_ix), _tag(_t)
1.125 + {
1.126 + ix.itag(_tag);
1.127 + }
1.128 + ~LineTag() { ix.etag(_tag);}
1.129 + };
1.130 +
1.131 + ///\e
1.132 +
1.133 + ///\e
1.134 + ///
1.135 + class Tag
1.136 + {
1.137 + XmlWriter &ix;
1.138 + const std::string _tag;
1.139 + public:
1.140 + ///\e
1.141 +
1.142 + ///\e
1.143 + ///
1.144 + Tag(XmlWriter &_ix,const std::string &_t) :
1.145 + ix(_ix), _tag(_t)
1.146 + {
1.147 + ix.beginTag(_tag);
1.148 + }
1.149 + ~Tag() {
1.150 + ix.endTag(_tag);
1.151 + }
1.152 + };
1.153 +
1.154 + ///\e
1.155 +
1.156 + ///\e
1.157 + ///
1.158 + XmlWriter(std::ostream& _os) : os(_os),level(-1) {}
1.159 + ~XmlWriter() { os<< std::endl; }
1.160 +
1.161 + XmlWriter &operator()(int v)
1.162 + {
1.163 + os << v;
1.164 + return *this;
1.165 }
1.166 - ~ContTag() { ix.etag(_tag);}
1.167 + XmlWriter &operator()(const std::string &_tag,int v)
1.168 + {
1.169 + LineTag t(*this,_tag);
1.170 + (*this)(v);
1.171 + return *this;
1.172 + }
1.173 + XmlWriter &operator()(double v)
1.174 + {
1.175 + os << v;
1.176 + return *this;
1.177 + }
1.178 + XmlWriter &operator()(const std::string &_tag,double v)
1.179 + {
1.180 + LineTag t(*this,_tag);
1.181 + (*this)(v);
1.182 + return *this;
1.183 + }
1.184 + XmlWriter &operator()(const std::string &v)
1.185 + {
1.186 + for(std::string::const_iterator i=v.begin();i!=v.end();++i)
1.187 + switch(*i) {
1.188 + case '\\':
1.189 + os << "\\\\";
1.190 + break;
1.191 + case '<':
1.192 + os << "\\<";
1.193 + break;
1.194 + case '&':
1.195 + os << "\\&";
1.196 + break;
1.197 + case '\n':
1.198 + os << "\\n";
1.199 + break;
1.200 + default:
1.201 + os<<*i;
1.202 + break;
1.203 + }
1.204 + return *this;
1.205 + }
1.206 + XmlWriter &operator()(const std::string &_tag,const std::string &v)
1.207 + {
1.208 + LineTag t(*this,_tag);
1.209 + (*this)(v);
1.210 + return *this;
1.211 + }
1.212 + ///\e
1.213 +
1.214 + ///\e
1.215 + ///
1.216 + template<class V>
1.217 + XmlWriter &operator()(const std::string &_tag,const V &v)
1.218 + {
1.219 + Tag t(*this,_tag);
1.220 + out(*this,v);
1.221 + return *this;
1.222 + }
1.223 + ///\e
1.224 +
1.225 + ///\e
1.226 + ///
1.227 + template<class V>
1.228 + XmlWriter &operator()(const V &v)
1.229 + {
1.230 + out(*this,v);
1.231 + return *this;
1.232 + }
1.233 };
1.234
1.235 - class LineTag
1.236 + //////////////////////////////////////////////////////////////////////
1.237 +
1.238 + class XmlReader
1.239 {
1.240 - XmlWriter &ix;
1.241 - const std::string _tag;
1.242 - public:
1.243 + std::istream& is;
1.244 + std::string next_tag;
1.245 + int line_number;
1.246 +
1.247 + void skipWhiteSpaces()
1.248 + {
1.249 + char c;
1.250 + while (is.get(c) && std::isspace(c,is.getloc())) if(c=='\n') line_number++;
1.251 + is.unget();
1.252 + }
1.253 + protected:
1.254 ///\e
1.255 -
1.256 +
1.257 ///\e
1.258 ///
1.259 - LineTag(XmlWriter &_ix,const std::string &_t) :
1.260 - ix(_ix), _tag(_t)
1.261 - {
1.262 - ix.itag(_tag);
1.263 + void useTag() {next_tag.clear();}
1.264 +
1.265 + void useTag(const std::string &_tag) {
1.266 + if(nextTag()==_tag) useTag();
1.267 + else throw DataFormatError("",line_number,"Unexpected token name");
1.268 }
1.269 - ~LineTag() { ix.etag(_tag);}
1.270 - };
1.271 -
1.272 - ///\e
1.273 -
1.274 - ///\e
1.275 - ///
1.276 - class Tag
1.277 - {
1.278 - XmlWriter &ix;
1.279 - const std::string _tag;
1.280 public:
1.281 ///\e
1.282
1.283 ///\e
1.284 ///
1.285 - Tag(XmlWriter &_ix,const std::string &_t) :
1.286 - ix(_ix), _tag(_t)
1.287 + const std::string &nextTag()
1.288 {
1.289 - ix.beginTag(_tag);
1.290 + if(next_tag.empty()) {
1.291 + char c;
1.292 + skipWhiteSpaces();
1.293 + if(!is.get(c) || c!='<')
1.294 + throw DataFormatError("",line_number,"Bad token");
1.295 + next_tag.clear();
1.296 + while (is.get(c) && c!='>') next_tag.push_back(c);
1.297 + if(c!='>')
1.298 + throw DataFormatError("",line_number,"Bad token");
1.299 + }
1.300 + return next_tag;
1.301 }
1.302 - ~Tag() {
1.303 - ix.endTag(_tag);
1.304 - }
1.305 - };
1.306 -
1.307 - ///\e
1.308
1.309 - ///\e
1.310 - ///
1.311 - XmlWriter(std::ostream& _os) : os(_os),level(-1) {}
1.312 - ~XmlWriter() { os<< std::endl; }
1.313 + ///\e
1.314
1.315 - XmlWriter &operator()(int v)
1.316 - {
1.317 - if(!(os << v)) throw (std::ios::failure ("data format error"));
1.318 - return *this;
1.319 - }
1.320 - XmlWriter &operator()(const std::string &_tag,int v)
1.321 - {
1.322 - LineTag t(*this,_tag);
1.323 - if(!(os << v)) throw (std::ios::failure ("data format error"));
1.324 - return *this;
1.325 - }
1.326 - XmlWriter &operator()(const std::string &_tag,double v)
1.327 - {
1.328 - LineTag t(*this,_tag);
1.329 - if(os << v) throw (std::ios::failure ("data format error"));
1.330 - return *this;
1.331 - }
1.332 - XmlWriter &operator()(double v)
1.333 - {
1.334 - os << v;
1.335 - return *this;
1.336 - }
1.337 - XmlWriter &operator()(const std::string &v)
1.338 - {
1.339 - for(std::string::const_iterator i=v.begin();i!=v.end();++i)
1.340 - switch(*i) {
1.341 - case '\\':
1.342 - os << "\\\\";
1.343 - break;
1.344 - case '<':
1.345 - os << "\\<";
1.346 - break;
1.347 - case '&':
1.348 - os << "\\&";
1.349 - break;
1.350 - case '\n':
1.351 - os << "\\n";
1.352 - break;
1.353 - default:
1.354 - os<<*i;
1.355 - break;
1.356 - }
1.357 - return *this;
1.358 - }
1.359 - XmlWriter &operator()(const std::string &_tag,const std::string &v)
1.360 - {
1.361 - LineTag t(*this,_tag);
1.362 - (*this)(v);
1.363 - return *this;
1.364 - }
1.365 - ///\e
1.366 -
1.367 - ///\e
1.368 - ///
1.369 - template<class V>
1.370 - XmlWriter &operator()(const std::string &_tag,const V &v)
1.371 - {
1.372 - Tag t(*this,_tag);
1.373 - out(*this,v);
1.374 - return *this;
1.375 - }
1.376 - ///\e
1.377 -
1.378 - ///\e
1.379 - ///
1.380 - template<class V>
1.381 - XmlWriter &operator()(const V &v)
1.382 - {
1.383 - out(*this,v);
1.384 - return *this;
1.385 - }
1.386 -};
1.387 -
1.388 -//////////////////////////////////////////////////////////////////////
1.389 -
1.390 -class XmlReader
1.391 -{
1.392 - std::istream& is;
1.393 -
1.394 - std::string next_tag;
1.395 - void skipWhiteSpaces()
1.396 - {
1.397 - char c;
1.398 - while (is.get(c) && std::isspace(c,is.getloc()));
1.399 - is.unget();
1.400 - }
1.401 -protected:
1.402 - ///\e
1.403 -
1.404 - ///\e
1.405 - ///
1.406 - void useTag() {next_tag.clear();}
1.407 -
1.408 - void useTag(const std::string &_tag) {
1.409 - if(nextTag()==_tag) useTag();
1.410 - else throw (std::ios::failure ("data format error"));
1.411 - }
1.412 -public:
1.413 - ///\e
1.414 -
1.415 - ///\e
1.416 - ///
1.417 - const std::string &nextTag()
1.418 - {
1.419 - if(next_tag.empty()) {
1.420 - char c;
1.421 - skipWhiteSpaces();
1.422 - if(!is.get(c) || c!='<')
1.423 - throw (std::ios::failure ("data format error"));
1.424 - next_tag.clear();
1.425 - while (is.get(c) && c!='>') next_tag.push_back(c);
1.426 - if(c!='>')
1.427 - throw (std::ios::failure ("data format error"));
1.428 - }
1.429 - return next_tag;
1.430 - }
1.431 -
1.432 - ///\e
1.433 -
1.434 - ///\e
1.435 - ///
1.436 - class Tag
1.437 - {
1.438 - XmlReader &ix;
1.439 - const std::string tag;
1.440 - public:
1.441 - ///\e
1.442 -
1.443 ///\e
1.444 ///
1.445 - Tag(XmlReader &_ix,const std::string &_tag) :
1.446 - ix(_ix), tag(_tag)
1.447 + class Tag
1.448 {
1.449 - ix.useTag(_tag);
1.450 + XmlReader &ix;
1.451 + const std::string tag;
1.452 + public:
1.453 + ///\e
1.454 +
1.455 + ///\e
1.456 + ///
1.457 + Tag(XmlReader &_ix,const std::string &_tag) :
1.458 + ix(_ix), tag(_tag)
1.459 + {
1.460 + ix.useTag(_tag);
1.461 + }
1.462 + ~Tag() {
1.463 + if(!std::uncaught_exception())
1.464 + ix.useTag('/'+tag);
1.465 + }
1.466 + };
1.467 +
1.468 + ///\e
1.469 +
1.470 + ///\e
1.471 + ///
1.472 + XmlReader(std::istream& _is) : is(_is), line_number(1) {}
1.473 +
1.474 + int operator()(const std::string &tag,int &v)
1.475 + {
1.476 + Tag t(*this,tag);
1.477 + skipWhiteSpaces();
1.478 + if(!(is >> v)) throw DataFormatError("",line_number,"Not an 'int'");
1.479 + return v;
1.480 }
1.481 - ~Tag() {
1.482 - if(!std::uncaught_exception())
1.483 - ix.useTag('/'+tag);
1.484 + double operator()(const std::string &tag,double &v)
1.485 + {
1.486 + Tag t(*this,tag);
1.487 + skipWhiteSpaces();
1.488 + if(!(is >> v))
1.489 + throw DataFormatError("",line_number,"Not a 'double'");
1.490 + return v;
1.491 + }
1.492 + std::string &operator()(const std::string &tag,std::string &v)
1.493 + {
1.494 + Tag t(*this,tag);
1.495 + v.clear();
1.496 + char c;
1.497 + while (is.get(c) && c!='<')
1.498 + if(c=='\\')
1.499 + if(!is.get(c))
1.500 + throw DataFormatError("",line_number,"Bad string");
1.501 + else switch(c) {
1.502 + case 'n':
1.503 + v.push_back('\n');
1.504 + break;
1.505 + default:
1.506 + v.push_back(c);
1.507 + break;
1.508 + }
1.509 + else {
1.510 + if(c=='\n') line_number++;
1.511 + v.push_back(c);
1.512 + }
1.513 + if(c!='<')
1.514 + throw DataFormatError("",line_number,"Unexpected eof");
1.515 + is.unget();
1.516 + return v;
1.517 + }
1.518 + ///\e
1.519 +
1.520 + ///\e
1.521 + ///
1.522 + template<class V>
1.523 + V &operator()(const std::string &tag,V &v)
1.524 + {
1.525 + Tag t(*this,tag);
1.526 + in(*this,v);
1.527 + return v;
1.528 + }
1.529 + ///\e
1.530 +
1.531 + ///\e
1.532 + ///
1.533 + template<class V>
1.534 + V &operator()(V &v)
1.535 + {
1.536 + in(*this,v);
1.537 + return v;
1.538 + }
1.539 + ///\e
1.540 +
1.541 + ///\e
1.542 + ///
1.543 + template<class V>
1.544 + V load(const std::string &tag)
1.545 + {
1.546 + Tag t(*this,tag);
1.547 + V v;
1.548 + (*this)(tag,v);
1.549 + return v;
1.550 }
1.551 };
1.552
1.553 - ///\e
1.554 + //////////////////////////////////////////////////////////////////////
1.555 +
1.556 + template<class A>
1.557 + void out(XmlWriter &x,const std::auto_ptr<A> &v)
1.558 + {
1.559 + x(*v);
1.560 + }
1.561 +
1.562 + template<class A>
1.563 + void in(XmlReader &x,std::auto_ptr<A> &v)
1.564 + {
1.565 + v=new A;
1.566 + x(*v);
1.567 + }
1.568 +
1.569 + //////////////////////////////
1.570 +
1.571 + template<class A,class B>
1.572 + void out(XmlWriter &x,const std::pair<A,B> &v)
1.573 + {
1.574 + x("first",v.first);
1.575 + x("second",v.second);
1.576 + }
1.577 +
1.578 + template<class A,class B>
1.579 + void in(XmlReader &x,std::pair<A,B> &v)
1.580 + {
1.581 + x("first",v.first);
1.582 + x("second",v.second);
1.583 + }
1.584 +
1.585 + //////////////////////////////
1.586 +
1.587 + template<class T>
1.588 + void out(XmlWriter &x,const std::list<T> &v)
1.589 + {
1.590 + for(typename std::list<T>::const_iterator it=v.begin();
1.591 + it!=v.end();++it) x("item",*it);
1.592 + }
1.593 +
1.594 + template<class T>
1.595 + void in(XmlReader &x,std::list<T> &v)
1.596 + {
1.597 + while(x.nextTag()=="item")
1.598 + {
1.599 + v.push_back(T());
1.600 + x("item",v.back());
1.601 + }
1.602 + }
1.603 +
1.604 + //////////////////////////////
1.605 +
1.606 + template<class T>
1.607 + void out(XmlWriter &x,const std::vector<T> &v)
1.608 + {
1.609 + for(typename std::vector<T>::const_iterator it=v.begin();
1.610 + it!=v.end();++it) x("item",*it);
1.611 + }
1.612 +
1.613 + template<class T>
1.614 + void in(XmlReader &x,std::vector<T> &v)
1.615 + {
1.616 + while(x.nextTag()=="item")
1.617 + {
1.618 + v.push_back(T());
1.619 + x("item",v.back());
1.620 + }
1.621 + }
1.622 +
1.623 + //////////////////////////////
1.624 +
1.625 + template<class K,class V>
1.626 + void out(XmlWriter &x,const std::map<K,V> &v)
1.627 + {
1.628 + for(typename std::map<K,V>::const_iterator it=v.begin();
1.629 + it!=v.end();++it) x("item",*it);
1.630 + }
1.631 +
1.632 + template<class K,class V>
1.633 + void in(XmlReader &x,std::map<K,V> &v)
1.634 + {
1.635 + while(x.nextTag()=="item")
1.636 + {
1.637 + typename std::map<K,V>::value_type it;
1.638 + x("item",it);
1.639 + v.insert(it);
1.640 + }
1.641 + }
1.642 +
1.643 + //////////////////////////////
1.644 +
1.645 + template<class T>
1.646 + void out(XmlWriter &x,const lemon::xy<T> &v)
1.647 + {
1.648 + // x("x",v.x);
1.649 + // x("y",v.y);
1.650 + { XmlWriter::LineTag t(x,"x"); x(v.x); }
1.651 + { XmlWriter::ContTag t(x,"y"); x(v.y); }
1.652 + }
1.653 +
1.654 + template<class T>
1.655 + void in(XmlReader &x,lemon::xy<T> &v)
1.656 + {
1.657 + x("x",v.x);
1.658 + x("y",v.y);
1.659 + }
1.660 +
1.661 + //////////////////////////////
1.662 +
1.663 + template<class T>
1.664 + void out(XmlWriter &x,const lemon::BoundingBox<T> &v)
1.665 + {
1.666 + if(!v.empty()) {
1.667 + x("point",v.bottomLeft());
1.668 + if(v.bottomLeft()!=v.topRight()) x("point",v.topRight());
1.669 + }
1.670 + }
1.671 +
1.672 + template<class T>
1.673 + void in(XmlReader &x,lemon::BoundingBox<T> &v)
1.674 + {
1.675 + v.clear();
1.676 + while(x.nextTag()=="point") {
1.677 + lemon::xy<T> co;
1.678 + x("point",co);
1.679 + v.add(co);
1.680 + }
1.681 + }
1.682
1.683 - ///\e
1.684 - ///
1.685 - XmlReader(std::istream& _is) : is(_is) {}
1.686 -
1.687 - int operator()(const std::string &tag,int &v)
1.688 - {
1.689 - Tag t(*this,tag);
1.690 - if(!(is >> v)) throw (std::ios::failure ("data format error"));
1.691 - return v;
1.692 - }
1.693 - double operator()(const std::string &tag,double &v)
1.694 - {
1.695 - Tag t(*this,tag);
1.696 - if(!(is >> v)) throw (std::ios::failure ("data format error"));
1.697 - return v;
1.698 - }
1.699 - std::string &operator()(const std::string &tag,std::string &v)
1.700 - {
1.701 - Tag t(*this,tag);
1.702 - v.clear();
1.703 - char c;
1.704 - while (is.get(c) && c!='<')
1.705 - if(c=='\\')
1.706 - if(!is.get(c)) throw (std::ios::failure ("data format error"));
1.707 - else switch(c) {
1.708 - case 'n':
1.709 - v.push_back('\n');
1.710 - break;
1.711 - default:
1.712 - v.push_back(c);
1.713 - break;
1.714 - }
1.715 - else v.push_back(c);
1.716 - if(c!='<')
1.717 - throw (std::ios::failure ("data format error"));
1.718 - is.unget();
1.719 - return v;
1.720 - }
1.721 - ///\e
1.722 -
1.723 - ///\e
1.724 - ///
1.725 - template<class V>
1.726 - V &operator()(const std::string &tag,V &v)
1.727 - {
1.728 - Tag t(*this,tag);
1.729 - in(*this,v);
1.730 - return v;
1.731 - }
1.732 - ///\e
1.733 -
1.734 - ///\e
1.735 - ///
1.736 - template<class V>
1.737 - V &operator()(V &v)
1.738 - {
1.739 - in(*this,v);
1.740 - return v;
1.741 - }
1.742 - ///\e
1.743 -
1.744 - ///\e
1.745 - ///
1.746 - template<class V>
1.747 - V load(const std::string &tag)
1.748 - {
1.749 - Tag t(*this,tag);
1.750 - V v;
1.751 - (*this)(tag,v);
1.752 - return v;
1.753 - }
1.754 -};
1.755 -
1.756 -//////////////////////////////////////////////////////////////////////
1.757 -
1.758 -template<class A,class B>
1.759 -void out(XmlWriter &i,const std::pair<A,B> &v)
1.760 -{
1.761 - i("first",v.first);
1.762 - i("second",v.second);
1.763 }
1.764 -
1.765 -template<class A,class B>
1.766 -void in(XmlReader &i,std::pair<A,B> &v)
1.767 -{
1.768 - i("first",v.first);
1.769 - i("second",v.second);
1.770 -}
1.771 -
1.772 -//////////////////////////////
1.773 -
1.774 -template<class T>
1.775 -void out(XmlWriter &i,const std::list<T> &v)
1.776 -{
1.777 - for(typename std::list<T>::const_iterator it=v.begin();
1.778 - it!=v.end();++it) i("item",*it);
1.779 -}
1.780 -
1.781 -template<class T>
1.782 -void in(XmlReader &i,std::list<T> &v)
1.783 -{
1.784 - while(i.nextTag()=="item")
1.785 - {
1.786 - v.push_back(T());
1.787 - i("item",v.back());
1.788 - }
1.789 -}
1.790 -
1.791 -//////////////////////////////
1.792 -
1.793 -template<class T>
1.794 -void out(XmlWriter &i,const std::vector<T> &v)
1.795 -{
1.796 - for(typename std::vector<T>::const_iterator it=v.begin();
1.797 - it!=v.end();++it) i("item",*it);
1.798 -}
1.799 -
1.800 -template<class T>
1.801 -void in(XmlReader &i,std::vector<T> &v)
1.802 -{
1.803 - while(i.nextTag()=="item")
1.804 - {
1.805 - v.push_back(T());
1.806 - i("item",v.back());
1.807 - }
1.808 -}
1.809 -
1.810 -//////////////////////////////
1.811 -
1.812 -template<class K,class V>
1.813 -void out(XmlWriter &i,const std::map<K,V> &v)
1.814 -{
1.815 - for(typename std::map<K,V>::const_iterator it=v.begin();
1.816 - it!=v.end();++it) i("item",*it);
1.817 -}
1.818 -
1.819 -template<class K,class V>
1.820 -void in(XmlReader &i,std::map<K,V> &v)
1.821 -{
1.822 - while(i.nextTag()=="item")
1.823 - {
1.824 - typename std::map<K,V>::value_type it;
1.825 - i("item",it);
1.826 - v.insert(it);
1.827 - }
1.828 -}
1.829 -
1.830 -//////////////////////////////
1.831 -
1.832 -template<class T>
1.833 -void out(XmlWriter &i,const lemon::xy<T> &v)
1.834 -{
1.835 -// i("x",v.x);
1.836 -// i("y",v.y);
1.837 - { XmlWriter::LineTag t(i,"x"); i(v.x); }
1.838 - { XmlWriter::ContTag t(i,"y"); i(v.y); }
1.839 -}
1.840 -
1.841 -template<class T>
1.842 -void in(XmlReader &i,lemon::xy<T> &v)
1.843 -{
1.844 - i("x",v.x);
1.845 - i("y",v.y);
1.846 -}
1.847 -
1.848 -//////////////////////////////
1.849 -
1.850 -template<class T>
1.851 -void out(XmlWriter &i,const lemon::BoundingBox<T> &v)
1.852 -{
1.853 - if(!v.empty()) {
1.854 - i("point",v.bottomLeft());
1.855 - if(v.bottomLeft()!=v.topRight()) i("point",v.topRight());
1.856 - }
1.857 -}
1.858 -
1.859 -template<class T>
1.860 -void in(XmlReader &i,lemon::BoundingBox<T> &v)
1.861 -{
1.862 - v.clear();
1.863 - while(i.nextTag()=="point") {
1.864 - lemon::xy<T> co;
1.865 - i("point",co);
1.866 - v+=co;
1.867 - }
1.868 -}
2.1 --- a/lemon/graph_to_eps.h Tue Jul 26 13:15:13 2005 +0000
2.2 +++ b/lemon/graph_to_eps.h Tue Jul 26 14:31:29 2005 +0000
2.3 @@ -719,8 +719,8 @@
2.4 for(NodeIt n(g);n!=INVALID;++n) {
2.5 double ns=_nodeSizes[n]*_nodeScale;
2.6 xy<double> p(ns,ns);
2.7 - bb+=p+_coords[n];
2.8 - bb+=-p+_coords[n];
2.9 + bb.add(p+_coords[n]);
2.10 + bb.add(-p+_coords[n]);
2.11 }
2.12 if (bb.empty()) {
2.13 bb = BoundingBox<double>(xy<double>(0,0));
3.1 --- a/lemon/xy.h Tue Jul 26 13:15:13 2005 +0000
3.2 +++ b/lemon/xy.h Tue Jul 26 14:31:29 2005 +0000
3.3 @@ -306,7 +306,7 @@
3.4 }
3.5
3.6 ///Increments a bounding box with a point
3.7 - BoundingBox& operator +=(const xy<T>& u){
3.8 + BoundingBox& add(const xy<T>& u){
3.9 if (_empty){
3.10 bottom_left=top_right=u;
3.11 _empty = false;
3.12 @@ -320,17 +320,17 @@
3.13 return *this;
3.14 }
3.15
3.16 - ///Sums a bounding box and a point
3.17 - BoundingBox operator +(const xy<T>& u){
3.18 - BoundingBox b = *this;
3.19 - return b += u;
3.20 - }
3.21 +// ///Sums a bounding box and a point
3.22 +// BoundingBox operator +(const xy<T>& u){
3.23 +// BoundingBox b = *this;
3.24 +// return b += u;
3.25 +// }
3.26
3.27 ///Increments a bounding box with an other bounding box
3.28 - BoundingBox& operator +=(const BoundingBox &u){
3.29 + BoundingBox& add(const BoundingBox &u){
3.30 if ( !u.empty() ){
3.31 - *this += u.bottomLeft();
3.32 - *this += u.topRight();
3.33 + this->add(u.bottomLeft());
3.34 + this->add(u.topRight());
3.35 }
3.36 return *this;
3.37 }
3.38 @@ -338,7 +338,20 @@
3.39 ///Sums two bounding boxes
3.40 BoundingBox operator +(const BoundingBox& u){
3.41 BoundingBox b = *this;
3.42 - return b += u;
3.43 + return b.add(u);
3.44 + }
3.45 +
3.46 +
3.47 + ///Intersection of two bounding boxes
3.48 + BoundingBox operator &(const BoundingBox& u){
3.49 + BoundingBox b;
3.50 + b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
3.51 + b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
3.52 + b.top_right.x=std::min(this->top_right.x,u.top_right.x);
3.53 + b.top_right.y=std::min(this->top_right.y,u.top_right.y);
3.54 + b._empty = this->_empty || u._empty ||
3.55 + b.bottom_left.x>top_right.x && b.bottom_left.y>top_right.y;
3.56 + return b;
3.57 }
3.58
3.59 };//class Boundingbox
4.1 --- a/test/xy_test.cc Tue Jul 26 13:15:13 2005 +0000
4.2 +++ b/test/xy_test.cc Tue Jul 26 14:31:29 2005 +0000
4.3 @@ -51,9 +51,9 @@
4.4 BB doboz1;
4.5 check(doboz1.empty(), "It should be empty.");
4.6
4.7 - doboz1 += a;
4.8 + doboz1.add(a);
4.9 check(!doboz1.empty(), "It should not be empty.");
4.10 - doboz1 += b;
4.11 + doboz1.add(b);
4.12
4.13 check(doboz1.bottomLeft().x==1 &&
4.14 doboz1.bottomLeft().y==2 &&
4.15 @@ -74,7 +74,7 @@
4.16 check(!doboz2.empty(),
4.17 "It should not be empty. Constructed from 1 point.");
4.18
4.19 - doboz2 += doboz1;
4.20 + doboz2.add(doboz1);
4.21 check(doboz2.inside(seged),
4.22 "It should be inside. Incremented a box with an other.");
4.23 }