<commit_before>/*
 * main.cpp
 *
 *  Created on: 27.11.2015 г.
 *      Author: trifon
 */

#include <cmath>

#include "tree.cpp"
#include "bintree.cpp"
#include "priority_queue.cpp"

using TestTree = Tree<int>;
using TestBinaryTree = BinaryTree<int>;

template <typename I>
int length(I it) {
	int result = 0;
	while (it++)
		result++;
	return result;
}

template <typename T>
int breadth(Tree<T> const& t) {
	int result = length(t.subtrees());
	for(typename Tree<T>::I it = t.subtrees();it;++it) {
		int l = breadth(*it);
		if (l > result)
			result = l;
	}
	return result;
}

void testTree() {
	TestTree t1(1);
	t1.addChild(TestTree(2)
				.addChild(TestTree(3))
				.addChild(TestTree(4)
						  .addChild(TestTree(5))
						  .addChild(TestTree(6)))
			    .addChild(TestTree(7))
			    .addChild(TestTree(8)))
	  .addChild(TestTree(9))
	  .addChild(TestTree(10));
	cout << t1 << endl;
	cout << breadth(t1) << endl;
}

template <typename T>
int depth(BinaryTreePosition<T> pos) {
	if (!pos)
		return 0;
	return 1 + max(depth(-pos), depth(+pos));
}

template <typename T>
bool operator==(BinaryTreePosition<T> p1, BinaryTreePosition<T> p2) {
	return  (!p1 && !p2) ||
			p1 && p2 && *p1 == *p2 && -p1 == -p2 && +p1 == +p2;
}

void testBinaryTree() {
	TestBinaryTree e;
	TestBinaryTree t(1, 2, TestBinaryTree(3, 4, 5));
	//TestBinaryTree t2(0, t, t);
	cout << "-----\n";
	//cout << t2;
	cout << t.root() << endl;
	t.assignFrom(-+t.root(), TestBinaryTree(6,7,8));
	printDOT(t, "tree.dot");
	cout << "Дълбочина: " << depth(t.root()) << endl;
	cout << t.root() << endl;
	t.deleteAt(-+t.root());
	cout << t.root() << endl;
	cout << "Проверка за равенство: " <<
			(TestBinaryTree(1, 2, TestBinaryTree(3, TestBinaryTree(), 6)).root()
			 ==
			t.root()) << endl;
	BinaryTreePosition<int> pos = t.root();
	pos = +pos;
	BinaryTreePosition<int> newpos = +pos;
}

void testPriorityQueue() {
	PriorityQueue<int> pq;
	pq.enqueue_prioritized(5);
	pq.enqueue_prioritized(6);
	pq.enqueue_prioritized(3);
	pq.enqueue_prioritized(4);
	pq.enqueue_prioritized(2);
	pq.enqueue_prioritized(1);
	cout << pq.dequeue_highest() << endl;
	cout << pq.dequeue_highest() << endl;
	pq.printDOT("heap.dot");
}

int main() {
	// testTree();
	// testBinaryTree();
	testPriorityQueue();
	return 0;
}

<commit_msg>Реализация на пирамидално сортиране.<commit_after>/*
 * main.cpp
 *
 *  Created on: 27.11.2015 г.
 *      Author: trifon
 */

#include <cmath>

#include "tree.cpp"
#include "bintree.cpp"
#include "priority_queue.cpp"

using TestTree = Tree<int>;
using TestBinaryTree = BinaryTree<int>;

template <typename I>
int length(I it) {
	int result = 0;
	while (it++)
		result++;
	return result;
}

template <typename T>
int breadth(Tree<T> const& t) {
	int result = length(t.subtrees());
	for(typename Tree<T>::I it = t.subtrees();it;++it) {
		int l = breadth(*it);
		if (l > result)
			result = l;
	}
	return result;
}

void testTree() {
	TestTree t1(1);
	t1.addChild(TestTree(2)
				.addChild(TestTree(3))
				.addChild(TestTree(4)
						  .addChild(TestTree(5))
						  .addChild(TestTree(6)))
			    .addChild(TestTree(7))
			    .addChild(TestTree(8)))
	  .addChild(TestTree(9))
	  .addChild(TestTree(10));
	cout << t1 << endl;
	cout << breadth(t1) << endl;
}

template <typename T>
int depth(BinaryTreePosition<T> pos) {
	if (!pos)
		return 0;
	return 1 + max(depth(-pos), depth(+pos));
}

template <typename T>
bool operator==(BinaryTreePosition<T> p1, BinaryTreePosition<T> p2) {
	return  (!p1 && !p2) ||
			p1 && p2 && *p1 == *p2 && -p1 == -p2 && +p1 == +p2;
}

void testBinaryTree() {
	TestBinaryTree e;
	TestBinaryTree t(1, 2, TestBinaryTree(3, 4, 5));
	//TestBinaryTree t2(0, t, t);
	cout << "-----\n";
	//cout << t2;
	cout << t.root() << endl;
	t.assignFrom(-+t.root(), TestBinaryTree(6,7,8));
	printDOT(t, "tree.dot");
	cout << "Дълбочина: " << depth(t.root()) << endl;
	cout << t.root() << endl;
	t.deleteAt(-+t.root());
	cout << t.root() << endl;
	cout << "Проверка за равенство: " <<
			(TestBinaryTree(1, 2, TestBinaryTree(3, TestBinaryTree(), 6)).root()
			 ==
			t.root()) << endl;
	BinaryTreePosition<int> pos = t.root();
	pos = +pos;
	BinaryTreePosition<int> newpos = +pos;
}

void testPriorityQueue() {
	PriorityQueue<int> pq;
	pq.enqueue_prioritized(5);
	pq.enqueue_prioritized(6);
	pq.enqueue_prioritized(3);
	pq.enqueue_prioritized(4);
	pq.enqueue_prioritized(2);
	pq.enqueue_prioritized(1);
	cout << pq.dequeue_highest() << endl;
	cout << pq.dequeue_highest() << endl;
	pq.printDOT("heap.dot");
}

template <typename T>
void printArray(T a[], int n) {
	for(int i = 0; i < n; i++)
		cout << a[i] << ' ';
	cout << endl;
}

inline int left(int i) {
	return 2 * i + 1;
}

inline int right(int i) {
	return 2 * i + 2;
}

// пресяваме възела с индекс i надолу
template <typename T>
void siftDown(T a[], int i, int n) {
	// докато има дете, от което a[i] е по-малко
	while (left(i)  < n && a[i] < a[left(i)] ||
		   right(i) < n && a[i] < a[right(i)]) {
		// кое е по-голямото дете
		// Може би е лявото
		int newi = left(i);
		// А дали не е дясното?
		if (right(i) < n && a[right(i)] > a[left(i)])
			newi = right(i);
		swap(a[i], a[newi]);
		i = newi;
	}
	// (left(i) >= n || a[i] >= a[left(i)]) &&
    // (right(i) >= n || a[i] >= a[right(i)])
}

template <typename T>
void buildHeap(T a[], int n) {
	for(int i = n / 2 - 1; i >= 0; i--)
		siftDown(a, i, n);
}

template <typename T>
void disassembleHeap(T a[], int n) {
	for(int i = n - 1; i >= 1; i--) {
		swap(a[0], a[i]);
		siftDown(a, 0, i);
	}
}

template <typename T>
void heapSort(T a[], int n) {
	printArray(a, n);
	// 1. построяваме пирамида
	buildHeap(a, n);
	printArray(a, n);

	// 2. разглобяваме пирамидата
	disassembleHeap(a, n);
	printArray(a, n);
}

void testHeapSort() {
	int a[] = { 5, 1, 7, 2, 8, 4, 6, 10, 3, 8, 7 };
	const int N = sizeof(a) / sizeof(a[0]);
	heapSort(a, N);
}

int main() {
	// testTree();
	// testBinaryTree();
	// testPriorityQueue();
	testHeapSort();
	return 0;
}

<|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 <fstream>
#include <iomanip>
#include <limits>
#include <algorithm>

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

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

