text:
/**************************************************************************\
 * Copyright (c) Kongsberg Oil & Gas Technologies AS
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * Neither the name of the copyright holder nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\**************************************************************************/

/*!
  \class ScXMLStateMachine ScXMLStateMachine.h Inventor/scxml/ScXMLStateMachine.h
  \brief Manager for processing events and setting states in SCXML structures.

  \since Coin 3.0
  \ingroup coin_scxml
*/

#include <Inventor/scxml/ScXMLStateMachine.h>

#ifdef _MSC_VER
#pragma warning(disable:4786) // symbol truncated
#endif // _MSC_VER

#include <cassert>
#include <cstring>
#include <algorithm>
#include <list>
#include <map>
#include <vector>

#include <boost/scoped_ptr.hpp>

#include <Inventor/errors/SoDebugError.h>

#include <Inventor/scxml/ScXML.h>
#include <Inventor/scxml/ScXMLEvent.h>
#include <Inventor/scxml/ScXMLDocument.h>

#include <Inventor/scxml/ScXMLScxmlElt.h>
#include <Inventor/scxml/ScXMLInvokeElt.h>
#include <Inventor/scxml/ScXMLStateElt.h>
#include <Inventor/scxml/ScXMLParallelElt.h>
#include <Inventor/scxml/ScXMLInitialElt.h>
#include <Inventor/scxml/ScXMLFinalElt.h>
#include <Inventor/scxml/ScXMLOnEntryElt.h>
#include <Inventor/scxml/ScXMLOnExitElt.h>
#include <Inventor/scxml/ScXMLTransitionElt.h>
#include <Inventor/scxml/ScXMLAnchorElt.h>
#include <Inventor/scxml/ScXMLHistoryElt.h>
#include <Inventor/scxml/ScXMLLogElt.h>
#include <Inventor/scxml/ScXMLSendElt.h>
#include <Inventor/scxml/ScXMLMinimumEvaluator.h>
#include <Inventor/scxml/ScXMLCoinEvaluator.h>
#include "scxml/ScXMLP.h"
#include "misc/SbHash.h"

// *************************************************************************

/*!
  \typedef void ScXMLStateMachineDeleteCB(void * userdata, ScXMLStateMachine * statemachine);

  This is the type definition for all callback functions to be invoked when a state machine
  is deleted.

  \typedef void ScXMLParallelStateChangeCB(void * userdata,
                                        ScXMLStateMachine * statemachine,
                                        int numstates,
                                        const char ** stateidentifiers,
                                        SbBool enterstate,
                                        SbBool success);

  This typedef is currently unused.

*/

// *************************************************************************

struct EventInfo {
  const ScXMLEvent * eventptr;
  SbBool deallocate;
};

class ScXMLStateMachine::PImpl {
public:
  PImpl(void)
    : pub(NULL),
      active(FALSE), finished(FALSE),
      name(SbName::empty()), sessionid(SbName::empty()),
      loglevel(3),
      description(NULL),
      evaluator(NULL),
      initializer(NULL)
  {
  }

  ~PImpl(void)
  {
    delete this->description;
    this->description = NULL;
  }

  ScXMLStateMachine * pub;

  SbBool active;
  SbBool finished;

  SbName name;
  SbName sessionid;
  int loglevel;
  ScXMLDocument * description;
  ScXMLEvaluator * evaluator;

  SbList<const char *> modules;

  mutable SbString varstring;

  // delete callbacks:
  typedef std::pair<ScXMLStateMachineDeleteCB *, void *> DeleteCBInfo;
  typedef std::vector<DeleteCBInfo> DeleteCallbackList;
  DeleteCallbackList deletecallbacklist;
  void invokeDeleteCallbacks(void);

  // state change callbacks:
  typedef std::pair<ScXMLStateChangeCB *, void *> StateChangeCBInfo;
  typedef std::vector<StateChangeCBInfo> StateChangeCallbackList;
  StateChangeCallbackList statechangecallbacklist;
  void invokeStateChangeCallbacks(const char * identifier, SbBool enterstate);

  boost::scoped_ptr<ScXMLTransitionElt> initializer;

  std::vector<ScXMLElt *> activestatelist;

  typedef std::pair<ScXMLElt *, ScXMLTransitionElt *> StateTransition;
  typedef std::vector<StateTransition> TransitionList;

  void findTransitions(TransitionList & transitions, ScXMLElt * stateobj, const ScXMLEvent * event);

  void exitState(ScXMLElt * object);
  void enterState(ScXMLElt * object);

  static long nextsessionid;
  static SbHash<const char *, ScXMLStateMachine *> * sessiondictionary;
}; // ScXMLStateMachine::PImpl

SbHash<const char *, ScXMLStateMachine *> * ScXMLStateMachine::PImpl::sessiondictionary = NULL;
long ScXMLStateMachine::PImpl::nextsessionid = 0;

// *************************************************************************

#define PRIVATE(obj) ((obj)->pimpl)
#define PUBLIC(obj) ((obj)->pub)

SCXML_OBJECT_SOURCE(ScXMLStateMachine);

void
ScXMLStateMachine::initClass(void)
{
  SCXML_OBJECT_INIT_CLASS(ScXMLStateMachine, ScXMLEventTarget, "ScXMLEventTarget");
  ScXMLStateMachine::PImpl::nextsessionid = 1;
  ScXMLStateMachine::PImpl::sessiondictionary =
    new SbHash<const char *, ScXMLStateMachine *>;
}

void
ScXMLStateMachine::cleanClass(void)
{
  ScXMLStateMachine::PImpl::nextsessionid = 0;
  delete ScXMLStateMachine::PImpl::sessiondictionary;
  ScXMLStateMachine::PImpl::sessiondictionary = NULL;
  ScXMLStateMachine::classTypeId = SoType::badType();
}

ScXMLStateMachine *
ScXMLStateMachine::getStateMachineForSessionId(const SbName & sessionid)
{
  if (sessionid == SbName::empty()) {
    return NULL;
  }
  const char * id = sessionid.getString();
  ScXMLStateMachine * statemachine = NULL;
  if (!ScXMLStateMachine::PImpl::sessiondictionary->get(id, statemachine)) {
    return NULL;
  }
  return statemachine;
}

ScXMLStateMachine::ScXMLStateMachine(void)
{
  PRIVATE(this)->pub = this;
  this->setEventTargetType("scxml");
  ScXMLP::lock();
  const long id = ScXMLStateMachine::PImpl::nextsessionid;
  ScXMLStateMachine::PImpl::nextsessionid += 1;
  ScXMLP::unlock();
  char sessionidstr[32];
  sprintf(sessionidstr, "x-coin-scxml-session%03ld", id);
  this->setSessionId(SbName(sessionidstr));
}

ScXMLStateMachine::~ScXMLStateMachine(void)
{
  PRIVATE(this)->invokeDeleteCallbacks();
  this->setSessionId(SbName::empty());
  this->setEnabledModulesList(SbList<const char *>());
}

// *************************************************************************

void
ScXMLStateMachine::setName(const SbName & nameobj)
{
  PRIVATE(this)->name = nameobj;
  this->setEventTargetName(nameobj.getString());
}

const SbName &
ScXMLStateMachine::getName(void) const
{
  return PRIVATE(this)->name;
}

void
ScXMLStateMachine::setDescription(ScXMLDocument * document)
{
  assert(!PRIVATE(this)->active);
  PRIVATE(this)->description = document;
  PRIVATE(this)->initializer.reset(NULL);
  PRIVATE(this)->active = FALSE;
  PRIVATE(this)->finished = FALSE;
  PRIVATE(this)->activestatelist.clear();

  // set up the correct evalutor and identify the modules that are enabled
  ScXMLElt * rootelt = document->getRoot();
  if (rootelt->isOfType(ScXMLScxmlElt::getClassTypeId())) {
    ScXMLScxmlElt * scxmlelt = static_cast<ScXMLScxmlElt *>(rootelt);
    const char * profile = scxmlelt->getProfileAttribute();
    SbName profilename = SbName::empty();
    if (profile) {
      profilename = profile;
    }

   SoType evaluatortype = ScXML::getEvaluatorTypeForProfile(profilename);
   if (evaluatortype != SoType::badType()) {
     assert(evaluatortype.canCreateInstance());
     ScXMLEvaluator * evaluator =
       static_cast<ScXMLEvaluator *>(evaluatortype.createInstance());
     evaluator->setStateMachine(this);
     this->setEvaluator(evaluator);
   }
   else {
     SoDebugError::post("ScXMLStateMachine::setDescription",
                        "No available evaluator for profile '%s'.",
                        profilename.getString());
   }
  }
}

const ScXMLDocument *
ScXMLStateMachine::getDescription(void) const
{
  return PRIVATE(this)->description;
}

/*!
  This sets the session identifier for the state machine.  Using this is
  optional, since state machines are already assigned unique session ids at
  construction-time.
*/
void
ScXMLStateMachine::setSessionId(const SbName & sessionidarg)
{
  if (PRIVATE(this)->sessionid != SbName::empty()) {
    ScXMLStateMachine::PImpl::sessiondictionary->erase(PRIVATE(this)->sessionid.getString());
    PRIVATE(this)->sessionid = SbName::empty();
  }
  if (sessionidarg != SbName::empty()) {
    PRIVATE(this)->sessionid = sessionidarg;
    ScXMLStateMachine::PImpl::sessiondictionary->put(PRIVATE(this)->sessionid.getString(), this);
  }
}

/*!
  Returns the session identifier string for the state machine.
*/
const SbName &
ScXMLStateMachine::getSessionId(void) const
{
  return PRIVATE(this)->sessionid;
}

void
ScXMLStateMachine::setLogLevel(int loglevel)
{
  PRIVATE(this)->loglevel = loglevel;
}

int
ScXMLStateMachine::getLogLevel(void) const
{
  return PRIVATE(this)->loglevel;
}

// *************************************************************************

/*!
  Fire up the engine.
*/
void
ScXMLStateMachine::initialize(void)
{
  assert(!PRIVATE(this)->active);
  PRIVATE(this)->active = TRUE;
  PRIVATE(this)->finished = FALSE;
  PRIVATE(this)->activestatelist.clear();
  this->processOneEvent(NULL); // process the 'initial' initializer
  this->processEventQueue(); // process any pending events from the initial-processing
}

// *************************************************************************

