<commit_before>/******************************************************************************
 * Name        : parser.cpp
 * Author      : Ben Blease
 * Email       : bblease@stevens.edu
 * Date        : 8/1/16
 * Description : Parsing for one2one using a top down recursive parser
******************************************************************************/

#include "parser.h"

Token::Token(tok  typ): typ(typ) { }

Token::Token(tok typ, char val): typ(typ), val(val) { }

Token::Token(tok typ, int num): typ(typ), num(num) { }

Token::Token(tok typ, bool bol): typ(typ), bol(bol) { }

Token::~Token() { }

Parser::Parser() { }

Parser::~Parser() { }

/*
*Simply splits strings based on delimiting characters
*/
std::vector<std::string> Parser::scan(std::string s){
	std::vector<std::string> out;
	bool comment = false;
	std::string focus;
	for (size_t i = 0; i < s.length(); i++){
		//check if comment
		if (s[i] == '#' || s[i] == '$'){
			comment = true;
		}
		//check if char is delimeter
		else if (!comment && (
			s[i] == ' ' ||
			s[i] == '+' ||
			s[i] == '-' ||
			s[i] == '*' ||
			s[i] == '/' ||
			s[i] == '%' ||
			s[i] == '^' ||
			s[i] == '<' ||
			s[i] == '>' ||
			s[i] == '.' ||
			s[i] == '(' ||
			s[i] == ')' ||
			s[i] == '{' ||
			s[i] == '}' ||
			s[i] == '\t' ||
			s[i] == '\n' ||
			s[i] == '\r')){
			//add std::string to output
			if (focus != ""){
				out.push_back(focus);
			}
			if (s[i] == '+' && s[i+1] == '+'){
				focus = "++";
				out.push_back(focus);
				i += 2;
			}
			//only add to output if the char is an operator
			if (s[i] != ' ' && s[i] != '\n' && s[i] != '\r' && s[i] != '\t'){
				//convert to std::string
				std::string a = std::string(1, s[i]);
				out.push_back(a);
			}
			focus = "";
		}else if (i == s.length()-1){
			//if the end is reached, add what's left
			focus += s[i];
			out.push_back(focus);
		}else if (!comment && s[i]) {
			focus += tolower(s[i]);
		}else if (i == s.length()-1 || s[i] == '\n' || s[i] == '$'){
			//comments end at the end of a line or the end of the file
			comment = false;
		}
	}
	return out;
}

/*
*Check if string is a keyword
*/
bool Parser::is_keyword(std::string var){
	std::map<std::string, tok>::iterator it;
	it = toks_.find(var);
	return it != toks_.end();
}

/*
*Check if string is ignored
*/
bool Parser::is_ignored(std::string a){
	return std::find(std::begin(ignored_), std::end(ignored_), a) != std::end(ignored_);
}

/*
*Corrects tokenized input operators
*May need correction
*/
void Parser::correct(std::vector<Token> &t){
	for (size_t i = 0; i < t.size(); i++){
		if (t[i].typ == assign_tok ||
			t[i].typ == num_ops ||
			t[i].typ == and_tok ||
			t[i].typ == or_tok ||
			t[i].typ == xor_tok ||
			t[i].typ == check_equal ||
			t[i].typ == check_lg){
			if (t[i-1].typ == rightp){
				std::stack<char> open; //determine if expression is correctly traversed
				for (size_t k = i; k >= 0; k--){
					if (t[k].typ == rightp){
						open.push('$');
					}
					else if (t[k].typ == leftp){
						open.pop();
					}
					if (open.empty() && k != i){
						t.insert(t.begin()+k, t[i]); //move operator
						t.erase(t.begin()+i+1); //delete operator from former position
						break;
					}
				}
			} else {
				Token swap = t[i];
				t[i] = t[i-1];
				t[i-1] = swap;
			}
		}
	}
}

/*
*Tokenizes delimited std::string resulting from scan
*May need revisions, currently inefficient
*/
std::vector<Token> Parser::tokenize(std::vector<std::string> s){
	std::vector<Token> out;
	for (size_t i = 0; i < s.size(); i++){
		int num;
		bool bol;
		//iss for ints iss2 for bools
		std::istringstream iss(s[i]);
		std::istringstream iss2(s[i]);
		if (is_keyword(s[i])){
			//create token
			Token tk = Token(toks_[s[i]]);
			out.push_back(tk);
		}
		//check if the string is a name
		else if (s[i].length() == 1 && isalpha(s[i][0])) {
			out.push_back(Token(name_tok, s[i][0]));
		}
		//check if the string is an integer
		else if (iss >> num){
			out.push_back(Token(int_tok, num));
		}
		//check if the string is a boolean
		else if (iss2 >> std::boolalpha >> bol){
			out.push_back(Token(bool_tok, bol));
		}
		//check if the string is an operator
		else if (s[i].length() == 1 && !isalpha(s[i][0])) {
			if (s[i][0] == '+' ||
				s[i][0] == '-' ||
				s[i][0] == '*' ||
			    s[i][0] == '/' ||
				s[i][0] == '%' ||
				s[i][0] == '^'){
				out.push_back(Token(num_ops, s[i][0]));
			}
			else if (s[i][0] == '<' ||
					 s[i][0] == '>'){
				out.push_back(Token(check_lg, s[i][0]));
			}
		}
		//throw error if token can't be created
		else if (!is_ignored(s[i])){
			std::cout << s[i] << std::endl;
			throw TokenException();
		}
	}
	correct(out);
	return out;
}

/*
*Check for missing paretheses, brackets, and end statements
*/
void Parser::check_parens(std::vector<Token> p){
	std::stack<char> check;
	for (size_t i = 0; i < p.size(); i++){
		if (p[i].typ == begin_tok || p[i].typ == leftp){
			check.push('$');
		}
		else if (p[i].typ == end_tok || p[i].typ == rightp){
			if (!check.empty()){
				check.pop();
			} else {
				throw ExtraParen();
			}
		}
	}
	if (!check.empty()) {
		throw ParenException();
	}
}

/*
*Eats the head of token vector
*/
inline void Parser::eat(std::vector<Token> &p){
	p.erase(p.begin());
}

/*
*Eats the current token if it matches the specified type
*/
void Parser::eat(tok t, std::vector<Token> &p){
	if (p[0].typ != t){
		throw SyntaxException();
	} else {
		eat(p);
	}
}

/*
*Create abstract syntax tree from tokens
*/
Expression * Parser::parse(std::vector<Token> &p){
	Expression *out;
	tok t = p[0].typ;
	//load information from token
	int num = p[0].num;
	char val = p[0].val;
	bool bol = p[0].bol;
	eat(p); //eat current token
	switch(t){
		default:
			out = new NullExp();
			break;

		case leftp: {
			out = parse(p);
			eat(rightp, p);
			break;
		}

		//build block
		case begin_tok: {
			std::vector<Expression*> exps;
			while (p[0].typ != end_tok){
				Expression *exp = parse(p);
				exps.push_back(exp);
			}
			//tell the interpreter that the expression is concluded on the PTR_STACK
			exps.push_back(new NullExp());
			out = new BlockExp(exps);
			eat(end_tok, p);
			break;
		}

		case int_tok:  {
			out = new NumExp(num);
			break;
		}

		case num_ops: {
			out = new OpExp(parse(p), parse(p), val);
			break;
		}

		case bool_tok: {
			out = new BoolExp(bol);
			break;
		}

		case not_tok: {
			out = new BoolOp(parse(p), '!');
			break;
		}
		case and_tok:
		case or_tok:
		case xor_tok: {
			out = new BoolOp(parse(p), parse(p), ops_[t]);
			break;
		}

		case check_equal: {
			out = new NumBoolExp(parse(p), parse(p), '=');
			break;
		}

		case check_lg: {
			out = new NumBoolExp(parse(p), parse(p), val);
			break;
		}

		case name_tok: {
			out = new VarExp(val);
			break;
		}

		case assign_tok: {
			if (p[0].typ == name_tok){
				char name = p[0].val;
				eat(name_tok, p); //eat name
				out = new SetExp(name, parse(p));
			} else {
				throw NameException();
			}
			break;
		}

		case if_tok: {
			out = new IfExp(parse(p), parse(p));
			break;
		}

		case for_tok: {
			if (p[0].typ == name_tok){
				char it = p[0].val;
				eat(name_tok, p);
				out = new ForExp(it, parse(p), parse(p), parse(p));
			} else {
				throw NameException();
			}
			break;
		}

		case while_tok: {
			out = new WhileExp(parse(p), parse(p));
			break;
		}

		case func: {
			if (p[0].typ == name_tok){
				char name;
				char var;
				name = p[0].val;
				eat(name_tok, p);
				//make sure variables are encapsulated in ( )
				if (p[0].typ == leftp){
					eat(leftp, p);
					//make sure a variable is present
					if (p[0].typ == name_tok){
						var = p[0].val;
						eat(name_tok, p);
						eat(rightp, p);
					} else {
						eat(rightp, p);
						var = '\0';
					}
				} else {
					var = '\0';
				}
				if (var == '\0'){
					out = new ProcExp(name, parse(p));
				} else {
					out = new ProcExp(name, var, parse(p));
				}
			} else {
				throw NameException();
			}
			break;
		}

		case run_tok: {

			if (p[0].typ == name_tok){
				char name = p[0].val;
				eat(p);
				if (p[1].typ == rightp){
					eat(leftp, p);
					eat(rightp, p);
					out = new CallExp(name);
				} else {
					eat(leftp, p);
					out = new CallExp(name, parse(p));
					eat(rightp, p);
				}
			} else {
				throw NameException();
			}

			break;
		}

		case print_tok: {
			out = new PrintExp(parse(p));
			break;
		}

		case inc_tok: {
			if (p[0].typ == name_tok){
				out = new IncExp(p[0].val, 	parse(p));
			} else {
				throw NameException();
			}
			break;
		}

		case del_tok: {
			out = new DelExp();
			break;
		}

		case top_tok: {
			out = new NullExp();
			break;
		}

		case empty_tok: {
			out = new EmptyExp();
			break;
		}
	}
	return out;
}

/*
*Create the final program for interpretation
*Also check if all parentheses are closed.
*/
Program * Parser::create_program(std::string file){
	std::vector<std::string> scanned = scan(file);
	std::vector<Token> tokenized = tokenize(scanned);
	check_parens(tokenized);
	Program *out = new Program(parse(tokenized));
	return out;
}
<commit_msg>extra parser delete.<commit_after><|endoftext|>


<commit_before>#include "segments.hpp"
#include "../utils/utils.hpp"
#include <cmath>
#include <cstdio>

using namespace geom2d;

enum {
	Nsegs = 10,
	Width = 100,
	Height = 100,
	Nangles = 32,

	// number of steps in the random walk
	Nsteps = 100000,
};

const double MaxR = 15;
const double MinR = 1;

void mkinst(FILE*);

int main(int argc, char *argv[]) {
	mkinst(stdout);
	return 0;
}

