// -*- 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. * * * \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... 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 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 = 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(); * Destroys the collection but doesn't acts on elements refered * by this collection. */ // \} /*! \name Accessors */ // \{ /*! \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; 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 = netgetComponents()->getSubSet(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 * * * 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) { for_each(Net*, net, cellgetExternalNets()) { assert(netIsExternal()); assert(netgetCell() == cell); end_for; } } \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) { for_each_net(net, cellgetExternalNets()) { assert(netIsExternal()); assert(netgetCell() == cell); end_for; } } \endcode */ // \} /*! \name Collection Functions */ // \{ // \} /* \name Others */ // \{ /* \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. */ // \} }