<commit_before>/*
	Optimal Read Normalization Algorithm:
	Developed by : Dilip A Durai and Marcel H Schulz
*/

#include <gatb/gatb_core.hpp>
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>

typedef Kmer<>::Type bloom;
static const char* STR_BASE = "-base";
static const char* STR_INPUT = "-input";
static const char* STR_OUTPUT = "-output";
static const char* STR_KMER = "-kmer";
static const char* STR_PAIR1 = "-pair1";
static const char* STR_PAIR2 = "-pair2";

int readacceptance(Graph graph, Kmer<>::ModelCanonical::Iterator itKmer, Kmer<>::ModelCanonical model, unsigned short *counter, double base){
	int acceptance=0;
	for (itKmer.first(); !itKmer.isDone(); itKmer.next())
	{
		std::string s = model.toString (itKmer->value());
		const char* sq = s.c_str();
		Node node = graph.buildNode(sq);
		double threshold=0;
		//Checking whether the node exists.
		auto index = graph.nodeMPHFIndex(node);
		auto abund = graph.queryAbundance(node);
		threshold = ceil((log(abund)/log(base)));
		if(threshold>abund)
		{
			threshold=abund;
		}
		if(threshold<1)
		{
			threshold=1;
		}
		if(counter[index] < threshold)
		{
			acceptance=acceptance+1;
			break;
			//__sync_fetch_and_add (&counter[index], 1);
	       	}
	}
	return acceptance;
}

void singleend(const char* filename, const char* out_file, double base, unsigned short kmer, int nbCores)
{
	int count=0;
	//const char* error = getError(filename , pair1, pair2);

	Dispatcher dispatcher(nbCores) ;
	ISynchronizer* synchro = System::thread().newSynchronizer();	//Locking a section

	//Variables required for GATB
	IBank* bank = Bank::open (filename);
	ProgressIterator<Sequence> itSeq (*bank);
	IBank* outBank = new BankFasta (out_file);

	//Creating a graph and an iterator. from the parameters. The threshold value is kept as the minimum abundance parameter of the graph. kmer size is the actual kmer+1
	Graph graph = Graph::create (Bank::open(filename), "-kmer-size %d -abundance-min 1", kmer);
	GraphIterator<Node> it = graph.iterator();

	long node_size= it.size();
	unsigned short *counter = new unsigned short[node_size];

	//Initializing the counter for each node in the de Bruijn graph
	for(int i=0;i<node_size;i++)
	{
	    counter[i]=0;
	}

	//Iterating over sequences
	dispatcher.iterate (itSeq, [&] (Sequence& seq)
	{
		int length = seq.getDataSize();
		int flag=1;
		int gb = 1;
		int acceptance=0;

		Kmer<>::ModelCanonical model (kmer);
		Kmer<>::ModelCanonical::Iterator itKmer (model);
		itKmer.setData (seq.getData());
		char* data = seq.getDataBuffer();

		//checking the thresholding
		if(flag==1){
			acceptance=readacceptance(graph, itKmer, model, counter, base);
		}
		if(acceptance > 0)
		{
			for (itKmer.first(); !itKmer.isDone(); itKmer.next())
			{
				std::string s = model.toString (itKmer->value());
				const char* sq = s.c_str();
				Node node = graph.buildNode(sq);
				//Checking whether the node exists.
				if(graph.contains(node))
	       			{
					auto index = graph.nodeMPHFIndex(node);
					__sync_fetch_and_add (&counter[index], 1);
				}
			}
			synchro->lock();
			outBank->insert(seq);
			count++;
			synchro->unlock();
		}

	});
	std::cout << "Kept " << count << " reads" <<  std::endl;

	//Free the memory
	std::string filename1 = string(filename).substr(string(filename).find_last_of("/\\") + 1);
	size_t lindex = filename1.find_last_of(".");
	filename1 = (filename1.substr(0,lindex)) + string(".h5");
	remove(filename1.c_str());

	delete [] counter;
	bank->flush();
	outBank->flush();
}

void pairedend(const char* read1, const char* read2, const char* out_file, double base, unsigned short kmer )
{
	IBank* bank1 = Bank::open (read1);
	LOCAL (bank1);
        IBank* bank2 = Bank::open (read2);
	LOCAL (bank2);

	IBank* outBank = new BankFasta (out_file);

	Graph graph = Graph::create ("-in %s,%s -kmer-size %d -abundance-min 1", read1, read2, kmer);
	GraphIterator<Node> NodeIterator = graph.iterator();
	long node_size= NodeIterator.size();
	unsigned short *counter = new unsigned short[node_size];

	for(int i=0;i<node_size;i++)
        {
            counter[i]=0;
        }

	int cnt=0;
	int count=0;
	int num_sequence=0;
	int *pos;
	int size;
	int index;
	unsigned short length;
	int tmp=0;

	// We iterate the two banks. Note how we provide two iterators from the two banks.
        PairedIterator<Sequence> itPair (bank1->iterator(), bank2->iterator());
        for(itPair.first(); !itPair.isDone(); itPair.next())
        {
        	num_sequence++;
        }
        //int inisize=2;
	std::vector<int> tempBank;

	Kmer<>::ModelCanonical model (kmer);
	Kmer<>::ModelCanonical::Iterator itKmer (model);
	Kmer<>::ModelCanonical::Iterator itKmer1 (model);

	//Iteration 1

	for (itPair.first(); !itPair.isDone(); itPair.next())
        {
            Sequence& s1 = itPair.item().first;
            Sequence& s2 = itPair.item().second;

	    int acceptance1=0;
	    int acceptance2=0;

	    itKmer.setData (s1.getData());
	    itKmer1.setData (s2.getData());

	    //checking the thresholding
	    acceptance1 = readacceptance(graph, itKmer, model, counter, base);
	    acceptance2 = readacceptance(graph, itKmer1, model, counter, base);
	    if(acceptance1 > 0 && acceptance2>0)
	    {
		for (itKmer.first(); !itKmer.isDone(); itKmer.next())
	    	{
			std::string s = model.toString (itKmer->value());
			const char* sq = s.c_str();
			Node node = graph.buildNode(sq);
			double threshold=0;
			//Checking whether the node exists.
			if(graph.contains(node))
			{
				auto index = graph.nodeMPHFIndex(node);
				auto abund = graph.queryAbundance(node);
				threshold = ceil((log(abund)/log(base)));
				if(threshold>abund)
				{
					threshold=abund;
				}
				if(threshold<1)
				{
					threshold=1;
				}
				if(counter[index] < threshold)
				{
					counter[index]=counter[index]+1;
				}
			}
		}
		for (itKmer1.first(); !itKmer1.isDone(); itKmer1.next())
	    	{
			std::string s = model.toString (itKmer1->value());
			const char* sq = s.c_str();
			Node node = graph.buildNode(sq);
			double threshold=0;
			//Checking whether the node exists.
			if(graph.contains(node))
			{
				auto index = graph.nodeMPHFIndex(node);
				auto abund = graph.queryAbundance(node);
				threshold = ceil((log(abund)/log(base)));
				if(threshold>abund)
				{
					threshold=abund;
				}
				if(threshold<1)
				{
					threshold=1;
				}
				if(counter[index] < threshold)
				{
					counter[index]=counter[index]+1;
				}
			}
	    	}
	    	outBank->insert(s1);
		outBank->insert(s2);
		count++;
	    }
	    else if(acceptance1>0 || acceptance2>0){
	      	tempBank.push_back(tmp);
	    }
	    else{
	    }
	    tmp++;
        }

	int coun=0;
	int tmp_index=0;
	std::cout << "Second Iteration" <<  std::endl;

	for (itPair.first(); !itPair.isDone() && tmp_index<tempBank.size(); itPair.next())
	{
        	if(coun==tempBank[tmp_index])
        	{
		    Sequence& s1 = itPair.item().first;
		    Sequence& s2 = itPair.item().second;

		    int acceptance1=0;
		    int acceptance2=0;
		    int acceptance=0;

		    itKmer.setData (s1.getData());
		    itKmer1.setData (s2.getData());

		    //checking the thresholding
		    acceptance1 = readacceptance(graph, itKmer, model, counter, base);
		    acceptance2 = readacceptance(graph, itKmer1, model, counter, base);

		    if(acceptance1 > 0 || acceptance2 > 0)
		    {
			for (itKmer1.first(); !itKmer1.isDone(); itKmer1.next())
		    	{
				std::string s = model.toString (itKmer->value());
				const char* sq = s.c_str();
				Node node = graph.buildNode(sq);
				double threshold=0;
				//Checking whether the node exists.
				if(graph.contains(node)){
					auto index = graph.nodeMPHFIndex(node);
					auto abund = graph.queryAbundance(node);
					threshold = ceil((log(abund)/log(base)));
					if(threshold>abund){
						threshold=abund;
					}
					if(threshold<1){
						threshold=1;
					}
					if(counter[index] < threshold){
						counter[index]=counter[index]+1;
					}
				}
			}
			for (itKmer.first(); !itKmer.isDone(); itKmer.next())
		    	{
				std::string s = model.toString (itKmer->value());
				const char* sq = s.c_str();
				Node node = graph.buildNode(sq);
				double threshold=0;
				//Checking whether the node exists.
				if(graph.contains(node))
				{
					auto index = graph.nodeMPHFIndex(node);
					auto abund = graph.queryAbundance(node);
					threshold = ceil((log(abund)/log(base)));
					if(threshold>abund)
					{
						threshold=abund;
					}
					if(threshold<1)
					{
						threshold=1;
					}
					if(counter[index] < threshold)
					{
						counter[index]=counter[index]+1;
					}
				}
		    	}
			outBank->insert(s1);
			outBank->insert(s2);
			count++;
		   }
		   tmp_index++;
		}
		coun++;
        }
	std::cout << "kept " << count << " reads" <<  std::endl;
	bank1->flush();
	bank2->flush();
	delete [] counter;
	outBank->flush();
}

