358 lines
11 KiB
C++
358 lines
11 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.
|
|
*
|
|
*
|
|
* \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...
|
|
|
|
for_each_instance(instance, getCollection(instanceSet)) {
|
|
// process here each instance of the set
|
|
// (the elements are visited according to the set ordering)
|
|
end_for;
|
|
}
|
|
\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 = cellgetNets();
|
|
|
|
cellDelete();
|
|
|
|
for_each_net(net, nets) {
|
|
...
|
|
end_for;
|
|
}
|
|
\endcode
|
|
*
|
|
*
|
|
*
|
|
* \section secCollectionImportant Important
|
|
*
|
|
* Collections are very light objects which are built, copied or
|
|
* destroyed very rapidly.
|
|
*
|
|
* \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).
|
|
*/
|
|
|
|
|
|
|
|
/*! \name Destructors
|
|
*/
|
|
// \{
|
|
|
|
/*! \function Collection::~Collection<Type>();
|
|
* Destroys the collection but doesn't acts on elements refered
|
|
* by this collection.
|
|
*/
|
|
|
|
// \}
|
|
|
|
|
|
/*! \name Accessors
|
|
*/
|
|
// \{
|
|
|
|
/*! \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;
|
|
|
|
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 = netgetComponents()->getSubSet<Segment*>(IsOnLayer(metal));
|
|
|
|
// segments represents here the subset of net components
|
|
// which are of type Segment and located on layer metal
|
|
\endcode
|
|
*
|
|
*
|
|
*/
|
|
|
|
// \}
|
|
|
|
|
|
/*! \name Predicates
|
|
*/
|
|
// \{
|
|
|
|
/* \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) {
|
|
for_each(Net*, net, cellgetExternalNets()) {
|
|
assert(netIsExternal());
|
|
assert(netgetCell() == cell);
|
|
end_for;
|
|
}
|
|
}
|
|
\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) {
|
|
for_each_net(net, cellgetExternalNets()) {
|
|
assert(netIsExternal());
|
|
assert(netgetCell() == cell);
|
|
end_for;
|
|
}
|
|
}
|
|
\endcode
|
|
*/
|
|
|
|
// \}
|
|
|
|
|
|
/*! \name Collection Functions
|
|
*/
|
|
// \{
|
|
|
|
// \}
|
|
|
|
|
|
/* \name Others
|
|
*/
|
|
// \{
|
|
|
|
/* \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.
|
|
*/
|
|
|
|
// \}
|
|
|
|
}
|