Commits

Anonymous committed 3e20e41

Creating Navigation package

Comments (0)

Files changed (11)

Navigation/DefaultChildColl.h

+#ifndef NAVIGATION_DEFAULTCHILDCOLL_H
+#define NAVIGATION_DEFAULTCHILDCOLL_H
+///////////////////////////////////////////////////////////////////////////////
+//
+// Implements default collection types for navigable objects. Used in the
+// templated Navigable base class.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <utility>
+#include <vector>
+
+#include "DataModel/ElementLink.h"
+#include "Navigation/DefaultWeight.h"
+
+////////////////////////////////////////////////////
+// Navigation of Relational Trees with Parameters //
+////////////////////////////////////////////////////
+
+template <typename CHILDCONTAINER, typename CHILDPAR>
+struct DefaultChildColl {
+
+  // default container is a map
+  //  typedef std::map<const CHILD*, CHILDPAR > type;
+  typedef std::pair< ElementLink<CHILDCONTAINER>, CHILDPAR > data;
+  typedef std::vector< typename data > type;
+  //  typedef std::map< ElementLink<CHILDCONT, CHILDPAR > type;
+  // object pointer (key) access 
+  static const typename CHILDCONTAINER::value_type*
+  getChildPtr(typename type::const_iterator iter) 
+  { return *(iter->first); };
+  // relational parameter (data) access
+  static CHILDPAR 
+  getChildPar(typename type::const_iterator iter) 
+  { return iter->second; };
+  // insertion of (key,data) pair
+  static void
+  insert(type& cont, const CHILDCONTAINER& aChildContainer,
+	 const typename CHILDCONTAINER::value_type* aChild, 
+	 const CHILDPAR& aPar=CHILDPAR()) {
+    ElementLink<CHILDCONTAINER> theLink;
+    theLink.toContainedElement(aChildContainer,aChild);
+    data theEntry(theLink,aPar);
+    cont.push_back(theEntry); 
+  }
+  // find method implementation
+  static typename type::const_iterator 
+  find(const type& cont, const typename CHILDCONTAINER::value_type* aChild)
+  {
+    type::const_iterator firstEntry = cont.begin();
+    type::const_iterator lastEntry  = cont.end();
+    for ( ; firstEntry != lastEntry ; firstEntry++ )
+      {
+	if ( *((*firstEntry).first) == aChild ) break;
+      }
+    return firstEntry;
+  }
+  //
+  //  { return cont.find(aChild); }
+  static typename type::iterator
+  find(type& cont, const typename CHILDCONTAINER::value_type* aChild)
+  {
+    type::iterator firstEntry = cont.begin();
+    type::iterator lastEntry  = cont.end();
+    for ( ; firstEntry != lastEntry; firstEntry++ )
+      {
+	if ( *((*firstEntry).first) == aChild ) break;
+      }
+    return firstEntry;
+  }  
+  //
+  //  { return cont.find(aChild); } 
+};
+
+///////////////////////////////////////////////////////
+// Navigation of Relational Trees without Parameters //
+///////////////////////////////////////////////////////
+
+template <typename CHILDCONTAINER>
+struct DefaultChildColl<CHILDCONTAINER,
+			typename CHILDCONTAINER::value_type, 
+			DefaultWeight> 
+{
+  // default container is a vector
+  typedef std::vector< ElementLink<CHILDCONTAINER> > type;
+  // object pointer access
+  static const typename CHILDCONTAINER::value_type* 
+  getChildPtr(typename type::const_iterator iter) 
+  { return *(*iter); }
+  // dummy relational parameter access (actual behaviour controlled by 
+  // DefaultWeight)
+  static DefaultWeight 
+  getChildPar(typename type::const_iterator) { return DefaultWeight(); }
+  // insertion of object pointer 
+  static void
+  insert(type& cont, const CHILDCONTAINER& aChildContainer,
+	 const typename CHILDCONTAINER::value_type* aChild, 
+	 const DefaultWeight&) {
+    ElementLink<CHILDCONTAINER> theLink;
+    theLink.toContainedElement(aChildContainer,aChild);
+    cont.push_back(theLink); 
+  }
+  // allocation of object pointer in list
+  static typename type::const_iterator 
+  find(const type& cont, const typename CHILDCONTAINER::value_type* aChild) 
+  {
+    type::const_iterator firstEntry = cont.begin();
+    type::const_iterator lastEntry  = cont.end();
+    for ( ; firstEntry != lastEntry; firstEntry++ )
+      {
+	if ( *(*firstEntry) == aChild ) break;
+      }
+    return firstEntry;
+    //    return std::find(cont.begin(), cont.end(), aChild); 
+  }
+  static typename type::iterator
+  find(type& cont, const typename CHILDCONTAINER::value_type* aChild) 
+  {
+    type::iterator firstEntry = cont.begin();
+    type::iterator lastEntry  = cont.end();
+    for ( ; firstEntry != lastEntry; firstEntry++ )
+      {
+	if ( *(*firstEntry) == aChild ) break;
+      }
+    return firstEntry;
+    //    return std::find(cont.begin(),cont.end(),aChild);
+  }
+};
+#endif
+