class ORNA : public Tool
{
public:
	ORNA(): Tool("ORNA")
	{
		getParser()->push_front (new OptionOneParam (STR_KMER, "kmer required",  false, "21"));
	        getParser()->push_front (new OptionOneParam (STR_INPUT, "Input File",  false, "ORNAERROR"));
	        getParser()->push_front (new OptionOneParam (STR_OUTPUT, "Output File",  false, "Normalized.fa"));
		getParser()->push_front (new OptionOneParam (STR_BASE, "Base for the logarithmic function",  false, "1.7"));
		getParser()->push_front (new OptionOneParam (STR_PAIR1, "First read of the pair", false, "ORNAERROR" ));
		getParser()->push_front (new OptionOneParam (STR_PAIR2, "Second read of the pair", false, "ORNAERROR" ));
	}
	void execute()
	{
		const char* filename = (getInput()->get(STR_INPUT))->getString();
		const char* read1= (getInput()->get(STR_PAIR1))->getString();
		const char* read2= (getInput()->get(STR_PAIR2))->getString();
		double base=getInput()->getDouble(STR_BASE);
		int user_kmer = getInput()->getInt(STR_KMER);
		const char* out_file= (getInput()->get(STR_OUTPUT))->getString();
		int nbCores = getInput()->getInt(STR_NB_CORES);
		unsigned short pairflag = 0;
		unsigned short kmer = user_kmer + 1;
		unsigned short cores = sysconf(_SC_NPROCESSORS_ONLN);
		if(nbCores==cores){
			nbCores=1;
		}
		if(std::strcmp(filename, "ORNAERROR") == 0)
		{
			if((std::strcmp(read1, "ORNAERROR") == 0) && (std::strcmp(read2, "ORNAERROR") == 0))
			{
				std::cout << "Input File(s) missing. Please refer to the help" << std::endl;
			}
			if (((std::strcmp(read1, "ORNAERROR") != 0) && (std::strcmp(read2, "ORNAERROR") == 0)) || ((std::strcmp(read1, "ORNAERROR") == 0) && (std::strcmp(read2, "ORNAERROR") != 0)))
			{
				std::cout << "One of the pair files is missing. Please refer to the help" << std::endl;
			}
			if((std::strcmp(read1, "ORNAERROR") != 0) && (std::strcmp(read2, "ORNAERROR") != 0))
			{
				pairflag = 1;
			}
		}
		if(pairflag==0)
		{
			std::cout << "Running ORNA in single end mode" << std::endl;
			singleend(filename, out_file, base, kmer, nbCores);
		}
		else
		{
			std::cout << "Running ORNA in paired end mode" << std::endl;
			pairedend(read1, read2, out_file, base, kmer);
		}
	}
};

int main (int argc, char* argv[])
{
	try{
		ORNA().run(argc,argv);
		return EXIT_SUCCESS;
	}
	catch(Exception& e){
		std::cout << "EXCEPTION: " << e.getMessage() << std::endl;
        	return EXIT_FAILURE;
	}

}

<commit_msg>Update main.cpp<commit_after>/*
	Optimal Read Normalization Algorithm:
	Developed by : Dilip A Durai and Marcel H Schulz
*/

#include <gatb/gatb_core.hpp>
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>

typedef Kmer<>::Type bloom;
static const char* STR_BASE = "-base";
static const char* STR_INPUT = "-input";
static const char* STR_OUTPUT = "-output";
static const char* STR_KMER = "-kmer";
static const char* STR_PAIR1 = "-pair1";
static const char* STR_PAIR2 = "-pair2";

int readacceptance(Graph graph, Kmer<>::ModelCanonical::Iterator itKmer, Kmer<>::ModelCanonical model, unsigned short *counter, double base){
	int acceptance=0;
	for (itKmer.first(); !itKmer.isDone(); itKmer.next())
	{
		std::string s = model.toString (itKmer->value());
		const char* sq = s.c_str();
		Node node = graph.buildNode(sq);
		double threshold=0;
		//Checking whether the node exists.
		auto index = graph.nodeMPHFIndex(node);
		auto abund = graph.queryAbundance(node);
		threshold = ceil((log(abund)/log(base)));
		if(threshold>abund)
		{
			threshold=abund;
		}
		if(threshold<1)
		{
			threshold=1;
		}
		if(counter[index] < threshold)
		{
			acceptance=acceptance+1;
			break;
			//__sync_fetch_and_add (&counter[index], 1);
	       	}
	}
	return acceptance;
}

void singleend(const char* filename, const char* out_file, double base, unsigned short kmer, int nbCores)
{
	int count=0;
	//const char* error = getError(filename , pair1, pair2);

	Dispatcher dispatcher(nbCores) ;
	ISynchronizer* synchro = System::thread().newSynchronizer();	//Locking a section

	//Variables required for GATB
	IBank* bank = Bank::open (filename);
	ProgressIterator<Sequence> itSeq (*bank);
	IBank* outBank = new BankFasta (out_file);

	//Creating a graph and an iterator. from the parameters. The threshold value is kept as the minimum abundance parameter of the graph. kmer size is the actual kmer+1
	Graph graph = Graph::create (Bank::open(filename), "-kmer-size %d -abundance-min 1", kmer);
	GraphIterator<Node> it = graph.iterator();

	long node_size= it.size();
	unsigned short *counter = new unsigned short[node_size];

	//Initializing the counter for each node in the de Bruijn graph
	for(int i=0;i<node_size;i++)
	{
	    counter[i]=0;
	}

	//Iterating over sequences
	dispatcher.iterate (itSeq, [&] (Sequence& seq)
	{
		int length = seq.getDataSize();
		int flag=1;
		int gb = 1;
		int acceptance=0;

		Kmer<>::ModelCanonical model (kmer);
		Kmer<>::ModelCanonical::Iterator itKmer (model);
		itKmer.setData (seq.getData());
		char* data = seq.getDataBuffer();

		//checking the thresholding
		if(flag==1){
			acceptance=readacceptance(graph, itKmer, model, counter, base);
		}
		if(acceptance > 0)
		{
			for (itKmer.first(); !itKmer.isDone(); itKmer.next())
			{
				std::string s = model.toString (itKmer->value());
				const char* sq = s.c_str();
				Node node = graph.buildNode(sq);
				//Checking whether the node exists.
				if(graph.contains(node))
	       			{
					auto index = graph.nodeMPHFIndex(node);
					__sync_fetch_and_add (&counter[index], 1);
				}
			}
			synchro->lock();
			outBank->insert(seq);
			count++;
			synchro->unlock();
		}

	});
	std::cout << "Kept " << count << " reads" <<  std::endl;

	//Free the memory
	std::string filename1 = string(filename).substr(string(filename).find_last_of("/\\") + 1);
	size_t lindex = filename1.find_last_of(".");
	filename1 = (filename1.substr(0,lindex)) + string(".h5");
	remove(filename1.c_str());

	delete [] counter;
	bank->flush();
	outBank->flush();
}