/*!
  Processes one event.
  This is an internal inner event-loop utility function.
*/
SbBool
ScXMLStateMachine::processOneEvent(const ScXMLEvent * event)
{
  // this function seriously needs more structuring
  this->setCurrentEvent(event);

  if (0 /* debug */) {
    if (event)
      SoDebugError::postInfo("ScXMLStateMachine::processOneEvent",
                             "event: %s",
                             event->getEventName().getString());
    else
      SoDebugError::postInfo("ScXMLStateMachine::processOneEvent",
                             "NULL event");
  }

  if (0 /* debug */) {
    std::vector<ScXMLElt *>::iterator it =
      PRIVATE(this)->activestatelist.begin();
    while (it != PRIVATE(this)->activestatelist.end()) {
      SoDebugError::postInfo("ScXMLStateMachine::processOneEvent",
                             "active state: %s", (*it)->getXMLAttribute("id"));
      ++it;
    }
  }

  PImpl::TransitionList transitions;
  if (PRIVATE(this)->activestatelist.size() == 0) {
    if (PRIVATE(this)->initializer.get() == NULL) {
      PRIVATE(this)->initializer.reset(new ScXMLTransitionElt);
      // FIXME
      if (PRIVATE(this)->description->getRoot()->getInitial()) {
      } else {
        PRIVATE(this)->initializer->setTargetAttribute(PRIVATE(this)->description->getRoot()->getInitialAttribute());
      }
    }
    transitions.push_back(PImpl::StateTransition(static_cast<ScXMLElt*>(NULL), PRIVATE(this)->initializer.get()));
  } else {
    for (int c = 0; c < static_cast<int>(PRIVATE(this)->activestatelist.size()); ++c) {
      // containers are also active states and must be checked
      ScXMLElt * stateobj = PRIVATE(this)->activestatelist.at(c);
      while (stateobj != NULL) {
        PRIVATE(this)->findTransitions(transitions, stateobj, event);
        stateobj = stateobj->getContainer();
      }
    }
  }

  // no transitions means no changes, just return
  if (transitions.size() == 0) {
    if (this->getEvaluator())
      this->getEvaluator()->clearTemporaryVariables();
    this->setCurrentEvent(NULL);
    return FALSE;
  }

  // we handle all targetless transitions first
  {
    PImpl::TransitionList::iterator transit = transitions.begin();
    while (transit != transitions.end()) {
      if (transit->second->isTargetLess()) {
        transit->second->execute(this);
      }
      ++transit;
    }
  }

  // handle self-targeting transitions next (not sure this is the right
  // place, but it's not improbable either)...
  {
    PImpl::TransitionList::iterator transit = transitions.begin();
    while (transit != transitions.end()) {
      if (transit->second->isSelfReferencing()) {
        ScXMLElt * containerobj = transit->second->getContainer();
        /*ScXMLAbstractStateElt * targetobj = */PRIVATE(this)->description->getStateById(transit->second->getTargetAttribute());

        if (containerobj->isOfType(ScXMLStateElt::getClassTypeId())) {
          ScXMLStateElt * state = static_cast<ScXMLStateElt *>(containerobj);
          PRIVATE(this)->exitState(state);
          transit->second->execute(this);
          PRIVATE(this)->enterState(state);
        } else {
          transit->second->execute(this);
        }
      }
      ++transit;
    }
  }

  std::vector<ScXMLElt *> newstateslist;

  // handle those with other targets next
  PImpl::TransitionList::iterator transit = transitions.begin();
  while (transit != transitions.end()) {
    if (transit->second->isTargetLess() ||
        transit->second->isSelfReferencing()) {
      ++transit;
      continue;
    }

    const char * targetid = transit->second->getTargetAttribute();
    ScXMLElt * targetstate = PRIVATE(this)->description->getStateById(targetid);
    if (!targetstate) {
      SoDebugError::post("ScXMLStateMachine::processOneEvent",
                         "transition to unknown state '%s' failed.", targetid);
      ++transit;
      continue;
    }

    std::vector<ScXMLElt *> sourcestates;

    ScXMLElt * sourcestate = transit->first;
    if (sourcestate != NULL) { // ignore sourcestate NULL (initializer)
      // find all activestate object contained within source state
      std::vector<ScXMLElt *>::iterator activeit =
        PRIVATE(this)->activestatelist.begin();
      while (activeit != PRIVATE(this)->activestatelist.end()) {
        if ((*activeit)->isContainedIn(sourcestate)) {
          ScXMLElt * active = *activeit;
          sourcestates.push_back(active); // remember, to remove from activelist
          while (active != sourcestate) {
            //SoDebugError::post("process",
            //       "found activestate as substate of transition source");

            PRIVATE(this)->exitState(active); // exit substates of transition point
            active = active->getContainer();
            assert(active);
          }
        }
        ++activeit;
      }

      while (!targetstate->isContainedIn(sourcestate)) {
        //SoDebugError::postInfo("process", "going up to find common ancestor");
        PRIVATE(this)->exitState(sourcestate);
        sourcestate = sourcestate->getContainer();
      }
    }

    // executable content in the transition
    //SoDebugError::postInfo("process", "executing transition code");
    transit->second->execute(this);

    {
      std::vector<ScXMLElt *> path;
      //SoDebugError::postInfo("process", "finding target-path from sourcestate %p",
      //                       sourcestate);
      while (sourcestate != targetstate) {
        path.push_back(targetstate);
        targetstate = targetstate->getContainer();
      }
      targetstate = PRIVATE(this)->description->getStateById(targetid); // restore

      //SoDebugError::postInfo("process", "reversing downward path");
      std::reverse(path.begin(), path.end());

      std::vector<ScXMLElt *>::iterator pathit = path.begin();
      while (pathit != path.end()) {
        // SoDebugError::postInfo("process", "entering down towards target");
        PRIVATE(this)->enterState(*pathit);
        ++pathit;
      }
    }

    //SoDebugError::post("process", "list of source states to remove - %d",
    //                   sourcestates.size());
    // remove source states form activestates
    std::vector<ScXMLElt *>::iterator it = sourcestates.begin();
    while (it != sourcestates.end()) {
      std::vector<ScXMLElt *>::iterator findit =
        std::find(PRIVATE(this)->activestatelist.begin(),
                  PRIVATE(this)->activestatelist.end(), *it);
      if (findit != PRIVATE(this)->activestatelist.end()) {
        //SoDebugError::post("process", "erasing old activestate");
        PRIVATE(this)->activestatelist.erase(findit);
      } else {
        SoDebugError::post("ScXMLStateMachine::processOneEvent",
                           "source state not found in activestate list");
      }
      ++it;
    }

    // add targetstate to active states
    if (std::find(PRIVATE(this)->activestatelist.begin(), PRIVATE(this)->activestatelist.end(), targetstate) == PRIVATE(this)->activestatelist.end()) {
      newstateslist.push_back(targetstate);
    }

    ++transit;
  }

  //SoDebugError::postInfo("process", "new states to potentially append to activestates: %d",
  //                       newstateslist.size());

  // inspect target states for substates + <initial> children
  std::vector<ScXMLElt *>::iterator appendit = newstateslist.begin();
  while (appendit != newstateslist.end()) {
    SbBool pushedsubstate = FALSE;
    ScXMLElt * newstate = *appendit;

    SbBool settled = FALSE;
    while (!settled) {
      settled = TRUE;
      if (newstate->isOfType(ScXMLStateElt::getClassTypeId())) {
        ScXMLStateElt * state = static_cast<ScXMLStateElt *>(newstate);
        if (state->getNumStates() > 0 || state->getNumParallels() > 0) {
          do {
            const ScXMLInitialElt * initial = state->getInitial();
            if (!initial) {
              SoDebugError::post("ScXMLStateMachine::processOneEvent",
                                 "state '%s' has substates but no <initial>.",
                                 state->getIdAttribute());
              break;
            }
            ScXMLTransitionElt * transition = initial->getTransition();
            if (!transition) {
              SoDebugError::post("ScXMLStateMachine::processOneEvent",
                                 "state '%s' has <initial> without a transition.",
                                 state->getIdAttribute());
              break;
            }
            const char * targetid = transition->getTargetAttribute();
            if (!targetid) {
              SoDebugError::post("ScXMLStateMachine::processOneEvent",
                                 "state '%s' has <initial> with a targetless transition.",
                                 state->getIdAttribute());
              break;
            }
            ScXMLElt * targetobj = PRIVATE(this)->description->getStateById(targetid);
            if (!targetobj) {
              SoDebugError::post("ScXMLStateMachine::processOneEvent",
                                 "could not find target of state \"%s\"'s <initial> transition.",
                                 state->getIdAttribute());
              break;
            }

            if (targetobj->getContainer() != state) {
              SoDebugError::post("ScXMLStateMachine::processOneEvent",
                                 "target of state \"%s\"'s <initial> transition is not an immediate child of the state",
                                 state->getIdAttribute());
              break;
            }

            // perform executable code
            transition->execute(this);

            PRIVATE(this)->enterState(targetobj);

            newstate = targetobj;
            settled = FALSE; // need to loop over on new state one more time
          } while ( FALSE );

        } else {
          // no substates in this state - can be marked as the deepest active state
          if (state->getInitial()) { // just checking
            SoDebugError::post("ScXMLStateMachine::processOneEvent",
                               "state '%s' has <initial> but no sub-states.",
                               state->getIdAttribute());
          }

          PRIVATE(this)->activestatelist.push_back(state);
          pushedsubstate = TRUE; // need to avoid adding parent state before doing outer loop
          ++appendit;
        }
      } else {
        // non-ScXMLStateElt object (ScXMLFinalElt for instance)
        if (newstate != *appendit) {
          PRIVATE(this)->activestatelist.push_back(newstate);
          pushedsubstate = TRUE; // need to avoid adding parent state before doing outer loop
          ++appendit;
        }
      }
    }
    if (!pushedsubstate) {
      PRIVATE(this)->activestatelist.push_back(*appendit);
      ++appendit;
    }
  }

  // if all active states are <final> states of the root scxml element,
  // we should set 'finished' to true and stop/hinder event processing

  if (this->getEvaluator())
    this->getEvaluator()->clearTemporaryVariables();
  this->setCurrentEvent(NULL);
  return TRUE; // transitions have been taken
}

// *************************************************************************

/*!
  Returns whether the state machine is active or not.
*/
SbBool
ScXMLStateMachine::isActive(void) const
{
  return PRIVATE(this)->active;
}

/*!
  Returns whether the state machine has run to completion or not.
*/
SbBool
ScXMLStateMachine::isFinished(void) const
{
  return PRIVATE(this)->finished;
}

// *************************************************************************

/*!
  This method returns the current event during event processing, and \c NULL
  when not processing events.

  Event processing is in special cases done with \c NULL as the current event,
  as for instance during state machine initialization.
*/

// *************************************************************************

/*!
  Returns the number of active states in the state machine.  This number
  should currently be 1, but in the future, when <parallel> is implemented,
  it can be greater.
*/
int
ScXMLStateMachine::getNumActiveStates(void) const
{
  return static_cast<int>(PRIVATE(this)->activestatelist.size());
}

/*!
  Returns the Nth active state.
*/
const ScXMLElt *
ScXMLStateMachine::getActiveState(int idx) const
{
  assert(idx >= 0 && idx < static_cast<int>(PRIVATE(this)->activestatelist.size()));
  return PRIVATE(this)->activestatelist.at(idx);
}

// *************************************************************************

/*!
  Registers a callback to be called when the state machine object is being
  deleted.
*/
void
ScXMLStateMachine::addDeleteCallback(ScXMLStateMachineDeleteCB * cb, void * userdata)
{
  PRIVATE(this)->deletecallbacklist.push_back(PImpl::DeleteCBInfo(cb, userdata));
}

/*!
  Unregisters a callback to be called when the state machine object is being
  deleted.
*/
void
ScXMLStateMachine::removeDeleteCallback(ScXMLStateMachineDeleteCB * cb, void * userdata)
{
  PImpl::DeleteCallbackList::iterator it =
    std::find(PRIVATE(this)->deletecallbacklist.begin(),
              PRIVATE(this)->deletecallbacklist.end(),
              PImpl::DeleteCBInfo(cb, userdata));
  if (it != PRIVATE(this)->deletecallbacklist.end()) {
    PRIVATE(this)->deletecallbacklist.erase(it);
  }
}

/*
  Invoke all the delete callbacks.
*/

void
ScXMLStateMachine::PImpl::invokeDeleteCallbacks(void)
{
  DeleteCallbackList::const_iterator it = this->deletecallbacklist.begin();
  while (it != this->deletecallbacklist.end()) {
    (it->first)(it->second, PUBLIC(this));
    ++it;
  }
}

// *************************************************************************

/*!
  \var ScXMLStateChangeCB

  This callback type is for notifying listeners on when the state machine
  enters and exits states that are tagged as "tasks" for logging purposes.
  This is what the Boolean "task" attribute in the state element sets up.

  The \a success argument is currently unsupported (will always be TRUE),
  but has been preemptively added to avoid a signature change later.

  \sa addStateChangeCallback
*/

/*!
  Registers a callback to be called when the state machine exits or enters
  a state.
*/
void
ScXMLStateMachine::addStateChangeCallback(ScXMLStateChangeCB * callback, void * userdata)
{
  PRIVATE(this)->statechangecallbacklist.push_back(PImpl::StateChangeCBInfo(callback, userdata));
}

/*!
  Unregisters a callback to be called when the state machine exits or enters
  a state.
*/
void
ScXMLStateMachine::removeStateChangeCallback(ScXMLStateChangeCB * callback, void * userdata)
{
  PImpl::StateChangeCallbackList::iterator findit =
    std::find(PRIVATE(this)->statechangecallbacklist.begin(),
              PRIVATE(this)->statechangecallbacklist.end(),
              PImpl::StateChangeCBInfo(callback, userdata));
  if (findit != PRIVATE(this)->statechangecallbacklist.end()) {
    PRIVATE(this)->statechangecallbacklist.erase(findit);
  }
}