Navigation/DefaultWeight.h

+#ifndef NAVIGATION_DEFAULTWEIGHT_H
+#define NAVIGATION_DEFAULTWEIGHT_H 1
+struct DefaultWeight {
+  DefaultWeight() {}
+  DefaultWeight& operator=(const DefaultWeight&) {return *this;}
+  const DefaultWeight& operator+(const DefaultWeight&) const {return *this;}
+  const DefaultWeight& operator*(const DefaultWeight&) const {return *this;}
+  bool operator==(DefaultWeight&) const {return true;}
+  operator double() {return 1.0;}
+};
+#endif

Navigation/INavigable.h

+#ifndef INAVIGABLE_H
+#define INAVIGABLE_H
+///////////////////////////////////////////////////////////////////////////////
+//
+// Common base type for classes representing navigable objects
+//
+///////////////////////////////////////////////////////////////////////////////
+
+namespace boost {
+  class any;
+}
+
+class INavigationToken;
+
+class INavigable
+{
+ public:
+  
+  virtual ~INavigable();
+
+  // enforce fillToken(,) method in derived classes!
+  virtual void fillToken( INavigationToken & thisToken ) const = 0;
+  virtual void fillToken( INavigationToken & thisToken, 
+			  const boost::any& weight ) const = 0;
+
+};
+#endif

Navigation/INavigationCondition.h

+#ifndef INAVIGATIONCONDITION_H
+#define INAVIGATIONCONDITION_H
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Navigation Condition Abstract Base Class 
+//
+///////////////////////////////////////////////////////////////////////////////
+
+class INavigable;
+
+class INavigationCondition
+{
+
+ public:
+
+  virtual ~INavigationCondition();
+
+  // accept function
+  virtual bool accept( const INavigable * thisNavigable ) = 0;
+
+  // reset function
+  virtual void reset() = 0;
+
+};
+#endif
+
+
+

Navigation/INavigationSelector.h

+#ifndef INAVIGATIONSELECTOR_H
+#define INAVIGATIONSELECTOR_H
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Navigation Processor Abstract Base Class 
+//
+///////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+class INavigationSelector
+{
+ public:
+
+  virtual ~INavigationSelector() 
+    { };
+
+  // check data acceptance
+  virtual bool accept(const T* data,double weight) const = 0;
+
+  // reset condition
+  virtual void reset() = 0;
+
+};
+#endif
+
+
+

Navigation/INavigationToken.h