void pairedend(const char* read1, const char* read2, const char* out_file, double base, unsigned short kmer )
{
	IBank* bank1 = Bank::open (read1);
	LOCAL (bank1);
        IBank* bank2 = Bank::open (read2);
	LOCAL (bank2);

	IBank* outBank = new BankFasta (out_file);

	Graph graph = Graph::create ("-in %s,%s -kmer-size %d -abundance-min 1", read1, read2, kmer);
	GraphIterator<Node> NodeIterator = graph.iterator();
	long node_size= NodeIterator.size();
	unsigned short *counter = new unsigned short[node_size];

	for(int i=0;i<node_size;i++)
        {
            counter[i]=0;
        }

	int cnt=0;
	int count=0;
	int num_sequence=0;
	int *pos;
	int size;
	int index;
	unsigned short length;
	int tmp=0;

        PairedIterator<Sequence> itPair (bank1->iterator(), bank2->iterator());
        for(itPair.first(); !itPair.isDone(); itPair.next())
        {
        	num_sequence++;
        }
        std::vector<int> tempBank;

	Kmer<>::ModelCanonical model (kmer);
	Kmer<>::ModelCanonical::Iterator itKmer (model);
	Kmer<>::ModelCanonical::Iterator itKmer1 (model);

	//Iteration 1

	for (itPair.first(); !itPair.isDone(); itPair.next())
        {
            Sequence& s1 = itPair.item().first;
            Sequence& s2 = itPair.item().second;

	    int acceptance1=0;
	    int acceptance2=0;

	    itKmer.setData (s1.getData());
	    itKmer1.setData (s2.getData());

	    //checking the threshold
	    acceptance1 = readacceptance(graph, itKmer, model, counter, base);
	    acceptance2 = readacceptance(graph, itKmer1, model, counter, base);
	    if(acceptance1 > 0 && acceptance2>0)
	    {
		for (itKmer.first(); !itKmer.isDone(); itKmer.next())
	    	{
			std::string s = model.toString (itKmer->value());
			const char* sq = s.c_str();
			Node node = graph.buildNode(sq);
			double threshold=0;
			//Checking whether the node exists.
			if(graph.contains(node))
			{
				auto index = graph.nodeMPHFIndex(node);
				auto abund = graph.queryAbundance(node);
				threshold = ceil((log(abund)/log(base)));
				if(threshold>abund)
				{
					threshold=abund;
				}
				if(threshold<1)
				{
					threshold=1;
				}
				if(counter[index] < threshold)
				{
					counter[index]=counter[index]+1;
				}
			}
		}
		for (itKmer1.first(); !itKmer1.isDone(); itKmer1.next())
	    	{
			std::string s = model.toString (itKmer1->value());
			const char* sq = s.c_str();
			Node node = graph.buildNode(sq);
			double threshold=0;
			//Checking whether the node exists.
			if(graph.contains(node))
			{
				auto index = graph.nodeMPHFIndex(node);
				auto abund = graph.queryAbundance(node);
				threshold = ceil((log(abund)/log(base)));
				if(threshold>abund)
				{
					threshold=abund;
				}
				if(threshold<1)
				{
					threshold=1;
				}
				if(counter[index] < threshold)
				{
					counter[index]=counter[index]+1;
				}
			}
	    	}
	    	outBank->insert(s1);
		outBank->insert(s2);
		count++;
	    }
	    else if(acceptance1>0 || acceptance2>0){
	      	tempBank.push_back(tmp);
	    }
	    else{
	    }
	    tmp++;
        }

	int coun=0;
	int tmp_index=0;
	std::cout << "Second Iteration" <<  std::endl;

	for (itPair.first(); !itPair.isDone() && tmp_index<tempBank.size(); itPair.next())
	{
        	if(coun==tempBank[tmp_index])
        	{
		    Sequence& s1 = itPair.item().first;
		    Sequence& s2 = itPair.item().second;

		    int acceptance1=0;
		    int acceptance2=0;
		    int acceptance=0;

		    itKmer.setData (s1.getData());
		    itKmer1.setData (s2.getData());

		    //checking the thresholding
		    acceptance1 = readacceptance(graph, itKmer, model, counter, base);
		    acceptance2 = readacceptance(graph, itKmer1, model, counter, base);

		    if(acceptance1 > 0 || acceptance2 > 0)
		    {
			for (itKmer1.first(); !itKmer1.isDone(); itKmer1.next())
		    	{
				std::string s = model.toString (itKmer->value());
				const char* sq = s.c_str();
				Node node = graph.buildNode(sq);
				double threshold=0;
				//Checking whether the node exists.
				if(graph.contains(node)){
					auto index = graph.nodeMPHFIndex(node);
					auto abund = graph.queryAbundance(node);
					threshold = ceil((log(abund)/log(base)));
					if(threshold>abund){
						threshold=abund;
					}
					if(threshold<1){
						threshold=1;
					}
					if(counter[index] < threshold){
						counter[index]=counter[index]+1;
					}
				}
			}
			for (itKmer.first(); !itKmer.isDone(); itKmer.next())
		    	{
				std::string s = model.toString (itKmer->value());
				const char* sq = s.c_str();
				Node node = graph.buildNode(sq);
				double threshold=0;
				//Checking whether the node exists.
				if(graph.contains(node))
				{
					auto index = graph.nodeMPHFIndex(node);
					auto abund = graph.queryAbundance(node);
					threshold = ceil((log(abund)/log(base)));
					if(threshold>abund)
					{
						threshold=abund;
					}
					if(threshold<1)
					{
						threshold=1;
					}
					if(counter[index] < threshold)
					{
						counter[index]=counter[index]+1;
					}
				}
		    	}
			outBank->insert(s1);
			outBank->insert(s2);
			count++;
		   }
		   tmp_index++;
		}
		coun++;
        }
	std::cout << "kept " << count << " reads" <<  std::endl;
	bank1->flush();
	bank2->flush();
	delete [] counter;
	outBank->flush();
}

class ORNA : public Tool
{
public:
	ORNA(): Tool("ORNA")
	{
		getParser()->push_front (new OptionOneParam (STR_KMER, "kmer required",  false, "21"));
	        getParser()->push_front (new OptionOneParam (STR_INPUT, "Input File",  false, "ORNAERROR"));
	        getParser()->push_front (new OptionOneParam (STR_OUTPUT, "Output File",  false, "Normalized.fa"));
		getParser()->push_front (new OptionOneParam (STR_BASE, "Base for the logarithmic function",  false, "1.7"));
		getParser()->push_front (new OptionOneParam (STR_PAIR1, "First read of the pair", false, "ORNAERROR" ));
		getParser()->push_front (new OptionOneParam (STR_PAIR2, "Second read of the pair", false, "ORNAERROR" ));
	}
	void execute()
	{
		const char* filename = (getInput()->get(STR_INPUT))->getString();
		const char* read1= (getInput()->get(STR_PAIR1))->getString();
		const char* read2= (getInput()->get(STR_PAIR2))->getString();
		double base=getInput()->getDouble(STR_BASE);
		int user_kmer = getInput()->getInt(STR_KMER);
		const char* out_file= (getInput()->get(STR_OUTPUT))->getString();
		int nbCores = getInput()->getInt(STR_NB_CORES);
		unsigned short pairflag = 0;
		unsigned short kmer = user_kmer + 1;
		unsigned short cores = sysconf(_SC_NPROCESSORS_ONLN);
		if(nbCores==cores){
			nbCores=1;
		}
		if(std::strcmp(filename, "ORNAERROR") == 0)
		{
			if((std::strcmp(read1, "ORNAERROR") == 0) && (std::strcmp(read2, "ORNAERROR") == 0))
			{
				std::cout << "Input File(s) missing. Please refer to the help" << std::endl;
			}
			if (((std::strcmp(read1, "ORNAERROR") != 0) && (std::strcmp(read2, "ORNAERROR") == 0)) || ((std::strcmp(read1, "ORNAERROR") == 0) && (std::strcmp(read2, "ORNAERROR") != 0)))
			{
				std::cout << "One of the pair files is missing. Please refer to the help" << std::endl;
			}
			if((std::strcmp(read1, "ORNAERROR") != 0) && (std::strcmp(read2, "ORNAERROR") != 0))
			{
				pairflag = 1;
			}
		}
		if(pairflag==0)
		{
			std::cout << "Running ORNA in single end mode" << std::endl;
			singleend(filename, out_file, base, kmer, nbCores);
		}
		else
		{
			std::cout << "Running ORNA in paired end mode" << std::endl;
			pairedend(read1, read2, out_file, base, kmer);
		}
	}
};

int main (int argc, char* argv[])
{
	try{
		ORNA().run(argc,argv);
		return EXIT_SUCCESS;
	}
	catch(Exception& e){
		std::cout << "EXCEPTION: " << e.getMessage() << std::endl;
        	return EXIT_FAILURE;
	}

}

<|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <boost/tokenizer.hpp>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
using namespace boost;

/*TODO: refine the commandexec algorithm before proceeding further.
This current algorithm was an initial attempt.
It does not work, and will be replaced. */

//function for iterating through parsed string
void commandexec(vector<string> x)
{
	//position of iterator
	int pos = 0;
	while (pos < x.size())
	{
		//if 'ls' is found
		if (x.at(pos) == "ls")
		{
			int pid = fork();
			if (pid == -1) //if pid is -s, an error has occurred.
			{
				perror("fork");
				exit(1);
			}
			else if (pid == 0) //if pid is 0, you are in child process. execvp here.
			{
//				execvp(x.at(pos), x.at(pos+1));
			}
			else
				wait(0);
		}
	}
}

int main (int argc, char **argv)
{

	//bool value use to determine when to kill rshell loop
	bool killrshell = false;

	while (!killrshell)
	{

		//bool will store syntax error
		bool synerror = false;
		//string will store raw user input
		string rawinput;
		//vector of strings, will convert to array for execvp
		vector<string> cmds;

		//simple command prompt print
		printf("%s", "$ ");

		//obtain user input commands
		getline(cin, rawinput);

		//temporary break loop condition: user inputs 'exit'
		if (rawinput.substr(0,4) == "exit")
		{
			killrshell = true;
			break;
		}

		//parse through raw input and remove comments if entered
		//removes everything after '#'
		if (rawinput.find('#') != string::npos) rawinput = rawinput.substr(0, rawinput.find('#'));

		//TODO: Parse raw input string for commands and connectors
		char_separator<char> delim(" ", "|");
		tokenizer< char_separator<char> > mytok(rawinput);

		//tokenizer test: storing tokenized objects in a string
		string parsedinput;
		for(auto it = mytok.begin(); it != mytok.end(); ++it)
		{
			parsedinput += *it;
		}
		parsedinput += ";";
		//token test output loop
		cout << parsedinput << endl;

		//initial scan for syntax errors
		if (!isalpha(parsedinput.at(0))) synerror = true;

		//bool variable to tell when the inner for loop is done
		bool seploopdone = false;

		//iterate through string and separate into commands and connectors
		while (synerror != true && seploopdone == false)
		{
			string parsecmd;
			for (int i=0; i<parsedinput.size(); i++)
			{
				if (i >= parsedinput.size()-1) break; //accomodates for concatenated ; at the end of the string
				//checks for & and |
				if ( (parsedinput.at(i) == '&' || parsedinput.at(i) == '|') && parsedinput.at(i+1) == parsedinput.at(i) )
				{
					//if 3 &&& |||, or 1 & | -- syntax error
					if (parsedinput.at(i+2) == parsedinput.at(i))
					{
						synerror =true;
						break;
					}
					else if (parsedinput.at(i+1) != parsedinput.at(i))
					{
						synerror=true;
						break;
					}
					else
					{
						string con1;
						con1 += parsedinput.at(i);
						string con2;
						con2 += parsedinput.at(i+1);
						string constring = con1 + con2;
						cmds.push_back(constring);
						parsecmd.clear();
						i++;
					}
				}
				else
				{
					parsecmd += parsedinput.at(i);
					if (!isalpha(parsedinput.at(i+1)))
					{
						cmds.push_back(parsecmd);
						parsecmd.clear();
					}
				}
			}
			if(synerror = true) break;
			seploopdone = true;
		}

		//PARSING TEST OUTPUT
		for (int i=0; i<cmds.size(); i++)
			cout << cmds.at(i) << endl;

		//temporary input handling -- if exit was not entered, output the input.
		printf("\"%s\" was entered.\n", rawinput.c_str());

	}

	return 0;
}
<commit_msg>rewriting & debugging parsing algorithm.<commit_after>#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <boost/tokenizer.hpp>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
using namespace boost;

