<commit_before>
/* Interface for debugging- spawns a  prompt that will controll the main thread if it hits a specifies break point*/

#include <pthread.h>
#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "debug_simHandler.hpp"

using namespace std;

/*function prototypes*/
void *run_debugger(void * holder);
void parseline(string line);
int handle_command(string command);
void help();
void messageHandler(uint64_t* msg);
void debugSend(int command, string build);

/*to store the last input in the debugger*/
int lastInstruction = 0;
string lastBuild = "";

#define DEBUG 16
#define SIZE (sizeof(uint64_t))

static bool isPaused = false;
static void (*sendMessage)(int,int,uint64_t*);
static void (*pauseSimulation)(int);
static void (*unPauseSimulation)(void);

/*spawn the debbugging prompt as a separate thread to
  controll the main one*/
void (*initDebugger(void (*sendMsg)(int,int,uint64_t*),
		    void (*pauseSim)(int),
		    void (*unPauseSim)(void)))(uint64_t*){

  pthread_t tid;

  sendMessage = sendMsg;
  pauseSimulation = pauseSim;
  unPauseSimulation = unPauseSim;

  isPaused = true;
  pthread_create(&tid,NULL,run_debugger, NULL);

  return messageHandler;
}

/*to be called by the simulator to controll the debugger
 * or to display some info*/
void messageHandler(uint64_t* msg){

  int sizeMsg;
  int command = (int)msg[2];

  if (command == BREAKPOINT){
    sizeMsg = 2*SIZE;
    uint64_t msgSend[sizeMsg/SIZE];
    msgSend[0] = sizeMsg;
    msgSend[1] = DEBUG;
    msgSend[2] = PAUSE;
    sendMessage(-1,sizeMsg,(uint64_t*)msgSend);
    pauseSimulation(0);
    cout << (char*)&msg[3];
    isPaused = true;

  } else if (command == PRINTCONTENT){
    cout << (char*)&msg[3];
    isPaused = true;
  }
}

//continuously attend command line prompt for debugger
//when the system is not paused
void *run_debugger(void* holder){

  (void)holder;
  string inpt;

  while(true){
    if (isPaused){
      cout << ">";
      isPaused = false;
      getline(cin,inpt);
      //react to the input
      parseline(inpt);
    }
  }
  return NULL;
}

/*parses the command line and run the debugger*/
void parseline(string line){

  string build = "";
  int wordCount = 1;

  int command = NOTHING;

  /*empty input*/
  if (line == ""){
    //enterlast stored command
    debugSend(lastInstruction,lastBuild);
    return;
  }

  /*loop through input line*/
  for (unsigned int i = 0; i < line.length(); i++){

    /*parse line for words*/
    if (line[i]!=' '){
      build += line[i];

    } else {
      //exract the command
      if (wordCount == 1)
	command = handle_command(build);
    wordCount++;
    build = "";
    }
  }

  /*no whitespace at all-single word commands*/
  if (wordCount == 1){
    command = handle_command(build);

    if (command != BREAKPOINT && command!=DUMP){
      debugSend(command,"");
      lastInstruction = command;
      lastBuild = build;
      return;
    }
  }

  /*if not enough info - these  types must have a specification*/
  if ((command == BREAKPOINT||command == DUMP)&& wordCount == 1){
      cout << "Please specify- type help for options" << endl;
      isPaused = true;
      return;
  }

  /*handle breakpoints and dumps*/
  if (wordCount == 2){
	if (command == BREAKPOINT||command == DUMP)
	  debugSend(command,build);
	else
	  debugSend(command,"");
      lastInstruction = command;
      lastBuild = build;
  }
}

int stringType2Int(string type){
  if (type == "factDer"){
    return FACTDER;
  } else if (type == "factCon"){
    return FACTCON;
  } else if (type == "factRet"){
    return FACTRET;
  } else if (type == "sense"){
    return SENSE;
  } else if (type == "action"){
    return ACTION;
  } else if (type == "block"){
    return BLOCK;
  } else {
    cout << "unknown type-- enter help for options" << endl;
    return -1;
  }
}