int main(int argc, char * argv[]) {
	unsigned int nrIterations = 0;
	unsigned int clPlatformID = 0;
	unsigned int clDeviceID = 0;
	unsigned int minThreads = 0;
	unsigned int maxThreadsPerBlock = 0;
	unsigned int maxItemsPerThread = 0;
	unsigned int maxColumns = 0;
	unsigned int maxRows = 0;
  AstroData::Observation< dataType > observation("SNRTuning", typeName);

	try {
    isa::utils::ArgumentList args(argc, argv);

		nrIterations = args.getSwitchArgument< unsigned int >("-iterations");
		clPlatformID = args.getSwitchArgument< unsigned int >("-opencl_platform");
		clDeviceID = args.getSwitchArgument< unsigned int >("-opencl_device");
		observation.setPadding(args.getSwitchArgument< unsigned int >("-padding"));
		minThreads = args.getSwitchArgument< unsigned int >("-min_threads");
		maxThreadsPerBlock = args.getSwitchArgument< unsigned int >("-max_threads");
		maxItemsPerThread = args.getSwitchArgument< unsigned int >("-max_items");
		maxColumns = args.getSwitchArgument< unsigned int >("-max_columns");
		maxRows = args.getSwitchArgument< unsigned int >("-max_rows");
		observation.setNrDMs(args.getSwitchArgument< unsigned int >("-dms"));
    observation.setNrPeriods(args.getSwitchArgument< unsigned int >("-periods"));
    observation.setNrBins(args.getSwitchArgument< unsigned int >("-bins"));
	} catch ( isa::utils::EmptyCommandLine &err ) {
		std::cerr << argv[0] << " -iterations ... -opencl_platform ... -opencl_device ... -padding ... -min_threads ... -max_threads ... -max_items ... -max_columns ... -max_rows ... -dms ... -periods ... -bins ... " << 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(clPlatformID, 1, clPlatforms, clContext, clDevices, clQueues);

	// Allocate memory
  std::vector< dataType > foldedData = std::vector< dataType >(observation.getNrBins() * observation.getNrPeriods() * observation.getNrPaddedDMs());
  cl::Buffer foldedData_d;
  std::vector< dataType > snrs = std::vector< dataType >(observation.getNrPeriods() * observation.getNrPaddedDMs());
  cl::Buffer snrs_d;
  try {
    foldedData_d = cl::Buffer(*clContext, CL_MEM_READ_WRITE, foldedData.size() * sizeof(dataType), NULL, NULL);
    snrs_d = cl::Buffer(*clContext, CL_MEM_WRITE_ONLY, snrs.size() * sizeof(dataType), NULL, NULL);
  } catch ( cl::Error &err ) {
    std::cerr << "OpenCL error allocating memory: " << isa::utils::toString< cl_int >(err.err()) << "." << std::endl;
    return 1;
  }

	srand(time(NULL));
  for ( unsigned int bin = 0; bin < observation.getNrBins(); bin++ ) {
    for ( unsigned int period = 0; period < observation.getNrPeriods(); period++ ) {
      for ( unsigned int DM = 0; DM < observation.getNrDMs(); DM++ ) {
        foldedData[(bin * observation.getNrPeriods() * observation.getNrPaddedDMs()) + (period * observation.getNrPaddedDMs()) + DM] = static_cast< dataType >(rand() % 10);
      }
    }
	}
  std::fill(snrs.begin(), snrs.end(), static_cast< dataType >(0));

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

	// Find the parameters
	std::vector< unsigned int > DMsPerBlock;
	for ( unsigned int DMs = minThreads; DMs <= maxColumns; DMs += minThreads ) {
		if ( (observation.getNrPaddedDMs() % DMs) == 0 ) {
			DMsPerBlock.push_back(DMs);
		}
	}
	std::vector< unsigned int > periodsPerBlock;
	for ( unsigned int periods = 1; periods <= maxRows; periods++ ) {
		if ( (observation.getNrPeriods() % periods) == 0 ) {
			periodsPerBlock.push_back(periods);
		}
	}

	std::cout << std::fixed << std::endl;
	std::cout << "# nrDMs nrPeriods nrBins DMsPerBlock periodsPerBlock DMsPerThread periodsPerThread GFLOP/s err time err" << std::endl << std::endl;

  for ( std::vector< unsigned int >::iterator DMs = DMsPerBlock.begin(); DMs != DMsPerBlock.end(); ++DMs ) {
    for ( std::vector< unsigned int >::iterator periods = periodsPerBlock.begin(); periods != periodsPerBlock.end(); ++periods ) {
      if ( (*DMs * *periods) > maxThreadsPerBlock ) {
        break;
      }
      for ( unsigned int DMsPerThread = 1; DMsPerThread <= maxItemsPerThread; DMsPerThread++ ) {
        if ( observation.getNrPaddedDMs() % (*DMs * DMsPerThread) != 0 ) {
          continue;
        }
        for ( unsigned int periodsPerThread = 1; periodsPerThread <= maxItemsPerThread; periodsPerThread++ ) {
          if ( observation.getNrPeriods() % (*periods * periodsPerThread) != 0 ) {
            continue;
          }
          if ( DMsPerThread + periodsPerThread > maxItemsPerThread ) {
            break;
          }
          // Generate kernel
          cl::Kernel * kernel;
          std::string * code = PulsarSearch::getSNROpenCL(*DMs, *periods, DMsPerThread, periodsPerThread, typeName, observation);

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

          cl::NDRange global(observation.getNrPaddedDMs() / DMsPerThread, observation.getNrPeriods() / periodsPerThread);
          cl::NDRange local(*DMs, *periods);

          kernel->setArg(0, foldedData_d);
          kernel->setArg(1, snrs_d);

          // Warm-up run
          try {
            clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local);
          } catch ( cl::Error &err ) {
            std::cerr << "OpenCL error kernel execution: " << isa::utils::toString< cl_int >(err.err()) << "." << std::endl;
            continue;
          }
          // Tuning runs
          double flops = isa::utils::giga(static_cast< long long unsigned int >(observation.getNrDMs()) * observation.getNrPeriods() * observation.getNrBins());
          isa::utils::Timer timer("Kernel Timer");
          isa::utils::Stats< double > stats;
          cl::Event event;

          try {
            for ( unsigned int iteration = 0; iteration < nrIterations; iteration++ ) {
              timer.start();
              clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, NULL, &event);
              event.wait();
              timer.stop();
              stats.addElement(flops / timer.getLastRunTime());
            }
          } catch ( cl::Error &err ) {
            std::cerr << "OpenCL error kernel execution: " << isa::utils::toString< cl_int >(err.err()) << "." << std::endl;
            continue;
          }

          std::cout << observation.getNrDMs() << " " << observation.getNrPeriods() << " " << observation.getNrBins() << " " << *DMs << " " << *periods << " " << DMsPerThread << " " << periodsPerThread << " " << std::setprecision(3) << stats.getAverage() << " " << stats.getStdDev() << " " << std::setprecision(6) << timer.getAverageTime() << " " << timer.getStdDev() << std::endl;
        }
      }
    }
  }

	std::cout << std::endl;

	return 0;
}

<commit_msg>Fixed a bug in tuning standard deviation.<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 <fstream>
#include <iomanip>
#include <limits>
#include <algorithm>

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

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

int main(int argc, char * argv[]) {
	unsigned int nrIterations = 0;
	unsigned int clPlatformID = 0;
	unsigned int clDeviceID = 0;
	unsigned int minThreads = 0;
	unsigned int maxThreadsPerBlock = 0;
	unsigned int maxItemsPerThread = 0;
	unsigned int maxColumns = 0;
	unsigned int maxRows = 0;
  AstroData::Observation< dataType > observation("SNRTuning", typeName);

	try {
    isa::utils::ArgumentList args(argc, argv);

		nrIterations = args.getSwitchArgument< unsigned int >("-iterations");
		clPlatformID = args.getSwitchArgument< unsigned int >("-opencl_platform");
		clDeviceID = args.getSwitchArgument< unsigned int >("-opencl_device");
		observation.setPadding(args.getSwitchArgument< unsigned int >("-padding"));
		minThreads = args.getSwitchArgument< unsigned int >("-min_threads");
		maxThreadsPerBlock = args.getSwitchArgument< unsigned int >("-max_threads");
		maxItemsPerThread = args.getSwitchArgument< unsigned int >("-max_items");
		maxColumns = args.getSwitchArgument< unsigned int >("-max_columns");
		maxRows = args.getSwitchArgument< unsigned int >("-max_rows");
		observation.setNrDMs(args.getSwitchArgument< unsigned int >("-dms"));
    observation.setNrPeriods(args.getSwitchArgument< unsigned int >("-periods"));
    observation.setNrBins(args.getSwitchArgument< unsigned int >("-bins"));
	} catch ( isa::utils::EmptyCommandLine &err ) {
		std::cerr << argv[0] << " -iterations ... -opencl_platform ... -opencl_device ... -padding ... -min_threads ... -max_threads ... -max_items ... -max_columns ... -max_rows ... -dms ... -periods ... -bins ... " << 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(clPlatformID, 1, clPlatforms, clContext, clDevices, clQueues);

	// Allocate memory
  std::vector< dataType > foldedData = std::vector< dataType >(observation.getNrBins() * observation.getNrPeriods() * observation.getNrPaddedDMs());
  cl::Buffer foldedData_d;
  std::vector< dataType > snrs = std::vector< dataType >(observation.getNrPeriods() * observation.getNrPaddedDMs());
  cl::Buffer snrs_d;
  try {
    foldedData_d = cl::Buffer(*clContext, CL_MEM_READ_WRITE, foldedData.size() * sizeof(dataType), 0, 0);
    snrs_d = cl::Buffer(*clContext, CL_MEM_WRITE_ONLY, snrs.size() * sizeof(dataType), 0, 0);
  } catch ( cl::Error &err ) {
    std::cerr << "OpenCL error allocating memory: " << isa::utils::toString(err.err()) << "." << std::endl;
    return 1;
  }

	srand(time(0));
  for ( unsigned int bin = 0; bin < observation.getNrBins(); bin++ ) {
    for ( unsigned int period = 0; period < observation.getNrPeriods(); period++ ) {
      for ( unsigned int DM = 0; DM < observation.getNrDMs(); DM++ ) {
        foldedData[(bin * observation.getNrPeriods() * observation.getNrPaddedDMs()) + (period * observation.getNrPaddedDMs()) + DM] = static_cast< dataType >(rand() % 10);
      }
    }
	}
  std::fill(snrs.begin(), snrs.end(), static_cast< dataType >(0));

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

	// Find the parameters
	std::vector< unsigned int > DMsPerBlock;
	for ( unsigned int DMs = minThreads; DMs <= maxColumns; DMs += minThreads ) {
		if ( (observation.getNrPaddedDMs() % DMs) == 0 ) {
			DMsPerBlock.push_back(DMs);
		}
	}
	std::vector< unsigned int > periodsPerBlock;
	for ( unsigned int periods = 1; periods <= maxRows; periods++ ) {
		if ( (observation.getNrPeriods() % periods) == 0 ) {
			periodsPerBlock.push_back(periods);
		}
	}

	std::cout << std::fixed << std::endl;
	std::cout << "# nrDMs nrPeriods nrBins DMsPerBlock periodsPerBlock DMsPerThread periodsPerThread GFLOP/s err time err" << std::endl << std::endl;

  for ( std::vector< unsigned int >::iterator DMs = DMsPerBlock.begin(); DMs != DMsPerBlock.end(); ++DMs ) {
    for ( std::vector< unsigned int >::iterator periods = periodsPerBlock.begin(); periods != periodsPerBlock.end(); ++periods ) {
      if ( (*DMs * *periods) > maxThreadsPerBlock ) {
        break;
      }
      for ( unsigned int DMsPerThread = 1; DMsPerThread <= maxItemsPerThread; DMsPerThread++ ) {
        if ( observation.getNrPaddedDMs() % (*DMs * DMsPerThread) != 0 ) {
          continue;
        }
        for ( unsigned int periodsPerThread = 1; periodsPerThread <= maxItemsPerThread; periodsPerThread++ ) {
          if ( observation.getNrPeriods() % (*periods * periodsPerThread) != 0 ) {
            continue;
          }
          if ( DMsPerThread + periodsPerThread > maxItemsPerThread ) {
            break;
          }
          // Generate kernel
          double flops = isa::utils::giga(static_cast< long long unsigned int >(observation.getNrDMs()) * observation.getNrPeriods() * observation.getNrBins());
          isa::utils::Timer timer("Kernel Timer");
          isa::utils::Stats< double > stats;
          cl::Event event;
          cl::Kernel * kernel;
          std::string * code = PulsarSearch::getSNROpenCL(*DMs, *periods, DMsPerThread, periodsPerThread, typeName, observation);

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

          cl::NDRange global(observation.getNrPaddedDMs() / DMsPerThread, observation.getNrPeriods() / periodsPerThread);
          cl::NDRange local(*DMs, *periods);

          kernel->setArg(0, foldedData_d);
          kernel->setArg(1, snrs_d);

          // Warm-up run
          try {
            clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &event);
            event.wait();
          } catch ( cl::Error &err ) {
            std::cerr << "OpenCL error kernel execution: " << isa::utils::toString(err.err()) << "." << std::endl;
            continue;
          }
          // Tuning runs
          try {
            for ( unsigned int iteration = 0; iteration < nrIterations; iteration++ ) {
              timer.start();
              clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &event);
              event.wait();
              timer.stop();
              stats.addElement(flops / timer.getLastRunTime());
            }
          } catch ( cl::Error &err ) {
            std::cerr << "OpenCL error kernel execution: " << isa::utils::toString(err.err()) << "." << std::endl;
            continue;
          }

          std::cout << observation.getNrDMs() << " " << observation.getNrPeriods() << " " << observation.getNrBins() << " " << *DMs << " " << *periods << " " << DMsPerThread << " " << periodsPerThread << " " << std::setprecision(3) << stats.getAverage() << " " << stats.getStdDev() << " " << std::setprecision(6) << timer.getAverageTime() << " " << timer.getStdDev() << std::endl;
        }
      }
    }
  }

	std::cout << std::endl;

	return 0;
}