/*TODO: refine the commandexec algorithm before proceeding further.
This current algorithm was an initial attempt.
It does not work, and will be replaced. */

//function for iterating through parsed string
void commandexec(vector<string> x)
{
	//position of iterator
	int pos = 0;
	while (pos < x.size())
	{
		//if 'ls' is found
		if (x.at(pos) == "ls")
		{
			int pid = fork();
			if (pid == -1) //if pid is -s, an error has occurred.
			{
				perror("fork");
				exit(1);
			}
			else if (pid == 0) //if pid is 0, you are in child process. execvp here.
			{
//				execvp(x.at(pos), x.at(pos+1));
			}
			else
				wait(0);
		}
	}
}

int main (int argc, char **argv)
{

	//bool value use to determine when to kill rshell loop
	bool killrshell = false;

	while (!killrshell)
	{

		//bool will store syntax error
		bool synerror = false;
		//string will store raw user input
		string rawinput;
		//vector of strings, will convert to array for execvp
		vector<string> cmds;

		//simple command prompt print
		printf("%s", "$ ");

		//obtain user input commands
		getline(cin, rawinput);

		//temporary break loop condition: user inputs 'exit'
		if (rawinput.substr(0,4) == "exit")
		{
			killrshell = true;
			break;
		}

		//parse through raw input and remove comments if entered
		//removes everything after '#'
		if (rawinput.find('#') != string::npos) rawinput = rawinput.substr(0, rawinput.find('#'));

		//variables to keep track of whitespaces
		int wsbegin = 0;
		int wsend = 0;
		string parsedinput = rawinput;

		//first remove leading whitespaces at the very beginning of the string
		while (parsedinput.at(wsend) == ' ') wsend++;
		parsedinput = parsedinput.substr(wsend, parsedinput.size()-1);
		//then reinit wsend for removing inner whitespaces
		wsend = 0;

		//next remove trailing whitespaces at the end of the string
		wsbegin = parsedinput.size()-1;
		if(parsedinput.at(wsbegin) == ' ')
		{
			while (parsedinput.at(wsbegin) == ' ')
				--wsbegin;

			parsedinput = parsedinput.substr(0, wsbegin+1);
		}
		//then reinit wsbegin for removing inner whitespaces
		wsbegin = 0;

		//remove extra whitespaces in the middle of the string
		for (int i=0; i<parsedinput.size(); i++)
		{
		}

		parsedinput += ';';
		cout << "new input:" << parsedinput << endl;

		//initial scan for syntax errors
		if (!isalpha(parsedinput.at(0))) synerror = true;

		//bool variable to tell when the inner for loop is done
		bool seploopdone = false;

		//iterate through string and separate into commands and connectors
		while (synerror != true && seploopdone == false)
		{
			string parsecmd;
			for (int i=0; i<parsedinput.size(); i++)
			{
				if (i >= parsedinput.size()-1) break; //accomodates for concatenated ; at the end of the string
				//checks for & and |
				if ( (parsedinput.at(i) == '&' || parsedinput.at(i) == '|') && parsedinput.at(i+1) == parsedinput.at(i) )
				{
					//if 3 &&& |||, or 1 & | -- syntax error
					if (parsedinput.at(i+2) == parsedinput.at(i))
					{
						synerror =true;
						break;
					}
					else if (parsedinput.at(i+1) != parsedinput.at(i))
					{
						synerror=true;
						break;
					}
					else
					{
						string con1;
						con1 += parsedinput.at(i);
						string con2;
						con2 += parsedinput.at(i+1);
						string constring = con1 + con2;
						cmds.push_back(constring);
						parsecmd.clear();
						i++;
					}
				}
				else
				{
					parsecmd += parsedinput.at(i);
					if (!isalpha(parsedinput.at(i+1)))
					{
						cmds.push_back(parsecmd);
						parsecmd.clear();
					}
				}
			}
			if(synerror = true) break;
			seploopdone = true;
		}

		//PARSING TEST OUTPUT
		for (int i=0; i<cmds.size(); i++)
			cout << cmds.at(i) << endl;

		//temporary input handling -- if exit was not entered, output the input.
		printf("\"%s\" was entered.\n", rawinput.c_str());

	}

	return 0;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library 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.
 *
 * This library 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 this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_UTILS_HPP
#define MAPNIK_UTILS_HPP

#include <mapnik/config.hpp>

// boost
#ifdef MAPNIK_THREADSAFE
#include <boost/thread/mutex.hpp>
#endif

// stl
#include <stdexcept>
#include <cstdlib>
#include <limits>
#include <ctime>
#include <algorithm>
#include <cmath>

namespace mapnik
{

#ifdef MAPNIK_THREADSAFE
using boost::mutex;
#endif

template <typename T>
class CreateUsingNew
{
public:
    static T* create()
    {
        return new T;
    }
    static void destroy(T* obj)
    {
        delete obj;
    }
};

template <typename T>
class CreateStatic
{
private:
    union MaxAlign
    {
        char t_[sizeof(T)];
        short int shortInt_;
        int int_;
        long int longInt_;
        float float_;
        double double_;
        long double longDouble_;
        struct Test;
        int Test::* pMember_;
        int (Test::*pMemberFn_)(int);
    };

public:

    static T* create()
    {
        static MaxAlign staticMemory;
        return new(&staticMemory) T;
    }
#ifdef __SUNPRO_CC
// Sun C++ Compiler doesn't handle `volatile` keyword same as GCC.
    static void destroy(T* obj)
#else
        static void destroy(volatile T* obj)
#endif
    {
        obj->~T();
    }
};

#ifdef __GNUC__
template <typename T,
          template <typename U> class CreatePolicy=CreateStatic> class MAPNIK_DECL singleton
{
#else
    template <typename T,
              template <typename U> class CreatePolicy=CreateStatic> class singleton
    {
#endif

#ifdef __SUNPRO_CC
/* Sun's C++ compiler will issue the following errors if CreatePolicy<T> is used:
   Error: A class template name was expected instead of mapnik::CreatePolicy<mapnik::T>
   Error: A "friend" declaration must specify a class or function.
*/
        friend class CreatePolicy;
#else
        friend class CreatePolicy<T>;
#endif
        static T* pInstance_;
        static bool destroyed_;
        singleton(const singleton &rhs);
        singleton& operator=(const singleton&);

        static void onDeadReference()
        {
            throw std::runtime_error("dead reference!");
        }

        static void DestroySingleton()
        {
            CreatePolicy<T>::destroy(pInstance_);
            pInstance_ = 0;
            destroyed_ = true;
        }

    protected:
#ifdef MAPNIK_THREADSAFE
        static mutex mutex_;
#endif
        singleton() {}
    public:
        static T& instance()
        {
            if (! pInstance_)
            {
#ifdef MAPNIK_THREADSAFE
                mutex::scoped_lock lock(mutex_);
#endif
                if (! pInstance_)
                {
                    if (destroyed_)
                    {
                        destroyed_ = false;
                        onDeadReference();
                    }
                    else
                    {
                        pInstance_ = CreatePolicy<T>::create();

                        // register destruction
                        std::atexit(&DestroySingleton);
                    }
                }
            }
            return *pInstance_;
        }
    };
#ifdef MAPNIK_THREADSAFE
    template <typename T,
              template <typename U> class CreatePolicy> mutex singleton<T,CreatePolicy>::mutex_;
#endif

    template <typename T,
              template <typename U> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0;
    template <typename T,
              template <typename U> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false;

#ifdef _WINDOWS

// UTF8 <--> UTF16 conversion routines

MAPNIK_DECL std::string utf16_to_utf8(std::wstring const& wstr);
MAPNIK_DECL std::wstring utf8_to_utf16(std::string const& str);

#endif  // _WINDOWS

}

#endif // MAPNIK_UTILS_HPP
<commit_msg>drop suncc support from singleton class<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library 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.
 *
 * This library 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 this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_UTILS_HPP
#define MAPNIK_UTILS_HPP

#include <mapnik/config.hpp>

// boost
#ifdef MAPNIK_THREADSAFE
#include <boost/thread/mutex.hpp>
#endif

// stl
#include <stdexcept>
#include <cstdlib>
#include <limits>
#include <ctime>
#include <algorithm>
#include <cmath>

namespace mapnik
{

#ifdef MAPNIK_THREADSAFE
using boost::mutex;
#endif

template <typename T>
class CreateUsingNew
{
public:
    static T* create()
    {
        return new T;
    }
    static void destroy(T* obj)
    {
        delete obj;
    }
};

template <typename T>
class CreateStatic
{
private:
    union MaxAlign
    {
        char t_[sizeof(T)];
        short int shortInt_;
        int int_;
        long int longInt_;
        float float_;
        double double_;
        long double longDouble_;
        struct Test;
        int Test::* pMember_;
        int (Test::*pMemberFn_)(int);
    };

public:

    static T* create()
    {
        static MaxAlign staticMemory;
        return new(&staticMemory) T;
    }
    static void destroy(volatile T* obj)
    {
        obj->~T();
    }
};

template <typename T,
          template <typename U> class CreatePolicy=CreateStatic> class MAPNIK_DECL singleton
{
    friend class CreatePolicy<T>;
    static T* pInstance_;
    static bool destroyed_;
    singleton(const singleton &rhs);
    singleton& operator=(const singleton&);

    static void onDeadReference()
    {
        throw std::runtime_error("dead reference!");
    }

    static void DestroySingleton()
    {
        CreatePolicy<T>::destroy(pInstance_);
        pInstance_ = 0;
        destroyed_ = true;
    }

protected:

#ifdef MAPNIK_THREADSAFE
        static mutex mutex_;
#endif
        singleton() {}
    public:
        static T& instance()
        {
            if (! pInstance_)
            {
#ifdef MAPNIK_THREADSAFE
                mutex::scoped_lock lock(mutex_);
#endif
                if (! pInstance_)
                {
                    if (destroyed_)
                    {
                        destroyed_ = false;
                        onDeadReference();
                    }
                    else
                    {
                        pInstance_ = CreatePolicy<T>::create();

                        // register destruction
                        std::atexit(&DestroySingleton);
                    }
                }
            }
            return *pInstance_;
        }
};

#ifdef MAPNIK_THREADSAFE
    template <typename T,
              template <typename U> class CreatePolicy> mutex singleton<T,CreatePolicy>::mutex_;
#endif

    template <typename T,
              template <typename U> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0;
    template <typename T,
              template <typename U> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false;

#ifdef _WINDOWS

// UTF8 <--> UTF16 conversion routines

MAPNIK_DECL std::string utf16_to_utf8(std::wstring const& wstr);
MAPNIK_DECL std::wstring utf8_to_utf16(std::string const& str);

#endif  // _WINDOWS

}

#endif // MAPNIK_UTILS_HPP
<|endoftext|>


<commit_before>#include <iostream>
#include <string>

#include <string>
#include <channel/Channel.h>

using namespace channel;
using namespace std;

int main() {

    Channel<string> channel;
    auto& sink = channel.sink();
    auto& source = channel.source();

    sink.give("abcde");
    sink.give("12345");
    sink.give("hehe");
    sink.give("öä+");

    auto msgs1 = source.takeWithin(std::chrono::milliseconds(1));

    sink.give("wglalala");
    sink.give("1aeh2345");
    sink.give("heaeg4he");
    sink.give("öä+ga4");

    auto msgs2 = source.takeNow();

    for (const auto& msgs : { msgs1, msgs2 })
        for (const auto& msg : msgs)
            cout << msg << endl;

    return 0;
}

<commit_msg>Update main.cpp<commit_after>#include <iostream>
#include <string>

#include <channel/Channel.h>

using namespace channel;
using namespace std;

int main() {

    Channel<string> channel;
    auto& sink = channel.sink();
    auto& source = channel.source();

    sink.give("abcde");
    sink.give("12345");
    sink.give("hehe");
    sink.give("öä+");

    auto msgs1 = source.takeWithin(std::chrono::milliseconds(1));

    sink.give("wglalala");
    sink.give("1aeh2345");
    sink.give("heaeg4he");
    sink.give("öä+ga4");

    auto msgs2 = source.takeNow();

    for (const auto& msgs : { msgs1, msgs2 })
        for (const auto& msg : msgs)
            cout << msg << endl;

    return 0;
}

<|endoftext|>


<commit_before>#include <iostream>

#include <cuda_runtime.h>

#include <helper_math.h>

#include "path_tracer.hpp"

const float kAperatureRadius = 0.04;
const uint2 kResolution = make_uint2(512, 512);
const size_t kNumScenes = 2;

const std::string kSceneFiles[kNumScenes]{
    "../scenes/scene-1/scene01.obj", "../scenes/scene-2/scene02.obj",
};
const cupt::Camera kCameras[2]{
    cupt::Camera(kResolution, make_float3(0, 5, 10), make_float3(0, 0, -1),
                 make_float3(0, 1, 0), make_float2(90, 90), kAperatureRadius,
                 5),
    cupt::Camera(kResolution, make_float3(0, 5, 10), make_float3(0, 0, -1),
                 make_float3(0, 1, 0), make_float2(90, 90), kAperatureRadius,
                 5),
};

int main(int argc, const char* argv[]) {
  if (argc < 3) {
    std::cout << "Usage: PathTracer SCENE-ID OUTPUT [SAMPLES] [DEPTH]"
              << std::endl;
    return -1;
  }

  std::cout << "Initializing CUDA Runtime..." << std::flush;
  cudaSetDevice(0);
  std::cout << "Done" << std::endl;

  cupt::PathTracer::Parameter parameter;
  parameter.mc_sample_times = argc > 3 ? atoi(argv[3]) : 1;
  parameter.max_trace_depth = argc > 4 ? atoi(argv[4]) : 1;
  cupt::PathTracer tracer(parameter);

  const size_t id = atoi(argv[1]) - 1;
  assert(id < kNumScenes);

  const std::string& filename = kSceneFiles[id];
  const std::string basedir(filename, 0, filename.rfind("/") + 1);

  std::cout << "Loading Scene..." << std::flush;
  cupt::Scene scene(filename.c_str(), basedir.c_str());
  scene.light = 20;
  tracer.SetScene(scene);
  std::cout << "Done" << std::endl;

  std::cout << "Rendering..." << std::flush;
  const cupt::Camera& camera = kCameras[id];
  cupt::Image image = tracer.Render(camera);
  std::cout << "Done" << ::std::endl;

  std::cout << "Saving Result..." << std::flush;
  bool success = image.Save(argv[2]);
  if (success) {
    std::cout << "Success!" << std::endl;
  } else {
    std::cout << "Failed!" << std::endl;
  }

  return 0;
}<commit_msg>调整部分参数<commit_after>#include <iostream>

#include <cuda_runtime.h>

#include <helper_math.h>

#include "path_tracer.hpp"

const float kAperatureRadius = 0.04;
const uint2 kResolution = make_uint2(512, 512);
const size_t kNumScenes = 2;

const std::string kSceneFiles[kNumScenes]{
    "../scenes/scene-1/scene01.obj", "../scenes/scene-2/scene02.obj",
};
const cupt::Camera kCameras[2]{
    cupt::Camera(kResolution, make_float3(0, 5, 10), make_float3(0, 0, -1),
                 make_float3(0, 1, 0), make_float2(90, 90), kAperatureRadius,
                 10),
    cupt::Camera(kResolution, make_float3(1, 7, 25), make_float3(0, 0, -1),
                 make_float3(0, 1, 0), make_float2(90, 90), kAperatureRadius,
                 5),
};

int main(int argc, const char* argv[]) {
  if (argc < 3) {
    std::cout << "Usage: PathTracer SCENE-ID OUTPUT [SAMPLES] [DEPTH]"
              << std::endl;
    return -1;
  }

  std::cout << "Initializing CUDA Runtime..." << std::flush;
  cudaSetDevice(0);
  std::cout << "Done" << std::endl;

  cupt::PathTracer::Parameter parameter;
  parameter.mc_sample_times = argc > 3 ? atoi(argv[3]) : 1;
  parameter.max_trace_depth = argc > 4 ? atoi(argv[4]) : 1;
  cupt::PathTracer tracer(parameter);

  const size_t id = atoi(argv[1]) - 1;
  assert(id < kNumScenes);

  const std::string& filename = kSceneFiles[id];
  const std::string basedir(filename, 0, filename.rfind("/") + 1);

  std::cout << "Loading Scene..." << std::flush;
  cupt::Scene scene(filename.c_str(), basedir.c_str());
  tracer.SetScene(scene);
  std::cout << "Done" << std::endl;

  std::cout << "Rendering..." << std::flush;
  const cupt::Camera& camera = kCameras[id];
  cupt::Image image = tracer.Render(camera);
  std::cout << "Done" << ::std::endl;

  std::cout << "Saving Result..." << std::flush;
  bool success = image.Save(argv[2]);
  if (success) {
    std::cout << "Success!" << std::endl;
  } else {
    std::cout << "Failed!" << std::endl;
  }

  return 0;
}<|endoftext|>


<commit_before>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

******************************************************************************/
#ifndef NOMLIB_STDINT_TYPES_HPP
#define NOMLIB_STDINT_TYPES_HPP

#include "platforms.hpp"

#define NOM_PTR_CAST(type, expression) \
  ( std::dynamic_pointer_cast<type>(expression) )
//#define NOM_STATIC_CAST(type, expression) static_cast<type>(expression)
//#define NOM_CONST_CAST(type, expression) const_cast<type>(expression)

#define NOM_ENDL(reserved) ( std::cout << std::endl )

/*
  TODO: This should be replaced by an actual CMake script -- think:
        compile-time check for the necessary feature support for C++11 style
        headers support.

        Look into why GCC doesn't like the inclusion of <cstdint> -- otherwise
        known as stdint.h. MSVCPP2013 & llvm-clang are fine with it).
*/

#ifndef NOM_PLATFORM_LINUX  // To be replace with NOM_COMPILER_FEATURE_NULLPTR
                            // (see above TODO note).
  #include <cstdint>
#else
  #include <sys/types.h>
#endif

// Borrowed from /usr/include/MacTypes.h && /usr/include/objc/objc.h:
#ifndef NULL
  #if defined( NOM_COMPILER_FEATURE_NULLPTR )
    #define NULL nullptr
  #else
    #define NULL 0 //__DARWIN_NULL
  #endif
#endif // ! NULL

#ifndef nil
  #if defined( NOM_COMPILER_FEATURE_NULLPTR )
    #define nil nullptr
  #else
    #define nil 0 //__DARWIN_NULL
  #endif
#endif // ! nil

// Portable fixed-size data types derive from stdint.h
namespace nom {

// 8-bit integer types
typedef int8_t int8;
typedef uint8_t uint8;

// 16-bit integer types
typedef int16_t int16;
typedef uint16_t uint16;

// 32-bit integer types
typedef int32_t int32;
typedef uint32_t uint32;

/// \brief 64-bit integer types
/// \note As per **/usr/include/MacTypes.h**:
///
/// "The MS Visual C/C++ compiler uses __int64 instead of long long".
#if defined( NOM_COMPILER_MSVCPP ) && defined( NOM_PLATFORM_ARCH_X86 )
  typedef signed __int64 int64;
  typedef unsigned __int64 uint64;
#else // Blindly assume a 64-bit architecture
  typedef int64_t int64; //typedef signed long long int int64;
  typedef uint64_t uint64; //typedef unsigned long long int uint64;
#endif

// Additional integer type definitions
#if defined (NOM_PLATFORM_ARCH_X86_64)
  typedef unsigned long ulong;
#else // Blindly assume 32-bit arch
  typedef long long ulong;
#endif

typedef unsigned char uchar;
typedef signed int sint;
typedef unsigned int uint;
typedef std::size_t size;
typedef int boolean;

typedef sint* sint_ptr;
typedef uint* uint_ptr;

typedef int32_t* int32_ptr;
typedef uint32_t* uint32_ptr;

typedef void* void_ptr;

} // namespace nom

/// Ensure our data types have the right sizes using C++11 compile-time asserts.
static_assert ( sizeof ( nom::uint8 ) == 1, "nom::uint8" );
static_assert ( sizeof ( nom::int8 ) == 1, "nom::int8" );

static_assert ( sizeof ( nom::uint16 ) == 2, "nom::uint16" );
static_assert ( sizeof ( nom::int16 ) == 2, "nom::int16" );

static_assert ( sizeof ( nom::uint32 ) == 4, "nom::uint32" );
static_assert ( sizeof ( nom::int32 ) == 4, "nom::int32" );

static_assert ( sizeof ( nom::uint64 ) == 8, "nom::uint64" );
static_assert ( sizeof ( nom::int64 ) == 8, "nom::int64" );

static_assert ( sizeof ( nom::ulong ) == 8, "nom::ulong" );

static_assert ( sizeof ( nom::uchar ) == 1, "nom::uchar" );

#if defined(NOM_PLATFORM_ARCH_X86_64)
  static_assert ( sizeof ( nom::size ) == ( sizeof(nom::uint64) ), "nom::size" );
  static_assert ( sizeof ( nom::int32_ptr ) == ( sizeof(long) ), "nom::int32_ptr" );
  static_assert ( sizeof ( nom::uint32_ptr ) == ( sizeof(nom::ulong) ), "nom::uint32_ptr" );
#elif defined(NOM_PLATFORM_ARCH_X86)
  static_assert ( sizeof ( nom::size ) == ( sizeof(nom::uint32) ), "nom::size" );
#else
  #pragma message ( "types.hpp: Unknown architecture; defined data types may be wrong." )
#endif

static_assert ( sizeof ( nom::boolean ) == ( sizeof(int) ), "nom::boolean" );

/// Additional type definitions

const nom::sint NOM_EXIT_FAILURE = 1; // EXIT_FAILURE from cstdlib headers
const nom::sint NOM_EXIT_SUCCESS = 0; // EXIT_SUCCESS from cstdlib headers

//#if defined(HAVE_SDL2)
const nom::sint SDL_SUCCESS = 0; // Non-error return value for SDL2 API
//#endif

#endif // include guard defined
<commit_msg>types: Introduce NOM_SCAST & NOM_CCAST macros<commit_after>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

******************************************************************************/
#ifndef NOMLIB_STDINT_TYPES_HPP
#define NOMLIB_STDINT_TYPES_HPP

#include "platforms.hpp"

#define NOM_PTR_CAST(type, expression) \
  ( std::dynamic_pointer_cast<type>(expression) )

#define NOM_SCAST(type, expression) static_cast<type>(expression)
#define NOM_CCAST(type, expression) const_cast<type>(expression)

#define NOM_ENDL(reserved) ( std::cout << std::endl )

/*
  TODO: This should be replaced by an actual CMake script -- think:
        compile-time check for the necessary feature support for C++11 style
        headers support.

        Look into why GCC doesn't like the inclusion of <cstdint> -- otherwise
        known as stdint.h. MSVCPP2013 & llvm-clang are fine with it).
*/

#ifndef NOM_PLATFORM_LINUX  // To be replace with NOM_COMPILER_FEATURE_NULLPTR
                            // (see above TODO note).
  #include <cstdint>
#else
  #include <sys/types.h>
#endif

// Borrowed from /usr/include/MacTypes.h && /usr/include/objc/objc.h:
#ifndef NULL
  #if defined( NOM_COMPILER_FEATURE_NULLPTR )
    #define NULL nullptr
  #else
    #define NULL 0 //__DARWIN_NULL
  #endif
#endif // ! NULL

#ifndef nil
  #if defined( NOM_COMPILER_FEATURE_NULLPTR )
    #define nil nullptr
  #else
    #define nil 0 //__DARWIN_NULL
  #endif
#endif // ! nil

// Portable fixed-size data types derive from stdint.h
namespace nom {

// 8-bit integer types
typedef int8_t int8;
typedef uint8_t uint8;

// 16-bit integer types
typedef int16_t int16;
typedef uint16_t uint16;

// 32-bit integer types
typedef int32_t int32;
typedef uint32_t uint32;

/// \brief 64-bit integer types
/// \note As per **/usr/include/MacTypes.h**:
///
/// "The MS Visual C/C++ compiler uses __int64 instead of long long".
#if defined( NOM_COMPILER_MSVCPP ) && defined( NOM_PLATFORM_ARCH_X86 )
  typedef signed __int64 int64;
  typedef unsigned __int64 uint64;
#else // Blindly assume a 64-bit architecture
  typedef int64_t int64; //typedef signed long long int int64;
  typedef uint64_t uint64; //typedef unsigned long long int uint64;
#endif

// Additional integer type definitions
#if defined (NOM_PLATFORM_ARCH_X86_64)
  typedef unsigned long ulong;
#else // Blindly assume 32-bit arch
  typedef long long ulong;
#endif

typedef unsigned char uchar;
typedef signed int sint;
typedef unsigned int uint;
typedef std::size_t size;
typedef int boolean;

typedef sint* sint_ptr;
typedef uint* uint_ptr;

typedef int32_t* int32_ptr;
typedef uint32_t* uint32_ptr;

typedef void* void_ptr;

} // namespace nom

/// Ensure our data types have the right sizes using C++11 compile-time asserts.
static_assert ( sizeof ( nom::uint8 ) == 1, "nom::uint8" );
static_assert ( sizeof ( nom::int8 ) == 1, "nom::int8" );

static_assert ( sizeof ( nom::uint16 ) == 2, "nom::uint16" );
static_assert ( sizeof ( nom::int16 ) == 2, "nom::int16" );

static_assert ( sizeof ( nom::uint32 ) == 4, "nom::uint32" );
static_assert ( sizeof ( nom::int32 ) == 4, "nom::int32" );

static_assert ( sizeof ( nom::uint64 ) == 8, "nom::uint64" );
static_assert ( sizeof ( nom::int64 ) == 8, "nom::int64" );

static_assert ( sizeof ( nom::ulong ) == 8, "nom::ulong" );

static_assert ( sizeof ( nom::uchar ) == 1, "nom::uchar" );

#if defined(NOM_PLATFORM_ARCH_X86_64)
  static_assert ( sizeof ( nom::size ) == ( sizeof(nom::uint64) ), "nom::size" );
  static_assert ( sizeof ( nom::int32_ptr ) == ( sizeof(long) ), "nom::int32_ptr" );
  static_assert ( sizeof ( nom::uint32_ptr ) == ( sizeof(nom::ulong) ), "nom::uint32_ptr" );
#elif defined(NOM_PLATFORM_ARCH_X86)
  static_assert ( sizeof ( nom::size ) == ( sizeof(nom::uint32) ), "nom::size" );
#else
  #pragma message ( "types.hpp: Unknown architecture; defined data types may be wrong." )
#endif

static_assert ( sizeof ( nom::boolean ) == ( sizeof(int) ), "nom::boolean" );

/// Additional type definitions

const nom::sint NOM_EXIT_FAILURE = 1; // EXIT_FAILURE from cstdlib headers
const nom::sint NOM_EXIT_SUCCESS = 0; // EXIT_SUCCESS from cstdlib headers

//#if defined(HAVE_SDL2)
const nom::sint SDL_SUCCESS = 0; // Non-error return value for SDL2 API
//#endif

#endif // include guard defined
<|endoftext|>


<commit_before>/** String conversion definitions.
 *
 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead.
 *
 * Copyright (c) 2008-2017, Jeroen T. Vermeulen <jtv@xs4all.nl>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 */
#ifndef PQXX_H_STRINGCONV
#define PQXX_H_STRINGCONV

#include "pqxx/compiler-public.hxx"

#include <sstream>
#include <stdexcept>

namespace pqxx
{

/**
 * @defgroup stringconversion String conversion
 *
 * For purposes of communication with the server, values need to be converted
 * from and to a human-readable string format that (unlike the various functions
 * and templates in the C and C++ standard libraries) is not sensitive to locale
 * settings and internationalization.  This section contains functionality that
 * is used extensively by libpqxx itself, but is also available for use by other
 * programs.
 */
//@{

/// Traits class for use in string conversions
/** Specialize this template for a type that you wish to add to_string and
 * from_string support for.
 */
template<typename T> struct string_traits {};

namespace internal
{
/// Throw exception for attempt to convert null to given type.
[[noreturn]] PQXX_LIBEXPORT void throw_null_conversion(
	const std::string &type);
} // namespace pqxx::internal

#define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(T)			\
template<> struct PQXX_LIBEXPORT string_traits<T>			\
{									\
  typedef T subject_type;						\
  static constexpr const char *name() noexcept { return #T; }		\
  static constexpr bool has_null() noexcept { return false; }		\
  static bool is_null(T) { return false; }				\
  static T null() 							\
    { internal::throw_null_conversion(name()); return subject_type(); }	\
  static void from_string(const char Str[], T &Obj);			\
  static std::string to_string(T Obj);					\
};

PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(bool)

PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(short)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned short)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(int)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned int)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long long)

PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(float)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(double)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long double)

#undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION

/// String traits for C-style string ("pointer to const char")
template<> struct PQXX_LIBEXPORT string_traits<const char *>
{
  static constexpr const char *name() noexcept { return "const char *"; }
  static constexpr bool has_null() noexcept { return true; }
  static bool is_null(const char *t) { return !t; }
  static const char *null() { return nullptr; }
  static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
  static std::string to_string(const char *Obj) { return Obj; }
};

/// String traits for non-const C-style string ("pointer to char")
template<> struct PQXX_LIBEXPORT string_traits<char *>
{
  static constexpr const char *name() noexcept { return "char *"; }
  static constexpr bool has_null() noexcept { return true; }
  static bool is_null(const char *t) { return !t; }
  static const char *null() { return nullptr; }

  // Don't allow this conversion since it breaks const-safety.
  // static void from_string(const char Str[], char *&Obj);

  static std::string to_string(char *Obj) { return Obj; }
};

/// String traits for C-style string constant ("array of char")
template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]>
{
  static constexpr const char *name() noexcept { return "char[]"; }
  static constexpr bool has_null() noexcept { return true; }
  static bool is_null(const char t[]) { return !t; }
  static const char *null() { return nullptr; }
  static std::string to_string(const char Obj[]) { return Obj; }
};

/// String traits for "array of const char."
/** Visual Studio 2010 isn't happy without this redundant specialization.
 * Other compilers shouldn't need it.
 */