+#ifndef INAVIGATIONTOKEN_H
+#define INAVIGATIONTOKEN_H
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Navigation Abstract Base Class
+//
+//  Author:   H. Ma, S. Rajagopalan, P. Loch
+//
+//  This class is the base class for the templated NavigationToken class. A
+//  method pushQuery(INavigable&) allows to terminate navigation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+class INavigable;
+
+namespace boost {
+  class any; 
+}
+
+class INavigationToken
+{
+ public:
+
+  virtual ~INavigationToken();
+
+  // check if query must be forwarded
+  virtual bool pushQuery( const INavigable& parent,
+			  const INavigable& child ) = 0;
+
+  // 
+  virtual bool trySetObject(const INavigable* child) = 0;
+  virtual bool trySetObject(const INavigable* child,
+			    const boost::any& relPar) = 0; 
+
+};
+#endif
+
+

Navigation/Navigable.h

+#ifndef NAVIGATION_NAVIGABLE_H
+#define NAVIGATION_NAVIGABLE_H
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//              Generalization of Navigable Object Features                  //
+//                                                                           //
+// File:     Control/Navigation/Navigable.h                                  //
+// Authors:  P. Calafiura, P. Loch, S. Rajagopalan                           //
+// Comments: Implements navigation query with honoring or forwarding the     //
+//           client request for a given object type. The actual              //
+//           implementation is in Navigable.icc                              //
+//                                                                           //
+// Created:  07-Oct-03  Calafiura/Loch/Rajagopalan                           //
+// Update:   18-Dec-03  Loch                                                 //
+//                      - implement ElementLink -> change of template        //
+//                        parameters necessary!                              //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+ 
+/** @class Navigable
+ * @brief  a template helper to implement INavigable. Holds
+ *         the container of children
+ *
+ * @author ATLAS Collaboration
+ * $Id: Navigable.h,v 1.1.1.1 2004-02-10 18:11:52 lochp Exp $
+ **/
+
+// package includes
+#include "Navigation/INavigable.h"
+#include "Navigation/INavigationToken.h"
+#include "Navigation/NavigationToken.h"
+#include "Navigation/DefaultWeight.h"
+#include "Navigation/DefaultChildColl.h"
+
+// services etc.
+#ifndef DATAMODEL_TOOLS_GENERATEINDEXINGPOLICY_H
+# include "DataModel/tools/GenerateIndexingPolicy.h"
+#endif
+
+// STL includes
+#include <vector>
+#include <map>
+#include <utility>  // pair
+
+// boost include (pointer arbitration)
+#include <boost/any.hpp>
+
+////////////////////////////////////////////////////////////////
+// Base class for implementation of Navigation token handling //
+////////////////////////////////////////////////////////////////
+
+// do-nothing class for Navigation termination implementation
+class NavTerminator{};
+
+template <typename CHILDCONTAINER=NavTerminator, 
+	  typename CHILDPAR=DefaultWeight,
+          typename CHILDCOLL=typename 
+	  DefaultChildColl<CHILDCONTAINER, CHILDPAR>::type >
+class Navigable : virtual public INavigable 
+{
+  public:
+
+  //////////////////////
+  // Type definitions //
+  //////////////////////
+
+  typedef CHILDCOLL                           child_coll;
+  typedef typename child_coll::iterator       child_iter;
+  typedef typename child_coll::const_iterator const_child_iter;
+  typedef typename CHILDCONTAINER::value_type child_type
+
+  /////////////////////////////////
+  // Constructors and Destructor //
+  /////////////////////////////////
+
+  Navigable();
+
+  virtual ~Navigable();
+
+  ////////////////////////////////////////////////////////////////////
+  // NavigationToken handling (INavigable interface implementation) //
+  ////////////////////////////////////////////////////////////////////
+
+  // no relational parameters
+  virtual void fillToken(INavigationToken& rTok) const;
+  // forwarding of parameters included
+  virtual void fillToken(INavigationToken& rTok, 
+			 const boost::any& parentParm) const;
+
+  //////////////////////////////////
+  // Add data objects or elements //
+  //////////////////////////////////
+
+  // add data object to the Navigable: replaces existing one (FIXME)
+  //  virtual void putDataObj(const CHILD* aChild, 
+  //			  const CHILDPAR& aPar=CHILDPAR());
+  // add element to the Navigable: use element pointer (linear search!)
+  void putElement(const CHILDCONTAINER& objCont, 
+		  const child_type* aChild,
+		  const CHILDPAR& aPar=CHILDPAR());
+  // add element to the Navigable: use element index (direct access!)
+  void putElement(const CHILDCONTAINER& objCont, 
+		  typename SG::GenerateIndexingPolicy<CHILDCONTAINER>::type::index_type index,
+		  const CHILDPAR& aPar=CHILDPAR());
+
+  ///////////////////////
+  // Data manipulation //
+  ///////////////////////
+
+  // remove object from the Navigable
+  bool remove(const child_type* aChild);
+
+  // check if child is already there  
+  bool contains(const child_type* aChild) const;
+
+  // get the associated parameter if any
+  const CHILDPAR& getParameter(const child_type* aChild) const;
+
+  ///////////////////////////
+  // Protected data access //
+  ///////////////////////////
+
+  protected:
+
+  // get collection of children
+  const child_coll& getChildren() const { return m_children; }
+  child_coll& getChildren() { return m_children; }
+
+  // get pointer to child given its collection iterator 
+  virtual const child_type* 
+  getChildPtr(const_child_iter iter) const;
+
+  // get the parameter associated with the child, if any
+  virtual CHILDPAR getChildPar(const_child_iter iter) const;
+
+  /////////////////////////////
+  // Internal query handling //
+  /////////////////////////////
+
+  private:
+
+  // honoring the query: filling the token if we match the token type
+  virtual void apply(NavigationToken<typename child_type>& 
+		     rTok) const;    // w/o parameters
+  virtual void apply(NavigationToken<typename child_type, 
+		     CHILDPAR>& rTok, // w/  parameters
+		     const CHILDPAR& aPar) const;
+
+  ///forwarding the query to children
+  virtual void toKids(INavigationToken& rTok) const;         // w/o parameters
+  virtual void toKids(INavigationToken& rTok,                // w/ parameters
+		      const boost::any& aPar) const;
+
+  ///////////////////////////
+  // Internal data storage //
+  ///////////////////////////
+
+  private:
+
+  child_coll m_children;
+
+};
+
+//////////////////////////
+// Termination handling //
+//////////////////////////
+
+// dummy type for dummy child collections
+class ErrorType{};
+
+template<>
+class Navigable<NavTerminator> : public INavigable 
+{
+ public:
+
+  // suppress compiler warnings
+  typedef ErrorType child_coll;
+  typedef ErrorType child_iter;
+
+  Navigable() { }
+  virtual ~Navigable() { }
+
+  // implement INavigable::fillToken(...) as "do-nothing"
+  virtual void fillToken( INavigationToken & ) const { }
+  virtual void fillToken( INavigationToken &, const boost::any& ) const { }
+};
+
+//////////////////////////////
+// Navigable implementation //
+//////////////////////////////
+
+#include "Navigation/Navigable.icc"
+
+#endif