void mkinst(FILE *out) {
	Segments dom(Width, Height, Nangles, std::vector<Segments::Seg>());

	std::vector<LineSg> lines;
	for (unsigned int i = 0; i < Nsegs; i++) {
	redo:
		Segments::Seg seg;
		seg.radius = randgen.real()*(MaxR-MinR) + MinR;
		seg.start.rot = randgen.integer(0, Nangles-1);
		seg.start.x = randgen.integer(1, Width - 2);
		seg.start.y = randgen.integer(1, Height - 2);

		LineSg line = dom.line(seg, seg.start);
		for (auto l = lines.begin(); l != lines.end(); l++) {
			if (l->hits(line))
				goto redo;
		}

		lines.push_back(line);
		dom.segs.push_back(seg);
	}

	Segments::State st = dom.initialstate();
	for (unsigned int i = 0; i < Nsteps; i++) {
		Segments::Operators ops(dom, st);
		if (ops.size() == 0)
			break;
		unsigned int n = randgen.integer(0, ops.size()-1);
		Segments::Edge e(dom, st, ops[n]);
		st = e.state;
	}

	fprintf(out, "%u %u %u\n", Width, Height, Nangles);
	fprintf(out, "%u\n", Nsegs);
	for (unsigned int i = 0; i < dom.segs.size(); i++) {
		const Segments::Pose &goal = st.poses[i];
		const Segments::Seg &sg = dom.segs[i];
		fprintf(out, "%g ", sg.radius);
		fprintf(out, "%u %u %u ", sg.start.x, sg.start.y, sg.start.rot);
		fprintf(out, "%u %u %u\n", goal.x, goal.y, goal.rot);
	}

}
<commit_msg>segments: add command-line options to mkinst.<commit_after>#include "segments.hpp"
#include "../utils/utils.hpp"
#include <cmath>
#include <cstdio>
#include <cstring>

using namespace geom2d;

static unsigned int Nsegs = 10;
static unsigned int Width = 100;
static unsigned int Height = 100;
static unsigned int Nangles = 32;
static unsigned long Nsteps = 1000000;
static double MaxR = 15;
static double MinR = 1;

void parseargs(int, const char*[]);
void helpmsg(int);
void mkinst(FILE*);

int main(int argc, const char *argv[]) {
	parseargs(argc, argv);
	mkinst(stdout);
	return 0;
}

void parseargs(int argc, const char *argv[]) {
	for (int i = 1; i < argc; i++) {
		if (i < argc-1 && strcmp(argv[i], "nsegs") == 0) {
			Nsegs = strtol(argv[++i], NULL, 10);

		} else if (i < argc-1 && strcmp(argv[i], "width") == 0) {
			Width = strtol(argv[++i], NULL, 10);

		} else if (i < argc-1 && strcmp(argv[i], "height") == 0) {
			Height = strtol(argv[++i], NULL, 10);

		} else if (i < argc-1 && strcmp(argv[i], "nangles") == 0) {
			Nangles = strtol(argv[++i], NULL, 10);

		} else if (i < argc-1 && strcmp(argv[i], "nsteps") == 0) {
			Nsteps = strtoul(argv[++i], NULL, 10);

		} else if (i < argc-1 && strcmp(argv[i], "maxr") == 0) {
			MaxR = strtod(argv[++i], NULL);

		} else if (i < argc-1 && strcmp(argv[i], "minr") == 0) {
			MinR = strtod(argv[++i], NULL);

		} else if (i < argc-1 && strcmp(argv[i], "h") == 0) {
			helpmsg(0);

		} else {
			helpmsg(1);
		}
	}
}

void helpmsg(int status) {
	puts("Usage: mkinst [options]");
	printf("-nsegs	the number of segments (default: %u)\n", Nsegs);
	printf("-width	width of the grid (default: %u)\n", Width);
	printf("-height	height of the grid (default: %u)\n", Height);
	printf("-nangles	the number of angles (must be even, default: %u)\n", Nangles);
	printf("-nsteps	number of steps in the random walk (default: %lu)\n", Nsteps);
	printf("-maxr	the max segment radius (default: %g)\n", MaxR);
	printf("-minr	the min segment radius (default: %g)\n", MinR);
	exit(status);
}

void mkinst(FILE *out) {
	Segments dom(Width, Height, Nangles, std::vector<Segments::Seg>());

	std::vector<LineSg> lines;
	for (unsigned int i = 0; i < Nsegs; i++) {
	redo:
		Segments::Seg seg;
		seg.radius = randgen.real()*(MaxR-MinR) + MinR;
		seg.start.rot = randgen.integer(0, Nangles-1);
		seg.start.x = randgen.integer(1, Width - 2);
		seg.start.y = randgen.integer(1, Height - 2);

		LineSg line = dom.line(seg, seg.start);
		for (auto l = lines.begin(); l != lines.end(); l++) {
			if (l->hits(line))
				goto redo;
		}

		lines.push_back(line);
		dom.segs.push_back(seg);
	}

	Segments::State st = dom.initialstate();
	for (unsigned int i = 0; i < Nsteps; i++) {
		Segments::Operators ops(dom, st);
		if (ops.size() == 0)
			break;
		unsigned int n = randgen.integer(0, ops.size()-1);
		Segments::Edge e(dom, st, ops[n]);
		st = e.state;
	}

	fprintf(out, "%u %u %u\n", Width, Height, Nangles);
	fprintf(out, "%u\n", Nsegs);
	for (unsigned int i = 0; i < dom.segs.size(); i++) {
		const Segments::Pose &goal = st.poses[i];
		const Segments::Seg &sg = dom.segs[i];
		fprintf(out, "%g ", sg.radius);
		fprintf(out, "%u %u %u ", sg.start.x, sg.start.y, sg.start.rot);
		fprintf(out, "%u %u %u\n", goal.x, goal.y, goal.rot);
	}

}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <algorithm>

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE TimSortTest
#include <boost/test/unit_test.hpp>

#include "timsort.hpp"

template<typename T>
int compare(T x, T y) {
    if(x == y) {
        return 0;
    }
    else if(x < y) {
        return -1;
    }
    else {
        return 1;
    }
}

