[Lemon-commits] [lemon_svn] deba: r2230 - in hugo/trunk/lemon: . bits
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:51:07 CET 2006
Author: deba
Date: Wed Oct 5 15:15:47 2005
New Revision: 2230
Added:
hugo/trunk/lemon/bits/static_map.h
Modified:
hugo/trunk/lemon/bits/array_map.h
hugo/trunk/lemon/bits/default_map.h
hugo/trunk/lemon/bits/vector_map.h
hugo/trunk/lemon/full_graph.h
hugo/trunk/lemon/grid_graph.h
hugo/trunk/lemon/hypercube_graph.h
Log:
Proper sized map type
Modified: hugo/trunk/lemon/bits/array_map.h
==============================================================================
--- hugo/trunk/lemon/bits/array_map.h (original)
+++ hugo/trunk/lemon/bits/array_map.h Wed Oct 5 15:15:47 2005
@@ -48,6 +48,7 @@
typedef _Item Item;
public:
+ typedef True AdaptibleTag;
/// The graph type of the maps.
typedef _Graph Graph;
@@ -69,6 +70,8 @@
public:
+ /// \brief Graph and Registry initialized map constructor.
+ ///
/// Graph and Registry initialized map constructor.
ArrayMap(const Graph& _g) : graph(&_g) {
Item it;
@@ -80,10 +83,9 @@
}
}
- /// Constructor to use default value to initialize the map.
-
- /// It constrates a map and initialize all of the the map.
-
+ /// \brief Constructor to use default value to initialize the map.
+ ///
+ /// It constructs a map and initialize all of the the map.
ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) {
Item it;
attach(_g.getNotifier(_Item()));
@@ -94,8 +96,9 @@
}
}
- /// Constructor to copy a map of the same map type.
-
+ /// \brief Constructor to copy a map of the same map type.
+ ///
+ /// Constructor to copy a map of the same map type.
ArrayMap(const ArrayMap& copy) : Parent(), graph(copy.graph) {
if (copy.attached()) {
attach(*copy.getRegistry());
@@ -137,35 +140,37 @@
public:
- ///The subscript operator. The map can be subscripted by the
- ///actual keys of the graph.
-
+ /// \brief The subscript operator.
+ ///
+ /// The subscript operator. The map can be subscripted by the
+ /// actual keys of the graph.
Value& operator[](const Key& key) {
int id = graph->id(key);
return values[id];
}
-
- ///The const subscript operator. The map can be subscripted by the
- ///actual keys of the graph.
-
+ /// \brief The const subscript operator.
+ ///
+ /// The const subscript operator. The map can be subscripted by the
+ /// actual keys of the graph.
const Value& operator[](const Key& key) const {
int id = graph->id(key);
return values[id];
}
-
+
+ /// \brief Setter function of the map.
+ ///
/// Setter function of the map. Equivalent with map[key] = val.
/// This is a compatibility feature with the not dereferable maps.
-
void set(const Key& key, const Value& val) {
(*this)[key] = val;
}
protected:
-
+
/// Add a new key to the map. It called by the map registry.
-
- void add(const Key& key) {
+
+ virtual void add(const Key& key) {
int id = graph->id(key);
if (id >= capacity) {
int new_capacity = (capacity == 0 ? 1 : capacity);
@@ -188,7 +193,7 @@
allocator.construct(&(values[id]), Value());
}
- void add(const std::vector<Key>& keys) {
+ virtual void add(const std::vector<Key>& keys) {
int max_id = -1;
for (int i = 0; i < (int)keys.size(); ++i) {
int id = graph->id(keys[i]);
@@ -229,19 +234,19 @@
/// Erase a key from the map. It called by the map registry.
- void erase(const Key& key) {
+ virtual void erase(const Key& key) {
int id = graph->id(key);
allocator.destroy(&(values[id]));
}
- void erase(const std::vector<Key>& keys) {
+ virtual void erase(const std::vector<Key>& keys) {
for (int i = 0; i < (int)keys.size(); ++i) {
int id = graph->id(keys[i]);
allocator.destroy(&(values[id]));
}
}
- void build() {
+ virtual void build() {
allocate_memory();
Item it;
for (graph->first(it); it != INVALID; graph->next(it)) {
@@ -250,7 +255,7 @@
}
}
- void clear() {
+ virtual void clear() {
if (capacity != 0) {
Item it;
for (graph->first(it); it != INVALID; graph->next(it)) {
Modified: hugo/trunk/lemon/bits/default_map.h
==============================================================================
--- hugo/trunk/lemon/bits/default_map.h (original)
+++ hugo/trunk/lemon/bits/default_map.h Wed Oct 5 15:15:47 2005
@@ -28,8 +28,6 @@
namespace lemon {
- /// \addtogroup graphmapfactory
- /// @{
template <typename _Graph, typename _Item, typename _Value>
struct DefaultMapSelector {
@@ -268,7 +266,6 @@
};
- /// @}
}
#endif
Added: hugo/trunk/lemon/bits/static_map.h
==============================================================================
--- (empty file)
+++ hugo/trunk/lemon/bits/static_map.h Wed Oct 5 15:15:47 2005
@@ -0,0 +1,348 @@
+/* -*- C++ -*-
+ * lemon/static_map.h - Part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_STATIC_MAP_H
+#define LEMON_STATIC_MAP_H
+
+#include <algorithm>
+#include <iostream>
+
+#include <lemon/utility.h>
+#include <lemon/bits/map_iterator.h>
+#include <lemon/bits/alteration_notifier.h>
+#include <lemon/error.h>
+#include <lemon/concept_check.h>
+#include <lemon/concept/maps.h>
+
+/// \ingroup graphmaps
+///
+///\file
+///\brief Static sized graph maps.
+
+namespace lemon {
+
+ /// \ingroup graphmaps
+ ///
+ /// \brief Graph map with static sized storage.
+ ///
+ /// The StaticMap template class is graph map structure what
+ /// does not update automatically the map when a key is added to or
+ /// erased from the map rather it throws an exception. This map factory
+ /// uses the allocators to implement the container functionality.
+ ///
+ /// \param Registry The AlterationNotifier that will notify this map.
+ /// \param Item The item type of the graph items.
+ /// \param Value The value type of the map.
+ ///
+ /// \author Balazs Dezso
+
+
+ template <typename _Graph, typename _Item, typename _Value>
+ class StaticMap : public AlterationNotifier<_Item>::ObserverBase {
+ public:
+
+ /// \brief Exception class for unsupported exceptions.
+ class UnsupportedOperation : public lemon::LogicError {
+ public:
+ virtual const char* exceptionName() const {
+ return "lemon::StaticMap::UnsupportedOperation";
+ }
+ };
+
+ typedef True AdaptibleTag;
+
+ /// The graph type of the map.
+ typedef _Graph Graph;
+ /// The key type of the map.
+ typedef _Item Key;
+ /// The id map type of the map.
+ typedef AlterationNotifier<_Item> Registry;
+ /// The value type of the map.
+ typedef _Value Value;
+
+ /// The map type.
+ typedef StaticMap Map;
+ /// The base class of the map.
+ typedef typename Registry::ObserverBase Parent;
+
+ private:
+
+ typedef std::vector<Value> Container;
+
+ public:
+
+ /// \brief Constructor to attach the new map into the registry.
+ ///
+ /// It constructs a map and attachs it into the registry.
+ /// It adds all the items of the graph to the map.
+ StaticMap(const Graph& _g) : graph(&_g) {
+ attach(_g.getNotifier(_Item()));
+ build();
+ }
+
+ /// \brief Constructor uses given value to initialize the map.
+ ///
+ /// It constructs a map uses a given value to initialize the map.
+ /// It adds all the items of the graph to the map.
+ StaticMap(const Graph& _g, const Value& _v) : graph(&_g) {
+ attach(_g.getNotifier(_Item()));
+ unsigned size = graph->maxId(_Item()) + 1;
+ container.reserve(size);
+ container.resize(size, _v);
+ }
+
+ /// \brief Copy constructor
+ ///
+ /// Copy constructor.
+ StaticMap(const StaticMap& _copy) : Parent(), graph(_copy.getGraph()) {
+ if (_copy.attached()) {
+ attach(*_copy.getRegistry());
+ container = _copy.container;
+ }
+ }
+
+ /// \brief Destrcutor
+ ///
+ /// Destructor.
+ virtual ~StaticMap() {
+ clear();
+ if (attached()) {
+ detach();
+ }
+ }
+
+
+ private:
+
+ StaticMap& operator=(const StaticMap&);
+
+ protected:
+
+ using Parent::attach;
+ using Parent::detach;
+ using Parent::attached;
+
+ const Graph* getGraph() const {
+ return graph;
+ }
+
+ public:
+
+ typedef typename Container::reference Reference;
+ typedef typename Container::pointer Pointer;
+ typedef const Value ConstValue;
+ typedef typename Container::const_reference ConstReference;
+ typedef typename Container::const_pointer ConstPointer;
+
+ /// \brief The subcript operator.
+ ///
+ /// The subscript operator. The map can be subscripted by the
+ /// actual items of the graph.
+
+ Reference operator[](const Key& key) {
+ return container[graph->id(key)];
+ }
+
+ /// \brief The const subcript operator.
+ ///
+ /// The const subscript operator. The map can be subscripted by the
+ /// actual items of the graph.
+
+ ConstReference operator[](const Key& key) const {
+ return container[graph->id(key)];
+ }
+
+
+ /// \brief The setter function of the map.
+ ///
+ /// It the same as operator[](key) = value expression.
+ ///
+ void set(const Key& key, const Value& value) {
+ (*this)[key] = value;
+ }
+
+ protected:
+
+ /// \brief Adds a new key to the map.
+ ///
+ /// It adds a new key to the map. It called by the observer registry
+ /// and it overrides the add() member function of the observer base.
+
+ void add(const Key&) {
+ throw UnsupportedOperation();
+ }
+
+ /// \brief Erases a key from the map.
+ ///
+ /// Erase a key from the map. It called by the observer registry
+ /// and it overrides the erase() member function of the observer base.
+ void erase(const Key&) {
+ throw UnsupportedOperation();
+ }
+
+ /// Buildes the map.
+
+ /// It buildes the map. It called by the observer registry
+ /// and it overrides the build() member function of the observer base.
+
+ void build() {
+ int size = graph->maxId(_Item()) + 1;
+ container.reserve(size);
+ container.resize(size);
+ }
+
+ /// Clear the map.
+
+ /// It erase all items from the map. It called by the observer registry
+ /// and it overrides the clear() member function of the observer base.
+ void clear() {
+ container.clear();
+ }
+
+ private:
+
+ Container container;
+ const Graph *graph;
+
+ };
+
+ /// \e
+ template <typename _Base>
+ class StaticMappableGraphExtender : public _Base {
+ public:
+
+ typedef StaticMappableGraphExtender<_Base> Graph;
+ typedef _Base Parent;
+
+ typedef typename Parent::Node Node;
+ typedef typename Parent::NodeIt NodeIt;
+
+ typedef typename Parent::Edge Edge;
+ typedef typename Parent::EdgeIt EdgeIt;
+
+
+ template <typename _Value>
+ class NodeMap
+ : public IterableMapExtender<StaticMap<Graph, Node, _Value> > {
+ public:
+ typedef StaticMappableGraphExtender Graph;
+ typedef IterableMapExtender<StaticMap<Graph, Node, _Value> > Parent;
+
+ NodeMap(const Graph& _g)
+ : Parent(_g) {}
+ NodeMap(const Graph& _g, const _Value& _v)
+ : Parent(_g, _v) {}
+
+ NodeMap& operator=(const NodeMap& cmap) {
+ return operator=<NodeMap>(cmap);
+ }
+
+
+ /// \brief Template assign operator.
+ ///
+ /// The given parameter should be conform to the ReadMap
+ /// concecpt and could be indiced by the current item set of
+ /// the NodeMap. In this case the value for each item
+ /// is assigned by the value of the given ReadMap.
+ template <typename CMap>
+ NodeMap& operator=(const CMap& cmap) {
+ checkConcept<concept::ReadMap<Node, _Value>, CMap>();
+ const typename Parent::Graph* graph = Parent::getGraph();
+ Node it;
+ for (graph->first(it); it != INVALID; graph->next(it)) {
+ Parent::set(it, cmap[it]);
+ }
+ return *this;
+ }
+
+ };
+
+ template <typename _Value>
+ class EdgeMap
+ : public IterableMapExtender<StaticMap<Graph, Edge, _Value> > {
+ public:
+ typedef StaticMappableGraphExtender Graph;
+ typedef IterableMapExtender<StaticMap<Graph, Edge, _Value> > Parent;
+
+ EdgeMap(const Graph& _g)
+ : Parent(_g) {}
+ EdgeMap(const Graph& _g, const _Value& _v)
+ : Parent(_g, _v) {}
+
+ EdgeMap& operator=(const EdgeMap& cmap) {
+ return operator=<EdgeMap>(cmap);
+ }
+
+ template <typename CMap>
+ EdgeMap& operator=(const CMap& cmap) {
+ checkConcept<concept::ReadMap<Edge, _Value>, CMap>();
+ const typename Parent::Graph* graph = Parent::getGraph();
+ Edge it;
+ for (graph->first(it); it != INVALID; graph->next(it)) {
+ Parent::set(it, cmap[it]);
+ }
+ return *this;
+ }
+ };
+
+ };
+
+ /// \e
+ template <typename _Base>
+ class StaticMappableUndirGraphExtender :
+ public StaticMappableGraphExtender<_Base> {
+ public:
+
+ typedef StaticMappableUndirGraphExtender Graph;
+ typedef StaticMappableGraphExtender<_Base> Parent;
+
+ typedef typename Parent::UndirEdge UndirEdge;
+
+ template <typename _Value>
+ class UndirEdgeMap
+ : public IterableMapExtender<StaticMap<Graph, UndirEdge, _Value> > {
+ public:
+ typedef StaticMappableUndirGraphExtender Graph;
+ typedef IterableMapExtender<
+ StaticMap<Graph, UndirEdge, _Value> > Parent;
+
+ UndirEdgeMap(const Graph& _g)
+ : Parent(_g) {}
+ UndirEdgeMap(const Graph& _g, const _Value& _v)
+ : Parent(_g, _v) {}
+
+ UndirEdgeMap& operator=(const UndirEdgeMap& cmap) {
+ return operator=<UndirEdgeMap>(cmap);
+ }
+
+ template <typename CMap>
+ UndirEdgeMap& operator=(const CMap& cmap) {
+ checkConcept<concept::ReadMap<UndirEdge, _Value>, CMap>();
+ const typename Parent::Graph* graph = Parent::getGraph();
+ UndirEdge it;
+ for (graph->first(it); it != INVALID; graph->next(it)) {
+ Parent::set(it, cmap[it]);
+ }
+ return *this;
+ }
+ };
+
+
+ };
+
+}
+
+#endif
Modified: hugo/trunk/lemon/bits/vector_map.h
==============================================================================
--- hugo/trunk/lemon/bits/vector_map.h (original)
+++ hugo/trunk/lemon/bits/vector_map.h Wed Oct 5 15:15:47 2005
@@ -44,12 +44,11 @@
/// uses the std::vector to implement the container function.
///
/// \param Registry The AlterationNotifier that will notify this map.
- /// \param IdMap The IdMap type of the graph items.
+ /// \param Item The item type of the graph items.
/// \param Value The value type of the map.
///
/// \author Balazs Dezso
-
template <
typename _Graph,
typename _Item,
@@ -57,6 +56,8 @@
>
class VectorMap : public AlterationNotifier<_Item>::ObserverBase {
public:
+
+ typedef True AdaptibleTag;
/// The graph type of the map.
typedef _Graph Graph;
@@ -93,26 +94,27 @@
typedef True FullTypeTag;
- /// Constructor to attach the new map into the registry.
-
- /// It construates a map and attachs it into the registry.
+ /// \brief Constructor to attach the new map into the registry.
+ ///
+ /// It constructs a map and attachs it into the registry.
/// It adds all the items of the graph to the map.
-
VectorMap(const Graph& _g) : graph(&_g) {
attach(_g.getNotifier(_Item()));
build();
}
- /// Constructor uses given value to initialize the map.
-
- /// It construates a map uses a given value to initialize the map.
+ /// \brief Constructor uses given value to initialize the map.
+ ///
+ /// It constructs a map uses a given value to initialize the map.
/// It adds all the items of the graph to the map.
-
VectorMap(const Graph& _g, const Value& _v) : graph(&_g) {
attach(_g.getNotifier(_Item()));
container.resize(graph->maxId(_Item()) + 1, _v);
}
+ /// \brief Copy constructor
+ ///
+ /// Copy constructor.
VectorMap(const VectorMap& _copy)
: Parent(), graph(_copy.getGraph()) {
if (_copy.attached()) {
@@ -121,6 +123,9 @@
}
}
+ /// \brief Destrcutor
+ ///
+ /// Destructor.
virtual ~VectorMap() {
if (attached()) {
detach();
@@ -144,29 +149,26 @@
public:
- /// The subcript operator.
-
+ /// \brief The subcript operator.
+ ///
/// The subscript operator. The map can be subscripted by the
- /// actual items of the graph.
-
+ /// actual items of the graph.
Reference operator[](const Key& key) {
return container[graph->id(key)];
}
- /// The const subcript operator.
-
+ /// \brief The const subcript operator.
+ ///
/// The const subscript operator. The map can be subscripted by the
/// actual items of the graph.
-
ConstReference operator[](const Key& key) const {
return container[graph->id(key)];
}
- /// The setter function of the map.
-
- /// It the same as operator[](key) = value expression.
+ /// \brief The setter function of the map.
///
+ /// It the same as operator[](key) = value expression.
void set(const Key& key, const Value& value) {
(*this)[key] = value;
}
@@ -176,35 +178,33 @@
/// \brief Adds a new key to the map.
///
/// It adds a new key to the map. It called by the observer registry
- /// and it overrides the add() member function of the observer base.
-
- void add(const Key& key) {
+ /// and it overrides the add() member function of the observer base.
+ virtual void add(const Key& key) {
int id = graph->id(key);
if (id >= (int)container.size()) {
container.resize(id + 1);
}
}
- /// Erases a key from the map.
-
+ /// \brief Erase a key from the map.
+ ///
/// Erase a key from the map. It called by the observer registry
/// and it overrides the erase() member function of the observer base.
- void erase(const Key&) {}
+ virtual void erase(const Key&) {}
- /// Buildes the map.
-
+ /// \brief Buildes the map.
+ ///
/// It buildes the map. It called by the observer registry
/// and it overrides the build() member function of the observer base.
-
- void build() {
+ virtual void build() {
container.resize(graph->maxId(_Item()) + 1);
}
- /// Clear the map.
-
+ /// \brief Clear the map.
+ ///
/// It erase all items from the map. It called by the observer registry
/// and it overrides the clear() member function of the observer base.
- void clear() {
+ virtual void clear() {
container.clear();
}
Modified: hugo/trunk/lemon/full_graph.h
==============================================================================
--- hugo/trunk/lemon/full_graph.h (original)
+++ hugo/trunk/lemon/full_graph.h Wed Oct 5 15:15:47 2005
@@ -22,7 +22,7 @@
#include <lemon/bits/iterable_graph_extender.h>
#include <lemon/bits/alteration_notifier.h>
-#include <lemon/bits/default_map.h>
+#include <lemon/bits/static_map.h>
#include <lemon/bits/undir_graph_extender.h>
@@ -195,7 +195,7 @@
AlterableFullGraphBase;
typedef IterableGraphExtender<AlterableFullGraphBase>
IterableFullGraphBase;
- typedef MappableGraphExtender<
+ typedef StaticMappableGraphExtender<
IterableGraphExtender<
AlterableGraphExtender<FullGraphBase> > > ExtendedFullGraphBase;
@@ -298,10 +298,12 @@
/// It finds the first edge from \c u to \c v. Otherwise it looks for
/// the next edge from \c u to \c v after \c prev.
/// \return The found edge or INVALID if there is no such an edge.
- Edge findEdge(Node u,Node v, Edge prev = INVALID)
- {
- return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
+ Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+ if (prev.id != -1 || u.id <= v.id) return -1;
+ return Edge(u.id * (u.id - 1) / 2 + v.id);
}
+
+ typedef True FindEdgeTag;
class Node {
@@ -328,8 +330,6 @@
Edge(int _id) : id(_id) {}
- Edge(const UndirFullGraphBase& _graph, int source, int target)
- : id(_graph._nodeNum * target+source) {}
public:
Edge() { }
Edge (Invalid) { id = -1; }
@@ -339,7 +339,7 @@
};
void first(Node& node) const {
- node.id = _nodeNum-1;
+ node.id = _nodeNum - 1;
}
static void next(Node& node) {
@@ -347,7 +347,7 @@
}
void first(Edge& edge) const {
- edge.id = _edgeNum-1;
+ edge.id = _edgeNum - 1;
}
static void next(Edge& edge) {
@@ -355,31 +355,35 @@
}
void firstOut(Edge& edge, const Node& node) const {
- edge.id = node.id != 0 ? node.id * (node.id - 1) / 2 : -1;
+ int src = node.id;
+ int trg = 0;
+ edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
}
/// \todo with specialized iterators we can make faster iterating
- void nextOut(Edge& e) const {
- int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
- int target = e.id - (source) * (source - 1) / 2;
- ++target;
- e.id = target < source ? source * (source - 1) / 2 + target : -1;
+ void nextOut(Edge& edge) const {
+ int src = source(edge).id;
+ int trg = target(edge).id;
+ ++trg;
+ edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
}
void firstIn(Edge& edge, const Node& node) const {
- edge.id = node.id * (node.id + 1) / 2 - 1;
+ int src = node.id + 1;
+ int trg = node.id;
+ edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
}
- void nextIn(Edge& e) const {
- int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
- int target = e.id - (source) * (source - 1) / 2; ++target;
- ++source;
- e.id = source < _nodeNum ? source * (source - 1) / 2 + target : -1;
+ void nextIn(Edge& edge) const {
+ int src = source(edge).id;
+ int trg = target(edge).id;
+ ++src;
+ edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
}
};
- typedef MappableUndirGraphExtender<
+ typedef StaticMappableUndirGraphExtender<
IterableUndirGraphExtender<
AlterableUndirGraphExtender<
UndirGraphExtender<UndirFullGraphBase> > > > ExtendedUndirFullGraphBase;
Modified: hugo/trunk/lemon/grid_graph.h
==============================================================================
--- hugo/trunk/lemon/grid_graph.h (original)
+++ hugo/trunk/lemon/grid_graph.h Wed Oct 5 15:15:47 2005
@@ -23,7 +23,7 @@
#include <lemon/bits/iterable_graph_extender.h>
#include <lemon/bits/alteration_notifier.h>
-#include <lemon/bits/default_map.h>
+#include <lemon/bits/static_map.h>
#include <lemon/bits/undir_graph_extender.h>
@@ -339,7 +339,7 @@
};
- typedef MappableUndirGraphExtender<
+ typedef StaticMappableUndirGraphExtender<
IterableUndirGraphExtender<
AlterableUndirGraphExtender<
UndirGraphExtender<GridGraphBase> > > > ExtendedGridGraphBase;
Modified: hugo/trunk/lemon/hypercube_graph.h
==============================================================================
--- hugo/trunk/lemon/hypercube_graph.h (original)
+++ hugo/trunk/lemon/hypercube_graph.h Wed Oct 5 15:15:47 2005
@@ -232,7 +232,7 @@
};
- typedef MappableGraphExtender<
+ typedef StaticMappableGraphExtender<
IterableGraphExtender<
AlterableGraphExtender<
HyperCubeGraphBase > > > ExtendedHyperCubeGraphBase;
More information about the Lemon-commits
mailing list