<commit_before>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

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

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

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

* Neither the name of the copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND
CONTRIBUTORS ``AS IS''  AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS  BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

// $Id$
// $URL$
// Maintainer: joaander

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

// remove silly warnings
#ifdef WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif

#include "ClockSource.h"
#include "Profiler.h"
#include "ParticleData.h"
#include "BondData.h"
#include "AngleData.h"
#include "DihedralData.h"
#include "ExecutionConfiguration.h"
#include "Initializers.h"
#include "HOOMDInitializer.h"
#include "RandomGenerator.h"
#include "Compute.h"
#include "ForceCompute.h"
#include "ConstForceCompute.h"
#include "HarmonicBondForceCompute.h"
#include "HarmonicAngleForceCompute.h"
#include "HarmonicDihedralForceCompute.h"
#include "HarmonicImproperForceCompute.h"
#include "CGCMMAngleForceCompute.h"
#include "FENEBondForceCompute.h"
#include "LJForceCompute.h"
#include "CGCMMForceCompute.h"
#include "GaussianForceCompute.h"
//#include "YukawaForceCompute.h"
#include "LJWallForceCompute.h"
#include "TempCompute.h"
#include "NeighborList.h"
#include "BinnedNeighborList.h"
#include "Analyzer.h"
#include "IMDInterface.h"
#include "HOOMDDumpWriter.h"
#include "PDBDumpWriter.h"
#include "MOL2DumpWriter.h"
#include "DCDDumpWriter.h"
#include "Logger.h"
#include "MSDAnalyzer.h"
#include "Updater.h"
#include "Integrator.h"
#include "TempRescaleUpdater.h"
#include "ZeroMomentumUpdater.h"
#include "SFCPackUpdater.h"
#include "BoxResizeUpdater.h"
#include "NVTUpdater.h"
#include "NPTUpdater.h"
#include "NVEUpdater.h"
#include "BD_NVTUpdater.h"
#include "System.h"
#include "Variant.h"

// include GPU classes
#ifdef ENABLE_CUDA
#include "NVTUpdaterGPU.h"
#include "NVEUpdaterGPU.h"
#include "NPTUpdaterGPU.h"
#include "BD_NVTUpdaterGPU.h"
#include "BinnedNeighborListGPU.h"
#include "NeighborListNsqGPU.h"
#include "LJForceComputeGPU.h"
#include "CGCMMForceComputeGPU.h"
#include "GaussianForceGPU.h"
//#include "YukawaForceComputeGPU.h"
#include "StochasticForceComputeGPU.h"
#include "HarmonicBondForceComputeGPU.h"
#include "HarmonicAngleForceComputeGPU.h"
#include "HarmonicDihedralForceComputeGPU.h"
#include "HarmonicImproperForceComputeGPU.h"
#include "CGCMMAngleForceComputeGPU.h"
#include "FENEBondForceComputeGPU.h"
#endif

#include "SignalHandler.h"

#include "HOOMDVersion.h"

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>

using namespace boost::filesystem;
using namespace boost::python;

#include <iostream>
#include <sstream>
using namespace std;

// include gpu_settings.h for g_gpu_error_checking
#ifdef ENABLE_CUDA
#include "gpu_settings.h"
#else
// otherwise, we need a dummy variable that will do nothing
bool g_gpu_error_checking = false;
#endif

/*! \file hoomd_module.cc
	\brief Brings all of the export_* functions together to export the hoomd python module
*/

//! Scans for possible hoomd data directories
/*! \returns the first one it finds
	This function is for use by the demos and benchmarks installed with HOOMD.
*/
string find_hoomd_data_dir()
	{
	// try checking offsets from the environment variable first:
	// it is searched first so as to override any other potential location
	if (getenv("HOOMD_ROOT"))
		{
		path hoomd_root_dir = path(string(getenv("HOOMD_ROOT")));
		// try root/share/hoomd (for /usr/local /usr etc)
		if (exists(hoomd_root_dir / "share" / "hoomd" / "hoomd_data_dir"))
			{
			string result = (hoomd_root_dir / "share" / "hoomd").string();
			return result;
			}
		// try root/share (for /opt/hoomd style install)
		if (exists(hoomd_root_dir / "share" / "hoomd_data_dir"))
			{
			string result = (hoomd_root_dir / "share").string();
			return result;
			}
		}

	// as a final fallback: try the source directory
	if (exists(path(HOOMD_SOURCE_DIR) / "share" / "hoomd" / "hoomd_data_dir"))
		return (path(HOOMD_SOURCE_DIR) / "share" / "hoomd").string();

	#ifdef WIN32
	// access the registry key
	string name = string("hoomd ") + string(HOOMD_VERSION);
	string reg_path = "SOFTWARE\\Ames Laboratory Iowa State University\\" + name;

	char *value = new char[1024];
	LONG value_size = 1024;
	LONG err_code = RegQueryValue(HKEY_LOCAL_MACHINE, reg_path.c_str(), value, &value_size);
	// see if it installed where the reg key says so
	if (err_code == ERROR_SUCCESS)
		{
		path install_dir = path(string(value));
		if (exists(install_dir / "hoomd_data_dir"))
			return (install_dir).string();
		}
	delete[] value;

	// otherwise, check the program files root
	if (getenv("PROGRAMFILES"))
		{
		path program_files_dir = path(string(getenv("PROGRAMFILES")));
		if (exists(program_files_dir / "hoomd" / "hoomd_data_dir"))
			return (program_files_dir / "hoomd").string();
		}
	#else
	// check a few likely installation locations
	if (exists("/usr/share/hoomd/hoomd_data_dir"))
		return "/usr/share/hoomd";
	if (exists("/usr/local/share/hoomd/hoomd_data_dir"))
		return "/usr/local/share/hoomd";
	if (exists("/opt/hoomd/share/hoomd_data_dir"))
		return "/opt/hoomd/share";
	#endif

	cerr << endl << "***Error! HOOMD data directory not found, please set the environment variable HOOMD_ROOT" << endl << endl;
	return string("");
	}

//! Scans for a VMD installation
/*! \returns Full path to the vmd executable
	This function is for use by the demos and benchmarks installed with HOOMD.
*/
string find_vmd()
	{
	#ifdef WIN32

	// find VMD through the registry
	string reg_path = "SOFTWARE\\University of Illinois\\VMD\\1.8.6";

	char *value = new char[1024];
	DWORD value_size = 1024;
	HKEY vmd_root_key;
	LONG err_code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_path.c_str(), 0, KEY_READ, &vmd_root_key);
	if (err_code == ERROR_SUCCESS)
		{
		err_code = RegQueryValueEx(vmd_root_key, "VMDDIR", NULL, NULL, (LPBYTE)value, &value_size);
		// see if it installed where the reg key says so
		if (err_code == ERROR_SUCCESS)
			{
			path install_dir = path(string(value));
			if (exists(install_dir / "vmd.exe"))
				return (install_dir / "vmd.exe").string();
			}
		}
	delete[] value;

	#else
	// check some likely locations
	if (exists("/usr/bin/vmd"))
		return "/usr/bin/vmd";
	if (exists("/usr/local/bin/vmd"))
		return "/usr/local/bin/vmd";
	if (exists("/opt/vmd/bin/vmd"))
		return "/opt/vmd/bin/vmd";
	if (exists(path("/Applications/3rd Party Apps/VMD 1.8.6.app/Contents/Resources/VMD.app/Contents/MacOS/VMD", no_check )))
		return("/Applications/3rd Party Apps/VMD 1.8.6.app/Contents/Resources/VMD.app/Contents/MacOS/VMD");
	if (exists(path("/Applications/VMD 1.8.6.app/Contents/Resources/VMD.app/Contents/MacOS/VMD", no_check)))
		return("/Applications/VMD 1.8.6.app/Contents/Resources/VMD.app/Contents/MacOS/VMD");
	#endif

	// return an empty string if we didn't find it
	return "";
	}

//! Method for setting g_gpu_error_checking
/*! \param value Value to set
	Sets the value of g_gpu_error_checking to enable or disable error checking on the GPU
*/
void set_gpu_error_checking(bool value)
	{
	g_gpu_error_checking = value;
	}

//! Method for getting the current version of HOOMD
/*! \returns Current HOOMD version identification string
*/
string get_hoomd_version()
	{
	ostringstream ver;
	// output the version info differently if this is tagged as a subversion build or not
	if (HOOMD_SUBVERSION_BUILD)
		ver << "HOOMD-blue svnversion " << HOOMD_SVNVERSION;
	else
		ver << "HOOMD-blue " << HOOMD_VERSION << endl;

	return ver.str();
	}

//! Create the python module
/*! each class setup their own python exports in a function export_ClassName
	create the hoomd python module and define the exports here.
*/
BOOST_PYTHON_MODULE(hoomd)
	{
	// write out the version information on the module import
	output_version_info(false);
	def("find_hoomd_data_dir", &find_hoomd_data_dir);
	def("find_vmd", &find_vmd);
	def("set_gpu_error_checking", &set_gpu_error_checking);
	def("get_hoomd_version", &get_hoomd_version);

	// data structures
	class_<std::vector<int> >("std_vector_int")
		.def(vector_indexing_suite<std::vector<int> >());

	InstallSIGINTHandler();

	// utils
	export_ClockSource();
	export_Profiler();

	// data structures
	export_BoxDim();
	export_ParticleDataInitializer();
	export_ParticleData();
	export_ExecutionConfiguration();
	export_BondData();
	export_AngleData();
	export_DihedralData();

	// initializers
	export_RandomInitializer();
	export_RandomInitializerWithWalls();
	export_SimpleCubicInitializer();
	export_HOOMDInitializer();
	export_RandomGenerator();

	// computes
	export_Compute();
	export_ForceCompute();
	export_ConstForceCompute();
	export_HarmonicBondForceCompute();
	export_HarmonicAngleForceCompute();
	export_HarmonicDihedralForceCompute();
	export_HarmonicImproperForceCompute();
	export_CGCMMAngleForceCompute();
	export_FENEBondForceCompute();
	export_LJForceCompute();
	export_CGCMMForceCompute();
	export_GaussianForceCompute();
	//export_YukawaForceCompute();
	export_LJWallForceCompute();
	export_TempCompute();
	export_NeighborList();
	export_BinnedNeighborList();
	#ifdef ENABLE_CUDA
	export_BinnedNeighborListGPU();
	export_NeighborListNsqGPU();
	export_LJForceComputeGPU();
	export_CGCMMForceComputeGPU();
	export_GaussianForceGPU();
	//export_YukawaForceComputeGPU();
	export_HarmonicBondForceComputeGPU();
	export_HarmonicAngleForceComputeGPU();
	export_HarmonicDihedralForceComputeGPU();
	export_HarmonicImproperForceComputeGPU();
	export_CGCMMAngleForceComputeGPU();
	export_FENEBondForceComputeGPU();
	#endif

	// analyzers
	export_Analyzer();
	export_IMDInterface();
	export_HOOMDDumpWriter();
	export_PDBDumpWriter();
	export_DCDDumpWriter();
	export_MOL2DumpWriter();
	export_Logger();
	export_MSDAnalyzer();
	export_ParticleGroup();

	// updaters
	export_Updater();
	export_Integrator();
	export_TempRescaleUpdater();
	export_ZeroMomentumUpdater();
	export_SFCPackUpdater();
	export_BoxResizeUpdater();
	export_NVTUpdater();
	export_NPTUpdater();
	export_NVEUpdater();
	export_BD_NVTUpdater();
	#ifdef ENABLE_CUDA
	export_NVEUpdaterGPU();
	export_NVTUpdaterGPU();
	export_NPTUpdaterGPU();
	export_BD_NVTUpdaterGPU();
	#endif

	// system
	export_System();

	// variant
	export_Variant();

	}

#ifdef WIN32
#pragma warning( pop )
#endif

<commit_msg>This should allow VMD 1.8.7 to be found. ticket #301<commit_after>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

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

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

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