/*constructs a message to be sent to the Simulator*/
void debugSend(int command, string build){

  int node;
  string name;
  int size;
  int type;
  char* nameSpot;

  if(command == CONTINUE){
    size = 2*SIZE;
    uint64_t msgCont[size/SIZE];
    msgCont[0] = size;
    msgCont[1] = DEBUG;
    msgCont[2] = UNPAUSE;
    /*broadcast unpause to all VMs*/
    sendMessage(-1,size,(uint64_t*)msgCont);
    unPauseSimulation();

  } else if (command == BREAKPOINT) {
    if (build[0] == ':'||build[0] == '@'){
      cout << "Please Specify a Type" << endl;
      isPaused = true;
      return;
    }
    type = stringType2Int(getType(build));
    if (type == -1){
      isPaused = true;
      return;
    }
    /*if no node specified broadcast to all*/
    if (getNode(build) == ""){
      node = -1;
    else
      node = atoi(getNode(build).c_str());
    name = getName(build);
    size = 3*SIZE + (name.length() + 1)
      + (SIZE - (name.length() + 1)%SIZE);
    uint64_t msgBreak[size/SIZE];
    msgBreak[0] = size;
    msgBreak[1] = DEBUG;
    msgBreak[2] = BREAKPOINT;
    msgBreak[3] = type;
    nameSpot = (char*)&msgBreak[4];
    memcpy(nameSpot,name.c_str(),name.length()+1);
    sendMessage(node,size,(uint64_t*)msgBreak);

  } else if (command == DUMP){
    node = atoi(build.c_str());
    size = 2*SIZE;
    uint64_t msgDump[size/SIZE];
    msgDump[0] = size;
    msgDump[1] = DEBUG;
    msgDump[2] = DUMP;
    sendMessage(node,size,(uint64_t*)msgDump);

  } else if (command == NOTHING){
    isPaused = true;
  }
  return;
}

/*recognizes and sets different modes for the debugger*/
int handle_command(string command){

  int retVal;

  if (command == "break"){
    retVal = BREAKPOINT;
  } else if (command == "help"||command == "h") {
    help();
    retVal = NOTHING;
  } else if (command == "run"|| command == "r") {
    retVal = CONTINUE;
  } else if (command == "dump"||command == "d") {
    retVal = DUMP;
  } else if (command == "continue"||command == "c"){
    retVal = CONTINUE;
  } else if (command == "quit"||command == "q"){
    exit(0);
  } else {
    cout << "unknown command: type 'help' for options " << endl;
    retVal = NOTHING;
  }
  return retVal;
}

/*prints the help screen*/
void help(){
  cout << endl;
  cout << "*******************************************************************" << endl;
  cout << endl;
  cout << "DEBUGGER HELP" << endl;
  cout << "\t-break <Specification>- set break point at specified place" << endl;
  cout << "\t\t-Specification Format:" << endl;
  cout << "\t\t  <type>:<name>@<block> OR" << endl;
  cout << "\t\t  <type>:<name>        OR" << endl;
  cout << "\t\t  <type>@<block>" << endl;
  cout << "\t\t    -type - [factRet|factDer|factCon|action|sense|block]" << endl;
  cout <<             "\t\t\t-a type MUST be specified" << endl;
  cout << "\t\t    -name - the name of certain type ex. the name of a fact" << endl;
  cout << "\t\t    -node - the number of the node" << endl;
  cout << "\t-dump or d <nodeID> <all> - dump the state of the system" << endl;
  cout << "\t-continue or c - continue execution" << endl;
  cout << "\t-run or r - start the program" << endl;
  cout << "\t-quit - exit debugger" << endl;
  cout << endl;
  cout << "\t-Press Enter to use last Input" << endl;
  cout << endl;
  cout << "*******************************************************************" << endl;
}

<commit_msg>fixed for andre's size specifications<commit_after>
/* Interface for debugging- spawns a  prompt that will controll the main thread if it hits a specifies break point*/

#include <pthread.h>
#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "debug_simHandler.hpp"

using namespace std;

/*function prototypes*/
void *run_debugger(void * holder);
void parseline(string line);
int handle_command(string command);
void help();
void messageHandler(uint64_t* msg);
void debugSend(int command, string build);

/*to store the last input in the debugger*/
int lastInstruction = 0;
string lastBuild = "";

#define DEBUG 16
#define SIZE (sizeof(uint64_t))

static bool isPaused = false;
static void (*sendMessage)(int,int,uint64_t*);
static void (*pauseSimulation)(int);
static void (*unPauseSimulation)(void);

/*spawn the debbugging prompt as a separate thread to
  controll the main one*/
void (*initDebugger(void (*sendMsg)(int,int,uint64_t*),
		    void (*pauseSim)(int),
		    void (*unPauseSim)(void)))(uint64_t*){

  pthread_t tid;

  sendMessage = sendMsg;
  pauseSimulation = pauseSim;
  unPauseSimulation = unPauseSim;

  isPaused = true;
  pthread_create(&tid,NULL,run_debugger, NULL);

  return messageHandler;
}

/*to be called by the simulator to controll the debugger
 * or to display some info*/
void messageHandler(uint64_t* msg){

  int sizeMsg;
  int command = (int)msg[2];

  if (command == BREAKPOINT){
    sizeMsg = 2*SIZE;
    uint64_t msgSend[sizeMsg/SIZE];
    msgSend[0] = sizeMsg;
    msgSend[1] = DEBUG;
    msgSend[2] = PAUSE;
    sendMessage(-1,sizeMsg+SIZE,(uint64_t*)msgSend);
    pauseSimulation(0);
    cout << (char*)&msg[3];
    isPaused = true;

  } else if (command == PRINTCONTENT){
    cout << (char*)&msg[3];
    isPaused = true;
  }
}

//continuously attend command line prompt for debugger
//when the system is not paused
void *run_debugger(void* holder){

  (void)holder;
  string inpt;

  while(true){
    if (isPaused){
      cout << ">";
      isPaused = false;
      getline(cin,inpt);
      //react to the input
      parseline(inpt);
    }
  }
  return NULL;
}

/*parses the command line and run the debugger*/
void parseline(string line){

  string build = "";
  int wordCount = 1;

  int command = NOTHING;

  /*empty input*/
  if (line == ""){
    //enterlast stored command
    debugSend(lastInstruction,lastBuild);
    return;
  }

  /*loop through input line*/
  for (unsigned int i = 0; i < line.length(); i++){

    /*parse line for words*/
    if (line[i]!=' '){
      build += line[i];

    } else {
      //exract the command
      if (wordCount == 1)
	command = handle_command(build);
    wordCount++;
    build = "";
    }
  }

  /*no whitespace at all-single word commands*/
  if (wordCount == 1){
    command = handle_command(build);

    if (command != BREAKPOINT && command!=DUMP){
      debugSend(command,"");
      lastInstruction = command;
      lastBuild = build;
      return;
    }
  }

  /*if not enough info - these  types must have a specification*/
  if ((command == BREAKPOINT||command == DUMP)&& wordCount == 1){
      cout << "Please specify- type help for options" << endl;
      isPaused = true;
      return;
  }

  /*handle breakpoints and dumps*/
  if (wordCount == 2){
	if (command == BREAKPOINT||command == DUMP)
	  debugSend(command,build);
	else
	  debugSend(command,"");
      lastInstruction = command;
      lastBuild = build;
  }
}

int stringType2Int(string type){
  if (type == "factDer"){
    return FACTDER;
  } else if (type == "factCon"){
    return FACTCON;
  } else if (type == "factRet"){
    return FACTRET;
  } else if (type == "sense"){
    return SENSE;
  } else if (type == "action"){
    return ACTION;
  } else if (type == "block"){
    return BLOCK;
  } else {
    cout << "unknown type-- enter help for options" << endl;
    return -1;
  }
}

/*constructs a message to be sent to the Simulator*/
void debugSend(int command, string build){

  int node;
  string name;
  int size;
  int type;
  char* nameSpot;

  if(command == CONTINUE){
    size = 2*SIZE;
    uint64_t msgCont[size/SIZE];
    msgCont[0] = size;
    msgCont[1] = DEBUG;
    msgCont[2] = UNPAUSE;
    /*broadcast unpause to all VMs*/
    sendMessage(-1,size+SIZE,(uint64_t*)msgCont);
    unPauseSimulation();

  } else if (command == BREAKPOINT) {
    if (build[0] == ':'||build[0] == '@'){
      cout << "Please Specify a Type" << endl;
      isPaused = true;
      return;
    }
    type = stringType2Int(getType(build));
    if (type == -1){
      isPaused = true;
      return;
    }
    /*if no node specified broadcast to all*/
    if (getNode(build) == "")
      node = -1;
    else
      node = atoi(getNode(build).c_str());
    name = getName(build);
    size = 3*SIZE + (name.length() + 1)
      + (SIZE - (name.length() + 1)%SIZE);
    uint64_t msgBreak[size/SIZE];
    msgBreak[0] = size;
    msgBreak[1] = DEBUG;
    msgBreak[2] = BREAKPOINT;
    msgBreak[3] = type;
    nameSpot = (char*)&msgBreak[4];
    memcpy(nameSpot,name.c_str(),name.length()+1);
    sendMessage(node,size+SIZE,(uint64_t*)msgBreak);

  } else if (command == DUMP){
    node = atoi(build.c_str());
    size = 2*SIZE;
    uint64_t msgDump[size/SIZE];
    msgDump[0] = size;
    msgDump[1] = DEBUG;
    msgDump[2] = DUMP;
    sendMessage(node,size+SIZE,(uint64_t*)msgDump);

  } else if (command == NOTHING){
    isPaused = true;
  }
  return;
}

/*recognizes and sets different modes for the debugger*/
int handle_command(string command){

  int retVal;

  if (command == "break"){
    retVal = BREAKPOINT;
  } else if (command == "help"||command == "h") {
    help();
    retVal = NOTHING;
  } else if (command == "run"|| command == "r") {
    retVal = CONTINUE;
  } else if (command == "dump"||command == "d") {
    retVal = DUMP;
  } else if (command == "continue"||command == "c"){
    retVal = CONTINUE;
  } else if (command == "quit"||command == "q"){
    exit(0);
  } else {
    cout << "unknown command: type 'help' for options " << endl;
    retVal = NOTHING;
  }
  return retVal;
}

/*prints the help screen*/
void help(){
  cout << endl;
  cout << "*******************************************************************" << endl;
  cout << endl;
  cout << "DEBUGGER HELP" << endl;
  cout << "\t-break <Specification>- set break point at specified place" << endl;
  cout << "\t\t-Specification Format:" << endl;
  cout << "\t\t  <type>:<name>@<block> OR" << endl;
  cout << "\t\t  <type>:<name>        OR" << endl;
  cout << "\t\t  <type>@<block>" << endl;
  cout << "\t\t    -type - [factRet|factDer|factCon|action|sense|block]" << endl;
  cout <<             "\t\t\t-a type MUST be specified" << endl;
  cout << "\t\t    -name - the name of certain type ex. the name of a fact" << endl;
  cout << "\t\t    -node - the number of the node" << endl;
  cout << "\t-dump or d <nodeID> <all> - dump the state of the system" << endl;
  cout << "\t-continue or c - continue execution" << endl;
  cout << "\t-run or r - start the program" << endl;
  cout << "\t-quit - exit debugger" << endl;
  cout << endl;
  cout << "\t-Press Enter to use last Input" << endl;
  cout << endl;
  cout << "*******************************************************************" << endl;
}

<|endoftext|>


<commit_before>/***************************************************************************
 *  mng/test_buf_streams.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de>
 *
 *  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)
 **************************************************************************/

//! \example mng/test_streams.cpp
//! This is an example of use of \c stxxl::buf_istream and \c stxxl::buf_ostream

#include <iostream>
#include <stxxl/mng>
#include <stxxl/bits/mng/buf_ostream.h>
#include <stxxl/bits/mng/buf_istream.h>

#define BLOCK_SIZE (1024 * 512)

typedef stxxl::typed_block<BLOCK_SIZE, int> block_type;
typedef stxxl::buf_ostream<block_type, stxxl::BIDArray<BLOCK_SIZE>::iterator> buf_ostream_type;
typedef stxxl::buf_istream<block_type, stxxl::BIDArray<BLOCK_SIZE>::iterator> buf_istream_type;

int main()
{
    const unsigned nblocks = 64;
    const unsigned nelements = nblocks * block_type::size;
    stxxl::BIDArray<BLOCK_SIZE> bids(nblocks);

    stxxl::block_manager * bm = stxxl::block_manager::get_instance();
    bm->new_blocks(stxxl::striping(), bids.begin(), bids.end());
    {
        buf_ostream_type out(bids.begin(), 2);
        for (unsigned i = 0; i < nelements; i++)
            out << i;
    }
    {
        buf_istream_type in(bids.begin(), bids.end(), 2);
        for (unsigned i = 0; i < nelements; i++)
        {
            int value;
            in >> value;
            if (value != int(i))
            {
                STXXL_ERRMSG("Error at position " << std::hex << i << " (" << value << ") block " << (i / block_type::size));
            }
        }
    }
    bm->delete_blocks(bids.begin(), bids.end());
}
<commit_msg>unmix int/unsigned<commit_after>/***************************************************************************
 *  mng/test_buf_streams.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de>
 *
 *  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)
 **************************************************************************/

//! \example mng/test_streams.cpp
//! This is an example of use of \c stxxl::buf_istream and \c stxxl::buf_ostream

#include <iostream>
#include <stxxl/mng>
#include <stxxl/bits/mng/buf_ostream.h>
#include <stxxl/bits/mng/buf_istream.h>

#define BLOCK_SIZE (1024 * 512)

typedef stxxl::typed_block<BLOCK_SIZE, unsigned> block_type;
typedef stxxl::buf_ostream<block_type, stxxl::BIDArray<BLOCK_SIZE>::iterator> buf_ostream_type;
typedef stxxl::buf_istream<block_type, stxxl::BIDArray<BLOCK_SIZE>::iterator> buf_istream_type;

int main()
{
    const unsigned nblocks = 64;
    const unsigned nelements = nblocks * block_type::size;
    stxxl::BIDArray<BLOCK_SIZE> bids(nblocks);

    stxxl::block_manager * bm = stxxl::block_manager::get_instance();
    bm->new_blocks(stxxl::striping(), bids.begin(), bids.end());
    {
        buf_ostream_type out(bids.begin(), 2);
        for (unsigned i = 0; i < nelements; i++)
            out << i;
    }
    {
        buf_istream_type in(bids.begin(), bids.end(), 2);
        for (unsigned i = 0; i < nelements; i++)
        {
            unsigned value;
            in >> value;
            if (value != i)
            {
                STXXL_ERRMSG("Error at position " << std::hex << i << " (" << value << ") block " << (i / block_type::size));
            }
        }
    }
    bm->delete_blocks(bids.begin(), bids.end());
}
<|endoftext|>


<commit_before>#include <luacpp/error.hpp>
#include <luacpp/lua.hpp>

namespace lua
{
	error::error(const char* what, int errcode) : std::runtime_error(what), err(errcode)
	{
	}

	int error::code()
	{
		return err;
	}
}
<commit_msg>Forgot to add updated doxygen comments to error.cpp<commit_after>#include <luacpp/error.hpp>
#include <luacpp/lua.hpp>

namespace lua
{
	error::error(const char* what) : std::runtime_error(what)
	{
	}
}
<|endoftext|>


<commit_before>/**
 *
 * OFDevCon Example Code Sprint
 * Camera Ribbon example
 * This example generates ribbons along the mouse trail that descend in space
 * When you click space bar, you can
 *
 * Created by James George for openFrameworks workshop at Waves Festival Vienna sponsored by Lichterloh and Pratersauna
 * Adapted during ofDevCon on 2/23/2012
 */

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
	//just set up the openFrameworks stuff
    ofSetFrameRate(60);
    ofSetVerticalSync(true);
    ofBackground(255);

	//initialize the variable so it's off at the beginning
    usecamera = false;
	pointsMax = 1000; //TODO: put this into the GUI

	//initialize kinect object
	//TODO: only initialize necessary sources
	kinect.open();
	kinect.initDepthSource();
	kinect.initColorSource();
	kinect.initInfraredSource();
	kinect.initBodySource();
	kinect.initBodyIndexSource();

	//set debugging variables
	debugging = false;//TODO: put this into the GUI
	previewScaleH = 1.0f;//TODO: put this into the GUI
	previewScaleW = 1.0f;//TODO: put this into the GUI

	//TODO: setup gui & text instructions for keypresses, etc.
	// change color settings
	// set mode to debugging

}

//--------------------------------------------------------------
void ofApp::update(){
	//don't move the points if we are using the camera
    if(!usecamera){
        ofVec3f sumOfAllPoints(0,0,0);
        for(unsigned int i = 0; i < points.size(); i++){
            points[i].z -= 4;
            sumOfAllPoints += points[i];
        }
        center = sumOfAllPoints / points.size();
    }

	/////////////////
	// Kinect
	///////////////////
	kinect.update();

	//--
	//Getting joint positions (skeleton tracking)
	//--
	//
	{
		auto bodies = kinect.getBodySource()->getBodies();
		for (auto body : bodies) {
			for (auto joint : body.joints) {
				//TODO: now do something with the joints
			}
		}
	}
	//
	//--

	//--
	//Getting bones (connected joints)
	//--
	//
	{
		// Note that for this we need a reference of which joints are connected to each other.
		// We call this the 'boneAtlas', and you can ask for a reference to this atlas whenever you like
		auto bodies = kinect.getBodySource()->getBodies();
		auto boneAtlas = ofxKinectForWindows2::Data::Body::getBonesAtlas();

		for (auto body : bodies) {
			for (auto bone : boneAtlas) {
				auto firstJointInBone = body.joints[bone.first];
				auto secondJointInBone = body.joints[bone.second];

				//TODO: now do something with the joints
			}
		}
	}
	//
	//--
}