Navigation/Navigable.icc

+//////////////////////////////
+// Navigable implementation //
+//////////////////////////////
+
+// constructor
+template <typename CHILDCONTAINER, typename CHILDPAR, typename CHILDCOLL>
+Navigable<CHILDCONTAINER,CHILDPAR,CHILDCOLL>::Navigable() { }
+
+// destructor
+template <typename CHILDCONTAINER, typename CHILDPAR, typename CHILDCOLL>
+Navigable<CHILDCONTAINER,CHILDPAR,CHILDCOLL>::~Navigable() { }
+
+//////////////////////////////////////////////
+// Navigation query handling w/o parameters //
+//////////////////////////////////////////////
+
+template <typename CHILDCONTAINER, typename CHILDPAR, typename CHILDCOLL>
+void 
+Navigable<CHILDCONTAINER, CHILDPAR, CHILDCOLL>::fillToken(INavigationToken& 
+							  token) const
+{
+  // check on request for CHILD type objects
+  NavigationToken<typename child_type>* pNoWTok = 
+    dynamic_cast< NavigationToken<typename child_type>* > 
+    (&token);
+
+  // honored: fill children object pointers into token
+  if (0 != pNoWTok) 
+    { 
+      apply(*pNoWTok);
+    } 
+  // wrong object type requested
+  else 
+    {
+      // check if query formulated with parameter type
+      NavigationToken<typename child_type, CHILDPAR>* pWTok = 
+	dynamic_cast< NavigationToken<typename child_type, CHILDPAR>* > 
+	(&token);
+
+      // honored: fill children object pointers and parameters into token
+      if (0 != pWTok) 
+	{
+	  apply(*pWTok, CHILDPAR());
+
+	}
+    }
+
+  // forward query
+  toKids(token);
+}
+
+/////////////////////////////////////////////
+// Navigation query handling w/ parameters //
+/////////////////////////////////////////////
+
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+void 
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::fillToken(INavigationToken& token,
+						 const boost::any& aPar) const 
+{
+  //  cout << "calling weighted fill token" <<endl;
+
+  // first check on object type query alone
+  NavigationToken<CHILD>* pNoWTok =
+    dynamic_cast< NavigationToken<CHILD>* > (&token);
+
+  // honored
+  if (0 != pNoWTok) 
+    { 
+      apply(*pNoWTok);
+    } 
+  // not this request, check with parameter
+  else 
+    {
+      NavigationToken<CHILD, CHILDPAR>* pWTok = 
+	dynamic_cast< NavigationToken<CHILD, CHILDPAR>* > (&token);
+      if (0 != pWTok) 
+	{
+	  apply(*pWTok, boost::any_cast<CHILDPAR>(aPar));
+	}
+    }
+
+  // forward query in any case
+  toKids(token, aPar);
+}
+
+//////////////////////////
+// Query can be honored //
+//////////////////////////
+
+// fill token with object pointers (no parameters)
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+void 
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::apply(NavigationToken<CHILD>&
+					     rTok) const 
+{
+  //  cout << "calling apply" <<endl;
+
+  // loop on children
+  const_child_iter iter(getChildren().begin());
+  const_child_iter iend(getChildren().end());
+  for (; iter != iend; ++iter) {
+    rTok.setObject(getChildPtr(iter));
+  }
+}
+
+// fill with parameter
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+void 
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::apply(NavigationToken<CHILD, CHILDPAR>&
+					     rTok, const CHILDPAR& aPar) const 
+{
+  //  cout << "calling apply" <<endl;
+
+  // loop children
+  const_child_iter iter(getChildren().begin());
+  const_child_iter iend(getChildren().end());
+  for (; iter != iend; ++iter) {
+    rTok.setObject(getChildPtr(iter), aPar * getChildPar(iter));
+  }
+}
+
+//////////////////////
+// Forwarding query //
+//////////////////////
+
+// no parameter
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+void 
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::toKids(INavigationToken& token) const 
+{
+  //  cout << "calling toKids" <<endl;
+
+  // loop on children
+  const_child_iter iter(getChildren().begin());
+  const_child_iter iend(getChildren().end());
+  for (; iter != iend; ++iter) {
+    //    if (token.pushQuery(*this, *getChildPtr(iter))) 
+    token.trySetObject(getChildPtr(iter)); // navigating inheritance
+    getChildPtr(iter)->fillToken(token);   // forward query
+  }
+}
+
+// with parameter
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+void 
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::toKids(INavigationToken& token,
+					      const boost::any& aPar) const 
+{
+  //  cout << "calling toKids" <<endl;
+
+  // loop on children
+  const_child_iter iter(getChildren().begin());
+  const_child_iter iend(getChildren().end());
+  // catch exception thrown by boost::any_cast 
+  try {
+    // only identical parameter types can be forwarded!
+    CHILDPAR parentWeight(boost::any_cast<CHILDPAR>(aPar));
+    for (; iter != iend; ++iter) 
+      {
+      //      if (token.pushQuery(*this, *getChildPtr(iter))) 
+	token.trySetObject(getChildPtr(iter),
+			   boost::any(parentWeight * getChildPar(iter)));
+	getChildPtr(iter)->fillToken(token, 
+				   parentWeight * getChildPar(iter)); 
+      } 
+  } catch(...) {
+    // parameter type mismatch: terminate parameter forwarding only
+    for (; iter != iend; ++iter) {
+      //      if (token.pushQuery(*this, *getChildPtr(iter))) 
+      getChildPtr(iter)->fillToken(token, aPar); //FIXME no weight?
+    }
+  }
+}
+
+///////////////////////////////////
+// Internal data object handling //
+///////////////////////////////////
+
+// access data objects by iterator
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+const CHILD*
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::getChildPtr(const_child_iter iter) const
+{ 
+  //  cout << "calling getChildPtr" <<endl;
+  return DefaultChildColl<CHILD, CHILDPAR>::getChildPtr(iter); 
+}
+
+// access relational parameter by iterator
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+CHILDPAR
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::getChildPar(const_child_iter iter) const
+{ 
+  //  cout << "calling getChildPtr" <<endl;
+  return DefaultChildColl<CHILD, CHILDPAR>::getChildPar(iter); 
+}
+
+// insert data objects
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+void
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::putDataObj(const CHILD* aChild, 
+						  const CHILDPAR& aPar) 
+{
+  DefaultChildColl<CHILD, CHILDPAR>::insert(getChildren(), aChild, aPar);
+}
+
+// insert data element
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+template <class DOBJCONTAINER>
+void
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::putElement(const 
+						  DOBJCONTAINER* /*dObj*/, 
+						  const CHILD* aChild, 
+						  const CHILDPAR& aPar) 
+{
+  //  to be fixed: just insert data object for the moment
+  DefaultChildColl<CHILD, CHILDPAR>::insert(getChildren(), aChild, aPar);
+}
+
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+template <class DOBJCONTAINER>
+void 
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::putElement(const 
+						  DOBJCONTAINER* /*dObj*/, 
+						  typename SG::GenerateIndexingPolicy<DOBJCONTAINER>::type::index_type /*index*/,
+						  const CHILDPAR& 
+						  /*aPar=CHILDPAR()*/)
+{
+  // to be fixed: no action in the moment
+}
+
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+bool
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::remove(const CHILD* aChild)
+{
+  if ( this->contains(aChild) ) 
+    {
+      Navigable<CHILD,CHILDPAR,CHILDCOLL>::child_coll theCollection =
+	this->getChildren();
+      theCollection.erase(DefaultChildColl<CHILD,CHILDPAR>::find(getChildren(),
+								 aChild));
+      return true;
+    }
+  return false;
+}
+
+template <typename CHILD, typename CHILDPAR, typename CHILDCOLL>
+bool
+Navigable<CHILD, CHILDPAR, CHILDCOLL>::
+contains(const CHILD* aChild) const
+{
+  return DefaultChildColl<CHILD, CHILDPAR>::find(getChildren(),aChild) 
+    != getChildren().end() ;
+}