<|endoftext|>


<commit_before>//
// MIT License
//
// Copyright 2017-2019
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <iostream>

#include "nes.hh"
#include "sdl_controller.hh"
#include "sdl_manager.hh"
#include "sdl_screen.hh"

namespace fs = boost::filesystem;
namespace po = boost::program_options;
namespace js = jones::sdl;

class screen_listener : public js::sdl_screen_listener {
public:
  explicit screen_listener(jones::nes &nes) : nes_(nes) {}

  ~screen_listener() override = default;

  void on_screen_closed() override {
    nes_.stop();
  }

private:
  jones::nes &nes_;
};

int main(int argc, char *argv[]) {
  std::string file_argument;
  try {
    po::options_description desc{"Options"};
    desc.add_options()
    ("help,h", "Help screen")
    ("file,f", po::value<std::string>(&file_argument)->required(), "file path to nes rom");

    po::variables_map vm;
    po::store(parse_command_line(argc, argv, desc), vm);
    po::notify(vm);
  } catch (const po::error &ex) {
    std::cerr << ex.what() << '\n';
    return -1;
  }

  const fs::path file_path(file_argument);
  if (!fs::exists(file_path)) {
    std::cerr << "file path does not exist; please check path" << std::endl;
    return -2;
  }

  if (fs::is_directory(file_path)) {
    std::cerr << "file path is a directory; please check path" << std::endl;
    return -3;
  }

  jones::nes nes(file_path.string().c_str());
  if (nes.power()) {
    std::cerr << "rom file is not valid; please check file" << std::endl;
    return -4;
  }

  auto listener = std::make_unique<screen_listener>(nes);
  auto screen = std::make_unique<js::sdl_screen>(std::move(listener));
  auto controller = std::make_unique<js::sdl_controller>(nes.controller_one(), nes.controller_two());

  js::sdl_manager manager;
  manager.add_component(screen.get());
  manager.add_component(controller.get());
  manager.initialize();

  nes.attach_screen(std::move(screen));
  nes.run();

  return 0;
}
<commit_msg>inverting condition to make it correct<commit_after>//
// MIT License
//
// Copyright 2017-2019
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <iostream>

#include "nes.hh"
#include "sdl_controller.hh"
#include "sdl_manager.hh"
#include "sdl_screen.hh"

namespace fs = boost::filesystem;
namespace po = boost::program_options;
namespace js = jones::sdl;

class screen_listener : public js::sdl_screen_listener {
public:
  explicit screen_listener(jones::nes &nes) : nes_(nes) {}

  ~screen_listener() override = default;

  void on_screen_closed() override {
    nes_.stop();
  }

private:
  jones::nes &nes_;
};

int main(int argc, char *argv[]) {
  std::string file_argument;
  try {
    po::options_description desc{"Options"};
    desc.add_options()
    ("help,h", "Help screen")
    ("file,f", po::value<std::string>(&file_argument)->required(), "file path to nes rom");

    po::variables_map vm;
    po::store(parse_command_line(argc, argv, desc), vm);
    po::notify(vm);
  } catch (const po::error &ex) {
    std::cerr << ex.what() << '\n';
    return -1;
  }

  const fs::path file_path(file_argument);
  if (!fs::exists(file_path)) {
    std::cerr << "file path does not exist; please check path" << std::endl;
    return -2;
  }

  if (fs::is_directory(file_path)) {
    std::cerr << "file path is a directory; please check path" << std::endl;
    return -3;
  }

  jones::nes nes(file_path.string().c_str());
  if (!nes.power()) {
    std::cerr << "rom file is not valid; please check file" << std::endl;
    return -4;
  }

  auto listener = std::make_unique<screen_listener>(nes);
  auto screen = std::make_unique<js::sdl_screen>(std::move(listener));
  auto controller = std::make_unique<js::sdl_controller>(nes.controller_one(), nes.controller_two());

  js::sdl_manager manager;
  manager.add_component(screen.get());
  manager.add_component(controller.get());
  manager.initialize();

  nes.attach_screen(std::move(screen));
  nes.run();

  return 0;
}
<|endoftext|>


<commit_before>
#include <cassert>
#include <string>
#include <iomanip>

#include <GL/glew.h>

#include <GLFW/glfw3.h>

#include <glow/logging.h>

#include <glowutils/Timer.h>

#include <glowwindow/Context.h>
#include <glowwindow/WindowEventHandler.h>
#include <glowwindow/Window.h>
#include <glowwindow/events.h>

#include "WindowEventDispatcher.h"

using namespace glow;

namespace glowwindow
{

std::set<Window*> Window::s_instances;

const std::set<Window*>& Window::instances()
{
    return s_instances;
}

Window::Window()
:   m_context(nullptr)
,   m_quitOnDestroy(true)
,   m_mode(WindowMode)
,   m_title("")
,   m_timer(nullptr)
,   m_swapts(0.0)
,   m_swaps(0)
,   m_window(nullptr)
{
    s_instances.insert(this);
}

Window::~Window()
{
    s_instances.erase(this);
    WindowEventDispatcher::deregisterWindow(this);

    if (s_instances.empty())
        MainLoop::quit(0);

    delete m_timer;
}

WindowEventHandler * Window::eventHandler() const
{
    return const_cast<WindowEventHandler*>(m_eventHandler.get());
}

Context * Window::context() const
{
    return m_context;
}

int Window::width() const
{
    return size().x;
}

int Window::height() const
{
    return size().y;
}

glm::ivec2 Window::size() const
{
    if (!m_window)
        return glm::ivec2();

    int w, h;
    glfwGetWindowSize(m_window, &w, &h);
    return glm::ivec2(w, h);
}

glm::ivec2 Window::position() const
{
    if (!m_window)
        return glm::ivec2();

    int x, y;
    glfwGetWindowPos(m_window, &x, &y);
    return glm::ivec2(x, y);
}

void Window::quitOnDestroy(const bool enable)
{
    m_quitOnDestroy = enable;
}

bool Window::create(const ContextFormat & format, const std::string & title, int width, int height)
{
    assert(nullptr == m_context);

    m_context = new Context();
    if (!m_context->create(format, width, height))
    {
        delete m_context;
        m_context = nullptr;

        return false;
    }

    m_window = m_context->window();
    if (!m_window)
    {
        fatal() << "Creating native window with OpenGL context failed.";
        return false;
    }

    setTitle(title);

    WindowEventDispatcher::registerWindow(this);

    promoteContext(width, height);

    m_windowedModeSize = glm::ivec2(width, height);

    return true;
}

void Window::setTitle(const std::string & title)
{
    m_title = title;

    if (!m_window)
        return;

    glfwSetWindowTitle(m_window, m_title.c_str());
}

void Window::promoteContext(int width, int height)
{
    if (m_eventHandler)
    {
         m_context->makeCurrent();
         m_eventHandler->initialize(*this);
         m_context->doneCurrent();

         queueEvent(new ResizeEvent(glm::ivec2(width, height)));
         queueEvent(new ResizeEvent(glm::ivec2(width, height), true));
    }
}

bool Window::quitsOnDestroy() const
{
    return m_quitOnDestroy;
}

void Window::show()
{
    if (!m_window)
        return;

    glfwShowWindow(m_window);
}

void Window::hide()
{
    if (!m_window)
        return;

    glfwHideWindow(m_window);
}

void Window::fullScreen()
{
    if (WindowMode != m_mode)
        return;

    GLFWmonitor* monitor = glfwGetPrimaryMonitor();
    if (!monitor)
        return;

    m_windowedModeSize = size();

    const GLFWvidmode* mode = glfwGetVideoMode(monitor);
    int w = mode->width;
    int h = mode->height;

    ContextFormat format = m_context->format();
    m_context->release();

    if (m_eventHandler)
        m_eventHandler->finalize(*this);

    WindowEventDispatcher::deregisterWindow(this);

    if (m_context->create(format, w, h, monitor))
    {
        promoteContext(w, h);
        WindowEventDispatcher::registerWindow(this);

        m_mode = FullScreenMode;
    }
    else
    {
        m_context->release();
        delete m_context;
        m_context = nullptr;
        m_window = nullptr;
    }
}

void Window::windowed()
{
    if (FullScreenMode != m_mode)
        return;

    int w = m_windowedModeSize.x;
    int h = m_windowedModeSize.y;

    ContextFormat format = m_context->format();
    m_context->release();

    if (m_eventHandler)
        m_eventHandler->finalize(*this);

    WindowEventDispatcher::deregisterWindow(this);

    if (m_context->create(format, w, h, nullptr))
    {
        promoteContext(w, h);
        WindowEventDispatcher::registerWindow(this);

        m_mode = WindowMode;
    }
    else
    {
        m_context->release();
        delete m_context;
        m_context = nullptr;
        m_window = nullptr;
    }
}

bool Window::isFullScreen() const
{
    return FullScreenMode == m_mode;
}

bool Window::isWindowed() const
{
    return WindowMode == m_mode;
}

void Window::toggleMode()
{
    switch (m_mode)
    {
        case FullScreenMode:
            windowed();
            return;
        case WindowMode:
            fullScreen();
            return;
    }
}

void Window::setEventHandler(WindowEventHandler * eventHandler)
{
    if (eventHandler == m_eventHandler)
        return;

    m_eventHandler = eventHandler;

    if (!m_eventHandler)
        return;

    if (!m_context)
        return;

    promoteContext(width(), height());
}

void Window::resize(int width, int height)
{
    if (!m_window)
        return;

    glfwSetWindowSize(m_window, width, height);
}

int Window::inputMode(int mode) const
{
    if (!m_window)
        return -1;

    return glfwGetInputMode(m_window, mode);
}

void Window::setInputMode(int mode, int value)
{
    if (!m_window)
        return;

    glfwSetInputMode(m_window, mode, value);
}

void Window::repaint()
{
    queueEvent(new PaintEvent);
}

void Window::close()
{
    queueEvent(new CloseEvent);
}

void Window::idle()
{
    if (m_eventHandler)
        m_eventHandler->idle(*this);
}

void Window::swap()
{
    if (!m_timer)
    {
        m_timer = new glowutils::Timer(true, false);
        m_swapts = 0.0;
    }

    m_context->swap();

    m_timer->update();

    ++m_swaps;

    if (m_timer->elapsed() - m_swapts >= 1e+9)
    {
        const float fps = 1e+9f * static_cast<float>(static_cast<long double>
            (m_swaps) / (m_timer->elapsed() - m_swapts));

        std::stringstream fpss;
        fpss << m_title << " (" << std::fixed << std::setprecision(2) << fps << " fps)";

        glfwSetWindowTitle(m_window, fpss.str().c_str());

        m_swapts = m_timer->elapsed();
        m_swaps = 0;
    }
}

void Window::destroy()
{
    m_context->release();

    delete m_context;
    m_context = nullptr;
    m_window = nullptr;

    if (m_eventHandler)
        m_eventHandler->finalize(*this);

    if (m_quitOnDestroy)
        MainLoop::quit(0);
}

GLFWwindow * Window::internalWindow() const
{
    return m_window;
}

void Window::queueEvent(WindowEvent * event)
{
    if (!event)
        return;

    m_eventQueue.push(event);
}

bool Window::hasPendingEvents()
{
    return !m_eventQueue.empty();
}

void Window::processEvents()
{
    if (m_eventQueue.empty() || !m_context)
        return;

    m_context->makeCurrent();

    while (!m_eventQueue.empty())
    {
        WindowEvent* event = m_eventQueue.front();
        m_eventQueue.pop();
        event->setWindow(this);

        processEvent(*event);

        delete event;

        if (!m_context)
        {
            clearEventQueue();
            return;
        }
    }

    m_context->doneCurrent();
}

void Window::processEvent(WindowEvent & event)
{
    if (m_eventHandler)
    {
        m_eventHandler->handleEvent(event);
    }

    finishEvent(event);
}

void Window::finishEvent(WindowEvent & event)
{
    if (event.type() == WindowEvent::Paint)
    {
        swap();
    }
    else if (!event.isAccepted())
    {
        defaultEventAction(event);
    }
}

void Window::defaultEventAction(WindowEvent & event)
{
    switch (event.type())
    {
        case WindowEvent::Close:
            destroy();
            break;

        case WindowEvent::KeyPress: {
            KeyEvent& keyEvent = static_cast<KeyEvent&>(event);
            switch (keyEvent.key())
            {
                case GLFW_KEY_ESCAPE:
                    close();
                    break;
                case GLFW_KEY_ENTER:
                    if ((keyEvent.modifiers() & GLFW_MOD_ALT) != 0)
                    {
                        toggleMode();
                    }
                    break;
            }
            break;
        }

        default:
            break;
    }
}

void Window::clearEventQueue()
{
    while (!m_eventQueue.empty())
    {
        delete m_eventQueue.front();
        m_eventQueue.pop();
    }
}

void Window::addTimer(int id, int interval, bool singleShot)
{
    WindowEventDispatcher::addTimer(this, id, interval, singleShot);
}

void Window::removeTimer(int id)
{
    WindowEventDispatcher::removeTimer(this, id);
}

} // namespace glowwindow
<commit_msg>Fix initial framebuffer size for retina displays<commit_after>
#include <cassert>
#include <string>
#include <iomanip>