template<size_t N> struct PQXX_LIBEXPORT string_traits<const char[N]>
{
  static constexpr const char *name() noexcept { return "char[]"; }
  static constexpr bool has_null() noexcept { return true; }
  static bool is_null(const char t[]) { return !t; }
  static const char *null() { return nullptr; }
  static std::string to_string(const char Obj[]) { return Obj; }
};

template<> struct PQXX_LIBEXPORT string_traits<std::string>
{
  static constexpr const char *name() noexcept { return "string"; }
  static constexpr bool has_null() noexcept { return false; }
  static bool is_null(const std::string &) { return false; }
  static std::string null()
	{ internal::throw_null_conversion(name()); return std::string(); }
  static void from_string(const char Str[], std::string &Obj) { Obj=Str; }
  static std::string to_string(const std::string &Obj) { return Obj; }
};

template<> struct PQXX_LIBEXPORT string_traits<const std::string>
{
  static constexpr const char *name() noexcept { return "const string"; }
  static constexpr bool has_null() noexcept { return false; }
  static bool is_null(const std::string &) { return false; }
  static const std::string null()
	{ internal::throw_null_conversion(name()); return std::string(); }
  static const std::string to_string(const std::string &Obj) { return Obj; }
};

template<> struct PQXX_LIBEXPORT string_traits<std::stringstream>
{
  static constexpr const char *name() noexcept { return "stringstream"; }
  static constexpr bool has_null() noexcept { return false; }
  static bool is_null(const std::stringstream &) { return false; }
  static std::stringstream null()
  {
    internal::throw_null_conversion(name());
    // No, dear compiler, we don't need a return here.
    throw 0;
  }
  static void from_string(const char Str[], std::stringstream &Obj)
	{ Obj.clear(); Obj << Str; }
  static std::string to_string(const std::stringstream &Obj)
	{ return Obj.str(); }
};