/*
  Invoke all the state change callbacks.
*/
void
ScXMLStateMachine::PImpl::invokeStateChangeCallbacks(const char * identifier, SbBool enterstate)
{
  StateChangeCallbackList::const_iterator it =
    this->statechangecallbacklist.begin();
  while (it != this->statechangecallbacklist.end()) {
    (it->first)(it->second, PUBLIC(this), identifier, enterstate, TRUE);
    ++it;
  }
}

// *************************************************************************

void
ScXMLStateMachine::setVariable(const char * name, const char * COIN_UNUSED_ARG(value))
{
  assert(name);
  if (name[0] == '_') { // reserved system variables
    // core reserved names
    if (strcmp(name, "_name") == 0) {
      SoDebugError::post("ScXMLStateMachine::setVariable",
                         "Name '%s' is a reserved system variable.", name);
    }
    else if (strcmp(name, "_sessionID") == 0) {
      SoDebugError::post("ScXMLStateMachine::setVariable",
                         "Name '%s' is a reserved system variable.", name);
    }
    else if (strcmp(name, "_event") == 0 ||
             strncmp(name, "_event.", 7) == 0) {
      SoDebugError::post("ScXMLStateMachine::setVariable",
                         "Name '%s' is a reserved system variable.", name);
    }
    // data module
    else if (strcmp(name, "_data") == 0) {
      SoDebugError::post("ScXMLStateMachine::setVariable",
                         "Name '%s' is a reserved system variable.", name);
    }
    // fallthrough
    else {
      SoDebugError::post("ScXMLStateMachine::setVariable",
                         "Name '%s' violates the reserved '_'-prefix "
                         "namespace for system variables.", name);
    }
  }

  else if (strncmp(name, "coin:", 5) == 0) {
    // coin profile
    if (strcmp(name, "coin:root") == 0) {
      SoDebugError::post("ScXMLStateMachine::setVariable",
                         "Name '%s' is a reserved system variable.", name);
    }
    else if (strcmp(name, "coin:camera") == 0) {
      SoDebugError::post("ScXMLStateMachine::setVariable",
                         "Name '%s' is a reserved system variable.", name);
    }
    // fallthrough
    else {
      SoDebugError::post("ScXMLStateMachine::setVariable",
                         "Name '%s' violates the reserved 'coin:'-prefix "
                         "namespace for system variables.", name);
    }
  }
  else {
    // FIXME
  }
}

const char *
ScXMLStateMachine::getVariable(const char * name) const
{
  if (strcmp(name, "_sessionid") == 0) {
    PRIVATE(this)->varstring.sprintf("'%s'", PRIVATE(this)->sessionid.getString());
    return PRIVATE(this)->varstring.getString();
    // return PRIVATE(this)->sessionid.getString();
  }
  if (strcmp(name, "_name") == 0) {
    PRIVATE(this)->varstring.sprintf("'%s'", PRIVATE(this)->name.getString());
    return PRIVATE(this)->varstring.getString();
    // return PRIVATE(this)->name.getString();
  }
  return NULL;
}

// *************************************************************************

void
ScXMLStateMachine::PImpl::findTransitions(TransitionList & transitions, ScXMLElt * stateobj, const ScXMLEvent * event)
{
  assert(stateobj);

  if (stateobj->isOfType(ScXMLHistoryElt::getClassTypeId())) {
    ScXMLHistoryElt * history = static_cast<ScXMLHistoryElt *>(stateobj);
    if (history->getTransition() &&
        history->getTransition()->isEventMatch(event) &&
        history->getTransition()->evaluateCondition(PUBLIC(this))) {
      StateTransition transition(stateobj, history->getTransition());
      TransitionList::iterator findit =
        std::find(transitions.begin(), transitions.end(), transition);
      if (findit == transitions.end()) {
        transitions.push_back(transition);
      }
    }
  }
  else if (stateobj->isOfType(ScXMLInitialElt::getClassTypeId())) {
    ScXMLInitialElt * initial = static_cast<ScXMLInitialElt *>(stateobj);
    if (initial->getTransition() &&
        initial->getTransition()->isEventMatch(event) &&
        initial->getTransition()->evaluateCondition(PUBLIC(this))) {
      StateTransition transition(stateobj, initial->getTransition());
      TransitionList::iterator findit =
        std::find(transitions.begin(), transitions.end(), transition);
      if (findit == transitions.end()) {
        transitions.push_back(transition);
      }
    }
  }
  else if (stateobj->isOfType(ScXMLStateElt::getClassTypeId())) {
    ScXMLStateElt * state = static_cast<ScXMLStateElt *>(stateobj);
    for (int j = 0; j < state->getNumTransitions(); ++j) {
      if (state->getTransition(j)->isEventMatch(event) &&
          state->getTransition(j)->evaluateCondition(PUBLIC(this))) {
        StateTransition transition(stateobj, state->getTransition(j));
        TransitionList::iterator findit =
          std::find(transitions.begin(), transitions.end(), transition);
        if (findit == transitions.end()) {
          transitions.push_back(transition);
        }
      }
    }
  }
}

// *************************************************************************

void
ScXMLStateMachine::PImpl::exitState(ScXMLElt * object)
{
  assert(object);
  if (object->isOfType(ScXMLStateElt::getClassTypeId())) {
    ScXMLStateElt * state = static_cast<ScXMLStateElt *>(object);
    const char * id = state->getIdAttribute();
    this->invokeStateChangeCallbacks(id, FALSE);
    ScXMLOnExitElt * onexit = state->getOnExit();
    if (onexit) {
      onexit->execute(PUBLIC(this));
    }
  }
}

void
ScXMLStateMachine::PImpl::enterState(ScXMLElt * object)
{
  assert(object);

  if (object->isOfType(ScXMLFinalElt::getClassTypeId())) {
    // When entering a <final>, ParentID.done should be posted
    ScXMLFinalElt * final = static_cast<ScXMLFinalElt *>(object);
    const ScXMLElt * container = final->getContainer();
    assert(container);
    const char * id = container->getXMLAttribute("id");
    if (!id || strlen(id) == 0) {
      if (container->isOfType(ScXMLDocument::getClassTypeId())) {
        // there is not ParentID to post a ParentID.done event in
        // this case. study SCXML state to see what to do?
        this->finished = TRUE;
        this->active = FALSE;
      } else {
        SoDebugError::post("ScXMLStateMachine::PImpl::enterState",
                           "<final> container has no id - can't post done-event");
      }
      return;
    }
    SbString eventstr;
    eventstr.sprintf("%s.done", id);
    PUBLIC(this)->queueInternalEvent(eventstr.getString());
  }
  else if (object->isOfType(ScXMLStateElt::getClassTypeId())) {
    ScXMLStateElt * state = static_cast<ScXMLStateElt *>(object);
    const char * id = state->getIdAttribute();
    this->invokeStateChangeCallbacks(id, TRUE);
    ScXMLOnEntryElt * onentry = state->getOnEntry();
    if (onentry) {
      onentry->execute(PUBLIC(this));
    }
  }
}

void
ScXMLStateMachine::setEvaluator(ScXMLEvaluator * evaluator)
{
  PRIVATE(this)->evaluator = evaluator;
}

ScXMLEvaluator *
ScXMLStateMachine::getEvaluator(void) const
{
  return PRIVATE(this)->evaluator;
}

SbBool
ScXMLStateMachine::isModuleEnabled(const char * modulename) const
{
  for (int i = 0; i < PRIVATE(this)->modules.getLength(); ++i) {
    if (strcmp(modulename, PRIVATE(this)->modules[i]) == 0) {
      return TRUE;
    }
  }
  return FALSE;
}

int
ScXMLStateMachine::getNumEnabledModules(void) const
{
  return PRIVATE(this)->modules.getLength();
}

const char *
ScXMLStateMachine::getEnabledModuleName(int idx) const
{
  assert(idx >= 0 && idx < PRIVATE(this)->modules.getLength());
  return PRIVATE(this)->modules[idx];
}

void
ScXMLStateMachine::setEnabledModulesList(const SbList<const char *> & modulenames)
{
  int i;
  for (i = 0; i < PRIVATE(this)->modules.getLength(); ++i) {
    delete [] PRIVATE(this)->modules[i];
  }
  PRIVATE(this)->modules.truncate(0);
  for (i = 0; i < modulenames.getLength(); ++i) {
    char * dup = new char [ strlen(modulenames[i]) + 1 ];
    strcpy(dup, modulenames[i]);
    PRIVATE(this)->modules.append(dup);
  }
}

#undef PUBLIC
#undef PRIVATE

max_stars_repo_name: veelo/coin

max_issues_repo_name: realthunder/coin

max_forks_repo_name: realthunder/coin


text:
/******************************************************************************
/* @file Program descriptions and command and config file parsing logic.
/*
/* uses:
/*          - boost.program_options    command-line and config file parsing
/*
/* @author langenhagen
/* @version 1500611
/******************************************************************************/
#pragma once

///////////////////////////////////////////////////////////////////////////////
// INCLUDES project headers

#include <detector_type.hpp>
#include <extractor_type.hpp>

///////////////////////////////////////////////////////////////////////////////
//INCLUDES C/C++ standard library (and other external libraries)

#include <iostream>
#include <stdarg.h> // va_list
#include <string>

#include <boost/program_options.hpp>

///////////////////////////////////////////////////////////////////////////////
// NAMESPACE, CONSTANTS and TYPE DECLARATIONS/IMPLEMENTATIONS

namespace app {

    /// Holds the attributes for the saliency detector.
    struct saliency_detector_description {
        string type_string;
        detector_type::detector_type type;
        string tweak_vector_string;
        Vec1r tweak_vector; ///< not further specified, may be used by the concrete saliency detector implementations.
    };

    /// Holds the feature extractor factory attributes.
    struct feature_extractor_description {
        string type_string;
        extractor_type::extractor_type type;
        string tweak_vector_string;
        Vec1r tweak_vector; ///< not further specified, may be used by the concrete extractor implementations.
    };

    /** @brief Hold global program configurations.
     * Holds the global program attributes and the
     * descriptions of the application's modules.
     */
    struct program_options {
        string config_file;
        string log_file;

        string directories_file;
        string output_directory;
        string features_file;
        string processed_images_file;
        string garbage_file;
        bool delete_old_features;

        Vec1str image_directories;
        bool include_subdirs;

        uint blur_kernel_size_uint;
        cv::Size blur_kernel_size;  ///< adjusted blur_kernel_size_uint.
        real threshold;
        real min_salient_region_size;
        bool use_grabcut;
        real grabcut_foreground_probability;

        bool save_saliency_maps;
        string saliency_maps_file;
        bool save_saliency_masks;
        string saliency_masks_file;
        bool symlink_garbage_files;

        saliency_detector_description sdd;
        feature_extractor_description fed;
    };

    /** Logs the given program parameters.
     * @param p The program_options to be logged.
     */
    void log_program_options( const program_options& p) {
        LOG(info) << "*** program parameters ***";
        LOG(info) << "Config file: " << p.config_file;
        LOG(info) << "Log file: " << p.log_file;
        LOG(info) << "Directories file: " << p.directories_file;
        LOG(info) << "Output directory: " << p.output_directory;
        LOG(info) << "Include subdirectories: " << yes_no(p.include_subdirs);
        LOG(info) << "Featuer vector file: " << p.features_file;
        LOG(info) << "Processed files file: " << p.processed_images_file;
        LOG(info) << "\"No saliency found in\"-file: " << p.garbage_file;
        LOG(info) << "Discard feature vectors from previous run: " << yes_no(p.delete_old_features);
        LOG(info) << "Saliency feature mask smoothness filter-size: " << p.blur_kernel_size_uint << "px";
        LOG(info) << "Saliency feature cutout threshold: " << p.threshold;
        LOG(info) << "Minimum salient region size: " << p.min_salient_region_size << "px";
        LOG(info) << "Use GrabCut postprocessing: " << yes_no(p.use_grabcut);
        LOG(info) << "GrabCut foreground threshold: " << p.grabcut_foreground_probability;
        LOG(info) << "Save saliency maps: " << yes_no(p.save_saliency_maps);
        LOG(info) << "Saliency maps file: " << p.saliency_maps_file;
        LOG(info) << "Save saliency masks: " << yes_no( p.save_saliency_masks);
        LOG(info) << "Saliency masks file: " << p.saliency_masks_file;
        LOG(info) << "Symlink garbage files: " << yes_no( p.symlink_garbage_files);
        LOG(info) << "Saliency detector type: " << p.sdd.type << " aka " << p.sdd.type_string;
        LOG(info) << "Saliency detector tweak vector: [" << to_string( p.sdd.tweak_vector) << "]";
        LOG(info) << "Feature extractor type: " << p.fed.type << " aka " << p.fed.type_string;
        LOG(info) << "Feature extractor tweak vector: [" << to_string( p.fed.tweak_vector) << "]";
    }