* Neither the name of the copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND
CONTRIBUTORS ``AS IS''  AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS  BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

// $Id$
// $URL$
// Maintainer: joaander

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

// remove silly warnings
#ifdef WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif

#include "ClockSource.h"
#include "Profiler.h"
#include "ParticleData.h"
#include "BondData.h"
#include "AngleData.h"
#include "DihedralData.h"
#include "ExecutionConfiguration.h"
#include "Initializers.h"
#include "HOOMDInitializer.h"
#include "RandomGenerator.h"
#include "Compute.h"
#include "ForceCompute.h"
#include "ConstForceCompute.h"
#include "HarmonicBondForceCompute.h"
#include "HarmonicAngleForceCompute.h"
#include "HarmonicDihedralForceCompute.h"
#include "HarmonicImproperForceCompute.h"
#include "CGCMMAngleForceCompute.h"
#include "FENEBondForceCompute.h"
#include "LJForceCompute.h"
#include "CGCMMForceCompute.h"
#include "GaussianForceCompute.h"
//#include "YukawaForceCompute.h"
#include "LJWallForceCompute.h"
#include "TempCompute.h"
#include "NeighborList.h"
#include "BinnedNeighborList.h"
#include "Analyzer.h"
#include "IMDInterface.h"
#include "HOOMDDumpWriter.h"
#include "PDBDumpWriter.h"
#include "MOL2DumpWriter.h"
#include "DCDDumpWriter.h"
#include "Logger.h"
#include "MSDAnalyzer.h"
#include "Updater.h"
#include "Integrator.h"
#include "TempRescaleUpdater.h"
#include "ZeroMomentumUpdater.h"
#include "SFCPackUpdater.h"
#include "BoxResizeUpdater.h"
#include "NVTUpdater.h"
#include "NPTUpdater.h"
#include "NVEUpdater.h"
#include "BD_NVTUpdater.h"
#include "System.h"
#include "Variant.h"

// include GPU classes
#ifdef ENABLE_CUDA
#include "NVTUpdaterGPU.h"
#include "NVEUpdaterGPU.h"
#include "NPTUpdaterGPU.h"
#include "BD_NVTUpdaterGPU.h"
#include "BinnedNeighborListGPU.h"
#include "NeighborListNsqGPU.h"
#include "LJForceComputeGPU.h"
#include "CGCMMForceComputeGPU.h"
#include "GaussianForceGPU.h"
//#include "YukawaForceComputeGPU.h"
#include "StochasticForceComputeGPU.h"
#include "HarmonicBondForceComputeGPU.h"
#include "HarmonicAngleForceComputeGPU.h"
#include "HarmonicDihedralForceComputeGPU.h"
#include "HarmonicImproperForceComputeGPU.h"
#include "CGCMMAngleForceComputeGPU.h"
#include "FENEBondForceComputeGPU.h"
#endif

#include "SignalHandler.h"

#include "HOOMDVersion.h"

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>

using namespace boost::filesystem;
using namespace boost::python;

#include <iostream>
#include <sstream>
using namespace std;

// include gpu_settings.h for g_gpu_error_checking
#ifdef ENABLE_CUDA
#include "gpu_settings.h"
#else
// otherwise, we need a dummy variable that will do nothing
bool g_gpu_error_checking = false;
#endif

/*! \file hoomd_module.cc
	\brief Brings all of the export_* functions together to export the hoomd python module
*/

//! Scans for possible hoomd data directories
/*! \returns the first one it finds
	This function is for use by the demos and benchmarks installed with HOOMD.
*/
string find_hoomd_data_dir()
	{
	// try checking offsets from the environment variable first:
	// it is searched first so as to override any other potential location
	if (getenv("HOOMD_ROOT"))
		{
		path hoomd_root_dir = path(string(getenv("HOOMD_ROOT")));
		// try root/share/hoomd (for /usr/local /usr etc)
		if (exists(hoomd_root_dir / "share" / "hoomd" / "hoomd_data_dir"))
			{
			string result = (hoomd_root_dir / "share" / "hoomd").string();
			return result;
			}
		// try root/share (for /opt/hoomd style install)
		if (exists(hoomd_root_dir / "share" / "hoomd_data_dir"))
			{
			string result = (hoomd_root_dir / "share").string();
			return result;
			}
		}

	// as a final fallback: try the source directory
	if (exists(path(HOOMD_SOURCE_DIR) / "share" / "hoomd" / "hoomd_data_dir"))
		return (path(HOOMD_SOURCE_DIR) / "share" / "hoomd").string();

	#ifdef WIN32
	// access the registry key
	string name = string("hoomd ") + string(HOOMD_VERSION);
	string reg_path = "SOFTWARE\\Ames Laboratory Iowa State University\\" + name;

	char *value = new char[1024];
	LONG value_size = 1024;
	LONG err_code = RegQueryValue(HKEY_LOCAL_MACHINE, reg_path.c_str(), value, &value_size);
	// see if it installed where the reg key says so
	if (err_code == ERROR_SUCCESS)
		{
		path install_dir = path(string(value));
		if (exists(install_dir / "hoomd_data_dir"))
			return (install_dir).string();
		}
	delete[] value;

	// otherwise, check the program files root
	if (getenv("PROGRAMFILES"))
		{
		path program_files_dir = path(string(getenv("PROGRAMFILES")));
		if (exists(program_files_dir / "hoomd" / "hoomd_data_dir"))
			return (program_files_dir / "hoomd").string();
		}
	#else
	// check a few likely installation locations
	if (exists("/usr/share/hoomd/hoomd_data_dir"))
		return "/usr/share/hoomd";
	if (exists("/usr/local/share/hoomd/hoomd_data_dir"))
		return "/usr/local/share/hoomd";
	if (exists("/opt/hoomd/share/hoomd_data_dir"))
		return "/opt/hoomd/share";
	#endif

	cerr << endl << "***Error! HOOMD data directory not found, please set the environment variable HOOMD_ROOT" << endl << endl;
	return string("");
	}

//! Scans for a VMD installation
/*! \returns Full path to the vmd executable
	This function is for use by the demos and benchmarks installed with HOOMD.
*/
string find_vmd()
	{
	#ifdef WIN32

	// find VMD through the registry
	vector<string> reg_paths;
	reg_paths.push_back("SOFTWARE\\University of Illinois\\VMD\\1.8.7");
	reg_paths.push_back("SOFTWARE\\University of Illinois\\VMD\\1.8.6");

	vector<string>::iterator cur_path;
	for (cur_path = reg_paths.begin(); cur_path != reg_paths.end(); ++cur_path)
		{
		string reg_path = *cur_path;

		char *value = new char[1024];
		DWORD value_size = 1024;
		HKEY vmd_root_key;
		LONG err_code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_path.c_str(), 0, KEY_READ, &vmd_root_key);
		if (err_code == ERROR_SUCCESS)
			{
			err_code = RegQueryValueEx(vmd_root_key, "VMDDIR", NULL, NULL, (LPBYTE)value, &value_size);
			// see if it installed where the reg key says so
			if (err_code == ERROR_SUCCESS)
				{
				path install_dir = path(string(value));
				if (exists(install_dir / "vmd.exe"))
					return (install_dir / "vmd.exe").string();
				}
			}
		delete[] value;
		}

	#else
	// check some likely locations
	if (exists("/usr/bin/vmd"))
		return "/usr/bin/vmd";
	if (exists("/usr/local/bin/vmd"))
		return "/usr/local/bin/vmd";
	if (exists("/opt/vmd/bin/vmd"))
		return "/opt/vmd/bin/vmd";
	if (exists(path("/Applications/3rd Party Apps/VMD 1.8.7.app/Contents/Resources/VMD.app/Contents/MacOS/VMD", no_check )))
		return("/Applications/3rd Party Apps/VMD 1.8.7.app/Contents/Resources/VMD.app/Contents/MacOS/VMD");
	if (exists(path("/Applications/VMD 1.8.7.app/Contents/Resources/VMD.app/Contents/MacOS/VMD", no_check)))
		return("/Applications/VMD 1.8.7.app/Contents/Resources/VMD.app/Contents/MacOS/VMD");
	if (exists(path("/Applications/3rd Party Apps/VMD 1.8.6.app/Contents/Resources/VMD.app/Contents/MacOS/VMD", no_check )))
		return("/Applications/3rd Party Apps/VMD 1.8.6.app/Contents/Resources/VMD.app/Contents/MacOS/VMD");
	if (exists(path("/Applications/VMD 1.8.6.app/Contents/Resources/VMD.app/Contents/MacOS/VMD", no_check)))
		return("/Applications/VMD 1.8.6.app/Contents/Resources/VMD.app/Contents/MacOS/VMD");
	#endif

	// return an empty string if we didn't find it
	return "";
	}

//! Method for setting g_gpu_error_checking
/*! \param value Value to set
	Sets the value of g_gpu_error_checking to enable or disable error checking on the GPU
*/
void set_gpu_error_checking(bool value)
	{
	g_gpu_error_checking = value;
	}

//! Method for getting the current version of HOOMD
/*! \returns Current HOOMD version identification string
*/
string get_hoomd_version()
	{
	ostringstream ver;
	// output the version info differently if this is tagged as a subversion build or not
	if (HOOMD_SUBVERSION_BUILD)
		ver << "HOOMD-blue svnversion " << HOOMD_SVNVERSION;
	else
		ver << "HOOMD-blue " << HOOMD_VERSION << endl;

	return ver.str();
	}

//! Create the python module
/*! each class setup their own python exports in a function export_ClassName
	create the hoomd python module and define the exports here.
*/
BOOST_PYTHON_MODULE(hoomd)
	{
	// write out the version information on the module import
	output_version_info(false);
	def("find_hoomd_data_dir", &find_hoomd_data_dir);
	def("find_vmd", &find_vmd);
	def("set_gpu_error_checking", &set_gpu_error_checking);
	def("get_hoomd_version", &get_hoomd_version);

	// data structures
	class_<std::vector<int> >("std_vector_int")
		.def(vector_indexing_suite<std::vector<int> >());

	InstallSIGINTHandler();

	// utils
	export_ClockSource();
	export_Profiler();

	// data structures
	export_BoxDim();
	export_ParticleDataInitializer();
	export_ParticleData();
	export_ExecutionConfiguration();
	export_BondData();
	export_AngleData();
	export_DihedralData();

	// initializers
	export_RandomInitializer();
	export_RandomInitializerWithWalls();
	export_SimpleCubicInitializer();
	export_HOOMDInitializer();
	export_RandomGenerator();

	// computes
	export_Compute();
	export_ForceCompute();
	export_ConstForceCompute();
	export_HarmonicBondForceCompute();
	export_HarmonicAngleForceCompute();
	export_HarmonicDihedralForceCompute();
	export_HarmonicImproperForceCompute();
	export_CGCMMAngleForceCompute();
	export_FENEBondForceCompute();
	export_LJForceCompute();
	export_CGCMMForceCompute();
	export_GaussianForceCompute();
	//export_YukawaForceCompute();
	export_LJWallForceCompute();
	export_TempCompute();
	export_NeighborList();
	export_BinnedNeighborList();
	#ifdef ENABLE_CUDA
	export_BinnedNeighborListGPU();
	export_NeighborListNsqGPU();
	export_LJForceComputeGPU();
	export_CGCMMForceComputeGPU();
	export_GaussianForceGPU();
	//export_YukawaForceComputeGPU();
	export_HarmonicBondForceComputeGPU();
	export_HarmonicAngleForceComputeGPU();
	export_HarmonicDihedralForceComputeGPU();
	export_HarmonicImproperForceComputeGPU();
	export_CGCMMAngleForceComputeGPU();
	export_FENEBondForceComputeGPU();
	#endif

	// analyzers
	export_Analyzer();
	export_IMDInterface();
	export_HOOMDDumpWriter();
	export_PDBDumpWriter();
	export_DCDDumpWriter();
	export_MOL2DumpWriter();
	export_Logger();
	export_MSDAnalyzer();
	export_ParticleGroup();

	// updaters
	export_Updater();
	export_Integrator();
	export_TempRescaleUpdater();
	export_ZeroMomentumUpdater();
	export_SFCPackUpdater();
	export_BoxResizeUpdater();
	export_NVTUpdater();
	export_NPTUpdater();
	export_NVEUpdater();
	export_BD_NVTUpdater();
	#ifdef ENABLE_CUDA
	export_NVEUpdaterGPU();
	export_NVTUpdaterGPU();
	export_NPTUpdaterGPU();
	export_BD_NVTUpdaterGPU();
	#endif

	// system
	export_System();

	// variant
	export_Variant();

	}

