<commit_before>#ifndef Matrix_hpp
#define Matrix_hpp

#include <iostream>

unsigned int Factorial( unsigned int number ) {
    return number <= 1 ? number : Factorial(number-1)*number;
}
/*class Matrix {
public:
	Matrix() : lines(0), columns(0), elements(nullptr) {}
	Matrix(int _lines, int _columns);
	Matrix(const Matrix& source_matrix);
	Matrix& operator= (const Matrix& source_matrix);
	void InitFromRandom();
	void InitFromFile(char *filename);
	void Output() const;
	int* operator[](int index) const;
	const Matrix operator+(const Matrix& right_matrix);
	const Matrix operator*(const Matrix& right_matrix);
	int GetNumberOfLines() const;
	int GetNumberOfColumns() const;
	~Matrix();
private:
	int lines, columns, **elements;
};

Matrix::Matrix(int _lines, int _columns)  :
	lines(_lines), columns(_columns), elements(new int*[_lines]) {
	for (int i = 0; i < lines; i++) {
		elements[i] = new int[columns];
		for (int j = 0; j < columns; j++){
			elements[i][j] = 0;
		}
	}
}
Matrix::Matrix(const Matrix& source_matrix)
	: lines(source_matrix.lines), columns(source_matrix.columns) {
	elements = new int*[lines];
	for (int i = 0; i < lines; i++) {
		elements[i] = new int[columns];
		for (int j  = 0; j < columns; j++) {
			elements[i][j] = source_matrix[i][j];
		}
	}
}
Matrix& Matrix::operator= (const Matrix& source_matrix) {
	if (lines != source_matrix.lines || columns != source_matrix.columns) {
		this -> ~Matrix();
		lines = source_matrix.lines;
		columns = source_matrix.columns;
		elements = new int*[lines];
		for (int i = 0; i < lines; i++) {
			elements[i] = new int[columns];
			for (int j = 0; j < columns; j++) {
				elements[i][j] = source_matrix[i][j];
			}
		}
	} else{
		for (int i = 0; i < lines; i++){
			for (int j = 0; j < columns; j++){
				elements[i][j] = source_matrix[i][j];
			}
		}
	}
	return *this;
}
void Matrix::InitFromRandom() {
	for (int i = 0; i < lines; i++)
		for (int j = 0; j < columns; j++)
			elements[i][j] = rand() % 90 + 10;
}
void Matrix::InitFromFile(char *filename) {
	std::fstream file(filename);
	for (int i = 0; i < lines; i++) {
		for (int j = 0; j < columns; j++) {
			file >> elements[i][j];
		}
	}
}
void Matrix::Output() const {
	for (int i = 0; i < lines; i++) {
		for (int j = 0; j < columns; j++)
			std::cout << elements[i][j] << " ";
		std::cout << "\n";
	}
}
int*  Matrix::operator[](int index) const {
	return elements[index];
}
Matrix Matrix::operator+(const Matrix& right_matrix) const {
	if (columns != right_matrix.GetNumberOfColumns()
		|| lines != right_matrix.GetNumberOfLines())
		return *(new Matrix());
	Matrix result(lines, columns);
	for (int i = 0; i < lines; i++)
		for (int j = 0; j < columns; j++)
			result[i][j] = elements[i][j] + right_matrix[i][j];
	return result;
}
Matrix Matrix::operator*(const Matrix& right_matrix) const {
	if (columns != right_matrix.lines) return *(new Matrix());
	Matrix result(lines, right_matrix.columns);
	for (int i = 0; i < lines; i++)
		for (int j = 0; j < right_matrix.columns; j++) {
			result[i][j] = 0;
			for (int k = 0; k < right_matrix.lines; k++)
				result[i][j] += elements[i][k] * right_matrix[k][j];
		}
	return result;
}
int Matrix::GetNumberOfLines() const {
	return lines;
}
int Matrix::GetNumberOfColumns() const {
	return columns;
}
Matrix::~Matrix() {
	for (int i = 0; i < lines; i++)
		delete[] elements[i];
	delete[] elements;
}
*/
#endif
<commit_msg>Update Matrix.hpp<commit_after>#ifndef Matrix_hpp
#define Matrix_hpp

#include <iostream>

unsigned int Factorial( unsigned int number ) {
  return number > 1 ? Factorial(number-1)*number : 1;
}
/*class Matrix {
public:
	Matrix() : lines(0), columns(0), elements(nullptr) {}
	Matrix(int _lines, int _columns);
	Matrix(const Matrix& source_matrix);
	Matrix& operator= (const Matrix& source_matrix);
	void InitFromRandom();
	void InitFromFile(char *filename);
	void Output() const;
	int* operator[](int index) const;
	const Matrix operator+(const Matrix& right_matrix);
	const Matrix operator*(const Matrix& right_matrix);
	int GetNumberOfLines() const;
	int GetNumberOfColumns() const;
	~Matrix();
private:
	int lines, columns, **elements;
};

Matrix::Matrix(int _lines, int _columns)  :
	lines(_lines), columns(_columns), elements(new int*[_lines]) {
	for (int i = 0; i < lines; i++) {
		elements[i] = new int[columns];
		for (int j = 0; j < columns; j++){
			elements[i][j] = 0;
		}
	}
}
Matrix::Matrix(const Matrix& source_matrix)
	: lines(source_matrix.lines), columns(source_matrix.columns) {
	elements = new int*[lines];
	for (int i = 0; i < lines; i++) {
		elements[i] = new int[columns];
		for (int j  = 0; j < columns; j++) {
			elements[i][j] = source_matrix[i][j];
		}
	}
}
Matrix& Matrix::operator= (const Matrix& source_matrix) {
	if (lines != source_matrix.lines || columns != source_matrix.columns) {
		this -> ~Matrix();
		lines = source_matrix.lines;
		columns = source_matrix.columns;
		elements = new int*[lines];
		for (int i = 0; i < lines; i++) {
			elements[i] = new int[columns];
			for (int j = 0; j < columns; j++) {
				elements[i][j] = source_matrix[i][j];
			}
		}
	} else{
		for (int i = 0; i < lines; i++){
			for (int j = 0; j < columns; j++){
				elements[i][j] = source_matrix[i][j];
			}
		}
	}
	return *this;
}
void Matrix::InitFromRandom() {
	for (int i = 0; i < lines; i++)
		for (int j = 0; j < columns; j++)
			elements[i][j] = rand() % 90 + 10;
}
void Matrix::InitFromFile(char *filename) {
	std::fstream file(filename);
	for (int i = 0; i < lines; i++) {
		for (int j = 0; j < columns; j++) {
			file >> elements[i][j];
		}
	}
}
void Matrix::Output() const {
	for (int i = 0; i < lines; i++) {
		for (int j = 0; j < columns; j++)
			std::cout << elements[i][j] << " ";
		std::cout << "\n";
	}
}
int*  Matrix::operator[](int index) const {
	return elements[index];
}
Matrix Matrix::operator+(const Matrix& right_matrix) const {
	if (columns != right_matrix.GetNumberOfColumns()
		|| lines != right_matrix.GetNumberOfLines())
		return *(new Matrix());
	Matrix result(lines, columns);
	for (int i = 0; i < lines; i++)
		for (int j = 0; j < columns; j++)
			result[i][j] = elements[i][j] + right_matrix[i][j];
	return result;
}
Matrix Matrix::operator*(const Matrix& right_matrix) const {
	if (columns != right_matrix.lines) return *(new Matrix());
	Matrix result(lines, right_matrix.columns);
	for (int i = 0; i < lines; i++)
		for (int j = 0; j < right_matrix.columns; j++) {
			result[i][j] = 0;
			for (int k = 0; k < right_matrix.lines; k++)
				result[i][j] += elements[i][k] * right_matrix[k][j];
		}
	return result;
}
int Matrix::GetNumberOfLines() const {
	return lines;
}
int Matrix::GetNumberOfColumns() const {
	return columns;
}
Matrix::~Matrix() {
	for (int i = 0; i < lines; i++)
		delete[] elements[i];
	delete[] elements;
}
*/
#endif
<|endoftext|>


<commit_before>/**
 * @file		config.CPP
 * @brief		Config file loader
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details	Load config file to run the engine
 */

#include "config.hpp"
#include "configloader.hpp"

namespace cossb {
namespace base {

config::config():_doc(nullptr)
{

}
config::~config()
{
	if(_doc)
		delete _doc;
}

bool config::load(const char* manifest_conf)
{
	if(_doc!=nullptr)
	{
		delete _doc;
		_doc = nullptr;
	}

	_doc = new tinyxml2::XMLDocument;
	if(_doc->LoadFile(manifest_conf)==XML_SUCCESS)
		return true;

	return false;
}

bool config::update(config* conf)
{
	return false;
}

/*map<string, string> config::get_dependency()
{
	switch(type)
	{
	case deptype::LIBRARY:	return parse_dependency("library");	break;
	case deptype::COMPONENT:	return parse_dependency("component");	break;
	default:
		cout << "unknown dependency type" << endl;
	}

	return list<string>();
}*/

void config::parse_dependency()
{
	XMLElement* elem_com = _doc->FirstChildElement("manifest");
	for(XMLElement* child = elem_com->FirstChildElement("dependency");child!=nullptr; child = child->NextSiblingElement("dependency"))
	{
		if(child->Attribute("type","library"))
			_dependency["library"] = child->GetText();
		else if(child->Attribute("type","component"))
			_dependency["component"] = child->GetText();
	}
}

void config::parse_path()
{
	XMLElement* elem_com = _doc->FirstChildElement("manifest")->FirstChildElement("property");
	for(XMLElement* child = elem_com->FirstChildElement("path");child!=nullptr; child = child->NextSiblingElement("path"))
		_path[child->Attribute("name")] = child->GetText();
}

void config::parse_repository()
{
	XMLElement* elem_uri = _doc->FirstChildElement("manifest")->FirstChildElement("repository");
	for(XMLElement* child = elem_uri->FirstChildElement("uri");child!=nullptr; child = child->NextSiblingElement("uri"))
		_repository.push_back(child->GetText());
}

void config::parse_product()
{
	XMLElement* elem_com = _doc->FirstChildElement("manifest")->FirstChildElement("product");
	for(XMLElement* child = elem_com->FirstChildElement();child!=nullptr; child = child->NextSiblingElement())
		_product[child->Value()] = child->GetText();
}

} /* namespace base */
} /* namespace cossb */
<commit_msg>fix bug, if no element value, std::string will occurred error.<commit_after>/**
 * @file		config.CPP
 * @brief		Config file loader
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details	Load config file to run the engine
 */

#include "config.hpp"
#include "configloader.hpp"

namespace cossb {
namespace base {

config::config():_doc(nullptr)
{

}
config::~config()
{
	if(_doc)
		delete _doc;
}

bool config::load(const char* manifest_conf)
{
	if(_doc!=nullptr)
	{
		delete _doc;
		_doc = nullptr;
	}

	_doc = new tinyxml2::XMLDocument;
	if(_doc->LoadFile(manifest_conf)==XML_SUCCESS)
	{
		parse_dependency();
		parse_product();
		parse_path();
		parse_repository();

		return true;
	}

	return false;
}

bool config::update(config* conf)
{
	return false;
}

/*map<string, string> config::get_dependency()
{
	switch(type)
	{
	case deptype::LIBRARY:	return parse_dependency("library");	break;
	case deptype::COMPONENT:	return parse_dependency("component");	break;
	default:
		cout << "unknown dependency type" << endl;
	}

	return list<string>();
}*/

void config::parse_dependency()
{
	XMLElement* elem_com = _doc->FirstChildElement("manifest");
	for(XMLElement* child = elem_com->FirstChildElement("dependency");child!=nullptr; child = child->NextSiblingElement("dependency"))
	{
		if(child->Attribute("type","library"))
			_dependency["library"] = child->GetText();
		else if(child->Attribute("type","component"))
			_dependency["component"] = child->GetText();
	}
}

void config::parse_path()
{
	XMLElement* elem_com = _doc->FirstChildElement("manifest")->FirstChildElement("property");
	for(XMLElement* child = elem_com->FirstChildElement("path");child!=nullptr; child = child->NextSiblingElement("path"))
		_path[child->Attribute("name")] = child->GetText();
}

void config::parse_repository()
{
	XMLElement* elem_uri = _doc->FirstChildElement("manifest")->FirstChildElement("repository");
	for(XMLElement* child = elem_uri->FirstChildElement("uri");child!=nullptr; child = child->NextSiblingElement("uri"))
		if(child->GetText())
			_repository.push_back(child->GetText());
}

void config::parse_product()
{
	XMLElement* elem_com = _doc->FirstChildElement("manifest")->FirstChildElement("product");
	for(XMLElement* child = elem_com->FirstChildElement();child!=nullptr; child = child->NextSiblingElement())
		_product[child->Value()] = child->GetText();
}

} /* namespace base */
} /* namespace cossb */
<|endoftext|>