BOOST_AUTO_TEST_CASE( simple10 ) {
    std::vector<int> a;
    a.push_back(60);
    a.push_back(50);
    a.push_back( 1);
    a.push_back(40);
    a.push_back(80);
    a.push_back(20);
    a.push_back(30);
    a.push_back(70);
    a.push_back(10);
    a.push_back(90);

    timsort(a.begin(), a.end(), &compare<int>);

    BOOST_CHECK_EQUAL( a[0],  1 );
    BOOST_CHECK_EQUAL( a[1], 10 );
    BOOST_CHECK_EQUAL( a[2], 20 );
    BOOST_CHECK_EQUAL( a[3], 30 );
    BOOST_CHECK_EQUAL( a[4], 40 );
    BOOST_CHECK_EQUAL( a[5], 50 );
    BOOST_CHECK_EQUAL( a[6], 60 );
    BOOST_CHECK_EQUAL( a[7], 70 );
    BOOST_CHECK_EQUAL( a[8], 80 );
    BOOST_CHECK_EQUAL( a[9], 90 );

    std::reverse(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    BOOST_CHECK_EQUAL( a[0],  1 );
    BOOST_CHECK_EQUAL( a[1], 10 );
    BOOST_CHECK_EQUAL( a[2], 20 );
    BOOST_CHECK_EQUAL( a[3], 30 );
    BOOST_CHECK_EQUAL( a[4], 40 );
    BOOST_CHECK_EQUAL( a[5], 50 );
    BOOST_CHECK_EQUAL( a[6], 60 );
    BOOST_CHECK_EQUAL( a[7], 70 );
    BOOST_CHECK_EQUAL( a[8], 80 );
    BOOST_CHECK_EQUAL( a[9], 90 );
}

BOOST_AUTO_TEST_CASE( shuffle30 ) {
    const int size = 30;

    std::vector<int> a;
    for(int i = 0; i < size; ++i) {
        a.push_back((i+1) * 10);
    }
    std::random_shuffle(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    for(int i = 0; i < size; ++i) {
        BOOST_CHECK_EQUAL( a[i], (i+1) * 10 );
    }
}

BOOST_AUTO_TEST_CASE( shuffle31 ) {
    const int size = 31;

    std::vector<int> a;
    for(int i = 0; i < size; ++i) {
        a.push_back((i+1) * 10);
    }
    std::random_shuffle(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    for(int i = 0; i < size; ++i) {
        BOOST_CHECK_EQUAL( a[i], (i+1) * 10 );
    }
}

BOOST_AUTO_TEST_CASE( shuffle32 ) {
    const int size = 32;

    std::vector<int> a;
    for(int i = 0; i < size; ++i) {
        a.push_back((i+1) * 10);
    }
    std::random_shuffle(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    for(int i = 0; i < size; ++i) {
        BOOST_CHECK_EQUAL( a[i], (i+1) * 10 );
    }
}

BOOST_AUTO_TEST_CASE( shuffle128 ) {
    const int size = 128;

    std::vector<int> a;
    for(int i = 0; i < size; ++i) {
        a.push_back((i+1) * 10);
    }
    std::random_shuffle(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    for(int i = 0; i < size; ++i) {
        BOOST_CHECK_EQUAL( a[i], (i+1) * 10 );
    }
}

<commit_msg>More tests<commit_after>#include <iostream>
#include <vector>
#include <algorithm>

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE TimSortTest
#include <boost/test/unit_test.hpp>

#include "timsort.hpp"

template<typename T>
int compare(T x, T y) {
    if(x == y) {
        return 0;
    }
    else if(x < y) {
        return -1;
    }
    else {
        return 1;
    }
}

BOOST_AUTO_TEST_CASE( simple10 ) {
    std::vector<int> a;
    a.push_back(60);
    a.push_back(50);
    a.push_back( 1);
    a.push_back(40);
    a.push_back(80);
    a.push_back(20);
    a.push_back(30);
    a.push_back(70);
    a.push_back(10);
    a.push_back(90);

    timsort(a.begin(), a.end(), &compare<int>);

    BOOST_CHECK_EQUAL( a[0],  1 );
    BOOST_CHECK_EQUAL( a[1], 10 );
    BOOST_CHECK_EQUAL( a[2], 20 );
    BOOST_CHECK_EQUAL( a[3], 30 );
    BOOST_CHECK_EQUAL( a[4], 40 );
    BOOST_CHECK_EQUAL( a[5], 50 );
    BOOST_CHECK_EQUAL( a[6], 60 );
    BOOST_CHECK_EQUAL( a[7], 70 );
    BOOST_CHECK_EQUAL( a[8], 80 );
    BOOST_CHECK_EQUAL( a[9], 90 );

    std::reverse(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    BOOST_CHECK_EQUAL( a[0],  1 );
    BOOST_CHECK_EQUAL( a[1], 10 );
    BOOST_CHECK_EQUAL( a[2], 20 );
    BOOST_CHECK_EQUAL( a[3], 30 );
    BOOST_CHECK_EQUAL( a[4], 40 );
    BOOST_CHECK_EQUAL( a[5], 50 );
    BOOST_CHECK_EQUAL( a[6], 60 );
    BOOST_CHECK_EQUAL( a[7], 70 );
    BOOST_CHECK_EQUAL( a[8], 80 );
    BOOST_CHECK_EQUAL( a[9], 90 );
}

BOOST_AUTO_TEST_CASE( shuffle30 ) {
    const int size = 30;

    std::vector<int> a;
    for(int i = 0; i < size; ++i) {
        a.push_back((i+1) * 10);
    }
    std::random_shuffle(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    for(int i = 0; i < size; ++i) {
        BOOST_CHECK_EQUAL( a[i], (i+1) * 10 );
    }
}

BOOST_AUTO_TEST_CASE( shuffle31 ) {
    const int size = 31;

    std::vector<int> a;
    for(int i = 0; i < size; ++i) {
        a.push_back((i+1) * 10);
    }
    std::random_shuffle(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    for(int i = 0; i < size; ++i) {
        BOOST_CHECK_EQUAL( a[i], (i+1) * 10 );
    }
}

BOOST_AUTO_TEST_CASE( shuffle32 ) {
    const int size = 32;

    std::vector<int> a;
    for(int i = 0; i < size; ++i) {
        a.push_back((i+1) * 10);
    }
    std::random_shuffle(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    for(int i = 0; i < size; ++i) {
        BOOST_CHECK_EQUAL( a[i], (i+1) * 10 );
    }
}

BOOST_AUTO_TEST_CASE( shuffle128 ) {
    const int size = 128;

    std::vector<int> a;
    for(int i = 0; i < size; ++i) {
        a.push_back((i+1) * 10);
    }
    std::random_shuffle(a.begin(), a.end());

    timsort(a.begin(), a.end(), &compare<int>);

    for(int i = 0; i < size; ++i) {
        BOOST_CHECK_EQUAL( a[i], (i+1) * 10 );
    }
}

BOOST_AUTO_TEST_CASE( shuffle1024 ) {
    const int size = 1024;

    std::vector<int> a;
    for(int i = 0; i < size; ++i) {
        a.push_back((i+1) * 10);
    }

    for(int n = 0; n < 100; ++n) {
        std::random_shuffle(a.begin(), a.end());

        timsort(a.begin(), a.end(), &compare<int>);

        for(int i = 0; i < size; ++i) {
            BOOST_CHECK_EQUAL( a[i], (i+1) * 10 );
        }
    }
}
<|endoftext|>


<commit_before>#include <string>
#include <cstdio>
#include <iostream>
#include <sstream>
#include "json11.hpp"
#include <cassert>
#include <list>
#include <set>
#include <unordered_map>

using namespace json11;
using std::string;

// Check that Json has the properties we want.
#include <type_traits>
#define CHECK_TRAIT(x) static_assert(std::x::value, #x)
CHECK_TRAIT(is_nothrow_constructible<Json>);
CHECK_TRAIT(is_nothrow_default_constructible<Json>);
CHECK_TRAIT(is_copy_constructible<Json>);
CHECK_TRAIT(is_nothrow_move_constructible<Json>);
CHECK_TRAIT(is_copy_assignable<Json>);
CHECK_TRAIT(is_nothrow_move_assignable<Json>);
CHECK_TRAIT(is_nothrow_destructible<Json>);

void parse_from_stdin() {
    string buf;
    while (!std::cin.eof()) buf += std::cin.get();

    string err;
    auto json = Json::parse(buf, err);
    if (!err.empty()) {
        printf("Failed: %s\n", err.c_str());
    } else {
        printf("Result: %s\n", json.dump().c_str());
    }
}

int main(int argc, char **argv) {
    if (argc == 2 && argv[1] == string("--stdin")) {
        parse_from_stdin();
        return 0;
    }

    const string simple_test =
        R"({"k1":"v1", "k2":42, "k3":["a",123,true,false,null]})";

    string err;
    auto json = Json::parse(simple_test, err);

    std::cout << "k1: " << json["k1"].string_value() << "\n";
    std::cout << "k3: " << json["k3"].dump() << "\n";

    for (auto &k : json["k3"].array_items()) {
        std::cout << "    - " << k.dump() << "\n";
    }

    std::list<int> l1 { 1, 2, 3 };
    std::vector<int> l2 { 1, 2, 3 };
    std::set<int> l3 { 1, 2, 3 };
    assert(Json(l1) == Json(l2));
    assert(Json(l2) == Json(l3));

    std::map<string, string> m1 { { "k1", "v1" }, { "k2", "v2" } };
    std::unordered_map<string, string> m2 { { "k1", "v1" }, { "k2", "v2" } };
    assert(Json(m1) == Json(m2));

    // Json literals
    Json obj = Json::object({
        { "k1", "v1" },
        { "k2", 42.0 },
        { "k3", Json::array({ "a", 123.0, true, false, nullptr }) },
    });

    std::cout << "obj: " << obj.dump() << "\n";

    assert(Json("a").number_value() == 0);
    assert(Json("a").string_value() == "a");
    assert(Json().number_value() == 0);

    assert(obj == json);
    assert(Json(42) == Json(42.0));
    assert(Json(42) != Json(42.1));

    const string unicode_escape_test =
        R"([ "blah\ud83d\udca9blah\ud83dblah\udca9blah\u0000blah\u1234" ])";

    const char utf8[] = "blah" "\xf0\x9f\x92\xa9" "blah" "\xed\xa0\xbd" "blah"
                        "\xed\xb2\xa9" "blah" "\0" "blah" "\xe1\x88\xb4";

    Json uni = Json::parse(unicode_escape_test, err);
    assert(uni[0].string_value().size() == (sizeof utf8) - 1);
    assert(memcmp(uni[0].string_value().data(), utf8, sizeof utf8) == 0);

    Json my_json = Json::object {
        { "key1", "value1" },
        { "key2", false },
        { "key3", Json::array { 1, 2, 3 } },
    };
    std::string json_str = my_json.dump();
    printf("%s\n", json_str.c_str());

    class Point {
    public:
        int x;
        int y;
        Point (int x, int y) : x(x), y(y) {}
        Json to_json() const { return Json::array { x, y }; }
    };

    std::vector<Point> points = { { 1, 2 }, { 10, 20 }, { 100, 200 } };
    std::string points_json = Json(points).dump();
    printf("%s\n", points_json.c_str());
}
<commit_msg>Test to demonstrate compiler behavior change in Xcode 7 / clang 3.7.<commit_after>#include <string>
#include <cstdio>
#include <iostream>
#include <sstream>
#include "json11.hpp"
#include <cassert>
#include <list>
#include <set>
#include <unordered_map>

using namespace json11;
using std::string;

// Check that Json has the properties we want.
#include <type_traits>
#define CHECK_TRAIT(x) static_assert(std::x::value, #x)
CHECK_TRAIT(is_nothrow_constructible<Json>);
CHECK_TRAIT(is_nothrow_default_constructible<Json>);
CHECK_TRAIT(is_copy_constructible<Json>);
CHECK_TRAIT(is_nothrow_move_constructible<Json>);
CHECK_TRAIT(is_copy_assignable<Json>);
CHECK_TRAIT(is_nothrow_move_assignable<Json>);
CHECK_TRAIT(is_nothrow_destructible<Json>);

void parse_from_stdin() {
    string buf;
    while (!std::cin.eof()) buf += std::cin.get();

    string err;
    auto json = Json::parse(buf, err);
    if (!err.empty()) {
        printf("Failed: %s\n", err.c_str());
    } else {
        printf("Result: %s\n", json.dump().c_str());
    }
}

int main(int argc, char **argv) {
    if (argc == 2 && argv[1] == string("--stdin")) {
        parse_from_stdin();
        return 0;
    }

    const string simple_test =
        R"({"k1":"v1", "k2":42, "k3":["a",123,true,false,null]})";

    string err;
    auto json = Json::parse(simple_test, err);

    std::cout << "k1: " << json["k1"].string_value() << "\n";
    std::cout << "k3: " << json["k3"].dump() << "\n";

    for (auto &k : json["k3"].array_items()) {
        std::cout << "    - " << k.dump() << "\n";
    }

    std::list<int> l1 { 1, 2, 3 };
    std::vector<int> l2 { 1, 2, 3 };
    std::set<int> l3 { 1, 2, 3 };
    assert(Json(l1) == Json(l2));
    assert(Json(l2) == Json(l3));

    std::map<string, string> m1 { { "k1", "v1" }, { "k2", "v2" } };
    std::unordered_map<string, string> m2 { { "k1", "v1" }, { "k2", "v2" } };
    assert(Json(m1) == Json(m2));

    // Json literals
    Json obj = Json::object({
        { "k1", "v1" },
        { "k2", 42.0 },
        { "k3", Json::array({ "a", 123.0, true, false, nullptr }) },
    });

    std::cout << "obj: " << obj.dump() << "\n";

    assert(Json("a").number_value() == 0);
    assert(Json("a").string_value() == "a");
    assert(Json().number_value() == 0);

    assert(obj == json);
    assert(Json(42) == Json(42.0));
    assert(Json(42) != Json(42.1));

    const string unicode_escape_test =
        R"([ "blah\ud83d\udca9blah\ud83dblah\udca9blah\u0000blah\u1234" ])";

    const char utf8[] = "blah" "\xf0\x9f\x92\xa9" "blah" "\xed\xa0\xbd" "blah"
                        "\xed\xb2\xa9" "blah" "\0" "blah" "\xe1\x88\xb4";

    Json uni = Json::parse(unicode_escape_test, err);
    assert(uni[0].string_value().size() == (sizeof utf8) - 1);
    assert(memcmp(uni[0].string_value().data(), utf8, sizeof utf8) == 0);

    // Demonstrates the behavior change in Xcode 7 / Clang 3.7 described
    // here: https://llvm.org/bugs/show_bug.cgi?id=23812
    Json nested_array = Json::array { Json::array { 1, 2, 3 } };
    assert(nested_array.is_array());
    assert(nested_array.array_items().size() == 1);
    assert(nested_array.array_items()[0].is_array());
    assert(nested_array.array_items()[0].array_items().size() == 3);

    Json my_json = Json::object {
        { "key1", "value1" },
        { "key2", false },
        { "key3", Json::array { 1, 2, 3 } },
    };
    std::string json_str = my_json.dump();
    printf("%s\n", json_str.c_str());

    class Point {
    public:
        int x;
        int y;
        Point (int x, int y) : x(x), y(y) {}
        Json to_json() const { return Json::array { x, y }; }
    };

    std::vector<Point> points = { { 1, 2 }, { 10, 20 }, { 100, 200 } };
    std::string points_json = Json(points).dump();
    printf("%s\n", points_json.c_str());
}
<|endoftext|>


<commit_before>/**
 * \file
 * \brief RawMessageQueue class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-01-17
 */

#ifndef INCLUDE_DISTORTOS_RAWMESSAGEQUEUE_HPP_
#define INCLUDE_DISTORTOS_RAWMESSAGEQUEUE_HPP_

#include "distortos/synchronization/MessageQueueBase.hpp"

namespace distortos
{

/**
 * \brief RawMessageQueue class is very similar to MessageQueue, but optimized for binary serializable types (like POD
 * types). Type T can be used with both RawMessageQueue and MessageQueue<T> only when
 * std::is_trivially_copyable<T>::value == true, otherwise only MessageQueue<T> use is safe, while using RawMessageQueue
 * results in undefined behavior.
 *
 * Similar to POSIX mqd_t - http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/mqueue.h.html
 */

class RawMessageQueue
{
public:

	/// type of uninitialized storage for Entry with link
	using EntryStorage = synchronization::MessageQueueBase::EntryStorage;

	/**
	 * \brief RawMessageQueue's constructor
	 *
	 * \param [in] entryStorage is an array of EntryStorage elements
	 * \param [in] valueStorage is a memory block for elements, sufficiently large for \a maxElements, each
	 * \a elementSize bytes long
	 * \param [in] elementSize is the size of single queue element, bytes
	 * \param [in] maxElements is the number of elements in \a entryStorage array and \a valueStorage memory block
	 */

	RawMessageQueue(EntryStorage* const entryStorage, void* const valueStorage, const size_t elementSize,
			const size_t maxElements) :
			messageQueueBase_{entryStorage, valueStorage, elementSize, maxElements},
			elementSize_{elementSize}
	{

	}

	/**
	 * \brief RawMessageQueue's constructor
	 *
	 * \param T is the type of data in queue
	 * \param N is the number of elements in \a entryStorage array and \a valueStorage memory block
	 *
	 * \param [in] entryStorage is a reference to an array of \a N EntryStorage elements
	 * \param [in] valueStorage is a reference to array that will be used as storage for \a N elements, each sizeof(T)
	 * bytes long
	 */

	template<typename T, size_t N>
	RawMessageQueue(EntryStorage (& entryStorage)[N], T (& valueStorage)[N]) :
			RawMessageQueue{entryStorage, valueStorage, sizeof(*valueStorage),
					sizeof(valueStorage) / sizeof(*valueStorage)}
	{

	}

private:

	/// contained synchronization::MessageQueueBase object which implements base functionality
	synchronization::MessageQueueBase messageQueueBase_;

	/// size of single queue element, bytes
	const size_t elementSize_;
};

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_RAWMESSAGEQUEUE_HPP_
<commit_msg>RawMessageQueue: add helper constructor with std::array as template argument<commit_after>/**
 * \file
 * \brief RawMessageQueue class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-01-17
 */

#ifndef INCLUDE_DISTORTOS_RAWMESSAGEQUEUE_HPP_
#define INCLUDE_DISTORTOS_RAWMESSAGEQUEUE_HPP_

#include "distortos/synchronization/MessageQueueBase.hpp"

namespace distortos
{

/**
 * \brief RawMessageQueue class is very similar to MessageQueue, but optimized for binary serializable types (like POD
 * types). Type T can be used with both RawMessageQueue and MessageQueue<T> only when
 * std::is_trivially_copyable<T>::value == true, otherwise only MessageQueue<T> use is safe, while using RawMessageQueue
 * results in undefined behavior.
 *
 * Similar to POSIX mqd_t - http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/mqueue.h.html
 */

class RawMessageQueue
{
public:

	/// type of uninitialized storage for Entry with link
	using EntryStorage = synchronization::MessageQueueBase::EntryStorage;

	/**
	 * \brief RawMessageQueue's constructor
	 *
	 * \param [in] entryStorage is an array of EntryStorage elements
	 * \param [in] valueStorage is a memory block for elements, sufficiently large for \a maxElements, each
	 * \a elementSize bytes long
	 * \param [in] elementSize is the size of single queue element, bytes
	 * \param [in] maxElements is the number of elements in \a entryStorage array and \a valueStorage memory block
	 */

	RawMessageQueue(EntryStorage* const entryStorage, void* const valueStorage, const size_t elementSize,
			const size_t maxElements) :
			messageQueueBase_{entryStorage, valueStorage, elementSize, maxElements},
			elementSize_{elementSize}
	{

	}

	/**
	 * \brief RawMessageQueue's constructor
	 *
	 * \param T is the type of data in queue
	 * \param N is the number of elements in \a entryStorage array and \a valueStorage memory block
	 *
	 * \param [in] entryStorage is a reference to an array of \a N EntryStorage elements
	 * \param [in] valueStorage is a reference to array that will be used as storage for \a N elements, each sizeof(T)
	 * bytes long
	 */

	template<typename T, size_t N>
	RawMessageQueue(EntryStorage (& entryStorage)[N], T (& valueStorage)[N]) :
			RawMessageQueue{entryStorage, valueStorage, sizeof(*valueStorage),
					sizeof(valueStorage) / sizeof(*valueStorage)}
	{

	}

	/**
	 * \brief RawMessageQueue's constructor
	 *
	 * \param T is the type of data in queue
	 * \param N is the number of elements in \a entryStorage array and \a valueStorage memory block
	 *
	 * \param [in] entryStorage is a reference to an std::array of \a N EntryStorage elements
	 * \param [in] valueStorage is a reference to std::array that will be used as storage for \a N elements, each
	 * sizeof(T) bytes long
	 */

	template<typename T, size_t N>
	RawMessageQueue(std::array<EntryStorage, N>& entryStorage, std::array<T, N>& valueStorage) :
			RawMessageQueue{entryStorage.data(), valueStorage.data(), sizeof(*valueStorage.data()), valueStorage.size()}
	{

	}

private:

	/// contained synchronization::MessageQueueBase object which implements base functionality
	synchronization::MessageQueueBase messageQueueBase_;

	/// size of single queue element, bytes
	const size_t elementSize_;
};

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_RAWMESSAGEQUEUE_HPP_
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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 TORRENT_CREATE_TORRENT_HPP_INCLUDED
#define TORRENT_CREATE_TORRENT_HPP_INCLUDED

#include "libtorrent/bencode.hpp"
#include "libtorrent/peer_id.hpp"
#include "libtorrent/file_storage.hpp"
#include "libtorrent/file_pool.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/hasher.hpp"

#include <vector>
#include <string>
#include <utility>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/optional.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/scoped_ptr.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

namespace libtorrent
{
	namespace fs = boost::filesystem;
	namespace pt = boost::posix_time;

	struct TORRENT_EXPORT create_torrent
	{
		create_torrent(file_storage& fs, int piece_size);
		create_torrent(file_storage& fs);
		entry generate() const;

		file_storage const& files() const { return m_files; }

		void set_comment(char const* str);
		void set_creator(char const* str);
		void set_hash(int index, sha1_hash const& h);
		void add_url_seed(std::string const& url);
		void add_node(std::pair<std::string, int> const& node);
		void add_tracker(std::string const& url, int tier = 0);

		int num_pieces() const { return m_files.num_pieces(); }
		int piece_length() const { return m_files.piece_length(); }
		int piece_size(int i) const { return m_files.piece_size(i); }

	private:

		file_storage& m_files;

		// the urls to the trackers
		typedef std::pair<std::string, int> announce_entry;
		std::vector<announce_entry> m_urls;

		std::vector<std::string> m_url_seeds;

		std::vector<sha1_hash> m_piece_hash;

		// dht nodes to add to the routing table/bootstrap from
		typedef std::vector<std::pair<std::string, int> > nodes_t;
		nodes_t m_nodes;

		// the hash that identifies this torrent
		// is mutable because it's calculated
		// lazily
		mutable sha1_hash m_info_hash;

		// if a creation date is found in the torrent file
		// this will be set to that, otherwise it'll be
		// 1970, Jan 1
		pt::ptime m_creation_date;

		// if a comment is found in the torrent file
		// this will be set to that comment
		std::string m_comment;

		// an optional string naming the software used
		// to create the torrent file
		std::string m_created_by;

		// this is used when creating a torrent. If there's
		// only one file there are cases where it's impossible
		// to know if it should be written as a multifile torrent
		// or not. e.g. test/test  there's one file and one directory
		// and they have the same name.
		bool m_multifile;

		// this is true if the torrent is private. i.e., is should not
		// be announced on the dht
		bool m_private;
	};

	namespace detail
	{
		inline bool default_pred(boost::filesystem::path const&) { return true; }

		inline void nop(int i) {}

		template <class Pred>
		void add_files_impl(file_storage& fs, boost::filesystem::path const& p
			, boost::filesystem::path const& l, Pred pred)
		{
			using boost::filesystem::path;
			using boost::filesystem::directory_iterator;
			std::string const& leaf = l.leaf();
			if (leaf == ".." || leaf == ".") return;
			if (!pred(l)) return;
			path f(p / l);
			if (is_directory(f))
			{
				for (directory_iterator i(f), end; i != end; ++i)
					add_files_impl(fs, p, l / i->leaf(), pred);
			}
			else
			{
				fs.add_file(l, file_size(f));
			}
		}
	}

	template <class Pred>
	void add_files(file_storage& fs, boost::filesystem::path const& file, Pred p)
	{
		detail::add_files_impl(fs, complete(file).branch_path(), file.leaf(), p);
	}

	inline void add_files(file_storage& fs, boost::filesystem::path const& file)
	{
		detail::add_files_impl(fs, complete(file).branch_path(), file.leaf(), detail::default_pred);
	}

	template <class Fun>
	void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, Fun f)
	{
		file_pool fp;
		boost::scoped_ptr<storage_interface> st(
			default_storage_constructor(const_cast<file_storage&>(t.files()), p, fp));

		// calculate the hash for all pieces
		int num = t.num_pieces();
		std::vector<char> buf(t.piece_length());
		for (int i = 0; i < num; ++i)
		{
			// read hits the disk and will block. Progress should
			// be updated in between reads
			st->read(&buf[0], i, 0, t.piece_size(i));
			hasher h(&buf[0], t.piece_size(i));
			t.set_hash(i, h.final());
			f(i);
		}
	}

	inline void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p)
	{
		set_piece_hashes(t, p, detail::nop);
	}

}

#endif

<commit_msg>add set_priv and priv to create_torrent<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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 TORRENT_CREATE_TORRENT_HPP_INCLUDED
#define TORRENT_CREATE_TORRENT_HPP_INCLUDED

#include "libtorrent/bencode.hpp"
#include "libtorrent/peer_id.hpp"
#include "libtorrent/file_storage.hpp"
#include "libtorrent/file_pool.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/hasher.hpp"

#include <vector>
#include <string>
#include <utility>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/optional.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/scoped_ptr.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

namespace libtorrent
{
	namespace fs = boost::filesystem;
	namespace pt = boost::posix_time;

	struct TORRENT_EXPORT create_torrent
	{
		create_torrent(file_storage& fs, int piece_size);
		create_torrent(file_storage& fs);
		entry generate() const;

		file_storage const& files() const { return m_files; }

		void set_comment(char const* str);
		void set_creator(char const* str);
		void set_hash(int index, sha1_hash const& h);
		void add_url_seed(std::string const& url);
		void add_node(std::pair<std::string, int> const& node);
		void add_tracker(std::string const& url, int tier = 0);
		void set_priv(bool p) const { return m_private = p; }

		int num_pieces() const { return m_files.num_pieces(); }
		int piece_length() const { return m_files.piece_length(); }
		int piece_size(int i) const { return m_files.piece_size(i); }
		bool priv() const { return m_private; }

	private:

		file_storage& m_files;

		// the urls to the trackers
		typedef std::pair<std::string, int> announce_entry;
		std::vector<announce_entry> m_urls;

		std::vector<std::string> m_url_seeds;

		std::vector<sha1_hash> m_piece_hash;

		// dht nodes to add to the routing table/bootstrap from
		typedef std::vector<std::pair<std::string, int> > nodes_t;
		nodes_t m_nodes;

		// the hash that identifies this torrent
		// is mutable because it's calculated
		// lazily
		mutable sha1_hash m_info_hash;

		// if a creation date is found in the torrent file
		// this will be set to that, otherwise it'll be
		// 1970, Jan 1
		pt::ptime m_creation_date;

		// if a comment is found in the torrent file
		// this will be set to that comment
		std::string m_comment;

		// an optional string naming the software used
		// to create the torrent file
		std::string m_created_by;

		// this is used when creating a torrent. If there's
		// only one file there are cases where it's impossible
		// to know if it should be written as a multifile torrent
		// or not. e.g. test/test  there's one file and one directory
		// and they have the same name.
		bool m_multifile;

		// this is true if the torrent is private. i.e., is should not
		// be announced on the dht
		bool m_private;
	};

	namespace detail
	{
		inline bool default_pred(boost::filesystem::path const&) { return true; }

		inline void nop(int i) {}

		template <class Pred>
		void add_files_impl(file_storage& fs, boost::filesystem::path const& p
			, boost::filesystem::path const& l, Pred pred)
		{
			using boost::filesystem::path;
			using boost::filesystem::directory_iterator;
			std::string const& leaf = l.leaf();
			if (leaf == ".." || leaf == ".") return;
			if (!pred(l)) return;
			path f(p / l);
			if (is_directory(f))
			{
				for (directory_iterator i(f), end; i != end; ++i)
					add_files_impl(fs, p, l / i->leaf(), pred);
			}
			else
			{
				fs.add_file(l, file_size(f));
			}
		}
	}

	template <class Pred>
	void add_files(file_storage& fs, boost::filesystem::path const& file, Pred p)
	{
		detail::add_files_impl(fs, complete(file).branch_path(), file.leaf(), p);
	}

	inline void add_files(file_storage& fs, boost::filesystem::path const& file)
	{
		detail::add_files_impl(fs, complete(file).branch_path(), file.leaf(), detail::default_pred);
	}

	template <class Fun>
	void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, Fun f)
	{
		file_pool fp;
		boost::scoped_ptr<storage_interface> st(
			default_storage_constructor(const_cast<file_storage&>(t.files()), p, fp));

		// calculate the hash for all pieces
		int num = t.num_pieces();
		std::vector<char> buf(t.piece_length());
		for (int i = 0; i < num; ++i)
		{
			// read hits the disk and will block. Progress should
			// be updated in between reads
			st->read(&buf[0], i, 0, t.piece_size(i));
			hasher h(&buf[0], t.piece_size(i));
			t.set_hash(i, h.final());
			f(i);
		}
	}

	inline void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p)
	{
		set_piece_hashes(t, p, detail::nop);
	}

}

#endif

<|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_EXPRESSIONS_GRAMMAR_HPP
#define MAPNIK_EXPRESSIONS_GRAMMAR_HPP

// mapnik
#include <mapnik/value.hpp>
#include <mapnik/expression_node.hpp>

// boost
#include <boost/version.hpp>
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/concept_check.hpp>

// spirit2
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>

// fusion
#include <boost/fusion/include/adapt_struct.hpp>

// phoenix
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/home/phoenix/object/construct.hpp>

namespace mapnik
{

using namespace boost;
namespace qi = boost::spirit::qi;
namespace standard_wide =  boost::spirit::standard_wide;
using standard_wide::space_type;

struct unicode_impl
{
    template <typename T>
    struct result
    {
        typedef UnicodeString type;
    };

    explicit unicode_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    UnicodeString operator()(std::string const& str) const
    {
        return tr_.transcode(str.c_str());
    }

    mapnik::transcoder const& tr_;
};

struct regex_match_impl
{
    template <typename T0, typename T1>
    struct result
    {
        typedef expr_node type;
    };

    explicit regex_match_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    template <typename T0,typename T1>
    expr_node operator() (T0 & node, T1 const& pattern) const
    {
#if defined(BOOST_REGEX_HAS_ICU)
        return regex_match_node(node,tr_.transcode(pattern.c_str()));
#else
        return regex_match_node(node,pattern);
#endif
    }

    mapnik::transcoder const& tr_;
};

struct regex_replace_impl
{
    template <typename T0, typename T1, typename T2>
    struct result
    {
        typedef expr_node type;
    };

    explicit regex_replace_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    template <typename T0,typename T1,typename T2>
    expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const
    {
#if defined(BOOST_REGEX_HAS_ICU)
        return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str()));
#else
        return regex_replace_node(node,pattern,format);
#endif
    }

    mapnik::transcoder const& tr_;
};

template <typename Iterator>
struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
{
    typedef qi::rule<Iterator, expr_node(), space_type> rule_type;

    explicit expression_grammar(mapnik::transcoder const& tr)
        : expression_grammar::base_type(expr),
          unicode_(unicode_impl(tr)),
          regex_match_(regex_match_impl(tr)),
          regex_replace_(regex_replace_impl(tr))
    {
        using boost::phoenix::construct;
        using qi::_1;
        using qi::_a;
        using qi::_b;
        using qi::_r1;
#if BOOST_VERSION > 104200
        using qi::no_skip;
#else
        using qi::lexeme;
#endif
        using qi::_val;
        using qi::lit;
        using qi::int_;
        using qi::double_;
        using standard_wide::char_;

        expr = logical_expr.alias();

        logical_expr = not_expr [_val = _1]
            >>
            *(  (  ( lit("and") | lit("&&")) >> not_expr [_val && _1] )
                | (( lit("or") | lit("||")) >> not_expr [_val || _1])
                )
            ;

        not_expr =
            cond_expr [_val = _1 ]
            | ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ])
            ;

        cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1]
            ;

        equality_expr =
            relational_expr [_val = _1]
            >> *(  ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1])
                   | (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1])
                )
            ;

        regex_match_expr = lit(".match")
            >> lit('(')
            >> ustring [_val = _1]
            >> lit(')')
            ;

        regex_replace_expr =
            lit(".replace")
            >> lit('(')
            >> ustring           [_a = _1]
            >> lit(',')
            >> ustring           [_b = _1]
            >> lit(')')          [_val = regex_replace_(_r1,_a,_b)]
            ;

        relational_expr = additive_expr[_val = _1]
            >>
            *(  (   (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ])
                | ( (lit('<')  | lit("lt") ) >> additive_expr [ _val <  _1 ])
                | ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ])
                | ( (lit('>')  | lit("gt") ) >> additive_expr [ _val >  _1 ])
                )
            ;
        additive_expr = multiplicative_expr [_val = _1]
            >> * (   '+' >> multiplicative_expr[_val += _1]
                     | '-' >> multiplicative_expr[_val -= _1]
                )
            ;

        multiplicative_expr = primary_expr [_val = _1]
            >> *(     '*' >> primary_expr [_val *= _1]
                      | '/' >> primary_expr [_val /= _1]
                      | '%' >> primary_expr [_val %= _1]
                      |  regex_match_expr[_val = regex_match_(_val, _1)]
                      |  regex_replace_expr(_val) [_val = _1]
                )
            ;

        primary_expr = strict_double [_val = _1]
            | int_ [_val = _1]
            | lit("true") [_val = true]
            | lit("false") [_val = false]
            | lit("null") [_val = value_null() ]
            | ustring [_val = unicode_(_1) ]
            | attr [_val = construct<mapnik::attribute>( _1 ) ]
            | '(' >> expr [_val = _1 ] >> ')'
            ;

        attr %= '[' >> +(char_ - ']') >> ']';
