lemon/concept/graph_component.h
author deba
Mon, 03 Apr 2006 09:45:23 +0000
changeset 2031 080d51024ac5
parent 1993 2115143eceea
child 2111 ea1fa1bc3f6d
permissions -rw-r--r--
Correcting the structure of the graph's and adaptor's map.
The template assign operators and map iterators can be used for adaptors also.

Some bugfix in the adaptors

New class SwapBpUGraphAdaptor which swaps the two nodeset of the graph.
klao@959
     1
/* -*- C++ -*-
klao@959
     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).
klao@959
     8
 *
klao@959
     9
 * Permission to use, modify and distribute this software is granted
klao@959
    10
 * provided that this copyright notice appears in all copies. For
klao@959
    11
 * precise terms see the accompanying LICENSE file.
klao@959
    12
 *
klao@959
    13
 * This software is provided "AS IS" with no warranty of any kind,
klao@959
    14
 * express or implied, and with no claim as to its suitability for any
klao@959
    15
 * purpose.
klao@959
    16
 *
klao@959
    17
 */
klao@959
    18
klao@1030
    19
///\ingroup graph_concepts
klao@959
    20
///\file
klao@959
    21
///\brief The graph components.
klao@959
    22
klao@959
    23
klao@959
    24
#ifndef LEMON_CONCEPT_GRAPH_COMPONENT_H
klao@959
    25
#define LEMON_CONCEPT_GRAPH_COMPONENT_H
klao@959
    26
deba@1993
    27
#include <lemon/bits/invalid.h>
klao@959
    28
#include <lemon/concept/maps.h>
klao@959
    29
deba@1307
    30
#include <lemon/bits/alteration_notifier.h>
deba@1134
    31
klao@959
    32