// TODO: Implement date conversions

/// Attempt to convert postgres-generated string to given built-in type
/** If the form of the value found in the string does not match the expected
 * type, e.g. if a decimal point is found when converting to an integer type,
 * the conversion fails.  Overflows (e.g. converting "9999999999" to a 16-bit
 * C++ type) are also treated as errors.  If in some cases this behaviour should
 * be inappropriate, convert to something bigger such as @c long @c int first
 * and then truncate the resulting value.
 *
 * Only the simplest possible conversions are supported.  No fancy features
 * such as hexadecimal or octal, spurious signs, or exponent notation will work.
 * No whitespace is stripped away.  Only the kinds of strings that come out of
 * PostgreSQL and out of to_string() can be converted.
 */
template<typename T>
  inline void from_string(const char Str[], T &Obj)
{
  if (!Str) throw std::runtime_error("Attempt to read null string");
  string_traits<T>::from_string(Str, Obj);
}

/// Conversion with known string length (for strings that may contain nuls)
/** This is only used for strings, where embedded nul bytes should not determine
 * the end of the string.
 *
 * For all other types, this just uses the regular, nul-terminated version of
 * from_string().
 */
template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
{
  return from_string(Str, Obj);
}

template<>
  inline void from_string<std::string>(					//[t0]
	const char Str[],
	std::string &Obj,
	size_t len)
{
  if (!Str) throw std::runtime_error("Attempt to read null string");
  Obj.assign(Str, len);
}

template<typename T>
  inline void from_string(const std::string &Str, T &Obj)		//[t45]
	{ from_string(Str.c_str(), Obj); }

template<typename T>
  inline void from_string(const std::stringstream &Str, T &Obj)		//[t0]
	{ from_string(Str.str(), Obj); }

template<> inline void
from_string(const std::string &Str, std::string &Obj)			//[t46]
	{ Obj = Str; }

namespace internal
{
/// Compute numeric value of given textual digit (assuming that it is a digit)
inline int digit_to_number(char c) noexcept { return c-'0'; }
inline char number_to_digit(int i) noexcept
	{ return static_cast<char>(i+'0'); }
} // namespace pqxx::internal

/// Convert built-in type to a readable string that PostgreSQL will understand
/** No special formatting is done, and any locale settings are ignored.  The
 * resulting string will be human-readable and in a format suitable for use in
 * SQL queries.
 */
template<typename T> inline std::string to_string(const T &Obj)
	{ return string_traits<T>::to_string(Obj); }

//@}

} // namespace pqxx

#endif
<commit_msg>Remove old workaround for noreturn warning.<commit_after>/** String conversion definitions.
 *
 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead.
 *
 * Copyright (c) 2008-2017, Jeroen T. Vermeulen <jtv@xs4all.nl>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 */
#ifndef PQXX_H_STRINGCONV
#define PQXX_H_STRINGCONV

#include "pqxx/compiler-public.hxx"

#include <sstream>
#include <stdexcept>

namespace pqxx
{

/**
 * @defgroup stringconversion String conversion
 *
 * For purposes of communication with the server, values need to be converted
 * from and to a human-readable string format that (unlike the various functions
 * and templates in the C and C++ standard libraries) is not sensitive to locale
 * settings and internationalization.  This section contains functionality that
 * is used extensively by libpqxx itself, but is also available for use by other
 * programs.
 */
//@{

/// Traits class for use in string conversions
/** Specialize this template for a type that you wish to add to_string and
 * from_string support for.
 */
template<typename T> struct string_traits {};

namespace internal
{
/// Throw exception for attempt to convert null to given type.
[[noreturn]] PQXX_LIBEXPORT void throw_null_conversion(
	const std::string &type);
} // namespace pqxx::internal

#define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(T)			\
template<> struct PQXX_LIBEXPORT string_traits<T>			\
{									\
  typedef T subject_type;						\
  static constexpr const char *name() noexcept { return #T; }		\
  static constexpr bool has_null() noexcept { return false; }		\
  static bool is_null(T) { return false; }				\
  [[noreturn]] static T null() 						\
    { internal::throw_null_conversion(name()); }			\
  static void from_string(const char Str[], T &Obj);			\
  static std::string to_string(T Obj);					\
};

PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(bool)

PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(short)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned short)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(int)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned int)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long long)

PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(float)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(double)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long double)

#undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION

/// String traits for C-style string ("pointer to const char")
template<> struct PQXX_LIBEXPORT string_traits<const char *>
{
  static constexpr const char *name() noexcept { return "const char *"; }
  static constexpr bool has_null() noexcept { return true; }
  static bool is_null(const char *t) { return !t; }
  static const char *null() { return nullptr; }
  static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
  static std::string to_string(const char *Obj) { return Obj; }
};

/// String traits for non-const C-style string ("pointer to char")
template<> struct PQXX_LIBEXPORT string_traits<char *>
{
  static constexpr const char *name() noexcept { return "char *"; }
  static constexpr bool has_null() noexcept { return true; }
  static bool is_null(const char *t) { return !t; }
  static const char *null() { return nullptr; }

  // Don't allow this conversion since it breaks const-safety.
  // static void from_string(const char Str[], char *&Obj);

  static std::string to_string(char *Obj) { return Obj; }
};

/// String traits for C-style string constant ("array of char")
template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]>
{
  static constexpr const char *name() noexcept { return "char[]"; }
  static constexpr bool has_null() noexcept { return true; }
  static bool is_null(const char t[]) { return !t; }
  static const char *null() { return nullptr; }
  static std::string to_string(const char Obj[]) { return Obj; }
};

/// String traits for "array of const char."
/** Visual Studio 2010 isn't happy without this redundant specialization.
 * Other compilers shouldn't need it.
 */
template<size_t N> struct PQXX_LIBEXPORT string_traits<const char[N]>
{
  static constexpr const char *name() noexcept { return "char[]"; }
  static constexpr bool has_null() noexcept { return true; }
  static bool is_null(const char t[]) { return !t; }
  static const char *null() { return nullptr; }
  static std::string to_string(const char Obj[]) { return Obj; }
};

template<> struct PQXX_LIBEXPORT string_traits<std::string>
{
  static constexpr const char *name() noexcept { return "string"; }
  static constexpr bool has_null() noexcept { return false; }
  static bool is_null(const std::string &) { return false; }
  static std::string null()
	{ internal::throw_null_conversion(name()); return std::string(); }
  static void from_string(const char Str[], std::string &Obj) { Obj=Str; }
  static std::string to_string(const std::string &Obj) { return Obj; }
};