#ifdef WIN32
#pragma warning( pop )
#endif

<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2006 Matthias Kretz <kretz@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2
    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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.

*/

#include "outputdevicechoice.h"
#include <phonon/backendcapabilities.h>
#include <phonon/objectdescription.h>
#include <phonon/phononnamespace.h>
#include <klocale.h>
#include <QHeaderView>
#include <ksimpleconfig.h>
#include <phonon/alsadeviceenumerator.h>
#include <phonon/alsadevice.h>
#include <QList>

class CategoryItem : public QStandardItem {
    public:
        CategoryItem(Phonon::Category cat)
            : QStandardItem(Phonon::categoryToString(cat)),
            m_cat(cat)
        {
        }

        int type() const { return 1001; }
        Phonon::Category category() const { return m_cat; }

    private:
        Phonon::Category m_cat;
};
OutputDeviceChoice::OutputDeviceChoice(QWidget *parent)
    : QWidget(parent)
{
    setupUi(this);
    QStandardItem *parentItem = m_categoryModel.invisibleRootItem();
    QStandardItem *outputItem = new QStandardItem(i18n("Audio Output"));
    outputItem->setSelectable(false);
    parentItem->appendRow(outputItem);
    QStandardItem *captureItem = new QStandardItem(i18n("Audio Capture"));
    parentItem->appendRow(captureItem);

    parentItem = outputItem;
    for (int i = 0; i < Phonon::LastCategory; ++i) {
        m_outputModel[i] = new Phonon::AudioOutputDeviceModel;
        QStandardItem *item = new CategoryItem(static_cast<Phonon::Category>(i));
        parentItem->appendRow(item);
    }
    parentItem = captureItem;

    categoryTree->setModel(&m_categoryModel);
    if (categoryTree->header()) {
        categoryTree->header()->hide();
    }
    categoryTree->expandAll();

    connect(categoryTree->selectionModel(),
            SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
            SLOT(updateDeviceList()));
}

void OutputDeviceChoice::updateDeviceList()
{
    kDebug() << k_funcinfo << endl;
    QStandardItem *currentItem = m_categoryModel.itemFromIndex(categoryTree->currentIndex());
    if (currentItem->type() == 1001) {
        if (deviceList->selectionModel()) {
            disconnect(deviceList->selectionModel(),
                    SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
                    this, SLOT(updateButtonsEnabled()));
        }
        CategoryItem *catItem = static_cast<CategoryItem*>(currentItem);
        deviceList->setModel(m_outputModel[catItem->category()]);
        connect(deviceList->selectionModel(),
                SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
                this, SLOT(updateButtonsEnabled()));
    } else {
        if (deviceList->selectionModel()) {
            disconnect(deviceList->selectionModel(),
                    SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
                    this, SLOT(updateButtonsEnabled()));
        }
        deviceList->setModel(&m_captureModel);
        connect(deviceList->selectionModel(),
                SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
                this, SLOT(updateButtonsEnabled()));
    }
}

void OutputDeviceChoice::load()
{
    KSimpleConfig phononrc("phononrc", true);
    KConfigGroup outputDeviceGroup(&phononrc, QLatin1String("AudioOutputDevice"));
    KConfigGroup captureDeviceGroup(&phononrc, QLatin1String("AudioCaptureDevice"));

    QList<Phonon::AudioOutputDevice> list = Phonon::BackendCapabilities::availableAudioOutputDevices();
    QHash<int, Phonon::AudioOutputDevice> hash;
    foreach (Phonon::AudioOutputDevice dev, list) {
        hash.insert(dev.index(), dev);
    }
    for (int i = 0; i < Phonon::LastCategory; ++i) {
        QHash<int, Phonon::AudioOutputDevice> hashCopy(hash);
        QList<int> order = outputDeviceGroup.readEntry<QList<int> >(QLatin1String("Category") + QString::number(i), QList<int>());
        QList<Phonon::AudioOutputDevice> orderedList;
        foreach (int idx, order) {
            if (hashCopy.contains(idx)) {
                orderedList << hashCopy.take(idx);
            }
            //} else {
                //orderedList << Phonon::AudioOutputDevice();
            //}
        }
        foreach (Phonon::AudioOutputDevice dev, hashCopy) {
            orderedList << dev;
        }
        m_outputModel[i]->setModelData(orderedList);
    }

    QList<Phonon::AudioCaptureDevice> list2 = Phonon::BackendCapabilities::availableAudioCaptureDevices();
    QList<int> order = captureDeviceGroup.readEntry<QList<int> >(QLatin1String("DeviceOrder"), QList<int>());
    QList<Phonon::AudioCaptureDevice> orderedList;
    foreach (int idx, order) {
        for (int i = 0; i < list2.size(); ++i) {
            if (list2.at(i).index() == idx) {
                orderedList << list2.takeAt(i);
                break; // out of the inner for loop to get the next idx
            }
        }
    }
    m_captureModel.setModelData(orderedList);
}

void OutputDeviceChoice::save()
{
    kDebug() << k_funcinfo << endl;
    KSimpleConfig config("phononrc");
    {
        KConfigGroup globalGroup(&config, QLatin1String("AudioOutputDevice"));
        for (int i = 0; i < Phonon::LastCategory; ++i) {
            if (m_outputModel.value(i)) {
                globalGroup.writeEntry(QLatin1String("Category") + QString::number(i), m_outputModel.value(i)->tupleIndexOrder());
            }
        }
    }
    {
        KConfigGroup globalGroup(&config, QLatin1String("AudioCaptureDevice"));
        globalGroup.writeEntry(QLatin1String("DeviceOrder"), m_captureModel.tupleIndexOrder());
    }
}

void OutputDeviceChoice::defaults()
{
    QList<Phonon::AudioOutputDevice> list = Phonon::BackendCapabilities::availableAudioOutputDevices();
    for (int i = 0; i < Phonon::LastCategory; ++i) {
        m_outputModel[i]->setModelData(list);
    }

    QList<Phonon::AudioCaptureDevice> list2 = Phonon::BackendCapabilities::availableAudioCaptureDevices();
    m_captureModel.setModelData(list2);
}

void OutputDeviceChoice::on_preferButton_clicked()
{
    QAbstractItemModel *model = deviceList->model();
    Phonon::AudioOutputDeviceModel *deviceModel = qobject_cast<Phonon::AudioOutputDeviceModel*>(model);
    if (deviceModel) {
        deviceModel->moveUp(deviceList->currentIndex());
        updateButtonsEnabled();
        emit changed();
    }
}

void OutputDeviceChoice::on_deferButton_clicked()
{
    QAbstractItemModel *model = deviceList->model();
    Phonon::AudioOutputDeviceModel *deviceModel = qobject_cast<Phonon::AudioOutputDeviceModel*>(model);
    if (deviceModel) {
        deviceModel->moveDown(deviceList->currentIndex());
        updateButtonsEnabled();
        emit changed();
    }
}
void OutputDeviceChoice::on_removeButton_clicked()
{
    QModelIndex idx = deviceList->currentIndex();

    QAbstractItemModel *model = deviceList->model();
    Phonon::AudioOutputDeviceModel *playbackModel = qobject_cast<Phonon::AudioOutputDeviceModel*>(model);
    if (playbackModel && idx.isValid()) {
        Phonon::AudioOutputDevice deviceToRemove = playbackModel->modelData(idx);
        QList<Phonon::AlsaDevice> deviceList = Phonon::AlsaDeviceEnumerator::availablePlaybackDevices();
        foreach (Phonon::AlsaDevice dev, deviceList) {
            if (dev.index() == deviceToRemove.index()) {
                // remove from persistent store
                if (dev.ceaseToExist()) {
                    // remove from all models
                    foreach (Phonon::AudioOutputDeviceModel *model, m_outputModel) {
                        QList<Phonon::AudioOutputDevice> data = model->modelData();
                        data.removeAll(deviceToRemove);
                        model->setModelData(data);
                    }
                    updateButtonsEnabled();
                    emit changed();
                }
            }
        }
    } else {
        Phonon::AudioCaptureDeviceModel *captureModel = qobject_cast<Phonon::AudioCaptureDeviceModel*>(model);
        if (captureModel && idx.isValid()) {
            Phonon::AudioCaptureDevice deviceToRemove = captureModel->modelData(idx);
            QList<Phonon::AlsaDevice> deviceList = Phonon::AlsaDeviceEnumerator::availableCaptureDevices();
            foreach (Phonon::AlsaDevice dev, deviceList) {
                if (dev.index() == deviceToRemove.index()) {
                    // remove from persistent store
                    if (dev.ceaseToExist()) {
                        QList<Phonon::AudioCaptureDevice> data = m_captureModel.modelData();
                        data.removeAll(deviceToRemove);
                        m_captureModel.setModelData(data);
                        updateButtonsEnabled();
                        emit changed();
                    }
                }
            }
        }
    }
}

void OutputDeviceChoice::updateButtonsEnabled()
{
    kDebug() << k_funcinfo << endl;
    if (deviceList->model()) {
        kDebug() << "model available" << endl;
        QModelIndex idx = deviceList->currentIndex();
        preferButton->setEnabled(idx.isValid() && idx.row() > 0);
        deferButton->setEnabled(idx.isValid() && idx.row() < deviceList->model()->rowCount() - 1);
        removeButton->setEnabled(idx.isValid() && !(idx.flags() & Qt::ItemIsEnabled));
    } else {
        preferButton->setEnabled(false);
        deferButton->setEnabled(false);
        removeButton->setEnabled(false);
    }
}

#include "outputdevicechoice.moc"
// vim: sw=4 ts=4
<commit_msg>compile fix<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2006 Matthias Kretz <kretz@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2
    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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.

*/

#include "outputdevicechoice.h"
#include <phonon/backendcapabilities.h>
#include <phonon/objectdescription.h>
#include <phonon/phononnamespace.h>
#include <klocale.h>
#include <QHeaderView>
#include <ksimpleconfig.h>
#include <phonon/alsadevicelist/alsadeviceenumerator.h>
#include <phonon/alsadevicelist/alsadevice.h>
#include <QList>

class CategoryItem : public QStandardItem {
    public:
        CategoryItem(Phonon::Category cat)
            : QStandardItem(Phonon::categoryToString(cat)),
            m_cat(cat)
        {
        }

        int type() const { return 1001; }
        Phonon::Category category() const { return m_cat; }

    private:
        Phonon::Category m_cat;
};
OutputDeviceChoice::OutputDeviceChoice(QWidget *parent)
    : QWidget(parent)
{
    setupUi(this);
    QStandardItem *parentItem = m_categoryModel.invisibleRootItem();
    QStandardItem *outputItem = new QStandardItem(i18n("Audio Output"));
    outputItem->setSelectable(false);
    parentItem->appendRow(outputItem);
    QStandardItem *captureItem = new QStandardItem(i18n("Audio Capture"));
    parentItem->appendRow(captureItem);

    parentItem = outputItem;
    for (int i = 0; i < Phonon::LastCategory; ++i) {
        m_outputModel[i] = new Phonon::AudioOutputDeviceModel;
        QStandardItem *item = new CategoryItem(static_cast<Phonon::Category>(i));
        parentItem->appendRow(item);
    }
    parentItem = captureItem;

    categoryTree->setModel(&m_categoryModel);
    if (categoryTree->header()) {
        categoryTree->header()->hide();
    }
    categoryTree->expandAll();

    connect(categoryTree->selectionModel(),
            SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
            SLOT(updateDeviceList()));
}