<commit_before>#include "../../testing/testing.hpp"

#include "../platform.hpp"
#include "../../std/stdio.hpp"

#include "../../base/start_mem_debug.hpp"

UNIT_TEST(TimeInSec)
{
  Platform & pl = GetPlatform();

  double t1 = pl.TimeInSec();
  double s = 0.0;
  for (int i = 0; i < 10000000; ++i)
    s += i*0.01;
  double t2 = pl.TimeInSec();

  TEST_NOT_EQUAL(s, 0.0, ("Fictive, to prevent loop optimization"));
  TEST_NOT_EQUAL(t1, t2, ("Timer values should not be equal"));

#ifndef DEBUG
  t1 = pl.TimeInSec();
  for (int i = 0; i < 10000000; ++i) {}
  t2 = pl.TimeInSec();

  TEST_EQUAL(t1, t2, ("Timer values should be equal: compiler loop optimization!"));
#endif
}

char const * TEST_FILE_NAME = "some_temporary_unit_test_file.tmp";

UNIT_TEST(WritableDir)
{
  string const path = GetPlatform().WritableDir() + TEST_FILE_NAME;
  FILE * f = fopen(path.c_str(), "w");
  TEST_NOT_EQUAL(f, 0, ("Can't create file", path));
  if (f)
    fclose(f);
  remove(path.c_str());
}

UNIT_TEST(WritablePathForFile)
{
  string const p1 = GetPlatform().WritableDir() + TEST_FILE_NAME;
  string const p2 = GetPlatform().WritablePathForFile(TEST_FILE_NAME);
  TEST_EQUAL(p1, p2, ());
}

UNIT_TEST(ReadPathForFile)
{
  char const * NON_EXISTING_FILE = "mgbwuerhsnmbui45efhdbn34.tmp";
  char const * arr[] = { "drawing_rules.bin", "basic.skn", "classificator.txt", "minsk-pass.wmw" };
  Platform & p = GetPlatform();
  for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
  {
    TEST_GREATER( p.ReadPathForFile(arr[i]).size(), 0, ("File should exist!") );
  }

  bool wasException = false;
  try
  {
    p.ReadPathForFile(NON_EXISTING_FILE);
  }
  catch (FileAbsentException const &)
  {
    wasException = true;
  }
  TEST( wasException, ());
}

UNIT_TEST(GetFilesInDir)
{
  Platform & pl = GetPlatform();
  Platform::FilesList files;
  TEST_GREATER(pl.GetFilesInDir(pl.WritableDir(), "*.dat", files), 0, ("/data/ folder should contain some *.dat files"));

  TEST_EQUAL(pl.GetFilesInDir(pl.WritableDir(), "asdnonexistentfile.dsa", files), 0, ());
  TEST_EQUAL(files.size(), 0, ());
}

UNIT_TEST(GetFileSize)
{
  Platform & pl = GetPlatform();
  uint64_t size = 0;
  pl.GetFileSize(pl.ReadPathForFile("classificator.txt").c_str(), size);
  TEST_GREATER(size, 0, ("File classificator.txt should exist for test"));
}

UNIT_TEST(CpuCores)
{
  int coresNum = GetPlatform().CpuCores();
  TEST_GREATER(coresNum, 0, ());
  TEST_LESS_OR_EQUAL(coresNum, 128, ());
}

UNIT_TEST(VisualScale)
{
  double visualScale = GetPlatform().VisualScale();
  TEST_GREATER_OR_EQUAL(visualScale, 1.0, ());
}
<commit_msg>Fixed typo<commit_after>#include "../../testing/testing.hpp"

#include "../platform.hpp"
#include "../../std/stdio.hpp"

#include "../../base/start_mem_debug.hpp"

UNIT_TEST(TimeInSec)
{
  Platform & pl = GetPlatform();

  double t1 = pl.TimeInSec();
  double s = 0.0;
  for (int i = 0; i < 10000000; ++i)
    s += i*0.01;
  double t2 = pl.TimeInSec();

  TEST_NOT_EQUAL(s, 0.0, ("Fictive, to prevent loop optimization"));
  TEST_NOT_EQUAL(t1, t2, ("Timer values should not be equal"));

#ifndef DEBUG
  t1 = pl.TimeInSec();
  for (int i = 0; i < 10000000; ++i) {}
  t2 = pl.TimeInSec();

  TEST_EQUAL(t1, t2, ("Timer values should be equal: compiler loop optimization!"));
#endif
}

char const * TEST_FILE_NAME = "some_temporary_unit_test_file.tmp";

UNIT_TEST(WritableDir)
{
  string const path = GetPlatform().WritableDir() + TEST_FILE_NAME;
  FILE * f = fopen(path.c_str(), "w");
  TEST_NOT_EQUAL(f, 0, ("Can't create file", path));
  if (f)
    fclose(f);
  remove(path.c_str());
}

UNIT_TEST(WritablePathForFile)
{
  string const p1 = GetPlatform().WritableDir() + TEST_FILE_NAME;
  string const p2 = GetPlatform().WritablePathForFile(TEST_FILE_NAME);
  TEST_EQUAL(p1, p2, ());
}

UNIT_TEST(ReadPathForFile)
{
  char const * NON_EXISTING_FILE = "mgbwuerhsnmbui45efhdbn34.tmp";
  char const * arr[] = { "drawing_rules.bin", "basic.skn", "classificator.txt", "minsk-pass.mwm" };
  Platform & p = GetPlatform();
  for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
  {
    TEST_GREATER( p.ReadPathForFile(arr[i]).size(), 0, ("File should exist!") );
  }

  bool wasException = false;
  try
  {
    p.ReadPathForFile(NON_EXISTING_FILE);
  }
  catch (FileAbsentException const &)
  {
    wasException = true;
  }
  TEST( wasException, ());
}

UNIT_TEST(GetFilesInDir)
{
  Platform & pl = GetPlatform();
  Platform::FilesList files;
  TEST_GREATER(pl.GetFilesInDir(pl.WritableDir(), "*.dat", files), 0, ("/data/ folder should contain some *.dat files"));

  TEST_EQUAL(pl.GetFilesInDir(pl.WritableDir(), "asdnonexistentfile.dsa", files), 0, ());
  TEST_EQUAL(files.size(), 0, ());
}

UNIT_TEST(GetFileSize)
{
  Platform & pl = GetPlatform();
  uint64_t size = 0;
  pl.GetFileSize(pl.ReadPathForFile("classificator.txt").c_str(), size);
  TEST_GREATER(size, 0, ("File classificator.txt should exist for test"));
}

UNIT_TEST(CpuCores)
{
  int coresNum = GetPlatform().CpuCores();
  TEST_GREATER(coresNum, 0, ());
  TEST_LESS_OR_EQUAL(coresNum, 128, ());
}

UNIT_TEST(VisualScale)
{
  double visualScale = GetPlatform().VisualScale();
  TEST_GREATER_OR_EQUAL(visualScale, 1.0, ());
}
<|endoftext|>


<commit_before>#include "folder.h"
#include "exception.h"
#include "fileops.h"
#include "types.h"

namespace IO {
	Folder::Folder() {}

	bool Folder::Path(const std::string& path) {
		std::lock_guard<std::mutex> l(m_mxCall);

		if (!IO::DoPathExist(path)) {
			return false;
		}
		m_path = path;

		return true;
	}

	std::string Folder::Path() const {
		std::lock_guard<std::mutex> l(m_mxCall);
		return m_path;
	}

	FileList Folder::CurrentContents() const {
		auto iter = CreateIterator();
		FileList files;

		for (auto x : iter) {
			FolderEntry toRet;
			if (boost::filesystem::is_directory(x)) {
				toRet.Type = TypeFolder;
			}
			if (boost::filesystem::is_regular_file(x)) {
				toRet.Type = TypeFile;
			}

			toRet.Name = x.path().filename().string();
			files.push_back(toRet);
		}
		return files;
	}

	boost::filesystem::directory_iterator  Folder::CreateIterator() const {
		std::lock_guard<std::mutex> l(m_mxCall);
		return boost::filesystem::directory_iterator(m_path);
	}
}
<commit_msg>Improve GCC 4.9 compatibility<commit_after>#include "folder.h"
#include "exception.h"
#include "fileops.h"
#include "types.h"
#include <iterator>

namespace IO {
	Folder::Folder() {}

	bool Folder::Path(const std::string& path) {
		std::lock_guard<std::mutex> l(m_mxCall);

		if (!IO::DoPathExist(path)) {
			return false;
		}
		m_path = path;

		return true;
	}

	std::string Folder::Path() const {
		std::lock_guard<std::mutex> l(m_mxCall);
		return m_path;
	}

	FileList Folder::CurrentContents() const {
		auto iter = CreateIterator();
		FileList files;

		for (auto x = iter; x != boost::filesystem::directory_iterator(); x++) {
			FolderEntry toRet;
			if (boost::filesystem::is_directory(*x)) {
				toRet.Type = TypeFolder;
			}
			if (boost::filesystem::is_regular_file(*x)) {
				toRet.Type = TypeFile;
			}

			toRet.Name = x->path().filename().string();
			files.push_back(toRet);
		}
		return files;
	}

	boost::filesystem::directory_iterator  Folder::CreateIterator() const {
		std::lock_guard<std::mutex> l(m_mxCall);
		return boost::filesystem::directory_iterator(m_path);
	}
}
<|endoftext|>


<commit_before><commit_msg>Put SampleBuffer into its own complation unit<commit_after><|endoftext|>


<commit_before>#include "position.h"
#include <cstring>
#include <cstdlib>
#include <stdexcept>

namespace {

Piece translate_fen_piece(char c) {
    Color color = std::isupper(c) ? WHITE : BLACK;
    c = std::tolower(c);
    PieceKind piece;
    switch (c) {
        case 'p': piece = PAWN; break;
        case 'n': piece = KNIGHT; break;
        case 'b': piece = BISHOP; break;
        case 'r': piece = ROOK; break;
        case 'q': piece = QUEEN; break;
        case 'k': piece = KING; break;
        default: throw std::runtime_error{"Invalid piece"};
    }
    return Piece{color, piece};
}

} // ~anonymous namespace

Position::Position() noexcept
    : moves(1u)
    , halfmoves(0u)
    , wtm(1u)
    , ep_target(Position::ENPASSANT_NONE)
    , castle(Position::CASTLE_NONE)
{
    boards.fill(0ull);
    sidemask.fill(0ull);
    sq2p.fill(NO_PIECE);
}

