
 // -*- 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      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
  *                <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.
  *               
  */

 }