void OutputDeviceChoice::updateDeviceList()
{
    kDebug() << k_funcinfo << endl;
    QStandardItem *currentItem = m_categoryModel.itemFromIndex(categoryTree->currentIndex());
    if (currentItem->type() == 1001) {
        if (deviceList->selectionModel()) {
            disconnect(deviceList->selectionModel(),
                    SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
                    this, SLOT(updateButtonsEnabled()));
        }
        CategoryItem *catItem = static_cast<CategoryItem*>(currentItem);
        deviceList->setModel(m_outputModel[catItem->category()]);
        connect(deviceList->selectionModel(),
                SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
                this, SLOT(updateButtonsEnabled()));
    } else {
        if (deviceList->selectionModel()) {
            disconnect(deviceList->selectionModel(),
                    SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
                    this, SLOT(updateButtonsEnabled()));
        }
        deviceList->setModel(&m_captureModel);
        connect(deviceList->selectionModel(),
                SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)),
                this, SLOT(updateButtonsEnabled()));
    }
}

void OutputDeviceChoice::load()
{
    KSimpleConfig phononrc("phononrc", true);
    KConfigGroup outputDeviceGroup(&phononrc, QLatin1String("AudioOutputDevice"));
    KConfigGroup captureDeviceGroup(&phononrc, QLatin1String("AudioCaptureDevice"));

    QList<Phonon::AudioOutputDevice> list = Phonon::BackendCapabilities::availableAudioOutputDevices();
    QHash<int, Phonon::AudioOutputDevice> hash;
    foreach (Phonon::AudioOutputDevice dev, list) {
        hash.insert(dev.index(), dev);
    }
    for (int i = 0; i < Phonon::LastCategory; ++i) {
        QHash<int, Phonon::AudioOutputDevice> hashCopy(hash);
        QList<int> order = outputDeviceGroup.readEntry<QList<int> >(QLatin1String("Category") + QString::number(i), QList<int>());
        QList<Phonon::AudioOutputDevice> orderedList;
        foreach (int idx, order) {
            if (hashCopy.contains(idx)) {
                orderedList << hashCopy.take(idx);
            }
            //} else {
                //orderedList << Phonon::AudioOutputDevice();
            //}
        }
        foreach (Phonon::AudioOutputDevice dev, hashCopy) {
            orderedList << dev;
        }
        m_outputModel[i]->setModelData(orderedList);
    }

    QList<Phonon::AudioCaptureDevice> list2 = Phonon::BackendCapabilities::availableAudioCaptureDevices();
    QList<int> order = captureDeviceGroup.readEntry<QList<int> >(QLatin1String("DeviceOrder"), QList<int>());
    QList<Phonon::AudioCaptureDevice> orderedList;
    foreach (int idx, order) {
        for (int i = 0; i < list2.size(); ++i) {
            if (list2.at(i).index() == idx) {
                orderedList << list2.takeAt(i);
                break; // out of the inner for loop to get the next idx
            }
        }
    }
    m_captureModel.setModelData(orderedList);
}

void OutputDeviceChoice::save()
{
    kDebug() << k_funcinfo << endl;
    KSimpleConfig config("phononrc");
    {
        KConfigGroup globalGroup(&config, QLatin1String("AudioOutputDevice"));
        for (int i = 0; i < Phonon::LastCategory; ++i) {
            if (m_outputModel.value(i)) {
                globalGroup.writeEntry(QLatin1String("Category") + QString::number(i), m_outputModel.value(i)->tupleIndexOrder());
            }
        }
    }
    {
        KConfigGroup globalGroup(&config, QLatin1String("AudioCaptureDevice"));
        globalGroup.writeEntry(QLatin1String("DeviceOrder"), m_captureModel.tupleIndexOrder());
    }
}

void OutputDeviceChoice::defaults()
{
    QList<Phonon::AudioOutputDevice> list = Phonon::BackendCapabilities::availableAudioOutputDevices();
    for (int i = 0; i < Phonon::LastCategory; ++i) {
        m_outputModel[i]->setModelData(list);
    }

    QList<Phonon::AudioCaptureDevice> list2 = Phonon::BackendCapabilities::availableAudioCaptureDevices();
    m_captureModel.setModelData(list2);
}

void OutputDeviceChoice::on_preferButton_clicked()
{
    QAbstractItemModel *model = deviceList->model();
    Phonon::AudioOutputDeviceModel *deviceModel = qobject_cast<Phonon::AudioOutputDeviceModel*>(model);
    if (deviceModel) {
        deviceModel->moveUp(deviceList->currentIndex());
        updateButtonsEnabled();
        emit changed();
    }
}

void OutputDeviceChoice::on_deferButton_clicked()
{
    QAbstractItemModel *model = deviceList->model();
    Phonon::AudioOutputDeviceModel *deviceModel = qobject_cast<Phonon::AudioOutputDeviceModel*>(model);
    if (deviceModel) {
        deviceModel->moveDown(deviceList->currentIndex());
        updateButtonsEnabled();
        emit changed();
    }
}
void OutputDeviceChoice::on_removeButton_clicked()
{
    QModelIndex idx = deviceList->currentIndex();

    QAbstractItemModel *model = deviceList->model();
    Phonon::AudioOutputDeviceModel *playbackModel = qobject_cast<Phonon::AudioOutputDeviceModel*>(model);
    if (playbackModel && idx.isValid()) {
        Phonon::AudioOutputDevice deviceToRemove = playbackModel->modelData(idx);
        QList<Phonon::AlsaDevice> deviceList = Phonon::AlsaDeviceEnumerator::availablePlaybackDevices();
        foreach (Phonon::AlsaDevice dev, deviceList) {
            if (dev.index() == deviceToRemove.index()) {
                // remove from persistent store
                if (dev.ceaseToExist()) {
                    // remove from all models
                    foreach (Phonon::AudioOutputDeviceModel *model, m_outputModel) {
                        QList<Phonon::AudioOutputDevice> data = model->modelData();
                        data.removeAll(deviceToRemove);
                        model->setModelData(data);
                    }
                    updateButtonsEnabled();
                    emit changed();
                }
            }
        }
    } else {
        Phonon::AudioCaptureDeviceModel *captureModel = qobject_cast<Phonon::AudioCaptureDeviceModel*>(model);
        if (captureModel && idx.isValid()) {
            Phonon::AudioCaptureDevice deviceToRemove = captureModel->modelData(idx);
            QList<Phonon::AlsaDevice> deviceList = Phonon::AlsaDeviceEnumerator::availableCaptureDevices();
            foreach (Phonon::AlsaDevice dev, deviceList) {
                if (dev.index() == deviceToRemove.index()) {
                    // remove from persistent store
                    if (dev.ceaseToExist()) {
                        QList<Phonon::AudioCaptureDevice> data = m_captureModel.modelData();
                        data.removeAll(deviceToRemove);
                        m_captureModel.setModelData(data);
                        updateButtonsEnabled();
                        emit changed();
                    }
                }
            }
        }
    }
}

void OutputDeviceChoice::updateButtonsEnabled()
{
    kDebug() << k_funcinfo << endl;
    if (deviceList->model()) {
        kDebug() << "model available" << endl;
        QModelIndex idx = deviceList->currentIndex();
        preferButton->setEnabled(idx.isValid() && idx.row() > 0);
        deferButton->setEnabled(idx.isValid() && idx.row() < deviceList->model()->rowCount() - 1);
        removeButton->setEnabled(idx.isValid() && !(idx.flags() & Qt::ItemIsEnabled));
    } else {
        preferButton->setEnabled(false);
        deferButton->setEnabled(false);
        removeButton->setEnabled(false);
    }
}

#include "outputdevicechoice.moc"
// vim: sw=4 ts=4
<|endoftext|>


<commit_before>// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include "datastore.hpp"
#include "entry_comparator_wrapper.h"
#include "i_compactable.h"
#include "unique_store_add_result.h"
#include "unique_store_dictionary.h"
#include <vespa/vespalib/btree/btree.hpp>
#include <vespa/vespalib/btree/btreebuilder.hpp>
#include <vespa/vespalib/btree/btreeiterator.hpp>
#include <vespa/vespalib/btree/btreenode.hpp>
#include <vespa/vespalib/btree/btreenodeallocator.hpp>
#include <vespa/vespalib/btree/btreeroot.hpp>