Position Position::from_fen(std::string_view fen) {
    Position position;
    auto it = fen.begin();
    const auto last = fen.end();

    auto expect = [last](std::string_view::iterator it, char c) {
        if (it == last || *it != c) {
            std::string msg = "Expected '";
            msg += c;
            msg += "', received '";
            if (it == last) {
                msg += "<eof>";
            } else {
                msg += *it;
            }
            msg += "'";
            throw std::runtime_error(msg.c_str());
        }
        ++it;
        return it;
    };

    for (int rank = 7; rank >= 0; --rank) {
        for (int file = 0; file < 8; ++file) {
            if (it == last) {
                throw std::runtime_error("Board specification too short");
            }
            char c = *it++;
            if (c >= '1' && c <= '8') {
                file += c - '0' - 1;
                if (file >= 8) {
                    throw std::runtime_error("Invalid board specification");
                }
            } else {
                Piece piece = translate_fen_piece(c);
                Square sq(static_cast<u8>(file), static_cast<u8>(rank));
                position.sq2p[sq.value()] = piece;
                position.sidemask[piece.color()] |= sq.mask();
                if (piece.kind() == KING) {
                    // position.kings[piece.color()] = sq.value();
                    position.kings[piece.color()] = sq;
                } else {
                    position.boards[piece.value()] |= sq.mask();
                }
            }
        }
        if (it < last && *it == '/') {
            ++it;
        }
    }
    it = expect(it, ' ');

    // Active Color
    if (it == last) {
        throw std::runtime_error("Expected color specification");
    }
    switch (*it++) {
        case 'W':
        case 'w':
            position._set_white_to_move(true);
            break;
        case 'B':
        case 'b':
            position._set_white_to_move(false);
            break;
        default:
            throw std::runtime_error("Invalid character in color specification");
    }
    it = expect(it, ' ');

    // Castling Availability
    if (it == last) {
        throw std::runtime_error("Expected castling availability specification");
    } else if (*it == '-') {
        position._set_castle_flags(Position::CASTLE_NONE);
        ++it;
    } else {
        u8 flags = 0;
        while (it < last && *it != ' ') {
            char c = *it++;
            switch (c) {
            case 'K':
                flags |= Position::CASTLE_WHITE_KING_SIDE;
                break;
            case 'k':
                flags |= Position::CASTLE_BLACK_KING_SIDE;
                break;
            case 'Q':
                flags |= Position::CASTLE_WHITE_QUEEN_SIDE;
                break;
            case 'q':
                flags |= Position::CASTLE_BLACK_QUEEN_SIDE;
                break;
            default:
                throw std::runtime_error("Invalid character in castling specification");
            }
        }
        position._set_castle_flags(flags);
    }
    it = expect(it, ' ');

    // En passant Target Square
    if (it == last) {
        throw std::runtime_error("Expected en passant target square");
    } else if (*it == '-') {
        position._set_enpassant_square(Position::ENPASSANT_NONE);
        ++it;
    } else {
        char c = *it++;
        if (!(c >= 'a' && c <= 'h')) {
            throw std::runtime_error("Invalid file for enpassant target square");
        }
        u8 file = c - 'a';
        u8 rank = *it++ - '1';
        assert(file >= 0 && file <= 7);
        assert(rank >= 0 && rank <= 7);
        Square square{file, rank};
        if (rank == RANK_3) {
            assert(square.value() >= A3 && square.value() <= H3);
            position._set_enpassant_square(square.value() - A3);
        } else if (rank == RANK_6) {
            assert(square.value() >= A6 && square.value() <= H6);
            position._set_enpassant_square(square.value() - A6);
        } else {
            throw std::runtime_error("Invalid rank for enpassant target square");
        }
    }

    // may or may not have halfmove and move specifications
    bool has_halfmove = it != last && *it++ == ' ';
    if (has_halfmove && it != last) {
        // Halfmove spec (50-move rule)
        while (it != last && *it != ' ') {
            if (*it < '0' && *it > '9') {
                throw std::runtime_error("Invalid halfmove specification");
            }
            position.halfmoves *= 10;
            position.halfmoves += *it - '0';
            ++it;
        }

        // assuming that if halfmove is there then move spec is also there
        it = expect(it, ' ');
        position.moves = 0;
        while (it != last && *it != ' ') {
            if (*it < '0' && *it > '9') {
                throw std::runtime_error("Invalid move specification");
            }
            position.moves *= 10;
            position.moves += *it - '0';
            ++it;
        }
    }

    return position;
}

[[nodiscard]]
constexpr u8 rook_square_to_castle_flag(Square square) noexcept {
    switch (square.value()) {
        case A8: return Position::CASTLE_BLACK_QUEEN_SIDE;
        case H8: return Position::CASTLE_BLACK_KING_SIDE;
        case A1: return Position::CASTLE_WHITE_QUEEN_SIDE;
        case H1: return Position::CASTLE_WHITE_KING_SIDE;
        default: return 0;
    }
}

[[nodiscard]]
constexpr bool is_rank2(u8 side, Square square) noexcept {
    constexpr u64 SECOND_RANK{0xff00ull};
    constexpr u64 SEVENTH_RANK{0xff000000000000ull};
    u64 mask = side == WHITE ? SECOND_RANK : SEVENTH_RANK;
    return square.mask() & mask;
}

[[nodiscard]]
constexpr bool is_rank7(u8 side, Square square) noexcept {
    return is_rank2(side ^ 1, square);
}

[[nodiscard]]
constexpr bool is_enpassant_square(u8 side, Square square) noexcept {
    constexpr u64 WHITE_ENPASSANT_SQUARES{0x00000000ff000000ull};
    constexpr u64 BLACK_ENPASSANT_SQUARES{0x000000ff00000000ull};
    u64 mask = side == WHITE ? WHITE_ENPASSANT_SQUARES : BLACK_ENPASSANT_SQUARES;
    return square.mask() & mask;
}

void Position::make_move(Savepos& sp, Move move) noexcept {
    assert(wtm == WHITE || wtm == BLACK);
    const Color side = static_cast<Color>(wtm);
    const Color contra = static_cast<Color>(side ^ 1);
    const Square from = move.from();
    const Square to = move.to();
    const Piece piece = piece_on_square(from);
    const Piece captured = piece_on_square(to);
    const Move::Flags flags = move.flags();
    const PieceKind kind = piece.kind();
    u64* board = kind != KING ? &boards[piece.value()] : 0;

    assert(to != from);
    assert(captured.kind() != KING);
    assert(piece.color() == side);
    assert(captured.empty() || captured.color() == contra);

    sp.halfmoves = halfmoves;
    sp.ep_target = ep_target;
    sp.castle = castle;
    sp.capture = captured;

    if (flags == Move::Flags::NONE) {
        if (board) {
            *board &= ~from.mask();
            *board |= to.mask();
        } else {
            kings[side] = to; // to.value();
            if (side == WHITE) {
                castle &= ~Position::CASTLE_WHITE;
            } else {
                castle &= ~Position::CASTLE_BLACK;
            }
        }
        sq2p[from.value()] = NO_PIECE;
        sq2p[to.value()] = piece;
        sidemask[side] &= ~from.mask();
        sidemask[side] |= to.mask();

        if (!captured.empty()) {
            boards[captured.value()] &= ~to.mask();
            sidemask[contra] &= ~to.mask();
            castle &= ~rook_square_to_castle_flag(to);
        } else if (kind == PAWN && is_rank2(side, from) && is_enpassant_square(side, to)) {
            u8 target = side == WHITE ? to.value() - 8 : to.value() + 8;
            _set_enpassant_square(target);
            assert((target >= A3 && target <= H3) || (target >= A6 && target <= H6));
        }

        if (kind == ROOK) {
            castle &= ~rook_square_to_castle_flag(from);
        }
    } else if (flags == Move::Flags::ENPASSANT) {
        assert(enpassant_available() == true);
        const Square target = enpassant_target_square();
        assert(kind == PAWN);
        assert(captured.empty());
        *board &= ~from.mask();
        *board |= to.mask();
        board[Piece(contra, PAWN).value()] &= ~target.mask();
        sq2p[target.value()] = NO_PIECE;
        sq2p[from.value()] = NO_PIECE;
        sq2p[to.value()] = piece;
        sidemask[side] &= ~from.mask();
        sidemask[side] |= to.mask();
        sidemask[contra] &= ~target.mask();
    } else if (flags == Move::Flags::PROMOTION) {
        const PieceKind promotion_kind = move.promotion();
        const Piece promotion_piece = Piece(side, promotion_kind);
        assert(kind == PAWN);
        *board &= ~from.mask();
        boards[promotion_piece.value()] |= to.mask();
        sq2p[to.value()] = promotion_piece;
        sq2p[from.value()] = NO_PIECE;
        sidemask[side] &= ~from.mask();
        sidemask[side] |= to.mask();
        if (!captured.empty()) {
            boards[captured.value()] &= ~to.mask();
            sidemask[contra] &= ~to.mask();
            castle &= ~rook_square_to_castle_flag(to);
        }
     } else if (flags == Move::Flags::CASTLE) {
         assert(kind == KING);
         u64* rooks = &boards[Piece(side, ROOK).value()];
         Square ksq;
         Square rsq;
         switch (to.value()) {
             case H1:
                 ksq = Square(G1);
                 rsq = Square(F1);
             case A1:
                 ksq = Square(C1);
                 rsq = Square(D1);
             case H8:
                 ksq = Square(G8);
                 rsq = Square(F8);
             case A8:
                 ksq = Square(C8);
                 rsq = Square(D8);
             default:
                 assert(0);
                 __builtin_unreachable();
         }
         kings[side] = ksq;
         *rooks &= ~to.mask();
         *rooks |= rsq.mask();

         sq2p[from.value()] = NO_PIECE;
         sq2p[to.value()] = NO_PIECE;
         sq2p[ksq.value()] = Piece(side, KING);
         sq2p[rsq.value()] = Piece(side, ROOK);
         sidemask[side] &= ~(to.mask() | from.mask());
         sidemask[side] |= ksq.mask() | rsq.mask();
        if (side == WHITE) {
            castle &= ~Position::CASTLE_WHITE;
        } else {
            castle &= ~Position::CASTLE_BLACK;
        }
     } else {
         assert(0);
         __builtin_unreachable();
     }

    wtm = contra;
    if (kind == PAWN || !captured.empty()) {
        halfmoves = 0;
    } else {
        ++halfmoves;
    }
    if (side == BLACK) {
        ++moves;
    }
}

void Position::undo_move(const Savepos& sp, Move move) noexcept {

}
<commit_msg>Set ep_target as actual Square<commit_after>#include "position.h"
#include <cstring>
#include <cstdlib>
#include <stdexcept>

namespace {

Piece translate_fen_piece(char c) {
    Color color = std::isupper(c) ? WHITE : BLACK;
    c = std::tolower(c);
    PieceKind piece;
    switch (c) {
        case 'p': piece = PAWN; break;
        case 'n': piece = KNIGHT; break;
        case 'b': piece = BISHOP; break;
        case 'r': piece = ROOK; break;
        case 'q': piece = QUEEN; break;
        case 'k': piece = KING; break;
        default: throw std::runtime_error{"Invalid piece"};
    }
    return Piece{color, piece};
}

} // ~anonymous namespace

Position::Position() noexcept
    : moves(1u)
    , halfmoves(0u)
    , wtm(1u)
    , ep_target(Position::ENPASSANT_NONE)
    , castle(Position::CASTLE_NONE)
{
    boards.fill(0ull);
    sidemask.fill(0ull);
    sq2p.fill(NO_PIECE);
}

