coriolis/hurricane/doc/hurricane/Collection.dox

487 lines
18 KiB
C++

// -*- C++ -*-
namespace Hurricane {
/*! \class Collection
* \brief Collection description (\b API)
*
* \section secCollectionIntro Introduction
*
* Collections introduce the concept of set of elements.
*
* Strictly speaking collections are not containers (in the STL
* way) but indeed set descriptors. For example, the set of
* instances called by a cell, which are located within a given
* rectangular area, will be a subtype of
* Collection\<Instance*\> whose first attribute will be a
* pointer to the cell and a second attribute the rectangular
* area.
*
* Main characteristics of Collections:
* <ul>
* <li>Collections <b>do not own</b> their elements (they
* remains when the Collection is deleted).
* <li>They can only be iterated \e forward. Once an
* element is consumed you cannot go back to it.
* You must restart the collection walktrough instead.
* <li>Collections are very light objects which are built,
* copied or destroyed very rapidly.
* </ul>
*
*
* \section secIterator STL Iterator Support
*
* The Collections now provides a basic iterator support to allow the
* C++11 \c for contruct:
\code
Cell* cell = ...; // Get a Cell from somewhere.
for( Net* inet : cell->getNets() ) {
cout << "This is " << inet;
if (inet->isExternal())
cout << " [external net].";
cout << endl;
}
\endcode
* Although the \c forEach macro is still retained for backward compatibility,
* it is advisable to use the C++11 way.
*
*
* \section secForEachMacro The forEach Macro (obsoleted)
*
* Collections are to be used in conjunction with the \c forEach macro
* which allows to easily iterate over the elements. Iteration is done
* through a simplistic iterator which have overload for the
* <code>operator*()</code> and <code>operator->()</code>
*
* The \c forEach macro takes three arguments:
* <center>
* <table>
* <tr><th colspan="2"> <code>forEach(type,iterator,collection)</code>
* <tr><td> \c type <td>Element's type of the collection.
* <tr><td> \c iterator <td>Name of the iterator's variable.
* <tr><td> \c collection <td>An appropriate collection to iterate over, that is,
* built over \c type elements.
* </table>
* </center>
*
* To use the forEach macro outside the Hurricane namespace, the
* following statement is necessary:
\code
using Hurricane::ForEachIterator
\endcode
* Here is a small example of a loop:
\code
using Hurricane::ForEachIterator;
Cell* cell = ...; // Get a Cell from somewhere.
forEach( Net*, inet, cell->getNets() ) {
cout << "This is " << (*inet);
if (inet->isExternal())
cout << " [external net].";
cout << endl;
}
\endcode
*
*
* \section secGenericgetCollection The Generic getCollection
*
* The collections provide the generic \c getCollection()
* function which allows to convert its argument into a generic
* collection. It has no specific interest for Hurricane
* collections, but this function is overloaded for STL containers.
*
* This allows to handle a STL containers like a normal
* collection as shown in the following example:
\code
set<Instance*> instanceSet;
// here we fill the set with the desired instances...
forEach(Instance*, iinstance, getCollection(instanceSet)) {
// process here each instance of the set
// (the elements are visited according to the set ordering)
}
\endcode
*
* \remark This approach is a little bit less efficient than the use of
* STL iterators, not much indeed, but has the advantage to be
* homogeneous with the remaining code (recall: the created
* collection doesn't make a copy of the STL container and its
* creation time is negligible).
*
* \caution The returned collection is valid whenever the STL container
* is valid. Then you should not do the following:
\code
GenericCollection<Instance*> getInstances(...)
{
set<Instance*> instanceSet;
// we fill the container with the appropriate instances
return getCollection(instanceSet); // instanceSet deleted after return
}
\endcode
*
*
*
* The same will occur anyway if you do:
\code
Cell* cell = ...; // we get the cell
Nets nets = cell->getNets();
cell->destroy();
forEach(Net*, inet, nets) {
...
}
\endcode
*
*
* \section secCollectionLocators Locators
*
* Each type of collection provides an associated Locator for
* tracing through the corresponding set of elements.
*
* Each locator moves efficiently through the data structure
* without building (in the form of a list or any other
* container type) the set of elements defined by the collection
* (it may however use a stack (or something else) to manage
* recursive traces).
*
* The elements are therefore visited in the order with which
* they are internally stored. No assumptions must be made about
* this ordering. However, collections representing an STL
* container are visited in the same order than the container's
* one.
*
* If you need to visit the objects in a given order, you must
* first fill a STL container: either a vector to be sorted
* accordingly or a set with the given sort criteria (see the
* Fill method below).
*/
/*! \function Collection::~Collection<Type>();
* Destroys the collection but doesn't acts on elements refered
* by this collection.
*/
/*! \function Collection<Type>* Collection::getClone() const;
* Allocates and returns a clone (copy) of the collection
* (whatever be its type).
*
* \remark In principle there is no need to use this function. However,
* if you do so, don't forget to delete the clone after use. It
* is indeed much easier to use generic collections which do
* that for you, as we will see later.
*/
/*! \function Locator<Type>* Collection::getLocator() const;
* Allocates and returns a locator adapted to visit the elements
* of the collection.
*
* \remark In principle there is no need to use this function. Use
* preferably the macro <b>for_each</b> described below.
* However, if you do so, don't forget to delete this locator
* after use, else use generic locators, which do that for you,
* as we will see later.
*/
/*! \function unsigned Collection::getSize() const;
* \Return the number of objects identified within the collection.
*
* \remark Very fast in some cases, but may need to visit the collection
* in most ones.
*/
/*! \function Type Collection::getFirst() const;
* \Return the first element of the collection.
*
* \remark The result is meaningful only when the collection is non
* empty.
*/
/*! \function GenericCollection<SubType> Collection::getSubSet<SubType>() const;
* \Return the collection corresponding to the subset of elements of
* type \c \<SubType\>.
*
* \remark The returned collection is a collection of objects of type
* <b>SubType</b> and not of type <b>Type</b>.
*
\code
Contacts Net::getContacts() const
{
return getComponents().getSubSet<Contact*>();
}
\endcode
*/
/*! \function GenericCollection<Type> Collection::getSubSet(const Filter<Type>& filter) const;
* \Return the collection representing the subset of elements accepted
* by the filter.
\code
Nets Cell::getExternalNets() const
{
return getNets().getSubSet(Net::getIsExternalFilter());
}
\endcode
*/
/*! \function GenericCollection<SubType> Collection::getSubSet<SubType>(const Filter<SubType>& filter) const;
* \Return the collection representing the subset of elements of type
* \c \<SubType\> accepted by the filter.
*
* \remark The returned collection is a collection of elements of type
* <b>SubType</b> and not of type <b>Type</b> and the filter
* must be a filter of elements of type <b>SubType</b>.
*
* \sample Filter Hurricane::Segment according to their Layer.
\code
class IsOnLayer : public Filter<Segment*> {
public:
Layer* _layer;
public:
IsOnLayer(Layer* layer)
: _layer(layer)
{
if (!_layer) throw Error("Can't create IsOnLayer filter : null layer");
};
IsOnLayer(const IsOnLayer& isOnLayer)
: _layer(isOnLayer._layer)
{ };
IsOnLayer& operator=(const IsOnLayer& isOnLayer)
{
_layer = isOnLayer._layer;
return *this;
};
virtual Filter<Net*>* getClone() const
{
return new IsOnLayer(*this);
};
virtual bool Accept(Segment* segment) const
{
return (segmentgetLayer() == _layer);
};
};
\endcode
*
* And somewher later:
\code
Layer* metal = getDataBase()->getTechnology()->getLayer("metal");
Segments segments = net->getComponents()->getSubSet<Segment*>(IsOnLayer(metal));
// segments represents here the subset of net components
// which are of type Segment and located on layer metal
\endcode
*
*
*/
/* \function bool Collection::isEmpty() const;
* This function returns \true if the collection designates no
* element and else \false.
*/
/*! \section secCollectionUtilitarians Utilitarians
*
* <b>Collection::Fill</b>
* <b>Collection::Fill</b>
* <b>Collection::Fill</b>
* \remark The elements are added to the container in the order with
* which the collection is visited. So the same order will
* appear in a list or a vector, but for a set they will be
* inserted according to the set ordering method.
*/
//! \name Collection Collection
// \{
/*! \def for_each_object(Type, element, collection)
* This powerful macro allows you to visit the set of elements
* designated by any type of collection. The first argument
* \c \<Type\> defines the type of elements that will be visited
* and the third argument \c \<collection\> is the traced
* collection. The code body located between macros
* <b>for_each</b> and <b>end_for</b> (that must not be
* forgotten) is then executed for each identified element, once
* this current element has been bound to the variable (you can
* exit prematurely with a traditional <b>break</b>). Sample use
* :
\code
Cell* cell = ...; // we get the cell
if (cell) {
forEach(Net*, inet, cellgetExternalNets()) {
assert(inet->isExternal());
assert(inet->getCell() == cell);
}
}
\endcode
* On this example the call to <b>cell-\>getExternalNets()</b>
* returns the collection of all external nets of the cell. Here
* the loop does some consistency checks on each net. As we will
* see later on there exist macros for each type of object which
* might be an element of a collection. Therefore the following
* sequence is equivalent to the previous one:
\code
Cell* cell = ...; // we get the cell
if (cell) {
forEach(Net*, inet, cellgetExternalNets()) {
assert(inet->isExternal());
assert(inet->getCell() == cell);
}
}
\endcode
*/
// \}
/* \function void Collection::Fill(list<Type>& list) const;
* No description.
*/
/* \function void Collection::Fill(vector<Type>& vector) const;
* No description.
*/
/* \function void Collection::Fill(set<Type, Comparator = less<Type>>& set) const;
* Those three functions allow to fill a STL container with the
* identified elements of a collection.
*/
/*! \class GenericCollection
* \brief Generic Collection auto-pointer.
*
* This class is an auto-pointer like wrapped around the raw collection.
* The database systematically returns collections wrapped inside
* GenericCollection.
*
* \remark The destruction of a GenericCollection triggers the destruction of
* the raw collection.
*/
/*! \function GenericCollection::GenericCollection(Collection<Type>* collection);
* Constructor from a raw Collection.
*
* \remark This constructor do not build a copy of the raw collection. So the original
* raw collection must not be deleted. It's deletion will occurs with the one
* of the GenericCollection.
*/
/*! \function GenericCollection::GenericCollection(const Collection<Type>& collection);
* Constructor from a raw Collection.
*
* \remark This constructor build a \e copy of the raw collection. So the originating
* collection can be safely deleted.
*/
/*! \function GenericCollection::GenericCollection(const GenericCollection<Type>& collection);
* Constructor from a raw Collection.
*
* \remark This constructor build a \e copy of the raw collection. So the originating
* collection can be safely deleted.
*/
/*! \class SubSetCollection
* \brief Applies a Filter to a Collection
*
* Build a sub-Collection of all the elements of the primary that
* match the Filter criterion.
*/
/*! \function SubSetCollection::SubSetCollection(const Collection<Type>& collection, const Filter<Type>& filter);
* Constructor from a primary Collection and a Filter.
*/
/*! \function SubSetCollection::SubSetCollection(const SubSetCollection& subSetCollection);
* Copy constructor.
*/
/*! \class SubTypeCollection
* \brief Applies a Type Filter to a Collection
*
* Build a sub-Collection of all the elements of the primary that
* are of a certain sub-type. The filtering mechanism relies on a
* \c dynamic_cast<> so there must be an inheritance path between
* the Collection type and the sub-type.
*/
/*! \function SubTypeCollection::SubTypeCollection(const Collection<Type>* collection);
* Constructor from a primary Collection and a Filter.
*/
/*! \function SubTypeCollection::SubTypeCollection(const GenericCollection<Type>& collection);
* Constructor from a primary Collection and a Filter.
*/
/*! \function SubTypeCollection::SubTypeCollection(const SubTypeCollection& subTypeCollection);
* Copy Constructor.
*/
/*! \typedef typedef list<Element> ElementList;
* A simple typedef for Collection encapsulated lists.
*/
/*! \class ListCollection
* \brief Hurricane Collection wrapper around a std::list.
*
* Automatically wrap a Hurricane Collection around a stl::list.
*/
/*! \function ListCollection::ListCollection(const ElementList* elementList = NULL);
* Constructor from a STL list, the list must not be de-allocated.
*/
/*! \class VectorCollection
* \brief Hurricane Collection wrapper around a std::vector.
*
* Automatically wrap a Hurricane Collection around a stl::vector.
*/
/*! \function VectorCollection::VectorCollection(const ElementVector* elementVector = NULL);
* Constructor from a STL vector, the vector must not be de-allocated.
*
*/
/*! \class MapCollection
* \brief Hurricane Collection wrapper around a std::map.
*
* Automatically wrap a Hurricane Collection around a stl::map.
*/
/*! \function MapCollection::MapCollection(const ElementMap* elementMap = NULL);
* Constructor from a STL map, the map must not be de-allocated.
*
*/
/*! \class SetCollection
* \brief Hurricane Collection wrapper around a std::set.
*
* Automatically wrap a Hurricane Collection around a stl::set.
*/
/*! \function SetCollection::SetCollection(const ElementSet* elementSet = NULL);
* Constructor from a STL set, the set must not be de-allocated.
*
*/
}