lemon/xy.h
author deba
Wed, 01 Mar 2006 10:17:25 +0000
changeset 1990 15fb7a4ea6be
parent 1956 a055123339d5
child 1993 2115143eceea
permissions -rw-r--r--
Some classes assumed that the GraphMaps should be inherited
from an ObserverBase. These classes parents replaced with
DefaultMap which cause that the graph maps should not be
inherited from the ObserverBase.
alpar@906
     1
/* -*- C++ -*-
alpar@906
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@906
     8
 *
alpar@906
     9
 * Permission to use, modify and distribute this software is granted
alpar@906
    10
 * provided that this copyright notice appears in all copies. For
alpar@906
    11
 * precise terms see the accompanying LICENSE file.
alpar@906
    12
 *
alpar@906
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    14
 * express or implied, and with no claim as to its suitability for any
alpar@906
    15
 * purpose.
alpar@906
    16
 *
alpar@906
    17
 */
alpar@906
    18
alpar@921
    19
#ifndef LEMON_XY_H
alpar@921
    20
#define LEMON_XY_H
athos@201
    21
athos@201
    22
#include <iostream>
deba@1420
    23
#include <lemon/utility.h>
athos@201
    24
klao@491
    25
///\ingroup misc
alpar@249
    26
///\file
alpar@249
    27
///\brief A simple two dimensional vector and a bounding box implementation 
alpar@249
    28
///
alpar@921
    29
/// The class \ref lemon::xy "xy" implements
alpar@249
    30
///a two dimensional vector with the usual
alpar@249
    31
/// operations.
alpar@249
    32
///
alpar@921
    33
/// The class \ref lemon::BoundingBox "BoundingBox" can be used to determine
ladanyi@1426
    34
/// the rectangular bounding box of a set of \ref lemon::xy "xy"'s.
alpar@458
    35
///
alpar@458
    36
///\author Attila Bernath
alpar@249
    37
alpar@249
    38
alpar@921
    39