Position Position::from_fen(std::string_view fen) {
    Position position;
    auto it = fen.begin();
    const auto last = fen.end();

    auto expect = [last](std::string_view::iterator it, char c) {
        if (it == last || *it != c) {
            std::string msg = "Expected '";
            msg += c;
            msg += "', received '";
            if (it == last) {
                msg += "<eof>";
            } else {
                msg += *it;
            }
            msg += "'";
            throw std::runtime_error(msg.c_str());
        }
        ++it;
        return it;
    };

    for (int rank = 7; rank >= 0; --rank) {
        for (int file = 0; file < 8; ++file) {
            if (it == last) {
                throw std::runtime_error("Board specification too short");
            }
            char c = *it++;
            if (c >= '1' && c <= '8') {
                file += c - '0' - 1;
                if (file >= 8) {
                    throw std::runtime_error("Invalid board specification");
                }
            } else {
                Piece piece = translate_fen_piece(c);
                Square sq(static_cast<u8>(file), static_cast<u8>(rank));
                position.sq2p[sq.value()] = piece;
                position.sidemask[piece.color()] |= sq.mask();
                if (piece.kind() == KING) {
                    position.kings[piece.color()] = sq;
                } else {
                    position.boards[piece.value()] |= sq.mask();
                }
            }
        }
        if (it < last && *it == '/') {
            ++it;
        }
    }
    it = expect(it, ' ');

    // Active Color
    if (it == last) {
        throw std::runtime_error("Expected color specification");
    }
    switch (*it++) {
        case 'W':
        case 'w':
            position._set_white_to_move(true);
            break;
        case 'B':
        case 'b':
            position._set_white_to_move(false);
            break;
        default:
            throw std::runtime_error("Invalid character in color specification");
    }
    it = expect(it, ' ');

    // Castling Availability
    if (it == last) {
        throw std::runtime_error("Expected castling availability specification");
    } else if (*it == '-') {
        position._set_castle_flags(Position::CASTLE_NONE);
        ++it;
    } else {
        u8 flags = 0;
        while (it < last && *it != ' ') {
            char c = *it++;
            switch (c) {
            case 'K':
                flags |= Position::CASTLE_WHITE_KING_SIDE;
                break;
            case 'k':
                flags |= Position::CASTLE_BLACK_KING_SIDE;
                break;
            case 'Q':
                flags |= Position::CASTLE_WHITE_QUEEN_SIDE;
                break;
            case 'q':
                flags |= Position::CASTLE_BLACK_QUEEN_SIDE;
                break;
            default:
                throw std::runtime_error("Invalid character in castling specification");
            }
        }
        position._set_castle_flags(flags);
    }
    it = expect(it, ' ');

    // En passant Target Square
    if (it == last) {
        throw std::runtime_error("Expected en passant target square");
    } else if (*it == '-') {
        position._set_enpassant_square(Position::ENPASSANT_NONE);
        ++it;
    } else {
        char c = *it++;
        if (!(c >= 'a' && c <= 'h')) {
            throw std::runtime_error("Invalid file for enpassant target square");
        }
        u8 file = c - 'a';
        u8 rank = *it++ - '1';
        assert(file >= 0 && file <= 7);
        assert(rank >= 0 && rank <= 7);
        Square square{file, rank};
        if (rank == RANK_3) {
            assert(square.value() >= A3 && square.value() <= H3);
            position._set_enpassant_square(square.value());
        } else if (rank == RANK_6) {
            assert(square.value() >= A6 && square.value() <= H6);
            position._set_enpassant_square(square.value());
        } else {
            throw std::runtime_error("Invalid rank for enpassant target square");
        }
    }

    // may or may not have halfmove and move specifications
    bool has_halfmove = it != last && *it++ == ' ';
    if (has_halfmove && it != last) {
        // Halfmove spec (50-move rule)
        while (it != last && *it != ' ') {
            if (*it < '0' && *it > '9') {
                throw std::runtime_error("Invalid halfmove specification");
            }
            position.halfmoves *= 10;
            position.halfmoves += *it - '0';
            ++it;
        }

        // assuming that if halfmove is there then move spec is also there
        it = expect(it, ' ');
        position.moves = 0;
        while (it != last && *it != ' ') {
            if (*it < '0' && *it > '9') {
                throw std::runtime_error("Invalid move specification");
            }
            position.moves *= 10;
            position.moves += *it - '0';
            ++it;
        }
    }

    return position;
}

[[nodiscard]]
constexpr u8 rook_square_to_castle_flag(Square square) noexcept {
    switch (square.value()) {
        case A8: return Position::CASTLE_BLACK_QUEEN_SIDE;
        case H8: return Position::CASTLE_BLACK_KING_SIDE;
        case A1: return Position::CASTLE_WHITE_QUEEN_SIDE;
        case H1: return Position::CASTLE_WHITE_KING_SIDE;
        default: return 0;
    }
}

[[nodiscard]]
constexpr bool is_rank2(u8 side, Square square) noexcept {
    constexpr u64 SECOND_RANK{0xff00ull};
    constexpr u64 SEVENTH_RANK{0xff000000000000ull};
    u64 mask = side == WHITE ? SECOND_RANK : SEVENTH_RANK;
    return square.mask() & mask;
}

[[nodiscard]]
constexpr bool is_rank7(u8 side, Square square) noexcept {
    return is_rank2(side ^ 1, square);
}

[[nodiscard]]
constexpr bool is_enpassant_square(u8 side, Square square) noexcept {
    constexpr u64 WHITE_ENPASSANT_SQUARES{0x00000000ff000000ull};
    constexpr u64 BLACK_ENPASSANT_SQUARES{0x000000ff00000000ull};
    u64 mask = side == WHITE ? WHITE_ENPASSANT_SQUARES : BLACK_ENPASSANT_SQUARES;
    return square.mask() & mask;
}

void Position::make_move(Savepos& sp, Move move) noexcept {
    assert(wtm == WHITE || wtm == BLACK);
    const Color side = static_cast<Color>(wtm);
    const Color contra = static_cast<Color>(side ^ 1);
    const Square from = move.from();
    const Square to = move.to();
    const Piece piece = piece_on_square(from);
    const Piece captured = piece_on_square(to);
    const Move::Flags flags = move.flags();
    const PieceKind kind = piece.kind();
    u64* board = kind != KING ? &boards[piece.value()] : 0;

    assert(to != from);
    assert(captured.kind() != KING);
    assert(piece.color() == side);
    assert(captured.empty() || captured.color() == contra);

    sp.halfmoves = halfmoves;
    sp.ep_target = ep_target;
    sp.castle = castle;
    sp.capture = captured;

    if (flags == Move::Flags::NONE) {
        if (board) {
            *board &= ~from.mask();
            *board |= to.mask();
        } else {
            kings[side] = to; // to.value();
            if (side == WHITE) {
                castle &= ~Position::CASTLE_WHITE;
            } else {
                castle &= ~Position::CASTLE_BLACK;
            }
        }
        sq2p[from.value()] = NO_PIECE;
        sq2p[to.value()] = piece;
        sidemask[side] &= ~from.mask();
        sidemask[side] |= to.mask();

        if (!captured.empty()) {
            boards[captured.value()] &= ~to.mask();
            sidemask[contra] &= ~to.mask();
            castle &= ~rook_square_to_castle_flag(to);
        } else if (kind == PAWN && is_rank2(side, from) && is_enpassant_square(side, to)) {
            u8 target = side == WHITE ? to.value() - 8 : to.value() + 8;
            _set_enpassant_square(target);
            assert((target >= A3 && target <= H3) || (target >= A6 && target <= H6));
        }

        if (kind == ROOK) {
            castle &= ~rook_square_to_castle_flag(from);
        }
    } else if (flags == Move::Flags::ENPASSANT) {
        assert(enpassant_available() == true);
        const Square target = enpassant_target_square();
        assert(kind == PAWN);
        assert(captured.empty());
        *board &= ~from.mask();
        *board |= to.mask();
        board[Piece(contra, PAWN).value()] &= ~target.mask();
        sq2p[target.value()] = NO_PIECE;
        sq2p[from.value()] = NO_PIECE;
        sq2p[to.value()] = piece;
        sidemask[side] &= ~from.mask();
        sidemask[side] |= to.mask();
        sidemask[contra] &= ~target.mask();
    } else if (flags == Move::Flags::PROMOTION) {
        const PieceKind promotion_kind = move.promotion();
        const Piece promotion_piece = Piece(side, promotion_kind);
        assert(kind == PAWN);
        *board &= ~from.mask();
        boards[promotion_piece.value()] |= to.mask();
        sq2p[to.value()] = promotion_piece;
        sq2p[from.value()] = NO_PIECE;
        sidemask[side] &= ~from.mask();
        sidemask[side] |= to.mask();
        if (!captured.empty()) {
            boards[captured.value()] &= ~to.mask();
            sidemask[contra] &= ~to.mask();
            castle &= ~rook_square_to_castle_flag(to);
        }
     } else if (flags == Move::Flags::CASTLE) {
         assert(kind == KING);
         u64* rooks = &boards[Piece(side, ROOK).value()];
         Square ksq;
         Square rsq;
         switch (to.value()) {
             case H1:
                 ksq = Square(G1);
                 rsq = Square(F1);
             case A1:
                 ksq = Square(C1);
                 rsq = Square(D1);
             case H8:
                 ksq = Square(G8);
                 rsq = Square(F8);
             case A8:
                 ksq = Square(C8);
                 rsq = Square(D8);
             default:
                 assert(0);
                 __builtin_unreachable();
         }
         kings[side] = ksq;
         *rooks &= ~to.mask();
         *rooks |= rsq.mask();

         sq2p[from.value()] = NO_PIECE;
         sq2p[to.value()] = NO_PIECE;
         sq2p[ksq.value()] = Piece(side, KING);
         sq2p[rsq.value()] = Piece(side, ROOK);
         sidemask[side] &= ~(to.mask() | from.mask());
         sidemask[side] |= ksq.mask() | rsq.mask();
        if (side == WHITE) {
            castle &= ~Position::CASTLE_WHITE;
        } else {
            castle &= ~Position::CASTLE_BLACK;
        }
     } else {
         assert(0);
         __builtin_unreachable();
     }

    wtm = contra;
    if (kind == PAWN || !captured.empty()) {
        halfmoves = 0;
    } else {
        ++halfmoves;
    }
    if (side == BLACK) {
        ++moves;
    }
}

void Position::undo_move(const Savepos& sp, Move move) noexcept {

}
<|endoftext|>


<commit_before>#pragma once

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <tuple>
#include <vector>
#include <cassert>

namespace kdbush {

template <std::uint8_t I, typename T>
struct nth {
    inline static typename std::tuple_element<I, T>::type get(const T &t) {
        return std::get<I>(t);
    }
};

template <typename TPoint, typename TIndex = std::size_t>
class KDBush {

public:
    using TNumber = decltype(nth<0, TPoint>::get(std::declval<TPoint>()));
    static_assert(
        std::is_same<TNumber, decltype(nth<1, TPoint>::get(std::declval<TPoint>()))>::value,
        "point component types must be identical");

    static const std::uint8_t defaultNodeSize = 64;

    KDBush(const std::uint8_t nodeSize_ = defaultNodeSize) : nodeSize(nodeSize_) {
    }

    KDBush(const std::vector<TPoint> &points_, const std::uint8_t nodeSize_ = defaultNodeSize)
        : KDBush(std::begin(points_), std::end(points_), nodeSize_) {
    }

    template <typename TPointIter>
    KDBush(const TPointIter &points_begin,
           const TPointIter &points_end,
           const std::uint8_t nodeSize_ = defaultNodeSize)
        : nodeSize(nodeSize_) {
        fill(points_begin, points_end);
    }

    void fill(const std::vector<TPoint> &points_) {
        fill(std::begin(points_), std::end(points_));
    }

    template <typename TPointIter>
    void fill(const TPointIter &points_begin, const TPointIter &points_end) {
        assert(points.empty());
        const TIndex size = static_cast<TIndex>(std::distance(points_begin, points_end));

        if (size == 0) return;

        points.reserve(size);
        ids.reserve(size);

        TIndex i = 0;
        for (auto p = points_begin; p != points_end; p++) {
            points.emplace_back(nth<0, TPoint>::get(*p), nth<1, TPoint>::get(*p));
            ids.push_back(i++);
        }

        sortKD(0, size - 1, 0);
    }

    template <typename TVisitor>
    void range(const TNumber minX,
               const TNumber minY,
               const TNumber maxX,
               const TNumber maxY,
               const TVisitor &visitor) const {
        range(minX, minY, maxX, maxY, visitor, 0, static_cast<TIndex>(ids.size() - 1), 0);
    }

    template <typename TVisitor>
    void within(const TNumber qx, const TNumber qy, const TNumber r, const TVisitor &visitor) const {
        within(qx, qy, r, visitor, 0, static_cast<TIndex>(ids.size() - 1), 0);
    }

protected:
    std::vector<TIndex> ids;
    std::vector<std::pair<TNumber, TNumber>> points;

private:
    const std::uint8_t nodeSize;