#if BOOST_VERSION > 104200
        ustring %= '\'' >> no_skip[*~char_('\'')] >> '\'';
#else
        ustring %= '\'' >> lexeme[*(char_-'\'')] >> '\'';
#endif
    }

    qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
    boost::phoenix::function<unicode_impl> unicode_;
    boost::phoenix::function<regex_match_impl> regex_match_;
    boost::phoenix::function<regex_replace_impl> regex_replace_;
    //
    rule_type expr;
    rule_type equality_expr;
    rule_type cond_expr;
    rule_type relational_expr;
    rule_type logical_expr;
    rule_type additive_expr;
    rule_type multiplicative_expr;
    rule_type not_expr;
    rule_type primary_expr;
    qi::rule<Iterator, std::string() > regex_match_expr;
    qi::rule<Iterator, expr_node(expr_node), qi::locals<std::string,std::string>, space_type> regex_replace_expr;
    qi::rule<Iterator, std::string() , space_type> attr;
    qi::rule<Iterator, std::string() > ustring;
};

} // namespace

#endif  // MAPNIK_EXPRESSIONS_GRAMMAR_HPP
<commit_msg>don't skip white space in attributes names<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_EXPRESSIONS_GRAMMAR_HPP
#define MAPNIK_EXPRESSIONS_GRAMMAR_HPP