    /** Prints a help message consisting of all given opptions_description pointers.
     * @param args The number of given options_description pointers.
     * @param ... an arbitrary number of options_description pointers.
     */
    void print_help_message( const int args, ... ) {
        using namespace boost::program_options; // options_description
        va_list vl;
        va_start(vl,args);

        for( int i=0; i< args; ++i) {
            options_description* d = va_arg(vl,options_description*);
            std::cout << *d << "\n";
        }
        va_end(vl);
    }

    /** Handles wrong input and either sets it right or writes error messages.
     * Decoupled from init_program_options for readability and the chance to init
     * stuff in between original init and adjustment.
     * @param[in,out] p The proram parameters that are to be checked for correctness.
     * @return TRUE - everything correct.
     *         FALSE - uncorrectable input.
     */
    bool adjust_program_options( program_options& p) {
        bool ret(true);

        if( p.blur_kernel_size_uint % 2 == 0) {
            LOG(warn) << "Given blur_kernel_size must be an odd number! Adjusting to " << ++p.blur_kernel_size_uint;
        }
        p.blur_kernel_size = cv::Size( p.blur_kernel_size_uint, p.blur_kernel_size_uint);

        p.sdd.type = detector_type_from_string( p.sdd.type_string);
        if( p.sdd.type == detector_type::ERROR_TYPE)
            ret = false;
        p.sdd.tweak_vector = from_string<real,vector>( p.sdd.tweak_vector_string);

        p.fed.type = extractor_from_string( p.fed.type_string);
        if( p.fed.type == extractor_type::ERROR_TYPE)
            ret = false;
        p.fed.tweak_vector = from_string<real,vector>( p.fed.tweak_vector_string);

        if(ret==false) {
            LOG( error) << "Not correctable error in program options!";
        }
        return ret;
    }

    /** Initializes the program options.
     * @param argc The argument counter (e.g. coming from the main function).
     * @param argv The argument vector array (e.g. coming from the main function).
     * @param[out] p The program parameters that are to be filled.
     * @return Returns TRUE in case of success,
     * returns FALSE in case of failure.
     */
    bool init_program_options( const int argc, const char* argv[], program_options& p) {
        using namespace boost::program_options;
        using namespace std;
        bool ret(true);

        // declare the options ************************************************

        // 1. group of options that will be allowed only on command line
        options_description cmd_desc("Command line options options");
        cmd_desc.add_options()
            ("help", "produce help message")
            ("config,c", value<string>(&p.config_file)->default_value("config.cfg"), "name of the config file")
            ;
        // 2. group description on the config file
        options_description config_desc("Configuration file parameters");
        config_desc.add_options()
            ("log_file", value<string>(&p.log_file)->default_value("log.log"), "name of the log file")
            ("directories_file", value<string>(&p.directories_file)->default_value("directories.txt"), "name of the file that stores the image directories")
            ("include_subdirs", value<bool>(&p.include_subdirs)->default_value(1), "whether or not to include subdirectories in looking through the image databases")
            ("output_directory", value<string>(&p.output_directory)->default_value("out"), "the output directory for eventual output-files")
            ("features_file", value<string>(&p.features_file)->default_value("features.desc"), "a file that stores the salient object feature vectors")
            ("processed_images_file", value<string>(&p.processed_images_file)->default_value("processed_files.txt"), "a file that stores the paths of the already processed images")
            ("garbage_file", value<string>(&p.garbage_file)->default_value("files_with_no_salient_regions.txt"), "a file that stores the paths images in which no salient region was found")
            ("delete_old_features", value<bool>(&p.delete_old_features)->default_value(false), "whether or not to delete/reuse the feature vectors generated in a previous run")
            ("blur_kernel_size", value<uint>(&p.blur_kernel_size_uint), "size of the blur filter to smooth the saliency masks in each dimension")
            ("threshold", value<real>(&p.threshold), "the threshold of deciding when a pixel of the saliency map is part of a salient object. Should be within ]0;1[")
            ("min_salient_region_size", value<real>(&p.min_salient_region_size)->default_value(0), "the minimum size of a salient region in pixels")
            ("use_grabcut", value<bool>(&p.use_grabcut)->default_value(false), "Whether or not to use GrabCut for creation of saliency masks")
            ("grabcut_foreground_probability", value<real>(&p.grabcut_foreground_probability)->default_value(static_cast<real>(0.2)), "The probability of a pixel to be long to the foreground")
            ("save_saliency_maps", value<bool>(&p.save_saliency_maps)->default_value(0), "whether or not to save saliency maps to disk")
            ("saliency_maps_file", value<string>(&p.saliency_maps_file)->default_value("saliency_maps.txt"), "stores the paths to eventually created saliency maps")
            ("save_saliency_masks", value<bool>(&p.save_saliency_masks)->default_value(false), "whether or not to save the saliency masks to disk")
            ("saliency_masks_file", value<string>(&p.saliency_masks_file)->default_value("saliency_masks.txt"), "stores the paths to eventually created saliency masks")
            ("symlink_garbage_files", value<bool>(&p.symlink_garbage_files)->default_value(false), "whether or not to symlink the files without salient regions")
            ("detector_type", value<string>(&p.sdd.type_string), detector_types_string().c_str())
            ("detector_tweak_vector", value<string>(&p.sdd.tweak_vector_string)->default_value(""), "real-numeric tweaks for the saliency detector separated by spaces \" \".")
            ("extractor_type", value<string>(&p.fed.type_string), extractor_types_string().c_str())
            ("extractor_tweak_vector", value<string>(&p.fed.tweak_vector_string)->default_value(""), "real-numeric tweaks for the feature extractor separated by spaces \" \".")
            ;
        // END option declarations ********************************************

        // *** parse the command line and the config files ***
        variables_map vm;

        // 1. parse command line ******************************************
        store(parse_command_line(argc, argv, cmd_desc), vm);
        boost::program_options::notify(vm);

        if( vm.count("help")) {
            // special 'help' case
            print_help_message( 2, &cmd_desc, &config_desc);
            return false;
        }
        // 2. parse config file *******************************************
        ifstream in_file(p.config_file.c_str());
        if (!in_file) {
            std::cerr << "Can not open config file: " << p.config_file << "\n"
                         "Did you create a config file or do you want to specify another config file?\n";
            ret = false;
        } else {
            // *** file access works ***
            parsed_options po (parse_config_file(in_file, config_desc, true));
            store( po, vm);
            boost::program_options::notify(vm);
        }
        in_file.close();
        return ret;
    }
}

ext: hpp

max_stars_repo_name: langenhagen/Master-Thesis

max_issues_repo_name: langenhagen/Master-Thesis

max_forks_repo_name: langenhagen/Master-Thesis


text:
// Copyright (C) 2018 Thanaphon Chavengsaksongkram <as12production@gmail.com>, He Sun <he.sun@ed.ac.uk>
// This file is subject to the license terms in the LICENSE file
// found in the top-level directory of this distribution.

#include <gtest/gtest.h>
#include <gSparse/GraphCSVReader.hpp>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <memory>

/*******************************************************
 * Test Cases
 * ******************************************************/
TEST(GraphCSVReader, ReadEdge)
{
    gSparse::PrecisionRowMatrix Weight;
    gSparse::EdgeMatrix Edges;
    std::shared_ptr<gSparse::IGraphReader> reader =  std::make_shared<gSparse::GraphCSVReader>("test-edges.csv","None"," ");
    reader->Read(Edges, Weight);
    //Building edges validation data
	gSparse::EdgeMatrix  Edges_Validate(3,2);
	Edges_Validate(0, 0) = 1; Edges_Validate(0, 1) = 2;
	Edges_Validate(1, 0) = 2; Edges_Validate(1, 1) = 3;
	Edges_Validate(2, 0) = 3; Edges_Validate(2, 1) = 1;

    //Building weight validation data
	gSparse::PrecisionRowMatrix  Weight_Validate(3,1);
	Weight_Validate << 1, 1, 1;
    EXPECT_EQ((Weight - Weight_Validate).norm(), 0.0);
	EXPECT_EQ((Edges - Edges_Validate).norm(), 0.0);
}