    template <typename TVisitor>
    void range(const TNumber minX,
               const TNumber minY,
               const TNumber maxX,
               const TNumber maxY,
               const TVisitor &visitor,
               const TIndex left,
               const TIndex right,
               const std::uint8_t axis) const {

        if (points.empty()) return;

        if (right - left <= nodeSize) {
            for (auto i = left; i <= right; i++) {
                const TNumber x = std::get<0>(points[i]);
                const TNumber y = std::get<1>(points[i]);
                if (x >= minX && x <= maxX && y >= minY && y <= maxY) visitor(ids[i]);
            }
            return;
        }

        const TIndex m = (left + right) >> 1;
        const TNumber x = std::get<0>(points[m]);
        const TNumber y = std::get<1>(points[m]);

        if (x >= minX && x <= maxX && y >= minY && y <= maxY) visitor(ids[m]);

        if (axis == 0 ? minX <= x : minY <= y)
            range(minX, minY, maxX, maxY, visitor, left, m - 1, (axis + 1) % 2);

        if (axis == 0 ? maxX >= x : maxY >= y)
            range(minX, minY, maxX, maxY, visitor, m + 1, right, (axis + 1) % 2);
    }

    template <typename TVisitor>
    void within(const TNumber qx,
                const TNumber qy,
                const TNumber r,
                const TVisitor &visitor,
                const TIndex left,
                const TIndex right,
                const std::uint8_t axis) const {

        if (points.empty()) return;

        const TNumber r2 = r * r;

        if (right - left <= nodeSize) {
            for (auto i = left; i <= right; i++) {
                const TNumber x = std::get<0>(points[i]);
                const TNumber y = std::get<1>(points[i]);
                if (sqDist(x, y, qx, qy) <= r2) visitor(ids[i]);
            }
            return;
        }

        const TIndex m = (left + right) >> 1;
        const TNumber x = std::get<0>(points[m]);
        const TNumber y = std::get<1>(points[m]);

        if (sqDist(x, y, qx, qy) <= r2) visitor(ids[m]);

        if (axis == 0 ? qx - r <= x : qy - r <= y)
            within(qx, qy, r, visitor, left, m - 1, (axis + 1) % 2);

        if (axis == 0 ? qx + r >= x : qy + r >= y)
            within(qx, qy, r, visitor, m + 1, right, (axis + 1) % 2);
    }

    void sortKD(const TIndex left, const TIndex right, const std::uint8_t axis) {
        if (right - left <= nodeSize) return;
        const TIndex m = (left + right) >> 1;
        if (axis == 0) {
            select<0>(m, left, right);
        } else {
            select<1>(m, left, right);
        }
        sortKD(left, m - 1, (axis + 1) % 2);
        sortKD(m + 1, right, (axis + 1) % 2);
    }

    template <std::uint8_t I>
    void select(const TIndex k, TIndex left, TIndex right) {

        while (right > left) {
            if (right - left > 600) {
                const double n = right - left + 1;
                const double m = k - left + 1;
                const double z = std::log(n);
                const double s = 0.5 * std::exp(2 * z / 3);
                const double r =
                    k - m * s / n + 0.5 * std::sqrt(z * s * (1 - s / n)) * (2 * m < n ? -1 : 1);
                select<I>(k, std::max(left, TIndex(r)), std::min(right, TIndex(r + s)));
            }

            const TNumber t = std::get<I>(points[k]);
            TIndex i = left;
            TIndex j = right;

            swapItem(left, k);
            if (std::get<I>(points[right]) > t) swapItem(left, right);

            while (i < j) {
                swapItem(i++, j--);
                while (std::get<I>(points[i]) < t) i++;
                while (std::get<I>(points[j]) > t) j--;
            }

            if (std::get<I>(points[left]) == t)
                swapItem(left, j);
            else {
                swapItem(++j, right);
            }

            if (j <= k) left = j + 1;
            if (k <= j) right = j - 1;
        }
    }

    void swapItem(const TIndex i, const TIndex j) {
        std::iter_swap(ids.begin() + static_cast<std::int32_t>(i), ids.begin() + static_cast<std::int32_t>(j));
        std::iter_swap(points.begin() + static_cast<std::int32_t>(i), points.begin() + static_cast<std::int32_t>(j));
    }

    TNumber sqDist(const TNumber ax, const TNumber ay, const TNumber bx, const TNumber by) const {
        auto dx = ax - bx;
        auto dy = ay - by;
        return dx * dx + dy * dy;
    }
};

} // namespace kdbush
<commit_msg>Fix compilation warning when coordinates are integers (#11)<commit_after>#pragma once

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <tuple>
#include <vector>
#include <cassert>

namespace kdbush {

template <std::uint8_t I, typename T>
struct nth {
    inline static typename std::tuple_element<I, T>::type get(const T &t) {
        return std::get<I>(t);
    }
};

template <typename TPoint, typename TIndex = std::size_t>
class KDBush {

public:
    using TNumber = decltype(nth<0, TPoint>::get(std::declval<TPoint>()));
    static_assert(
        std::is_same<TNumber, decltype(nth<1, TPoint>::get(std::declval<TPoint>()))>::value,
        "point component types must be identical");

    static const std::uint8_t defaultNodeSize = 64;

    KDBush(const std::uint8_t nodeSize_ = defaultNodeSize) : nodeSize(nodeSize_) {
    }

    KDBush(const std::vector<TPoint> &points_, const std::uint8_t nodeSize_ = defaultNodeSize)
        : KDBush(std::begin(points_), std::end(points_), nodeSize_) {
    }

    template <typename TPointIter>
    KDBush(const TPointIter &points_begin,
           const TPointIter &points_end,
           const std::uint8_t nodeSize_ = defaultNodeSize)
        : nodeSize(nodeSize_) {
        fill(points_begin, points_end);
    }

    void fill(const std::vector<TPoint> &points_) {
        fill(std::begin(points_), std::end(points_));
    }

    template <typename TPointIter>
    void fill(const TPointIter &points_begin, const TPointIter &points_end) {
        assert(points.empty());
        const TIndex size = static_cast<TIndex>(std::distance(points_begin, points_end));

        if (size == 0) return;

        points.reserve(size);
        ids.reserve(size);

        TIndex i = 0;
        for (auto p = points_begin; p != points_end; p++) {
            points.emplace_back(nth<0, TPoint>::get(*p), nth<1, TPoint>::get(*p));
            ids.push_back(i++);
        }

        sortKD(0, size - 1, 0);
    }

    template <typename TVisitor>
    void range(const TNumber minX,
               const TNumber minY,
               const TNumber maxX,
               const TNumber maxY,
               const TVisitor &visitor) const {
        range(minX, minY, maxX, maxY, visitor, 0, static_cast<TIndex>(ids.size() - 1), 0);
    }

    template <typename TVisitor>
    void within(const TNumber qx, const TNumber qy, const TNumber r, const TVisitor &visitor) const {
        within(qx, qy, r, visitor, 0, static_cast<TIndex>(ids.size() - 1), 0);
    }

protected:
    std::vector<TIndex> ids;
    std::vector<std::pair<TNumber, TNumber>> points;

private:
    const std::uint8_t nodeSize;

    template <typename TVisitor>
    void range(const TNumber minX,
               const TNumber minY,
               const TNumber maxX,
               const TNumber maxY,
               const TVisitor &visitor,
               const TIndex left,
               const TIndex right,
               const std::uint8_t axis) const {

        if (points.empty()) return;

        if (right - left <= nodeSize) {
            for (auto i = left; i <= right; i++) {
                const TNumber x = std::get<0>(points[i]);
                const TNumber y = std::get<1>(points[i]);
                if (x >= minX && x <= maxX && y >= minY && y <= maxY) visitor(ids[i]);
            }
            return;
        }

        const TIndex m = (left + right) >> 1;
        const TNumber x = std::get<0>(points[m]);
        const TNumber y = std::get<1>(points[m]);

        if (x >= minX && x <= maxX && y >= minY && y <= maxY) visitor(ids[m]);

        if (axis == 0 ? minX <= x : minY <= y)
            range(minX, minY, maxX, maxY, visitor, left, m - 1, (axis + 1) % 2);

        if (axis == 0 ? maxX >= x : maxY >= y)
            range(minX, minY, maxX, maxY, visitor, m + 1, right, (axis + 1) % 2);
    }

    template <typename TVisitor>
    void within(const TNumber qx,
                const TNumber qy,
                const TNumber r,
                const TVisitor &visitor,
                const TIndex left,
                const TIndex right,
                const std::uint8_t axis) const {

        if (points.empty()) return;

        const TNumber r2 = r * r;

        if (right - left <= nodeSize) {
            for (auto i = left; i <= right; i++) {
                const TNumber x = std::get<0>(points[i]);
                const TNumber y = std::get<1>(points[i]);
                if (sqDist(x, y, qx, qy) <= r2) visitor(ids[i]);
            }
            return;
        }

        const TIndex m = (left + right) >> 1;
        const TNumber x = std::get<0>(points[m]);
        const TNumber y = std::get<1>(points[m]);

        if (sqDist(x, y, qx, qy) <= r2) visitor(ids[m]);

        if (axis == 0 ? qx - r <= x : qy - r <= y)
            within(qx, qy, r, visitor, left, m - 1, (axis + 1) % 2);

        if (axis == 0 ? qx + r >= x : qy + r >= y)
            within(qx, qy, r, visitor, m + 1, right, (axis + 1) % 2);
    }

    void sortKD(const TIndex left, const TIndex right, const std::uint8_t axis) {
        if (right - left <= nodeSize) return;
        const TIndex m = (left + right) >> 1;
        if (axis == 0) {
            select<0>(m, left, right);
        } else {
            select<1>(m, left, right);
        }
        sortKD(left, m - 1, (axis + 1) % 2);
        sortKD(m + 1, right, (axis + 1) % 2);
    }

    template <std::uint8_t I>
    void select(const TIndex k, TIndex left, TIndex right) {

        while (right > left) {
            if (right - left > 600) {
                const double n = static_cast<double>(right - left + 1);
                const double m = static_cast<double>(k - left + 1);
                const double z = std::log(n);
                const double s = 0.5 * std::exp(2 * z / 3);
                const double r =
                    k - m * s / n + 0.5 * std::sqrt(z * s * (1 - s / n)) * (2 * m < n ? -1 : 1);
                select<I>(k, std::max(left, TIndex(r)), std::min(right, TIndex(r + s)));
            }

            const TNumber t = std::get<I>(points[k]);
            TIndex i = left;
            TIndex j = right;

            swapItem(left, k);
            if (std::get<I>(points[right]) > t) swapItem(left, right);

            while (i < j) {
                swapItem(i++, j--);
                while (std::get<I>(points[i]) < t) i++;
                while (std::get<I>(points[j]) > t) j--;
            }

            if (std::get<I>(points[left]) == t)
                swapItem(left, j);
            else {
                swapItem(++j, right);
            }

            if (j <= k) left = j + 1;
            if (k <= j) right = j - 1;
        }
    }

    void swapItem(const TIndex i, const TIndex j) {
        std::iter_swap(ids.begin() + static_cast<std::int32_t>(i), ids.begin() + static_cast<std::int32_t>(j));
        std::iter_swap(points.begin() + static_cast<std::int32_t>(i), points.begin() + static_cast<std::int32_t>(j));
    }

    TNumber sqDist(const TNumber ax, const TNumber ay, const TNumber bx, const TNumber by) const {
        auto dx = ax - bx;
        auto dy = ay - by;
        return dx * dx + dy * dy;
    }
};

} // namespace kdbush
<|endoftext|>


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <iostream>
#include <string>
#include <vector>
#include <exception>
#include <iomanip>
#include <ctime>

#include <ArgumentList.hpp>
#include <InitializeOpenCL.hpp>
#include <Kernel.hpp>
#include <utils.hpp>
#include <Timer.hpp>
#include <Stats.hpp>
#include <VectorAdd.hpp>

typedef float dataType;
std::string typeName("float");

int main(int argc, char * argv[]) {
  unsigned int clPlatform = 0;
  unsigned int clDevice = 0;
  unsigned int extIterations = 0;
  unsigned int intIterations = 0;
  unsigned int N = 0;
  unsigned int threadUnit = 0;
  unsigned int maxThreads = 0;
  isa::utils::ArgumentList args(argc, argv);

  try {
    clPlatform = args.getSwitchArgument< unsigned int >("-opencl_platform");
    clDevice = args.getSwitchArgument< unsigned int >("-opencl_device");
    extIterations = args.getSwitchArgument< unsigned int >("-extIterations");
    intIterations = args.getSwitchArgument< unsigned int >("-intIterations");
    N = args.getSwitchArgument< unsigned int >("-N");
    threadUnit = args.getSwitchArgument< unsigned int >("-thread_unit");
    maxThreads = args.getSwitchArgument< unsigned int >("-max_threads");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << args.getName() << " -opencl_platform ... -opencl_device ... -extIterations ... -intIterations ... -N ... -thread_unit ... -max_threads ..." << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  // Initialize OpenCL
	cl::Context * clContext = new cl::Context();
	std::vector< cl::Platform > * clPlatforms = new std::vector< cl::Platform >();
	std::vector< cl::Device > * clDevices = new std::vector< cl::Device >();
	std::vector< std::vector< cl::CommandQueue > > * clQueues = new std::vector< std::vector < cl::CommandQueue > >();

  isa::OpenCL::initializeOpenCL(clPlatform, 1, clPlatforms, clContext, clDevices, clQueues);

  // Allocate memory
  std::vector< dataType > A(N);
  std::vector< dataType > B(N);
  cl::Buffer A_d, B_d, C_d;
  try {
    A_d = cl::Buffer(*clContext, CL_MEM_READ_ONLY, A.size() * sizeof(dataType), 0, 0);
    B_d = cl::Buffer(*clContext, CL_MEM_READ_ONLY, B.size() * sizeof(dataType), 0, 0);
    C_d = cl::Buffer(*clContext, CL_MEM_WRITE_ONLY, A.size() * sizeof(dataType), 0, 0);
  } catch ( cl::Error & err ) {
    std::cerr << "OpenCL error allocating memory: " << isa::utils::toString(err.err()) << "." << std::endl;
  }

  std::srand(std::time(0));
  for ( unsigned int n = 0; n < N; n++ ) {
    A[n] = static_cast< dataType >(std::rand() % 100);
    B[n] = A[n];
  }

  // Copy data structures to device
  try {
    clQueues->at(clDevice)[0].enqueueWriteBuffer(A_d, CL_FALSE, 0, A.size() * sizeof(dataType), reinterpret_cast< void * >(A.data()), 0, 0);
    clQueues->at(clDevice)[0].enqueueWriteBuffer(B_d, CL_FALSE, 0, B.size() * sizeof(dataType), reinterpret_cast< void * >(B.data()), 0, 0);
  } catch ( cl::Error & err ) {
    std::cerr << "OpenCL error H2D transfer: " << isa::utils::toString(err.err()) << "." << std::endl;
    return 1;
  }

  for ( unsigned int threads = threadUnit; threads <= maxThreads; threads += threadUnit ) {
    if ( (N % threads) != 0 ) {
      continue;
    }
    for ( unsigned int vector = 1; vector <= 16; vector *= 2 ) {
      if ( (N % (threads * vector)) != 0 ) {
        continue;
      }
      cl::Kernel * kernel;
      isa::utils::Timer kernelTimer("Kernel Timer");
      isa::utils::Stats< double > kernelFlops;
      isa::utils::Stats< double > kernelBandwidth;
      std::string * code = isa::Benchmarks::getVectorAddOpenCL(intIterations, vector, typeName);

      try {
        kernel = isa::OpenCL::compile("vectorAdd", *code, "-cl-mad-enable -Werror", *clContext, clDevices->at(clDevice));
      } catch ( isa::OpenCL::OpenCLError & err ) {
        std::cerr << err.what() << std::endl;
        return 1;
      }

      try {
        double flops = isa::utils::giga(static_cast< long long unsigned int >(N) * extIterations);
        double gbs = isa::utils::giga(static_cast< long long unsigned int >(N) * 3 * sizeof(dataType));
        cl::Event kernelSync;
        cl::NDRange global(N / vector);
        cl::NDRange local(threads);

        kernel->setArg(0, A_d);
        kernel->setArg(1, B_d);
        kernel->setArg(2, C_d);
        // Warm-up
        clQueues->at(clDevice)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &kernelSync);
        kernelSync.wait();

        for ( unsigned int iteration = 0; iteration < extIterations; iteration++ ) {
          kernelTimer.start();
          clQueues->at(clDevice)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &kernelSync);
          kernelSync.wait();
          kernelTimer.stop();
          kernelFlops.addElement(flops / kernelTimer.getLastRunTime());
          kernelBandwidth.addElement(gbs / kernelTimer.getLastRunTime());
        }
      } catch ( cl::Error & err ) {
        std::cerr << "OpenCL error kernel execution: " << isa::utils::toString(err.err()) << "." << std::endl;
      }

      std::cout << std::fixed;
      std::cout << threads << " " << vector << " ";
      std::cout << std::setprecision(3);
      std::cout << kernelFlops.getAverage() << " " << kernelFlops.getStdDev() << " ";
      std::cout << kernelBandwidth.getAverage() << " " << kernelBandwidth.getStdDev() << " ";
      std::cout << std::setprecision(6);
      std::cout << kernelTimer.getAverageTime() << " " << kernelTimer.getStdDev();
      std::cout << std::endl;
    }
  }

  return 0;
}

