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


    /*!
      \page multitask Performing different tasks


      \dontinclude multitask.cpp


      So far, we have only considered programs which perform one
      type of task.
      This is of limited use, so we need to devise a way of
      setting our \ref Maniple "Maniples" to work on a variety of
      \ref Task "Tasks" at once.
      

      \section multitaskclasses Two types of task

      We start by defining two types of task we would like to
      perform.
      We will re-use the \c PlusOne task from the earlier example,
      and add a \c DivTwo task, which divides its input by two.
      The first thing to do is define an enumeration type to
      distinguish between the two.
      \skipline enum
      We will use this in the Task::tag member, to allow
      us to identify the two types of task.
      We can then define the PlusOne class
      \skip class PlusOne : public SciGPU::Legion::CPUtask {
      \until };
      and the DivTwo class
      \skip class DivTwo : public SciGPU::Legion::CPUtask {
      \until };
      Note how both of these supply a \c TaskTypeID value
      to the Task class constructor, which sets the Task::tag
      field.


      \section multitasklist The main program

      The main program has to manage a list of several different
      types of task.
      It can do this by creating a list of \c Task* pointers, and
      then allocating each item as an object of a particular
      class.
      We start by declaring the list
      \skipline list<SciGPU::Legion::Task*> tasks;
      We can queue up instances of \c PlusOne tasks
      \skip for(
      \until }
      and \c DivTwo tasks
      \skip for(
      \until }
      Finally, we submit them to the Legion
      \skip list<SciGPU::Legion::Task*>::const_iterator it;
      \until }
      Any \ref Maniple "Maniples" in the Legion will immediately
      start processing the work we've provided.
      We don't need to do anything else, since the virtual
      Task::Perform function does the rest.

      Once everything is complete, we can print some results.
      This introduces a subtlety: we have a list of \c Task* pointers,
      but Task is an abstract base class.
      We need to cast each one to the appropriate \c PlusOne or
      \c DivTwo object before we can do anything else.
      This is where the Task::tag value (set by the constructors)
      is used:
      \skip for( it=tasks.begin(); it!=tasks.end(); it++ ) {
      \until // End loop over tasks
      The loop examines the tag embedded in the base Task object,
      and uses that to guide a \c dynamic_cast to the appropriate type.
      Suitable overides of \c operator<< then print out the results.

      We can also print out some statistics
      \skipline myLegion.PrintCompletedStats( cout );
      which tells how many objects of each type were processed by
      each Maniple.
      Finally, we need to delete all of the Task objects we created.
      Remember that \c tasks is an \c std::list of \c Task* pointers.
      When the list's destructor is called, it will delete the
      pointers, but not the objects themselves.
      So to be good citizens, we close with
      \skip // Release all the tasks
      \until }
      which will ensure that all memory is released.
    */

  }
}