// mapnik
#include <mapnik/value.hpp>
#include <mapnik/expression_node.hpp>

// boost
#include <boost/version.hpp>
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/concept_check.hpp>

// spirit2
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>

// fusion
#include <boost/fusion/include/adapt_struct.hpp>

// phoenix
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/home/phoenix/object/construct.hpp>

namespace mapnik
{

using namespace boost;
namespace qi = boost::spirit::qi;
namespace standard_wide =  boost::spirit::standard_wide;
using standard_wide::space_type;

struct unicode_impl
{
    template <typename T>
    struct result
    {
        typedef UnicodeString type;
    };

    explicit unicode_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    UnicodeString operator()(std::string const& str) const
    {
        return tr_.transcode(str.c_str());
    }

    mapnik::transcoder const& tr_;
};

struct regex_match_impl
{
    template <typename T0, typename T1>
    struct result
    {
        typedef expr_node type;
    };

    explicit regex_match_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    template <typename T0,typename T1>
    expr_node operator() (T0 & node, T1 const& pattern) const
    {
#if defined(BOOST_REGEX_HAS_ICU)
        return regex_match_node(node,tr_.transcode(pattern.c_str()));
#else
        return regex_match_node(node,pattern);
#endif
    }

    mapnik::transcoder const& tr_;
};

struct regex_replace_impl
{
    template <typename T0, typename T1, typename T2>
    struct result
    {
        typedef expr_node type;
    };

    explicit regex_replace_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    template <typename T0,typename T1,typename T2>
    expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const
    {
#if defined(BOOST_REGEX_HAS_ICU)
        return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str()));
#else
        return regex_replace_node(node,pattern,format);
#endif
    }

    mapnik::transcoder const& tr_;
};

template <typename Iterator>
struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
{
    typedef qi::rule<Iterator, expr_node(), space_type> rule_type;

    explicit expression_grammar(mapnik::transcoder const& tr)
        : expression_grammar::base_type(expr),
          unicode_(unicode_impl(tr)),
          regex_match_(regex_match_impl(tr)),
          regex_replace_(regex_replace_impl(tr))
    {
        using boost::phoenix::construct;
        using qi::_1;
        using qi::_a;
        using qi::_b;
        using qi::_r1;
#if BOOST_VERSION > 104200
        using qi::no_skip;
#else
        using qi::lexeme;
#endif
        using qi::_val;
        using qi::lit;
        using qi::int_;
        using qi::double_;
        using standard_wide::char_;

        expr = logical_expr.alias();

        logical_expr = not_expr [_val = _1]
            >>
            *(  (  ( lit("and") | lit("&&")) >> not_expr [_val && _1] )
                | (( lit("or") | lit("||")) >> not_expr [_val || _1])
                )
            ;

        not_expr =
            cond_expr [_val = _1 ]
            | ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ])
            ;

        cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1]
            ;

        equality_expr =
            relational_expr [_val = _1]
            >> *(  ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1])
                   | (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1])
                )
            ;

        regex_match_expr = lit(".match")
            >> lit('(')
            >> ustring [_val = _1]
            >> lit(')')
            ;

        regex_replace_expr =
            lit(".replace")
            >> lit('(')
            >> ustring           [_a = _1]
            >> lit(',')
            >> ustring           [_b = _1]
            >> lit(')')          [_val = regex_replace_(_r1,_a,_b)]
            ;

        relational_expr = additive_expr[_val = _1]
            >>
            *(  (   (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ])
                | ( (lit('<')  | lit("lt") ) >> additive_expr [ _val <  _1 ])
                | ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ])
                | ( (lit('>')  | lit("gt") ) >> additive_expr [ _val >  _1 ])
                )
            ;
        additive_expr = multiplicative_expr [_val = _1]
            >> * (   '+' >> multiplicative_expr[_val += _1]
                     | '-' >> multiplicative_expr[_val -= _1]
                )
            ;

        multiplicative_expr = primary_expr [_val = _1]
            >> *(     '*' >> primary_expr [_val *= _1]
                      | '/' >> primary_expr [_val /= _1]
                      | '%' >> primary_expr [_val %= _1]
                      |  regex_match_expr[_val = regex_match_(_val, _1)]
                      |  regex_replace_expr(_val) [_val = _1]
                )
            ;

        primary_expr = strict_double [_val = _1]
            | int_ [_val = _1]
            | lit("true") [_val = true]
            | lit("false") [_val = false]
            | lit("null") [_val = value_null() ]
            | ustring [_val = unicode_(_1) ]
            | attr [_val = construct<mapnik::attribute>( _1 ) ]
            | '(' >> expr [_val = _1 ] >> ')'
            ;