namespace lemon {
klao@959
    33
  namespace concept {
klao@959
    34
klao@961
    35
    /****************   Graph iterator concepts   ****************/
klao@961
    36
klao@1030
    37
    /// Skeleton class for graph Node and Edge types
klao@961
    38
klao@1909
    39
    /// This class describes the interface of Node and Edge (and UEdge
klao@1030
    40
    /// in undirected graphs) subtypes of graph types.
klao@1030
    41
    ///
klao@1030
    42
    /// \note This class is a template class so that we can use it to
klao@1030
    43
    /// create graph skeleton classes. The reason for this is than Node
klao@1030
    44
    /// and Edge types should \em not derive from the same base class.
klao@1030
    45
    /// For Node you should instantiate it with character 'n' and for Edge
klao@1030
    46
    /// with 'e'.
klao@961
    47
klao@1030
    48
#ifndef DOXYGEN
klao@1030
    49
    template <char _selector = '0'>
klao@1030
    50
#endif
klao@961
    51
    class GraphItem {
klao@961
    52
    public:
deba@989
    53
      /// Default constructor.
deba@989
    54
      
klao@1030
    55
      /// \warning The default constructor is not required to set
klao@1030
    56
      /// the item to some well-defined value. So you should consider it
klao@1030
    57
      /// as uninitialized.
klao@961
    58
      GraphItem() {}
deba@989
    59
      /// Copy constructor.
deba@989
    60
      
deba@989
    61
      /// Copy constructor.
deba@989
    62
      ///
deba@989
    63
      GraphItem(GraphItem const&) {}
deba@989
    64
      /// Invalid constructor \& conversion.
deba@989
    65
deba@989
    66
      /// This constructor initializes the item to be invalid.
deba@989
    67
      /// \sa Invalid for more details.
klao@961
    68
      GraphItem(Invalid) {}
deba@989
    69
      /// Assign operator for nodes.
klao@961
    70
deba@989
    71
      /// The nodes are assignable. 
deba@989
    72
      ///
klao@961
    73
      GraphItem& operator=(GraphItem const&) { return *this; }
deba@989
    74
      /// Equality operator.
deba@989
    75
      
deba@989
    76
      /// Two iterators are equal if and only if they represents the
deba@989
    77
      /// same node in the graph or both are invalid.
klao@961
    78
      bool operator==(GraphItem) const { return false; }
deba@989
    79
      /// Inequality operator.
deba@989
    80
	
deba@989
    81
      /// \sa operator==(const Node& n)
deba@989
    82
      ///
klao@961
    83
      bool operator!=(GraphItem) const { return false; }
klao@961
    84
klao@1030
    85
      /// Artificial ordering operator.
deba@989
    86
klao@1030
    87
      /// To allow the use of graph descriptors as key type in std::map or
klao@1030
    88
      /// similar associative container we require this.
klao@1030
    89
      ///
klao@1030
    90
      /// \note This operator only have to define some strict ordering of
klao@1030
    91
      /// the items; this order has nothing to do with the iteration
klao@1030
    92
      /// ordering of the items.
klao@1030
    93
      ///
klao@1030
    94
      /// \bug This is a technical requirement. Do we really need this?
klao@1030
    95
      bool operator<(GraphItem) const { return false; }
deba@989
    96
deba@989
    97
      template<typename _GraphItem>
deba@989
    98
      struct Constraints {
deba@989
    99
	void constraints() {
deba@989
   100
	  _GraphItem i1;
deba@989
   101
	  _GraphItem i2 = i1;
deba@989
   102
	  _GraphItem i3 = INVALID;
deba@989
   103
	  
deba@989
   104
	  i1 = i2 = i3;
deba@989
   105
deba@989
   106
	  bool b;
deba@989
   107
	  //	  b = (ia == ib) && (ia != ib) && (ia < ib);
deba@989
   108
	  b = (ia == ib) && (ia != ib);
deba@989
   109
	  b = (ia == INVALID) && (ib != INVALID);
deba@1136
   110
	  //	  b = (ia < ib);
deba@989
   111
	}
deba@989
   112
deba@989
   113
	const _GraphItem &ia;
deba@989
   114
	const _GraphItem &ib;
deba@989
   115
      };
klao@961
   116
    };
klao@961
   117
klao@1030
   118
    /// A type describing the concept of graph node
klao@1030
   119
klao@1030
   120
    /// This is an instantiation of \ref GraphItem which can be used as a
klao@1030
   121
    /// Node subtype in graph skeleton definitions
klao@1030
   122
    typedef GraphItem<'n'> GraphNode;
klao@1030
   123
klao@1030
   124
    /// A type describing the concept of graph edge
klao@1030
   125
klao@1030
   126
    /// This is an instantiation of \ref GraphItem which can be used as a
klao@1030
   127
    /// Edge subtype in graph skeleton definitions
klao@1030
   128
    typedef GraphItem<'e'> GraphEdge;
klao@1030
   129
klao@1030
   130
klao@1030
   131
    /**************** Basic features of graphs ****************/
klao@1030
   132
klao@959
   133
    /// An empty base graph class.
klao@959
   134
  
klao@961
   135
    /// This class provides the minimal set of features needed for a graph
klao@961
   136
    /// structure. All graph concepts have to be conform to this base
klao@961
   137
    /// graph.
klao@961
   138
    ///
klao@961
   139
    /// \bug This is not true. The minimal graph concept is the
klao@961
   140
    /// BaseIterableGraphComponent.
klao@959
   141
klao@959
   142
    class BaseGraphComponent {
klao@959
   143
    public:
klao@959
   144
klao@959
   145
      typedef BaseGraphComponent Graph;
klao@959
   146
      
klao@959
   147
      /// Node class of the graph.
klao@959
   148
klao@959
   149
      /// This class represents the Nodes of the graph. 
klao@959
   150
      ///
deba@989
   151
      typedef GraphItem<'n'> Node;
klao@959
   152
klao@959
   153
      /// Edge class of the graph.
klao@959
   154
klao@959
   155
      /// This class represents the Edges of the graph. 
klao@959
   156
      ///
deba@989
   157
      typedef GraphItem<'e'> Edge;
klao@959
   158
alpar@986
   159
      ///Gives back the target node of an edge.
klao@959
   160
alpar@986
   161
      ///Gives back the target node of an edge.
klao@959
   162
      ///
alpar@986
   163
      Node target(const Edge&) const { return INVALID;}
klao@959
   164
alpar@986
   165
      ///Gives back the source node of an edge.
klao@959
   166
alpar@986
   167
      ///Gives back the source node of an edge.
klao@959
   168
      ///
alpar@986
   169
      Node source(const Edge&) const { return INVALID;}
klao@959
   170
klao@961
   171
deba@989
   172
      template <typename _Graph>
deba@989
   173
      struct Constraints {
deba@989
   174
	typedef typename _Graph::Node Node;
deba@989
   175
	typedef typename _Graph::Edge Edge;
klao@959
   176
      
deba@989
   177
	void constraints() {
deba@989
   178
	  checkConcept<GraphItem<'n'>, Node>();
deba@989
   179
	  checkConcept<GraphItem<'e'>, Edge>();
deba@989
   180
	  {
deba@989
   181
	    Node n;
alpar@1644
   182
	    Edge e(INVALID);
deba@989
   183
	    n = graph.source(e);
deba@989
   184
	    n = graph.target(e);
deba@989
   185
	  }      
deba@989
   186
	}
klao@959
   187
      
deba@989
   188
	const _Graph& graph;
deba@989
   189
      };
klao@959
   190
    };
klao@959
   191
klao@959
   192
    /// An empty iterable base graph class.
klao@959
   193
  
klao@959
   194
    /// This class provides beside the core graph features
klao@959
   195
    /// core iterable interface for the graph structure.
klao@959
   196
    /// Most of the base graphs should be conform to this concept.
klao@959
   197
klao@959
   198
    class BaseIterableGraphComponent : virtual public BaseGraphComponent {
klao@959
   199
    public:
klao@959
   200
klao@959
   201
      typedef BaseGraphComponent::Node Node;
klao@959
   202
      typedef BaseGraphComponent::Edge Edge;
klao@959
   203
klao@959
   204
      /// Gives back the first Node in the iterating order.
klao@959
   205
      
klao@959
   206
      /// Gives back the first Node in the iterating order.
klao@959
   207
      ///     
klao@959
   208
      void first(Node&) const {}
klao@959
   209
klao@959
   210
      /// Gives back the next Node in the iterating order.
klao@959
   211
      
klao@959
   212
      /// Gives back the next Node in the iterating order.
klao@959
   213
      ///     
klao@959
   214
      void next(Node&) const {}
klao@959
   215
klao@959
   216
      /// Gives back the first Edge in the iterating order.
klao@959
   217
      
klao@959
   218
      /// Gives back the first Edge in the iterating order.
klao@959
   219
      ///     
klao@959
   220
      void first(Edge&) const {}
klao@959
   221
      /// Gives back the next Edge in the iterating order.
klao@959
   222
      
klao@959
   223
      /// Gives back the next Edge in the iterating order.
klao@959
   224
      ///     
klao@959
   225
      void next(Edge&) const {}
klao@959
   226
klao@959
   227
klao@959
   228
      /// Gives back the first of the Edges point to the given Node.
klao@959
   229
      
klao@959
   230
      /// Gives back the first of the Edges point to the given Node.
klao@959
   231
      ///     
klao@959
   232
      void firstIn(Edge&, const Node&) const {}
klao@959
   233
klao@959
   234
      /// Gives back the next of the Edges points to the given Node.
klao@959
   235
klao@959
   236
klao@959
   237
      /// Gives back the next of the Edges points to the given Node.
klao@959
   238
      ///
klao@959
   239
      void nextIn(Edge&) const {}
klao@959
   240
klao@959
   241
      /// Gives back the first of the Edges start from the given Node.
klao@959
   242
      
klao@959
   243
      /// Gives back the first of the Edges start from the given Node.
klao@959
   244
      ///     
klao@959
   245
      void firstOut(Edge&, const Node&) const {}
klao@959
   246
klao@959
   247
      /// Gives back the next of the Edges start from the given Node.
klao@959
   248
      
klao@959
   249
      /// Gives back the next of the Edges start from the given Node.
klao@959
   250
      ///     
klao@959
   251
      void nextOut(Edge&) const {}
klao@959
   252
klao@959
   253
deba@989
   254
      template <typename _Graph>
deba@989
   255
      struct Constraints {
deba@989
   256
      
deba@989
   257
	void constraints() {
deba@989
   258
	  checkConcept< BaseGraphComponent, _Graph >();
deba@989
   259
	  typename _Graph::Node node;      
deba@989
   260
	  typename _Graph::Edge edge;
deba@989
   261
	  {
deba@989
   262
	    graph.first(node);
deba@989
   263
	    graph.next(node);
deba@989
   264
	  }
deba@989
   265
	  {
deba@989
   266
	    graph.first(edge);
deba@989
   267
	    graph.next(edge);
deba@989
   268
	  }
deba@989
   269
	  {
deba@989
   270
	    graph.firstIn(edge, node);
deba@989
   271
	    graph.nextIn(edge);
deba@989
   272
	  }
deba@989
   273
	  {
deba@989
   274
	    graph.firstOut(edge, node);
deba@989
   275
	    graph.nextOut(edge);
deba@989
   276
	  }
deba@989
   277
	}
klao@959
   278
deba@989
   279
	const _Graph& graph;
deba@989
   280
      };
klao@959
   281
    };
klao@959
   282
klao@959
   283
    /// An empty idable base graph class.
klao@959
   284
  
klao@959
   285
    /// This class provides beside the core graph features
klao@959
   286
    /// core id functions for the graph structure.
klao@959
   287
    /// The most of the base graphs should be conform to this concept.
klao@959
   288
    /// The id's are unique and immutable.
klao@959
   289
    class IDableGraphComponent : virtual public BaseGraphComponent {
klao@959
   290
    public:
klao@959
   291
klao@959
   292
      typedef BaseGraphComponent::Node Node;
klao@959
   293
      typedef BaseGraphComponent::Edge Edge;
klao@959
   294
klao@959
   295
      /// Gives back an unique integer id for the Node. 
klao@959
   296
klao@959
   297
      /// Gives back an unique integer id for the Node. 
klao@959
   298
      ///
klao@959
   299
      int id(const Node&) const { return -1;}
klao@959
   300
deba@1106
   301
      /// \brief Gives back the node by the unique id.
deba@1106
   302
      ///
deba@1106
   303
      /// Gives back the node by the unique id.
deba@1106
   304
      /// If the graph does not contain node with the given id
deba@1106
   305
      /// then the result of the function is undetermined. 
alpar@1367
   306
      Node fromId(int , Node) const { return INVALID;}
klao@959
   307
deba@1106
   308
      /// \brief Gives back an unique integer id for the Edge. 
deba@1106
   309
      ///
klao@959
   310
      /// Gives back an unique integer id for the Edge. 
klao@959
   311
      ///
klao@959
   312
      int id(const Edge&) const { return -1;}
klao@959
   313
deba@1106
   314
      /// \brief Gives back the edge by the unique id.
deba@1106
   315
      ///
deba@1106
   316
      /// Gives back the edge by the unique id.
deba@1106
   317
      /// If the graph does not contain edge with the given id
deba@1106
   318
      /// then the result of the function is undetermined. 
alpar@1367
   319
      Edge fromId(int, Edge) const { return INVALID;}
deba@1106
   320
deba@989
   321
      template <typename _Graph>
deba@989
   322
      struct Constraints {
klao@959
   323
deba@989
   324
	void constraints() {
deba@989
   325
	  checkConcept< BaseGraphComponent, _Graph >();
deba@989
   326
	  typename _Graph::Node node;
deba@989
   327
	  int nid = graph.id(node);
deba@989
   328
	  nid = graph.id(node);
deba@1106
   329
	  node = graph.fromId(nid, Node());
deba@989
   330
	  typename _Graph::Edge edge;
deba@989
   331
	  int eid = graph.id(edge);
deba@989
   332
	  eid = graph.id(edge);
deba@1106
   333
	  edge = graph.fromId(eid, Edge());
deba@989
   334
	}
klao@959
   335
deba@989
   336
	const _Graph& graph;
deba@989
   337
      };
klao@959
   338
    };
klao@959
   339
klao@959
   340
klao@959
   341
    /// An empty max-idable base graph class.
klao@959
   342
  
klao@959
   343
    /// This class provides beside the core graph features
klao@959
   344
    /// core max id functions for the graph structure.
klao@959
   345
    /// The most of the base graphs should be conform to this concept.
klao@959
   346
    /// The id's are unique and immutable.
klao@959
   347
    class MaxIDableGraphComponent : virtual public BaseGraphComponent {
klao@959
   348
    public:
klao@959
   349
klao@959
   350
      /// Gives back an integer greater or equal to the maximum Node id. 
klao@959
   351
klao@959
   352
      /// Gives back an integer greater or equal to the maximum Node id. 
klao@959
   353
      ///
deba@980
   354
      int maxId(Node = INVALID) const { return -1;}
klao@959
   355
klao@959
   356
      /// Gives back an integer greater or equal to the maximum Edge id. 
klao@959
   357
klao@959
   358
      /// Gives back an integer greater or equal to the maximum Edge id. 
klao@959
   359
      ///
deba@980
   360
      int maxId(Edge = INVALID) const { return -1;}
klao@959
   361
deba@989
   362
      template <typename _Graph>
deba@989
   363
      struct Constraints {
klao@959
   364
deba@989
   365
	void constraints() {
deba@989
   366
	  checkConcept<BaseGraphComponent, _Graph>();
deba@989
   367
	  int nid = graph.maxId(typename _Graph::Node());
deba@989
   368
	  ignore_unused_variable_warning(nid);
deba@989
   369
	  int eid = graph.maxId(typename _Graph::Edge());
deba@989
   370
	  ignore_unused_variable_warning(eid);
deba@989
   371
	}
deba@989
   372
      
deba@989
   373
	const _Graph& graph;
deba@989
   374
      };
klao@959
   375
    };
klao@959
   376
klao@959
   377
    /// An empty extendable base graph class.
klao@959
   378
  
klao@959
   379
    /// This class provides beside the core graph features
klao@959
   380
    /// core graph extend interface for the graph structure.
klao@959
   381
    /// The most of the base graphs should be conform to this concept.
klao@959
   382
    class BaseExtendableGraphComponent : virtual public BaseGraphComponent {
klao@959
   383
    public:
klao@959
   384
klao@959
   385
      typedef BaseGraphComponent::Node Node;
klao@959
   386
      typedef BaseGraphComponent::Edge Edge;
klao@959
   387
klao@959
   388
      /// Adds a new Node to the graph.
klao@959
   389
klao@959
   390
      /// Adds a new Node to the graph.
klao@959
   391
      ///
klao@959
   392
      Node addNode() {
klao@959
   393
	return INVALID;
klao@959
   394
      }
klao@959
   395
    
klao@959
   396
      /// Adds a new Edge connects the two Nodes to the graph.
klao@959
   397
klao@959
   398
      /// Adds a new Edge connects the two Nodes to the graph.
klao@959
   399
      ///
alpar@1367
   400
      Edge addEdge(const Node&, const Node&) {
klao@959
   401
	return INVALID;
klao@959
   402
      }
klao@959
   403
deba@989
   404
      template <typename _Graph>
deba@989
   405
      struct Constraints {
deba@989
   406
	void constraints() {
deba@989
   407
	  checkConcept<BaseGraphComponent, _Graph >();
deba@989
   408
	  typename _Graph::Node node_a, node_b;
deba@989
   409
	  node_a = graph.addNode();
alpar@1494
   410
	  node_b = graph.addNode();
deba@989
   411
	  typename _Graph::Edge edge;
deba@989
   412
	  edge = graph.addEdge(node_a, node_b);
deba@989
   413
	}
klao@959
   414
deba@989
   415
	_Graph& graph;
deba@989
   416
      };
klao@959
   417
    };
klao@959
   418
klao@959
   419
    /// An empty erasable base graph class.
klao@959
   420
  
klao@959
   421
    /// This class provides beside the core graph features
klao@959
   422
    /// core erase functions for the graph structure.
klao@959
   423
    /// The most of the base graphs should be conform to this concept.
klao@959
   424
    class BaseErasableGraphComponent : virtual public BaseGraphComponent {
klao@959
   425
    public:
klao@959
   426
klao@959
   427
      typedef BaseGraphComponent::Node Node;
klao@959
   428
      typedef BaseGraphComponent::Edge Edge;
klao@959
   429
klao@959
   430
      /// Erase a Node from the graph.
klao@959
   431
      
klao@959
   432
      /// Erase a Node from the graph. This function should not
klao@959
   433
      /// erase edges connecting to the Node.
klao@959
   434
      void erase(const Node&) {}    
klao@959
   435
klao@959
   436
      /// Erase an Edge from the graph.
klao@959
   437
klao@959
   438
      /// Erase an Edge from the graph.
klao@959
   439
      ///
klao@959
   440
      void erase(const Edge&) {}
klao@959
   441
deba@989
   442
      template <typename _Graph>
deba@989
   443
      struct Constraints {
deba@989
   444
	void constraints() {
deba@989
   445
	  checkConcept<BaseGraphComponent, _Graph>();
deba@989
   446
	  typename _Graph::Node node;
deba@989
   447
	  graph.erase(node);
deba@989
   448
	  typename _Graph::Edge edge;
deba@989
   449
	  graph.erase(edge);
deba@989
   450
	}
klao@959
   451
deba@989
   452
	_Graph& graph;
deba@989
   453
      };
klao@959
   454
    };
klao@959
   455
klao@959
   456
    /// An empty clearable base graph class.
klao@959
   457
  
klao@959
   458
    /// This class provides beside the core graph features
klao@959
   459
    /// core clear functions for the graph structure.
klao@959
   460
    /// The most of the base graphs should be conform to this concept.
klao@1022
   461
    class ClearableGraphComponent : virtual public BaseGraphComponent {
klao@959
   462
    public:
klao@959
   463
klao@959
   464
      /// Erase all the Nodes and Edges from the graph.
klao@959
   465
klao@959
   466
      /// Erase all the Nodes and Edges from the graph.
klao@959
   467
      ///
klao@959
   468
      void clear() {}    
deba@989
   469
deba@989
   470
      template <typename _Graph>
deba@989
   471
      struct Constraints {
deba@989
   472
	void constraints() {
klao@1022
   473
	  checkConcept<BaseGraphComponent, _Graph>();
deba@989
   474
	  graph.clear();
deba@989
   475
	}
deba@989
   476
klao@1022
   477
	_Graph graph;
deba@989
   478
      };
klao@959
   479
    };
klao@959
   480
klao@959
   481
deba@989
   482
    /// Skeleton class for graph NodeIt and EdgeIt
deba@989
   483
deba@989
   484
    /// Skeleton class for graph NodeIt and EdgeIt.
klao@959
   485
    ///
deba@989
   486
    template <typename _Graph, typename _Item>
deba@989
   487
    class GraphIterator : public _Item {
deba@989
   488
    public:
deba@989
   489
      /// \todo Don't we need the Item type as typedef?
klao@959
   490
deba@989
   491
      /// Default constructor.
deba@989
   492
      
deba@989
   493
      /// @warning The default constructor sets the iterator
deba@989
   494
      /// to an undefined value.
deba@989
   495
      GraphIterator() {}
deba@989
   496
      /// Copy constructor.
deba@989
   497
      
deba@989
   498
      /// Copy constructor.
deba@989
   499
      ///
deba@989
   500
      GraphIterator(GraphIterator const&) {}
deba@989
   501
      /// Sets the iterator to the first item.
deba@989
   502
      
deba@989
   503
      /// Sets the iterator to the first item of \c the graph.
deba@989
   504
      ///
deba@989
   505
      explicit GraphIterator(const _Graph&) {}
deba@989
   506
      /// Invalid constructor \& conversion.
deba@989
   507
deba@989
   508
      /// This constructor initializes the item to be invalid.
deba@989
   509
      /// \sa Invalid for more details.
deba@989
   510
      GraphIterator(Invalid) {}
deba@989
   511
      /// Assign operator for items.
deba@989
   512
deba@989
   513
      /// The items are assignable. 
deba@989
   514
      ///
deba@989
   515
      GraphIterator& operator=(GraphIterator const&) { return *this; }      
deba@989
   516
      /// Next item.
deba@989
   517
deba@989
   518
      /// Assign the iterator to the next item.
deba@989
   519
      ///
deba@989
   520
      GraphIterator& operator++() { return *this; }
deba@989
   521
      //	Node operator*() const { return INVALID; }
deba@989
   522
      /// Equality operator
deba@989
   523
deba@989
   524
      /// Two iterators are equal if and only if they point to the
deba@989
   525
      /// same object or both are invalid.
deba@989
   526
      bool operator==(const GraphIterator&) const { return true;}
deba@989
   527
      /// Inequality operator
deba@989
   528
	
deba@989
   529
      /// \sa operator==(Node n)
deba@989
   530
      ///
deba@989
   531
      bool operator!=(const GraphIterator&) const { return true;}
deba@989
   532
      
deba@989
   533
      template<typename _GraphIterator>
deba@989
   534
      struct Constraints {
deba@989
   535
	void constraints() {
deba@989
   536
	  //	  checkConcept< Item, _GraphIterator >();
deba@989
   537
	  _GraphIterator it1(g);
deba@989
   538
	
deba@989
   539
	  /// \todo Do we need NodeIt(Node) kind of constructor?
deba@989
   540
	  //	_GraphIterator it2(bj);
deba@989
   541
	  _GraphIterator it2;
deba@989
   542
deba@989
   543
	  it2 = ++it1;
deba@989
   544
	  ++it2 = it1;
deba@989
   545
	  ++(++it1);
deba@989
   546
	  /// \bug This should be: is_base_and_derived<BaseItem, _GraphIterator>
deba@989
   547
	  _Item bi = it1;
deba@989
   548
	  bi = it2;
deba@989
   549
	}
deba@989
   550
	_Graph& g;
deba@989
   551
      };
klao@959
   552
    };
klao@959
   553
deba@989
   554
    /// Skeleton class for graph InEdgeIt and OutEdgeIt
klao@959
   555
deba@989
   556
    /// \note Because InEdgeIt and OutEdgeIt may not inherit from the same
deba@989
   557
    /// base class, the _selector is a additional template parameter. For 
deba@989
   558
    /// InEdgeIt you should instantiate it with character 'i' and for 
deba@989
   559
    /// OutEdgeIt with 'o'.
klao@1021
   560
    /// \todo Is this a good name for this concept?
klao@1021
   561
    template <typename Graph,
klao@1021
   562
	      typename Edge = typename Graph::Edge,
klao@1021
   563
	      char _selector = '0'>
klao@1021
   564
    class GraphIncIterator : public Edge {
deba@989
   565
    public:
deba@989
   566
      /// Default constructor.
deba@989
   567
      
deba@989
   568
      /// @warning The default constructor sets the iterator
deba@989
   569
      /// to an undefined value.
klao@1021
   570
      GraphIncIterator() {}
deba@989
   571
      /// Copy constructor.
deba@989
   572
      
deba@989
   573
      /// Copy constructor.
deba@989
   574
      ///
alpar@1375
   575
      GraphIncIterator(GraphIncIterator const& gi) :Edge(gi) {}
deba@1134
   576
      /// Sets the iterator to the first edge incoming into or outgoing 
deba@1134
   577
      /// from the node.
deba@989
   578
      
deba@1134
   579
      /// Sets the iterator to the first edge incoming into or outgoing 
deba@1134
   580
      /// from the node.
deba@989
   581
      ///
klao@1021
   582
      explicit GraphIncIterator(const Graph&, const typename Graph::Node&) {}
deba@989
   583
      /// Invalid constructor \& conversion.
deba@989
   584
deba@989
   585
      /// This constructor initializes the item to be invalid.
deba@989
   586
      /// \sa Invalid for more details.
klao@1021
   587
      GraphIncIterator(Invalid) {}
deba@989
   588
      /// Assign operator for nodes.
deba@989
   589
deba@989
   590
      /// The nodes are assignable. 
deba@989
   591
      ///
klao@1021
   592
      GraphIncIterator& operator=(GraphIncIterator const&) { return *this; }      
deba@989
   593
      /// Next edge.
deba@989
   594
deba@989
   595
      /// Assign the iterator to the next node.
deba@989
   596
      ///
klao@1021
   597
      GraphIncIterator& operator++() { return *this; }
klao@1021
   598
deba@989
   599
      //	Node operator*() const { return INVALID; }
klao@1021
   600
deba@989
   601
      /// Equality operator
deba@989
   602
deba@989
   603
      /// Two iterators are equal if and only if they point to the
deba@989
   604
      /// same object or both are invalid.
klao@1021
   605
      bool operator==(const GraphIncIterator&) const { return true;}
klao@1021
   606
deba@989
   607
      /// Inequality operator
deba@989
   608
	
deba@989
   609
      /// \sa operator==(Node n)
deba@989
   610
      ///
klao@1021
   611
      bool operator!=(const GraphIncIterator&) const { return true;}
deba@989
   612
klao@1021
   613
      template <typename _GraphIncIterator>
deba@989
   614
      struct Constraints {
klao@1021
   615
	typedef typename Graph::Node Node;
deba@989
   616
	void constraints() {
klao@1021
   617
	  checkConcept<GraphItem<'e'>, _GraphIncIterator>();
klao@1021
   618
	  _GraphIncIterator it1(graph, node);
deba@989
   619
	  /// \todo Do we need OutEdgeIt(Edge) kind of constructor?
klao@1021
   620
	  //	_GraphIncIterator it2(edge);
klao@1021
   621
	  _GraphIncIterator it2;
deba@989
   622
deba@989
   623
	  it2 = ++it1;
deba@989
   624
	  ++it2 = it1;
deba@989
   625
	  ++(++it1);
deba@989
   626
	  Edge e = it1;
deba@989
   627
	  e = it2;
klao@1158
   628
klao@1158
   629
	  const_constraits();
deba@989
   630
	}
deba@989
   631
klao@1158
   632
	void const_constraits() {
klao@1158
   633
	  Node n = graph.baseNode(it);
klao@1158
   634
	  n = graph.runningNode(it);
klao@1158
   635
	}
klao@1158
   636
klao@1158
   637
	Edge edge;
klao@1158
   638
	Node node;
klao@1158
   639
	Graph graph;
klao@1158
   640
	_GraphIncIterator it;
deba@989
   641
      };
deba@989
   642
    };
klao@1021
   643
klao@1021
   644
deba@989
   645
    /// An empty iterable base graph class.
deba@989
   646
  
deba@989
   647
    /// This class provides beside the core graph features
deba@989
   648
    /// iterator based iterable interface for the graph structure.
deba@989
   649
    /// This concept is part of the StaticGraphConcept.
deba@989
   650
    class IterableGraphComponent : virtual public BaseGraphComponent {
klao@959
   651
klao@959
   652
    public:
klao@959
   653
    
klao@959
   654
      typedef IterableGraphComponent Graph;
klao@959
   655
klao@959
   656
      typedef BaseGraphComponent::Node Node;
klao@959
   657
      typedef BaseGraphComponent::Edge Edge;
klao@959
   658
deba@989
   659
      /// This iterator goes through each node.
klao@959
   660
deba@989
   661
      /// This iterator goes through each node.
deba@989
   662
      ///
deba@989
   663
      typedef GraphIterator<Graph, Node> NodeIt;
deba@989
   664
      /// This iterator goes through each node.
klao@959
   665
deba@989
   666
      /// This iterator goes through each node.
deba@989
   667
      ///
deba@989
   668
      typedef GraphIterator<Graph, Edge> EdgeIt;
deba@989
   669
      /// This iterator goes trough the incoming edges of a node.
klao@959
   670
deba@989
   671
      /// This iterator goes trough the \e inccoming edges of a certain node
deba@989
   672
      /// of a graph.
klao@1021
   673
      typedef GraphIncIterator<Graph, Edge, 'i'> InEdgeIt;
deba@989
   674
      /// This iterator goes trough the outgoing edges of a node.
klao@959
   675
deba@989
   676
      /// This iterator goes trough the \e outgoing edges of a certain node
deba@989
   677
      /// of a graph.
klao@1021
   678
      typedef GraphIncIterator<Graph, Edge, 'o'> OutEdgeIt;
deba@1563
   679
deba@1563
   680
      /// \brief The base node of the iterator.
deba@1563
   681
      ///
deba@1563
   682
      /// Gives back the base node of the iterator.
deba@1627
   683
      /// It is always the target of the pointed edge.
deba@1563
   684
      Node baseNode(const InEdgeIt&) const { return INVALID; }
deba@1563
   685
deba@1563
   686
      /// \brief The running node of the iterator.
deba@1563
   687
      ///
deba@1563
   688
      /// Gives back the running node of the iterator.
deba@1627
   689
      /// It is always the source of the pointed edge.
deba@1563
   690
      Node runningNode(const InEdgeIt&) const { return INVALID; }
deba@1563
   691
deba@1563
   692
      /// \brief The base node of the iterator.
deba@1563
   693
      ///
deba@1563
   694
      /// Gives back the base node of the iterator.
deba@1627
   695
      /// It is always the source of the pointed edge.
deba@1563
   696
      Node baseNode(const OutEdgeIt&) const { return INVALID; }
deba@1563
   697
deba@1563
   698
      /// \brief The running node of the iterator.
deba@1563
   699
      ///
deba@1563
   700
      /// Gives back the running node of the iterator.
deba@1627
   701
      /// It is always the target of the pointed edge.
deba@1563
   702
      Node runningNode(const OutEdgeIt&) const { return INVALID; }
deba@1563
   703
deba@1627
   704
      /// \brief The opposite node on the given edge.
deba@1627
   705
      ///
deba@1627
   706
      /// Gives back the opposite on the given edge.
deba@1627
   707
      /// \todo It should not be here.
deba@1627
   708
      Node oppositeNode(const Node&, const Edge&) const { return INVALID; }
deba@1627
   709
deba@989
   710
    
deba@1563
   711
      template <typename _Graph> 
deba@1563
   712
      struct Constraints {
deba@1563
   713
	void constraints() {
deba@1563
   714
	  checkConcept< BaseGraphComponent, _Graph>();
deba@1563
   715
	  
deba@1563
   716
	  checkConcept<GraphIterator<_Graph, typename _Graph::Edge>,
deba@1563
   717
	    typename _Graph::EdgeIt >();
deba@1563
   718
	  checkConcept<GraphIterator<_Graph, typename _Graph::Node>,
deba@1563
   719
	    typename _Graph::NodeIt >();
deba@1563
   720
	  checkConcept<GraphIncIterator<_Graph>, typename _Graph::InEdgeIt>();
deba@1563
   721
	  checkConcept<GraphIncIterator<_Graph>, typename _Graph::OutEdgeIt>();
deba@1627
   722
alpar@1644
   723
	  typename _Graph::Node n(INVALID);
alpar@1644
   724
	  typename _Graph::Edge e(INVALID);
deba@1627
   725
	  n = graph.oppositeNode(n, e);
deba@1563
   726
	}
deba@1627
   727
	
deba@1627
   728
	const _Graph& graph;
deba@1627
   729
	
deba@1563
   730
      };
deba@989
   731
    };
klao@959
   732
deba@1134
   733
    /// An empty alteration notifier base graph class.
deba@1134
   734
  
deba@1134
   735
    /// This class provides beside the core graph features
deba@1134
   736
    /// alteration notifier interface for the graph structure.
deba@1134
   737
    /// This is an observer-notifier pattern. More Obsevers can
deba@1134
   738
    /// be registered into the notifier and whenever an alteration
deba@1134
   739
    /// occured in the graph all the observers will notified about it.
deba@1999
   740
    class AlterableGraphComponent : virtual public BaseIterableGraphComponent {
deba@1134
   741
    public:
deba@1134
   742
deba@1134
   743
      /// The edge observer registry.
deba@1999
   744
      typedef AlterationNotifier<AlterableGraphComponent, Edge> 
deba@1999
   745
      EdgeNotifier;
deba@1134
   746
      /// The node observer registry.
deba@1999
   747
      typedef AlterationNotifier<AlterableGraphComponent, Node> 
deba@1999
   748
      NodeNotifier;
deba@1134
   749
      
deba@1134
   750
      /// \brief Gives back the edge alteration notifier.
deba@1134
   751
      ///
deba@1134
   752
      /// Gives back the edge alteration notifier.
deba@1134
   753
      EdgeNotifier getNotifier(Edge) const {
deba@1134
   754
	return EdgeNotifier();
deba@1134
   755
      }
deba@1134
   756
      
deba@1134
   757
      /// \brief Gives back the node alteration notifier.
deba@1134
   758
      ///
deba@1134
   759
      /// Gives back the node alteration notifier.
deba@1134
   760
      NodeNotifier getNotifier(Node) const {
deba@1134
   761
	return NodeNotifier();
deba@1134
   762
      }
deba@1134
   763
      
deba@1134
   764
    };
deba@1134
   765
klao@959
   766
klao@1030
   767
    /// Class describing the concept of graph maps
klao@1030
   768
klao@1030
   769
    /// This class describes the common interface of the graph maps
alpar@1631
   770
    /// (NodeMap, EdgeMap), that is \ref maps-page "maps" which can be used to
klao@1030
   771
    /// associate data to graph descriptors (nodes or edges).
deba@989
   772
    template <typename Graph, typename Item, typename _Value>
deba@989
   773
    class GraphMap : public ReadWriteMap<Item, _Value> {
deba@989
   774
    protected:      
deba@989
   775
      GraphMap() {}
deba@989
   776
    public:
deba@1134
   777
      /// \brief Construct a new map.
deba@1134
   778
      ///
deba@1134
   779
      /// Construct a new map for the graph.
deba@989
   780
      explicit GraphMap(const Graph&) {}
deba@1134
   781
      /// \brief Construct a new map with default value.
deba@1134
   782
      ///
deba@1134
   783
      /// Construct a new map for the graph and initalise the values.
deba@989
   784
      GraphMap(const Graph&, const _Value&) {}
deba@1134
   785
      /// \brief Copy constructor.
deba@1134
   786
      ///
deba@1134
   787
      /// Copy Constructor.
alpar@1367
   788
      GraphMap(const GraphMap& gm) :ReadWriteMap<Item, _Value>(gm) {}
deba@989
   789
      
deba@1134
   790
      /// \brief Assign operator.
deba@1134
   791
      ///
deba@1134
   792
      /// Assign operator.
deba@989
   793
      GraphMap& operator=(const GraphMap&) { return *this;}
klao@959
   794
deba@989
   795
      template<typename _Map>
deba@989
   796
      struct Constraints {
deba@989
   797
	void constraints() {
deba@989
   798
	  checkConcept<ReadWriteMap<Item, _Value>, _Map >();
deba@989
   799
	  // Construction with a graph parameter
deba@989
   800
	  _Map a(g);
deba@989
   801
	  // Constructor with a graph and a default value parameter
deba@989
   802
	  _Map a2(g,t);
deba@989
   803
	  // Copy constructor. Do we need it?
deba@989
   804
	  _Map b=c;
klao@959
   805
deba@989
   806
	  ignore_unused_variable_warning(a2);
deba@989
   807
	}
klao@959
   808
deba@989
   809
	const _Map &c;
deba@989
   810
	const Graph &g;
deba@989
   811
	const typename GraphMap::Value &t;
klao@959
   812
      };
klao@959
   813
klao@959
   814
    };
klao@961
   815
deba@989
   816
    /// An empty mappable base graph class.
klao@959
   817
  
deba@989
   818
    /// This class provides beside the core graph features
deba@989
   819
    /// map interface for the graph structure.
deba@989
   820
    /// This concept is part of the StaticGraphConcept.
klao@959
   821
    class MappableGraphComponent : virtual public BaseGraphComponent {
klao@959
   822
    public:
klao@959
   823
klao@959
   824
      typedef MappableGraphComponent Graph;
klao@959
   825
klao@959
   826
      typedef BaseGraphComponent::Node Node;
klao@959
   827
      typedef BaseGraphComponent::Edge Edge;
klao@959
   828
deba@989
   829
      /// ReadWrite map of the nodes.
deba@989
   830
    
deba@989
   831
      /// ReadWrite map of the nodes.
deba@989
   832
      ///
alpar@987
   833
      template <typename _Value>
deba@989
   834
      class NodeMap : public GraphMap<Graph, Node, _Value> {
deba@989
   835
      private:
deba@989
   836
	NodeMap();
klao@959
   837
      public:
deba@1134
   838
	/// \brief Construct a new map.
deba@1134
   839
	///
deba@1134
   840
	/// Construct a new map for the graph.
deba@1134
   841
	/// \todo call the right parent class constructor
deba@989
   842
	explicit NodeMap(const Graph&) {}
deba@1134
   843
	/// \brief Construct a new map with default value.
deba@1134
   844
	///
deba@1134
   845
	/// Construct a new map for the graph and initalise the values.
alpar@987
   846
	NodeMap(const Graph&, const _Value&) {}
deba@1134
   847
	/// \brief Copy constructor.
deba@1134
   848
	///
deba@1134
   849
	/// Copy Constructor.
alpar@1367
   850
	NodeMap(const NodeMap& nm) : GraphMap<Graph, Node, _Value>(nm) {}
klao@959
   851
deba@1134
   852
	/// \brief Assign operator.
deba@1134
   853
	///
deba@1134
   854
	/// Assign operator.
klao@959
   855
	NodeMap& operator=(const NodeMap&) { return *this;}
deba@989
   856
klao@959
   857
      };
klao@959
   858
deba@989
   859
      /// ReadWrite map of the edges.
deba@989
   860
    
deba@989
   861
      /// ReadWrite map of the edges.
deba@989
   862
      ///
alpar@987
   863
      template <typename _Value>
deba@989
   864
      class EdgeMap : public GraphMap<Graph, Edge, _Value> {
deba@989
   865
      private:
deba@989
   866
	EdgeMap();
klao@959
   867
      public:
deba@1134
   868
	/// \brief Construct a new map.
deba@1134
   869
	///
deba@1134
   870
	/// Construct a new map for the graph.
deba@1134
   871
	/// \todo call the right parent class constructor
deba@989
   872
	explicit EdgeMap(const Graph&) {}
deba@1134
   873
	/// \brief Construct a new map with default value.
deba@1134
   874
	///
deba@1134
   875
	/// Construct a new map for the graph and initalise the values.
alpar@987
   876
	EdgeMap(const Graph&, const _Value&) {}
deba@1134
   877
	/// \brief Copy constructor.
deba@1134
   878
	///
deba@1134
   879
	/// Copy Constructor.
alpar@1367
   880
	EdgeMap(const EdgeMap& em) :GraphMap<Graph, Edge, _Value>(em) {}
klao@959
   881
deba@1134
   882
	/// \brief Assign operator.
deba@1134
   883
	///
deba@1134
   884
	/// Assign operator.
klao@959
   885
	EdgeMap& operator=(const EdgeMap&) { return *this;}
deba@989
   886
klao@959
   887
      };
klao@959
   888
deba@989
   889
      template <typename _Graph>
deba@989
   890
      struct Constraints {
klao@959
   891
deba@989
   892
	struct Type {
deba@989
   893
	  int value;
deba@989
   894
	  Type() : value(0) {}
deba@989
   895
	  Type(int _v) : value(_v) {}
deba@989
   896
	};
klao@959
   897
deba@989
   898
	void constraints() {
deba@989
   899
	  checkConcept<BaseGraphComponent, _Graph>();
deba@989
   900
	  { // int map test
deba@989
   901
	    typedef typename _Graph::template NodeMap<int> IntNodeMap;
deba@1134
   902
	    checkConcept<GraphMap<_Graph, typename _Graph::Node, int>, 
deba@1134
   903
	      IntNodeMap >();
deba@989
   904
	  } { // bool map test
deba@989
   905
	    typedef typename _Graph::template NodeMap<bool> BoolNodeMap;
deba@1134
   906
	    checkConcept<GraphMap<_Graph, typename _Graph::Node, bool>,
deba@1134
   907
	      BoolNodeMap >();
deba@989
   908
	  } { // Type map test
deba@989
   909
	    typedef typename _Graph::template NodeMap<Type> TypeNodeMap;
deba@1134
   910
	    checkConcept<GraphMap<_Graph, typename _Graph::Node, Type>,
deba@1134
   911
	      TypeNodeMap >();
deba@989
   912
	  } 
deba@989
   913
deba@989
   914
	  { // int map test
deba@989
   915
	    typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
deba@1134
   916
	    checkConcept<GraphMap<_Graph, typename _Graph::Edge, int>,
deba@1134
   917
	      IntEdgeMap >();
deba@989
   918
	  } { // bool map test
deba@989
   919
	    typedef typename _Graph::template EdgeMap<bool> BoolEdgeMap;
deba@1134
   920
	    checkConcept<GraphMap<_Graph, typename _Graph::Edge, bool>,
deba@1134
   921
	      BoolEdgeMap >();
deba@989
   922
	  } { // Type map test
deba@989
   923
	    typedef typename _Graph::template EdgeMap<Type> TypeEdgeMap;
deba@1134
   924
	    checkConcept<GraphMap<_Graph, typename _Graph::Edge, Type>, 
deba@1134
   925
	      TypeEdgeMap >();
deba@989
   926
	  } 
deba@989
   927
	}
deba@989
   928
deba@989
   929
	_Graph& graph;
klao@959
   930
      };
klao@959
   931
    };
klao@959
   932
deba@1134
   933
    /// \brief An empty extendable extended graph class.
deba@1134
   934
    ///
deba@1134
   935
    /// This class provides beside the core graph features
deba@1134
   936
    /// item addition interface for the graph structure.
deba@1134
   937
    /// The difference between this class and the 
deba@1134
   938
    /// \c BaseExtendableGraphComponent is that it should
deba@1134
   939
    /// notify the item alteration observers.
klao@959
   940
    class ExtendableGraphComponent : virtual public BaseGraphComponent {
klao@959
   941
    public:
klao@959
   942
klao@959
   943
      typedef ExtendableGraphComponent Graph;
klao@959
   944
klao@959
   945
      typedef BaseGraphComponent::Node Node;
klao@959
   946
      typedef BaseGraphComponent::Edge Edge;
klao@959
   947
deba@1134
   948
      /// \brief Add a node to the graph.
deba@1134
   949
      ///
deba@1134
   950
      /// Add a node to the graph and notify the observers.
klao@959
   951
      Node addNode() {
klao@959
   952
	return INVALID;
klao@959
   953
      }
klao@959
   954
    
deba@1134
   955
      /// \brief Add an edge to the graph.
deba@1134
   956
      ///
deba@1134
   957
      /// Add an edge to the graph and notify the observers.
alpar@1367
   958
      Edge addEdge(const Node&, const Node&) {
klao@959
   959
	return INVALID;
klao@959
   960
      }
klao@959
   961
deba@989
   962
      template <typename _Graph>
deba@989
   963
      struct Constraints {
deba@989
   964
	void constraints() {
deba@989
   965
	  checkConcept<BaseGraphComponent, _Graph >();
deba@989
   966
	  typename _Graph::Node node_a, node_b;
deba@989
   967
	  node_a = graph.addNode();
alpar@1494
   968
	  node_b = graph.addNode();
deba@989
   969
	  typename _Graph::Edge edge;
deba@989
   970
	  edge = graph.addEdge(node_a, node_b);      
deba@989
   971
	}
deba@989
   972
	_Graph& graph;
deba@989
   973
      };
klao@959
   974
    };
deba@1134
   975
deba@1134
   976
    /// \brief An empty erasable extended graph class.
deba@1134
   977
    ///
deba@1134
   978
    /// This class provides beside the core graph features
deba@1134
   979
    /// item erase interface for the graph structure.
deba@1134
   980
    /// The difference between this class and the 
deba@1134
   981
    /// \c BaseErasableGraphComponent is that it should
deba@1134
   982
    /// notify the item alteration observers.
klao@959
   983
    class ErasableGraphComponent : virtual public BaseGraphComponent {
klao@959
   984
    public:
klao@959
   985
klao@959
   986
      typedef ErasableGraphComponent Graph;
klao@959
   987
klao@959
   988
      typedef BaseGraphComponent::Node Node;
klao@959
   989
      typedef BaseGraphComponent::Edge Edge;
klao@959
   990
deba@1134
   991
      /// \brief Erase the Node and notify the node alteration observers.
deba@1134
   992
      ///
deba@1134
   993
      ///  Erase the Node and notify the node alteration observers.
klao@959
   994
      void erase(const Node&) {}    
deba@1134
   995
deba@1134
   996
      /// \brief Erase the Edge and notify the edge alteration observers.
deba@1134
   997
      ///
deba@1134
   998
      ///  Erase the Edge and notify the edge alteration observers.
klao@959
   999
      void erase(const Edge&) {}
klao@959
  1000
deba@989
  1001
      template <typename _Graph>
deba@989
  1002
      struct Constraints {
deba@989
  1003
	void constraints() {
deba@989
  1004
	  checkConcept<BaseGraphComponent, _Graph >();
deba@989
  1005
	  typename _Graph::Node node;
deba@989
  1006
	  graph.erase(node);
deba@989
  1007
	  typename _Graph::Edge edge;
deba@989
  1008
	  graph.erase(edge);      
deba@989
  1009
	}
klao@959
  1010
deba@989
  1011
	_Graph& graph;
deba@989
  1012
      };
klao@959
  1013
    };
klao@959
  1014
klao@959
  1015
  }
klao@959
  1016
klao@959
  1017
}
klao@959
  1018
klao@959
  1019
#endif