<commit_msg>Small fix.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <iostream>
#include <string>
#include <vector>
#include <exception>
#include <iomanip>
#include <ctime>

#include <ArgumentList.hpp>
#include <InitializeOpenCL.hpp>
#include <Kernel.hpp>
#include <utils.hpp>
#include <Timer.hpp>
#include <Stats.hpp>
#include <VectorAdd.hpp>

typedef float dataType;
std::string typeName("float");

int main(int argc, char * argv[]) {
  unsigned int clPlatform = 0;
  unsigned int clDevice = 0;
  unsigned int extIterations = 0;
  unsigned int intIterations = 0;
  unsigned int N = 0;
  unsigned int threadUnit = 0;
  unsigned int maxThreads = 0;
  isa::utils::ArgumentList args(argc, argv);

  try {
    clPlatform = args.getSwitchArgument< unsigned int >("-opencl_platform");
    clDevice = args.getSwitchArgument< unsigned int >("-opencl_device");
    extIterations = args.getSwitchArgument< unsigned int >("-extIterations");
    intIterations = args.getSwitchArgument< unsigned int >("-intIterations");
    N = args.getSwitchArgument< unsigned int >("-N");
    threadUnit = args.getSwitchArgument< unsigned int >("-thread_unit");
    maxThreads = args.getSwitchArgument< unsigned int >("-max_threads");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << args.getName() << " -opencl_platform ... -opencl_device ... -extIterations ... -intIterations ... -N ... -thread_unit ... -max_threads ..." << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  // Initialize OpenCL
	cl::Context * clContext = new cl::Context();
	std::vector< cl::Platform > * clPlatforms = new std::vector< cl::Platform >();
	std::vector< cl::Device > * clDevices = new std::vector< cl::Device >();
	std::vector< std::vector< cl::CommandQueue > > * clQueues = new std::vector< std::vector < cl::CommandQueue > >();

  isa::OpenCL::initializeOpenCL(clPlatform, 1, clPlatforms, clContext, clDevices, clQueues);

  // Allocate memory
  std::vector< dataType > A(N);
  std::vector< dataType > B(N);
  cl::Buffer A_d, B_d, C_d;
  try {
    A_d = cl::Buffer(*clContext, CL_MEM_READ_ONLY, A.size() * sizeof(dataType), 0, 0);
    B_d = cl::Buffer(*clContext, CL_MEM_READ_ONLY, B.size() * sizeof(dataType), 0, 0);
    C_d = cl::Buffer(*clContext, CL_MEM_WRITE_ONLY, A.size() * sizeof(dataType), 0, 0);
  } catch ( cl::Error & err ) {
    std::cerr << "OpenCL error allocating memory: " << isa::utils::toString(err.err()) << "." << std::endl;
  }

  std::srand(std::time(0));
  for ( unsigned int n = 0; n < N; n++ ) {
    A[n] = static_cast< dataType >(std::rand() % 100);
    B[n] = A[n];
  }

  // Copy data structures to device
  try {
    clQueues->at(clDevice)[0].enqueueWriteBuffer(A_d, CL_FALSE, 0, A.size() * sizeof(dataType), reinterpret_cast< void * >(A.data()), 0, 0);
    clQueues->at(clDevice)[0].enqueueWriteBuffer(B_d, CL_FALSE, 0, B.size() * sizeof(dataType), reinterpret_cast< void * >(B.data()), 0, 0);
  } catch ( cl::Error & err ) {
    std::cerr << "OpenCL error H2D transfer: " << isa::utils::toString(err.err()) << "." << std::endl;
    return 1;
  }

  for ( unsigned int threads = threadUnit; threads <= maxThreads; threads += threadUnit ) {
    if ( (N % threads) != 0 ) {
      continue;
    }
    for ( unsigned int vector = 1; vector <= 16; vector *= 2 ) {
      if ( (N % (threads * vector)) != 0 ) {
        continue;
      }
      cl::Kernel * kernel;
      isa::utils::Timer kernelTimer("Kernel Timer");
      isa::utils::Stats< double > kernelFlops;
      isa::utils::Stats< double > kernelBandwidth;
      std::string * code = isa::Benchmarks::getVectorAddOpenCL(intIterations, vector, typeName);

      try {
        kernel = isa::OpenCL::compile("vectorAdd", *code, "-cl-mad-enable -Werror", *clContext, clDevices->at(clDevice));
      } catch ( isa::OpenCL::OpenCLError & err ) {
        std::cerr << err.what() << std::endl;
        return 1;
      }

      try {
        double flops = isa::utils::giga(static_cast< long long unsigned int >(N) * intIterations);
        double gbs = isa::utils::giga(static_cast< long long unsigned int >(N) * 3 * sizeof(dataType));
        cl::Event kernelSync;
        cl::NDRange global(N / vector);
        cl::NDRange local(threads);

        kernel->setArg(0, A_d);
        kernel->setArg(1, B_d);
        kernel->setArg(2, C_d);
        // Warm-up
        clQueues->at(clDevice)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &kernelSync);
        kernelSync.wait();

        for ( unsigned int iteration = 0; iteration < extIterations; iteration++ ) {
          kernelTimer.start();
          clQueues->at(clDevice)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &kernelSync);
          kernelSync.wait();
          kernelTimer.stop();
          kernelFlops.addElement(flops / kernelTimer.getLastRunTime());
          kernelBandwidth.addElement(gbs / kernelTimer.getLastRunTime());
        }
      } catch ( cl::Error & err ) {
        std::cerr << "OpenCL error kernel execution: " << isa::utils::toString(err.err()) << "." << std::endl;
      }

      std::cout << std::fixed;
      std::cout << threads << " " << vector << " ";
      std::cout << std::setprecision(3);
      std::cout << kernelFlops.getAverage() << " " << kernelFlops.getStdDev() << " ";
      std::cout << kernelBandwidth.getAverage() << " " << kernelBandwidth.getStdDev() << " ";
      std::cout << std::setprecision(6);
      std::cout << kernelTimer.getAverageTime() << " " << kernelTimer.getStdDev();
      std::cout << std::endl;
    }
  }

  return 0;
}

<|endoftext|>


<commit_before>#include <windows.h>

#include <gl\glu.h>
#include <gl\gl.h>

#include <gl\glext.h>

#include "Settings.h"
#include "VideoBase.h"

#define VER(major,minor,patch) ((major<<16)+(minor<<8)+(patch))

bool CVideoBase::ext_bgra=false;
bool CVideoBase::ext_point_params=false;
float CVideoBase::opt_geodetail=0.5f;
bool CVideoBase::opt_linear=false;
bool CVideoBase::opt_mipmaps=false;
bool CVideoBase::opt_shadows=false;
bool CVideoBase::opt_bumpmaps=false;
bool CVideoBase::opt_lensflares=false;
bool CVideoBase::opt_startwinkle=false;

CVideoBase::CVideoBase()
{
}

CVideoBase::~CVideoBase()
{
}

bool CVideoBase::Init()
{
	GetExtensions();
	GetOptions();
	glShadeModel(GL_SMOOTH);
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClearDepth(1.0f);
	glDisable(GL_DITHER);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glDisable(GL_NORMALIZE);
	glEnable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
	glEnable(GL_CULL_FACE);
	glDisable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
	return true;
}