//--------------------------------------------------------------
void ofApp::draw(){

	//if we're using the camera, start it.
	//everything that you draw between begin()/end() shows up from the view of the camera
    if(usecamera){
        camera.begin();
    }

	ofSetColor(0);
	//do the same thing from the first example...
    ofMesh mesh;
	mesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);
	for(unsigned int i = 1; i < points.size(); i++){

		//find this point and the next point
		ofVec3f thisPoint = points[i-1];
		ofVec3f nextPoint = points[i];

		//get the direction from one to the next.
		//the ribbon should fan out from this direction
		ofVec3f direction = (nextPoint - thisPoint);

		//get the distance from one point to the next
		float distance = direction.length();

		//get the normalized direction. normalized vectors always have a length of one
		//and are really useful for representing directions as opposed to something with length
		ofVec3f unitDirection = direction.getNormalized();

		//find both directions to the left and to the right
		ofVec3f toTheLeft = unitDirection.getRotated(-90, ofVec3f(0,0,1));
		ofVec3f toTheRight = unitDirection.getRotated(90, ofVec3f(0,0,1));

		//use the map function to determine the distance.
		//the longer the distance, the narrower the line.
		//this makes it look a bit like brush strokes
		float thickness = ofMap(distance, 0, 60, 20, 2, true);

		//calculate the points to the left and to the right
		//by extending the current point in the direction of left/right by the length
		ofVec3f leftPoint = thisPoint+toTheLeft*thickness;
		ofVec3f rightPoint = thisPoint+toTheRight*thickness;

		//add these points to the triangle strip
		mesh.addVertex(ofVec3f(leftPoint.x, leftPoint.y, leftPoint.z));
		mesh.addVertex(ofVec3f(rightPoint.x, rightPoint.y, rightPoint.z));
	}

	//end the shape
	mesh.draw();

	//if we're using the camera, take it away
    if(usecamera){
    	camera.end();
    }

	ofPushStyle();
	//TODO: move these hardcoded numbers into GUI
	ofEnableBlendMode(OF_BLENDMODE_SUBTRACT);
	ofSetColor(127);
	if (debugging) {
		kinect.getDepthSource()->draw(0, 0, previewWidth, previewHeight);  // note that the depth texture is RAW so may appear dark

																		   // Color is at 1920x1080 instead of 512x424 so we should fix aspect ratio
		float colorHeight = previewWidth * (kinect.getColorSource()->getHeight() / kinect.getColorSource()->getWidth());
		float colorTop = (previewHeight - colorHeight) / 2.0;

		kinect.getColorSource()->draw(previewWidth, 0 + colorTop, previewWidth, colorHeight);
		kinect.getBodySource()->drawProjected(previewWidth, 0 + colorTop, previewWidth, colorHeight);

		kinect.getInfraredSource()->draw(0, previewHeight, previewWidth, previewHeight);

		kinect.getBodyIndexSource()->draw(previewWidth, previewHeight, previewWidth, previewHeight);
		kinect.getBodySource()->drawProjected(previewWidth, previewHeight, previewWidth, previewHeight, ofxKFW2::ProjectionCoordinates::DepthCamera);
	}
	ofPopStyle();

}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
	switch (key) {

	case ' ':
		//hitting space key swaps the camera view
		usecamera = !usecamera;
		break;

	case 'd':
	case 'D':
		//hitting space key swaps the camera view
		debugging = !debugging;
		break;

	case 'f':
	case 'F':
		//hitting 'f' key toggles full screen mode
		ofToggleFullscreen();
		break;

	default:
		break;
	}

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){
}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){
	//if we are using the camera, the mouse moving should rotate it around the whole sculpture
    if(usecamera){
        float rotateAmount = ofMap(ofGetMouseX(), 0, ofGetWidth(), 0, 360);
        ofVec3f furthestPoint;
        if (points.size() > 0) {
            furthestPoint = points[0];
        }
        else
        {
            furthestPoint = ofVec3f(x, y, 0);
        }

        ofVec3f directionToFurthestPoint = (furthestPoint - center);
        ofVec3f directionToFurthestPointRotated = directionToFurthestPoint.getRotated(rotateAmount, ofVec3f(0,1,0));
        camera.setPosition(center + directionToFurthestPointRotated);
        camera.lookAt(center);
    }
	//otherwise add points like before
    else{
        ofVec3f mousePoint(x,y,0);
		if (points.size() < pointsMax) {
			points.push_back(mousePoint);
		}
		else {
			for (int i = 0; i < pointsMax-1; i++) {
				points[i] = points[i + 1];
			}
			points[pointsMax-1] = mousePoint;
		}
    }
}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){
	previewWidth = ofGetWindowWidth() / 2;
	previewHeight = ofGetWindowHeight() / 2;
}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>A bunch of "TODO" comments.<commit_after>/**
 *
 * OFDevCon Example Code Sprint
 * Camera Ribbon example
 * This example generates ribbons along the mouse trail that descend in space
 * When you click space bar, you can
 *
 * Created by James George for openFrameworks workshop at Waves Festival Vienna sponsored by Lichterloh and Pratersauna
 * Adapted during ofDevCon on 2/23/2012
 */

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
	//just set up the openFrameworks stuff
    ofSetFrameRate(60);//TODO: put this into the GUI
    ofSetVerticalSync(true);
    ofBackground(255);//TODO: put this into the GUI

	//initialize the variable so it's off at the beginning
    usecamera = false;
	pointsMax = 1000; //TODO: put this into the GUI

	//initialize kinect object
	//TODO: only initialize necessary sources
	kinect.open();
	kinect.initDepthSource();
	kinect.initColorSource();
	kinect.initInfraredSource();
	kinect.initBodySource();
	kinect.initBodyIndexSource();

	//set debugging variables
	debugging = false;//TODO: put this into the GUI
	previewScaleH = 1.0f;//TODO: put this into the GUI
	previewScaleW = 1.0f;//TODO: put this into the GUI

	//TODO: setup gui & text instructions for keypresses, etc.
	// change color settings
	// set mode to debugging

}

//--------------------------------------------------------------
void ofApp::update(){
	//don't move the points if we are using the camera
    if(!usecamera){
        ofVec3f sumOfAllPoints(0,0,0);
        for(unsigned int i = 0; i < points.size(); i++){
            points[i].z -= 4;
            sumOfAllPoints += points[i];
        }
        center = sumOfAllPoints / points.size();
    }

	/////////////////
	// Kinect
	///////////////////
	kinect.update();

	//--
	//Getting joint positions (skeleton tracking)
	//--
	//
	{
		auto bodies = kinect.getBodySource()->getBodies();
		for (auto body : bodies) {
			for (auto joint : body.joints) {
				//TODO: now do something with the joints
			}
		}
	}
	//
	//--

	//--
	//Getting bones (connected joints)
	//--
	//
	{
		// Note that for this we need a reference of which joints are connected to each other.
		// We call this the 'boneAtlas', and you can ask for a reference to this atlas whenever you like
		auto bodies = kinect.getBodySource()->getBodies();
		auto boneAtlas = ofxKinectForWindows2::Data::Body::getBonesAtlas();

		for (auto body : bodies) {
			for (auto bone : boneAtlas) {
				auto firstJointInBone = body.joints[bone.first];
				auto secondJointInBone = body.joints[bone.second];

				//TODO: now do something with the joints
			}
		}
	}
	//
	//--
}

//--------------------------------------------------------------
void ofApp::draw(){

	//if we're using the camera, start it.
	//everything that you draw between begin()/end() shows up from the view of the camera
    if(usecamera){
        camera.begin();
    }

	ofSetColor(0);//TODO: put this into the GUI
	//do the same thing from the first example...
    ofMesh mesh;
	mesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);
	for(unsigned int i = 1; i < points.size(); i++){

		//find this point and the next point
		ofVec3f thisPoint = points[i-1];
		ofVec3f nextPoint = points[i];

		//get the direction from one to the next.
		//the ribbon should fan out from this direction
		ofVec3f direction = (nextPoint - thisPoint);

		//get the distance from one point to the next
		float distance = direction.length();

		//get the normalized direction. normalized vectors always have a length of one
		//and are really useful for representing directions as opposed to something with length
		ofVec3f unitDirection = direction.getNormalized();

		//find both directions to the left and to the right
		ofVec3f toTheLeft = unitDirection.getRotated(-90, ofVec3f(0,0,1));
		ofVec3f toTheRight = unitDirection.getRotated(90, ofVec3f(0,0,1));

		//use the map function to determine the distance.
		//the longer the distance, the narrower the line.
		//this makes it look a bit like brush strokes
		float thickness = ofMap(distance, 0, 60, 20, 2, true);//TODO: put these constants into the GUI
															  //TODO: have tail shrink towards end so it disappears

		//calculate the points to the left and to the right
		//by extending the current point in the direction of left/right by the length
		ofVec3f leftPoint = thisPoint+toTheLeft*thickness;
		ofVec3f rightPoint = thisPoint+toTheRight*thickness;

		//add these points to the triangle strip
		mesh.addVertex(ofVec3f(leftPoint.x, leftPoint.y, leftPoint.z));
		mesh.addVertex(ofVec3f(rightPoint.x, rightPoint.y, rightPoint.z));
	}

	//end the shape
	mesh.draw();

	//if we're using the camera, take it away
    if(usecamera){
    	camera.end();
    }

	ofPushStyle();
	//TODO: move these hardcoded numbers into GUI
	ofEnableBlendMode(OF_BLENDMODE_SUBTRACT);//TODO: put this into the GUI
	ofSetColor(127);//TODO: put this into the GUI
	if (debugging) {
		kinect.getDepthSource()->draw(0, 0, previewWidth, previewHeight);  // note that the depth texture is RAW so may appear dark

		float colorHeight = previewWidth * (kinect.getColorSource()->getHeight() / kinect.getColorSource()->getWidth());
		float colorTop = (previewHeight - colorHeight) / 2.0;
		// Color is at 1920x1080 instead of 512x424 so we should fix aspect ratio

		kinect.getColorSource()->draw(previewWidth, 0 + colorTop, previewWidth, colorHeight);
		kinect.getBodySource()->drawProjected(previewWidth, 0 + colorTop, previewWidth, colorHeight);

		kinect.getInfraredSource()->draw(0, previewHeight, previewWidth, previewHeight);

		kinect.getBodyIndexSource()->draw(previewWidth, previewHeight, previewWidth, previewHeight);
		kinect.getBodySource()->drawProjected(previewWidth, previewHeight, previewWidth, previewHeight, ofxKFW2::ProjectionCoordinates::DepthCamera);
	}
	ofPopStyle();

}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
	switch (key) {

	case ' ':
		//hitting space key swaps the camera view
		usecamera = !usecamera;
		break;

	case 'd':
	case 'D':
		//hitting space key swaps the camera view
		debugging = !debugging;
		break;

	case 'f':
	case 'F':
		//hitting 'f' key toggles full screen mode
		ofToggleFullscreen();
		break;

	default:
		break;
	}

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){
}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){
	//if we are using the camera, the mouse moving should rotate it around the whole sculpture
    if(usecamera){
        float rotateAmount = ofMap(ofGetMouseX(), 0, ofGetWidth(), 0, 360);//TODO: put this into the GUI
        ofVec3f furthestPoint;
        if (points.size() > 0) {
            furthestPoint = points[0];
        }
        else
        {
            furthestPoint = ofVec3f(x, y, 0);
        }

        ofVec3f directionToFurthestPoint = (furthestPoint - center);
        ofVec3f directionToFurthestPointRotated = directionToFurthestPoint.getRotated(rotateAmount, ofVec3f(0,1,0));
        camera.setPosition(center + directionToFurthestPointRotated);
        camera.lookAt(center);
    }
	//otherwise add points like before
    else{
        ofVec3f mousePoint(x,y,0);
		if (points.size() < pointsMax) {
			points.push_back(mousePoint);
		}
		else {
			for (int i = 0; i < pointsMax-1; i++) {
				points[i] = points[i + 1];
			}
			points[pointsMax-1] = mousePoint;
		}
    }
}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){
	previewWidth = ofGetWindowWidth() / 2;
	previewHeight = ofGetWindowHeight() / 2;
}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>