template<> struct PQXX_LIBEXPORT string_traits<const std::string>
{
  static constexpr const char *name() noexcept { return "const string"; }
  static constexpr bool has_null() noexcept { return false; }
  static bool is_null(const std::string &) { return false; }
  static const std::string null()
	{ internal::throw_null_conversion(name()); return std::string(); }
  static const std::string to_string(const std::string &Obj) { return Obj; }
};

template<> struct PQXX_LIBEXPORT string_traits<std::stringstream>
{
  static constexpr const char *name() noexcept { return "stringstream"; }
  static constexpr bool has_null() noexcept { return false; }
  static bool is_null(const std::stringstream &) { return false; }
  static std::stringstream null()
  {
    internal::throw_null_conversion(name());
    // No, dear compiler, we don't need a return here.
    throw 0;
  }
  static void from_string(const char Str[], std::stringstream &Obj)
	{ Obj.clear(); Obj << Str; }
  static std::string to_string(const std::stringstream &Obj)
	{ return Obj.str(); }
};

// TODO: Implement date conversions

/// Attempt to convert postgres-generated string to given built-in type
/** If the form of the value found in the string does not match the expected
 * type, e.g. if a decimal point is found when converting to an integer type,
 * the conversion fails.  Overflows (e.g. converting "9999999999" to a 16-bit
 * C++ type) are also treated as errors.  If in some cases this behaviour should
 * be inappropriate, convert to something bigger such as @c long @c int first
 * and then truncate the resulting value.
 *
 * Only the simplest possible conversions are supported.  No fancy features
 * such as hexadecimal or octal, spurious signs, or exponent notation will work.
 * No whitespace is stripped away.  Only the kinds of strings that come out of
 * PostgreSQL and out of to_string() can be converted.
 */
template<typename T>
  inline void from_string(const char Str[], T &Obj)
{
  if (!Str) throw std::runtime_error("Attempt to read null string");
  string_traits<T>::from_string(Str, Obj);
}

/// Conversion with known string length (for strings that may contain nuls)
/** This is only used for strings, where embedded nul bytes should not determine
 * the end of the string.
 *
 * For all other types, this just uses the regular, nul-terminated version of
 * from_string().
 */
template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
{
  return from_string(Str, Obj);
}

template<>
  inline void from_string<std::string>(					//[t0]
	const char Str[],
	std::string &Obj,
	size_t len)
{
  if (!Str) throw std::runtime_error("Attempt to read null string");
  Obj.assign(Str, len);
}

template<typename T>
  inline void from_string(const std::string &Str, T &Obj)		//[t45]
	{ from_string(Str.c_str(), Obj); }

template<typename T>
  inline void from_string(const std::stringstream &Str, T &Obj)		//[t0]
	{ from_string(Str.str(), Obj); }

template<> inline void
from_string(const std::string &Str, std::string &Obj)			//[t46]
	{ Obj = Str; }

namespace internal
{
/// Compute numeric value of given textual digit (assuming that it is a digit)
inline int digit_to_number(char c) noexcept { return c-'0'; }
inline char number_to_digit(int i) noexcept
	{ return static_cast<char>(i+'0'); }
} // namespace pqxx::internal

/// Convert built-in type to a readable string that PostgreSQL will understand
/** No special formatting is done, and any locale settings are ignored.  The
 * resulting string will be human-readable and in a format suitable for use in
 * SQL queries.
 */
template<typename T> inline std::string to_string(const T &Obj)
	{ return string_traits<T>::to_string(Obj); }

//@}

} // namespace pqxx

#endif
<|endoftext|>


<commit_before>#pragma once

#include <tudocomp/pre_header/Registry.hpp>
#include <tudocomp/pre_header/Env.hpp>

namespace tdc {

inline AlgorithmValue& EnvRoot::algo_value() {
    return *m_algo_value;
}

inline Stat& EnvRoot::stat_current() {
    return m_stat_stack.empty() ? m_stat_root : m_stat_stack.top();
}

inline void EnvRoot::begin_stat_phase(const std::string& name) {
    DLOG(INFO) << "begin phase \"" << name << "\"";

    m_stat_stack.push(Stat(name));
    Stat& stat = m_stat_stack.top();
    stat.begin();
}

inline void EnvRoot::end_stat_phase() {
    DCHECK(!m_stat_stack.empty());

    Stat& stat_ref = m_stat_stack.top();
    DLOG(INFO) << "end phase \"" << stat_ref.title() << "\"";

    stat_ref.end();

    Stat stat = stat_ref; //copy
    m_stat_stack.pop();

    if(!m_stat_stack.empty()) {
        Stat& parent = m_stat_stack.top();
        parent.add_sub(stat);
    } else {
        m_stat_root = stat;
    }
}

inline Stat& EnvRoot::finish_stats() {
    while(!m_stat_stack.empty()) {
        end_stat_phase();
    }

    return m_stat_root;
}

inline void EnvRoot::restart_stats(const std::string& root_name) {
    finish_stats();
    begin_stat_phase(root_name);
}

template<class T>
inline void EnvRoot::log_stat(const std::string& name, const T& value) {
    DLOG(INFO) << "stat: " << name << " = " << value;
    stat_current().add_stat(name, value);
}

inline Env::Env(Env&& other):
    m_root(std::move(other.m_root)),
    m_node(other.m_node),
    m_registry(std::move(other.m_registry)) {}

inline Env::Env(std::shared_ptr<EnvRoot> root,
                const AlgorithmValue& node,
                const Registry& registry):
    m_root(root),
    m_node(node),
    m_registry(std::make_unique<Registry>(registry)) {}

inline Env::~Env() = default;

inline const AlgorithmValue& Env::algo() const {
    return m_node;
}

inline std::shared_ptr<EnvRoot>& Env::root() {
    return m_root;
}

inline const Registry& Env::registry() const {
    return *m_registry;
}

inline void Env::error(const std::string& msg) {
    throw std::runtime_error(msg);
}

inline Env Env::env_for_option(const std::string& option) {
    CHECK(algo().arguments().count(option) > 0);
    auto& a = algo().arguments().at(option).as_algorithm();

    return Env(m_root, a, registry());
}

inline const OptionValue& Env::option(const std::string& option) const {
    return algo().arguments().at(option);
}

inline void Env::begin_stat_phase(const std::string& name) {
    m_root->begin_stat_phase(name); //delegate
}

inline void Env::end_stat_phase() {
    m_root->end_stat_phase(); //delegate
}

inline Stat& Env::finish_stats() {
    return m_root->finish_stats(); //delegate
}

inline void Env::restart_stats(const std::string& root_name) {
    m_root->restart_stats(root_name); //delegate
}

template<class T>
inline void Env::log_stat(const std::string& name, const T& value) {
    m_root->log_stat(name, value);
}

}

<commit_msg>Only log stat messages in super-verbose mode<commit_after>#pragma once

#include <tudocomp/pre_header/Registry.hpp>
#include <tudocomp/pre_header/Env.hpp>

namespace tdc {

inline AlgorithmValue& EnvRoot::algo_value() {
    return *m_algo_value;
}

inline Stat& EnvRoot::stat_current() {
    return m_stat_stack.empty() ? m_stat_root : m_stat_stack.top();
}

inline void EnvRoot::begin_stat_phase(const std::string& name) {
    VLOG(2) << "begin phase \"" << name << "\"";

    m_stat_stack.push(Stat(name));
    Stat& stat = m_stat_stack.top();
    stat.begin();
}

inline void EnvRoot::end_stat_phase() {
    DCHECK(!m_stat_stack.empty());

    Stat& stat_ref = m_stat_stack.top();
    VLOG(2) << "end phase \"" << stat_ref.title() << "\"";

    stat_ref.end();

    Stat stat = stat_ref; //copy
    m_stat_stack.pop();

    if(!m_stat_stack.empty()) {
        Stat& parent = m_stat_stack.top();
        parent.add_sub(stat);
    } else {
        m_stat_root = stat;
    }
}

inline Stat& EnvRoot::finish_stats() {
    while(!m_stat_stack.empty()) {
        end_stat_phase();
    }

    return m_stat_root;
}

inline void EnvRoot::restart_stats(const std::string& root_name) {
    finish_stats();
    begin_stat_phase(root_name);
}

template<class T>
inline void EnvRoot::log_stat(const std::string& name, const T& value) {
    VLOG(2) << "stat: " << name << " = " << value;
    stat_current().add_stat(name, value);
}

inline Env::Env(Env&& other):
    m_root(std::move(other.m_root)),
    m_node(other.m_node),
    m_registry(std::move(other.m_registry)) {}

inline Env::Env(std::shared_ptr<EnvRoot> root,
                const AlgorithmValue& node,
                const Registry& registry):
    m_root(root),
    m_node(node),
    m_registry(std::make_unique<Registry>(registry)) {}

inline Env::~Env() = default;

inline const AlgorithmValue& Env::algo() const {
    return m_node;
}

inline std::shared_ptr<EnvRoot>& Env::root() {
    return m_root;
}

inline const Registry& Env::registry() const {
    return *m_registry;
}

inline void Env::error(const std::string& msg) {
    throw std::runtime_error(msg);
}

inline Env Env::env_for_option(const std::string& option) {
    CHECK(algo().arguments().count(option) > 0);
    auto& a = algo().arguments().at(option).as_algorithm();

    return Env(m_root, a, registry());
}

inline const OptionValue& Env::option(const std::string& option) const {
    return algo().arguments().at(option);
}

inline void Env::begin_stat_phase(const std::string& name) {
    m_root->begin_stat_phase(name); //delegate
}

inline void Env::end_stat_phase() {
    m_root->end_stat_phase(); //delegate
}

inline Stat& Env::finish_stats() {
    return m_root->finish_stats(); //delegate
}

inline void Env::restart_stats(const std::string& root_name) {
    m_root->restart_stats(root_name); //delegate
}

template<class T>
inline void Env::log_stat(const std::string& name, const T& value) {
    m_root->log_stat(name, value);
}

}

<|endoftext|>