void CVideoBase::ShutDown()
{
}

bool CVideoBase::IsExtensionSupported(const char *supported, const char *extension)
{
	const size_t extlen = strlen(extension);

	if (supported == NULL)
		return false;

	for (const char* p = supported; ; p++)
	{
		p = strstr(p, extension);

		if (p == NULL)
			return false;

		if ((p==supported || p[-1]==' ') && (p[extlen]==' ' || p[extlen]==0))
			return true;
	}
}

void CVideoBase::GetVersion(int *major, int *minor, int *patch)
{
	*major=*minor=*patch=0;
	char *verstr=strdup((const char*)glGetString(GL_VERSION));
	char *tok=strtok(verstr,".");
	if (tok!=NULL)
		*major=atoi(tok);
	tok=strtok(NULL,".");
	if (tok!=NULL)
		*minor=atoi(tok);
	tok=strtok(NULL,".");
	if (tok!=NULL)
		*patch=atoi(tok);
	free(verstr);
	verstr=tok=NULL;
}

void CVideoBase::GetExtensions()
{
	int major,minor,patch;
	GetVersion(&major,&minor,&patch);
	char *ext_str=(const char*)glGetString(GL_EXTENSIONS);
	if (ext_str==NULL)
		return;
	{
		ext_bgra=IsExtensionSupported(ext_str,"GL_EXT_bgra");
		if (VER(major,minor,patch)>=VER(1,2,0))
			ext_bgra=true;
	}
	{
		ext_point_params=IsExtensionSupported(ext_str,"GL_ARB_point_parameters");
		if (VER(major,minor,patch)>=VER(1,4,0))
			ext_point_params=true;
	}
}

void CVideoBase::GetOptions()
{
	opt_geodetail=0.5f;
	opt_linear=false;
	opt_mipmaps=false;
	opt_shadows=false;
	opt_bumpmaps=false;
	opt_lensflares=false;
	opt_startwinkle=false;
	switch (CSettings::DetailLevel)
	{
	case 2:
		opt_shadows=true;
		opt_bumpmaps=true;
		opt_startwinkle=true;
	case 1:
		opt_geodetail=1.0f;
		opt_mipmaps=true;
	case 0:
		opt_lensflares=true;
		opt_linear=true;
	default:
		break;
	}
}
<commit_msg>Const correctness.<commit_after>#include <windows.h>

#include <gl\glu.h>
#include <gl\gl.h>

#include <gl\glext.h>

#include "Settings.h"
#include "VideoBase.h"

#define VER(major,minor,patch) ((major<<16)+(minor<<8)+(patch))

bool CVideoBase::ext_bgra=false;
bool CVideoBase::ext_point_params=false;
float CVideoBase::opt_geodetail=0.5f;
bool CVideoBase::opt_linear=false;
bool CVideoBase::opt_mipmaps=false;
bool CVideoBase::opt_shadows=false;
bool CVideoBase::opt_bumpmaps=false;
bool CVideoBase::opt_lensflares=false;
bool CVideoBase::opt_startwinkle=false;

CVideoBase::CVideoBase()
{
}

CVideoBase::~CVideoBase()
{
}

bool CVideoBase::Init()
{
	GetExtensions();
	GetOptions();
	glShadeModel(GL_SMOOTH);
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClearDepth(1.0f);
	glDisable(GL_DITHER);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glDisable(GL_NORMALIZE);
	glEnable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
	glEnable(GL_CULL_FACE);
	glDisable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
	return true;
}

void CVideoBase::ShutDown()
{
}

bool CVideoBase::IsExtensionSupported(const char *supported, const char *extension)
{
	const size_t extlen = strlen(extension);

	if (supported == NULL)
		return false;

	for (const char* p = supported; ; p++)
	{
		p = strstr(p, extension);

		if (p == NULL)
			return false;

		if ((p==supported || p[-1]==' ') && (p[extlen]==' ' || p[extlen]==0))
			return true;
	}
}

void CVideoBase::GetVersion(int *major, int *minor, int *patch)
{
	*major=*minor=*patch=0;
	char *verstr=strdup((const char*)glGetString(GL_VERSION));
	char *tok=strtok(verstr,".");
	if (tok!=NULL)
		*major=atoi(tok);
	tok=strtok(NULL,".");
	if (tok!=NULL)
		*minor=atoi(tok);
	tok=strtok(NULL,".");
	if (tok!=NULL)
		*patch=atoi(tok);
	free(verstr);
	verstr=tok=NULL;
}

void CVideoBase::GetExtensions()
{
	int major,minor,patch;
	GetVersion(&major,&minor,&patch);
	const char *ext_str=(const char*)glGetString(GL_EXTENSIONS);
	if (ext_str==NULL)
		return;
	{
		ext_bgra=IsExtensionSupported(ext_str,"GL_EXT_bgra");
		if (VER(major,minor,patch)>=VER(1,2,0))
			ext_bgra=true;
	}
	{
		ext_point_params=IsExtensionSupported(ext_str,"GL_ARB_point_parameters");
		if (VER(major,minor,patch)>=VER(1,4,0))
			ext_point_params=true;
	}
}

void CVideoBase::GetOptions()
{
	opt_geodetail=0.5f;
	opt_linear=false;
	opt_mipmaps=false;
	opt_shadows=false;
	opt_bumpmaps=false;
	opt_lensflares=false;
	opt_startwinkle=false;
	switch (CSettings::DetailLevel)
	{
	case 2:
		opt_shadows=true;
		opt_bumpmaps=true;
		opt_startwinkle=true;
	case 1:
		opt_geodetail=1.0f;
		opt_mipmaps=true;
	case 0:
		opt_lensflares=true;
		opt_linear=true;
	default:
		break;
	}
}
<|endoftext|>


<commit_before>#include "ride/quickopendlg.h"

#include "ride/wx.h"
#include "ride/generated/ui.h"
#include "ride/wxutils.h"
#include <vector>
#include <set>

// based on http://docs.wholetomato.com/default.asp?W193

class QuickOpenDlg : public ui::QuickOpen {
public:
  QuickOpenDlg(wxWindow* parent);

private:
  void UpdateFilters();

protected:
  void OnCancel(wxCommandEvent& event);
  void OnOk(wxCommandEvent& event);
  void OnActivate(wxActivateEvent& event);
  void OnFilterKeyUp(wxKeyEvent& event);
  void OnFilterUpdated(wxCommandEvent& event);
  void OnFilterNameEnter(wxCommandEvent& event);

  std::vector<wxString> files_;
};

void AddIfMoreThanOne(std::vector<wxString>& ret, const std::vector<wxString>& space) {
  if (space.size() != 1) {
    ret.insert(ret.begin(), space.begin(), space.end());
  }
}

std::vector<wxString> SmartSplit(const wxString& str, const wxString& full) {
  const auto space = Split(str, ' ');
  const auto dash = Split(str, '-');
  const auto under = Split(str, '_');
  std::vector<wxString> ret;
  ret.push_back(full);

  AddIfMoreThanOne(ret, space);
  AddIfMoreThanOne(ret, dash);
  AddIfMoreThanOne(ret, under);

  return ret;
}

bool MatchFilter(const wxString& filter, const wxString file, int* count) {
  const wxFileName name(file);
  const auto filters = RemoveEmptyStrings(Split(filter, ' '));
  const auto parts = SmartSplit(name.GetName(), name.GetFullName());
  if (filters.empty()) return true;
  for (auto fi : filters) {
    const bool exclude = fi.StartsWith("-");
    const wxString fl = exclude ? fi.Mid(1) : fi;
    const bool check_end_of_part = fl.EndsWith(".");
    const wxString f = check_end_of_part ? fl.Left(fl.Length() - 1) : fl;
    for (auto part : parts) {
      int change_match_count_by = 0;
      if (check_end_of_part) {
        if (part.EndsWith(f)) {
          change_match_count_by = 1;
        }
      }
      else {
        if (part.StartsWith(f)) {
          change_match_count_by = 1;
        }
      }
      if (change_match_count_by > 0) {
        if (exclude) return false;
        *count += change_match_count_by;
      }
    }
  }
  return *count > 0;
}

struct FilterMatch {
  wxString path;
  int count;

  FilterMatch(const wxString& p, int c) : path(p), count(c) {}
  bool operator<(const FilterMatch& rhs) const {
    if (count == rhs.count) return path < rhs.path;
    else return count < rhs.count;
  }
};

void QuickOpenDlg::UpdateFilters() {
  const wxString filter = uiFilterName->GetValue();

  std::set<FilterMatch> matches;
  for (const wxString& file : files_) {
    int count = 0;
    if (MatchFilter(filter, file, &count)) {
      FilterMatch m(file, count);
      assert(matches.find(m) == matches.end());
      matches.insert(m);
    }
  }

  uiFileList->Freeze();
  uiFileList->DeleteAllItems();
  for (const FilterMatch& match: matches) {
    int i = uiFileList->InsertItem(0, "");
    uiFileList->SetItem(i, 0, wxFileName(match.path).GetFullName());
    uiFileList->SetItem(i, 1, match.path);
    uiFileList->SetItem(i, 2, wxString::Format("%d", match.count));
  }
  if (matches.empty() == false) {
    SetSelection(uiFileList, 0, true);
  }
  uiFileList->Thaw();
}

QuickOpenDlg::QuickOpenDlg(wxWindow* parent)
  : ui::QuickOpen(parent, wxID_ANY)
{
  const long file_index = uiFileList->InsertColumn(0, "File");
  const long path_index = uiFileList->InsertColumn(1, "Path");
  const long count_index = uiFileList->InsertColumn(2, "Hits");
  uiFileList->SetColumnWidth(file_index, 150);
  uiFileList->SetColumnWidth(path_index, 300);
  uiFileList->SetColumnWidth(count_index, 50);

  /*files_.push_back("/project/dog/src/BigCalendarCtrl.rs");
  files_.push_back("/project/dog/src/BigCalendarTask.rs");
  files_.push_back("/project/dog/src/CalendarButtonsDlg.rs");
  files_.push_back("/project/dog/src/CalendarData.rs");
  files_.push_back("/project/dog/src/CalendarDefines.rs");
  files_.push_back("/project/dog/src/CalendarExt.rs");
  files_.push_back("/project/dog/src/CalendarExt.rs");
  */

  files_.push_back("/project/dog/src/big-calendar-ctrl.rs");
  files_.push_back("/project/dog/src/big-calendar-task.rs");
  files_.push_back("/project/dog/src/calendar-buttons-dlg.rs");
  files_.push_back("/project/dog/src/calendar-data.rs");
  files_.push_back("/project/dog/src/calendar-defines.rs");
  files_.push_back("/project/dog/src/calendar-ext.rs");
  files_.push_back("/project/dog/assets/pixel-shader.glsl");
  files_.push_back("/project/dog/assets/fragment-shader.glsl");
  files_.push_back("/project/dog/assets/texture-enemy.png");

  files_.push_back("/project/dog/assets/texture-enemy.template.png");
  /*
  files_.push_back("/project/dog/src/big_calendar_ctrl.rs");
  files_.push_back("/project/dog/src/big_calendar_task.rs");
  files_.push_back("/project/dog/src/calendar_buttons_dlg.rs");
  files_.push_back("/project/dog/src/calendar_data.rs");
  files_.push_back("/project/dog/src/calendar_defines.rs");
  files_.push_back("/project/dog/src/calendar_ext.rs");
  files_.push_back("/project/dog/src/calendar_ext.rs");*/

  uiFileList->Bind(wxEVT_KEY_DOWN, &QuickOpenDlg::OnFilterKeyUp, this);
  UpdateFilters();
}

void QuickOpenDlg::OnActivate(wxActivateEvent& event) {
  uiFilterName->SelectAll();
  uiFilterName->SetFocus();
  uiFilterName->SetFocusFromKbd();
}