<commit_before>/*
 * Copyright 2017 deepstreamHub GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License 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 <cstdio>

#include <algorithm>
#include <stdexcept>
#include <iterator>

#include <buffer.hpp>
#include <event.hpp>
#include <message_builder.hpp>

#include <cassert>

namespace deepstream
{

Event::Event(const SendFn& send) :
	send_(send)
{
	assert( send_ );
}

Event::SubscribeFnPtr Event::subscribe(const Name& name, const SubscribeFn& f)
{
	SubscribeFnPtr p_f( new SubscribeFn(f) );
	subscribe(name, p_f);

	return p_f;
}

void Event::subscribe(const Name& name, const SubscribeFnPtr& p_f)
{
	assert( p_f );

	if( name.empty() )
		throw std::invalid_argument( "Empty event subscription pattern" );

	auto ret = subscriber_map_.equal_range(name);
	SubscriberMap::iterator first = ret.first;
	SubscriberMap::iterator last = ret.second;

	if( first != last )
	{
		assert( first != subscriber_map_.end() );
		assert( first->first == name );
		assert( std::distance(first, last) == 1 );

		// avoid inserting duplicates
		SubscriberList& subscribers = first->second;
		assert( !subscribers.empty() );

		SubscriberList::const_iterator it =
			std::find( subscribers.cbegin(), subscribers.cend(), p_f );

		if( it == subscribers.cend() )
			subscribers.push_back(p_f);

		return;
	}

	subscriber_map_[name].push_back(p_f);

	MessageBuilder message(Topic::EVENT, Action::SUBSCRIBE);
	message.add_argument( name );
	send_(message);
}

void Event::unsubscribe(const Name& name)
{
	SubscriberMap::iterator it = subscriber_map_.find(name);

	if( it == subscriber_map_.end() )
		return;

	subscriber_map_.erase(it);

	MessageBuilder message(Topic::EVENT, Action::UNSUBSCRIBE);
	message.add_argument(name);
	send_(message);
}

void Event::unsubscribe(const Name& name, const SubscribeFnPtr& p_f)
{
	SubscriberMap::iterator it = subscriber_map_.find(name);

	if( it == subscriber_map_.end() )
		return;

	SubscriberList& subscribers = it->second;
	SubscriberList::iterator ju =
		std::find( subscribers.begin(), subscribers.end(), p_f );

	if( ju == subscribers.end() )
		return;

	subscribers.erase(ju);

	if( subscribers.empty() )
		unsubscribe(name);
}

void Event::listen(const std::string& pattern, const ListenFnPtr& p_f)
{
	ListenerMap::iterator it = listener_map_.find(pattern);

	if( it != listener_map_.end() )
		return;

	listener_map_[pattern] = p_f;

	MessageBuilder message(Topic::EVENT, Action::LISTEN);
	message.add_argument(pattern);
	send_(message);
}

void Event::unlisten(const std::string& pattern)
{
	ListenerMap::iterator it = listener_map_.find(pattern);

	if( it == listener_map_.end() )
		return;

	listener_map_.erase(it);

	MessageBuilder message(Topic::EVENT, Action::UNLISTEN);
	message.add_argument(pattern);
	send_(message);
}

void Event::notify_(const Message& message)
{
	assert( message.topic() == Topic::EVENT );

	switch( message.action() )
	{
		case Action::EVENT:
			assert( message.num_arguments() == 2 );
			notify_subscribers_(
				Name( message[0].cbegin(), message[0].cend() ),
				message[1]
			);
			break;

		default:
			assert(0);
	}
}

void Event::notify_subscribers_(const Name& name, const Buffer& data)
{
	SubscriberMap::iterator it = subscriber_map_.find(name);

	if( it == subscriber_map_.end() )
	{
		std::fprintf(
			stderr, "E|EVT: no subscriber named '%s'\n", name.c_str()
		);
		return;
	}

	assert( it->first == name );

	// Copying the list of subscribers is a necessity here because the callbacks
	// may unsubscribe during their execution and modifications of a subscriber
	// list may invalidate iterations and ranges. Also, copying the smart
	// pointer pointer here is a necessity because the referenced function may
	// decide to unsubscribe and in this case, the std::function object must not
	// be destructed. Copying ensures a non-zero reference count until `*p_f`
	// returns.
	// Finally, the iterator `it` may be invalid after executing a callback
	// because the list of subscribers for this `name` may have been erased.
	SubscriberList subscribers = it->second;
	it = subscriber_map_.end();

	for(const SubscribeFnPtr& p_f : subscribers)
	{
		auto f = *p_f;
		f(data);
	}
}

}
<commit_msg>Events: fix dangling reference to a temporary<commit_after>/*
 * Copyright 2017 deepstreamHub GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License 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 <cstdio>

#include <algorithm>
#include <stdexcept>
#include <iterator>

#include <buffer.hpp>
#include <event.hpp>
#include <message_builder.hpp>

#include <cassert>

namespace deepstream
{

Event::Event(const SendFn& send) :
	send_(send)
{
	assert( send_ );
}

Event::SubscribeFnPtr Event::subscribe(const Name& name, const SubscribeFn& f)
{
	SubscribeFnPtr p_f( new SubscribeFn(f) );
	subscribe(name, p_f);

	return p_f;
}

void Event::subscribe(const Name& name, const SubscribeFnPtr& p_f)
{
	assert( p_f );

	if( name.empty() )
		throw std::invalid_argument( "Empty event subscription pattern" );

	auto ret = subscriber_map_.equal_range(name);
	SubscriberMap::iterator first = ret.first;
	SubscriberMap::iterator last = ret.second;

	if( first != last )
	{
		assert( first != subscriber_map_.end() );
		assert( first->first == name );
		assert( std::distance(first, last) == 1 );

		// avoid inserting duplicates
		SubscriberList& subscribers = first->second;
		assert( !subscribers.empty() );

		SubscriberList::const_iterator it =
			std::find( subscribers.cbegin(), subscribers.cend(), p_f );

		if( it == subscribers.cend() )
			subscribers.push_back(p_f);

		return;
	}

	subscriber_map_[name].push_back(p_f);

	MessageBuilder message(Topic::EVENT, Action::SUBSCRIBE);
	message.add_argument( name );
	send_(message);
}

void Event::unsubscribe(const Name& name)
{
	SubscriberMap::iterator it = subscriber_map_.find(name);

	if( it == subscriber_map_.end() )
		return;

	subscriber_map_.erase(it);

	MessageBuilder message(Topic::EVENT, Action::UNSUBSCRIBE);
	message.add_argument(name);
	send_(message);
}

void Event::unsubscribe(const Name& name, const SubscribeFnPtr& p_f)
{
	SubscriberMap::iterator it = subscriber_map_.find(name);

	if( it == subscriber_map_.end() )
		return;

	SubscriberList& subscribers = it->second;
	SubscriberList::iterator ju =
		std::find( subscribers.begin(), subscribers.end(), p_f );

	if( ju == subscribers.end() )
		return;

	subscribers.erase(ju);

	if( subscribers.empty() )
		unsubscribe(name);
}

void Event::listen(const std::string& pattern, const ListenFnPtr& p_f)
{
	ListenerMap::iterator it = listener_map_.find(pattern);

	if( it != listener_map_.end() )
		return;

	listener_map_[pattern] = p_f;

	MessageBuilder message(Topic::EVENT, Action::LISTEN);
	message.add_argument(pattern);
	send_(message);
}

void Event::unlisten(const std::string& pattern)
{
	ListenerMap::iterator it = listener_map_.find(pattern);

	if( it == listener_map_.end() )
		return;

	listener_map_.erase(it);

	MessageBuilder message(Topic::EVENT, Action::UNLISTEN);
	message.add_argument(pattern);
	send_(message);
}

void Event::notify_(const Message& message)
{
	assert( message.topic() == Topic::EVENT );

	const Buffer& arg0 = message[0];
	Name name( arg0.cbegin(), arg0.cend() );

	switch( message.action() )
	{
		case Action::EVENT:
			assert( message.num_arguments() == 2 );
			notify_subscribers_( name, message[1] );
			break;

		default:
			assert(0);
	}
}

void Event::notify_subscribers_(const Name& name, const Buffer& data)
{
	SubscriberMap::iterator it = subscriber_map_.find(name);

	if( it == subscriber_map_.end() )
	{
		std::fprintf(
			stderr, "E|EVT: no subscriber named '%s'\n", name.c_str()
		);
		return;
	}

	assert( it->first == name );

	// Copying the list of subscribers is a necessity here because the callbacks
	// may unsubscribe during their execution and modifications of a subscriber
	// list may invalidate iterations and ranges. Also, copying the smart
	// pointer pointer here is a necessity because the referenced function may
	// decide to unsubscribe and in this case, the std::function object must not
	// be destructed. Copying ensures a non-zero reference count until `*p_f`
	// returns.
	// Finally, the iterator `it` may be invalid after executing a callback
	// because the list of subscribers for this `name` may have been erased.
	SubscriberList subscribers = it->second;
	it = subscriber_map_.end();

	for(const SubscribeFnPtr& p_f : subscribers)
	{
		auto f = *p_f;
		f(data);
	}
}

}
<|endoftext|>


<commit_before><commit_msg>some code simplifications<commit_after><|endoftext|>


<commit_before>#include <mix/computer.h>
#include <mix/command.h>

#include <gtest/gtest.h>

using namespace mix;

namespace {

Command MakeSTA(int address, const WordField& field = Word::MaxField(), std::size_t index_register = 0)
{
	return Command{24, address, index_register, field};
}

Command MakeLDA(int address, const WordField& field = Word::MaxField(), std::size_t index_register = 0)
{
	return Command{8, address, index_register, field};
}

Command MakeADD(int address, const WordField& field = Word::MaxField(), std::size_t index_register = 0)
{
	return Command{1, address, index_register, field};
}

class ADD_TAOCP_Book_Test : public ::testing::Test
{
private:
	void SetUp() override
	{
		Register ra;
		ra.set_byte(1, Byte{1});
		ra.set_byte(2, Byte{1});
		ra.set_byte(3, Byte{1});
		ra.set_byte(4, Byte{1});
		ra.set_byte(5, Byte{1});
		mix.set_ra(ra);
	}

protected:
	Computer mix;
};

} // namespace

TEST_F(ADD_TAOCP_Book_Test, Register_A_Bytes_Sum)
{
	mix.execute(MakeSTA(2000));
	mix.execute(MakeLDA(2000, WordField{5, 5}));

	mix.execute(MakeADD(2000, WordField{4, 4}));
	mix.execute(MakeADD(2000, WordField{3, 3}));
	mix.execute(MakeADD(2000, WordField{2, 2}));
	mix.execute(MakeADD(2000, WordField{1, 1}));

	ASSERT_EQ(5, mix.ra().value());
}
<commit_msg>Add second example of ADD from TAOCP<commit_after>#include <mix/computer.h>
#include <mix/command.h>

#include <gtest/gtest.h>

using namespace mix;

namespace {

Command MakeSTA(int address, const WordField& field = Word::MaxField(), std::size_t index_register = 0)
{
	return Command{24, address, index_register, field};
}

Command MakeLDA(int address, const WordField& field = Word::MaxField(), std::size_t index_register = 0)
{
	return Command{8, address, index_register, field};
}

Command MakeADD(int address, const WordField& field = Word::MaxField(), std::size_t index_register = 0)
{
	return Command{1, address, index_register, field};
}
} // namespace

TEST(ADD_TAOCP_Book_Test, Register_A_Bytes_Sum)
{
	Computer mix;

	{
		Register ra;
		ra.set_byte(1, Byte{1});
		ra.set_byte(2, Byte{1});
		ra.set_byte(3, Byte{1});
		ra.set_byte(4, Byte{1});
		ra.set_byte(5, Byte{1});
		mix.set_ra(ra);
	}

	mix.execute(MakeSTA(2000));
	mix.execute(MakeLDA(2000, WordField{5, 5}));

	mix.execute(MakeADD(2000, WordField{4, 4}));
	mix.execute(MakeADD(2000, WordField{3, 3}));
	mix.execute(MakeADD(2000, WordField{2, 2}));
	mix.execute(MakeADD(2000, WordField{1, 1}));

	const auto result = mix.ra().value();
	const auto expected_result = 1 * 5;
	ASSERT_EQ(expected_result, result);
}

TEST(ADD_TAOCP_Book_Test, Simple_Addition)
{
	Computer mix;

	{
		Register ra;
		ra.set_value(1234, WordField{0, 2});
		ra.set_byte(3, Byte{1});
		ra.set_value(150, WordField{4, 5});
		mix.set_ra(ra);
	}

	{
		Word w;
		w.set_value(100, WordField{0, 2});
		w.set_byte(3, Byte{5});
		w.set_value(50, WordField{4, 5});
		mix.set_memory(1000, w);
	}

	mix.execute(MakeADD(1000));

	{
		ASSERT_EQ(1334, mix.ra().value(WordField{0, 2}));
		ASSERT_EQ(6, mix.ra().value(WordField{3, 3}));
		ASSERT_EQ(200, mix.ra().value(WordField{4, 5}));
	}
}

<|endoftext|>


<commit_before>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(std::string input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  for (char c : input) {
    if (c != delimiter) {
      word += c;
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "Invalid command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
  std::string input;

  struct timeval timeout;
  fd_set read_set;
  int file_desc = 0;
  int result;
  char receive_buffer[SAY_MAX];
  memset(&receive_buffer, 0, SAY_MAX);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  while(1) {
    FD_ZERO(&read_set);
    FD_SET(file_desc, &read_set);

    timeout.tv_sec = 0; // TODO change time value?
    timeout.tv_usec = 0;

//    if ((result = select(file_desc + 1, &read_set, NULL, NULL, NULL)) < 0) {
//      continue;
//    }
    if ((result = select(file_desc + 1, &read_set, NULL, NULL, &timeout)) < 0) {
      Error("client: problem using select");
    }

//    size_t size = sizeof(receive_buffer);

//    std::cout << "past select, result: " << result << std::endl;

    if (result > 0) {
      if (FD_ISSET(file_desc, &read_set)) {
        // Socket has data
        result = read(client_socket, receive_buffer, sizeof(receive_buffer));
      }

      if (result == 0) {
        close(file_desc);
      } else {
        // TODO capture user input, store, clean input, then print buffer, afterward replace input
        std::cout << "[" << channel << "]" << "[" << username << "]: " << receive_buffer << std::endl;
      }
    }

//    std::cout << "past check result" << std::endl;

//    std::cout << "> ";
//    getline(std::cin, input);
//
//    if (input[0] == '/') {
//      if (!ProcessInput(input)) {
//        break;
//      }
//    } else {
//      // Send chat messages
//      RequestSay(input.c_str());
//      std::cout << "[" << channel << "]" << "[" << username << "]: " << input << std::endl;
//    }

    std::cout << "> ";
    getline(std::cin, input);

    if (input[0] == '/') {
      if (!ProcessInput(input)) {
        break;
      }
    } else {
      // Send chat messages
      RequestSay(input.c_str());
      std::cout << "[" << channel << "]" << "[" << username << "]: " << input << std::endl;
    }

//    if (FD_ISSET(STDIN_FILENO, &read_set)) {
//      std::cout << "> ";
//      getline(std::cin, input);
//
//      if (input[0] == '/') {
//        if (!ProcessInput(input)) {
//          break;
//        }
//      } else {
//        // Send chat messages
//        RequestSay(input.c_str());
//        std::cout << "[" << channel << "]" << "[" << username << "]: " << input << std::endl;
//      }
//    }

//    std::cout << "past getline" << std::endl;

  }

  return 0;
}<commit_msg>fd_set read_set; read -> recv;<commit_after>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(std::string input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  for (char c : input) {
    if (c != delimiter) {
      word += c;
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "Invalid command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
  std::string input;

  struct timeval timeout;
  fd_set read_set;
  int file_desc = 0;
  int result;
  char receive_buffer[SAY_MAX];
  memset(&receive_buffer, 0, SAY_MAX);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  while(1) {
    FD_ZERO(&read_set);
    FD_SET(file_desc, &read_set);
    FD_SET(STDIN_FILENO, &read_set);

    timeout.tv_sec = 0; // TODO change time value?
    timeout.tv_usec = 0;

//    if ((result = select(file_desc + 1, &read_set, NULL, NULL, NULL)) < 0) {
//      continue;
//    }
    if ((result = select(file_desc + 1, &read_set, NULL, NULL, &timeout)) < 0) {
      Error("client: problem using select");
    }

//    size_t size = sizeof(receive_buffer);

//    std::cout << "past select, result: " << result << std::endl;

    if (result > 0) {
      if (FD_ISSET(file_desc, &read_set)) {
        // Socket has data
        result = recv(file_desc, receive_buffer, sizeof(receive_buffer), 0);

        FD_CLR(file_desc, &read_set);
        memset(&receive_buffer, 0, SAY_MAX);

        if (result == 0) {
          close(file_desc);
        } else {
          // TODO capture user input, store, clean input, then print buffer, afterward replace input
          std::cout << "[" << channel << "]" << "[" << username << "]: " << receive_buffer << std::endl;
        }
      }
    }

//    std::cout << "past check result" << std::endl;

//    std::cout << "> ";
//    getline(std::cin, input);
//
//    if (input[0] == '/') {
//      if (!ProcessInput(input)) {
//        break;
//      }
//    } else {
//      // Send chat messages
//      RequestSay(input.c_str());
//      std::cout << "[" << channel << "]" << "[" << username << "]: " << input << std::endl;
//    }

    if (FD_ISSET(STDIN_FILENO, &read_set)) {
      std::cout << "> ";
      getline(std::cin, input);

      if (input[0] == '/') {
        if (!ProcessInput(input)) {
          break;
        }
      } else {
        // Send chat messages
        RequestSay(input.c_str());
        std::cout << "[" << channel << "]" << "[" << username << "]: " << input << std::endl;
      }
    }

//    std::cout << "past getline" << std::endl;

  }

  return 0;
}<|endoftext|>


<commit_before>/***********************************************************************
 test_uds.cpp - Tests the Unix domain socket verifier in
 	UnixDomainSocketConnection.  This test always succeeds on Windows!

 Copyright (c) 2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the
 CREDITS file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ 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 Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>

#include <iostream>
#include <sstream>
#include <string>

#if !defined(MYSQLPP_PLATFORM_WINDOWS)
#include <unistd.h>
#include <fcntl.h>
#include <sys/un.h>
#include <sys/socket.h>

#include <errno.h>

static const char* success_path = "test_uds_success.sock";
static const char* failure_path = "test_uds_failure.sock";

static int
make_socket(const char* path, mode_t mode)
{
	// Just in case a socket with this name exists already, try to
	// remove it.  Only a failure if it exists and we can't remove it.
	if ((unlink(path) < 0) && (errno != ENOENT)) {
		return -1;
	}

	// Create the domain socket
	int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
	if (fd < 0) {
		return -1;
	}

	// Bind the socket to the named file
	struct sockaddr_un sun;
	memset(&sun, sizeof(sun), 0);
	sun.sun_family = AF_LOCAL;
	strncpy(sun.sun_path, path, sizeof(sun.sun_path));
	sun.sun_path[sizeof(sun.sun_path) - 1] = '\0';
	if (bind(fd, (sockaddr*)&sun, sizeof(sun)) < 0) {
		return -1;
	}

	// Change the socket's mode as requested
	if (chmod(path, mode) < 0) {
		return -1;
	}

	return fd;
}

static void
test_success()
{
	std::string error;
	int fd = make_socket(success_path, S_IREAD | S_IWRITE);
	if (fd >= 0) {
		bool fail = !mysqlpp::UnixDomainSocketConnection::is_socket(
				success_path, &error);
		if (fail) {
			throw mysqlpp::SelfTestFailed(error);
		}
	}
	else {
		std::ostringstream outs;
		outs << "Failed to create test domain socket: " << strerror(errno);
		throw mysqlpp::SelfTestFailed(outs.str());
	}
}

static void
test_failure()
{
	int fd = make_socket(failure_path, S_IREAD);
	if (fd < 0) {
		std::ostringstream outs;
		outs << "Failed to create test domain socket: " << strerror(errno);
		throw mysqlpp::SelfTestFailed(outs.str());
	}

	if (mysqlpp::UnixDomainSocketConnection::is_socket(failure_path)) {
		throw mysqlpp::SelfTestFailed("Failed to fail on read-only socket");
	}
	else if (mysqlpp::UnixDomainSocketConnection::is_socket(
			"BogusBogus.sock")) {
		throw mysqlpp::SelfTestFailed("Failed to fail on bad file name");
	}
	else {
		close(fd);
		unlink(failure_path);
		fd = creat(failure_path, S_IREAD | S_IWRITE);
		bool success = mysqlpp::UnixDomainSocketConnection::is_socket(
				failure_path);
		if (success) {
			throw mysqlpp::SelfTestFailed("Failed to fail on non-socket");
		}
	}
}
#endif

int
main()
{
#if defined(MYSQLPP_PLATFORM_WINDOWS)
	// Test not appropriate to this platform.  Always succeed.
	return 0;
#else
	try {
		test_success();
		unlink(success_path);
		test_failure();
		unlink(failure_path);
		return 0;
	}
	catch (mysqlpp::SelfTestFailed& e) {
		std::cerr << "TCP address parse error: " << e.what() << std::endl;
		return 1;
	}
	catch (std::exception& e) {
		std::cerr << "Unexpected test failure: " << e.what() << std::endl;
		return 2;
	}
#endif
}
<commit_msg>#include fix for OS X<commit_after>/***********************************************************************
 test_uds.cpp - Tests the Unix domain socket verifier in
 	UnixDomainSocketConnection.  This test always succeeds on Windows!

 Copyright (c) 2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the
 CREDITS file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ 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 Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>

#include <iostream>
#include <sstream>
#include <string>

#if !defined(MYSQLPP_PLATFORM_WINDOWS)
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <errno.h>

static const char* success_path = "test_uds_success.sock";
static const char* failure_path = "test_uds_failure.sock";

static int
make_socket(const char* path, mode_t mode)
{
	// Just in case a socket with this name exists already, try to
	// remove it.  Only a failure if it exists and we can't remove it.
	if ((unlink(path) < 0) && (errno != ENOENT)) {
		return -1;
	}

	// Create the domain socket
	int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
	if (fd < 0) {
		return -1;
	}

	// Bind the socket to the named file
	struct sockaddr_un sun;
	memset(&sun, sizeof(sun), 0);
	sun.sun_family = AF_LOCAL;
	strncpy(sun.sun_path, path, sizeof(sun.sun_path));
	sun.sun_path[sizeof(sun.sun_path) - 1] = '\0';
	if (bind(fd, (sockaddr*)&sun, sizeof(sun)) < 0) {
		return -1;
	}

	// Change the socket's mode as requested
	if (chmod(path, mode) < 0) {
		return -1;
	}

	return fd;
}

static void
test_success()
{
	std::string error;
	int fd = make_socket(success_path, S_IREAD | S_IWRITE);
	if (fd >= 0) {
		bool fail = !mysqlpp::UnixDomainSocketConnection::is_socket(
				success_path, &error);
		if (fail) {
			throw mysqlpp::SelfTestFailed(error);
		}
	}
	else {
		std::ostringstream outs;
		outs << "Failed to create test domain socket: " << strerror(errno);
		throw mysqlpp::SelfTestFailed(outs.str());
	}
}

static void
test_failure()
{
	int fd = make_socket(failure_path, S_IREAD);
	if (fd < 0) {
		std::ostringstream outs;
		outs << "Failed to create test domain socket: " << strerror(errno);
		throw mysqlpp::SelfTestFailed(outs.str());
	}

	if (mysqlpp::UnixDomainSocketConnection::is_socket(failure_path)) {
		throw mysqlpp::SelfTestFailed("Failed to fail on read-only socket");
	}
	else if (mysqlpp::UnixDomainSocketConnection::is_socket(
			"BogusBogus.sock")) {
		throw mysqlpp::SelfTestFailed("Failed to fail on bad file name");
	}
	else {
		close(fd);
		unlink(failure_path);
		fd = creat(failure_path, S_IREAD | S_IWRITE);
		bool success = mysqlpp::UnixDomainSocketConnection::is_socket(
				failure_path);
		if (success) {
			throw mysqlpp::SelfTestFailed("Failed to fail on non-socket");
		}
	}
}
#endif

int
main()
{
#if defined(MYSQLPP_PLATFORM_WINDOWS)
	// Test not appropriate to this platform.  Always succeed.
	return 0;
#else
	try {
		test_success();
		unlink(success_path);
		test_failure();
		unlink(failure_path);
		return 0;
	}
	catch (mysqlpp::SelfTestFailed& e) {
		std::cerr << "TCP address parse error: " << e.what() << std::endl;
		return 1;
	}
	catch (std::exception& e) {
		std::cerr << "Unexpected test failure: " << e.what() << std::endl;
		return 2;
	}
#endif
}
<|endoftext|>


<commit_before>#include "Halide.h"

using namespace Halide;

int main(int argc, char** argv) {
    ImageParam input(UInt(32), 3, "input");
    input.dim(2).set_bounds(0, 4).set_stride(1).dim(0).set_stride(4);

    Var x, y, c;
    Func f("f");
    f(x, y, c) = input(x, y, c) + 1;
    f.bound(c, 0, 4)
     .reorder_storage(c, x, y)
     .reorder(c, x, y);

    f.compute_root();
    f.output_buffer().dim(2).set_bounds(0, 4).set_stride(1).dim(0).set_stride(4);

    Target target = get_target_from_environment();
    if (target.has_gpu_feature() || target.has_feature(Target::OpenGLCompute)) {
        f.unroll(c)
         .gpu_tile(x, y, 64, 64);
    }

    Func g("g");
    g(x, y, c) = f(x, y, c) - 1;
    g.bound(c, 0, CHANNELS)
     .reorder_storage(c, x, y)
     .reorder(c, x, y);
    if (target.has_gpu_feature() || target.has_feature(Target::OpenGLCompute)) {
        g.unroll(c)
         .gpu_tile(x, y, 64, 64);
    }
    g.output_buffer().dim(2).set_bounds(0, 4).set_stride(1).dim(0).set_stride(4);

    std::string fn_name = std::string("two_kernels_filter") + (argc > 1 ? argv[1] : "");
    g.compile_to_file(fn_name, {input}, fn_name);
}
<commit_msg>Fix last commit<commit_after>#include "Halide.h"

using namespace Halide;

int main(int argc, char** argv) {
    ImageParam input(UInt(32), 3, "input");
    input.dim(2).set_bounds(0, 4).set_stride(1).dim(0).set_stride(4);

    Var x, y, c;
    Func f("f");
    f(x, y, c) = input(x, y, c) + 1;
    f.bound(c, 0, 4)
     .reorder_storage(c, x, y)
     .reorder(c, x, y);

    f.compute_root();
    f.output_buffer().dim(2).set_bounds(0, 4).set_stride(1).dim(0).set_stride(4);

    Target target = get_target_from_environment();
    if (target.has_gpu_feature() || target.has_feature(Target::OpenGLCompute)) {
        f.unroll(c)
         .gpu_tile(x, y, 64, 64);
    }

    Func g("g");
    g(x, y, c) = f(x, y, c) - 1;
    g.bound(c, 0, 4)
     .reorder_storage(c, x, y)
     .reorder(c, x, y);
    if (target.has_gpu_feature() || target.has_feature(Target::OpenGLCompute)) {
        g.unroll(c)
         .gpu_tile(x, y, 64, 64);
    }
    g.output_buffer().dim(2).set_bounds(0, 4).set_stride(1).dim(0).set_stride(4);

    std::string fn_name = std::string("two_kernels_filter") + (argc > 1 ? argv[1] : "");
    g.compile_to_file(fn_name, {input}, fn_name);
}
<|endoftext|>


<commit_before><commit_msg>removing locally defined struct text_list<commit_after><|endoftext|>


<commit_before>// -*- mode: c++; coding: utf-8 -*-
/*! @file exact.cpp
    @brief Inplementation of ExactModel class
*/
#include "exact.hpp"
#include "util.hpp"