#include <GL/glew.h>

#include <GLFW/glfw3.h>

#include <glow/logging.h>

#include <glowutils/Timer.h>

#include <glowwindow/Context.h>
#include <glowwindow/WindowEventHandler.h>
#include <glowwindow/Window.h>
#include <glowwindow/events.h>

#include "WindowEventDispatcher.h"

using namespace glow;

namespace glowwindow
{

std::set<Window*> Window::s_instances;

const std::set<Window*>& Window::instances()
{
    return s_instances;
}

Window::Window()
:   m_context(nullptr)
,   m_quitOnDestroy(true)
,   m_mode(WindowMode)
,   m_title("")
,   m_timer(nullptr)
,   m_swapts(0.0)
,   m_swaps(0)
,   m_window(nullptr)
{
    s_instances.insert(this);
}

Window::~Window()
{
    s_instances.erase(this);
    WindowEventDispatcher::deregisterWindow(this);

    if (s_instances.empty())
        MainLoop::quit(0);

    delete m_timer;
}

WindowEventHandler * Window::eventHandler() const
{
    return const_cast<WindowEventHandler*>(m_eventHandler.get());
}

Context * Window::context() const
{
    return m_context;
}

int Window::width() const
{
    return size().x;
}

int Window::height() const
{
    return size().y;
}

glm::ivec2 Window::size() const
{
    if (!m_window)
        return glm::ivec2();

    int w, h;
    glfwGetWindowSize(m_window, &w, &h);
    return glm::ivec2(w, h);
}

glm::ivec2 Window::position() const
{
    if (!m_window)
        return glm::ivec2();

    int x, y;
    glfwGetWindowPos(m_window, &x, &y);
    return glm::ivec2(x, y);
}

void Window::quitOnDestroy(const bool enable)
{
    m_quitOnDestroy = enable;
}

bool Window::create(const ContextFormat & format, const std::string & title, int width, int height)
{
    assert(nullptr == m_context);

    m_context = new Context();
    if (!m_context->create(format, width, height))
    {
        delete m_context;
        m_context = nullptr;

        return false;
    }

    m_window = m_context->window();
    if (!m_window)
    {
        fatal() << "Creating native window with OpenGL context failed.";
        return false;
    }

    setTitle(title);

    WindowEventDispatcher::registerWindow(this);

    promoteContext(width, height);

    m_windowedModeSize = glm::ivec2(width, height);

    return true;
}

void Window::setTitle(const std::string & title)
{
    m_title = title;

    if (!m_window)
        return;

    glfwSetWindowTitle(m_window, m_title.c_str());
}

void Window::promoteContext(int width, int height)
{
    if (m_eventHandler)
    {
        m_context->makeCurrent();
        m_eventHandler->initialize(*this);
        m_context->doneCurrent();

        int frameBufferWidth = 0;
        int frameBufferHeight = 0;
        glfwGetFramebufferSize(m_window, &frameBufferWidth, &frameBufferHeight);

        queueEvent(new ResizeEvent(glm::ivec2(width, height)));
        queueEvent(new ResizeEvent(glm::ivec2(frameBufferWidth, frameBufferHeight), true));
    }
}

bool Window::quitsOnDestroy() const
{
    return m_quitOnDestroy;
}

void Window::show()
{
    if (!m_window)
        return;

    glfwShowWindow(m_window);
}

void Window::hide()
{
    if (!m_window)
        return;

    glfwHideWindow(m_window);
}

void Window::fullScreen()
{
    if (WindowMode != m_mode)
        return;

    GLFWmonitor* monitor = glfwGetPrimaryMonitor();
    if (!monitor)
        return;

    m_windowedModeSize = size();

    const GLFWvidmode* mode = glfwGetVideoMode(monitor);
    int w = mode->width;
    int h = mode->height;

    ContextFormat format = m_context->format();
    m_context->release();

    if (m_eventHandler)
        m_eventHandler->finalize(*this);

    WindowEventDispatcher::deregisterWindow(this);

    if (m_context->create(format, w, h, monitor))
    {
        promoteContext(w, h);
        WindowEventDispatcher::registerWindow(this);

        m_mode = FullScreenMode;
    }
    else
    {
        m_context->release();
        delete m_context;
        m_context = nullptr;
        m_window = nullptr;
    }
}

void Window::windowed()
{
    if (FullScreenMode != m_mode)
        return;

    int w = m_windowedModeSize.x;
    int h = m_windowedModeSize.y;

    ContextFormat format = m_context->format();
    m_context->release();

    if (m_eventHandler)
        m_eventHandler->finalize(*this);

    WindowEventDispatcher::deregisterWindow(this);

    if (m_context->create(format, w, h, nullptr))
    {
        promoteContext(w, h);
        WindowEventDispatcher::registerWindow(this);

        m_mode = WindowMode;
    }
    else
    {
        m_context->release();
        delete m_context;
        m_context = nullptr;
        m_window = nullptr;
    }
}

bool Window::isFullScreen() const
{
    return FullScreenMode == m_mode;
}

bool Window::isWindowed() const
{
    return WindowMode == m_mode;
}

void Window::toggleMode()
{
    switch (m_mode)
    {
        case FullScreenMode:
            windowed();
            return;
        case WindowMode:
            fullScreen();
            return;
    }
}

void Window::setEventHandler(WindowEventHandler * eventHandler)
{
    if (eventHandler == m_eventHandler)
        return;

    m_eventHandler = eventHandler;

    if (!m_eventHandler)
        return;

    if (!m_context)
        return;

    promoteContext(width(), height());
}

void Window::resize(int width, int height)
{
    if (!m_window)
        return;

    glfwSetWindowSize(m_window, width, height);
}

int Window::inputMode(int mode) const
{
    if (!m_window)
        return -1;

    return glfwGetInputMode(m_window, mode);
}

void Window::setInputMode(int mode, int value)
{
    if (!m_window)
        return;

    glfwSetInputMode(m_window, mode, value);
}

void Window::repaint()
{
    queueEvent(new PaintEvent);
}

void Window::close()
{
    queueEvent(new CloseEvent);
}

void Window::idle()
{
    if (m_eventHandler)
        m_eventHandler->idle(*this);
}

void Window::swap()
{
    if (!m_timer)
    {
        m_timer = new glowutils::Timer(true, false);
        m_swapts = 0.0;
    }

    m_context->swap();

    m_timer->update();

    ++m_swaps;

    if (m_timer->elapsed() - m_swapts >= 1e+9)
    {
        const float fps = 1e+9f * static_cast<float>(static_cast<long double>
            (m_swaps) / (m_timer->elapsed() - m_swapts));

        std::stringstream fpss;
        fpss << m_title << " (" << std::fixed << std::setprecision(2) << fps << " fps)";

        glfwSetWindowTitle(m_window, fpss.str().c_str());

        m_swapts = m_timer->elapsed();
        m_swaps = 0;
    }
}

void Window::destroy()
{
    m_context->release();

    delete m_context;
    m_context = nullptr;
    m_window = nullptr;

    if (m_eventHandler)
        m_eventHandler->finalize(*this);

    if (m_quitOnDestroy)
        MainLoop::quit(0);
}

GLFWwindow * Window::internalWindow() const
{
    return m_window;
}

void Window::queueEvent(WindowEvent * event)
{
    if (!event)
        return;

    m_eventQueue.push(event);
}

bool Window::hasPendingEvents()
{
    return !m_eventQueue.empty();
}

void Window::processEvents()
{
    if (m_eventQueue.empty() || !m_context)
        return;

    m_context->makeCurrent();

    while (!m_eventQueue.empty())
    {
        WindowEvent* event = m_eventQueue.front();
        m_eventQueue.pop();
        event->setWindow(this);

        processEvent(*event);

        delete event;

        if (!m_context)
        {
            clearEventQueue();
            return;
        }
    }

    m_context->doneCurrent();
}

void Window::processEvent(WindowEvent & event)
{
    if (m_eventHandler)
    {
        m_eventHandler->handleEvent(event);
    }

    finishEvent(event);
}

void Window::finishEvent(WindowEvent & event)
{
    if (event.type() == WindowEvent::Paint)
    {
        swap();
    }
    else if (!event.isAccepted())
    {
        defaultEventAction(event);
    }
}

void Window::defaultEventAction(WindowEvent & event)
{
    switch (event.type())
    {
        case WindowEvent::Close:
            destroy();
            break;

        case WindowEvent::KeyPress: {
            KeyEvent& keyEvent = static_cast<KeyEvent&>(event);
            switch (keyEvent.key())
            {
                case GLFW_KEY_ESCAPE:
                    close();
                    break;
                case GLFW_KEY_ENTER:
                    if ((keyEvent.modifiers() & GLFW_MOD_ALT) != 0)
                    {
                        toggleMode();
                    }
                    break;
            }
            break;
        }

        default:
            break;
    }
}

void Window::clearEventQueue()
{
    while (!m_eventQueue.empty())
    {
        delete m_eventQueue.front();
        m_eventQueue.pop();
    }
}

void Window::addTimer(int id, int interval, bool singleShot)
{
    WindowEventDispatcher::addTimer(this, id, interval, singleShot);
}

void Window::removeTimer(int id)
{
    WindowEventDispatcher::removeTimer(this, id);
}

} // namespace glowwindow
<|endoftext|>