#if BOOST_VERSION > 104200
        ustring %= '\'' >> no_skip[*~char_('\'')] >> '\'';
        attr %= '[' >> no_skip[+~char_(']')] >> ']';
#else
        ustring %= '\'' >> lexeme[*(char_-'\'')] >> '\'';
        attr %= '[' >> lexeme[+(char_ - ']')] >> ']';
#endif
    }

    qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
    boost::phoenix::function<unicode_impl> unicode_;
    boost::phoenix::function<regex_match_impl> regex_match_;
    boost::phoenix::function<regex_replace_impl> regex_replace_;
    //
    rule_type expr;
    rule_type equality_expr;
    rule_type cond_expr;
    rule_type relational_expr;
    rule_type logical_expr;
    rule_type additive_expr;
    rule_type multiplicative_expr;
    rule_type not_expr;
    rule_type primary_expr;
    qi::rule<Iterator, std::string() > regex_match_expr;
    qi::rule<Iterator, expr_node(expr_node), qi::locals<std::string,std::string>, space_type> regex_replace_expr;
    qi::rule<Iterator, std::string() , space_type> attr;
    qi::rule<Iterator, std::string() > ustring;
};

} // namespace

#endif  // MAPNIK_EXPRESSIONS_GRAMMAR_HPP
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 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
 *
 *****************************************************************************/

//$Id$

#ifndef MARKERS_SYMBOLIZER_HPP
#define MARKERS_SYMBOLIZER_HPP

namespace mapnik {

   struct MAPNIK_DECL markers_symbolizer
   {
     public:
      markers_symbolizer()
         : allow_overlap_(false) {}
     private:
      bool allow_overlap_;

   };
}

#endif // MARKERS_SYMBOLIZER_HPP
<commit_msg>expose get/set for allow_overlap in MarkersSymbolizer<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 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
 *
 *****************************************************************************/

//$Id$

#ifndef MARKERS_SYMBOLIZER_HPP
#define MARKERS_SYMBOLIZER_HPP

namespace mapnik {

   struct MAPNIK_DECL markers_symbolizer
   {
    public:
      markers_symbolizer()
         : allow_overlap_(false) {}

    void set_allow_overlap(bool overlap)
    {
        allow_overlap_ = overlap;
    }
    float get_allow_overlap() const
    {
        return allow_overlap_;
    }
    private:
      bool allow_overlap_;

   };
}

#endif // MARKERS_SYMBOLIZER_HPP
<|endoftext|>


<commit_before>#pragma once

#include <stdexcept>
#include <string>
#include <cassert>

#define NEVER_INLINE  __attribute__((noinline))
#define ALWAYS_INLINE __attribute__((always_inline))
#define UNUSED __attribute__((unused))

#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

#define compiler_barrier() asm volatile("" ::: "memory")

#define MICROSCOPES_DCHECK(expr, msg) \
  do { \
    if (unlikely(!(expr))) \
      throw ::std::runtime_error(msg); \
  } while (0)

// from https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/stubs/common.h
#define MICROSCOPES_ARRAYSIZE(a) \
  ((sizeof(a) / sizeof(*(a))) / \
      static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))

#define _STRINGIFY(x) #x

/**
 * __LINE__ comes from the preprocessor as an int.
 * Stringify hack comes from:
 * http://www.decompile.com/cpp/faq/file_and_line_error_string.htm
 */
#define _LINEHACK(x) _STRINGIFY(x)

#define _SOURCE_INFO \
  (::std::string(__PRETTY_FUNCTION__) + \
   ::std::string(" (" __FILE__ ":" _LINEHACK(__LINE__) ")"))

#define MICROSCOPES_NOT_REACHABLE() \
  do { \
    throw ::std::runtime_error( \
      ::std::string("Should not be reached: ") + \
      ::std::string(_SOURCE_INFO)); \
  } while (0)

#ifdef NDEBUG
  #define ALWAYS_ASSERT(expr) (likely((expr)) ? (void)0 : abort())
#else
  #define ALWAYS_ASSERT(expr) assert((expr))
#endif

#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
  #define GCC_AT_LEAST_47 1
#else
  #define GCC_AT_LEAST_47 0
#endif

// g++-4.6 does not support override, so we define it to be a no-op
#if !defined(__clang__) && !GCC_AT_LEAST_47
  #define override
#endif
<commit_msg>MICROSCOPES_DCHECK disabled for non debug builds<commit_after>#pragma once

#include <stdexcept>
#include <string>
#include <cassert>

#define NEVER_INLINE  __attribute__((noinline))
#define ALWAYS_INLINE __attribute__((always_inline))
#define UNUSED __attribute__((unused))

#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

#define compiler_barrier() asm volatile("" ::: "memory")

#ifdef DEBUG_MODE
  #define MICROSCOPES_DCHECK(expr, msg) \
    do { \
      if (unlikely(!(expr))) \
        throw ::std::runtime_error(msg); \
    } while (0)
#else
  #define MICROSCOPES_DCHECK(expr, msg) ((void)0)
#endif

// from https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/stubs/common.h
#define MICROSCOPES_ARRAYSIZE(a) \
  ((sizeof(a) / sizeof(*(a))) / \
      static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))

#define _STRINGIFY(x) #x

/**
 * __LINE__ comes from the preprocessor as an int.
 * Stringify hack comes from:
 * http://www.decompile.com/cpp/faq/file_and_line_error_string.htm
 */
#define _LINEHACK(x) _STRINGIFY(x)

#define _SOURCE_INFO \
  (::std::string(__PRETTY_FUNCTION__) + \
   ::std::string(" (" __FILE__ ":" _LINEHACK(__LINE__) ")"))

#define MICROSCOPES_NOT_REACHABLE() \
  do { \
    throw ::std::runtime_error( \
      ::std::string("Should not be reached: ") + \
      ::std::string(_SOURCE_INFO)); \
  } while (0)

#ifdef NDEBUG
  #define ALWAYS_ASSERT(expr) (likely((expr)) ? (void)0 : abort())
#else
  #define ALWAYS_ASSERT(expr) assert((expr))
#endif

#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
  #define GCC_AT_LEAST_47 1
#else
  #define GCC_AT_LEAST_47 0
#endif

// g++-4.6 does not support override, so we define it to be a no-op
#if !defined(__clang__) && !GCC_AT_LEAST_47
  #define override
#endif
<|endoftext|>


<commit_before>#pragma once

#include <stdexcept>
#include <string>
#include <cassert>

#define NEVER_INLINE  __attribute__((noinline))
#define ALWAYS_INLINE __attribute__((always_inline))
#define UNUSED __attribute__((unused))

#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

#define compiler_barrier() asm volatile("" ::: "memory")

#define MICROSCOPES_CHECK(expr, msg) \
  do { \
    if (unlikely(!(expr))) \
      throw ::std::runtime_error(msg); \
  } while (0)

#ifdef DEBUG_MODE
  #define MICROSCOPES_DCHECK(expr, msg) MICROSCOPES_CHECK(expr, msg)
#else
  #define MICROSCOPES_DCHECK(expr, msg) ((void)0)
#endif

// from https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/stubs/common.h
#define MICROSCOPES_ARRAYSIZE(a) \
  ((sizeof(a) / sizeof(*(a))) / \
      static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))

#define _STRINGIFY(x) #x

/**
 * __LINE__ comes from the preprocessor as an int.
 * Stringify hack comes from:
 * http://www.decompile.com/cpp/faq/file_and_line_error_string.htm
 */
#define _LINEHACK(x) _STRINGIFY(x)

#define _SOURCE_INFO \
  (::std::string(__PRETTY_FUNCTION__) + \
   ::std::string(" (" __FILE__ ":" _LINEHACK(__LINE__) ")"))

#define MICROSCOPES_NOT_REACHABLE() \
  do { \
    throw ::std::runtime_error( \
      ::std::string("Should not be reached: ") + \
      ::std::string(_SOURCE_INFO)); \
  } while (0)

#define MICROSCOPES_UNIMPLEMENTED() \
  do { \
    throw ::std::runtime_error( \
      ::std::string("Not implemented: ") + \
      ::std::string(_SOURCE_INFO)); \
  } while (0)

#ifdef NDEBUG
  #define ALWAYS_ASSERT(expr) (likely((expr)) ? (void)0 : abort())
#else
  #define ALWAYS_ASSERT(expr) assert((expr))
#endif

#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
  #define GCC_AT_LEAST_47 1
#else
  #define GCC_AT_LEAST_47 0
#endif

// g++-4.6 does not support override, so we define it to be a no-op
#if !defined(__clang__) && !GCC_AT_LEAST_47
  #define override
#endif
<commit_msg>macro nits + MICROSCOPES_MEM{CPY,SET}<commit_after>#pragma once

#include <stdexcept>
#include <string>
#include <cassert>

#define NEVER_INLINE  __attribute__((noinline))
#define ALWAYS_INLINE __attribute__((always_inline))
#define UNUSED        __attribute__((unused))

#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

#define compiler_barrier() asm volatile("" ::: "memory")

#define MICROSCOPES_CHECK(expr, msg) \
  do { \
    if (unlikely(!(expr))) \
      throw ::std::runtime_error(msg); \
  } while (0)

#ifdef DEBUG_MODE
#  define MICROSCOPES_DCHECK(expr, msg) MICROSCOPES_CHECK(expr, msg)
#else
#  define MICROSCOPES_DCHECK(expr, msg) ((void)0)
#endif

// from https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/stubs/common.h
#define MICROSCOPES_ARRAYSIZE(a) \
  ((sizeof(a) / sizeof(*(a))) / \
      static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))

#define _STRINGIFY(x) #x

/**
 * __LINE__ comes from the preprocessor as an int.
 * Stringify hack comes from:
 * http://www.decompile.com/cpp/faq/file_and_line_error_string.htm
 */
#define _LINEHACK(x) _STRINGIFY(x)

#define _SOURCE_INFO \
  (::std::string(__PRETTY_FUNCTION__) + \
   ::std::string(" (" __FILE__ ":" _LINEHACK(__LINE__) ")"))

#define MICROSCOPES_NOT_REACHABLE() \
  do { \
    throw ::std::runtime_error( \
      ::std::string("Should not be reached: ") + \
      ::std::string(_SOURCE_INFO)); \
  } while (0)

#define MICROSCOPES_UNIMPLEMENTED() \
  do { \
    throw ::std::runtime_error( \
      ::std::string("Not implemented: ") + \
      ::std::string(_SOURCE_INFO)); \
  } while (0)

#ifdef NDEBUG
#  define ALWAYS_ASSERT(expr) (likely((expr)) ? (void)0 : abort())
#else
#  define ALWAYS_ASSERT(expr) assert((expr))
#endif

#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
#  define GCC_AT_LEAST_47 1
#else
#  define GCC_AT_LEAST_47 0
#endif

// g++-4.6 does not support override, so we define it to be a no-op
#if !defined(__clang__) && !GCC_AT_LEAST_47
#  define override
#endif

#ifdef __GNUG__
#  define MICROSCOPES_MEMCPY __builtin_memcpy
#  define MICROSCOPES_MEMSET __builtin_memset
#else
#  define MICROSCOPES_MEMCPY memcpy
#  define MICROSCOPES_MEMSET memset
#endif /* __GNUG__ */
<|endoftext|>


