/*
* $Revision: 2584 $
*
* last checkin:
* $Author: gutwenger $
* $Date: 2012-07-12 02:38:07 +0200 (Do, 12. Jul 2012) $
***************************************************************/
/** \file
* \brief Declaration and implementation of ClusterArray class.
*
* \author Sebastian Leipert
*
* \par License:
* This file is part of the Open Graph Drawing Framework (OGDF).
*
* \par
* Copyright (C)
* See README.txt in the root directory of the OGDF installation for details.
*
* \par
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* Version 2 or 3 as published by the Free Software Foundation;
* see the file LICENSE.txt included in the packaging of this file
* for details.
*
* \par
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* \par
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* \see http://www.gnu.org/copyleft/gpl.html
***************************************************************/
#ifdef _MSC_VER
#pragma once
#endif
#ifndef OGDF_CLUSTER_ARRAY_H
#define OGDF_CLUSTER_ARRAY_H
#include "../basic/Array.h"
#include "ClusterGraph.h"
namespace ogdf {
//---------------------------------------------------------
// ClusterArrayBase
// base class for ClusterArray, defines interface for event handling
// used by Graph
//---------------------------------------------------------
//! Abstract base class for cluster arrays.
/**
* Defines the interface for event handling used by the ClusterGraph class.
* Use the paramiterized class ClusterArray for creating edge arrays.
*/
class ClusterArrayBase {
/**
* Pointer to list element in the list of all registered cluster
* arrays which references this array.
*/
ListIterator m_it;
public:
const ClusterGraph *m_pClusterGraph; //!< The associated cluster graph.
//! Initializes a cluster array not associated with a cluster graph.
ClusterArrayBase() : m_pClusterGraph(0) { }
//! Initializes a cluster array associated with \a pC.
ClusterArrayBase(const ClusterGraph *pC) : m_pClusterGraph(pC) {
if(pC) m_it = pC->registerArray(this);
}
// destructor, unregisters the array
virtual ~ClusterArrayBase() {
if (m_pClusterGraph) m_pClusterGraph->unregisterArray(m_it);
}
// event interface used by Graph
//! Virtual function called when table size has to be enlarged.
virtual void enlargeTable(int newTableSize) = 0;
//! Virtual function called when table has to be reinitialized.
virtual void reinit(int initTableSize) = 0;
//! Virtual function called when array is disconnected from the cluster graph.
virtual void disconnect() = 0;
//! Associates the array with a new cluster graph.
void reregister(const ClusterGraph *pC) {
if (m_pClusterGraph) m_pClusterGraph->unregisterArray(m_it);
if ((m_pClusterGraph = pC) != 0) m_it = pC->registerArray(this);
}
}; // class ClusterArrayBase
//! Dynamic arrays indexed with clusters.
/**
* Cluster arrays adjust their table size automatically
* when the cluster graph grows.
*/
template class ClusterArray : private Array, protected ClusterArrayBase {
T m_x; //!< The default value for array elements.
public:
//! Constructs an empty cluster array associated with no graph.
ClusterArray() : Array(), ClusterArrayBase() { }
//! Constructs a cluster array associated with \a C.
ClusterArray(const ClusterGraph &C) :
Array(C.clusterArrayTableSize()),
ClusterArrayBase(&C) { }
//! Constructs a cluster array associated with \a C.
/**
* @param C is the associated cluster graph.
* @param x is the default value for all array elements.
*/
ClusterArray(const ClusterGraph &C, const T &x) :
Array(0,C.clusterArrayTableSize()-1,x),
ClusterArrayBase(&C), m_x(x) { }
//! Constructs a cluster array associated with \a C and a given
//! size (for static use).
/**
* @param C is the associated cluster graph.
* @param x is the default value for all array elements.
* @param size is the size of the array.
*/
ClusterArray(const ClusterGraph &C, const T &x, int size) :
Array(0,size-1,x),
ClusterArrayBase(&C), m_x(x) { }
//! Constructs a cluster array that is a copy of \a A.
/**
* Associates the array with the same cluster graph as \a A and copies all elements.
*/
ClusterArray(const ClusterArray &A) :
Array(A),
ClusterArrayBase(A.m_pClusterGraph), m_x(A.m_x) { }
//! Returns true iff the array is associated with a graph.
bool valid() const { return (Array::low() <= Array::high()); }
//! Returns a pointer to the associated cluster graph.
const ClusterGraph *graphOf() const {
return m_pClusterGraph;
}
//! Returns a reference to the element with index \a c.
const T &operator[](cluster c) const {
OGDF_ASSERT(c != 0 && c->graphOf() == m_pClusterGraph)
return Array::operator [](c->index());
}
//! Returns a reference to the element with index \a c.
T &operator[](cluster c) {
OGDF_ASSERT(c != 0 && c->graphOf() == m_pClusterGraph)
return Array::operator [](c->index());
}
//! Returns a reference to the element with index \a index.
/**
* \attention Make sure that \a index is a valid index for a cluster
* in the associated cluster graph!
*/
const T &operator[](int index) const {
return Array::operator [](index);
}
//! Returns a reference to the element with index \a index.
/**
* \attention Make sure that \a index is a valid index for a cluster
* in the associated cluster graph!
*/
T &operator[](int index) {
return Array::operator [](index);
}
//! Assignment operator.
ClusterArray &operator=(const ClusterArray &a) {
Array::operator =(a);
m_x = a.m_x;
reregister(a.m_pClusterGraph);
return *this;
}
//! Reinitializes the array. Associates the array with no cluster graph.
void init() {
Array::init(); reregister(0);
}
//! Reinitializes the array. Associates the array with \a C.
void init(const ClusterGraph &C) {
Array::init( C.clusterArrayTableSize() ); reregister(&C);
}
//! Reinitializes the array. Associates the array with \a C.
/**
* @param C is the associated cluster graph.
* @param x is the default value.
*/
void init(const ClusterGraph &C, const T &x) {
Array::init(0,C.clusterArrayTableSize()-1, m_x = x); reregister(&C);
}
//! Sets all array elements to \a x.
void fill(const T &x) {
int high = m_pClusterGraph->maxClusterIndex();
if(high >= 0)
Array::fill(0,high,x);
}
private:
virtual void enlargeTable(int newTableSize) {
Array::grow(newTableSize-Array::size(),m_x);
}
virtual void reinit(int initTableSize) {
Array::init(0,initTableSize-1,m_x);
}
virtual void disconnect() {
Array::init();
m_pClusterGraph = 0;
}
OGDF_NEW_DELETE
}; // class ClusterArray
} // end namespace ogdf
#endif