<commit_before>#include "Wiegand.h"

volatile unsigned long WIEGAND::_cardTempHigh=0;
volatile unsigned long WIEGAND::_cardTemp=0;
volatile unsigned long WIEGAND::_lastWiegand=0;
unsigned long WIEGAND::_code=0;
volatile int WIEGAND::_bitCount=0;
int WIEGAND::_wiegandType=0;

WIEGAND::WIEGAND()
{
}

unsigned long WIEGAND::getCode()
{
	return _code;
}

int WIEGAND::getWiegandType()
{
	return _wiegandType;
}

bool WIEGAND::available()
{
	bool ret;
    noInterrupts();
	ret=DoWiegandConversion();
	interrupts();
	return ret;
}

void WIEGAND::begin()
{
  begin(2,0,3,1);
}

void WIEGAND::begin(int pinD0, int pinIntD0, int pinD1, int pinIntD1)
{
	_lastWiegand = 0;
	_cardTempHigh = 0;
	_cardTemp = 0;
	_code = 0;
	_wiegandType = 0;
	_bitCount = 0;
	pinMode(pinD0, INPUT);					// Set D0 pin as input
	pinMode(pinD1, INPUT);					// Set D1 pin as input
	attachInterrupt(pinIntD0, ReadD0, FALLING);	// Hardware interrupt - high to low pulse
	attachInterrupt(pinIntD1, ReadD1, FALLING);	// Hardware interrupt - high to low pulse
}

void WIEGAND::ReadD0 ()
{
	_bitCount++;				// Increament bit count for Interrupt connected to D0
	if (_bitCount>31)			// If bit count more than 31, process high bits
	{
		_cardTempHigh |= ((0x80000000 & _cardTemp)>>31);	//	shift value to high bits
		_cardTempHigh <<= 1;
		_cardTemp <<=1;
	}
	else
	{
		_cardTemp <<= 1;		// D0 represent binary 0, so just left shift card data
	}
	_lastWiegand = millis();	// Keep track of last wiegand bit received
}

void WIEGAND::ReadD1()
{
	_bitCount ++;				// Increment bit count for Interrupt connected to D1
	if (_bitCount>31)			// If bit count more than 31, process high bits
	{
		_cardTempHigh |= ((0x80000000 & _cardTemp)>>31);	// shift value to high bits
		_cardTempHigh <<= 1;
		_cardTemp |= 1;
		_cardTemp <<=1;
	}
	else
	{
		_cardTemp |= 1;			// D1 represent binary 1, so OR card data with 1 then
		_cardTemp <<= 1;		// left shift card data
	}
	_lastWiegand = millis();	// Keep track of last wiegand bit received
}

unsigned long WIEGAND::GetCardId (volatile unsigned long *codehigh, volatile unsigned long *codelow, char bitlength)
{
	unsigned long cardID=0;

	if (bitlength==26)								// EM tag
		cardID = (*codelow & 0x1FFFFFE) >>1;

	if (bitlength==34)								// Mifare
	{
		*codehigh = *codehigh & 0x03;				// only need the 2 LSB of the codehigh
		*codehigh <<= 30;							// shift 2 LSB to MSB
		*codelow >>=1;
		cardID = *codehigh | *codelow;
	}
	return cardID;
}

bool WIEGAND::DoWiegandConversion ()
{
	unsigned long cardID;
	unsigned long sysTick = millis();

	if ((sysTick - _lastWiegand) > 25)								// if no more signal coming through after 25ms
	{
		if ((_bitCount==26) || (_bitCount==34) || (_bitCount==8)) 	// bitCount for keypress=8, Wiegand 26=26, Wiegand 34=34
		{
			_cardTemp >>= 1;			// shift right 1 bit to get back the real value - interrupt done 1 left shift in advance
			if (_bitCount>32)			// bit count more than 32 bits, shift high bits right to make adjustment
				_cardTempHigh >>= 1;

			if((_bitCount==26) || (_bitCount==34))		// wiegand 26 or wiegand 34
			{
				cardID = GetCardId (&_cardTempHigh, &_cardTemp, _bitCount);
				_wiegandType=_bitCount;
				_bitCount=0;
				_cardTemp=0;
				_cardTempHigh=0;
				_code=cardID;
				return true;
			}
			else if (_bitCount==8)		// keypress wiegand
			{
				// 8-bit Wiegand keyboard data, high nibble is the "NOT" of low nibble
				// eg if key 1 pressed, data=E1 in binary 11100001 , high nibble=1110 , low nibble = 0001
				char highNibble = (_cardTemp & 0xf0) >>4;
				char lowNibble = (_cardTemp & 0x0f);
				_wiegandType=_bitCount;
				_bitCount=0;
				_cardTemp=0;
				_cardTempHigh=0;

				if (lowNibble == (~highNibble & 0x0f))		// check if low nibble matches the "NOT" of high nibble.
				{
					if (lowNibble==0x0b)					// ENT pressed
					{
						_code=0x0d;
					}
					else if (lowNibble==0x0a)				// ESC pressed
					{
						_code=0x1b;
					}
					else
					{
						_code=(int)lowNibble;				// 0 - 9 keys
					}
					return true;
				}
			}
		}
		else
		{
			// well time over 25 ms and bitCount !=8 , !=26, !=34 , must be noise or nothing then.
			_lastWiegand=sysTick;
			_bitCount=0;
			_cardTemp=0;
			_cardTempHigh=0;
			return false;
		}
	}
	else
		return false;
}<commit_msg>Support 4-bit Wiegand keypad codes<commit_after>#include "Wiegand.h"

volatile unsigned long WIEGAND::_cardTempHigh=0;
volatile unsigned long WIEGAND::_cardTemp=0;
volatile unsigned long WIEGAND::_lastWiegand=0;
unsigned long WIEGAND::_code=0;
volatile int WIEGAND::_bitCount=0;
int WIEGAND::_wiegandType=0;

WIEGAND::WIEGAND()
{
}

unsigned long WIEGAND::getCode()
{
	return _code;
}

int WIEGAND::getWiegandType()
{
	return _wiegandType;
}

bool WIEGAND::available()
{
	bool ret;
    noInterrupts();
	ret=DoWiegandConversion();
	interrupts();
	return ret;
}

void WIEGAND::begin()
{
  begin(2,0,3,1);
}

void WIEGAND::begin(int pinD0, int pinIntD0, int pinD1, int pinIntD1)
{
	_lastWiegand = 0;
	_cardTempHigh = 0;
	_cardTemp = 0;
	_code = 0;
	_wiegandType = 0;
	_bitCount = 0;
	pinMode(pinD0, INPUT);					// Set D0 pin as input
	pinMode(pinD1, INPUT);					// Set D1 pin as input
	attachInterrupt(pinIntD0, ReadD0, FALLING);	// Hardware interrupt - high to low pulse
	attachInterrupt(pinIntD1, ReadD1, FALLING);	// Hardware interrupt - high to low pulse
}

void WIEGAND::ReadD0 ()
{
	_bitCount++;				// Increament bit count for Interrupt connected to D0
	if (_bitCount>31)			// If bit count more than 31, process high bits
	{
		_cardTempHigh |= ((0x80000000 & _cardTemp)>>31);	//	shift value to high bits
		_cardTempHigh <<= 1;
		_cardTemp <<=1;
	}
	else
	{
		_cardTemp <<= 1;		// D0 represent binary 0, so just left shift card data
	}
	_lastWiegand = millis();	// Keep track of last wiegand bit received
}

