/*!
  \file
    This file contains documentation for the 'picky' example.
    It contains some C++ code, to help Doxygen find its way around.
*/


namespace SciGPU {
  namespace Legion {


    /*!
      \page picky Picky Maniples

      \dontinclude picky.cpp

      
      There are times when a Maniple will want to select
      particular \ref Task "Tasks" from the list pending for
      its Legion.
      To do this, we derive a new Maniple type, and over-ride
      the Maniple::ApproveTask method.


      \section pickymaniple A Picky Maniple Class

      In this example, we will re-use the \c PlusOne and
      \c DivTwo classes from the \ref multitask example.
      Suppose we want a Maniple to process only \c PlusOne
      tasks, and then, only those whose \c initial value
      was a multiple of some number.

      We can achieve this with the following class, derived
      from the CPUmaniple base class:
      \skip class PickyManiple : public SciGPU::Legion::CPUmaniple {
      \until };
      This class contains a \c factor member, which is used
      to select specific \c PlusOne objects - only those
      whose \c initial value is a multiple of \c factor will be
      processed by an object of the \c PickyManiple class.
      We have also over-ridden the Maniple::Initialise method,
      to enable a \c PickyManiple let the user know what
      \ref Task "Tasks" each Maniple will perform.
      
      We now come to the Maniple::ApproveTask method itself.
      \skip bool PickyManiple::ApproveTask
      \until } // End method
      This returns \c true or \c false, depending on whether
      the object is willing to process the Task.
      To determine whether the actual Task object is of type
      \c PlusOne, this method first attempts a
      \c dynamic_cast to a \c PlusOne&.
      If this fails, an exception of type \c std::bad_cast
      is raised by the runtime.
      The method catches this exception, and returns \c false.
      If the \c dynamic_cast is successful, the
      \c PickyManiple can examine the \c initial field of
      the \c PlusOne object, and approve or reject
      it accordingly.


      
      \section pickylegion Enlisting the Legion

      Putting the new \c PickyManiple objects into a Legion
      is straightforward:
      \skip // Create PickyManiples with various factors
      \until }
      This simply creates several \c PickyManiple objects,
      each with a different \c factor member.
      We also add a default Maniple, which can pick up
      any \ref Task "Tasks" which the \c PickManiples miss.
      \skipline myLegion.AddManiple
      
      The Legion then runs as before, but the final statistics
      can be very different
      \verbatim
$ ./examples/picky/PickyLegion --maniples=4 --nPlusOne=2000
Legion Picky
============

Maniple 0x4a5d670: Starting up
Maniple 0x4a5cef0: Starting up
Maniple 0x4a5cef0: Picky with factor = 1
Maniple 0x4a5d3f0: Starting up
Maniple 0x4a5d3f0: Picky with factor = 12
Maniple 0x4a5d170: Starting up
Maniple 0x4a5d170: Picky with factor = 3
nComplete = 2204
nComplete = 3000

Results:

Statistics for Completed Tasks
Tags Observed    :     1     2
------------------------------------------
Maniple 0x4a5d170:   462     0     |   462
Maniple 0x4a5cef0:  1175     0     |  1175
Maniple 0x4a5d670:   193  1000     |  1193
Maniple 0x4a5d3f0:   170     0     |   170
------------------------------------------
Totals           :  2000  1000     |  3000

Maniple 0x4a5d170: Caught terminate signal
Maniple 0x4a5d170: Shutting down
Maniple 0x4a5cef0: Caught terminate signal
Maniple 0x4a5cef0: Shutting down
Maniple 0x4a5d670: Caught terminate signal
Maniple 0x4a5d670: Shutting down
Maniple 0x4a5d3f0: Caught terminate signal
Maniple 0x4a5d3f0: Shutting down
      \endverbatim
      In this case, Maniple \c 0x4a5d670 was the default Maniple,
      and took care of all the \c DivTwo tasks.
      It also mopped up a few \c PlusOne tasks.
      Maniple \c 0x4a5cef0 had a \c factor of 1, and hence accepted
      any \c PlusOne task.
      Maniple \c 0x4a5d3f0 had a \c factor of 12, and hence processed
      about ten times fewer \c PlusOne tasks than Maniple 0x4a5cef0.
      

      \section pickysophisticated More Sophistication
      
      If a more sophisticated means of selecting a Task
      is required, a Maniple can also over-ride the
      Maniple::SelectTaskFromRange method.
      This supplies two iterators, marking the beginning
      and end of the available list of \ref Task "Tasks".
      The over-riding method returns an iterator pointing
      to the desired task (or the end iterator if none
      are acceptable).
    */
  }
}