namespace search::datastore {

template <typename DictionaryT, typename ParentT>
UniqueStoreDictionary<DictionaryT, ParentT>::
ReadSnapshotImpl::ReadSnapshotImpl(FrozenView frozen_view)
    : _frozen_view(frozen_view)
{
}

template <typename DictionaryT, typename ParentT>
size_t
UniqueStoreDictionary<DictionaryT, ParentT>::
ReadSnapshotImpl::count(const EntryComparator& comp) const
{
    auto itr = _frozen_view.lowerBound(EntryRef(), comp);
    if (itr.valid() && !comp(EntryRef(), itr.getKey())) {
        return 1u;
    }
    return 0u;
}

template <typename DictionaryT, typename ParentT>
size_t
UniqueStoreDictionary<DictionaryT, ParentT>::
ReadSnapshotImpl::count_in_range(const EntryComparator& low,
                                 const EntryComparator& high) const
{
    auto low_itr = _frozen_view.lowerBound(EntryRef(), low);
    auto high_itr = low_itr;
    if (high_itr.valid() && !high(EntryRef(), high_itr.getKey())) {
        high_itr.seekPast(EntryRef(), high);
    }
    return high_itr - low_itr;
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::
ReadSnapshotImpl::foreach_key(std::function<void(EntryRef)> callback) const
{
    _frozen_view.foreach_key(callback);
}

template <typename DictionaryT, typename ParentT>
UniqueStoreDictionary<DictionaryT, ParentT>::UniqueStoreDictionary()
    : ParentT(),
      _dict()
{
}

template <typename DictionaryT, typename ParentT>
UniqueStoreDictionary<DictionaryT, ParentT>::~UniqueStoreDictionary() = default;

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::freeze()
{
    _dict.getAllocator().freeze();
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::transfer_hold_lists(generation_t generation)
{
    _dict.getAllocator().transferHoldLists(generation);
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::trim_hold_lists(generation_t firstUsed)
{
    _dict.getAllocator().trimHoldLists(firstUsed);
}

template <typename DictionaryT, typename ParentT>
UniqueStoreAddResult
UniqueStoreDictionary<DictionaryT, ParentT>::add(const EntryComparator &comp,
                                                 std::function<EntryRef(void)> insertEntry)
{
    auto itr = _dict.lowerBound(EntryRef(), comp);
    if (itr.valid() && !comp(EntryRef(), itr.getKey())) {
        return UniqueStoreAddResult(itr.getKey(), false);

    } else {
        EntryRef newRef = insertEntry();
        _dict.insert(itr, newRef, DataType());
        return UniqueStoreAddResult(newRef, true);
    }
}

template <typename DictionaryT, typename ParentT>
EntryRef
UniqueStoreDictionary<DictionaryT, ParentT>::find(const EntryComparator &comp)
{
    auto itr = _dict.lowerBound(EntryRef(), comp);
    if (itr.valid() && !comp(EntryRef(), itr.getKey())) {
        return itr.getKey();
    } else {
        return EntryRef();
    }
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::remove(const EntryComparator &comp, EntryRef ref)
{
    assert(ref.valid());
    auto itr = _dict.lowerBound(ref, comp);
    assert(itr.valid() && itr.getKey() == ref);
    _dict.remove(itr);
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::move_entries(ICompactable &compactable)
{
    auto itr = _dict.begin();
    while (itr.valid()) {
        EntryRef oldRef(itr.getKey());
        EntryRef newRef(compactable.move(oldRef));
        if (newRef != oldRef) {
            _dict.thaw(itr);
            itr.writeKey(newRef);
        }
        ++itr;
    }
}

template <typename DictionaryT, typename ParentT>
uint32_t
UniqueStoreDictionary<DictionaryT, ParentT>::get_num_uniques() const
{
    return _dict.getFrozenView().size();
}

template <typename DictionaryT, typename ParentT>
vespalib::MemoryUsage
UniqueStoreDictionary<DictionaryT, ParentT>::get_memory_usage() const
{
    return _dict.getMemoryUsage();
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::build(const std::vector<EntryRef> &refs,
                                                   const std::vector<uint32_t> &ref_counts,
                                                   std::function<void(EntryRef)> hold)
{
    assert(refs.size() == ref_counts.size());
    assert(!refs.empty());
    typename DictionaryType::Builder builder(_dict.getAllocator());
    for (size_t i = 1; i < refs.size(); ++i) {
        if (ref_counts[i] != 0u) {
            builder.insert(refs[i], DataType());
        } else {
            hold(refs[i]);
        }
    }
    _dict.assign(builder);
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::build(vespalib::ConstArrayRef<EntryRef> refs)
{
    typename DictionaryType::Builder builder(_dict.getAllocator());
    for (const auto& ref : refs) {
        builder.insert(ref, DataType());
    }
    _dict.assign(builder);
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::build_with_payload(const std::vector<EntryRef>& refs,
                                                                const std::vector<uint32_t>& payloads)
{
    assert(refs.size() == payloads.size());
    typename DictionaryType::Builder builder(_dict.getAllocator());
    for (size_t i = 0; i < refs.size(); ++i) {
        if constexpr (std::is_same_v<DataType, uint32_t>) {
            builder.insert(refs[i], payloads[i]);
        } else {
            builder.insert(refs[i], DataType());
        }
    }
    _dict.assign(builder);
}

template <typename DictionaryT, typename ParentT>
std::unique_ptr<typename ParentT::ReadSnapshot>
UniqueStoreDictionary<DictionaryT, ParentT>::get_read_snapshot() const
{
    return std::make_unique<ReadSnapshotImpl>(_dict.getFrozenView());
}

}
<commit_msg>Don't use frozen view when getting number of unique values.<commit_after>// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include "datastore.hpp"
#include "entry_comparator_wrapper.h"
#include "i_compactable.h"
#include "unique_store_add_result.h"
#include "unique_store_dictionary.h"
#include <vespa/vespalib/btree/btree.hpp>
#include <vespa/vespalib/btree/btreebuilder.hpp>
#include <vespa/vespalib/btree/btreeiterator.hpp>
#include <vespa/vespalib/btree/btreenode.hpp>
#include <vespa/vespalib/btree/btreenodeallocator.hpp>
#include <vespa/vespalib/btree/btreeroot.hpp>

namespace search::datastore {

template <typename DictionaryT, typename ParentT>
UniqueStoreDictionary<DictionaryT, ParentT>::
ReadSnapshotImpl::ReadSnapshotImpl(FrozenView frozen_view)
    : _frozen_view(frozen_view)
{
}

template <typename DictionaryT, typename ParentT>
size_t
UniqueStoreDictionary<DictionaryT, ParentT>::
ReadSnapshotImpl::count(const EntryComparator& comp) const
{
    auto itr = _frozen_view.lowerBound(EntryRef(), comp);
    if (itr.valid() && !comp(EntryRef(), itr.getKey())) {
        return 1u;
    }
    return 0u;
}

template <typename DictionaryT, typename ParentT>
size_t
UniqueStoreDictionary<DictionaryT, ParentT>::
ReadSnapshotImpl::count_in_range(const EntryComparator& low,
                                 const EntryComparator& high) const
{
    auto low_itr = _frozen_view.lowerBound(EntryRef(), low);
    auto high_itr = low_itr;
    if (high_itr.valid() && !high(EntryRef(), high_itr.getKey())) {
        high_itr.seekPast(EntryRef(), high);
    }
    return high_itr - low_itr;
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::
ReadSnapshotImpl::foreach_key(std::function<void(EntryRef)> callback) const
{
    _frozen_view.foreach_key(callback);
}

template <typename DictionaryT, typename ParentT>
UniqueStoreDictionary<DictionaryT, ParentT>::UniqueStoreDictionary()
    : ParentT(),
      _dict()
{
}

template <typename DictionaryT, typename ParentT>
UniqueStoreDictionary<DictionaryT, ParentT>::~UniqueStoreDictionary() = default;

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::freeze()
{
    _dict.getAllocator().freeze();
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::transfer_hold_lists(generation_t generation)
{
    _dict.getAllocator().transferHoldLists(generation);
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::trim_hold_lists(generation_t firstUsed)
{
    _dict.getAllocator().trimHoldLists(firstUsed);
}

template <typename DictionaryT, typename ParentT>
UniqueStoreAddResult
UniqueStoreDictionary<DictionaryT, ParentT>::add(const EntryComparator &comp,
                                                 std::function<EntryRef(void)> insertEntry)
{
    auto itr = _dict.lowerBound(EntryRef(), comp);
    if (itr.valid() && !comp(EntryRef(), itr.getKey())) {
        return UniqueStoreAddResult(itr.getKey(), false);

    } else {
        EntryRef newRef = insertEntry();
        _dict.insert(itr, newRef, DataType());
        return UniqueStoreAddResult(newRef, true);
    }
}

template <typename DictionaryT, typename ParentT>
EntryRef
UniqueStoreDictionary<DictionaryT, ParentT>::find(const EntryComparator &comp)
{
    auto itr = _dict.lowerBound(EntryRef(), comp);
    if (itr.valid() && !comp(EntryRef(), itr.getKey())) {
        return itr.getKey();
    } else {
        return EntryRef();
    }
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::remove(const EntryComparator &comp, EntryRef ref)
{
    assert(ref.valid());
    auto itr = _dict.lowerBound(ref, comp);
    assert(itr.valid() && itr.getKey() == ref);
    _dict.remove(itr);
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::move_entries(ICompactable &compactable)
{
    auto itr = _dict.begin();
    while (itr.valid()) {
        EntryRef oldRef(itr.getKey());
        EntryRef newRef(compactable.move(oldRef));
        if (newRef != oldRef) {
            _dict.thaw(itr);
            itr.writeKey(newRef);
        }
        ++itr;
    }
}

template <typename DictionaryT, typename ParentT>
uint32_t
UniqueStoreDictionary<DictionaryT, ParentT>::get_num_uniques() const
{
    return _dict.size();
}

template <typename DictionaryT, typename ParentT>
vespalib::MemoryUsage
UniqueStoreDictionary<DictionaryT, ParentT>::get_memory_usage() const
{
    return _dict.getMemoryUsage();
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::build(const std::vector<EntryRef> &refs,
                                                   const std::vector<uint32_t> &ref_counts,
                                                   std::function<void(EntryRef)> hold)
{
    assert(refs.size() == ref_counts.size());
    assert(!refs.empty());
    typename DictionaryType::Builder builder(_dict.getAllocator());
    for (size_t i = 1; i < refs.size(); ++i) {
        if (ref_counts[i] != 0u) {
            builder.insert(refs[i], DataType());
        } else {
            hold(refs[i]);
        }
    }
    _dict.assign(builder);
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::build(vespalib::ConstArrayRef<EntryRef> refs)
{
    typename DictionaryType::Builder builder(_dict.getAllocator());
    for (const auto& ref : refs) {
        builder.insert(ref, DataType());
    }
    _dict.assign(builder);
}

template <typename DictionaryT, typename ParentT>
void
UniqueStoreDictionary<DictionaryT, ParentT>::build_with_payload(const std::vector<EntryRef>& refs,
                                                                const std::vector<uint32_t>& payloads)
{
    assert(refs.size() == payloads.size());
    typename DictionaryType::Builder builder(_dict.getAllocator());
    for (size_t i = 0; i < refs.size(); ++i) {
        if constexpr (std::is_same_v<DataType, uint32_t>) {
            builder.insert(refs[i], payloads[i]);
        } else {
            builder.insert(refs[i], DataType());
        }
    }
    _dict.assign(builder);
}

template <typename DictionaryT, typename ParentT>
std::unique_ptr<typename ParentT::ReadSnapshot>
UniqueStoreDictionary<DictionaryT, ParentT>::get_read_snapshot() const
{
    return std::make_unique<ReadSnapshotImpl>(_dict.getFrozenView());
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "CppUTest/CppUTestConfig.h"
#include "CppUTestExt/MockSupport.h"
#include "CppUTestExt/MockSupport_c.h"
#include <string.h>

static MockSupport* currentMockSupport = NULL;
static MockFunctionCall* currentCall = NULL;

class MockCFunctionComparatorNode : public MockNamedValueComparator
{
public:
	MockCFunctionComparatorNode(MockCFunctionComparatorNode* next, MockTypeEqualFunction_c equal, MockTypeValueToStringFunction_c toString)
		: next_(next), equal_(equal), toString_(toString) {}
	virtual ~MockCFunctionComparatorNode() {};

	virtual bool isEqual(void* object1, void* object2)
	{
		return equal_(object1, object2) != 0;
	}
	virtual SimpleString valueToString(void* object)
	{
		return SimpleString(toString_(object));
	}

	MockCFunctionComparatorNode* next_;
	MockTypeEqualFunction_c equal_;
	MockTypeValueToStringFunction_c toString_;
};

static MockCFunctionComparatorNode* comparatorList_ = NULL;

extern "C" {

MockFunctionCall_c* expectOneCall_c(const char* name);
MockFunctionCall_c* actualCall_c(const char* name);
void disable_c(void);
void enable_c(void);
void setIntData_c(const char* name, int value);
void setDoubleData_c(const char* name, double value);
void setStringData_c(const char* name, const char* value);
void setPointerData_c(const char* name, void* value);
void setDataObject_c(const char* name, const char* type, void* value);
MockValue_c getData_c(const char* name);

void checkExpectations_c();
int expectedCallsLeft_c();
void clear_c();

MockFunctionCall_c* withIntParameters_c(const char* name, int value);
MockFunctionCall_c* withDoubleParameters_c(const char* name, double value);
MockFunctionCall_c* withStringParameters_c(const char* name, const char* value);
MockFunctionCall_c* withPointerParameters_c(const char* name, void* value);
MockFunctionCall_c* withParameterOfType_c(const char* type, const char* name, void* value);
MockFunctionCall_c* andReturnIntValue_c(int value);
MockFunctionCall_c* andReturnDoubleValue_c(double value);
MockFunctionCall_c* andReturnStringValue_c(const char* value);
MockFunctionCall_c* andReturnPointerValue_c(void* value);
MockValue_c returnValue_c();

static void installComparator_c (const char* typeName, MockTypeEqualFunction_c isEqual, MockTypeValueToStringFunction_c valueToString)
{
	comparatorList_ = new MockCFunctionComparatorNode(comparatorList_, isEqual, valueToString);
	currentMockSupport->installComparator(typeName, *comparatorList_);
}

static void removeAllComparators_c()
{
	while (comparatorList_) {
		MockCFunctionComparatorNode *next = comparatorList_->next_;
		delete comparatorList_;
		comparatorList_ = next;
	}
	currentMockSupport->removeAllComparators();
}

static MockFunctionCall_c gFunctionCall = {
		withIntParameters_c,
		withDoubleParameters_c,
		withStringParameters_c,
		withPointerParameters_c,
		withParameterOfType_c,
		andReturnIntValue_c,
		andReturnDoubleValue_c,
		andReturnStringValue_c,
		andReturnPointerValue_c,
		returnValue_c
};

static MockSupport_c gMockSupport = {
		expectOneCall_c,
		actualCall_c,
		returnValue_c,
		enable_c,
		disable_c,
		setIntData_c,
		setDoubleData_c,
		setStringData_c,
		setPointerData_c,
		setDataObject_c,
		getData_c,
		checkExpectations_c,
		expectedCallsLeft_c,
		clear_c,
		installComparator_c,
		removeAllComparators_c
};

MockFunctionCall_c* withIntParameters_c(const char* name, int value)
{
	currentCall = &currentCall->withParameter(name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* withDoubleParameters_c(const char* name, double value)
{
	currentCall = &currentCall->withParameter(name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* withStringParameters_c(const char* name, const char* value)
{
	currentCall = &currentCall->withParameter(name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* withPointerParameters_c(const char* name, void* value)
{
	currentCall = &currentCall->withParameter(name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* withParameterOfType_c(const char* type, const char* name, void* value)
{
	currentCall = &currentCall->withParameterOfType(type, name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* andReturnIntValue_c(int value)
{
	currentCall = &currentCall->andReturnValue(value);
	return &gFunctionCall;
}

MockFunctionCall_c* andReturnDoubleValue_c(double value)
{
	currentCall = &currentCall->andReturnValue(value);
	return &gFunctionCall;
}

MockFunctionCall_c* andReturnStringValue_c(const char* value)
{
	currentCall = &currentCall->andReturnValue(value);
	return &gFunctionCall;
}

MockFunctionCall_c* andReturnPointerValue_c(void* value)
{
	currentCall = &currentCall->andReturnValue(value);
	return &gFunctionCall;
}

static MockValue_c getMockValueCFromNamedValue(const MockNamedValue& namedValue)
{
	MockValue_c returnValue;
	if (strcmp(namedValue.getType().asCharString(), "int") == 0) {
		returnValue.type = MOCKVALUETYPE_INTEGER;
		returnValue.value.intValue = namedValue.getIntValue();
	}
	else if (strcmp(namedValue.getType().asCharString(), "double") == 0) {
		returnValue.type = MOCKVALUETYPE_DOUBLE;
		returnValue.value.doubleValue = namedValue.getDoubleValue();
	}
	else if (strcmp(namedValue.getType().asCharString(), "char*") == 0) {
		returnValue.type = MOCKVALUETYPE_STRING;
		returnValue.value.stringValue = namedValue.getStringValue();
	}
	else if (strcmp(namedValue.getType().asCharString(), "void*") == 0) {
		returnValue.type = MOCKVALUETYPE_POINTER;
		returnValue.value.pointerValue = namedValue.getPointerValue();
	}
	else {
		returnValue.type = MOCKVALUETYPE_OBJECT;
		returnValue.value.objectValue = namedValue.getObjectPointer();
	}
	return returnValue;
}

MockValue_c returnValue_c()
{
	return getMockValueCFromNamedValue(currentCall->returnValue());
}

MockFunctionCall_c* expectOneCall_c(const char* name)
{
	currentCall = &currentMockSupport->expectOneCall(name);
	return &gFunctionCall;
}

MockFunctionCall_c* actualCall_c(const char* name)
{
	currentCall = &currentMockSupport->actualCall(name);
	return &gFunctionCall;
}

void disable_c(void)
{
	currentMockSupport->disable();
}

void enable_c(void)
{
	currentMockSupport->enable();
}

void setIntData_c(const char* name, int value)
{
	return currentMockSupport->setData(name, value);
}

void setDoubleData_c(const char* name, double value)
{
	return currentMockSupport->setData(name, value);
}

void setStringData_c(const char* name, const char* value)
{
	return currentMockSupport->setData(name, value);
}

void setPointerData_c(const char* name, void* value)
{
	return currentMockSupport->setData(name, value);
}

void setDataObject_c(const char* name, const char* type, void* value)
{
	return currentMockSupport->setDataObject(name, type, value);
}

MockValue_c getData_c(const char* name)
{
	return getMockValueCFromNamedValue(currentMockSupport->getData(name));
}

void checkExpectations_c()
{
	currentMockSupport->checkExpectations();
}

int expectedCallsLeft_c()
{
	return currentMockSupport->expectedCallsLeft();
}

void clear_c()
{
	currentMockSupport->clear();
}

MockSupport_c* mock_c()
{
	currentMockSupport = &mock();
	return &gMockSupport;
}

MockSupport_c* mock_scope_c(const char* scope)
{
	currentMockSupport = &mock(scope);
	return &gMockSupport;
}

}
<commit_msg>Removed dependency to Standard C<commit_after>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "CppUTest/CppUTestConfig.h"
#include "CppUTest/PlatformSpecificFunctions_c.h"
#include "CppUTestExt/MockSupport.h"
#include "CppUTestExt/MockSupport_c.h"

static MockSupport* currentMockSupport = NULL;
static MockFunctionCall* currentCall = NULL;

class MockCFunctionComparatorNode : public MockNamedValueComparator
{
public:
	MockCFunctionComparatorNode(MockCFunctionComparatorNode* next, MockTypeEqualFunction_c equal, MockTypeValueToStringFunction_c toString)
		: next_(next), equal_(equal), toString_(toString) {}
	virtual ~MockCFunctionComparatorNode() {};

	virtual bool isEqual(void* object1, void* object2)
	{
		return equal_(object1, object2) != 0;
	}
	virtual SimpleString valueToString(void* object)
	{
		return SimpleString(toString_(object));
	}

	MockCFunctionComparatorNode* next_;
	MockTypeEqualFunction_c equal_;
	MockTypeValueToStringFunction_c toString_;
};

static MockCFunctionComparatorNode* comparatorList_ = NULL;

extern "C" {

MockFunctionCall_c* expectOneCall_c(const char* name);
MockFunctionCall_c* actualCall_c(const char* name);
void disable_c(void);
void enable_c(void);
void setIntData_c(const char* name, int value);
void setDoubleData_c(const char* name, double value);
void setStringData_c(const char* name, const char* value);
void setPointerData_c(const char* name, void* value);
void setDataObject_c(const char* name, const char* type, void* value);
MockValue_c getData_c(const char* name);

void checkExpectations_c();
int expectedCallsLeft_c();
void clear_c();

MockFunctionCall_c* withIntParameters_c(const char* name, int value);
MockFunctionCall_c* withDoubleParameters_c(const char* name, double value);
MockFunctionCall_c* withStringParameters_c(const char* name, const char* value);
MockFunctionCall_c* withPointerParameters_c(const char* name, void* value);
MockFunctionCall_c* withParameterOfType_c(const char* type, const char* name, void* value);
MockFunctionCall_c* andReturnIntValue_c(int value);
MockFunctionCall_c* andReturnDoubleValue_c(double value);
MockFunctionCall_c* andReturnStringValue_c(const char* value);
MockFunctionCall_c* andReturnPointerValue_c(void* value);
MockValue_c returnValue_c();

static void installComparator_c (const char* typeName, MockTypeEqualFunction_c isEqual, MockTypeValueToStringFunction_c valueToString)
{
	comparatorList_ = new MockCFunctionComparatorNode(comparatorList_, isEqual, valueToString);
	currentMockSupport->installComparator(typeName, *comparatorList_);
}

static void removeAllComparators_c()
{
	while (comparatorList_) {
		MockCFunctionComparatorNode *next = comparatorList_->next_;
		delete comparatorList_;
		comparatorList_ = next;
	}
	currentMockSupport->removeAllComparators();
}

static MockFunctionCall_c gFunctionCall = {
		withIntParameters_c,
		withDoubleParameters_c,
		withStringParameters_c,
		withPointerParameters_c,
		withParameterOfType_c,
		andReturnIntValue_c,
		andReturnDoubleValue_c,
		andReturnStringValue_c,
		andReturnPointerValue_c,
		returnValue_c
};

static MockSupport_c gMockSupport = {
		expectOneCall_c,
		actualCall_c,
		returnValue_c,
		enable_c,
		disable_c,
		setIntData_c,
		setDoubleData_c,
		setStringData_c,
		setPointerData_c,
		setDataObject_c,
		getData_c,
		checkExpectations_c,
		expectedCallsLeft_c,
		clear_c,
		installComparator_c,
		removeAllComparators_c
};

MockFunctionCall_c* withIntParameters_c(const char* name, int value)
{
	currentCall = &currentCall->withParameter(name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* withDoubleParameters_c(const char* name, double value)
{
	currentCall = &currentCall->withParameter(name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* withStringParameters_c(const char* name, const char* value)
{
	currentCall = &currentCall->withParameter(name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* withPointerParameters_c(const char* name, void* value)
{
	currentCall = &currentCall->withParameter(name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* withParameterOfType_c(const char* type, const char* name, void* value)
{
	currentCall = &currentCall->withParameterOfType(type, name, value);
	return &gFunctionCall;
}

MockFunctionCall_c* andReturnIntValue_c(int value)
{
	currentCall = &currentCall->andReturnValue(value);
	return &gFunctionCall;
}

MockFunctionCall_c* andReturnDoubleValue_c(double value)
{
	currentCall = &currentCall->andReturnValue(value);
	return &gFunctionCall;
}

MockFunctionCall_c* andReturnStringValue_c(const char* value)
{
	currentCall = &currentCall->andReturnValue(value);
	return &gFunctionCall;
}

MockFunctionCall_c* andReturnPointerValue_c(void* value)
{
	currentCall = &currentCall->andReturnValue(value);
	return &gFunctionCall;
}

static MockValue_c getMockValueCFromNamedValue(const MockNamedValue& namedValue)
{
	MockValue_c returnValue;
	if (PlatformSpecificStrCmp(namedValue.getType().asCharString(), "int") == 0) {
		returnValue.type = MOCKVALUETYPE_INTEGER;
		returnValue.value.intValue = namedValue.getIntValue();
	}
	else if (PlatformSpecificStrCmp(namedValue.getType().asCharString(), "double") == 0) {
		returnValue.type = MOCKVALUETYPE_DOUBLE;
		returnValue.value.doubleValue = namedValue.getDoubleValue();
	}
	else if (PlatformSpecificStrCmp(namedValue.getType().asCharString(), "char*") == 0) {
		returnValue.type = MOCKVALUETYPE_STRING;
		returnValue.value.stringValue = namedValue.getStringValue();
	}
	else if (PlatformSpecificStrCmp(namedValue.getType().asCharString(), "void*") == 0) {
		returnValue.type = MOCKVALUETYPE_POINTER;
		returnValue.value.pointerValue = namedValue.getPointerValue();
	}
	else {
		returnValue.type = MOCKVALUETYPE_OBJECT;
		returnValue.value.objectValue = namedValue.getObjectPointer();
	}
	return returnValue;
}

MockValue_c returnValue_c()
{
	return getMockValueCFromNamedValue(currentCall->returnValue());
}

MockFunctionCall_c* expectOneCall_c(const char* name)
{
	currentCall = &currentMockSupport->expectOneCall(name);
	return &gFunctionCall;
}

MockFunctionCall_c* actualCall_c(const char* name)
{
	currentCall = &currentMockSupport->actualCall(name);
	return &gFunctionCall;
}

void disable_c(void)
{
	currentMockSupport->disable();
}

void enable_c(void)
{
	currentMockSupport->enable();
}

void setIntData_c(const char* name, int value)
{
	return currentMockSupport->setData(name, value);
}

void setDoubleData_c(const char* name, double value)
{
	return currentMockSupport->setData(name, value);
}

void setStringData_c(const char* name, const char* value)
{
	return currentMockSupport->setData(name, value);
}

void setPointerData_c(const char* name, void* value)
{
	return currentMockSupport->setData(name, value);
}

void setDataObject_c(const char* name, const char* type, void* value)
{
	return currentMockSupport->setDataObject(name, type, value);
}

MockValue_c getData_c(const char* name)
{
	return getMockValueCFromNamedValue(currentMockSupport->getData(name));
}

void checkExpectations_c()
{
	currentMockSupport->checkExpectations();
}

int expectedCallsLeft_c()
{
	return currentMockSupport->expectedCallsLeft();
}

void clear_c()
{
	currentMockSupport->clear();
}

MockSupport_c* mock_c()
{
	currentMockSupport = &mock();
	return &gMockSupport;
}

MockSupport_c* mock_scope_c(const char* scope)
{
	currentMockSupport = &mock(scope);
	return &gMockSupport;
}

}
<|endoftext|>


<commit_before>#include <assert.h>
#include <string>
#include "Dir.h"

namespace Maps {

int wasdqeToDir(char dir) {
	int intDir = 0;
	if (dir == 'w') {
		intDir = Maps::North;
	}
	else if (dir == 'a') {
		intDir = Maps::West;
	}
	else if (dir == 's') {
		intDir = Maps::South;
	}
	else if (dir == 'd') {
		intDir = Maps::East;
	}
	else if (dir == 'q') {
		intDir = Maps::Down;
	}
	else if (dir == 'e') {
		intDir = Maps::Up;
	}
	return intDir;
}

std::string dirName(int dir) {
	assert(0 <= dir && dir < NUM_DIRS);

	std::string dirName;
	if (dir == Dir::Stop) {
		dirName = "Stop";
	} else if (dir == Dir::North) {
		dirName = "North";
	} else if (dir == Dir::East) {
		dirName = "East";
	} else if (dir == Dir::West) {
		dirName = "West";
	} else if (dir == Dir::South) {
		dirName = "South";
	} else if (dir == Dir::Up) {
		dirName = "Up";
	} else if (dir == Dir::Down) {
		dirName = "Down";
	}
	return dirName;
}

int oppositeDir(int dir) {
	assert(0 <= dir && dir < NUM_DIRS);

	int revDir; // The reverse directoin
	if (dir == Dir::Stop) {
		revDir = Dir::Stop;
	} else if (dir == Dir::North) {
		revDir = Dir::South;
	} else if (dir == Dir::East) {
		revDir = Dir::West;
	} else if (dir == Dir::West) {
		revDir = Dir::East;
	} else if (dir == Dir::South) {
		revDir = Dir::North;
	} else if (dir == Dir::Up) {
		revDir = Dir::Down;
	} else if (dir == Dir::Down) {
		revDir = Dir::Up;
	}
	return revDir;
}

} // End Maps
<commit_msg>Rename method<commit_after>#include <assert.h>
#include <string>
#include "Dir.h"

namespace Maps {

int charToDir(char dir) {
	int intDir = 0;
	if (dir == 'w') {
		intDir = Maps::North;
	}
	else if (dir == 'a') {
		intDir = Maps::West;
	}
	else if (dir == 's') {
		intDir = Maps::South;
	}
	else if (dir == 'd') {
		intDir = Maps::East;
	}
	else if (dir == 'q') {
		intDir = Maps::Down;
	}
	else if (dir == 'e') {
		intDir = Maps::Up;
	}
	return intDir;
}

std::string dirName(int dir) {
	assert(0 <= dir && dir < NUM_DIRS);

	std::string dirName;
	if (dir == Dir::Stop) {
		dirName = "Stop";
	} else if (dir == Dir::North) {
		dirName = "North";
	} else if (dir == Dir::East) {
		dirName = "East";
	} else if (dir == Dir::West) {
		dirName = "West";
	} else if (dir == Dir::South) {
		dirName = "South";
	} else if (dir == Dir::Up) {
		dirName = "Up";
	} else if (dir == Dir::Down) {
		dirName = "Down";
	}
	return dirName;
}

int oppositeDir(int dir) {
	assert(0 <= dir && dir < NUM_DIRS);

	int revDir; // The reverse directoin
	if (dir == Dir::Stop) {
		revDir = Dir::Stop;
	} else if (dir == Dir::North) {
		revDir = Dir::South;
	} else if (dir == Dir::East) {
		revDir = Dir::West;
	} else if (dir == Dir::West) {
		revDir = Dir::East;
	} else if (dir == Dir::South) {
		revDir = Dir::North;
	} else if (dir == Dir::Up) {
		revDir = Dir::Down;
	} else if (dir == Dir::Down) {
		revDir = Dir::Up;
	}
	return revDir;
}

} // End Maps
<|endoftext|>


<commit_before>/*

    Copyright Eli Dupree and Isaac Dupree, 2011, 2012

    This file is part of Lasercake.

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

    Lasercake 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Lasercake.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef LASERCAKE_NUMBER_STRUCTURES_HPP__
#define LASERCAKE_NUMBER_STRUCTURES_HPP__

#include "../config.hpp"
#include <numeric>
#include <boost/integer/static_log2.hpp>

// returns the signum (-1, 0, or 1)
template <typename Number>
inline Number sign(Number n) {
  return (n > 0) - (n < 0);
}

template <typename Number>
inline bool is_negative(Number n) {
  // this is (very slightly) the fastest comparison-with-zero among < 0, <= 0, > 0, >= 0:
  // in signed two's complement, it's the value of the highest bit:
  // which leads to one less x86 instruction (small code = more fits in cache).
  // (Once inlined and optimized in context, the chosen comparison might make no difference.)
  return (n < 0);
}

template<typename ScalarType1, typename ScalarType2>
auto divide_rounding_towards_zero(ScalarType1 dividend, ScalarType2 divisor)
  -> decltype(dividend/divisor) /*C++11 syntax for return type that lets it refer to argument names*/
{
  caller_correct_if(divisor != 0, "divisor must be nonzero");
  using namespace std;
  const auto abs_result = abs(dividend) / abs(divisor);
  if (is_negative(dividend) == is_negative(divisor)) return abs_result;
  else return -abs_result;
}

inline int32_t i64log2(uint64_t argument) {
  caller_error_if(argument == 0, "the logarithm of zero is undefined");
#if defined(DETECTED_builtin_clz64)
  return 63 - DETECTED_builtin_clz64(argument);
#else
  int32_t shift
         = argument &  (((1ULL << 32) - 1) << 32)           ? 32 : 0;
  shift += argument & ((((1ULL << 16) - 1) << 16) << shift) ? 16 : 0;
  shift += argument & ((((1ULL <<  8) - 1) <<  8) << shift) ?  8 : 0;
  shift += argument & ((((1ULL <<  4) - 1) <<  4) << shift) ?  4 : 0;
  shift += argument & ((((1ULL <<  2) - 1) <<  2) << shift) ?  2 : 0;
  shift += argument & ((((1ULL <<  1) - 1) <<  1) << shift) ?  1 : 0;
  return shift;
#endif
}
inline int32_t num_bits_in_integer_that_are_not_leading_zeroes(uint64_t i) {
  if(i == 0) return 0;
  else return i64log2(i) + 1;
}
template<uint64_t Bits>
struct static_num_bits_in_integer_that_are_not_leading_zeroes {
  static const uint64_t value = boost::static_log2<Bits>::value + 1;
};
template<>
struct static_num_bits_in_integer_that_are_not_leading_zeroes<0> {
  static const uint64_t value = 0;
};

inline int32_t count_trailing_zeroes_64(uint64_t argument) {
  caller_error_if(argument == 0, "the number of trailing zeroes of zero is undefined");
#if defined(DETECTED_builtin_ctz64)
  return DETECTED_builtin_ctz64(argument);
#else
  int32_t shift
         = argument &  ((1ULL << 32) - 1)           ? 0 : 32;
  shift += argument & (((1ULL << 16) - 1) << shift) ? 0 : 16;
  shift += argument & (((1ULL <<  8) - 1) << shift) ? 0 : 8;
  shift += argument & (((1ULL <<  4) - 1) << shift) ? 0 : 4;
  shift += argument & (((1ULL <<  2) - 1) << shift) ? 0 : 2;
  shift += argument & (((1ULL <<  1) - 1) << shift) ? 0 : 1;
  return shift;
#endif
}

inline uint32_t i64sqrt(uint64_t radicand)
{
  typedef uint64_t full_t;
  typedef uint32_t half_t;

  // log2(0) doesn't exist, but sqrt(0) does, so we have to check for it here.
  if(radicand == 0)return 0;

  //shift is the log base 2 of radicand, rounded down.
  int shift = i64log2(radicand);

  //bounds are [lower_bound, upper_bound), a half-open range.
  //lower_bound is guaranteed to be less than or equal to the answer.
  //upper_bound is guaranteed to be greater than the answer.
  half_t lower_bound = half_t(1) << (shift >> 1);

  //upper_bound is twice the original lower_bound;
  //upper_bound is    2**(floor(log2(radicand) / 2)+1)
  //which is equal to 2**ceil((log2(radicand)+1) / 2)
  full_t upper_bound = full_t(lower_bound) << 1;

#ifdef DETECTED_uint128_t
  typedef DETECTED_uint128_t twice_t;
  assert_if_ASSERT_EVERYTHING(full_t(lower_bound)*lower_bound <= radicand);
  assert_if_ASSERT_EVERYTHING(twice_t(upper_bound)*upper_bound > radicand);
#endif

  while(lower_bound < upper_bound - 1)
  {
    const half_t mid = half_t((upper_bound + lower_bound) >> 1);
    if(full_t(mid) * mid > radicand) {
      upper_bound = mid;
    }
    else {
      lower_bound = mid;
    }
  }

  return lower_bound;
}

template<typename IntType> struct non_normalized_rational {
  IntType numerator;
  IntType denominator;
  non_normalized_rational(IntType n, IntType d):numerator(n),denominator(d){ caller_error_if(denominator == 0, "Constructing a rational with denominator zero..."); }
  non_normalized_rational(IntType n):numerator(n),denominator(1){}
  non_normalized_rational():numerator(0),denominator(1){}
  bool operator< (non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    if (is_negative(denominator) == is_negative(o.denominator))
      return numerator*o.denominator <  o.numerator*denominator;
    else
      return numerator*o.denominator >  o.numerator*denominator;
  }
  bool operator> (non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    if (is_negative(denominator) == is_negative(o.denominator))
      return numerator*o.denominator >  o.numerator*denominator;
    else
      return numerator*o.denominator <  o.numerator*denominator;
  }
  bool operator<=(non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    if (is_negative(denominator) == is_negative(o.denominator))
      return numerator*o.denominator <= o.numerator*denominator;
    else
      return numerator*o.denominator >= o.numerator*denominator;
  }
  bool operator>=(non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    if (is_negative(denominator) == is_negative(o.denominator))
      return numerator*o.denominator >= o.numerator*denominator;
    else
      return numerator*o.denominator <= o.numerator*denominator;
  }
  bool operator==(non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    return numerator*o.denominator == o.numerator*denominator; }
  bool operator!=(non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    return numerator*o.denominator != o.numerator*denominator; }
};
template<typename IntType> inline std::ostream& operator<<(std::ostream& os, non_normalized_rational<IntType>const& r) {
  return os << r.numerator << '/' << r.denominator;
}

template<typename IntType, typename Num>
inline auto multiply_rational_into(Num n, non_normalized_rational<IntType> rat)
-> decltype(n * rat.numerator / rat.denominator) {
  return n * rat.numerator / rat.denominator;
}

#endif
<commit_msg>Added (and didn't test!) arithmetic operators for non_normalized_rational<commit_after>/*

    Copyright Eli Dupree and Isaac Dupree, 2011, 2012

    This file is part of Lasercake.

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

    Lasercake 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Lasercake.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef LASERCAKE_NUMBER_STRUCTURES_HPP__
#define LASERCAKE_NUMBER_STRUCTURES_HPP__

#include "../config.hpp"
#include <numeric>
#include <boost/integer/static_log2.hpp>

// returns the signum (-1, 0, or 1)
template <typename Number>
inline Number sign(Number n) {
  return (n > 0) - (n < 0);
}

template <typename Number>
inline bool is_negative(Number n) {
  // this is (very slightly) the fastest comparison-with-zero among < 0, <= 0, > 0, >= 0:
  // in signed two's complement, it's the value of the highest bit:
  // which leads to one less x86 instruction (small code = more fits in cache).
  // (Once inlined and optimized in context, the chosen comparison might make no difference.)
  return (n < 0);
}

template<typename ScalarType1, typename ScalarType2>
auto divide_rounding_towards_zero(ScalarType1 dividend, ScalarType2 divisor)
  -> decltype(dividend/divisor) /*C++11 syntax for return type that lets it refer to argument names*/
{
  caller_correct_if(divisor != 0, "divisor must be nonzero");
  using namespace std;
  const auto abs_result = abs(dividend) / abs(divisor);
  if (is_negative(dividend) == is_negative(divisor)) return abs_result;
  else return -abs_result;
}

inline int32_t i64log2(uint64_t argument) {
  caller_error_if(argument == 0, "the logarithm of zero is undefined");
#if defined(DETECTED_builtin_clz64)
  return 63 - DETECTED_builtin_clz64(argument);
#else
  int32_t shift
         = argument &  (((1ULL << 32) - 1) << 32)           ? 32 : 0;
  shift += argument & ((((1ULL << 16) - 1) << 16) << shift) ? 16 : 0;
  shift += argument & ((((1ULL <<  8) - 1) <<  8) << shift) ?  8 : 0;
  shift += argument & ((((1ULL <<  4) - 1) <<  4) << shift) ?  4 : 0;
  shift += argument & ((((1ULL <<  2) - 1) <<  2) << shift) ?  2 : 0;
  shift += argument & ((((1ULL <<  1) - 1) <<  1) << shift) ?  1 : 0;
  return shift;
#endif
}
inline int32_t num_bits_in_integer_that_are_not_leading_zeroes(uint64_t i) {
  if(i == 0) return 0;
  else return i64log2(i) + 1;
}
template<uint64_t Bits>
struct static_num_bits_in_integer_that_are_not_leading_zeroes {
  static const uint64_t value = boost::static_log2<Bits>::value + 1;
};
template<>
struct static_num_bits_in_integer_that_are_not_leading_zeroes<0> {
  static const uint64_t value = 0;
};

inline int32_t count_trailing_zeroes_64(uint64_t argument) {
  caller_error_if(argument == 0, "the number of trailing zeroes of zero is undefined");
#if defined(DETECTED_builtin_ctz64)
  return DETECTED_builtin_ctz64(argument);
#else
  int32_t shift
         = argument &  ((1ULL << 32) - 1)           ? 0 : 32;
  shift += argument & (((1ULL << 16) - 1) << shift) ? 0 : 16;
  shift += argument & (((1ULL <<  8) - 1) << shift) ? 0 : 8;
  shift += argument & (((1ULL <<  4) - 1) << shift) ? 0 : 4;
  shift += argument & (((1ULL <<  2) - 1) << shift) ? 0 : 2;
  shift += argument & (((1ULL <<  1) - 1) << shift) ? 0 : 1;
  return shift;
#endif
}

inline uint32_t i64sqrt(uint64_t radicand)
{
  typedef uint64_t full_t;
  typedef uint32_t half_t;

  // log2(0) doesn't exist, but sqrt(0) does, so we have to check for it here.
  if(radicand == 0)return 0;

  //shift is the log base 2 of radicand, rounded down.
  int shift = i64log2(radicand);

  //bounds are [lower_bound, upper_bound), a half-open range.
  //lower_bound is guaranteed to be less than or equal to the answer.
  //upper_bound is guaranteed to be greater than the answer.
  half_t lower_bound = half_t(1) << (shift >> 1);

  //upper_bound is twice the original lower_bound;
  //upper_bound is    2**(floor(log2(radicand) / 2)+1)
  //which is equal to 2**ceil((log2(radicand)+1) / 2)
  full_t upper_bound = full_t(lower_bound) << 1;

#ifdef DETECTED_uint128_t
  typedef DETECTED_uint128_t twice_t;
  assert_if_ASSERT_EVERYTHING(full_t(lower_bound)*lower_bound <= radicand);
  assert_if_ASSERT_EVERYTHING(twice_t(upper_bound)*upper_bound > radicand);
#endif

  while(lower_bound < upper_bound - 1)
  {
    const half_t mid = half_t((upper_bound + lower_bound) >> 1);
    if(full_t(mid) * mid > radicand) {
      upper_bound = mid;
    }
    else {
      lower_bound = mid;
    }
  }

  return lower_bound;
}

template<typename IntType> struct non_normalized_rational {
  IntType numerator;
  IntType denominator;
  non_normalized_rational(IntType n, IntType d):numerator(n),denominator(d){ caller_error_if(denominator == 0, "Constructing a rational with denominator zero..."); }
  non_normalized_rational(IntType n):numerator(n),denominator(1){}
  non_normalized_rational():numerator(0),denominator(1){}
  bool operator< (non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    if (is_negative(denominator) == is_negative(o.denominator))
      return numerator*o.denominator <  o.numerator*denominator;
    else
      return numerator*o.denominator >  o.numerator*denominator;
  }
  bool operator> (non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    if (is_negative(denominator) == is_negative(o.denominator))
      return numerator*o.denominator >  o.numerator*denominator;
    else
      return numerator*o.denominator <  o.numerator*denominator;
  }
  bool operator<=(non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    if (is_negative(denominator) == is_negative(o.denominator))
      return numerator*o.denominator <= o.numerator*denominator;
    else
      return numerator*o.denominator >= o.numerator*denominator;
  }
  bool operator>=(non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    if (is_negative(denominator) == is_negative(o.denominator))
      return numerator*o.denominator >= o.numerator*denominator;
    else
      return numerator*o.denominator <= o.numerator*denominator;
  }
  bool operator==(non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    return numerator*o.denominator == o.numerator*denominator; }
  bool operator!=(non_normalized_rational const& o)const {
    assert(denominator != 0 && o.denominator != 0);
    return numerator*o.denominator != o.numerator*denominator; }

  non_normalized_rational reciprocal()const {
    return non_normalized_rational(denominator, numerator);
  }
  non_normalized_rational operator+(non_normalized_rational const& o)const {
    // Simplify only the stupidest case.
    if (denominator == o.denominator) return non_normalized_rational(numerator + numerator, denominator);
    return non_normalized_rational(numerator * o.denominator + denominator * o.numerator, denominator * o.denominator);
  }
  void operator+=(non_normalized_rational const& o) {
    // Simplify only the stupidest case.
    if (denominator == o.denominator) {
      numerator += o.numerator;
    }
    else {
      numerator = numerator * o.denominator + denominator * o.numerator;
      denominator *= o.denominator;
    }
  }
  non_normalized_rational operator-(non_normalized_rational const& o)const {
    // Simplify only the stupidest case.
    if (denominator == o.denominator) return non_normalized_rational(numerator - numerator, denominator);
    return non_normalized_rational(numerator * o.denominator - denominator * o.numerator, denominator * o.denominator);
  }
  void operator-=(non_normalized_rational const& o) {
    // Simplify only the stupidest case.
    if (denominator == o.denominator) {
      numerator -= o.numerator;
    }
    else {
      numerator = numerator * o.denominator - denominator * o.numerator;
      denominator *= o.denominator;
    }
  }
  non_normalized_rational operator*(non_normalized_rational const& o)const {
    // Simplify the stupidest cases.
    if (numerator == o.denominator) return non_normalized_rational(o.numerator, denominator);
    if (o.numerator == denominator) return non_normalized_rational(numerator, o.denominator);
    return non_normalized_rational(numerator * o.numerator, denominator * o.denominator);
  }
  void operator*=(non_normalized_rational const& o) {
    // Simplify the stupidest cases.
    if (numerator == o.denominator) numerator = o.numerator;
    else if (o.numerator == denominator) denominator = o.denominator;
    else {
      numerator *= o.numerator;
      denominator *= o.denominator;
    }
  }
  non_normalized_rational operator/(non_normalized_rational const& o)const {
    return *this * o.reciprocal();
  }
  void operator/=(non_normalized_rational const& o) {
    *this *= o.reciprocal();
  }
};
template<typename IntType> inline std::ostream& operator<<(std::ostream& os, non_normalized_rational<IntType>const& r) {
  return os << r.numerator << '/' << r.denominator;
}

template<typename IntType, typename Num>
inline auto multiply_rational_into(Num n, non_normalized_rational<IntType> rat)
-> decltype(n * rat.numerator / rat.denominator) {
  return n * rat.numerator / rat.denominator;
}

#endif
<|endoftext|>


<commit_before>#include <cmath>

/*
 * Member function definitions of Foaw template class.
 * See foaw.h for template class declaration.
 */
template <typename T, size_t N>
Foaw<T, N>::Foaw(T sample_period, T allowed_error) :
    m_positions(),
    m_position_index(0),
    m_velocity(0.0),
    m_T(sample_period),
    m_d(allowed_error) { }

template <typename T, size_t N>
void Foaw<T, N>::reset() {
    m_positions.fill(0.0);
}

template <typename T, size_t N>
void Foaw<T, N>::add_position(T x) {
    m_positions[m_position_index++] = x;
    if (m_position_index == N) {
        m_position_index = 0;
    }
}

template <typename T, size_t N>
T Foaw<T, N>::estimate_velocity() const {
    size_t last_index = m_position_index - 1;
    if (m_position_index == 0) {
        last_index = N - 1;
    }

    m_velocity = 0.0;
    for (unsigned int n = 1; n < N; ++n) {
        T bn = 0.0;
        for (unsigned int i = 0; i <= n; ++i) {
            bn += (n - 2*i)*m_positions[(last_index - i + N) % N];
        }
        bn /= m_T*n*(n + 1)*(n + 2)/6;

        /*
         * The definition of 'an' in the paper doesn't make much sense so assume
         * line passes through last sampled position (which may not be the case
         * with a best fit line).
         */
        T an = m_positions[last_index];
        for (unsigned int j = 1; j < n; ++j) {
            T ykj = an - bn * j * m_T;
            T error = m_positions[(last_index - j + N) % N] - ykj;
            if (std::abs(error) > m_d) {
                return m_velocity;
            }

        }
        m_velocity = bn;
    }
    return m_velocity;
}

template <typename T, size_t N>
T Foaw<T, N>::sample_period() const {
    return m_T;
}

template <typename T, size_t N>
T Foaw<T, N>::allowed_error() const {
    return m_d;
}
<commit_msg>Fix incorrect slope calculation in FOAW algorithm<commit_after>#include <cmath>

/*
 * Member function definitions of Foaw template class.
 * See foaw.h for template class declaration.
 */
template <typename T, size_t N>
Foaw<T, N>::Foaw(T sample_period, T allowed_error) :
    m_positions(),
    m_position_index(0),
    m_velocity(0.0),
    m_T(sample_period),
    m_d(allowed_error) { }

template <typename T, size_t N>
void Foaw<T, N>::reset() {
    m_positions.fill(0.0);
}

template <typename T, size_t N>
void Foaw<T, N>::add_position(T x) {
    m_positions[m_position_index++] = x;
    if (m_position_index == N) {
        m_position_index = 0;
    }
}

template <typename T, size_t N>
T Foaw<T, N>::estimate_velocity() const {
    size_t last_index = m_position_index - 1;
    if (m_position_index == 0) {
        last_index = N - 1;
    }

    m_velocity = 0.0;
    for (int n = 1; n < static_cast<int>(N); ++n) {
        T bn = 0.0;
        for (int i = 0; i <= n; ++i) {
            bn += (n - 2*i)*m_positions[(last_index - i + N) % N];
        }
        bn /= m_T*n*(n + 1)*(n + 2)/6;

        /*
         * The definition of 'an' in the paper doesn't make much sense so assume
         * line passes through last sampled position (which may not be the case
         * with a best fit line).
         */
        T an = m_positions[last_index];
        for (int j = 1; j < n; ++j) {
            T ykj = an - bn * j * m_T;
            T error = m_positions[(last_index - j + N) % N] - ykj;
            if (std::abs(error) > m_d) {
                return m_velocity;
            }

        }
        m_velocity = bn;
    }
    return m_velocity;
}

template <typename T, size_t N>
T Foaw<T, N>::sample_period() const {
    return m_T;
}

template <typename T, size_t N>
T Foaw<T, N>::allowed_error() const {
    return m_d;
}
<|endoftext|>