namespace lemon {
alpar@431
    40
alpar@431
    41
  /// \addtogroup misc
alpar@431
    42
  /// @{
alpar@431
    43
alpar@1257
    44
  /// A simple two dimensional vector (plainvector) implementation
alpar@242
    45
alpar@1257
    46
  /// A simple two dimensional vector (plainvector) implementation
alpar@458
    47
  ///with the usual vector
alpar@458
    48
  /// operators.
alpar@458
    49
  ///
alpar@458
    50
  ///\author Attila Bernath
athos@207
    51
  template<typename T>
athos@207
    52
    class xy {
athos@201
    53
athos@207
    54
    public:
athos@240
    55
alpar@987
    56
      typedef T Value;
alpar@964
    57
alpar@1974
    58
      ///First co-ordinate
alpar@1974
    59
      T x;
alpar@1974
    60
      ///Second co-ordinate
alpar@1974
    61
      T y;     
athos@207
    62
      
alpar@1257
    63
      ///Default constructor
alpar@1257
    64
      xy() {}
athos@201
    65
athos@240
    66
      ///Constructing the instance from coordinates
athos@514
    67
      xy(T a, T b) : x(a), y(b) { }
athos@201
    68
athos@201
    69
alpar@1049
    70
      ///Conversion constructor
alpar@1049
    71
      template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
alpar@1049
    72
athos@207
    73
      ///Gives back the square of the norm of the vector
alpar@1257
    74
      T normSquare() const {
ladanyi@1426
    75
        return x*x+y*y;
alpar@1391
    76
      }
athos@201
    77
  
athos@207
    78
      ///Increments the left hand side by u
alpar@1257
    79
      xy<T>& operator +=(const xy<T>& u) {
ladanyi@1426
    80
        x += u.x;
ladanyi@1426
    81
        y += u.y;
ladanyi@1426
    82
        return *this;
alpar@1391
    83
      }
athos@201
    84
  
athos@207
    85
      ///Decrements the left hand side by u
alpar@1257
    86
      xy<T>& operator -=(const xy<T>& u) {
ladanyi@1426
    87
        x -= u.x;
ladanyi@1426
    88
        y -= u.y;
ladanyi@1426
    89
        return *this;
alpar@1391
    90
      }
athos@201
    91
athos@207
    92
      ///Multiplying the left hand side with a scalar
alpar@1257
    93
      xy<T>& operator *=(const T &u) {
ladanyi@1426
    94
        x *= u;
ladanyi@1426
    95
        y *= u;
ladanyi@1426
    96
        return *this;
alpar@1391
    97
      }
athos@207
    98
athos@207
    99
      ///Dividing the left hand side by a scalar
alpar@1257
   100
      xy<T>& operator /=(const T &u) {
ladanyi@1426
   101
        x /= u;
ladanyi@1426
   102
        y /= u;
ladanyi@1426
   103
        return *this;
alpar@1391
   104
      }
athos@201
   105
  
athos@207
   106
      ///Returns the scalar product of two vectors
alpar@1257
   107
      T operator *(const xy<T>& u) const {
ladanyi@1426
   108
        return x*u.x+y*u.y;
alpar@1391
   109
      }
athos@201
   110
  
athos@207
   111
      ///Returns the sum of two vectors
athos@207
   112
      xy<T> operator+(const xy<T> &u) const {
ladanyi@1426
   113
        xy<T> b=*this;
ladanyi@1426
   114
        return b+=u;
alpar@1391
   115
      }
athos@201
   116
alpar@1049
   117
      ///Returns the neg of the vectors
alpar@1049
   118
      xy<T> operator-() const {
ladanyi@1426
   119
        xy<T> b=*this;
ladanyi@1426
   120
        b.x=-b.x; b.y=-b.y;
ladanyi@1426
   121
        return b;
alpar@1391
   122
      }
alpar@1049
   123
athos@207
   124
      ///Returns the difference of two vectors
athos@207
   125
      xy<T> operator-(const xy<T> &u) const {
ladanyi@1426
   126
        xy<T> b=*this;
ladanyi@1426
   127
        return b-=u;
alpar@1391
   128
      }
athos@201
   129
athos@207
   130
      ///Returns a vector multiplied by a scalar
athos@207
   131
      xy<T> operator*(const T &u) const {
ladanyi@1426
   132
        xy<T> b=*this;
ladanyi@1426
   133
        return b*=u;
alpar@1391
   134
      }
athos@201
   135
athos@207
   136
      ///Returns a vector divided by a scalar
athos@207
   137
      xy<T> operator/(const T &u) const {
ladanyi@1426
   138
        xy<T> b=*this;
ladanyi@1426
   139
        return b/=u;
alpar@1391
   140
      }
athos@201
   141
athos@207
   142
      ///Testing equality
alpar@1257
   143
      bool operator==(const xy<T> &u) const {
ladanyi@1426
   144
        return (x==u.x) && (y==u.y);
alpar@1391
   145
      }
athos@201
   146
athos@207
   147
      ///Testing inequality
alpar@1257
   148
      bool operator!=(xy u) const {
ladanyi@1426
   149
        return  (x!=u.x) || (y!=u.y);
alpar@1391
   150
      }
athos@201
   151
athos@207
   152
    };
athos@201
   153
alpar@1071
   154
  ///Returns a vector multiplied by a scalar
alpar@1083
   155
alpar@1083
   156
  ///Returns a vector multiplied by a scalar
alpar@1083
   157
  ///\relates xy
alpar@1071
   158
  template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
alpar@1071
   159
    return x*u;
alpar@1391
   160
  }
alpar@1071
   161
alpar@814
   162
  ///Read a plainvector from a stream
alpar@814
   163
alpar@967
   164
  ///Read a plainvector from a stream
alpar@814
   165
  ///\relates xy
alpar@814
   166
  ///
athos@207
   167
  template<typename T>