void WIEGAND::ReadD1()
{
	_bitCount ++;				// Increment bit count for Interrupt connected to D1
	if (_bitCount>31)			// If bit count more than 31, process high bits
	{
		_cardTempHigh |= ((0x80000000 & _cardTemp)>>31);	// shift value to high bits
		_cardTempHigh <<= 1;
		_cardTemp |= 1;
		_cardTemp <<=1;
	}
	else
	{
		_cardTemp |= 1;			// D1 represent binary 1, so OR card data with 1 then
		_cardTemp <<= 1;		// left shift card data
	}
	_lastWiegand = millis();	// Keep track of last wiegand bit received
}

unsigned long WIEGAND::GetCardId (volatile unsigned long *codehigh, volatile unsigned long *codelow, char bitlength)
{
	unsigned long cardID=0;

	if (bitlength==26)								// EM tag
		cardID = (*codelow & 0x1FFFFFE) >>1;

	if (bitlength==34)								// Mifare
	{
		*codehigh = *codehigh & 0x03;				// only need the 2 LSB of the codehigh
		*codehigh <<= 30;							// shift 2 LSB to MSB
		*codelow >>=1;
		cardID = *codehigh | *codelow;
	}
	return cardID;
}

char translateEnterEscapeKeyPress(char originalKeyPress) {
    switch(originalKeyPress) {
        case 0x0b:        // 11 or * key
            return 0x0d;  // 13 or ASCII ENTER

        case 0x0a:        // 10 or # key
            return 0x1b;  // 27 or ASCII ESCAPE

        default:
            return originalKeyPress;
    }
}

bool WIEGAND::DoWiegandConversion ()
{
	unsigned long cardID;
	unsigned long sysTick = millis();

	if ((sysTick - _lastWiegand) > 25)								// if no more signal coming through after 25ms
	{
		if ((_bitCount==26) || (_bitCount==34) || (_bitCount==8) || (_bitCount==4)) 	// bitCount for keypress=4 or 8, Wiegand 26=26, Wiegand 34=34
		{
			_cardTemp >>= 1;			// shift right 1 bit to get back the real value - interrupt done 1 left shift in advance
			if (_bitCount>32)			// bit count more than 32 bits, shift high bits right to make adjustment
				_cardTempHigh >>= 1;

			if((_bitCount==26) || (_bitCount==34))		// wiegand 26 or wiegand 34
			{
				cardID = GetCardId (&_cardTempHigh, &_cardTemp, _bitCount);
				_wiegandType=_bitCount;
				_bitCount=0;
				_cardTemp=0;
				_cardTempHigh=0;
				_code=cardID;
				return true;
			}
			else if (_bitCount==8)		// keypress wiegand with integrity
			{
				// 8-bit Wiegand keyboard data, high nibble is the "NOT" of low nibble
				// eg if key 1 pressed, data=E1 in binary 11100001 , high nibble=1110 , low nibble = 0001
				char highNibble = (_cardTemp & 0xf0) >>4;
				char lowNibble = (_cardTemp & 0x0f);
				_wiegandType=_bitCount;
				_bitCount=0;
				_cardTemp=0;
				_cardTempHigh=0;

				if (lowNibble == (~highNibble & 0x0f))		// check if low nibble matches the "NOT" of high nibble.
                {
                    _code = (int)translateEnterEscapeKeyPress(lowNibble);
					return true;
				}

                // TODO: Handle validation failure case!
			}
            else if (4 == _bitCount) {
                // 4-bit Wiegand codes have no data integrity check so we just
                // read the LOW nibble.
                _code = (int)translateEnterEscapeKeyPress(_cardTemp & 0x0000000F);

                _wiegandType = _bitCount;
                _bitCount = 0;
                _cardTemp = 0;
                _cardTempHigh = 0;

                return true;
            }
		}
		else
		{
			// well time over 25 ms and bitCount !=8 , !=26, !=34 , must be noise or nothing then.
			_lastWiegand=sysTick;
			_bitCount=0;
			_cardTemp=0;
			_cardTempHigh=0;
			return false;
		}
	}
	else
		return false;
}<|endoftext|>


<commit_before>/* Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2017, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

#ifndef NUPIC_UTIL_SLIDING_WINDOW_HPP
#define NUPIC_UTIL_SLIDING_WINDOW_HPP

#include <vector>
#include <algorithm>
#include <iterator>
#include <cmath>
#include <string>

#include <nupic/types/Types.hpp>
#include <nupic/utils/Log.hpp>
#include <nupic/math/Math.hpp> //for macro ASSERT_INPUT_ITERATOR

namespace nupic {
  namespace util {

template<class T>
class SlidingWindow {
  public:
    SlidingWindow(UInt maxCapacity, std::string id="SlidingWindow", int debug=0) :
      maxCapacity(maxCapacity),
      ID(id),
      DEBUG(debug)
{
      buffer_.reserve(maxCapacity);
      idxNext_ = 0;
}

    template<class IteratorT>
    SlidingWindow(UInt maxCapacity, IteratorT initialData_begin,
      IteratorT initialData_end, std::string id="SlidingWindow", int debug=0):
      SlidingWindow(maxCapacity, id, debug) {
      // Assert that It obeys the STL forward iterator concept
      ASSERT_INPUT_ITERATOR(IteratorT);
      for(IteratorT it = initialData_begin; it != initialData_end; ++it) {
        append(*it);
      }
    }

    const UInt maxCapacity;
    const std::string ID; //name of this object
    const int DEBUG;

    size_t size() const {
      NTA_ASSERT(buffer_.size() <= maxCapacity);
      return buffer_.size();
    }

    /** append new value to the end of the buffer and handle the
       "overflows"-may pop the oldest element if full.
      */
    void append(T newValue) {
      if(size() < maxCapacity) {
        buffer_.push_back(newValue);
      } else {
        buffer_[idxNext_] = newValue;
      }
      idxNext_ = (idxNext_ +1 ) %maxCapacity;
    }

      /** like append, but return the dropped value if it was dropped.
        :param T newValue - new value to append to the sliding window
        :param T* - a return pass-by-value with the removed element,
          if this function returns false, this value will remain unchanged.
        :return bool if some value has been dropped (and updated as
          droppedValue)
      */
      bool append(T newValue, T* droppedValue) {
        //only in this case we drop oldest; this happens always after
        //first maxCap steps ; must be checked before append()
        const bool isFull = (buffer_.size()==maxCapacity);
        if(isFull) {
          *droppedValue = buffer_[idxNext_];
        }
        append(newValue);
        return isFull;
      }

      /**
        :return unordered content (data ) of this sl. window;
          call getLinearizedData() if you need them oredered from
          oldest->newest
        This direct access method is fast.
      */
      const std::vector<T>& getData() const {
        return buffer_;
      }

      /** linearize method for the internal buffer; this is slower than
        the pure getData() but ensures that the data are ordered (oldest at
        the beginning, newest at the end of the vector
        This handles case of |5,6;1,2,3,4| => |1,2,3,4,5,6|
        :return new linearized vector
      */
      std::vector<T> getLinearizedData() const {
        std::vector<T> lin;
        lin.reserve(buffer_.size());

        //insert the "older" part at the beginning
        lin.insert(std::begin(lin), std::begin(buffer_) + idxNext_, std::end(buffer_));
        //append the "newer" part to the end of the constructed vect
        lin.insert(std::end(lin), std::begin(buffer_), std::begin(buffer_) + idxNext_);
        return lin;
      }

      bool operator==(const SlidingWindow& r2) const {
        const bool sameSizes = (this->size() == r2.size()) && (this->maxCapacity == r2.maxCapacity);
        return sameSizes && std::equal(this->buffer_.cbegin(), this->buffer_.cend(), r2.getData().cbegin()); //also content must be same
      }

      bool operator!=(const SlidingWindow& r2) const {
        return !operator==(r2);
      }

      /** operator[] provides fast access to the elements indexed relatively
        to the oldest element. So slidingWindow[0] returns oldest element,
        slidingWindow[size()] returns the newest.
      :param UInt index - index/offset from the oldest element, values 0..size()
      :return T - i-th oldest value in the buffer
      :throws 0<=index<=size()
      */
      T& operator[](UInt index) {
        NTA_ASSERT(index <= size());
        NTA_ASSERT(size() > 0);
        //get last updated position, "current"+index(offset)
        //avoid calling getLinearizeData() as it involves copy()
        if (size() == maxCapacity) {
          return &buffer_[(idxNext_ + index) % maxCapacity];
        } else {
          return &buffer_[index];
        }
      }

      const T& operator[](UInt index) const {
        return this->operator[](index); //call the overloaded operator[] above
      }

      std::ostream& operator<<(std::ostream& os) {
        return os << ID << std::endl;
      }

      private:
        std::vector<T> buffer_;
        UInt idxNext_;
};
}} //end ns
#endif //header
<commit_msg>SlidingWindow: rev: move variables down<commit_after>/* Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2017, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

#ifndef NUPIC_UTIL_SLIDING_WINDOW_HPP
#define NUPIC_UTIL_SLIDING_WINDOW_HPP

#include <vector>
#include <algorithm>
#include <iterator>
#include <cmath>
#include <string>

#include <nupic/types/Types.hpp>
#include <nupic/utils/Log.hpp>
#include <nupic/math/Math.hpp> //for macro ASSERT_INPUT_ITERATOR

namespace nupic {
  namespace util {

template<class T>
class SlidingWindow {
  public:
    SlidingWindow(UInt maxCapacity, std::string id="SlidingWindow", int debug=0) :
      maxCapacity(maxCapacity),
      ID(id),
      DEBUG(debug)
{
      buffer_.reserve(maxCapacity);
      idxNext_ = 0;
}

    template<class IteratorT>
    SlidingWindow(UInt maxCapacity, IteratorT initialData_begin,
      IteratorT initialData_end, std::string id="SlidingWindow", int debug=0):
      SlidingWindow(maxCapacity, id, debug) {
      // Assert that It obeys the STL forward iterator concept
      ASSERT_INPUT_ITERATOR(IteratorT);
      for(IteratorT it = initialData_begin; it != initialData_end; ++it) {
        append(*it);
      }
    }

    size_t size() const {
      NTA_ASSERT(buffer_.size() <= maxCapacity);
      return buffer_.size();
    }

    /** append new value to the end of the buffer and handle the
       "overflows"-may pop the oldest element if full.
      */
    void append(T newValue) {
      if(size() < maxCapacity) {
        buffer_.push_back(newValue);
      } else {
        buffer_[idxNext_] = newValue;
      }
      idxNext_ = (idxNext_ +1 ) %maxCapacity;
    }

      /** like append, but return the dropped value if it was dropped.
        :param T newValue - new value to append to the sliding window
        :param T* - a return pass-by-value with the removed element,
          if this function returns false, this value will remain unchanged.
        :return bool if some value has been dropped (and updated as
          droppedValue)
      */
      bool append(T newValue, T* droppedValue) {
        //only in this case we drop oldest; this happens always after
        //first maxCap steps ; must be checked before append()
        const bool isFull = (buffer_.size()==maxCapacity);
        if(isFull) {
          *droppedValue = buffer_[idxNext_];
        }
        append(newValue);
        return isFull;
      }

      /**
        :return unordered content (data ) of this sl. window;
          call getLinearizedData() if you need them oredered from
          oldest->newest
        This direct access method is fast.
      */
      const std::vector<T>& getData() const {
        return buffer_;
      }

      /** linearize method for the internal buffer; this is slower than
        the pure getData() but ensures that the data are ordered (oldest at
        the beginning, newest at the end of the vector
        This handles case of |5,6;1,2,3,4| => |1,2,3,4,5,6|
        :return new linearized vector
      */
      std::vector<T> getLinearizedData() const {
        std::vector<T> lin;
        lin.reserve(buffer_.size());

        //insert the "older" part at the beginning
        lin.insert(std::begin(lin), std::begin(buffer_) + idxNext_, std::end(buffer_));
        //append the "newer" part to the end of the constructed vect
        lin.insert(std::end(lin), std::begin(buffer_), std::begin(buffer_) + idxNext_);
        return lin;
      }

      bool operator==(const SlidingWindow& r2) const {
        const bool sameSizes = (this->size() == r2.size()) && (this->maxCapacity == r2.maxCapacity);
        return sameSizes && std::equal(this->buffer_.cbegin(), this->buffer_.cend(), r2.getData().cbegin()); //also content must be same
      }

      bool operator!=(const SlidingWindow& r2) const {
        return !operator==(r2);
      }

      /** operator[] provides fast access to the elements indexed relatively
        to the oldest element. So slidingWindow[0] returns oldest element,
        slidingWindow[size()] returns the newest.
      :param UInt index - index/offset from the oldest element, values 0..size()
      :return T - i-th oldest value in the buffer
      :throws 0<=index<=size()
      */
      T& operator[](UInt index) {
        NTA_ASSERT(index <= size());
        NTA_ASSERT(size() > 0);
        //get last updated position, "current"+index(offset)
        //avoid calling getLinearizeData() as it involves copy()
        if (size() == maxCapacity) {
          return &buffer_[(idxNext_ + index) % maxCapacity];
        } else {
          return &buffer_[index];
        }
      }

      const T& operator[](UInt index) const {
        return this->operator[](index); //call the overloaded operator[] above
      }

      std::ostream& operator<<(std::ostream& os) {
        return os << ID << std::endl;
      }

      public:
        const UInt maxCapacity;
        const std::string ID; //name of this object
        const int DEBUG;
      private:
        std::vector<T> buffer_;
        UInt idxNext_;
};
}} //end ns
#endif //header
<|endoftext|>