#include <functional>
#include <chrono>

#include <json.hpp>

#include <wtl/debug.hpp>
#include <wtl/exception.hpp>
#include <wtl/iostr.hpp>
#include <wtl/zfstream.hpp>
#include <wtl/algorithm.hpp>
#include <wtl/numeric.hpp>
#include <wtl/math.hpp>
#include <wtl/os.hpp>
#include <wtl/concurrent.hpp>

namespace likeligrid {

const std::vector<double> ExactModel::STEPS_ = {0.32, 0.16, 0.08, 0.04, 0.02, 0.01};
const std::vector<size_t> ExactModel::BREAKS_ = {5, 5, 5, 5, 5, 5};
bool ExactModel::SIGINT_RAISED_ = false;

ExactModel::ExactModel(const std::string& infile,
    const size_t max_sites,
    const unsigned int concurrency)
    : ExactModel(wtl::izfstream(infile), max_sites, concurrency) {HERE;}

ExactModel::ExactModel(
    std::istream& ist,
    const size_t max_sites,
    const unsigned int concurrency)
    : concurrency_(concurrency) {HERE;

    nlohmann::json jso;
    ist >> jso;
    names_ = jso["pathway"].get<std::vector<std::string>>();
    const size_t npath = names_.size();
    annot_.reserve(npath);
    for (const std::string& s: jso["annotation"]) {
        annot_.emplace_back(s);
    }
    std::cerr << "annot_: " << annot_ << std::endl;

    const size_t nsam = jso["sample"].size();
    std::vector<bits_t> all_genotypes;
    all_genotypes.reserve(nsam);
    for (const std::string& s: jso["sample"]) {
        all_genotypes.emplace_back(s);
    }

    genot_.reserve(nsam);
    const size_t ngene = jso["sample"].at(0).get<std::string>().size();
    nsam_with_s_.assign(ngene + 1, 0);  // at most
    std::valarray<double> s_gene(ngene);
    for (const auto& bits: all_genotypes) {
        const size_t s = bits.count();
        ++nsam_with_s_[s];
        if (s > max_sites) continue;
        genot_.push_back(bits);
        for (size_t j=0; j<ngene; ++j) {
            if (bits[j]) ++s_gene[j];
        }
    }
    wtl::rstrip(&nsam_with_s_);
    std::cerr << "Original N_s: " << nsam_with_s_ << std::endl;
    if (max_sites + 1 < nsam_with_s_.size()) {
        nsam_with_s_.resize(max_sites + 1);
        std::cerr << "Using N_s: " << nsam_with_s_ << std::endl;
    } else {
        std::cerr << "Note: -s is too large" << std::endl;
    }
    w_gene_ = s_gene / s_gene.sum();
    std::cerr << "s_gene : " << s_gene << std::endl;
    std::cerr << "w_gene_: " << w_gene_ << std::endl;

    mle_params_.resize(annot_.size());
    mle_params_ = 1.0;
}

void ExactModel::run(const bool writing) {HERE;
    while (stage_ < STEPS_.size()) {
        if (writing) {run_fout();} else {run_cout();}
    }
    --stage_;
    search_limits();
}

void ExactModel::run_fout() {HERE;
    const std::string outfile = init_meta();
    std::cerr << "mle_params_: " << mle_params_ << std::endl;
    if (outfile.empty()) return;
    const auto axes = make_vicinity(mle_params_, breaks(), radius());
    for (size_t j=0; j<names_.size(); ++j) {
        std::cerr << names_[j] << ": " << axes[j] << std::endl;
    }
    {
        wtl::ozfstream fout(outfile, std::ios::out | std::ios::app);
        std::cerr << "Writing: " << outfile << std::endl;
        run_impl(fout, wtl::itertools::product(axes));
    }
}

void ExactModel::run_cout() {HERE;
    const auto axes = make_vicinity(mle_params_, breaks(), radius());
    for (size_t j=0; j<names_.size(); ++j) {
        std::cerr << names_[j] << ": " << axes[j] << std::endl;
    }
    {
        std::stringstream sst;
        run_impl(sst, wtl::itertools::product(axes));
        std::cout << sst.str();
        read_results(sst);
    }
    std::cerr << "mle_params_: " << mle_params_ << std::endl;
    ++stage_;
}

void ExactModel::search_limits() const {HERE;
    {
        const std::vector<std::valarray<double>> axes(names_.size(), wtl::lin_spaced(200, 2.0, 0.01));
        wtl::ozfstream fout("uniaxis.tsv.gz");
        run_impl(fout, wtl::itertools::uniaxis(axes, mle_params_));
    }
    for (const auto& p: find_intersections(*this)) {
        std::cerr << p.first << ": " << p.second << std::endl;
        const auto axes = make_vicinity(p.second, 5, 0.02);
        wtl::ozfstream fout("limit-" + p.first + ".tsv.gz");
        //TODO: if exists
        run_impl(fout, wtl::itertools::product(axes));
    }
}

void ExactModel::run_impl(std::ostream& ost, wtl::itertools::Generator<std::valarray<double>>&& gen) const {HERE;
    std::cerr << skip_ << " to " << gen.max_count() << std::endl;
    if (skip_ == 0) {
        ost << "##max_count=" << gen.max_count() << "\n";
        ost << "##max_sites=" << nsam_with_s_.size() - 1 << "\n";
        ost << "##step=" << STEPS_.at(stage_) << "\n";
        ost << "loglik\t" << wtl::join(names_, "\t") << "\n";
        ost.flush();
    }

    wtl::Semaphore semaphore(concurrency_);
    auto task = [this,&semaphore](const std::valarray<double> th_path) {
        // argument is copied for thread
        auto buffer = wtl::make_oss();
        buffer << calc_loglik(th_path) << "\t"
               << wtl::str_join(th_path, "\t") << "\n";
        semaphore.unlock();
        return buffer.str();
    };

    std::deque<std::future<std::string>> futures;
    const auto min_interval = std::chrono::seconds(2);
    auto next_time = std::chrono::system_clock::now() + min_interval;
    size_t stars = 0;
    for (const auto& th_path: gen(skip_)) {
        semaphore.lock();
        futures.push_back(std::async(std::launch::async, task, th_path));
        auto now = std::chrono::system_clock::now();
        if (now > next_time) {
            next_time = now + min_interval;
            size_t progress = 0;
            while (wtl::is_ready(futures.front())) {
                ost << futures.front().get();
                futures.pop_front();
                ++progress;
            }
            if (progress > 0) {
                ost.flush();
                for (size_t n= 0.2 * gen.percent(); stars<n; ++stars) {
                    std::cerr << "*";
                }
            }
        }
        if (SIGINT_RAISED_) {throw wtl::KeyboardInterrupt();}
    }
    for (auto& ftr: futures) {
        ost << ftr.get();
    }
    for (; stars<20U; ++stars) {
        std::cerr << "*";
    }
}

inline std::valarray<size_t> to_indices(const bits_t& bits) {
    std::valarray<size_t> indices(bits.count());
    for (size_t i=0, j=0; i<indices.size(); ++j) {
        if (bits[j]) {
            indices[i] = j;
            ++i;
        }
    }
    return indices;
}

inline double slice_prod(const std::valarray<double>& coefs, const bits_t& bits) {
    double p = 1.0;
    for (size_t i=0; i<coefs.size(); ++i) {
        if (bits[i]) p *= coefs[i];
    }
    return p;
}

class Denoms {
  public:
    Denoms() = delete;
    Denoms(const std::valarray<double>& w_gene,
        const std::valarray<double>& th_path,
        const std::vector<bits_t>& annot,
        const size_t max_sites):
        w_gene_(w_gene),
        th_path_(th_path),
        annot_(annot),
        max_sites_(max_sites),
        denoms_(max_sites + 1)
    {
        const size_t ngene = w_gene.size();
        effects_.reserve(ngene);
        for (size_t j=0; j<ngene; ++j) {
            effects_.emplace_back(translate(j));
        }
        // std::cerr << "effects_: " << effects_ << std::endl;
        mutate(bits_t(), bits_t(), 1.0);
        // std::cerr << "denoms_: " << denoms_ << std::endl;
    }
    const std::valarray<double> log() const {return std::log(denoms_);}