deba@1392
   168
  inline std::istream& operator>>(std::istream &is, xy<T> &z) {
deba@1392
   169
    char c;
deba@1392
   170
    if (is >> c) {
deba@1392
   171
      if (c != '(') is.putback(c);
deba@1392
   172
    } else {
deba@1392
   173
      is.clear();
deba@1392
   174
    }
deba@1392
   175
    if (!(is >> z.x)) return is;
deba@1392
   176
    if (is >> c) {
deba@1392
   177
      if (c != ',') is.putback(c);
deba@1392
   178
    } else {
deba@1392
   179
      is.clear();
deba@1392
   180
    }
deba@1392
   181
    if (!(is >> z.y)) return is;
deba@1392
   182
    if (is >> c) {
deba@1392
   183
      if (c != ')') is.putback(c);
deba@1392
   184
    } else {
deba@1392
   185
      is.clear();
deba@1392
   186
    }
athos@207
   187
    return is;
athos@207
   188
  }
athos@201
   189
alpar@814
   190
  ///Write a plainvector to a stream
alpar@814
   191
alpar@967
   192
  ///Write a plainvector to a stream
alpar@814
   193
  ///\relates xy
alpar@814
   194
  ///
athos@207
   195
  template<typename T>
deba@1392
   196
  inline std::ostream& operator<<(std::ostream &os, const xy<T>& z)
athos@207
   197
  {
athos@240
   198
    os << "(" << z.x << ", " << z.y << ")";
athos@207
   199
    return os;
athos@207
   200
  }
athos@207
   201
alpar@1202
   202
  ///Rotate by 90 degrees
alpar@1202
   203
alpar@1202
   204
  ///Returns its parameter rotated by 90 degrees in positive direction.
alpar@1202
   205
  ///\relates xy
alpar@1202
   206
  ///
alpar@1202
   207
  template<typename T>
alpar@1202
   208
  inline xy<T> rot90(const xy<T> &z)
alpar@1202
   209
  {
alpar@1202
   210
    return xy<T>(-z.y,z.x);
alpar@1202
   211
  }
alpar@1202
   212
alpar@1202
   213
  ///Rotate by 270 degrees
alpar@1202
   214
alpar@1202
   215
  ///Returns its parameter rotated by 90 degrees in negative direction.
alpar@1202
   216
  ///\relates xy
alpar@1202
   217
  ///
alpar@1202
   218
  template<typename T>
alpar@1202
   219
  inline xy<T> rot270(const xy<T> &z)
alpar@1202
   220
  {
alpar@1202
   221
    return xy<T>(z.y,-z.x);
alpar@1202
   222
  }
alpar@1202
   223
alpar@1202
   224
  
athos@244
   225
alpar@458
   226
  /// A class to calculate or store the bounding box of plainvectors.
alpar@458
   227
alpar@458
   228
  /// A class to calculate or store the bounding box of plainvectors.
alpar@458
   229
  ///
alpar@458
   230
  ///\author Attila Bernath
athos@244
   231
  template<typename T>