<commit_before>// Visit http://www.johndcook.com/stand_alone_code.html for the source of this code and more like it.

#include <cmath>
#include <sstream>
#include <iostream>
#include <stdexcept>

#include "gamma_win.h"

// Note that the functions Gamma and LogGamma are mutually dependent.

double gamma
(
    double x    // We require x > 0
)
{
  if (x <= 0.0)
  {
    std::stringstream os;
        os << "Invalid input argument " << x <<  ". Argument must be positive.";
        throw std::invalid_argument( os.str() );
  }

    // Split the function domain into three intervals:
    // (0, 0.001), [0.001, 12), and (12, infinity)

    ///////////////////////////////////////////////////////////////////////////
    // First interval: (0, 0.001)
  //
  // For small x, 1/Gamma(x) has power series x + gamma x^2  - ...
  // So in this range, 1/Gamma(x) = x + gamma x^2 with error on the order of x^3.
  // The relative error over this interval is less than 6e-7.

  const double gamma = 0.577215664901532860606512090; // Euler's gamma constant

    if (x < 0.001)
        return 1.0/(x*(1.0 + gamma*x));

    ///////////////////////////////////////////////////////////////////////////
    // Second interval: [0.001, 12)

  if (x < 12.0)
    {
        // The algorithm directly approximates gamma over (1,2) and uses
        // reduction identities to reduce other arguments to this interval.

    double y = x;
        int n = 0;
        bool arg_was_less_than_one = (y < 1.0);

        // Add or subtract integers as necessary to bring y into (1,2)
        // Will correct for this below
        if (arg_was_less_than_one)
        {
            y += 1.0;
        }
        else
        {
            n = static_cast<int> (floor(y)) - 1;  // will use n later
            y -= n;
        }

        // numerator coefficients for approximation over the interval (1,2)
        static const double p[] =
        {
            -1.71618513886549492533811E+0,
             2.47656508055759199108314E+1,
            -3.79804256470945635097577E+2,
             6.29331155312818442661052E+2,
             8.66966202790413211295064E+2,
            -3.14512729688483675254357E+4,
            -3.61444134186911729807069E+4,
             6.64561438202405440627855E+4
        };

        // denominator coefficients for approximation over the interval (1,2)
        static const double q[] =
        {
            -3.08402300119738975254353E+1,
             3.15350626979604161529144E+2,
            -1.01515636749021914166146E+3,
            -3.10777167157231109440444E+3,
             2.25381184209801510330112E+4,
             4.75584627752788110767815E+3,
            -1.34659959864969306392456E+5,
            -1.15132259675553483497211E+5
        };

        double num = 0.0;
        double den = 1.0;
        int i;

        double z = y - 1;
        for (i = 0; i < 8; i++)
        {
            num = (num + p[i])*z;
            den = den*z + q[i];
        }
        double result = num/den + 1.0;

        // Apply correction if argument was not initially in (1,2)
        if (arg_was_less_than_one)
        {
            // Use identity gamma(z) = gamma(z+1)/z
            // The variable "result" now holds gamma of the original y + 1
            // Thus we use y-1 to get back the orginal y.
            result /= (y-1.0);
        }
        else
        {
            // Use the identity gamma(z+n) = z*(z+1)* ... *(z+n-1)*gamma(z)
            for (i = 0; i < n; i++)
                result *= y++;
        }

    return result;
    }

    ///////////////////////////////////////////////////////////////////////////
    // Third interval: [12, infinity)

    if (x > 171.624)
    {
    // Correct answer too large to display. Force +infinity.
    double temp = DBL_MAX;
    return temp*2.0;
    }

    return exp(LogGamma(x));
}

double lgamma
(
    double x    // x must be positive
)
{
  if (x <= 0.0)
  {
    std::stringstream os;
        os << "Invalid input argument " << x <<  ". Argument must be positive.";
        throw std::invalid_argument( os.str() );
  }

    if (x < 12.0)
    {
        return log(fabs(Gamma(x)));
    }

  // Abramowitz and Stegun 6.1.41
    // Asymptotic series should be good to at least 11 or 12 figures
    // For error analysis, see Whittiker and Watson
    // A Course in Modern Analysis (1927), page 252

    static const double c[8] =
    {
     1.0/12.0,
    -1.0/360.0,
    1.0/1260.0,
    -1.0/1680.0,
    1.0/1188.0,
    -691.0/360360.0,
    1.0/156.0,
    -3617.0/122400.0
    };
    double z = 1.0/(x*x);
    double sum = c[7];
    for (int i=6; i >= 0; i--)
    {
        sum *= z;
        sum += c[i];
    }
    double series = sum/x;

    static const double halfLogTwoPi = 0.91893853320467274178032973640562;
    double logGamma = (x - 0.5)*log(x) - x + halfLogTwoPi + series;
  return logGamma;
}
<commit_msg>Re #5 fixing samsmodels compilation on MSVC<commit_after>// Visit http://www.johndcook.com/stand_alone_code.html for the source of this code and more like it.

#include <cmath>
#include <sstream>
#include <iostream>
#include <stdexcept>

#include "gamma_win.h"

// Note that the functions Gamma and LogGamma are mutually dependent.

double gamma
(
    double x    // We require x > 0
)
{
  if (x <= 0.0)
  {
    std::stringstream os;
        os << "Invalid input argument " << x <<  ". Argument must be positive.";
        throw std::invalid_argument( os.str() );
  }

    // Split the function domain into three intervals:
    // (0, 0.001), [0.001, 12), and (12, infinity)

    ///////////////////////////////////////////////////////////////////////////
    // First interval: (0, 0.001)
  //
  // For small x, 1/Gamma(x) has power series x + gamma x^2  - ...
  // So in this range, 1/Gamma(x) = x + gamma x^2 with error on the order of x^3.
  // The relative error over this interval is less than 6e-7.

  const double gamma = 0.577215664901532860606512090; // Euler's gamma constant

    if (x < 0.001)
        return 1.0/(x*(1.0 + gamma*x));

    ///////////////////////////////////////////////////////////////////////////
    // Second interval: [0.001, 12)

  if (x < 12.0)
    {
        // The algorithm directly approximates gamma over (1,2) and uses
        // reduction identities to reduce other arguments to this interval.

    double y = x;
        int n = 0;
        bool arg_was_less_than_one = (y < 1.0);

        // Add or subtract integers as necessary to bring y into (1,2)
        // Will correct for this below
        if (arg_was_less_than_one)
        {
            y += 1.0;
        }
        else
        {
            n = static_cast<int> (floor(y)) - 1;  // will use n later
            y -= n;
        }

        // numerator coefficients for approximation over the interval (1,2)
        static const double p[] =
        {
            -1.71618513886549492533811E+0,
             2.47656508055759199108314E+1,
            -3.79804256470945635097577E+2,
             6.29331155312818442661052E+2,
             8.66966202790413211295064E+2,
            -3.14512729688483675254357E+4,
            -3.61444134186911729807069E+4,
             6.64561438202405440627855E+4
        };

        // denominator coefficients for approximation over the interval (1,2)
        static const double q[] =
        {
            -3.08402300119738975254353E+1,
             3.15350626979604161529144E+2,
            -1.01515636749021914166146E+3,
            -3.10777167157231109440444E+3,
             2.25381184209801510330112E+4,
             4.75584627752788110767815E+3,
            -1.34659959864969306392456E+5,
            -1.15132259675553483497211E+5
        };

        double num = 0.0;
        double den = 1.0;
        int i;

        double z = y - 1;
        for (i = 0; i < 8; i++)
        {
            num = (num + p[i])*z;
            den = den*z + q[i];
        }
        double result = num/den + 1.0;

        // Apply correction if argument was not initially in (1,2)
        if (arg_was_less_than_one)
        {
            // Use identity gamma(z) = gamma(z+1)/z
            // The variable "result" now holds gamma of the original y + 1
            // Thus we use y-1 to get back the orginal y.
            result /= (y-1.0);
        }
        else
        {
            // Use the identity gamma(z+n) = z*(z+1)* ... *(z+n-1)*gamma(z)
            for (i = 0; i < n; i++)
                result *= y++;
        }

    return result;
    }

    ///////////////////////////////////////////////////////////////////////////
    // Third interval: [12, infinity)

    if (x > 171.624)
    {
    // Correct answer too large to display. Force +infinity.
    double temp = DBL_MAX;
    return temp*2.0;
    }

    return exp(lgamma(x));
}