<commit_before>#include <stdlib.h>
#include "gtest/gtest.h"

#include "au_set.h"
#include "param_svc.h"
#include "parameter_sets.h"
#include "wels_const.h"

using namespace WelsEnc;

class ParameterSetStrategyTest : public ::testing::Test {
 public:
  virtual void SetUp() {
    pMa = NULL;
    m_pSpsArray = NULL;
    m_pSubsetArray = NULL;

    pMa = new CMemoryAlign (0);
    m_pSpsArray	= (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "m_pSpsArray");
    ASSERT_TRUE (NULL != m_pSpsArray);
    m_pSubsetArray	= (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "m_pSubsetArray");
    ASSERT_TRUE (NULL != m_pSubsetArray);

    m_pSpsArrayPointer = &m_pSpsArray[0];
    m_pSubsetArrayPointer = &m_pSubsetArray[0];

  }
  virtual void TearDown() {
    pMa->WelsFree (m_pSpsArray, "m_pSpsArray");
    pMa->WelsFree (m_pSubsetArray, "m_pSubsetArray");
    delete pMa;
  }
  void GenerateParam (SWelsSvcCodingParam* pParam);
 public:
  CMemoryAlign* pMa;
  SWelsSPS*						m_pSpsArray;
  SSubsetSps*					m_pSubsetArray;

  SWelsSPS*						m_pSpsArrayPointer;
  SSubsetSps*					m_pSubsetArrayPointer;

};

void ParameterSetStrategyTest::GenerateParam (SWelsSvcCodingParam* pParam) {
  SEncParamBase sEncParamBase;
  //TODO: consider randomize it
  sEncParamBase.iUsageType = CAMERA_VIDEO_REAL_TIME;
  sEncParamBase.iPicWidth = 1280;
  sEncParamBase.iPicHeight = 720;
  sEncParamBase.iTargetBitrate = 1000000;
  sEncParamBase.iRCMode = RC_BITRATE_MODE;
  sEncParamBase.fMaxFrameRate = 30.0f;
  pParam->ParamBaseTranscode (sEncParamBase);
}

TEST_F (ParameterSetStrategyTest, FindExistingSps) {
  int iDlayerIndex = 0;
  int iDlayerCount = 0;
  bool bUseSubsetSps = false;
  int iFoundId = -1;
  int iRet = 0;
  SSpatialLayerConfig* pDlayerParam;

  //init parameter
  SWelsSvcCodingParam sParam1;
  GenerateParam (&sParam1);

  //prepare first SPS
  int iCurSpsId = 0;
  int iCurSpsInUse = 1;
  m_pSpsArrayPointer = &m_pSpsArray[iCurSpsId];

  pDlayerParam	= & (sParam1.sSpatialLayers[iDlayerIndex]);
  iRet = WelsInitSps (m_pSpsArrayPointer, pDlayerParam, &sParam1.sDependencyLayers[iDlayerIndex], sParam1.uiIntraPeriod,
                      sParam1.iMaxNumRefFrame,
                      iCurSpsId, sParam1.bEnableFrameCroppingFlag, sParam1.iRCMode != RC_OFF_MODE, iDlayerCount);

  // try finding #0
  iFoundId = FindExistingSps (&sParam1, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, iCurSpsId);

  // try not finding
  SWelsSvcCodingParam sParam2 = sParam1;
  sParam2.iMaxNumRefFrame ++;
  iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, INVALID_ID);

  // add new sps
  iCurSpsId = 1;
  m_pSpsArrayPointer = &m_pSpsArray[iCurSpsId];
  pDlayerParam	= & (sParam2.sSpatialLayers[iDlayerIndex]);
  iRet = WelsInitSps (m_pSpsArrayPointer, pDlayerParam, &sParam2.sDependencyLayers[iDlayerIndex], sParam2.uiIntraPeriod,
                      sParam2.iMaxNumRefFrame,
                      iCurSpsId, sParam2.bEnableFrameCroppingFlag, sParam2.iRCMode != RC_OFF_MODE, iDlayerCount);
  iCurSpsInUse = 2;

  // try finding #1
  iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, iCurSpsId);

  // try finding #0
  iFoundId = FindExistingSps (&sParam1, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, 0);

  // try not finding
  if (sParam2.sDependencyLayers[0].iActualWidth > 1) {

    sParam2.sDependencyLayers[0].iActualWidth--;
  } else {
    sParam2.sDependencyLayers[0].iActualWidth++;
  }

  iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, INVALID_ID);
}

<commit_msg>Avoid a warning about a variable set but not used<commit_after>#include <stdlib.h>
#include "gtest/gtest.h"

#include "au_set.h"
#include "param_svc.h"
#include "parameter_sets.h"
#include "wels_const.h"

using namespace WelsEnc;

class ParameterSetStrategyTest : public ::testing::Test {
 public:
  virtual void SetUp() {
    pMa = NULL;
    m_pSpsArray = NULL;
    m_pSubsetArray = NULL;

    pMa = new CMemoryAlign (0);
    m_pSpsArray	= (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "m_pSpsArray");
    ASSERT_TRUE (NULL != m_pSpsArray);
    m_pSubsetArray	= (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "m_pSubsetArray");
    ASSERT_TRUE (NULL != m_pSubsetArray);

    m_pSpsArrayPointer = &m_pSpsArray[0];
    m_pSubsetArrayPointer = &m_pSubsetArray[0];

  }
  virtual void TearDown() {
    pMa->WelsFree (m_pSpsArray, "m_pSpsArray");
    pMa->WelsFree (m_pSubsetArray, "m_pSubsetArray");
    delete pMa;
  }
  void GenerateParam (SWelsSvcCodingParam* pParam);
 public:
  CMemoryAlign* pMa;
  SWelsSPS*						m_pSpsArray;
  SSubsetSps*					m_pSubsetArray;

  SWelsSPS*						m_pSpsArrayPointer;
  SSubsetSps*					m_pSubsetArrayPointer;

};

void ParameterSetStrategyTest::GenerateParam (SWelsSvcCodingParam* pParam) {
  SEncParamBase sEncParamBase;
  //TODO: consider randomize it
  sEncParamBase.iUsageType = CAMERA_VIDEO_REAL_TIME;
  sEncParamBase.iPicWidth = 1280;
  sEncParamBase.iPicHeight = 720;
  sEncParamBase.iTargetBitrate = 1000000;
  sEncParamBase.iRCMode = RC_BITRATE_MODE;
  sEncParamBase.fMaxFrameRate = 30.0f;
  pParam->ParamBaseTranscode (sEncParamBase);
}

TEST_F (ParameterSetStrategyTest, FindExistingSps) {
  int iDlayerIndex = 0;
  int iDlayerCount = 0;
  bool bUseSubsetSps = false;
  int iFoundId = -1;
  int iRet = 0;
  SSpatialLayerConfig* pDlayerParam;

  //init parameter
  SWelsSvcCodingParam sParam1;
  GenerateParam (&sParam1);

  //prepare first SPS
  int iCurSpsId = 0;
  int iCurSpsInUse = 1;
  m_pSpsArrayPointer = &m_pSpsArray[iCurSpsId];

  pDlayerParam	= & (sParam1.sSpatialLayers[iDlayerIndex]);
  iRet = WelsInitSps (m_pSpsArrayPointer, pDlayerParam, &sParam1.sDependencyLayers[iDlayerIndex], sParam1.uiIntraPeriod,
                      sParam1.iMaxNumRefFrame,
                      iCurSpsId, sParam1.bEnableFrameCroppingFlag, sParam1.iRCMode != RC_OFF_MODE, iDlayerCount);

  // try finding #0
  iFoundId = FindExistingSps (&sParam1, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, iCurSpsId);

  // try not finding
  SWelsSvcCodingParam sParam2 = sParam1;
  sParam2.iMaxNumRefFrame ++;
  iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, INVALID_ID);

  // add new sps
  iCurSpsId = 1;
  m_pSpsArrayPointer = &m_pSpsArray[iCurSpsId];
  pDlayerParam	= & (sParam2.sSpatialLayers[iDlayerIndex]);
  iRet = WelsInitSps (m_pSpsArrayPointer, pDlayerParam, &sParam2.sDependencyLayers[iDlayerIndex], sParam2.uiIntraPeriod,
                      sParam2.iMaxNumRefFrame,
                      iCurSpsId, sParam2.bEnableFrameCroppingFlag, sParam2.iRCMode != RC_OFF_MODE, iDlayerCount);
  iCurSpsInUse = 2;

  // try finding #1
  iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, iCurSpsId);

  // try finding #0
  iFoundId = FindExistingSps (&sParam1, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, 0);

  // try not finding
  if (sParam2.sDependencyLayers[0].iActualWidth > 1) {

    sParam2.sDependencyLayers[0].iActualWidth--;
  } else {
    sParam2.sDependencyLayers[0].iActualWidth++;
  }

  iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
                              m_pSpsArray, m_pSubsetArray);
  EXPECT_EQ (iFoundId, INVALID_ID);
  (void) iRet; // Not using iRet at the moment
}

<|endoftext|>


<commit_before>#include "halide_image.h"

#include <stdint.h>
#include <stdio.h>
#include <limits>
#include <type_traits>
#include <vector>

using namespace std;
using namespace Halide::Tools;

//-----------------------------------------------------------------------------
// Returns the dimension sizes of a statically sized array from inner to outer.
// E.g. ary[2][3][4] returns (4, 3, 2).

template<typename T>
vector<int> dimension_sizes(T const &, vector<int> dimSizes = vector<int>() ) {
    return dimSizes;
}

template<typename Array, size_t N>
vector<int> dimension_sizes(Array (&vals)[N], vector<int> dimSizes = vector<int>()) {
    dimSizes = dimension_sizes(vals[0], dimSizes);
    dimSizes.push_back((int)N);
    return dimSizes;
}

//-----------------------------------------------------------------------------
// Return the address of the first element, no matter how many dimensions
// Array has.

template<typename T>
T const * first_of_array(T const &val) {
    return &val;
}

template<typename Array, size_t N>
typename remove_all_extents<Array>::type const * first_of_array(Array (&vals)[N]) {
    return first_of_array(vals[0]);
}

//-----------------------------------------------------------------------------
// Verify dimension_sizes() works as intended.

void print_vector(vector<int> const &v) {
    printf("(");
    for (size_t i = 0, last = v.size(); i < last; ++i) {
        if (i)
            printf(", ");
        printf("%d", v[i]);
    }
    printf(")");
}
void compare_vectors(vector<int> const &under_test, vector<int> const &reference) {
    if (under_test == reference)
        return;

    printf("Vector under test contained ");
    print_vector(under_test);
    printf(" instead of ");
    print_vector(reference);
    printf("\n");
    exit(-1);
}

void verify_dimension_sizes() {
    int a1[2];
    int a2[4][3];
    int a3[7][6][5];
    int a4[11][10][9][8];

    vector<int> v1(1), v2(2), v3(3), v4(4);
    v1[0] = 2;
    v2[0] = 3; v2[1] = 4;
    v3[0] = 5; v3[1] = 6; v3[2] = 7;
    v4[0] = 8; v4[1] = 9; v4[2] = 10; v4[3] = 11;

    compare_vectors(dimension_sizes(a1), v1);
    compare_vectors(dimension_sizes(a2), v2);
    compare_vectors(dimension_sizes(a3), v3);
    compare_vectors(dimension_sizes(a4), v4);
}

//-----------------------------------------------------------------------------