athos@244
   232
    class BoundingBox {
athos@244
   233
      xy<T> bottom_left, top_right;
athos@244
   234
      bool _empty;
athos@244
   235
    public:
athos@244
   236
      
ladanyi@1426
   237
      ///Default constructor: creates an empty bounding box
athos@244
   238
      BoundingBox() { _empty = true; }
athos@244
   239
athos@244
   240
      ///Constructing the instance from one point
athos@244
   241
      BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
athos@244
   242
ladanyi@1426
   243
      ///Were any points added?
athos@244
   244
      bool empty() const {
ladanyi@1426
   245
        return _empty;
athos@244
   246
      }
athos@244
   247
alpar@1391
   248
      ///Makes the BoundingBox empty
alpar@1391
   249
      void clear() {
ladanyi@1426
   250
        _empty=1;
alpar@1391
   251
      }
alpar@1391
   252
alpar@1927
   253
      ///\brief Gives back the bottom left corner
alpar@1927
   254
      ///(if the bounding box is empty, then the return value is not defined) 
athos@244
   255
      xy<T> bottomLeft() const {
ladanyi@1426
   256
        return bottom_left;
alpar@1391
   257
      }
athos@244
   258
alpar@1927
   259
      ///\brief Sets the bottom left corner
alpar@1927
   260
      ///(should only bee used for non-empty box) 
alpar@1927
   261
      void bottomLeft(xy<T> p) {
alpar@1927
   262
	bottom_left = p;
alpar@1927
   263
      }
alpar@1927
   264
alpar@1927
   265
      ///\brief Gives back the top right corner
alpar@1927
   266
      ///(if the bounding box is empty, then the return value is not defined) 
athos@244
   267
      xy<T> topRight() const {
ladanyi@1426
   268
        return top_right;
alpar@1391
   269
      }
athos@244
   270
alpar@1927
   271
      ///\brief Sets the top right corner
alpar@1927
   272
      ///(should only bee used for non-empty box) 
alpar@1927
   273
      void topRight(xy<T> p) {
alpar@1927
   274
	top_right = p;
alpar@1927
   275
      }
alpar@1927
   276
alpar@1927
   277
      ///\brief Gives back the bottom right corner
alpar@1927
   278
      ///(if the bounding box is empty, then the return value is not defined) 
alpar@1045
   279
      xy<T> bottomRight() const {
ladanyi@1426
   280
        return xy<T>(top_right.x,bottom_left.y);
alpar@1391
   281
      }
alpar@1045
   282
alpar@1927
   283
      ///\brief Sets the bottom right corner
alpar@1927
   284
      ///(should only bee used for non-empty box) 
alpar@1927
   285
      void bottomRight(xy<T> p) {
alpar@1927
   286
	top_right.x = p.x;
alpar@1927
   287
	bottom_left.y = p.y;
alpar@1927
   288
      }
alpar@1927
   289
alpar@1927
   290
      ///\brief Gives back the top left corner
alpar@1927
   291
      ///(if the bounding box is empty, then the return value is not defined) 
alpar@1045
   292
      xy<T> topLeft() const {
ladanyi@1426
   293
        return xy<T>(bottom_left.x,top_right.y);
alpar@1391
   294
      }
alpar@1045
   295
alpar@1927
   296
      ///\brief Sets the top left corner
alpar@1927
   297
      ///(should only bee used for non-empty box) 
alpar@1927
   298
      void topLeft(xy<T> p) {
alpar@1927
   299
	top_right.y = p.y;
alpar@1927
   300
	bottom_left.x = p.x;
alpar@1927
   301
      }
alpar@1927
   302
alpar@1927
   303
      ///\brief Gives back the bottom of the box
alpar@1927
   304
      ///(if the bounding box is empty, then the return value is not defined) 
alpar@1045
   305
      T bottom() const {
ladanyi@1426
   306
        return bottom_left.y;
alpar@1391
   307
      }
alpar@1045
   308
alpar@1927
   309
      ///\brief Sets the bottom of the box
alpar@1927
   310
      ///(should only bee used for non-empty box) 
alpar@1927
   311
      void bottom(T t) {
alpar@1927
   312
	bottom_left.y = t;
alpar@1927
   313
      }
alpar@1927
   314
alpar@1927
   315
      ///\brief Gives back the top of the box
alpar@1927
   316
      ///(if the bounding box is empty, then the return value is not defined) 
alpar@1045
   317
      T top() const {
ladanyi@1426
   318
        return top_right.y;
alpar@1391
   319
      }
alpar@1045
   320
alpar@1927
   321
      ///\brief Sets the top of the box
alpar@1927
   322
      ///(should only bee used for non-empty box) 
alpar@1927
   323
      void top(T t) {
alpar@1927
   324
	top_right.y = t;
alpar@1927
   325
      }
alpar@1927
   326
alpar@1927
   327
      ///\brief Gives back the left side of the box
alpar@1927
   328
      ///(if the bounding box is empty, then the return value is not defined) 
alpar@1045
   329
      T left() const {
ladanyi@1426
   330
        return bottom_left.x;
alpar@1391
   331
      }
alpar@1045
   332
alpar@1927
   333
      ///\brief Sets the left side of the box
alpar@1927
   334
      ///(should only bee used for non-empty box) 
alpar@1927
   335
      void left(T t) {
alpar@1927
   336
	bottom_left.x = t;
alpar@1927
   337
      }
alpar@1927
   338
alpar@1927
   339
      ///\brief Gives back the right side of the box
alpar@1927
   340
      ///(if the bounding box is empty, then the return value is not defined) 
alpar@1045
   341
      T right() const {
ladanyi@1426
   342
        return top_right.x;
alpar@1391
   343
      }
alpar@1045
   344
alpar@1927
   345
      ///\brief Sets the right side of the box
alpar@1927
   346
      ///(should only bee used for non-empty box) 
alpar@1927
   347
      void right(T t) {
alpar@1927
   348
	top_right.x = t;
alpar@1927
   349
      }
alpar@1927
   350
alpar@1927
   351
      ///\brief Gives back the height of the box
alpar@1927
   352
      ///(if the bounding box is empty, then the return value is not defined) 
alpar@1102
   353
      T height() const {
ladanyi@1426
   354
        return top_right.y-bottom_left.y;
alpar@1391
   355
      }
alpar@1102
   356
alpar@1927
   357
      ///\brief Gives back the width of the box
alpar@1927
   358
      ///(if the bounding box is empty, then the return value is not defined) 
alpar@1102
   359
      T width() const {
ladanyi@1426
   360
        return top_right.x-bottom_left.x;
alpar@1391
   361
      }
alpar@1102
   362
athos@244
   363
      ///Checks whether a point is inside a bounding box
athos@244
   364
      bool inside(const xy<T>& u){
ladanyi@1426
   365
        if (_empty)
ladanyi@1426
   366
          return false;
ladanyi@1426
   367
        else{
ladanyi@1426
   368
          return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
ladanyi@1426
   369
              (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
ladanyi@1426
   370
        }
athos@244
   371
      }
athos@244
   372
  
athos@244
   373
      ///Increments a bounding box with a point
alpar@1588
   374
      BoundingBox& add(const xy<T>& u){
ladanyi@1426
   375
        if (_empty){
ladanyi@1426
   376
          bottom_left=top_right=u;
ladanyi@1426
   377
          _empty = false;
ladanyi@1426
   378
        }
ladanyi@1426
   379
        else{
ladanyi@1426
   380
          if (bottom_left.x > u.x) bottom_left.x = u.x;
ladanyi@1426
   381
          if (bottom_left.y > u.y) bottom_left.y = u.y;
ladanyi@1426
   382
          if (top_right.x < u.x) top_right.x = u.x;
ladanyi@1426
   383
          if (top_right.y < u.y) top_right.y = u.y;
ladanyi@1426
   384
        }
ladanyi@1426
   385
        return *this;
alpar@1391
   386
      }
athos@244
   387
  
alpar@1588
   388
//       ///Sums a bounding box and a point
alpar@1588
   389
//       BoundingBox operator +(const xy<T>& u){
alpar@1588
   390
//         BoundingBox b = *this;
alpar@1588
   391
//         return b += u;
alpar@1588
   392
//       }
athos@244
   393
athos@244
   394
      ///Increments a bounding box with an other bounding box
alpar@1588
   395
      BoundingBox& add(const BoundingBox &u){
ladanyi@1426
   396
        if ( !u.empty() ){
alpar@1588
   397
          this->add(u.bottomLeft());
alpar@1588
   398
	  this->add(u.topRight());
ladanyi@1426
   399
        }
ladanyi@1426
   400
        return *this;
alpar@1391
   401
      }
athos@244
   402
  
athos@244
   403
      ///Sums two bounding boxes
athos@244
   404
      BoundingBox operator +(const BoundingBox& u){
ladanyi@1426
   405
        BoundingBox b = *this;
alpar@1588
   406
        return b.add(u);
alpar@1588
   407
      }
alpar@1588
   408
alpar@1588
   409
alpar@1588
   410
      ///Intersection of two bounding boxes
alpar@1588
   411
      BoundingBox operator &(const BoundingBox& u){
alpar@1588
   412
        BoundingBox b;
alpar@1588
   413
	b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
alpar@1588
   414
	b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
alpar@1588
   415
	b.top_right.x=std::min(this->top_right.x,u.top_right.x);
alpar@1588
   416
	b.top_right.y=std::min(this->top_right.y,u.top_right.y);
alpar@1588
   417
	b._empty = this->_empty || u._empty ||
alpar@1588
   418
	  b.bottom_left.x>top_right.x && b.bottom_left.y>top_right.y;
alpar@1588
   419
        return b;
alpar@1391
   420
      }
athos@244
   421
athos@244
   422
    };//class Boundingbox
athos@244
   423
athos@244
   424
alpar@1317
   425
  ///Map of x-coordinates of an xy<>-map
alpar@1317
   426
alpar@1317
   427
  ///\ingroup maps
alpar@1317
   428
  ///
alpar@1317
   429
  template<class M>
alpar@1317
   430
  class XMap 
alpar@1317
   431
  {
deba@1706
   432
    M& _map;
alpar@1317
   433
  public:
deba@1420
   434
alpar@1317
   435
    typedef typename M::Value::Value Value;
alpar@1317
   436
    typedef typename M::Key Key;
alpar@1317
   437
    ///\e
deba@1706
   438
    XMap(M& map) : _map(map) {}
alpar@1317
   439
    Value operator[](Key k) const {return _map[k].x;}
alpar@1352
   440
    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
alpar@1317
   441
  };
alpar@1317
   442
    
alpar@1317
   443
  ///Returns an \ref XMap class
alpar@1317
   444
alpar@1317
   445
  ///This function just returns an \ref XMap class.
alpar@1317
   446
  ///
alpar@1317
   447
  ///\ingroup maps
alpar@1317
   448
  ///\relates XMap
alpar@1317
   449
  template<class M> 
alpar@1317
   450
  inline XMap<M> xMap(M &m) 
alpar@1317
   451
  {
alpar@1317
   452
    return XMap<M>(m);
alpar@1317
   453
  }
alpar@1317
   454
deba@1420
   455
  template<class M> 
deba@1420
   456
  inline XMap<M> xMap(const M &m) 
deba@1420
   457
  {
deba@1420
   458
    return XMap<M>(m);
deba@1420
   459
  }
deba@1420
   460
alpar@1317
   461
  ///Constant (read only) version of \ref XMap
alpar@1317
   462
alpar@1317
   463
  ///\ingroup maps
alpar@1317
   464
  ///
alpar@1317
   465
  template<class M>
alpar@1317
   466
  class ConstXMap 
alpar@1317
   467
  {
deba@1706
   468
    const M& _map;
alpar@1317
   469
  public:
deba@1420
   470
alpar@1317
   471
    typedef typename M::Value::Value Value;
alpar@1317
   472
    typedef typename M::Key Key;
alpar@1317
   473
    ///\e
alpar@1317
   474
    ConstXMap(const M &map) : _map(map) {}
alpar@1317
   475
    Value operator[](Key k) const {return _map[k].x;}
alpar@1317
   476
  };
alpar@1317
   477
    
alpar@1317
   478
  ///Returns a \ref ConstXMap class
alpar@1317
   479
alpar@1317
   480
  ///This function just returns an \ref ConstXMap class.
alpar@1317
   481
  ///
alpar@1317
   482
  ///\ingroup maps
alpar@1317
   483
  ///\relates ConstXMap
alpar@1317
   484
  template<class M> 
alpar@1317
   485
  inline ConstXMap<M> xMap(const M &m) 
alpar@1317
   486
  {
alpar@1317
   487
    return ConstXMap<M>(m);
alpar@1317
   488
  }
alpar@1317
   489
alpar@1317
   490
  ///Map of y-coordinates of an xy<>-map
alpar@1317
   491
    
alpar@1317
   492
  ///\ingroup maps
alpar@1317
   493
  ///
alpar@1317
   494
  template<class M>
alpar@1317
   495
  class YMap 
alpar@1317
   496
  {
deba@1706
   497
    M& _map;
alpar@1317
   498
  public:
deba@1420
   499
alpar@1317
   500
    typedef typename M::Value::Value Value;
alpar@1317
   501
    typedef typename M::Key Key;
alpar@1317
   502
    ///\e
deba@1706
   503
    YMap(M& map) : _map(map) {}
alpar@1317
   504
    Value operator[](Key k) const {return _map[k].y;}
alpar@1352
   505
    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
alpar@1317
   506
  };
alpar@1317
   507
alpar@1317
   508
  ///Returns an \ref YMap class
alpar@1317
   509
alpar@1317
   510
  ///This function just returns an \ref YMap class.
alpar@1317
   511
  ///
alpar@1317
   512
  ///\ingroup maps
alpar@1317
   513
  ///\relates YMap
alpar@1317
   514
  template<class M> 
alpar@1317
   515
  inline YMap<M> yMap(M &m) 
alpar@1317
   516
  {
alpar@1317
   517
    return YMap<M>(m);
alpar@1317
   518
  }
alpar@1317
   519
deba@1420
   520
  template<class M> 
deba@1420
   521
  inline YMap<M> yMap(const M &m) 
deba@1420
   522
  {
deba@1420
   523
    return YMap<M>(m);
deba@1420
   524
  }
deba@1420
   525
alpar@1317
   526
  ///Constant (read only) version of \ref YMap
alpar@1317
   527
alpar@1317
   528
  ///\ingroup maps
alpar@1317
   529
  ///
alpar@1317
   530
  template<class M>
alpar@1317
   531
  class ConstYMap 
alpar@1317
   532
  {
deba@1706
   533
    const M& _map;
alpar@1317
   534
  public:
deba@1420
   535
alpar@1317
   536
    typedef typename M::Value::Value Value;
alpar@1317
   537
    typedef typename M::Key Key;
alpar@1317
   538
    ///\e
alpar@1317
   539
    ConstYMap(const M &map) : _map(map) {}
alpar@1317
   540
    Value operator[](Key k) const {return _map[k].y;}
alpar@1317
   541
  };
alpar@1317
   542
    
alpar@1317
   543
  ///Returns a \ref ConstYMap class
alpar@1317
   544
alpar@1317
   545
  ///This function just returns an \ref ConstYMap class.
alpar@1317
   546
  ///
alpar@1317
   547
  ///\ingroup maps
alpar@1317
   548
  ///\relates ConstYMap
alpar@1317
   549
  template<class M> 
alpar@1317
   550
  inline ConstYMap<M> yMap(const M &m) 
alpar@1317
   551
  {
alpar@1317
   552
    return ConstYMap<M>(m);
alpar@1317
   553
  }
alpar@1317
   554
alpar@1317
   555
alpar@1352
   556
  ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
alpar@1352
   557
alpar@1352
   558
  ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
alpar@1352
   559
  ///\ingroup maps
alpar@1352
   560
  ///
alpar@1352
   561
  template<class M>
alpar@1352
   562
  class NormSquareMap 
alpar@1352
   563
  {
deba@1706
   564
    const M& _map;
alpar@1352
   565
  public:
deba@1420
   566
alpar@1352
   567
    typedef typename M::Value::Value Value;
alpar@1352
   568
    typedef typename M::Key Key;
alpar@1352
   569
    ///\e
alpar@1352
   570
    NormSquareMap(const M &map) : _map(map) {}
alpar@1352
   571
    Value operator[](Key k) const {return _map[k].normSquare();}
alpar@1352
   572
  };
alpar@1352
   573
    
alpar@1352
   574
  ///Returns a \ref NormSquareMap class
alpar@1352
   575
alpar@1352
   576
  ///This function just returns an \ref NormSquareMap class.
alpar@1352
   577
  ///
alpar@1352
   578
  ///\ingroup maps
alpar@1352
   579
  ///\relates NormSquareMap
alpar@1352
   580
  template<class M> 
alpar@1352
   581
  inline NormSquareMap<M> normSquareMap(const M &m) 
alpar@1352
   582
  {
alpar@1352
   583
    return NormSquareMap<M>(m);
alpar@1352
   584
  }
alpar@1352
   585
alpar@431
   586
  /// @}
athos@244
   587
athos@244
   588
alpar@921
   589
} //namespace lemon
athos@201
   590
alpar@921
   591
#endif //LEMON_XY_H