    double lnp_sample(const bits_t& genotype) const {
        double p = 0.0;
        const double p_basic = slice_prod(w_gene_, genotype);
        auto mut_route = to_indices(genotype);
        do {
            p += p_basic * discount(mut_route);
        } while (std::next_permutation(std::begin(mut_route), std::end(mut_route)));
        return std::log(p);
    }

  private:
    void mutate(const bits_t& genotype, const bits_t& pathtype, const double anc_p) {
        const auto s = genotype.count() + 1;
        for (size_t j=0; j<w_gene_.size(); ++j) {
            if (genotype[j]) continue;
            const bits_t& mut_path = effects_[j];
            double p = anc_p;
            p *= w_gene_[j];
            p *= discount_if_subset(pathtype, mut_path);
            denoms_[s] += p;
            if (s < max_sites_) {
                mutate(bits_t(genotype).set(j), pathtype | mut_path, p);
            }
        }
    }

    double discount_if_subset(const bits_t& pathtype, const bits_t& mut_path) const {
        double p = 1.0;
        for (size_t i=0; i<th_path_.size(); ++i) {
            if (mut_path[i]) {
                if (pathtype[i]) {
                    p *= th_path_[i];
                } else {
                    return 1.0;
                }
            }
        }
        return p;
    }

    double discount(const std::valarray<size_t>& mut_route) const {
        double p = 1.0;
        bits_t pathtype;
        for (const auto j: mut_route) {
            const auto& mut_path = effects_[j];
            p *= discount_if_subset(pathtype, mut_path);
            pathtype |= mut_path;
        }
        return p;
    }