template<typename T>
void compare_extents(Image<T> const &img, int reference, int dimension) {
    if (img.extent(dimension) == reference)
        return;
    printf("Extent of dimension %d of %d is %d instead of %d\n"
        , dimension, img.dimensions(), img.extent(dimension), reference);
    exit(-1);
}

template<typename T
    , typename Int = typename is_integral<T>::type
    , typename Signed = integral_constant<bool, numeric_limits<T>::is_signed>
>
struct print_compared_t;

template<typename T> struct print_compared_t<T, true_type, true_type> {
    void operator()(T test, T reference) const {
        printf("%lld instead of %lld\n"
            , static_cast<int64_t>(test)
            , static_cast<int64_t>(reference));
    }
};

template<typename T> struct print_compared_t<T, true_type, false_type> {
    void operator()(T test, T reference) const {
        printf("%llu instead of %llu\n"
            , static_cast<uint64_t>(test)
            , static_cast<uint64_t>(reference));
    }
};

template<> struct print_compared_t<float> {
    void operator()(float test, float reference) const {
        printf("%0.8g instead of %0.8g\n", test, reference);
    }
};

template<> struct print_compared_t<double> {
    void operator()(double test, double reference) const {
        printf("%0.17g instead of %0.17g\n", test, reference);
    }
};

template<typename T>
void print_compared(T test, T reference) {
    print_compared_t<T> printer;
    printer(test, reference);
}

template<typename Array, typename T = typename remove_all_extents<Array>::type>
void verify_image_construction_from_array(Array &vals) {
    Image<T> img(vals);
    vector<int> dimSizes(dimension_sizes(vals));
    int dims = (int)dimSizes.size();
    int n = 1;
    for (int i = 0; i < dims; ++i) {
        compare_extents(img, dimSizes[i], i);
        n *= dimSizes[i];
    }
    T const *reference = first_of_array(vals);
    T const *under_test = img.data();
    for (int i = 0; i < n; ++i) {
        if (under_test[i] == reference[i])
            continue;

        printf("Value at index %d is ", i);
        print_compared(under_test[i], reference[i]);
        exit(-1);
    }
}

template<typename T>
void construct_various_dimensionalities(T q) {
    T a1[2];
    T a2[4][3];
    T a3[7][6][5];
    T a4[11][10][9][8];

    int v = 0;
    for (int i0 = 0; i0 < 11; ++i0) {
        if (i0 < 2)
            a1[i0] = static_cast<T>( (++v) * q );

        for (int i1 = 0; i1 < 10; ++i1) {
            if (i0 < 4 && i1 < 3)
                a2[i0][i1] = static_cast<T>( (++v) * q );

            for (int i2 = 0; i2 < 9; ++i2) {
                if (i0 < 7 && i1 < 6 && i2 < 5)
                    a3[i0][i1][i2] = static_cast<T>( (++v) * q );

                for (int i3 = 0; i3 < 8; ++i3)
                    a4[i0][i1][i2][i3] = static_cast<T>( (++v) * q );
            }
        }
    }

    verify_image_construction_from_array(a1);
    verify_image_construction_from_array(a2);
    verify_image_construction_from_array(a3);
    verify_image_construction_from_array(a4);
}
//-----------------------------------------------------------------------------

int main()
{
    // Verify dimension_sizes() works as intended.
    verify_dimension_sizes();

    construct_various_dimensionalities(static_cast<uint8_t >(1));
    construct_various_dimensionalities(static_cast<uint16_t>(2));
    construct_various_dimensionalities(static_cast<uint32_t>(4));
    construct_various_dimensionalities(static_cast<uint64_t>(8));

    construct_various_dimensionalities(static_cast<int8_t >(-1));
    construct_various_dimensionalities(static_cast<int16_t>(-2));
    construct_various_dimensionalities(static_cast<int32_t>(-3));
    construct_various_dimensionalities(static_cast<int64_t>(-4));

    construct_various_dimensionalities(1.1f);
    construct_various_dimensionalities(1.2);

    printf("Success!\n");
    return 0;
}<commit_msg>Use ostream instead of printf<commit_after>#include "halide_image.h"

#include <stdint.h>
#include <iostream>
#include <limits>
#include <type_traits>
#include <vector>

using namespace std;
using namespace Halide::Tools;

//-----------------------------------------------------------------------------
// Returns the dimension sizes of a statically sized array from inner to outer.
// E.g. ary[2][3][4] returns (4, 3, 2).

template<typename T>
vector<int> dimension_sizes(T const &, vector<int> dimSizes = vector<int>() ) {
    return dimSizes;
}

template<typename Array, size_t N>
vector<int> dimension_sizes(Array (&vals)[N], vector<int> dimSizes = vector<int>()) {
    dimSizes = dimension_sizes(vals[0], dimSizes);
    dimSizes.push_back((int)N);
    return dimSizes;
}

//-----------------------------------------------------------------------------
// Return the address of the first element, no matter how many dimensions
// Array has.

template<typename T>
T const * first_of_array(T const &val) {
    return &val;
}

template<typename Array, size_t N>
typename remove_all_extents<Array>::type const * first_of_array(Array (&vals)[N]) {
    return first_of_array(vals[0]);
}

//-----------------------------------------------------------------------------
// Verify dimension_sizes() works as intended.

void print_vector(vector<int> const &v) {
    cout << "(";
    for (size_t i = 0, last = v.size(); i < last; ++i) {
        if (i)
            cout << ", ";
        cout << v[i];
    }
    cout << ")";
}

void compare_vectors(vector<int> const &under_test, vector<int> const &reference) {
    if (under_test == reference)
        return;

    cout << "Vector under test contained ";
    print_vector(under_test);
    cout << " instead of ";
    print_vector(reference);
    cout << "\n";
    exit(-1);
}

void verify_dimension_sizes() {
    int a1[2];
    int a2[4][3];
    int a3[7][6][5];
    int a4[11][10][9][8];

    vector<int> v1(1), v2(2), v3(3), v4(4);
    v1[0] = 2;
    v2[0] = 3; v2[1] = 4;
    v3[0] = 5; v3[1] = 6; v3[2] = 7;
    v4[0] = 8; v4[1] = 9; v4[2] = 10; v4[3] = 11;

    compare_vectors(dimension_sizes(a1), v1);
    compare_vectors(dimension_sizes(a2), v2);
    compare_vectors(dimension_sizes(a3), v3);
    compare_vectors(dimension_sizes(a4), v4);
}

//-----------------------------------------------------------------------------
// Convert integral values to 64-bit and set the number of digits to print
// for floating point values.

template<typename T
    , typename Int = typename is_integral<T>::type
    , typename Signed = integral_constant<bool, numeric_limits<T>::is_signed>
>
struct printable_t;

template<typename T> struct printable_t<T, true_type, true_type> {
    int64_t v;
    printable_t(T v) : v(static_cast<int64_t>(v)) {}
    void print(ostream &os) const {
        os << v;
    }
};

template<typename T> struct printable_t<T, true_type, false_type> {
    uint64_t v;
    printable_t(T v) : v(static_cast<uint64_t>(v)) {}
    void print(ostream &os) const {
        os << v;
    }
};

template<typename T> struct printable_t<T, false_type> {
    T v;
    printable_t(T v) : v(v) {}
    void print(ostream &os) const {
        streamsize prec = os.precision();
        os.precision(numeric_limits<T>::digits10 + 2);
        os << v;
        os.precision(prec);
    }
};

template<typename T>
inline ostream & operator<<(ostream &os, printable_t<T> const &pr) {
    pr.print(os);
    return os;
}

template<typename T>
inline printable_t<T> printable(T v) {
    return printable_t<T>(v);
}

//-----------------------------------------------------------------------------

template<typename T>
void compare_extents(Image<T> const &img, int reference, int dimension) {
    if (img.extent(dimension) == reference)
        return;
    cout << "Extent of dimension " << dimension << " of " << img.dimensions()
        << " is " << img.extent(dimension) << " instead of " << reference << "\n";
    exit(-1);
}

template<typename Array, typename T = typename remove_all_extents<Array>::type>
void verify_image_construction_from_array(Array &vals) {
    Image<T> img(vals);
    vector<int> dimSizes(dimension_sizes(vals));
    int dims = (int)dimSizes.size();
    int n = 1;
    for (int i = 0; i < dims; ++i) {
        compare_extents(img, dimSizes[i], i);
        n *= dimSizes[i];
    }
    T const *reference = first_of_array(vals);
    T  *under_test = img.data();
    for (int i = 0; i < n; ++i) {
        if (under_test[i] == reference[i])
            continue;

        cout << "Value at index " << i << " is "
            << printable(under_test[i]) << " instead of "
            << printable(reference[i]) << "\n";
        exit(-1);
    }
}

template<typename T>
void construct_various_dimensionalities(T q) {
    T a1[2];
    T a2[4][3];
    T a3[7][6][5];
    T a4[11][10][9][8];

    int v = 0;
    for (int i0 = 0; i0 < 11; ++i0) {
        if (i0 < 2)
            a1[i0] = static_cast<T>( (++v) * q );

        for (int i1 = 0; i1 < 10; ++i1) {
            if (i0 < 4 && i1 < 3)
                a2[i0][i1] = static_cast<T>( (++v) * q );

            for (int i2 = 0; i2 < 9; ++i2) {
                if (i0 < 7 && i1 < 6 && i2 < 5)
                    a3[i0][i1][i2] = static_cast<T>( (++v) * q );

                for (int i3 = 0; i3 < 8; ++i3)
                    a4[i0][i1][i2][i3] = static_cast<T>( (++v) * q );
            }
        }
    }

    verify_image_construction_from_array(a1);
    verify_image_construction_from_array(a2);
    verify_image_construction_from_array(a3);
    verify_image_construction_from_array(a4);
}

//-----------------------------------------------------------------------------

int main()
{
    // Verify dimension_sizes() works as intended.
    verify_dimension_sizes();

    construct_various_dimensionalities(static_cast<uint8_t >(1));
    construct_various_dimensionalities(static_cast<uint16_t>(2));
    construct_various_dimensionalities(static_cast<uint32_t>(4));
    construct_various_dimensionalities(static_cast<uint64_t>(8));

    construct_various_dimensionalities(static_cast<int8_t >(-1));
    construct_various_dimensionalities(static_cast<int16_t>(-2));
    construct_various_dimensionalities(static_cast<int32_t>(-3));
    construct_various_dimensionalities(static_cast<int64_t>(-4));

    construct_various_dimensionalities(1.1f);
    construct_various_dimensionalities(1.2);

    printf("Success!\n");
    return 0;
}<|endoftext|>


<commit_before>// Copyright (c) 2015
// Author: Chrono Law
#ifndef _NGX_COMMON_HEADERS_HPP
#define _NGX_COMMON_HEADERS_HPP

extern "C" {

#include <nginx.h>
#include <ngx_http.h>

}

#include <cassert>
#include <boost/core/ignore_unused.hpp>

#define ngx_cpp_version 1000000
#define NGX_CPP_VERSION "1.0.0"

#endif  //_NGX_COMMON_HEADERS_HPP
<commit_msg>nginx.h fix<commit_after>// Copyright (c) 2015
// Author: Chrono Law
#ifndef _NGX_COMMON_HEADERS_HPP
#define _NGX_COMMON_HEADERS_HPP

extern "C" {

#include <ngx_http.h>
#include <nginx.h>

}

#include <cassert>
#include <boost/core/ignore_unused.hpp>

#define ngx_cpp_version 1000000
#define NGX_CPP_VERSION "1.0.0"

#endif  //_NGX_COMMON_HEADERS_HPP
<|endoftext|>