double lgamma
(
    double x    // x must be positive
)
{
  if (x <= 0.0)
  {
    std::stringstream os;
        os << "Invalid input argument " << x <<  ". Argument must be positive.";
        throw std::invalid_argument( os.str() );
  }

    if (x < 12.0)
    {
        return log(fabs(gamma(x)));
    }

  // Abramowitz and Stegun 6.1.41
    // Asymptotic series should be good to at least 11 or 12 figures
    // For error analysis, see Whittiker and Watson
    // A Course in Modern Analysis (1927), page 252

    static const double c[8] =
    {
     1.0/12.0,
    -1.0/360.0,
    1.0/1260.0,
    -1.0/1680.0,
    1.0/1188.0,
    -691.0/360360.0,
    1.0/156.0,
    -3617.0/122400.0
    };
    double z = 1.0/(x*x);
    double sum = c[7];
    for (int i=6; i >= 0; i--)
    {
        sum *= z;
        sum += c[i];
    }
    double series = sum/x;

    static const double halfLogTwoPi = 0.91893853320467274178032973640562;
    double logGamma = (x - 0.5)*log(x) - x + halfLogTwoPi + series;
  return logGamma;
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/

#include <osg/TexEnv>
#include <osg/TexEnvCombine>

#include <osgFX/MultiTextureControl>

using namespace osg;
using namespace osgFX;

MultiTextureControl::MultiTextureControl()
{
}

MultiTextureControl::MultiTextureControl(const MultiTextureControl& copy, const osg::CopyOp& copyop):
    Group(copy,copyop),
    _textureWeightList(copy._textureWeightList)
{
    updateStateSet();
}

void MultiTextureControl::setTextureWeight(unsigned int unit, float weight)
{
    if (unit >= _textureWeightList.size())
    {
        _textureWeightList.resize(unit+1,0.0f);
    }
    _textureWeightList[unit] = weight;

    updateStateSet();
}

void MultiTextureControl::updateStateSet()
{
    osg::StateSet* stateset = getOrCreateStateSet();

    stateset->clear();

    unsigned int numTextureUnitsOn = 0;
    unsigned int unit;
    for(unit=0;unit<_textureWeightList.size();++unit)
    {
        if (_textureWeightList[unit]>0.0f) ++numTextureUnitsOn;
    }

    if (numTextureUnitsOn<=1)
    {
        for(unit=0;unit<_textureWeightList.size();++unit)
        {
            if (_textureWeightList[unit]>0.0f)
            {
                osg::TexEnv* texenv = new osg::TexEnv(osg::TexEnv::MODULATE);
                stateset->setTextureAttribute(unit, texenv);
                stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON);
            }
            else
            {
                stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
            }
        }

    }
    else if (_textureWeightList.size()==2)
    {
        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+0);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+1);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT);
            texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);

            float r = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]);
            texenv->setConstantColor(osg::Vec4(r,r,r,r));

            stateset->setTextureAttribute(0, texenv);
        }

        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::MODULATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);

            stateset->setTextureAttribute(1, texenv);
        }
    }
    else if (_textureWeightList.size()==3)
    {
        float b = (_textureWeightList[0]+_textureWeightList[1])/(_textureWeightList[0]+_textureWeightList[1]+_textureWeightList[2]);
        float a = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]);

        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+0);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+1);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT);
            texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);

            texenv->setConstantColor(osg::Vec4(a,a,a,a));

            stateset->setTextureAttribute(0, texenv);
        }

        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+2);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT);
            texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);

            texenv->setConstantColor(osg::Vec4(b,b,b,b));

            stateset->setTextureAttribute(1, texenv);
        }

        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::MODULATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);

            stateset->setTextureAttribute(2, texenv);
        }
    }

/*
    bool firstActiveTextureUnit = true;
    for(unsigned int unit = 0;
        unit < _textureWeightList.size();
        ++unit)
    {
        float r = _textureWeightList[unit];

        if (r==0.0f)
        {
            stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::OFF);
        }
        else
        {
            stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON);

            if (firstActiveTextureUnit)
            {
                stateset->setTextureAttribute(unit, new osg::TexEnv);
                firstActiveTextureUnit = false;
            }
            else
            {

                osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
                texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
                texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
                texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
                texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE);
                texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
                texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT);
                texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);

                texenv->setConstantColor(osg::Vec4(r,r,r,r));

                stateset->setTextureAttribute(unit, texenv);
            }

        }

    }
*/
}

<commit_msg>Changed the updateStateSet code so that it creates a new StateSet each update rather than clear and reuse the existing one, this change fixes a threading issue that occured when the viewer is in DrawThreadPerContext.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/

#include <osg/TexEnv>
#include <osg/TexEnvCombine>

#include <osgFX/MultiTextureControl>

using namespace osg;
using namespace osgFX;

MultiTextureControl::MultiTextureControl()
{
}

MultiTextureControl::MultiTextureControl(const MultiTextureControl& copy, const osg::CopyOp& copyop):
    Group(copy,copyop),
    _textureWeightList(copy._textureWeightList)
{
    updateStateSet();
}

void MultiTextureControl::setTextureWeight(unsigned int unit, float weight)
{
    if (unit >= _textureWeightList.size())
    {
        _textureWeightList.resize(unit+1,0.0f);
    }
    _textureWeightList[unit] = weight;

    updateStateSet();
}

void MultiTextureControl::updateStateSet()
{
#if 0
    osg::StateSet* stateset = getOrCreateStateSet();
    stateset->clear();
#else
    // temporary measure to avoid multi-threaded crash
    osg::StateSet* stateset = new osg::StateSet;
#endif

    unsigned int numTextureUnitsOn = 0;
    unsigned int unit;
    for(unit=0;unit<_textureWeightList.size();++unit)
    {
        if (_textureWeightList[unit]>0.0f) ++numTextureUnitsOn;
    }

    if (numTextureUnitsOn<=1)
    {
        for(unit=0;unit<_textureWeightList.size();++unit)
        {
            if (_textureWeightList[unit]>0.0f)
            {
                osg::TexEnv* texenv = new osg::TexEnv(osg::TexEnv::MODULATE);
                stateset->setTextureAttribute(unit, texenv);
                stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON);
            }
            else
            {
                stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
            }
        }

    }
    else if (_textureWeightList.size()==2)
    {
        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+0);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+1);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT);
            texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);

            float r = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]);
            texenv->setConstantColor(osg::Vec4(r,r,r,r));

            stateset->setTextureAttribute(0, texenv);
        }

        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::MODULATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);

            stateset->setTextureAttribute(1, texenv);
        }
    }
    else if (_textureWeightList.size()==3)
    {
        float b = (_textureWeightList[0]+_textureWeightList[1])/(_textureWeightList[0]+_textureWeightList[1]+_textureWeightList[2]);
        float a = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]);

        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+0);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+1);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT);
            texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);

            texenv->setConstantColor(osg::Vec4(a,a,a,a));

            stateset->setTextureAttribute(0, texenv);
        }

        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+2);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT);
            texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);

            texenv->setConstantColor(osg::Vec4(b,b,b,b));

            stateset->setTextureAttribute(1, texenv);
        }

        {
            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
            texenv->setCombine_RGB(osg::TexEnvCombine::MODULATE);
            texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
            texenv->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR);
            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);

            stateset->setTextureAttribute(2, texenv);
        }
    }

    setStateSet(stateset);
}

<|endoftext|>


<commit_before>/*
 * Copyright 2015 - 2017 gtalent2@gmail.com
 *
 * 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/.
 */
#include <map>
#include <ox/std/std.hpp>

using namespace std;
using namespace ox::std;

template<typename T>
int testBigEndianAdapt(string str) {
	auto i = (T) stoull(str, nullptr, 16);
	return !(bigEndianAdapt(bigEndianAdapt(i)) == i);
}

map<string, int(*)(string)> tests = {
	{
		{ "bigEndianAdapt<uint16_t>", testBigEndianAdapt<uint16_t> },
		{ "bigEndianAdapt<uint32_t>", testBigEndianAdapt<uint32_t> },
		{ "bigEndianAdapt<uint64_t>", testBigEndianAdapt<uint64_t> },
	},
};

int main(int argc, const char **args) {
	int retval = -1;
	if (argc > 1) {
		auto testName = args[1];
		string testArg = args[2];
		if (tests.find(testName) != tests.end()) {
			retval = tests[testName](testArg);
		}
	}
	return retval;
}
<commit_msg>Add explicit <string> include to byteswap test<commit_after>/*
 * Copyright 2015 - 2017 gtalent2@gmail.com
 *
 * 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/.
 */
#include <map>
#include <string>
#include <ox/std/std.hpp>

using namespace std;
using namespace ox::std;

template<typename T>
int testBigEndianAdapt(string str) {
	auto i = (T) stoull(str, nullptr, 16);
	return !(bigEndianAdapt(bigEndianAdapt(i)) == i);
}

map<string, int(*)(string)> tests = {
	{
		{ "bigEndianAdapt<uint16_t>", testBigEndianAdapt<uint16_t> },
		{ "bigEndianAdapt<uint32_t>", testBigEndianAdapt<uint32_t> },
		{ "bigEndianAdapt<uint64_t>", testBigEndianAdapt<uint64_t> },
	},
};

int main(int argc, const char **args) {
	int retval = -1;
	if (argc > 1) {
		auto testName = args[1];
		string testArg = args[2];
		if (tests.find(testName) != tests.end()) {
			retval = tests[testName](testArg);
		}
	}
	return retval;
}
<|endoftext|>