
 // -*- C++ -*-


 namespace Hurricane {

 /*! \class        Filter
  *  \brief        Filter description (\b API)
  *
  *  \section      secFilterIntro  Introduction
  *
  *                A filter is a functional object which, used in conjunction 
  *                with a collection, allows to get only the elements of this 
  *                collection which meet some criteria. 
  *
  *                This class is an abstract class which must be derived in 
  *                order to get the appropriate behaviour. 
  *
  *                You will have also to define the default constructor, the 
  *                copy constructor, the assignment operator and overload the 
  *                two following member functions : 
  *
  *
  *  \section      secFilterSimpleExample  Simple Example
  *
  *                Definition of the filter selecting external nets of a cell : 
\code
class IsExternal : public Filter<Net*> {
// ***********************************
 
   public:
 
      IsExternal() {};
 
      IsExternal(const IsExternal& isExternal) {};
 
      IsExternal& operator=(const IsExternal& isExternal) {return *this;};
 
      virtual Filter<Net*>* getClone() const {return new IsExternal(*this);};
 
      virtual bool accept(Net* net) const {return net->isExternal();};
 
};
\endcode
  *                Implementation of the accessor <b>getExternalNets</b> for the 
  *                cells : 
\code
Nets Cell::getExternalNet() const
// ******************************
{
   return getNets().getSubSet(IsExternal());
}
\endcode
  *                Similarly, the accessor <b>getInternalNets</b> can be 
  *                implemented using the <b>!</b> operator : 
\code
Nets Cell::getInternalNets() const
// *******************************
{
   return getNets().getSubSet(!IsExternal());
}
\endcode
  * 
  *
  *  \section      secFilterComplexExample  Complex Example
  *
  *                In order to implement previous examples we could have used 
  *                filter with a simpler interface. Now the filters as they are 
  *                defined open the door to much more complex processing. 
  *
  *                As a matter of fact the function <b>accept</b> receives only 
  *                one argument which represents the element of the collection 
  *                to be accepted or rejected. 
  *
  *                Sometimes the filter must take into account other criteria. 
  *                For example to print the external nets of a cell whose name 
  *                start with a given character. Those additional criteria will 
  *                then become attributes of the filter as shown in the 
  *                following example : 
  *
  *                Filter definition : 
\code
class MyFilter : public Filter<Net*> {
// *********************************
 
   public:
 
      char _c;
 
      MyFilter(char c) : _c(c) {};
 
      MyFilter(const MyFilter& myFilter) : _c(myFilter._c) {};
 
      MyFilter& operator=(const MyFilter& myFilter)
      {
         _c = myFilter._c;
         return *this;
      };
 
      virtual Filter<Net*>* getClone() const {return new MyFilter(*this);};
 
      virtual bool accept(Net* net) const
      {
         return net->isExternal() && (net->getName()[0] == _c);
      };
 
};
\endcode
  *                Afterwards do 
\code
forEach(Net*, inet, cell->getNets().getSubSet(MyFilter('k'))) {
   assert(inet->isExternal());
   assert(inet->getName()[0] == 'k');
   cerr << "net: " << (*inet) << endl;
}
\endcode
  *                Although this example is not of great interest, it 
  *                illustrates the way to proceed to create a complex filter. 
  */



 /*! \section      secFilterRemarks  Remarks
  *
  *                It is wise to use filters only when it is trully necessary, 
  *                that is to produce useful collections to be used extensively. 
  *
  *                Indeed, for the previous example, preferably write it like 
  *                this : 
\code
forEach(Net*, inet, cell->getNets()) {
   if (inet->isExternal() && (inet->getName()[0] == 'k'))
      cerr << "net: " << *net << endl;
}
\endcode
  *                or more simply : 
\code
forEach(Net*, net, cell->getExternalNets()) {
   if (inet->getName()[0] == 'k')
      cerr << "net: " << *inet << endl;
}
\endcode
  *                Filters are objects like any other : they can be passed as 
  *                function arguments as shown below : 
\code
Nets Cell::getNets(const GenericFilter<Net*>& filter) const
// ********************************************************
{
   return getNets().getSubSet(filter);
}
\endcode
  *                As far as the type <b>NetFilter</b> is defined as being a 
  *                <b>GenericFilter\<Net*\></b> the previous function can be 
  *                written like this : 
\code
Nets Cell::getNets(const NetFilter& filter) const
// **********************************************
{
   return getNets().getSubSet(filter);
}
\endcode
  */


 /*! \function     Filter<Type>* Filter::getClone() const;
  *  \Return       a filter copy. 
  */


 /*! \function     bool Filter::accept(Type element) const;
  *                This member function returns \true if the filter accepts the 
  *                element else \false. 
  */


 /*! \function     GenericFilter<Type> Filter::operator ! () const;
  *  \Return       the inverse filter of the filter \c \<this\> (accepted 
  *                elements are those rejected and conversely). 
  */


 /*! \class        GenericFilter
  *  \brief        Generic Filter auto-pointer.
  *
  *                This class is an auto-pointer like wrapped around the raw filter.
  *                The database systematically returns filters wrapped inside
  *                GenericFilter.
  *
  *  \remark       The destruction of a GenericFilter triggers the destruction of
  *                the raw filter.
  */

 /*! \function     GenericFilter::GenericFilter(Filter<Type>* filter);
  *                Constructor from a raw Filter.
  *
  *  \remark       This constructor do not build a copy of the raw filter. So the original
  *                raw filter must not be deleted. It's deletion will occurs with the one
  *                of the GenericFilter.
  */

 /*! \function     GenericFilter::GenericFilter(const Filter<Type>& filter);
  *                Constructor from a raw Filter.
  *
  *  \remark       This constructor build a \e copy of the raw filter. So the originating
  *                filter can be safely deleted.
  */

 /*! \function     GenericFilter::GenericFilter(const GenericFilter<Type>& filter);
  *                Constructor from a raw Filter.
  *
  *  \remark       This constructor build a \e copy of the raw filter. So the originating
  *                filter can be safely deleted.
  */


 /*! \class        NotFilter
  *  \brief        Filter negation.
  *
  *                This filter invert the matching criterion of any other filter.
  *
  *  \remark       This is a raw Filter.
  *                
  */

 /*! \function     NotFilter::NotFilter(const Filter<Type>& filter);
  *                Constructor from a raw Filter.
  *
  *  \remark       This constructor build a \e copy of the raw filter. So the originating
  *                filter can be safely deleted.
  */

 /*! \function     NotFilter::NotFilter(const NotFilter<Type>& filter);
  *                Copy constructor.
  *
  *  \remark       This constructor build a \e copy of the raw filter. So the originating
  *                filter can be safely deleted.
  */

 }