Navigation/NavigationToken.h

+#ifndef NAVIGATIONTOKEN_H
+#define NAVIGATIONTOKEN_H
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Navigation Token Template Class
+//
+//  Comments: (P.Loch, January 15, 2003)
+//
+//  The basic idea of the system is that each composite object can be queried
+//  for constituents of one (or many) given object types. If this query can 
+//  be honored, pointers to the constituent objects are stored in the token,
+//  together with a kinematic weight. Otherwise the query is forwarded, if
+//  the constituent objects are of composite nature themselves.
+//  
+///////////////////////////////////////////////////////////////////////////////
+
+#include "Navigation/INavigationToken.h"
+#include "Navigation/INavigable.h"
+
+#include "Navigation/INavigationSelector.h"
+#include "Navigation/INavigationCondition.h"
+
+#include "Navigation/DefaultWeight.h"
+
+#include <map>
+#include <list>
+
+#include <boost/any.hpp>
+
+template <typename CHILD, typename CHILDPAR=DefaultWeight>
+class NavigationToken : public INavigationToken
+{
+
+ public:
+
+ typedef std::map<const CHILD*, CHILDPAR>    tokenStore; 
+ typedef typename tokenStore::iterator       tokenIterator;
+ typedef typename tokenStore::const_iterator tokenConstIterator;
+
+ //////////////////////////////////
+ // Constructors and destructors //
+ //////////////////////////////////
+
+ // default constructor
+ NavigationToken() : 
+   m_navCondition(0),
+   m_navSelector(0)
+   { };
+
+ // constructor with navigation selector argument
+ NavigationToken( const INavigationSelector<CHILD>* thisSelector ) :
+   m_navCondition(0),
+   m_navSelector(thisSelector)
+   { };
+
+ // constructor with navigation condition argument
+ NavigationToken( const INavigationCondition* thisCondition ) :
+   m_navCondition(thisCondition),
+   m_navSelector(0)
+   { };
+
+ // constructor with navigation condition and selector
+ NavigationToken( const INavigationSelector<CHILD>* thisSelector, 
+		  const INavigationCondition* thisCondition ) :
+   m_navCondition(thisCondition),
+   m_navSelector(thisSelector)
+   { };
+
+ // destructor
+ virtual ~NavigationToken() 
+ { }
+
+ /////////////////////
+ // Fill conditions //
+ /////////////////////
+
+ // check if query is to be forwarded
+ virtual bool pushQuery( const INavigable& parent, 
+			 const INavigable& /* child */ );
+
+ //////////////////////////////////////////////////////
+ // Access to object containers and objects in Token //
+ //////////////////////////////////////////////////////
+
+ // return reference to object store (map)
+ const tokenStore& objectMap() { return m_data; };
+
+ // return pointer to object store
+ // tokenStore const * operator->() { return &m_data; };
+
+ // return iterators for object access (obsolete - no list anymore) 
+ // tokenListIterator  firstObject() { return m_list.begin(); };
+ // tokenListIterator  lastObject()  { return m_list.end(); };
+
+ // return iterators for object and weight access
+ tokenConstIterator firstMappedObject() { return m_data.begin(); };
+ tokenConstIterator lastMappedObject()  { return m_data.end(); };
+
+ // return weight for a given object in container
+ const CHILDPAR& getParameter( const CHILD* data );
+  
+ // clear/reset token
+ void clear();
+ void reset() { this->clear(); }
+
+ // find out if a certain object is stored in the token
+ bool contains( const CHILD* data ) 
+   { 
+     return ( m_data.find(data) != m_data.end() );
+   }
+
+ ///////////////////////
+ // Store object data //
+ ///////////////////////
+
+ // objects with default weight
+ void setObject( const CHILD* data )
+   {
+     this->setObject( data, CHILDPAR() );
+   }
+
+ // objects with variable weight FIXME!!!!!!!!!!
+ void setObject( const CHILD* data, CHILDPAR weight );
+
+ // check if queried object is of requested type itself
+ virtual bool trySetObject( const INavigable* theObject );
+
+ virtual bool trySetObject( const INavigable* theObject,
+			    const boost::any& theWeight);
+
+
+ ////////////////////////////////
+ // Operations on Token object //
+ ////////////////////////////////
+
+ // copy operator
+ NavigationToken& operator=(const NavigationToken & anotherToken)
+ {
+   if ( anotherToken.m_data != 0 )
+     {
+       m_data         = anotherToken.m_data;
+       m_navCondition = anotherToken.m_navCondition; 
+       m_navSelector  = anotherToken.m_navSelector;
+     }   
+   return *this;
+ }
+
+ private:
+  
+ tokenStore  m_data;
+
+ // internal pointer to associated navigation processor
+ const INavigationCondition*       m_navCondition;
+ const INavigationSelector<CHILD>* m_navSelector;
+
+};
+
+#include "Navigation/NavigationToken.icc"
+
+#endif
+