    bits_t translate(const size_t& mut_idx) const {
        bits_t mut_path;
        for (size_t j=0; j<annot_.size(); ++j) {
            mut_path.set(j, annot_[j][mut_idx]);
        }
        return mut_path;
    }
    const std::valarray<double>& w_gene_;
    const std::valarray<double>& th_path_;
    const std::vector<bits_t>& annot_;
    const size_t max_sites_;
    std::valarray<double> denoms_;
    std::vector<bits_t> effects_;
};

double ExactModel::calc_loglik(const std::valarray<double>& th_path) const {
    const size_t max_sites = nsam_with_s_.size() - 1;
    Denoms subcalc(w_gene_, th_path, annot_, max_sites);
    double loglik = 0.0;
    for (const auto& genotype: genot_) {
        loglik += subcalc.lnp_sample(genotype);
    }
    const auto lnD = subcalc.log();
    // std::cout << "lnD: " << lnD << std::endl;
    // -inf, 0, D2, D3, ...
    for (size_t s=2; s<=max_sites; ++s) {
        loglik -= nsam_with_s_[s] * lnD[s];
    }
    return loglik;
}

std::string ExactModel::init_meta() {HERE;
    if (stage_ >= STEPS_.size()) return "";
    auto oss = wtl::make_oss(2, std::ios::fixed);
    oss << "grid-" << STEPS_.at(stage_) << ".tsv.gz";
    std::string outfile = oss.str();
    try {
        wtl::izfstream ist(outfile);
        std::cerr << "Reading: " << outfile << std::endl;
        read_results(ist);
        if (skip_ == 0) {
            ++stage_;
            outfile = init_meta();
        }
    } catch (std::ios::failure& e) {
        if (errno != 2) throw;
    }
    return outfile;
}

void ExactModel::read_results(std::istream& ist) {HERE;
    size_t max_count;
    double step;
    std::tie(max_count, std::ignore, step) = read_metadata(ist);
    stage_ = guess_stage(STEPS_, step);
    std::vector<std::string> colnames;
    std::valarray<double> mle_params;
    std::tie(skip_, colnames, mle_params) = read_body(ist);
    if (skip_ == max_count) {  // is complete file
        skip_ = 0;
        mle_params_.swap(mle_params);
    }
    if (names_ != colnames) {
        std::ostringstream oss;
        oss << "Contradiction in column names:\n"
            << "genotype file: " << names_ << "\n"
            << "result file:" << colnames;
        throw std::runtime_error(oss.str());
    }
}

void ExactModel::unit_test() {HERE;
    std::stringstream sst;
    sst <<
R"({
  "pathway": ["A", "B"],
  "annotation": ["0011", "1100"],
  "sample": ["0011", "0101", "1001", "0110", "1010", "1100"]
})";
    ExactModel model(sst, 4);
    model.run(false);
}

} // namespace likeligrid
<commit_msg>Round uniaxis<commit_after>// -*- mode: c++; coding: utf-8 -*-
/*! @file exact.cpp
    @brief Inplementation of ExactModel class
*/
#include "exact.hpp"
#include "util.hpp"

#include <functional>
#include <chrono>

#include <json.hpp>

#include <wtl/debug.hpp>
#include <wtl/exception.hpp>
#include <wtl/iostr.hpp>
#include <wtl/zfstream.hpp>
#include <wtl/algorithm.hpp>
#include <wtl/numeric.hpp>
#include <wtl/math.hpp>
#include <wtl/os.hpp>
#include <wtl/concurrent.hpp>