void QuickOpenDlg::OnFilterKeyUp(wxKeyEvent& event) {
  if (event.GetKeyCode() == wxUP) {
    auto selected = GetSelection(uiFileList);
    if (selected.empty()){
      SetSelection(uiFileList, 0, true);
    }
    else {
      long last = *selected.begin();
      if (event.ShiftDown() == false) ClearSelection(uiFileList);
      SetSelection(uiFileList, last - 1, true);
    }
  }
  else if (event.GetKeyCode() == wxDOWN) {
    auto selected = GetSelection(uiFileList);
    if (selected.empty()){
      SetSelection(uiFileList, 0, true);
    }
    else {
      long last = *selected.rbegin();
      if (event.ShiftDown() == false) ClearSelection(uiFileList);
      SetSelection(uiFileList, last + 1, true);
    }
  }
  else {
    event.Skip();
  }
}

void QuickOpenDlg::OnFilterNameEnter(wxCommandEvent& event) {
  EndModal(wxID_OK);
}

void QuickOpenDlg::OnFilterUpdated(wxCommandEvent& event) {
  UpdateFilters();
}

void QuickOpenDlg::OnCancel(wxCommandEvent& event) {
  EndModal(wxID_CANCEL);
}

void QuickOpenDlg::OnOk(wxCommandEvent& event) {
  EndModal(wxID_OK);
}

bool ShowQuickOpenDlg(wxWindow* parent) {
  QuickOpenDlg dlg(parent);
  if (wxID_OK != dlg.ShowModal()) return false;;
  // do something!
  return true;
}
<commit_msg>Partial matching implemented<commit_after>#include "ride/quickopendlg.h"

#include "ride/wx.h"
#include "ride/generated/ui.h"
#include "ride/wxutils.h"
#include <vector>
#include <set>

// based on http://docs.wholetomato.com/default.asp?W193

class QuickOpenDlg : public ui::QuickOpen {
public:
  QuickOpenDlg(wxWindow* parent);

private:
  void UpdateFilters();

protected:
  void OnCancel(wxCommandEvent& event);
  void OnOk(wxCommandEvent& event);
  void OnActivate(wxActivateEvent& event);
  void OnFilterKeyUp(wxKeyEvent& event);
  void OnFilterUpdated(wxCommandEvent& event);
  void OnFilterNameEnter(wxCommandEvent& event);

  std::vector<wxString> files_;
};

void AddIfMoreThanOne(std::vector<wxString>& ret, const std::vector<wxString>& space) {
  if (space.size() != 1) {
    ret.insert(ret.begin(), space.begin(), space.end());
  }
}

std::vector<wxString> SmartSplit(const wxString& str, const wxString& full) {
  const auto space = Split(str, ' ');
  const auto dash = Split(str, '-');
  const auto under = Split(str, '_');
  std::vector<wxString> ret;
  ret.push_back(full);

  AddIfMoreThanOne(ret, space);
  AddIfMoreThanOne(ret, dash);
  AddIfMoreThanOne(ret, under);

  return ret;
}

bool MatchFilter(const wxString& filter, const wxString file, int* count) {
  const wxFileName name(file);
  const auto filters = RemoveEmptyStrings(Split(filter, ' '));
  const auto parts = SmartSplit(name.GetName(), name.GetFullName());
  if (filters.empty()) return true;
  for (auto fi : filters) {
    const bool exclude = fi.StartsWith("-");
    const wxString fl = exclude ? fi.Mid(1) : fi;
    const bool check_end_of_part = fl.EndsWith(".");
    const wxString f = check_end_of_part ? fl.Left(fl.Length() - 1) : fl;
    const bool partial_matching = f.Contains(".");
    for (auto part : parts) {
      int change_match_count_by = 0;
      if (partial_matching) {
        if (part.find(f) != wxString::npos) {
          change_match_count_by = 1;
        }
      }
      else {
        if (check_end_of_part) {
          if (part.EndsWith(f)) {
            change_match_count_by = 1;
          }
        }
        else {
          if (part.StartsWith(f)) {
            change_match_count_by = 1;
          }
        }
      }
      if (change_match_count_by > 0) {
        if (exclude) return false;
        *count += change_match_count_by;
      }
    }
  }
  return *count > 0;
}

struct FilterMatch {
  wxString path;
  int count;

  FilterMatch(const wxString& p, int c) : path(p), count(c) {}
  bool operator<(const FilterMatch& rhs) const {
    if (count == rhs.count) return path < rhs.path;
    else return count < rhs.count;
  }
};

void QuickOpenDlg::UpdateFilters() {
  const wxString filter = uiFilterName->GetValue();

  std::set<FilterMatch> matches;
  for (const wxString& file : files_) {
    int count = 0;
    if (MatchFilter(filter, file, &count)) {
      FilterMatch m(file, count);
      assert(matches.find(m) == matches.end());
      matches.insert(m);
    }
  }

  uiFileList->Freeze();
  uiFileList->DeleteAllItems();
  for (const FilterMatch& match: matches) {
    int i = uiFileList->InsertItem(0, "");
    uiFileList->SetItem(i, 0, wxFileName(match.path).GetFullName());
    uiFileList->SetItem(i, 1, match.path);
    uiFileList->SetItem(i, 2, wxString::Format("%d", match.count));
  }
  if (matches.empty() == false) {
    SetSelection(uiFileList, 0, true);
  }
  uiFileList->Thaw();
}

QuickOpenDlg::QuickOpenDlg(wxWindow* parent)
  : ui::QuickOpen(parent, wxID_ANY)
{
  const long file_index = uiFileList->InsertColumn(0, "File");
  const long path_index = uiFileList->InsertColumn(1, "Path");
  const long count_index = uiFileList->InsertColumn(2, "Hits");
  uiFileList->SetColumnWidth(file_index, 150);
  uiFileList->SetColumnWidth(path_index, 300);
  uiFileList->SetColumnWidth(count_index, 50);

  /*files_.push_back("/project/dog/src/BigCalendarCtrl.rs");
  files_.push_back("/project/dog/src/BigCalendarTask.rs");
  files_.push_back("/project/dog/src/CalendarButtonsDlg.rs");
  files_.push_back("/project/dog/src/CalendarData.rs");
  files_.push_back("/project/dog/src/CalendarDefines.rs");
  files_.push_back("/project/dog/src/CalendarExt.rs");
  files_.push_back("/project/dog/src/CalendarExt.rs");
  */

  files_.push_back("/project/dog/src/big-calendar-ctrl.rs");
  files_.push_back("/project/dog/src/big-calendar-task.rs");
  files_.push_back("/project/dog/src/calendar-buttons-dlg.rs");
  files_.push_back("/project/dog/src/calendar-data.rs");
  files_.push_back("/project/dog/src/calendar-defines.rs");
  files_.push_back("/project/dog/src/calendar-ext.rs");
  files_.push_back("/project/dog/assets/pixel-shader.glsl");
  files_.push_back("/project/dog/assets/fragment-shader.glsl");
  files_.push_back("/project/dog/assets/texture-enemy.png");

  files_.push_back("/project/dog/assets/texture-enemy.template.png");
  /*
  files_.push_back("/project/dog/src/big_calendar_ctrl.rs");
  files_.push_back("/project/dog/src/big_calendar_task.rs");
  files_.push_back("/project/dog/src/calendar_buttons_dlg.rs");
  files_.push_back("/project/dog/src/calendar_data.rs");
  files_.push_back("/project/dog/src/calendar_defines.rs");
  files_.push_back("/project/dog/src/calendar_ext.rs");
  files_.push_back("/project/dog/src/calendar_ext.rs");*/

  uiFileList->Bind(wxEVT_KEY_DOWN, &QuickOpenDlg::OnFilterKeyUp, this);
  UpdateFilters();
}

void QuickOpenDlg::OnActivate(wxActivateEvent& event) {
  uiFilterName->SelectAll();
  uiFilterName->SetFocus();
  uiFilterName->SetFocusFromKbd();
}

void QuickOpenDlg::OnFilterKeyUp(wxKeyEvent& event) {
  if (event.GetKeyCode() == wxUP) {
    auto selected = GetSelection(uiFileList);
    if (selected.empty()){
      SetSelection(uiFileList, 0, true);
    }
    else {
      long last = *selected.begin();
      if (event.ShiftDown() == false) ClearSelection(uiFileList);
      SetSelection(uiFileList, last - 1, true);
    }
  }
  else if (event.GetKeyCode() == wxDOWN) {
    auto selected = GetSelection(uiFileList);
    if (selected.empty()){
      SetSelection(uiFileList, 0, true);
    }
    else {
      long last = *selected.rbegin();
      if (event.ShiftDown() == false) ClearSelection(uiFileList);
      SetSelection(uiFileList, last + 1, true);
    }
  }
  else {
    event.Skip();
  }
}

void QuickOpenDlg::OnFilterNameEnter(wxCommandEvent& event) {
  EndModal(wxID_OK);
}

void QuickOpenDlg::OnFilterUpdated(wxCommandEvent& event) {
  UpdateFilters();
}

void QuickOpenDlg::OnCancel(wxCommandEvent& event) {
  EndModal(wxID_CANCEL);
}

void QuickOpenDlg::OnOk(wxCommandEvent& event) {
  EndModal(wxID_OK);
}

bool ShowQuickOpenDlg(wxWindow* parent) {
  QuickOpenDlg dlg(parent);
  if (wxID_OK != dlg.ShowModal()) return false;;
  // do something!
  return true;
}
<|endoftext|>


<commit_before><commit_msg>Update documentation front page<commit_after><|endoftext|>


<commit_before>#pragma once

#include <stdlib.h>
#include <stdio.h>

class Logger
{
public:
    static Logger* global()
    {
        if (!_gLogger)
        {
            _gLogger = new Logger(true, false);
        }

        return _gLogger;
    }

    Logger(bool writeToFile, bool writeToConsole) :
        _fp(nullptr),
        _writeToFile(writeToFile),
        _writeToConsole(writeToConsole)
    {
        if (writeToFile)
        {
            // Get current path
            char path[256] = {0};

        	{
        		size_t len = ape::platform::getLibraryPath(path, sizeof(path));

        		// Find last / and
        		while (len > 0 && path[--len] != SEPARATOR_CHR) {};

        		// Overwrite path from here on
                strcpy(&apiPath[len + 1], "apelog.txt");
        	}

            // Open file
            _fp = fopen(path, 'w+');
        }
    }

    ~Logger()
    {
        if (_fp)
        {
            fclose(_fp);
        }
    }

    template <typename... Args>
    void log(char* fmt, Args... args)
    {
        if (_writeToFile)
        {
            fprintf(_fp, fmt, args...);
        }

        if (_writeToConsole)
        {
            printf(fmt, args...);
        }
    }

private:
    static Logger* _gLogger;

    FILE* _fp;
    bool _writeToFile;
    bool _writeToConsole;
}

#define gLogger Logger::global()
<commit_msg>Fix build<commit_after>#pragma once

#include "apecore.hpp"

#include <stdlib.h>
#include <stdio.h>

class Logger
{
public:
    static Logger* global()
    {
        if (!_gLogger)
        {
            _gLogger = new Logger(true, false);
        }

        return _gLogger;
    }

    Logger(bool writeToFile, bool writeToConsole) :
        _fp(nullptr),
        _writeToFile(writeToFile),
        _writeToConsole(writeToConsole)
    {
        if (writeToFile)
        {
            // Get current path
            char path[256] = {0};

        	{
        		size_t len = ape::platform::getLibraryPath(path, sizeof(path));

        		// Find last / and
        		while (len > 0 && path[--len] != SEPARATOR_CHR) {};

        		// Overwrite path from here on
                strcpy(&path[len + 1], "apelog.txt");
        	}

            // Open file
            _fp = fopen(path, "w+");
        }
    }

    ~Logger()
    {
        if (_fp)
        {
            fclose(_fp);
        }
    }

    template <typename... Args>
    void log(char* fmt, Args... args)
    {
        if (_writeToFile)
        {
            fprintf(_fp, fmt, args...);
        }

        if (_writeToConsole)
        {
            printf(fmt, args...);
        }
    }

private:
    static Logger* _gLogger;

    FILE* _fp;
    bool _writeToFile;
    bool _writeToConsole;
}

#define gLogger Logger::global()
<|endoftext|>