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