namespace likeligrid {

const std::vector<double> ExactModel::STEPS_ = {0.32, 0.16, 0.08, 0.04, 0.02, 0.01};
const std::vector<size_t> ExactModel::BREAKS_ = {5, 5, 5, 5, 5, 5};
bool ExactModel::SIGINT_RAISED_ = false;

ExactModel::ExactModel(const std::string& infile,
    const size_t max_sites,
    const unsigned int concurrency)
    : ExactModel(wtl::izfstream(infile), max_sites, concurrency) {HERE;}

ExactModel::ExactModel(
    std::istream& ist,
    const size_t max_sites,
    const unsigned int concurrency)
    : concurrency_(concurrency) {HERE;

    nlohmann::json jso;
    ist >> jso;
    names_ = jso["pathway"].get<std::vector<std::string>>();
    const size_t npath = names_.size();
    annot_.reserve(npath);
    for (const std::string& s: jso["annotation"]) {
        annot_.emplace_back(s);
    }
    std::cerr << "annot_: " << annot_ << std::endl;

    const size_t nsam = jso["sample"].size();
    std::vector<bits_t> all_genotypes;
    all_genotypes.reserve(nsam);
    for (const std::string& s: jso["sample"]) {
        all_genotypes.emplace_back(s);
    }

    genot_.reserve(nsam);
    const size_t ngene = jso["sample"].at(0).get<std::string>().size();
    nsam_with_s_.assign(ngene + 1, 0);  // at most
    std::valarray<double> s_gene(ngene);
    for (const auto& bits: all_genotypes) {
        const size_t s = bits.count();
        ++nsam_with_s_[s];
        if (s > max_sites) continue;
        genot_.push_back(bits);
        for (size_t j=0; j<ngene; ++j) {
            if (bits[j]) ++s_gene[j];
        }
    }
    wtl::rstrip(&nsam_with_s_);
    std::cerr << "Original N_s: " << nsam_with_s_ << std::endl;
    if (max_sites + 1 < nsam_with_s_.size()) {
        nsam_with_s_.resize(max_sites + 1);
        std::cerr << "Using N_s: " << nsam_with_s_ << std::endl;
    } else {
        std::cerr << "Note: -s is too large" << std::endl;
    }
    w_gene_ = s_gene / s_gene.sum();
    std::cerr << "s_gene : " << s_gene << std::endl;
    std::cerr << "w_gene_: " << w_gene_ << std::endl;

    mle_params_.resize(annot_.size());
    mle_params_ = 1.0;
}

void ExactModel::run(const bool writing) {HERE;
    while (stage_ < STEPS_.size()) {
        if (writing) {run_fout();} else {run_cout();}
    }
    --stage_;
    search_limits();
}

void ExactModel::run_fout() {HERE;
    const std::string outfile = init_meta();
    std::cerr << "mle_params_: " << mle_params_ << std::endl;
    if (outfile.empty()) return;
    const auto axes = make_vicinity(mle_params_, breaks(), radius());
    for (size_t j=0; j<names_.size(); ++j) {
        std::cerr << names_[j] << ": " << axes[j] << std::endl;
    }
    {
        wtl::ozfstream fout(outfile, std::ios::out | std::ios::app);
        std::cerr << "Writing: " << outfile << std::endl;
        run_impl(fout, wtl::itertools::product(axes));
    }
}

void ExactModel::run_cout() {HERE;
    const auto axes = make_vicinity(mle_params_, breaks(), radius());
    for (size_t j=0; j<names_.size(); ++j) {
        std::cerr << names_[j] << ": " << axes[j] << std::endl;
    }
    {
        std::stringstream sst;
        run_impl(sst, wtl::itertools::product(axes));
        std::cout << sst.str();
        read_results(sst);
    }
    std::cerr << "mle_params_: " << mle_params_ << std::endl;
    ++stage_;
}

void ExactModel::search_limits() const {HERE;
    {
        auto axis = wtl::round(wtl::lin_spaced(200, 2.0, 0.01), 100);
        axis = (axis * 100.0).apply(std::round) / 100.0;
        const std::vector<std::valarray<double>> axes(names_.size(), axis);
        wtl::ozfstream fout("uniaxis.tsv.gz");
        run_impl(fout, wtl::itertools::uniaxis(axes, mle_params_));
    }
    for (const auto& p: find_intersections(*this)) {
        std::cerr << p.first << ": " << p.second << std::endl;
        const auto axes = make_vicinity(p.second, 5, 0.02);
        wtl::ozfstream fout("limit-" + p.first + ".tsv.gz");
        //TODO: if exists
        run_impl(fout, wtl::itertools::product(axes));
    }
}

void ExactModel::run_impl(std::ostream& ost, wtl::itertools::Generator<std::valarray<double>>&& gen) const {HERE;
    std::cerr << skip_ << " to " << gen.max_count() << std::endl;
    if (skip_ == 0) {
        ost << "##max_count=" << gen.max_count() << "\n";
        ost << "##max_sites=" << nsam_with_s_.size() - 1 << "\n";
        ost << "##step=" << STEPS_.at(stage_) << "\n";
        ost << "loglik\t" << wtl::join(names_, "\t") << "\n";
        ost.flush();
    }

    wtl::Semaphore semaphore(concurrency_);
    auto task = [this,&semaphore](const std::valarray<double> th_path) {
        // argument is copied for thread
        auto buffer = wtl::make_oss();
        buffer << calc_loglik(th_path) << "\t"
               << wtl::str_join(th_path, "\t") << "\n";
        semaphore.unlock();
        return buffer.str();
    };

    std::deque<std::future<std::string>> futures;
    const auto min_interval = std::chrono::seconds(2);
    auto next_time = std::chrono::system_clock::now() + min_interval;
    size_t stars = 0;
    for (const auto& th_path: gen(skip_)) {
        semaphore.lock();
        futures.push_back(std::async(std::launch::async, task, th_path));
        auto now = std::chrono::system_clock::now();
        if (now > next_time) {
            next_time = now + min_interval;
            size_t progress = 0;
            while (wtl::is_ready(futures.front())) {
                ost << futures.front().get();
                futures.pop_front();
                ++progress;
            }
            if (progress > 0) {
                ost.flush();
                for (size_t n= 0.2 * gen.percent(); stars<n; ++stars) {
                    std::cerr << "*";
                }
            }
        }
        if (SIGINT_RAISED_) {throw wtl::KeyboardInterrupt();}
    }
    for (auto& ftr: futures) {
        ost << ftr.get();
    }
    for (; stars<20U; ++stars) {
        std::cerr << "*";
    }
}

inline std::valarray<size_t> to_indices(const bits_t& bits) {
    std::valarray<size_t> indices(bits.count());
    for (size_t i=0, j=0; i<indices.size(); ++j) {
        if (bits[j]) {
            indices[i] = j;
            ++i;
        }
    }
    return indices;
}

inline double slice_prod(const std::valarray<double>& coefs, const bits_t& bits) {
    double p = 1.0;
    for (size_t i=0; i<coefs.size(); ++i) {
        if (bits[i]) p *= coefs[i];
    }
    return p;
}

class Denoms {
  public:
    Denoms() = delete;
    Denoms(const std::valarray<double>& w_gene,
        const std::valarray<double>& th_path,
        const std::vector<bits_t>& annot,
        const size_t max_sites):
        w_gene_(w_gene),
        th_path_(th_path),
        annot_(annot),
        max_sites_(max_sites),
        denoms_(max_sites + 1)
    {
        const size_t ngene = w_gene.size();
        effects_.reserve(ngene);
        for (size_t j=0; j<ngene; ++j) {
            effects_.emplace_back(translate(j));
        }
        // std::cerr << "effects_: " << effects_ << std::endl;
        mutate(bits_t(), bits_t(), 1.0);
        // std::cerr << "denoms_: " << denoms_ << std::endl;
    }
    const std::valarray<double> log() const {return std::log(denoms_);}

    double lnp_sample(const bits_t& genotype) const {
        double p = 0.0;
        const double p_basic = slice_prod(w_gene_, genotype);
        auto mut_route = to_indices(genotype);
        do {
            p += p_basic * discount(mut_route);
        } while (std::next_permutation(std::begin(mut_route), std::end(mut_route)));
        return std::log(p);
    }

  private:
    void mutate(const bits_t& genotype, const bits_t& pathtype, const double anc_p) {
        const auto s = genotype.count() + 1;
        for (size_t j=0; j<w_gene_.size(); ++j) {
            if (genotype[j]) continue;
            const bits_t& mut_path = effects_[j];
            double p = anc_p;
            p *= w_gene_[j];
            p *= discount_if_subset(pathtype, mut_path);
            denoms_[s] += p;
            if (s < max_sites_) {
                mutate(bits_t(genotype).set(j), pathtype | mut_path, p);
            }
        }
    }

    double discount_if_subset(const bits_t& pathtype, const bits_t& mut_path) const {
        double p = 1.0;
        for (size_t i=0; i<th_path_.size(); ++i) {
            if (mut_path[i]) {
                if (pathtype[i]) {
                    p *= th_path_[i];
                } else {
                    return 1.0;
                }
            }
        }
        return p;
    }

    double discount(const std::valarray<size_t>& mut_route) const {
        double p = 1.0;
        bits_t pathtype;
        for (const auto j: mut_route) {
            const auto& mut_path = effects_[j];
            p *= discount_if_subset(pathtype, mut_path);
            pathtype |= mut_path;
        }
        return p;
    }

    bits_t translate(const size_t& mut_idx) const {
        bits_t mut_path;
        for (size_t j=0; j<annot_.size(); ++j) {
            mut_path.set(j, annot_[j][mut_idx]);
        }
        return mut_path;
    }
    const std::valarray<double>& w_gene_;
    const std::valarray<double>& th_path_;
    const std::vector<bits_t>& annot_;
    const size_t max_sites_;
    std::valarray<double> denoms_;
    std::vector<bits_t> effects_;
};

double ExactModel::calc_loglik(const std::valarray<double>& th_path) const {
    const size_t max_sites = nsam_with_s_.size() - 1;
    Denoms subcalc(w_gene_, th_path, annot_, max_sites);
    double loglik = 0.0;
    for (const auto& genotype: genot_) {
        loglik += subcalc.lnp_sample(genotype);
    }
    const auto lnD = subcalc.log();
    // std::cout << "lnD: " << lnD << std::endl;
    // -inf, 0, D2, D3, ...
    for (size_t s=2; s<=max_sites; ++s) {
        loglik -= nsam_with_s_[s] * lnD[s];
    }
    return loglik;
}

std::string ExactModel::init_meta() {HERE;
    if (stage_ >= STEPS_.size()) return "";
    auto oss = wtl::make_oss(2, std::ios::fixed);
    oss << "grid-" << STEPS_.at(stage_) << ".tsv.gz";
    std::string outfile = oss.str();
    try {
        wtl::izfstream ist(outfile);
        std::cerr << "Reading: " << outfile << std::endl;
        read_results(ist);
        if (skip_ == 0) {
            ++stage_;
            outfile = init_meta();
        }
    } catch (std::ios::failure& e) {
        if (errno != 2) throw;
    }
    return outfile;
}

void ExactModel::read_results(std::istream& ist) {HERE;
    size_t max_count;
    double step;
    std::tie(max_count, std::ignore, step) = read_metadata(ist);
    stage_ = guess_stage(STEPS_, step);
    std::vector<std::string> colnames;
    std::valarray<double> mle_params;
    std::tie(skip_, colnames, mle_params) = read_body(ist);
    if (skip_ == max_count) {  // is complete file
        skip_ = 0;
        mle_params_.swap(mle_params);
    }
    if (names_ != colnames) {
        std::ostringstream oss;
        oss << "Contradiction in column names:\n"
            << "genotype file: " << names_ << "\n"
            << "result file:" << colnames;
        throw std::runtime_error(oss.str());
    }
}

void ExactModel::unit_test() {HERE;
    std::stringstream sst;
    sst <<
R"({
  "pathway": ["A", "B"],
  "annotation": ["0011", "1100"],
  "sample": ["0011", "0101", "1001", "0110", "1010", "1100"]
})";
    ExactModel model(sst, 4);
    model.run(false);
}

} // namespace likeligrid
<|endoftext|>