Navigation/NavigationToken.icc

+////////////////////////////////////
+// NavigationToken Implementation //
+////////////////////////////////////
+
+// query depth control
+template<typename CHILD, typename CHILDPAR>
+bool NavigationToken<CHILD,CHILDPAR>::pushQuery(const INavigable& parent, 
+						const INavigable& /* child */ )
+{
+  return ( m_navCondition != 0 )
+    ? ( m_navCondition->accept(&parent) )
+    : true;
+}
+
+// relational parameter access
+template<typename CHILD, typename CHILDPAR>
+const CHILDPAR& 
+NavigationToken<CHILD,CHILDPAR>::getParameter(const CHILD* data )
+{
+  NavigationToken<CHILD,CHILDPAR>::tokenIterator found = m_data.find(data);
+  return ( found != m_data.end() 
+	   ? (*found).second 
+	   : CHILDPAR() ); 
+}
+
+  
+// clear/reset token
+template <typename CHILD, typename CHILDPAR>
+void NavigationToken<CHILD,CHILDPAR>::clear()
+{
+  m_data.clear();
+  if ( m_navSelector  != 0 ) m_navSelector->reset();
+  if ( m_navCondition != 0 ) m_navCondition->reset();
+}
+
+// set object in token
+template <typename CHILD, typename CHILDPAR>
+void NavigationToken<CHILD,CHILDPAR>::setObject(const CHILD* data, 
+						CHILDPAR weight )
+{
+  // check pointer validity
+  if ( data != 0 )
+    {
+      if ( m_navSelector == 0 ||
+	   ( m_navSelector !=0  && 
+	     m_navSelector->accept(data, weight) ) )
+	{
+	  // important: add weights!
+	  if ( m_data.find(data) != m_data.end() )
+	    {
+	      m_data[data] = m_data[data] + weight;
+	    }
+	  else
+	    {
+	      m_data[data] = weight;
+	    }
+	}
+    }
+}
+
+// check if queried object is of requested type itself
+template <typename CHILD, typename CHILDPAR>
+bool NavigationToken<CHILD,CHILDPAR>::trySetObject(const INavigable* theObject)
+{
+  const CHILD* thePtr = dynamic_cast<const CHILD*>(theObject);
+  if ( thePtr != 0 ) 
+    {
+      this->setObject(thePtr);
+      return true;
+    }
+  
+  return false;
+}
+
+// check if queried object is of requested type itself, including parameters
+template <typename CHILD, typename CHILDPAR> 
+bool NavigationToken<CHILD,CHILDPAR>::trySetObject(const INavigable* theObject,
+						   const boost::any& theWeight)
+{
+  const CHILD* thePtr = dynamic_cast<const CHILD*>(theObject);
+  try {
+    CHILDPAR myWeight(boost::any_cast<CHILDPAR>(theWeight));
+    if ( thePtr != 0 ) 
+      {
+	setObject(thePtr,myWeight);
+	return true;
+      }
+  } catch(...) { }
+  return false;
+}
+
+package Navigation
+
+author Peter Loch <loch@physics.arizona.edu>
+
+use DataModel DataModel-* Control
+
+# apply_pattern dual_use_library *.cxx