// -*- 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\ whose first attribute will be a * pointer to the cell and a second attribute the rectangular * area. * * Main characteristics of Collections: * * * * \section secForEachMacro The forEach Macro * * 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 * operator*() and operator->() * * The \c forEach macro takes three arguments: *
* *
forEach(type,iterator,collection) *
\c type Element's type of the collection. *
\c iterator Name of the iterator's variable. *
\c collection An appropriate collection to iterate over, that is, * built over \c type elements. *
*
* * 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 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 getInstances(...) { set 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(); * Destroys the collection but doesn't acts on elements refered * by this collection. */ /*! \function Collection* 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* 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 for_each 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 Collection::getSubSet() const; * \Return the collection corresponding to the subset of elements of * type \c \. * * \remark The returned collection is a collection of objects of type * SubType and not of type Type. * \code Contacts Net::getContacts() const { return getComponents().getSubSet(); } \endcode */ /*! \function GenericCollection Collection::getSubSet(const Filter& 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 Collection::getSubSet(const Filter& filter) const; * \Return the collection representing the subset of elements of type * \c \ accepted by the filter. * * \remark The returned collection is a collection of elements of type * SubType and not of type Type and the filter * must be a filter of elements of type SubType. * * \sample Filter Hurricane::Segment according to their Layer. \code class IsOnLayer : public Filter { 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* 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(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 * * Collection::Fill * Collection::Fill * Collection::Fill * \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 \ defines the type of elements that will be visited * and the third argument \c \ is the traced * collection. The code body located between macros * for_each and end_for (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 break). 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 cell-\>getExternalNets() * 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& list) const; * No description. */ /* \function void Collection::Fill(vector& vector) const; * No description. */ /* \function void Collection::Fill(set>& 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* 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& 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& 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& collection, const Filter& 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* collection); * Constructor from a primary Collection and a Filter. */ /*! \function SubTypeCollection::SubTypeCollection(const GenericCollection& collection); * Constructor from a primary Collection and a Filter. */ /*! \function SubTypeCollection::SubTypeCollection(const SubTypeCollection& subTypeCollection); * Copy Constructor. */ /*! \typedef typedef list 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. * */ }