Source

mana-core-navigation / Navigation / Navigable.icc

Full commit
//////////////////////////////
// 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() ;
}