TEST(GraphCSVReader, ReadAll)
{
	/* Testing Initialization */
	gSparse::GraphCSVReader csvReader("test-edges.csv", "test-weight.csv", " ");

	//Loading Test Data
	gSparse::EdgeMatrix  Edges;
	gSparse::PrecisionRowMatrix  Weight;
	csvReader.Read(Edges, Weight);

	//Building edges validation data
	gSparse::EdgeMatrix  Edges_Validate(3,2);
	Edges_Validate(0, 0) = 1; Edges_Validate(0, 1) = 2;
	Edges_Validate(1, 0) = 2; Edges_Validate(1, 1) = 3;
	Edges_Validate(2, 0) = 3; Edges_Validate(2, 1) = 1;

	//Building weight validation data
	gSparse::PrecisionRowMatrix  Weight_Validate(3,1);
	Weight_Validate << 1, 2, 3;

	EXPECT_EQ((Weight - Weight_Validate).norm(), 0.0);
	EXPECT_EQ((Edges - Edges_Validate).norm(), 0.0);
}
TEST(GraphCSVReader, EdgeNotFound)
{
    gSparse::EdgeMatrix  Edges;
	gSparse::PrecisionRowMatrix  Weight;
    /* Test fail file opening */
	gSparse::GraphCSVReader csvReaderFail("ThisFileDoesNotExist.txt", "Test/test-weight.csv", " ");
	EXPECT_ANY_THROW(csvReaderFail.Read(Edges, Weight));
}
TEST(GraphCSVReader, WeightNotFound)
{
    gSparse::EdgeMatrix  Edges;
	gSparse::PrecisionRowMatrix  Weight;
    /* Test fail file opening */
	gSparse::GraphCSVReader csvReaderFail("Test/test-edges.csv", "ThisFileDoesNotExist.txt", " ");
	EXPECT_ANY_THROW(csvReaderFail.Read(Edges, Weight));
}
TEST(GraphCSVReader, AllNotFound)
{
    gSparse::EdgeMatrix  Edges;
	gSparse::PrecisionRowMatrix  Weight;
    /* Test fail file opening */
	gSparse::GraphCSVReader csvReaderFail("ThisFileDoesNotExist.txt", "ThisFileDoesNotExist.txt", " ");
	EXPECT_ANY_THROW(csvReaderFail.Read(Edges, Weight));
}
int main(int argc, char **argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

ext: cpp


text:
/*    This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
 *    See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
 *    Author(s):       Siargey Kachanovich
 *
 *    Copyright (C) 2016 Inria
 *
 *    Modification(s):
 *      - YYYY/MM Author: Description of the modification
 */

// #ifdef _DEBUG
// # define TBB_USE_THREADING_TOOL
// #endif

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Subsampling - test pick_n_random_points
#include <boost/test/unit_test.hpp>

#include <gudhi/pick_n_random_points.h>
#include <vector>
#include <iterator>

#include <CGAL/Epick_d.h>

BOOST_AUTO_TEST_CASE(test_pick_n_random_points)
{
  typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag>                K;
  typedef typename K::FT                                            FT;
  typedef typename K::Point_d                                       Point_d;

  std::vector<Point_d> vect;
  vect.push_back(Point_d(std::vector<FT>({0,0,0,0})));
  vect.push_back(Point_d(std::vector<FT>({0,0,0,1})));
  vect.push_back(Point_d(std::vector<FT>({0,0,1,0})));
  vect.push_back(Point_d(std::vector<FT>({0,0,1,1})));
  vect.push_back(Point_d(std::vector<FT>({0,1,0,0})));
  vect.push_back(Point_d(std::vector<FT>({0,1,0,1})));
  vect.push_back(Point_d(std::vector<FT>({0,1,1,0})));
  vect.push_back(Point_d(std::vector<FT>({0,1,1,1})));
  vect.push_back(Point_d(std::vector<FT>({1,0,0,0})));
  vect.push_back(Point_d(std::vector<FT>({1,0,0,1})));
  vect.push_back(Point_d(std::vector<FT>({1,0,1,0})));
  vect.push_back(Point_d(std::vector<FT>({1,0,1,1})));
  vect.push_back(Point_d(std::vector<FT>({1,1,0,0})));
  vect.push_back(Point_d(std::vector<FT>({1,1,0,1})));
  vect.push_back(Point_d(std::vector<FT>({1,1,1,0})));
  vect.push_back(Point_d(std::vector<FT>({1,1,1,1})));

  std::vector<Point_d> results;
  Gudhi::subsampling::pick_n_random_points(vect, 5, std::back_inserter(results));
  std::clog << "landmark vector contains: ";
  for (auto l: results)
    std::clog << l << "\n";

  BOOST_CHECK(results.size() == 5);
}


text:
#include <libcommon/meta_info.h>
#include <libcommon/ServerSettings.h>
#include <list>
#include <nlohmann/json.hpp>
#include <cstddef>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <libcommon/config_factory.h>
#include <libcommon/configurator.h>
#include <libcommon/config_exceptions.h>
#include <libcommon/PipelineConfig.h>
#include <libcommon/FakeCameraConfig.h>
#include <boost/format.hpp>
#include <filesystem>
namespace tmk_config = tmk::common::configuration;
void testCreate(const std::string& filename)
{
    tmk_config::meta_info info,info1,info2;
    nlohmann::json json;
    int i=0;
    for(auto infos : {info,info1,info2})
    {
        std::stringstream str;
        str<<"infos_"<<i++;
        tmk_config::_fabrics.ToJson(json,infos,str.str());
        infos.save(json);
    }
    tmk_config::ServerSettings serverSetts;
    serverSetts.save(json);
    for(auto tt : { std::make_tuple(2,"config_demo"),
                    std::make_tuple(5,"config_default") })
    {
        tmk_config::PipelineConfig pipelineConfig;
        for(int i=0; i< std::get<0>(tt); i++)
        {
            tmk_config::PipelineNodeConfig node(    i,
                            (boost::format("bin//block_%d")
                                % (i+1)).str(),
                            (
                                [=]()->auto
                                {
                                    std::list<std::string> pars;
                                    int n=0;
                                    std::generate_n(std::back_inserter(pars),
                                                    i+1,
                                                    [&]()->auto
                                                    {
                                                        return (boost::format("par_%d")% n++).str();
                                                    });
                                    return std::move(pars);
                                }
                            )(),
                            i == 0 ? tmk_config::PipelineNodeType::FIRST :
                                    (i < (std::get<0>(tt)-1) )?
                                        tmk_config::PipelineNodeType::MIDDLE :
                                        tmk_config::PipelineNodeType::LAST,
                            i < (std::get<0>(tt)-1) ? i+1 : -1,
                            (boost::format("node_%d")%i).str() );
            pipelineConfig.AddNode(node);
        }
        pipelineConfig.PipelineConfigName() = std::get<1>(tt);
        pipelineConfig.save(json);
    }

    tmk_config::FakeCameraConfig fake_camera_config;
    fake_camera_config.save( json );

    {
        {
            std::ofstream out(  filename,
                                std::ios_base::openmode::_S_out
                              | std::ios_base::openmode::_S_trunc );
            out << std::setw(4)<<json << std::endl;
            out.close();
        }
    }
}

void testRead(const std::string& filename)
{
    try
    {
        tmk_config::Configuration::Load(filename);
        std::filesystem::path oldPath(filename);
        auto oldfilename = oldPath.filename().stem();
        oldfilename+= std::string(".modified");
        tmk_config::Configuration::Instance()
                                    .Save(oldPath
                                    .replace_filename(oldfilename )
                                    .string());
    }
    catch(tmk_config::configuration_exception& ex)
    {
        std::cout   << "exception : "  << std::endl
                    << ex.what()  << std::endl
                    ;
    }

}

int main(int argc,char** argv)
{
    std::string filename = "server_settings_multiple_metas_pipeline.json";
    try
    {
        testCreate(filename);
        testRead(filename);
    }

    catch(const nlohmann::json::type_error& terr)
    {
        std::cout   << "exception : "  << std::endl
                    << terr.what()  << std::endl
                    ;
    }
    catch(const std::exception& ex)
    {
        std::cout   << "exception : "  << std::endl
                    << ex.what()  << std::endl
                    ;
    }

}


text:
/*=============================================================================
    Copyright (c) 2001-2011 Joel de Guzman
    Copyright (c) 2011 Eric Niebler

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_SINGLE_VIEW_BEGIN_IMPL_05052005_0305)
#define BOOST_FUSION_SINGLE_VIEW_BEGIN_IMPL_05052005_0305

#include <boost/fusion/support/config.hpp>
#include <boost/mpl/int.hpp>

namespace boost {
namespace fusion {
struct single_view_tag;

template <typename SingleView, typename Pos> struct single_view_iterator;

namespace extension {
template <typename Tag> struct begin_impl;

template <> struct begin_impl<single_view_tag> {
  template <typename Sequence> struct apply {
    typedef single_view_iterator<Sequence, mpl::int_<0>> type;

    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Sequence &seq) {
      return type(seq);
    }
  };
};
} // namespace extension
} // namespace fusion
} // namespace boost

#endif

max_stars_repo_name: henrywarhurst/matrix

max_issues_repo_name: henrywarhurst/matrix

max_forks_repo_name: henrywarhurst/matrix


text:
//
// $Id$
//
// -------------------------------------------------------------------------
// This file is part of ZeroBugs, Copyright (c) 2010 Cristian L. Vlasceanu
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// -------------------------------------------------------------------------

#include <pthread.h>
#include <stdio.h>
#include <fstream>
#include <boost/functional.hpp>
#include <boost/python.hpp>
#include <boost/tokenizer.hpp>
#include "dharma/canonical_path.h"
#include "dharma/config.h"
#include "dharma/environ.h"
#include "dharma/system_error.h"
#include "generic/auto_file.h"
#include "zdk/argv_util.h"
#include "zdk/check_ptr.h"
#include "zero_python/breakpoint.h"
#include "zero_python/breakpoint_registry.h"
#include "zero_python/call.h"
#include "zero_python/class_type.h"
#include "zero_python/data_type.h"
#include "zero_python/debug_event.h"
#include "zero_python/debug_symbol.h"
#include "zero_python/debugger.h"
#include "zero_python/elf_header.h"
#include "zero_python/macro.h"
#include "zero_python/marshaller.h"
#include "zero_python/module.h"
#include "zero_python/process.h"
#include "zero_python/python_embed.h"
#include "zero_python/symbol.h"
#include "zero_python/symbol_map.h"
#include "zero_python/process.h"
#include "zero_python/properties.h"
#include "zero_python/python_embed.h"
#include "zero_python/symbol.h"
#include "zero_python/symbol_map.h"
#include "zero_python/symbol_table.h"
#include "zero_python/stack_trace.h"
#include "zero_python/thread.h"
#include "zero_python/translation_unit.h"
#include "zero_python/type_system.h"
#include "zero_python/update.h"
#include "zero_python/utility.h"
#include "python_gate.h"
#include "filter.h"
#include "updater.h"

using namespace std;
using namespace boost;
using namespace boost::python;

static PythonGate* plugin = 0;
static WeakPtr<Python> interp;

static Debugger* theDebugger = 0; // hack

static Debugger* debugger()
{
    return theDebugger;
}

static void event_loop()
{
    ThreadMarshaller::instance().event_loop();
}

static int event_pipe()
{
    return ThreadMarshaller::instance().event_pipe();
}

static void event_iteration()
{
    ThreadMarshaller::instance().event_iteration(true);
}

static void bypass_builtin_command_interpreter(bool bypass)
{
    if (plugin)
    {
        plugin->set_grab_event(bypass);
    }
}

PythonEmbed& py_interp()
{
    if (RefPtr<Python> python = interp.lock())
    {
        return *python;
    }
    throw runtime_error("Python interpreter not initialized");
}

BOOST_PYTHON_MODULE(zero)
{
    export_breakpoint();
    export_data_type();     // export DataType before ClassType
    export_class_type();    //  since ClassType inherits DataType
    export_debugger();
    export_debug_event();
    export_debug_symbol();
    export_elf_header();
    export_macro();
    export_module();
    export_process();
    export_properties();
    export_symbol();
    export_symbol_map();
    export_symbol_table();
    export_stack_trace();
    export_thread();
    export_translation_unit();
    export_type_system();
    export_update();

    def("bypass_builtin_command_interpreter",
         bypass_builtin_command_interpreter
       );
    def("debugger", debugger, "return current debugger instance",
        return_value_policy<reference_existing_object>()
       );
    def("event_iteration", event_iteration,
        "run one iteration in the event-handling thread");
    def("event_pipe", event_pipe, "return the file descriptor of a pipe"
                                  "that receives notifications when events occur;\n"
                                  "useful when implementing a custom UI. Toolkits "
                                  "such as GTK allow users to define IO handlers.\n");
}

int32_t query_version(int32_t* minor)
{
    if (minor) *minor = ZDK_MINOR;
    return ZDK_MAJOR;
}

/**
 * Advertise the interfaces supported by this plugin
 */
void query_plugin(InterfaceRegistry* registry)
{
    registry->update(DebuggerPlugin::_uuid());
    registry->update(DataFilter::_uuid());
}

/**
 * Create a plugin instance
 */
Plugin* create_plugin(uuidref_t iid)
{
    static UserDataFilter* filter = 0;

    if (uuid_equal(DebuggerPlugin::_uuid(), iid))
    {
        if (!plugin)
        {
            plugin = new PythonGate(interp);

            if (RefPtr<Python> python = interp.lock())
            {
                python->set_context(interface_cast<ZObject*>(plugin));
            }
        }
        return plugin;
    }
    else if (uuid_equal(DataFilter::_uuid(), iid))
    {
        if (!filter)
        {
            filter = new UserDataFilter(interp);
        }
        return filter;
    }
    return 0;
}

PythonGate::PythonGate(WeakPtr<Python>& interp)
    : debugger_(NULL)
    , pyThread_(pthread_t())
    , file_(NULL)
    , argc_(0)
    , argv_(NULL)
    , adapter_(new ZObjectAdapter(this))
    , grabEvent_(false)
    , exitOnExcept_(false)
    , interp_(interp.lock())
{
    if (!interp_)
    {
        interp_.reset(new Python);
        interp = interp_;
    }
    updater_ = new Updater(interp_);
    TheBreakPointRegistry::instance(); // create on main thread
}

PythonGate::~PythonGate() throw()
{
    if (file_)
    {
        fclose(file_);
    }
    if (pyThread_)
    {
        pthread_join(pyThread_, NULL);
    }
    adapter_->clear();
    plugin = NULL;
}

void PythonGate::release()
{
    delete this;
}

/**
 * Check that the interpreter version matches what we
 * compiled against.
 */
static bool check_interp_version(Debugger* debugger)
{
    const char* version = Py_GetVersion();

    if (const char* delim = strchr(version, ' '))
    {
        const string dynVer(version, distance(version, delim));

        if (dynVer != PY_VERSION)
        {
            ostringstream err;
            err << "Python plug-in expects interpreter " << PY_VERSION;
            err << " got: " << dynVer;

            debugger->message(err.str().c_str(), Debugger::MSG_ERROR);
            return false;
        }
    }
    return true;
}

/**
 * Parse command line and other initializing stuff
 */
bool PythonGate::initialize(Debugger* debugger, int* argc, char*** argv)
{
    assert(debugger);

    theDebugger = debugger_ = debugger;
    rcFileName_ = canonical_path("./.zero.py");

    bool checkVersion = true;

    rcFile_.reset(fopen(rcFileName_.c_str(), "r"));
    if (!rcFile_)
    {
        rcFileName_ = env::get_string("ZERO_PLUGIN_PATH") + "/.zero.py";
        rcFile_.reset(fopen(rcFileName_.c_str(), "r"));
    }

BEGIN_ARG_PARSE(argc, argv)
    ON_ARGV("--py-run=", filename_)
    {
        if ((file_ = fopen(filename_.c_str(), "r")) == 0)
        {
            throw SystemError(filename_);
        }
    }
    // same as --py-run, only _exit on exceptions
    ON_ARGV("--py-exec=", filename_)
    {
        exitOnExcept_ = true;
        if ((file_ = fopen(filename_.c_str(), "r")) == 0)
        {
            throw SystemError(filename_);
        }
    }
    ON_ARG("--py-show-cmds")
    {
        ThreadMarshaller::instance().set_debug_commands();
    }
    ON_ARG("--py-show-events")
    {
        ThreadMarshaller::instance().set_debug_events();
    }
    ON_ARG("--py-disable")
    {
        return false;
    }
    ON_ARG("--py-no-version-check")
    {
        checkVersion = false;
    }
END_ARG_PARSE

    if (checkVersion && !check_interp_version(debugger))
    {
        return false;
    }
    argc_ = *argc;
    argv_ = *argv;

    if (PyImport_AppendInittab("zero", initzero) == -1)
    {
        throw runtime_error("Failed to register module __zero__");
    }
    return true;
}

void PythonGate::start()
{
    // instantiate on main thread
    ThreadMarshaller::instance();

    Temporary<bool>  setFlags(exitOnExcept_, true);

    pthread_create(&pyThread_, NULL, interp_thread, this);
    ThreadMarshaller::instance().wait_for_event_activation();
}

void PythonGate::shutdown()
{
    ThreadMarshaller::shutdown();
}

void PythonGate::register_streamable_objects(ObjectFactory*)
{
}

void PythonGate::on_table_init(SymbolTable*)
{
}

static bool table_done(RefPtr<SymbolTable> table)
{
    call_<void>("on_table_done", table);
    return true;
}

void PythonGate::on_table_done(SymbolTable* table)
{
    ThreadMarshaller::instance().send_event(bind(table_done, table), __func__);
}

static bool attached_event(RefPtr<Thread> thread)
{
    if (CHKPTR(thread->process())->enum_threads() == 1)
    {
        call_<void>("on_process", ptr(thread->process()), thread);
    }
    else
    {
        call_<void>("on_thread", thread);
    }
    return true;
}

void PythonGate::on_attach(Thread* thread)
{
    if (thread)
    {
        ThreadMarshaller::instance().send_event(
                bind(attached_event, thread), __func__);
    }
}

static bool detached_event(RefPtr<Thread> thread)
{
    if (!thread)
    {
        call_<void>("on_process_detach", ptr((Process*)0));
    }
    else
    {
        call_<void>("on_thread_detach", thread);

        if (Process* proc = thread->process())
        {
            if (proc->enum_threads() == 0)
            {
                call_<void>("on_process_detach", ptr(proc));
            }
        }
    }
    return true;
}

void PythonGate::on_detach(Thread* thread)
{
    ThreadMarshaller::instance().send_event(
        bind(detached_event, thread), __func__);
}

bool PythonGate::debug_event(RefPtr<DebugEvent> event)
{
    bool ret = call_<bool>("on_event", event);
    return ret;
}

void PythonGate::send_debug_event (
    DebugEvent::Type    type,
    const char*         name,
    Thread*             thread,
    int                 sysCallNum
)
{
    assert (sysCallNum < 0 || type == DebugEvent::SYSCALL_ENTER);

    RefPtr<DebugEvent> event(new DebugEvent(type, thread, sysCallNum));

    bool gtkMode = ThreadMarshaller::instance().is_gtk_mode_active();

    ThreadMarshaller::instance().send_event(
            bind(&PythonGate::debug_event, this, event),
            name,
            gtkMode);
}

void PythonGate::on_syscall(Thread* thread, int32_t num)
{
    send_debug_event(DebugEvent::SYSCALL_ENTER, __func__, CHKPTR(thread), num);
}

bool PythonGate::on_event(Thread* thread, EventType eType)
{
    if (ThreadMarshaller::instance().process_pending_commands())
    {
        return true;
    }

    DebugEvent::Type type = static_cast<DebugEvent::Type>(eType);
    if (thread)
    {
        if ((eType != E_PROMPT) && thread->is_done_stepping())
        {
            if (eType == E_THREAD_RETURN)
            {
                type = DebugEvent::RETURNED;
            }
            else
            {
                type = DebugEvent::DONE_STEPPING;
            }
        }
    }
    send_debug_event(type, __func__, thread);
    Lock<Mutex> lock(mutex_);
    return grabEvent_;
}

void PythonGate::set_grab_event(bool grab)
{
    Lock<Mutex> lock(mutex_);
    grabEvent_ = grab;
}

void PythonGate::on_program_resumed()
{
    // todo: invoke callback in script
}

static void on_brkpnt_ins(RefPtr<Symbol> sym, BreakPoint::Type type)
{
    call_<void>("on_breakpoint_inserted", sym, type);
}

static void on_brkpnt_del(RefPtr<Symbol> sym, BreakPoint::Type type)
{
    call_<void>("on_breakpoint_deleted", sym, type);
}

void PythonGate::on_insert_breakpoint(volatile BreakPoint* bpnt)
{
    assert(bpnt);

    ThreadMarshaller::instance().send_event(
            bind(on_brkpnt_ins, bpnt->symbol(), bpnt->type()),
            __func__);
}

void PythonGate::on_remove_breakpoint(volatile BreakPoint* bpnt)
{
    assert(bpnt);

    ThreadMarshaller::instance().send_event(
            bind(on_brkpnt_del, bpnt->symbol(), bpnt->type()),
            __func__);
}

static bool progress_callback(string what, double percent, bool* cancel)
{
    assert(cancel);
    *cancel = !call_<bool>("on_progress", what, percent);
    return true;
}

bool PythonGate::on_progress(const char* what, double percent, word_t cookie)
{
    bool cancel = false;
    ThreadMarshaller::instance().send_event(
        bind(progress_callback, what, percent, &cancel), __func__);
    return !cancel;
}

const char* PythonGate::description() const
{
    return "PythonGate Plugin";
}

const char* PythonGate::copyright() const
{
    return "";
}

void* PythonGate::interp_thread(void* ptr)
{
    assert(ptr);
    PythonGate* plugin = reinterpret_cast<PythonGate*>(ptr);
    string error;

    try
    {
        plugin->run_interp();
    }
    catch (const std::exception& e)
    {
        error = e.what();
    }
    catch (const error_already_set&)
    {
        error = python_get_error();
    }
    catch (...)
    {
        error = "unknown exception in Python thread\n";
    }
    if (!error.empty())
    {
        if (plugin->exitOnExcept_)
        {
            cerr << error << endl;
            _exit(1);
        }
        ThreadMarshaller::instance().break_command_loop();
        plugin->debugger_->message(error.c_str(), Debugger::MSG_ERROR, NULL, true);
    }
    return NULL;
}

void PythonGate::run_interp()
{
    PySys_SetArgv(argc_, argv_);
    ThreadMarshaller::instance().set_callbacks(this);

    bool haveScript = false;

    // run .zero.py file if detected
    if (rcFile_)
    {
        interp_->run_file(rcFile_.get(), rcFileName_.c_str());
        haveScript = true;
    }
    if (file_)
    {
        interp_->run_file(file_, filename_);
        haveScript = true;
    }
    if (haveScript)
    {
        call_<void>("on_init", ptr(debugger_));
    }
    event_loop();
}

void PythonGate::on_error(const string& msg)
{
    if (!call_<bool>("on_error", msg))
    {
        debugger_->message(msg.c_str(), Debugger::MSG_ERROR, NULL, true);
    }
}

bool PythonGate::on_command_loop_state(bool active)
{
    call_<void>("on_command_loop_state", active);
    return true;
}

// vim: tabstop=4:softtabstop=4:expandtab:shiftwidth=4

max_stars_repo_name: cristivlas/zerobugs

max_issues_repo_name: cristivlas/zerobugs

max_forks_repo_name: cristivlas/zerobugs


text:
/**
 * Copyright (C) 2019 Xilinx, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may
 * not use this file except in compliance with the License. A copy of the
 * License is located at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

#include "device_linux.h"
#include "core/common/query_requests.h"

#include "common/utils.h"
#include "xrt.h"
#include "scan.h"
#include <string>
#include <iostream>
#include <map>
#include <functional>
#include <boost/format.hpp>

namespace {

namespace query = xrt_core::query;
using pdev = std::shared_ptr<pcidev::pci_device>;
using key_type = query::key_type;

inline pdev
get_pcidev(const xrt_core::device* device)
{
  return pcidev::get_dev(device->get_device_id(), device->is_userpf());
}

struct bdf
{
  using result_type = query::pcie_bdf::result_type;

  static result_type
  get(const xrt_core::device* device, key_type)
  {
    auto pdev = get_pcidev(device);
    return std::make_tuple(pdev->bus,pdev->dev,pdev->func);
  }
};

// Specialize for other value types.
template <typename ValueType>
struct sysfs_fcn
{
  static ValueType
  get(const pdev& dev, const char* subdev, const char* entry)
  {
    std::string err;
    ValueType value;
    dev->sysfs_get(subdev, entry, err, value, static_cast<ValueType>(-1));
    if (!err.empty())
      throw std::runtime_error(err);
    return value;
  }
};

template <>
struct sysfs_fcn<std::string>
{
  using ValueType = std::string;

  static ValueType
  get(const pdev& dev, const char* subdev, const char* entry)
  {
    std::string err;
    ValueType value;
    dev->sysfs_get(subdev, entry, err, value);
    if (!err.empty())
      throw std::runtime_error(err);
    return value;
  }
};

template <typename VectorValueType>
struct sysfs_fcn<std::vector<VectorValueType>>
{
  //using ValueType = std::vector<std::string>;
  using ValueType = std::vector<VectorValueType>;

  static ValueType
  get(const pdev& dev, const char* subdev, const char* entry)
  {
    std::string err;
    ValueType value;
    dev->sysfs_get(subdev, entry, err, value);
    if (!err.empty())
      throw std::runtime_error(err);
    return value;
  }
};

template <typename QueryRequestType>
struct sysfs_getter : QueryRequestType
{
  const char* entry;
  const char* subdev;

  sysfs_getter(const char* e, const char* s)
    : entry(e), subdev(s)
  {}

  boost::any
  get(const xrt_core::device* device) const
  {
    return sysfs_fcn<typename QueryRequestType::result_type>
      ::get(get_pcidev(device), entry, subdev);
  }
};

template <typename QueryRequestType, typename Getter>
struct function0_getter : QueryRequestType
{
  boost::any
  get(const xrt_core::device* device) const
  {
    auto k = QueryRequestType::key;
    return Getter::get(device, k);
  }
};

static std::map<xrt_core::query::key_type, std::unique_ptr<query::request>> query_tbl;

template <typename QueryRequestType>
static void
emplace_sysfs_request(const char* entry, const char* subdev)
{
  auto x = QueryRequestType::key;
  query_tbl.emplace(x, std::make_unique<sysfs_getter<QueryRequestType>>(entry, subdev));
}

template <typename QueryRequestType, typename Getter>
static void
emplace_func0_request()
{
  auto k = QueryRequestType::key;
  query_tbl.emplace(k, std::make_unique<function0_getter<QueryRequestType, Getter>>());
}

static void
initialize_query_table()
{
  emplace_sysfs_request<query::pcie_vendor>               ("", "vendor");
  emplace_sysfs_request<query::pcie_device>               ("", "device");
  emplace_sysfs_request<query::pcie_subsystem_vendor>     ("", "subsystem_vendor");
  emplace_sysfs_request<query::pcie_subsystem_id>         ("", "subsystem_device");
  emplace_sysfs_request<query::pcie_link_speed>           ("", "link_speed");
  emplace_sysfs_request<query::pcie_express_lane_width>   ("", "link_width");
  emplace_sysfs_request<query::dma_threads_raw>           ("dma", "channel_stat_raw");
  emplace_sysfs_request<query::rom_vbnv>                  ("rom", "VBNV");
  emplace_sysfs_request<query::rom_ddr_bank_size>         ("rom", "ddr_bank_size");
  emplace_sysfs_request<query::rom_ddr_bank_count_max>    ("rom", "ddr_bank_count_max");
  emplace_sysfs_request<query::rom_fpga_name>             ("rom", "FPGA");
  emplace_sysfs_request<query::rom_raw>                   ("rom", "raw");
  emplace_sysfs_request<query::rom_uuid>                  ("rom", "uuid");
  emplace_sysfs_request<query::rom_time_since_epoch>      ("rom", "timestamp");
  emplace_sysfs_request<query::mem_topology_raw>          ("icap", "mem_topology");
  emplace_sysfs_request<query::ip_layout_raw>             ("icap", "ip_layout");
  emplace_sysfs_request<query::clock_freqs>               ("icap", "clock_freqs");
  emplace_sysfs_request<query::idcode>                    ("icap", "idcode");
  emplace_sysfs_request<query::status_mig_calibrated>     ("", "mig_calibration");
  emplace_sysfs_request<query::xmc_version>               ("xmc", "version");
  emplace_sysfs_request<query::xmc_serial_num>            ("xmc", "serial_num");
  emplace_sysfs_request<query::xmc_max_power>             ("xmc", "max_power");
  emplace_sysfs_request<query::xmc_bmc_version>           ("xmc", "bmc_ver");
  emplace_sysfs_request<query::xmc_status>                ("xmc", "status");
  emplace_sysfs_request<query::xmc_reg_base>              ("xmc", "reg_base");
  emplace_sysfs_request<query::dna_serial_num>            ("dna", "dna");
  emplace_sysfs_request<query::status_p2p_enabled>        ("", "p2p_enable");
  emplace_sysfs_request<query::temp_card_top_front>       ("xmc", "xmc_se98_temp0");
  emplace_sysfs_request<query::temp_card_top_rear>        ("xmc", "xmc_se98_temp1");
  emplace_sysfs_request<query::temp_card_bottom_front>    ("xmc", "xmc_se98_temp2");
  emplace_sysfs_request<query::temp_fpga>                 ("xmc", "xmc_fpga_temp");
  emplace_sysfs_request<query::fan_trigger_critical_temp> ("xmc", "xmc_fan_temp");
  emplace_sysfs_request<query::fan_fan_presence>          ("xmc", "fan_presence");
  emplace_sysfs_request<query::fan_speed_rpm>             ("xmc", "xmc_fan_rpm");
  emplace_sysfs_request<query::ddr_temp_0>                ("xmc", "xmc_ddr_temp0");
  emplace_sysfs_request<query::ddr_temp_1>                ("xmc", "xmc_ddr_temp1");
  emplace_sysfs_request<query::ddr_temp_2>                ("xmc", "xmc_ddr_temp2");
  emplace_sysfs_request<query::ddr_temp_3>                ("xmc", "xmc_ddr_temp3");
  emplace_sysfs_request<query::hbm_temp>                  ("xmc", "xmc_hbm_temp");
  emplace_sysfs_request<query::cage_temp_0>               ("xmc", "xmc_cage_temp0");
  emplace_sysfs_request<query::cage_temp_1>               ("xmc", "xmc_cage_temp1");
  emplace_sysfs_request<query::cage_temp_2>               ("xmc", "xmc_cage_temp2");
  emplace_sysfs_request<query::cage_temp_3>               ("xmc", "xmc_cage_temp3");
  emplace_sysfs_request<query::v12v_pex_millivolts>       ("xmc", "xmc_12v_pex_vol");
  emplace_sysfs_request<query::v12v_pex_milliamps>        ("xmc", "xmc_12v_pex_curr");
  emplace_sysfs_request<query::v12v_aux_millivolts>       ("xmc", "xmc_12v_aux_vol");
  emplace_sysfs_request<query::v12v_aux_milliamps>        ("xmc", "xmc_12v_aux_curr");
  emplace_sysfs_request<query::v3v3_pex_millivolts>       ("xmc", "xmc_3v3_pex_vol");
  emplace_sysfs_request<query::v3v3_aux_millivolts>       ("xmc", "xmc_3v3_aux_vol");
  emplace_sysfs_request<query::ddr_vpp_bottom_millivolts> ("xmc", "xmc_ddr_vpp_btm");
  emplace_sysfs_request<query::ddr_vpp_top_millivolts>    ("xmc", "xmc_ddr_vpp_top");

  emplace_sysfs_request<query::v5v5_system_millivolts>    ("xmc", "xmc_sys_5v5");
  emplace_sysfs_request<query::v1v2_vcc_top_millivolts>   ("xmc", "xmc_1v2_top");
  emplace_sysfs_request<query::v1v2_vcc_bottom_millivolts>("xmc", "xmc_vcc1v2_btm");
  emplace_sysfs_request<query::v1v8_millivolts>           ("xmc", "xmc_1v8");
  emplace_sysfs_request<query::v0v85_millivolts>          ("xmc", "xmc_0v85");
  emplace_sysfs_request<query::v0v9_vcc_millivolts>       ("xmc", "xmc_mgt0v9avcc");
  emplace_sysfs_request<query::v12v_sw_millivolts>        ("xmc", "xmc_12v_sw");
  emplace_sysfs_request<query::mgt_vtt_millivolts>        ("xmc", "xmc_mgtavtt");
  emplace_sysfs_request<query::int_vcc_millivolts>        ("xmc", "xmc_vccint_vol");
  emplace_sysfs_request<query::int_vcc_milliamps>         ("xmc", "xmc_vccint_curr");

  emplace_sysfs_request<query::v3v3_pex_milliamps>        ("xmc", "xmc_3v3_pex_curr");
  emplace_sysfs_request<query::v0v85_milliamps>           ("xmc", "xmc_0v85_curr");
  emplace_sysfs_request<query::v3v3_vcc_millivolts>       ("xmc", "xmc_3v3_vcc_vol");
  emplace_sysfs_request<query::hbm_1v2_millivolts>        ("xmc", "xmc_hbm_1v2_vol");
  emplace_sysfs_request<query::v2v5_vpp_millivolts>       ("xmc", "xmc_vpp2v5_vol");
  emplace_sysfs_request<query::int_bram_vcc_millivolts>   ("xmc", "xmc_vccint_bram_vol");

  emplace_sysfs_request<query::firewall_detect_level>     ("firewall", "detected_level");
  emplace_sysfs_request<query::firewall_status>           ("firewall", "detected_status");
  emplace_sysfs_request<query::firewall_time_sec>         ("firewall", "detected_time");

  emplace_sysfs_request<query::power_microwatts>          ("xmc", "xmc_power");

  //emplace_sysfs_request<query::mig_ecc_enabled,         sp::_4, "ecc_enabled");
  //emplace_sysfs_request<query::mig_ecc_status,          sp::_4, "ecc_status");
  //emplace_sysfs_request<query::mig_ecc_ce_cnt,          sp::_4, "ecc_ce_cnt");
  //emplace_sysfs_request<query::mig_ecc_ue_cnt,          sp::_4, "ecc_ue_cnt");
  //emplace_sysfs_request<query::mig_ecc_ce_ffa,          sp::_4, "ecc_ce_ffa");
  //emplace_sysfs_request<query::mig_ecc_ue_ffa,          sp::_4, "ecc_ue_ffa");

  emplace_sysfs_request<query::flash_bar_offset>          ("flash", "bar_off");
  emplace_sysfs_request<query::is_mfg>                    ("", "mfg");
  emplace_sysfs_request<query::f_flash_type>              ("flash", "flash_type");
  emplace_sysfs_request<query::flash_type>                ("", "flash_type");
  emplace_sysfs_request<query::board_name>                ("", "board_name");
  emplace_func0_request<query::pcie_bdf,                  bdf>();
}

struct X { X() { initialize_query_table(); }};
static X x;

}

namespace xrt_core {

const query::request&
device_linux::
lookup_query(query::key_type query_key) const
{
  auto it = query_tbl.find(query_key);

  if (it == query_tbl.end()) {
    using qtype = std::underlying_type<query::key_type>::type;
    std::string err = boost::str( boost::format("The given query request ID (%d) is not supported on Linux.")
                                  % static_cast<qtype>(query_key));
    throw std::runtime_error(err);
  }

  return *(it->second);
}

device_linux::
device_linux(id_type device_id, bool user)
  : shim<device_pcie>(device_id, user)
{
}

device_linux::
device_linux(handle_type device_handle, id_type device_id)
  : shim<device_pcie>(device_handle, device_id)
{
}

void
device_linux::
read_dma_stats(boost::property_tree::ptree& pt) const
{
  auto handle = get_device_handle();

  xclDeviceUsage devstat = { 0 };
  xclGetUsageInfo(handle, &devstat);

  boost::property_tree::ptree pt_channels;
  for (unsigned int idx = 0; idx < XCL_DEVICE_USAGE_COUNT; ++idx) {
    boost::property_tree::ptree pt_dma;
    pt_dma.put( "id", std::to_string(get_device_id()));
    pt_dma.put( "h2c", xrt_core::utils::unit_convert(devstat.h2c[idx]) );
    pt_dma.put( "c2h", xrt_core::utils::unit_convert(devstat.c2h[idx]) );

    // Create our array of data
    pt_channels.push_back(std::make_pair("", pt_dma));
  }

  pt.add_child( "transfer_metrics.channels", pt_channels);
}

void
device_linux::
read(uint64_t offset, void* buf, uint64_t len) const
{
  if (auto err = pcidev::get_dev(get_device_id(), false)->pcieBarRead(offset, buf, len))
    throw error(err, "read failed");
}

void
device_linux::
write(uint64_t offset, const void* buf, uint64_t len) const
{
  if (auto err = pcidev::get_dev(get_device_id(), false)->pcieBarWrite(offset, buf, len))
    throw error(err, "write failed");
}

int
device_linux::
open(const std::string& subdev, int flag) const
{
  return pcidev::get_dev(get_device_id(), false)->open(subdev, flag);
}

void
device_linux::
close(int dev_handle) const
{
  pcidev::get_dev(get_device_id(), false)->close(dev_handle);
}

} // xrt_core

max_stars_repo_name: zohourih/XRT

max_issues_repo_name: zohourih/XRT

max_forks_repo_name: zohourih/XRT


text:
/*
 * StlFileProvider.hpp
 *
 *  Created on: Nov 15, 2012
 *      Author: petr
 */
#pragma once
#ifndef STLFILEPROVIDER_HPP_
#define STLFILEPROVIDER_HPP_

#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <limits>
#include <Eigen/Dense>
// #include <boost/iostreams/device/back_inserter.hpp>
// #include <boost/iostreams/stream.hpp>
// #include <boost/archive/binary_oarchive.hpp>
// #include <boost/archive/binary_iarchive.hpp>
// #include <boost/serialization/vector.hpp>
#include "TriangleElement.hpp"
#include "BoundingBox.hpp"
#include "FileProvider.hpp"

/// Loads the data from the STL file and creates geometry class which stores the elements inside.
template <typename GeometryManager, typename type>
class StlFileProvider : public FileProvider {

public:
	StlFileProvider(){};
	StlFileProvider(const char* file);

	virtual void readFile(const char* iname) {};

	friend std::ostream& operator<<(std::ostream& os, const StlFileProvider& provider);

};

///====================================
///          Implementation
///====================================

StlFileProvider::StlFileProvider(const char* file) {

	int rank; MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
	//readInputFile(file);

}

void StlFileProvider::readFile(const char* iname) {

	std::ifstream iFile;
	char          line[120];
	char          name[20];

	iFile.open(iname);

	// read first line and the name of the body from it
	if (!iFile.is_open()) {
		// file not existent or some other stuff
		// throw error? :)
	}

	// read first line and the name of the body from it
	iFile.getline(line, 120);

	sscanf(line, "%*s %s", name);

	long int nElements     = 0;
	long int nNormals      = 0;
	long int nVertices     = 0;
	int      nFacet        = 0;
	int      nOuter        = 0;
	int      vertexCounter = 0;

	/*aabb.maxX[0] = -std::numeric_limits<double>::max();
	aabb.maxX[1] = -std::numeric_limits<double>::max();
	aabb.maxX[2] = -std::numeric_limits<double>::max();

	aabb.minX[0] = std::numeric_limits<double>::max();
	aabb.minX[1] = std::numeric_limits<double>::max();
	aabb.minX[2] = std::numeric_limits<double>::max();
*/

	TriangleElement<double> workingElement;
	elements.reserve(11000000);

	std::vector<Eigen::Vector3d > vertices;

	// go through the rest of the lines and load the data
	while ( iFile.getline(line, 120)) {

		char flag[120];

		sscanf(line, "%s", flag);

		if ( strstr(line, "facet normal") ) {
			// load the normal, we do not use them, but lets read them
			double normal[3];
			sscanf(line, "%*s %*s %lf %lf %lf", &normal[0], &normal[1], &normal[2]);

			workingElement.ID = nElements; // simply element number

			nFacet++;
			nElements++;
			nNormals++;
		}
		if ( strstr(flag, "outer") ) {
			nOuter++;
			vertexCounter = 0;
		}
		if ( strstr(flag, "vertex")  != 0 ) {
			Eigen::Vector3d vertex;

			sscanf(line, "%*s %lf %lf %lf", &vertex[0],
										    &vertex[1],
										    &vertex[2]);

			if (aabb.maxX[0] < vertex[0])
				aabb.maxX[0] = vertex[0];
			if (aabb.maxX[1] < vertex[1])
				aabb.maxX[1] = vertex[1];
			if (aabb.maxX[2] < vertex[2])
				aabb.maxX[2] = vertex[2];

			if (aabb.minX[0] > vertex[0])
				aabb.minX[0] = vertex[0];
			if (aabb.minX[1] > vertex[1])
				aabb.minX[1] = vertex[1];
			if (aabb.minX[2] > vertex[2])
				aabb.minX[2] = vertex[2];

			vertices.push_back(vertex);

			nVertices++;
			vertexCounter++;
		}
		if ( strstr(flag, "endloop")  != 0 ) {
			nOuter--;
		}
		if ( strstr(line, "endfacet")) {

			// compute dx, dy, dz
			double dx;

			TriangleElement<double> tr(vertices[0], vertices[1], vertices[2], nElements);

			elements.push_back( tr );

//			std::cout << tr << std::endl;

			nFacet--;
			vertices.clear();
		}

		// read next line
		line[0] = 'X';

	}

	if ( (nFacet != 0) && (nOuter != 0) && ((nVertices/3) != nElements) ) {
		// file was loaded incorectly, some shit happened
		std::cout << "Error" << std::endl;
	}

	numberOfElements = nElements;
	dim              = 3;

//	std::cout << aabb << std::endl;

	iFile.close();

	// done loading elemenents

}

// ostream operators

std::ostream& operator<<(std::ostream& os, const StlFileProvider& provider) {

	os << "Dimension : " << provider.dim << std::endl;
	os << "Number of elements: " << provider.numberOfElements << std::endl;
	os << "Min DX : " << provider.mindx[0] << ", " << provider.mindx[1] << ", " << provider.mindx[2] << std::endl;
	os << "AABB : " << provider.aabb << std::endl;

    return os;
}

#endif /* STLFILEPROVIDER_HPP_ */

max_stars_repo_name: petrkotas/libLS

max_issues_repo_name: petrkotas/libLS

max_forks_repo_name: petrkotas/libLS


text:
/// @file AltWProjectVisGridder.cc
///
/// @copyright (c) 2007,2016 CSIRO
/// Australia Telescope National Facility (ATNF)
/// Commonwealth Scientific and Industrial Research Organisation (CSIRO)
/// PO Box 76, Epping NSW 1710, Australia
/// atnf-enquiries@csiro.au
///
/// This file is part of the ASKAP software distribution.
///
/// The ASKAP software distribution is free software: you can redistribute it
/// and/or modify it under the terms of the GNU General Public License as
/// published by the Free Software Foundation; either version 2 of the License,
/// or (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
/// GNU General Public License for more details.
///
/// You should have received a copy of the GNU General Public License
/// along with this program; if not, write to the Free Software
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
///

// Package level header file
#include <askap_synthesis.h>

// System includes
#include <cmath>

// ASKAPsoft includes
#include <askap/AskapLogging.h>
#include <askap/AskapError.h>
#include <askap/AskapUtil.h>
#include <casacore/casa/Arrays/Array.h>
#include <casacore/casa/Arrays/ArrayMath.h>
#include <casacore/casa/BasicSL/Constants.h>
#include <fft/FFTWrapper.h>
#include <profile/AskapProfiler.h>
//ASKAPSoft package includes
#include <gridding/WProjectVisGridder.h>
#include <gridding/SupportSearcher.h>
#include <utils/PaddingUtils.h>
#include <measurementequation/ImageParamsHelper.h>
#include <utils/ImageUtils.h>
#include <fft/FFTWrapper.h>
// Local package includes
#include "AltWProjectVisGridder.h"
#include <boost/lexical_cast.hpp>

ASKAP_LOGGER(logger, ".gridding.AltWProjectVisGridder");

namespace askap {
namespace synthesis {

AltWProjectVisGridder::AltWProjectVisGridder(const double wmax,
                                       const int nwplanes,
                                       const double cutoff,
                                       const int overSample,
                                       const int maxSupport,
                                       const int limitSupport,
                                       const std::string& name,
                                       const float alpha, const bool writeOut) :
        WProjectVisGridder(wmax, nwplanes, cutoff, overSample,maxSupport,limitSupport,name,alpha),
        itsWriteOut(writeOut)

{

}

AltWProjectVisGridder::~AltWProjectVisGridder()
{
}

/// Clone a copy of this Gridder
IVisGridder::ShPtr AltWProjectVisGridder::clone()
{
    return IVisGridder::ShPtr(new AltWProjectVisGridder(*this));
}

/// @brief static method to create gridder
/// @details Each gridder should have a static factory method, which is
/// able to create a particular type of the gridder and initialise it with
/// the parameters taken form the given parset. It is assumed that the
/// method receives a subset of parameters where the gridder name is already
/// taken out.
/// @param[in] parset input parset file
/// @return a shared pointer to the gridder instance
IVisGridder::ShPtr AltWProjectVisGridder::createGridder(const LOFAR::ParameterSet& parset)
{
    const double wmax = parset.getDouble("wmax", 35000.0);
    const int nwplanes = parset.getInt32("nwplanes", 65);
    const double cutoff = parset.getDouble("cutoff", 1e-3);
    const int oversample = parset.getInt32("oversample", 8);
    const int maxSupport = parset.getInt32("maxsupport", 256);
    const int limitSupport = parset.getInt32("limitsupport", 0);
    const string tablename = parset.getString("tablename", "");
    const float alpha=parset.getFloat("alpha", 1.);
    const bool writeOut=parset.getBool("dumpgrid",false);

    ASKAPLOG_INFO_STR(logger, "Gridding using (Alternate) W projection with " << nwplanes << " w-planes");
    boost::shared_ptr<AltWProjectVisGridder> gridder(new AltWProjectVisGridder(wmax, nwplanes,
            cutoff, oversample, maxSupport, limitSupport, tablename, alpha,writeOut));
    gridder->configureGridder(parset);
    gridder->configureWSampling(parset);
    return gridder;
}
void AltWProjectVisGridder::finaliseGrid(casa::Array<double>& out) {
    static int passThrough = 0;
    ASKAPTRACE("AltWProjectVisGridder::finaliseGrid");
    ASKAPLOG_INFO_STR(logger, "Using Alternate Finalise Grid ");
    ASKAPLOG_INFO_STR(logger, "There are " << itsGrid.size() << " grids");

    ASKAPDEBUGASSERT(itsGrid.size() > 0);
    // buffer for result as doubles
    casa::Array<double> dBuffer(itsGrid[0].shape());
    ASKAPDEBUGASSERT(dBuffer.shape().nelements()>=2);
    ASKAPDEBUGASSERT(itsShape == scimath::PaddingUtils::paddedShape(out.shape(),paddingFactor()));

    /// Loop over all grids Fourier transforming and accumulating
    for (unsigned int i=0; i<itsGrid.size(); i++) {
        casa::Array<casa::DComplex> scratch(itsGrid[i].shape());
        casa::convertArray<casa::DComplex,casa::Complex>(scratch, itsGrid[i]);

        if (itsWriteOut == true) {
          // for debugging
          ASKAPLOG_INFO_STR(logger, "Writing out Grids ");
          casa::Array<float> buf(scratch.shape());
          casa::convertArray<float,double>(buf,imag(scratch));
          string name = boost::lexical_cast<std::string>(passThrough) + "." + boost::lexical_cast<std::string>(i) + ".prefft.imag";
          scimath::saveAsCasaImage(name,buf);
          casa::convertArray<float,double>(buf,real(scratch));
          name = boost::lexical_cast<std::string>(passThrough) + "." + boost::lexical_cast<std::string>(i) + ".prefft.real";
          scimath::saveAsCasaImage(name,buf);
          /*
              // adjust values to extract part which gives a real symmetric FT and the remainder
              casa::Matrix<float> bufM(buf.nonDegenerate());
              for (int x=0; x<int(bufM.nrow()); ++x) {
                   for (int y=0; y<int(bufM.ncolumn())/2; ++y) {
                        const float val = 0.5*(bufM(x,y)+bufM(bufM.nrow() - x -1, bufM.ncolumn() - y -1));
                        bufM(x,y) = val;
                        bufM(bufM.nrow() - x -1, bufM.ncolumn() - y -1) = val;
                   }
              }
              scimath::saveAsCasaImage("uvcoverage.sympart",buf);
              casa::Matrix<casa::DComplex> scratchM(scratch.nonDegenerate());
              for (int x=0; x<int(scratchM.nrow()); ++x) {
                   for (int y=0; y<int(scratchM.ncolumn()); ++y) {
                        scratchM(x,y) -= double(bufM(x,y));
                    }
              }
              // as we ignore imaginary part after FT, make scratch hermitian to be fair
              for (int x=0; x<int(scratchM.nrow()); ++x) {
                   for (int y=0; y<int(scratchM.ncolumn())/2; ++y) {
                        const casa::DComplex val = 0.5*(scratchM(x,y)+
                              conj(scratchM(scratchM.nrow() - x -1, scratchM.ncolumn() - y -1)));
                        scratchM(x,y) = val;
                        scratchM(scratchM.nrow() - x -1, scratchM.ncolumn() - y -1) = conj(val);
                   }
              }
              casa::convertArray<float,double>(buf,imag(scratch));
              scimath::saveAsCasaImage("uvcoverage.asympart.imag",buf);
              casa::convertArray<float,double>(buf,real(scratch));
              scimath::saveAsCasaImage("uvcoverage.asympart.real",buf);
              scimath::fft2d(scratch, false);
              casa::convertArray<float,double>(buf,real(scratch));
              scimath::saveAsCasaImage("psf.asympart.real",buf);

              ASKAPCHECK(false, "Debug termination");
          */

        }

        scimath::fft2d(scratch, false);
        if (i==0) {
            toDouble(dBuffer, scratch);
        } else {
            casa::Array<double> work(dBuffer.shape());
            toDouble(work, scratch);
            dBuffer+=work;
        }
    }
    // Now we can do the convolution correction
    correctConvolution(dBuffer);
    dBuffer*=double(dBuffer.shape()(0))*double(dBuffer.shape()(1));
    out = scimath::PaddingUtils::extract(dBuffer,paddingFactor());
    passThrough++;
}

/// @brief assignment operator
/// @details Defined as private, so it can't be called (to enforce usage of the
/// copy constructor
/// @param[in] other input object
/// @return reference to itself
AltWProjectVisGridder& AltWProjectVisGridder::operator=(const AltWProjectVisGridder &)
{
    ASKAPTHROW(AskapError, "This method is not supposed to be called!");
    return *this;
}

} // namespace askap
} // namespace synthesis

ext: cc

max_stars_repo_name: steve-ord/askapsoft

max_issues_repo_name: ATNF/askapsoft

max_forks_repo_name: ATNF/askapsoft