text:
// rosmon - versatile ROS node launcher & monitor
// Author: Max Schwarz <max.schwarz@uni-bonn.de>

#include <ros/init.h>
#include <ros/master.h>
#include <ros/rate.h>
#include <ros/node_handle.h>
#include <ros/package.h>
#include <ros/console_backend.h>
#include <ros/this_node.h>

#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>

#include <unistd.h>
#include <getopt.h>
#include <csignal>

#include <iostream>

#include <fmt/format.h>

#include "launch/launch_config.h"
#include "launch/bytes_parser.h"
#include "monitor/monitor.h"
#include "ui.h"
#include "ros_interface.h"
#include "package_registry.h"
#include "fd_watcher.h"
#include "logger.h"

namespace fs = boost::filesystem;

bool g_shouldStop = false;
bool g_flushStdout = false;

static fs::path findFile(const fs::path& base, const std::string& name)
{
	for(fs::directory_iterator it(base); it != fs::directory_iterator(); ++it)
	{
		if(fs::is_directory(*it))
		{
			fs::path p = findFile(*it, name);
			if(!p.empty())
				return p;
		}
		else if(it->path().leaf() == name)
			return *it;
	}

	return fs::path();
}

void usage()
{
	fprintf(stderr,
		"Usage:\n"
		"  rosmon [actions] [options] some_package test.launch [arg1:=value1 ...]\n"
		"  rosmon [actions] [options] path/to/test.launch [arg1:=value1 ...]\n"
		"\n"
		"Actions (default is to launch the launch file):\n"
		"  --benchmark     Exit after loading the launch file\n"
		"  --list-args     List launch file arguments\n"
		"\n"
		"Options:\n"
		"  --disable-ui    Disable fancy terminal UI\n"
		"  --flush-log     Flush logfile after writing an entry\n"
		"  --flush-stdout  Flush stdout after writing an entry\n"
		"  --help          This help screen\n"
		"  --log=FILE      Write log file to FILE\n"
		"  --name=NAME     Use NAME as ROS node name. By default, an anonymous\n"
		"                  name is chosen.\n"
		"  --no-start      Don't automatically start the nodes in the beginning\n"
		"  --stop-timeout=SECONDS\n"
		"                  Kill a process if it is still running this long\n"
		"                  after the initial signal is send.\n"
		"  --disable-diagnostics\n"
		"                  Disable publication of ros diagnostics message about\n"
		"                  monitored nodes\n"
		"  --diagnostics-prefix=PREFIX\n"
		"                  Prefix for the ros diagnostics generated by this node.\n"
		"                  By default this will be the node name.\n"
		"  --cpu-limit=[0-n]\n"
		"                  Default CPU Usage limit of monitored process. n is the\n"
		"                  number of CPU cores. This is the sum of system and user\n"
		"                  CPU usage.\n"
		"  --memory-limit=15MB\n"
		"                  Default memory limit usage of monitored process.\n"
		"  --output-attr=obey|ignore\n"
		"                  Obey or ignore output=\"*\" attributes on node tags.\n"
		"                  Default is to ignore.\n"
		"\n"
		"rosmon also obeys some environment variables:\n"
		"  ROSMON_COLOR_MODE   Can be set to 'truecolor', '256colors', 'ansi'\n"
		"                      to force a specific color mode\n"
		"                      If unset, rosmon tries to detect the best\n"
		"                      available color mode.\n"
	);
}

void handleSignal(int)
{
	g_shouldStop = true;
}

void logToStdout(const rosmon::LogEvent& event)
{
	std::cout << event.message;

	if(!event.message.empty() && event.message.back() != '\n')
		std::cout << '\n';

	if(g_flushStdout)
		fflush(stdout);
}

// Options
static const struct option OPTIONS[] = {
	{"disable-ui", no_argument, nullptr, 'd'},
	{"benchmark", no_argument, nullptr, 'b'},
	{"flush-log", no_argument, nullptr, 'f'},
	{"flush-stdout", no_argument, nullptr, 'F'},
	{"help", no_argument, nullptr, 'h'},
	{"list-args", no_argument, nullptr, 'L'},
	{"log",  required_argument, nullptr, 'l'},
	{"name", required_argument, nullptr, 'n'},
	{"no-start", no_argument, nullptr, 'S'},
	{"stop-timeout", required_argument, nullptr, 's'},
	{"disable-diagnostics", no_argument, nullptr, 'D'},
	{"cpu-limit", required_argument, nullptr, 'c'},
	{"memory-limit", required_argument, nullptr, 'm'},
	{"diagnostics-prefix", required_argument, nullptr, 'p'},
	{"output-attr", required_argument, nullptr, 'o'},
	{nullptr, 0, nullptr, 0}
};

enum Action {
	ACTION_LAUNCH,
	ACTION_BENCHMARK,
	ACTION_LIST_ARGS,
};

int main(int argc, char** argv)
{
	std::string name;
	std::string logFile;
	std::string launchFilePath;

	Action action = ACTION_LAUNCH;
	bool enableUI = true;
	bool flushLog = false;
	bool startNodes = true;
	double stopTimeout = rosmon::launch::LaunchConfig::DEFAULT_STOP_TIMEOUT;
	uint64_t memoryLimit = rosmon::launch::LaunchConfig::DEFAULT_MEMORY_LIMIT;
	float cpuLimit = rosmon::launch::LaunchConfig::DEFAULT_CPU_LIMIT;
	bool disableDiagnostics = false;
	std::string diagnosticsPrefix;
	rosmon::launch::LaunchConfig::OutputAttr outputAttrMode = rosmon::launch::LaunchConfig::OutputAttr::Ignore;

	// Parse options
	while(true)
	{
		int option_index;
		int c = getopt_long(argc, argv, "h", OPTIONS, &option_index);

		if(c == -1)
			break;

		switch(c)
		{
			case 'h':
				usage();
				return 0;
			case 'n':
				name = optarg;
				break;
			case 'l':
				logFile = optarg;
				break;
			case 'L':
				action = ACTION_LIST_ARGS;
				break;
			case 'b':
				action = ACTION_BENCHMARK;
				break;
			case 'd':
				enableUI = false;
				break;
			case 'f':
				flushLog = true;
				break;
			case 'F':
				g_flushStdout = true;
				break;
			case 'S':
				startNodes = false;
				break;
			case 's':
				try
				{
					stopTimeout = boost::lexical_cast<double>(optarg);
				}
				catch(boost::bad_lexical_cast&)
				{
					fmt::print(stderr, "Bad value for --stop-timeout argument: '{}'\n", optarg);
					return 1;
				}

				if(stopTimeout < 0)
				{
					fmt::print(stderr, "Stop timeout cannot be negative\n");
					return 1;
				}
				break;
			case 'D' :
				disableDiagnostics = true;
				break;
			case 'c':
				try
				{
					cpuLimit = boost::lexical_cast<float>(optarg);
				}
				catch(boost::bad_lexical_cast&)
				{
					fmt::print(stderr, "Bad value for --cpu-limit argument: '{}'\n", optarg);
					return 1;
				}

				if(cpuLimit < 0)
				{
					fmt::print(stderr, "CPU Limit cannot be negative\n");
					return 1;
				}
				break;
			case 'm':
			{
				bool ok;
				std::tie(memoryLimit, ok) = rosmon::launch::parseMemory(optarg);
				if(!ok)
				{
					fmt::print(stderr, "Bad value for --memory-limit argument: '{}'\n", optarg);
					return 1;
				}
				break;
			}
			case 'o':
				if(optarg == std::string("obey"))
					outputAttrMode = rosmon::launch::LaunchConfig::OutputAttr::Obey;
				else if(optarg == std::string("ignore"))
					outputAttrMode = rosmon::launch::LaunchConfig::OutputAttr::Ignore;
				else
				{
					fmt::print(stderr, "Bad value for --output-attr argument: '{}'\n", optarg);
					return 1;
				}
				break;
			case 'p':
				fmt::print(stderr, "Prefix : {}", optarg);
				diagnosticsPrefix = std::string(optarg);
				break;
		}
	}

	// Parse the positional arguments
	if(optind == argc)
	{
		usage();
		return 1;
	}

	// Find first launch file argument (must contain ':=')
	int firstArg = optind + 1;
	for(; firstArg < argc; ++firstArg)
	{
		if(strstr(argv[firstArg], ":="))
			break;
	}

	// From the position of the argument (or the end-of-options), we know
	// if we were called with a) package + filename or b) just a path.

	if(firstArg - optind == 1)
	{
		launchFilePath = argv[optind];
	}
	else if(firstArg - optind == 2)
	{
		const char* packageName = argv[optind];
		const char* fileName = argv[optind + 1];

		std::string package = rosmon::PackageRegistry::getPath(packageName);
		if(package.empty())
		{
			fmt::print(stderr, "Could not find path of package '{}'\n", packageName);
			return 1;
		}

		fs::path path = findFile(package, fileName);
		if(path.empty())
		{
			fmt::print(stderr, "Could not find launch file '{}' in package '{}'\n",
				fileName, packageName
			);
			return 1;
		}

		launchFilePath = path.string();
	}
	else
	{
		usage();
		return 1;
	}

	// Setup logging
	boost::scoped_ptr<rosmon::Logger> logger;
	{
		// Setup a sane ROSCONSOLE_FORMAT if the user did not already
		setenv("ROSCONSOLE_FORMAT", "[${function}]: ${message}", 0);

		// Disable direct logging to stdout
		ros::console::backend::function_print = nullptr;

		// Open logger
		if(logFile.empty())
		{
			// Log to /tmp by default

			time_t t = time(nullptr);
			tm currentTime;
			memset(&currentTime, 0, sizeof(currentTime));
			localtime_r(&t, &currentTime);

			char buf[256];
			strftime(buf, sizeof(buf), "/tmp/rosmon_%Y_%m_%d_%H_%M_%S.log", &currentTime);

			logFile = buf;
		}

		logger.reset(new rosmon::Logger(logFile, flushLog));
	}

	rosmon::FDWatcher::Ptr watcher(new rosmon::FDWatcher);

	rosmon::launch::LaunchConfig::Ptr config(new rosmon::launch::LaunchConfig);
	config->setDefaultStopTimeout(stopTimeout);
	config->setDefaultCPULimit(cpuLimit);
	config->setDefaultMemoryLimit(memoryLimit);
	config->setOutputAttrMode(outputAttrMode);

	// Parse launch file arguments from command line
	for(int i = firstArg; i < argc; ++i)
	{
		char* arg = strstr(argv[i], ":=");

		if(!arg)
		{
			fmt::print(stderr, "You specified a non-argument after an argument\n");
			return 1;
		}

		char* name = argv[i];

		*arg = 0;

		char* value = arg + 2;

		config->setArgument(name, value);
	}

	bool onlyArguments = (action == ACTION_LIST_ARGS);

	try
	{
		config->parse(launchFilePath, onlyArguments);
		config->evaluateParameters();
	}
	catch(rosmon::launch::ParseException& e)
	{
		fmt::print(stderr, "Could not load launch file: {}\n", e.what());
		return 1;
	}

	switch(action)
	{
		case ACTION_BENCHMARK:
			return 0;
		case ACTION_LIST_ARGS:
			for(const auto& arg : config->arguments())
				std::cout << arg.first << std::endl;

			return 0;
		case ACTION_LAUNCH:
			break;
	}

	if(config->disableUI())
		enableUI = false;

	// Initialize the ROS node.
	{
		uint32_t init_options = ros::init_options::NoSigintHandler;

		// If the user did not specify a node name on the command line, look in
		// the launch file
		if(name.empty())
			name = config->rosmonNodeName();

		// As last fallback, choose anonymous name.
		if(name.empty())
		{
			name = "rosmon";
			init_options |= ros::init_options::AnonymousName;
		}

		// prevent ros::init from parsing the launch file arguments as remappings
		int dummyArgc = 1;
		ros::init(dummyArgc, argv, name, init_options);
	}

	// Check connectivity to ROS master
	{
		fmt::print("ROS_MASTER_URI: '{}'\n", ros::master::getURI());
		if(ros::master::check())
		{
			fmt::print("roscore is already running.\n");
		}
		else
		{
			fmt::print("roscore is not runnning.\n");
			fmt::print("Waiting until it is up (abort with CTRL+C)...\n");

			while(!ros::master::check())
				ros::WallDuration(0.5).sleep();

			fmt::print("roscore is running now.\n");
		}
	}

	ros::NodeHandle nh;

	fmt::print("Running as '{}'\n", ros::this_node::getName());

    rosmon::monitor::Monitor monitor(config, watcher);
	monitor.logMessageSignal.connect(boost::bind(&rosmon::Logger::log, logger.get(), _1));

	fmt::print("\n\n");
	monitor.setParameters();

	if(config->nodes().empty())
	{
		fmt::print("No ROS nodes to be launched. Finished...\n");
		return 0;
	}

	// Should we automatically start the nodes?
	if(startNodes)
		monitor.start();

	// Start the ncurses UI
	boost::scoped_ptr<rosmon::UI> ui;
	if(enableUI)
	{
		ui.reset(new rosmon::UI(&monitor, watcher));
	}
	else
	{
		monitor.logMessageSignal.connect(logToStdout);
	}

	// ROS interface
    rosmon::ROSInterface rosInterface(&monitor, !disableDiagnostics, diagnosticsPrefix);

	ros::WallDuration waitDuration(0.1);

	// On SIGINT, SIGTERM, SIGHUP we stop gracefully.
	signal(SIGINT, handleSignal);
	signal(SIGHUP, handleSignal);
	signal(SIGTERM, handleSignal);

	// Main loop
	while(ros::ok() && monitor.ok() && !g_shouldStop)
	{
		ros::spinOnce();
		watcher->wait(waitDuration);

		if(ui)
			ui->update();
	}

	if(ui)
		ui->log({"[rosmon]", "Shutting down..."});
	monitor.shutdown();

	// Wait for graceful shutdown
	ros::WallTime start = ros::WallTime::now();
	while(!monitor.allShutdown() && ros::WallTime::now() - start < ros::WallDuration(monitor.shutdownTimeout()))
	{
		watcher->wait(waitDuration);

		if(ui)
			ui->update();
	}

	// If we timed out, force exit (kill the nodes with SIGKILL)
	if(!monitor.allShutdown())
		monitor.forceExit();

	rosInterface.shutdown();

	// Wait until that is finished (should always work)
	while(!monitor.allShutdown())
	{
		watcher->wait(waitDuration);

		if(enableUI)
			ui->update();
	}

	// If coredumps are available, be helpful and display gdb commands
	bool coredumpsAvailable = std::any_of(monitor.nodes().begin(), monitor.nodes().end(),
		[](const rosmon::monitor::NodeMonitor::Ptr& n) { return n->coredumpAvailable(); }
	);

	if(ui && coredumpsAvailable)
	{
		ui->log({"[rosmon]", "\n"});
		ui->log({"[rosmon]", "If you want to debug one of the crashed nodes, you can use the following commands"});
		for(auto& node : monitor.nodes())
		{
			if(node->coredumpAvailable())
			{
				ui->log({
					"[rosmon]",
					fmt::format("{:20}: # {}", node->name(), node->debuggerCommand())
				});
			}
		}
	}

	return 0;
}

max_stars_repo_name: marco-tranzatto/rosmon

max_issues_repo_name: marco-tranzatto/rosmon

max_forks_repo_name: marco-tranzatto/rosmon


text:
/// x86-64 (Linux) register machine class definition.
///
/// @file	PlnX86_64RegisterMachine.cpp
/// @copyright	2019-2021 YAMAGUCHI Toshinobu

#include <vector>
#include <algorithm>
#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
#include <sstream>
#include <boost/assert.hpp>
#include <boost/algorithm/string.hpp>
#include "../PlnModel.h"
#include "PlnX86_64DataAllocator.h"
#include "PlnX86_64Generator.h"
#include "PlnX86_64RegisterMachineImp.h"
#include "PlnX86_64RegisterSave.h"

static const char* r(int rt, int size)
{
	BOOST_ASSERT(rt < REG_NUM);

	static const char* tbl[REG_NUM][4];
	static bool init = false;
	if (!init) {
		init = true;
		tbl[RAX][0] = "%al"; tbl[RAX][1] = "%ax";
		tbl[RAX][2] = "%eax"; tbl[RAX][3] = "%rax";

		tbl[RBX][0] = "%bl"; tbl[RBX][1] = "%bx";
		tbl[RBX][2] = "%ebx"; tbl[RBX][3] = "%rbx";

		tbl[RCX][0] = "%cl"; tbl[RCX][1] = "%cx";
		tbl[RCX][2] = "%ecx"; tbl[RCX][3] = "%rcx";

		tbl[RDX][0] = "%dl"; tbl[RDX][1] = "%dx";
		tbl[RDX][2] = "%edx"; tbl[RDX][3] = "%rdx";

		tbl[RDI][0] = "%dil"; tbl[RDI][1] = "%di";
		tbl[RDI][2] = "%edi"; tbl[RDI][3] = "%rdi";

		tbl[RSI][0] = "%sil"; tbl[RSI][1] = "%si";
		tbl[RSI][2] = "%esi"; tbl[RSI][3] = "%rsi";

		tbl[RBP][0] = "%bpl"; tbl[RBP][1] = "%bp";
		tbl[RBP][2] = "%ebp"; tbl[RBP][3] = "%rbp";

		tbl[RSP][0] = "%spl"; tbl[RSP][1] = "%sp";
		tbl[RSP][2] = "%esp"; tbl[RSP][3] = "%rsp";

		tbl[R8][0] = "%r8b"; tbl[R8][1] = "%r8w";
		tbl[R8][2] = "%r8d"; tbl[R8][3] = "%r8";

		tbl[R9][0] = "%r9b"; tbl[R9][1] = "%r9w";
		tbl[R9][2] = "%r9d"; tbl[R9][3] = "%r9";

		tbl[R10][0] = "%r10b"; tbl[R10][1] = "%r10w";
		tbl[R10][2] = "%r10d"; tbl[R10][3] = "%r10";

		tbl[R11][0] = "%r11b"; tbl[R11][1] = "%r11w";
		tbl[R11][2] = "%r11d"; tbl[R11][3] = "%r11";

		tbl[R12][0] = "%r12b"; tbl[R12][1] = "%r12w";
		tbl[R12][2] = "%r12d"; tbl[R12][3] = "%r12";

		tbl[R13][0] = "%r13b"; tbl[R13][1] = "%r13w";
		tbl[R13][2] = "%r13d"; tbl[R13][3] = "%r13";

		tbl[R14][0] = "%r14b"; tbl[R14][1] = "%r14w";
		tbl[R14][2] = "%r14d"; tbl[R14][3] = "%r14";

		tbl[R15][0] = "%r15b"; tbl[R15][1] = "%r15w";
		tbl[R15][2] = "%r15d"; tbl[R15][3] = "%r15";

		tbl[XMM0][0] = "%xmm0"; tbl[XMM0][1] = "%xmm0";
		tbl[XMM0][2] = "%xmm0"; tbl[XMM0][3] = "%xmm0";

		tbl[XMM1][0] = "%xmm1"; tbl[XMM1][1] = "%xmm1";
		tbl[XMM1][2] = "%xmm1"; tbl[XMM1][3] = "%xmm1";

		tbl[XMM2][0] = "%xmm2"; tbl[XMM2][1] = "%xmm2";
		tbl[XMM2][2] = "%xmm2"; tbl[XMM2][3] = "%xmm2";

		tbl[XMM3][0] = "%xmm3"; tbl[XMM3][1] = "%xmm3";
		tbl[XMM3][2] = "%xmm3"; tbl[XMM3][3] = "%xmm3";

		tbl[XMM4][0] = "%xmm4"; tbl[XMM4][1] = "%xmm4";
		tbl[XMM4][2] = "%xmm4"; tbl[XMM4][3] = "%xmm4";

		tbl[XMM5][0] = "%xmm5"; tbl[XMM5][1] = "%xmm5";
		tbl[XMM5][2] = "%xmm5"; tbl[XMM5][3] = "%xmm5";

		tbl[XMM6][0] = "%xmm6"; tbl[XMM6][1] = "%xmm6";
		tbl[XMM6][2] = "%xmm6"; tbl[XMM6][3] = "%xmm6";

		tbl[XMM7][0] = "%xmm7"; tbl[XMM7][1] = "%xmm7";
		tbl[XMM7][2] = "%xmm7"; tbl[XMM7][3] = "%xmm7";

		tbl[XMM8][0] = "%xmm8"; tbl[XMM8][1] = "%xmm8";
		tbl[XMM8][2] = "%xmm8"; tbl[XMM8][3] = "%xmm8";

		tbl[XMM9][0] = "%xmm9"; tbl[XMM9][1] = "%xmm9";
		tbl[XMM9][2] = "%xmm9"; tbl[XMM9][3] = "%xmm9";

		tbl[XMM10][0] = "%xmm10"; tbl[XMM10][1] = "%xmm10";
		tbl[XMM10][2] = "%xmm10"; tbl[XMM10][3] = "%xmm10";

		tbl[XMM11][0] = "%xmm11"; tbl[XMM11][1] = "%xmm11";
		tbl[XMM11][2] = "%xmm11"; tbl[XMM11][3] = "%xmm11";

		tbl[XMM12][0] = "%xmm12"; tbl[XMM12][1] = "%xmm12";
		tbl[XMM12][2] = "%xmm12"; tbl[XMM12][3] = "%xmm12";

		tbl[XMM13][0] = "%xmm13"; tbl[XMM13][1] = "%xmm13";
		tbl[XMM13][2] = "%xmm13"; tbl[XMM13][3] = "%xmm13";

		tbl[XMM14][0] = "%xmm14"; tbl[XMM14][1] = "%xmm14";
		tbl[XMM14][2] = "%xmm14"; tbl[XMM14][3] = "%xmm14";

		tbl[XMM15][0] = "%xmm15"; tbl[XMM15][1] = "%xmm15";
		tbl[XMM15][2] = "%xmm15"; tbl[XMM15][3] = "%xmm15";

		tbl[RIP][0] = "%rip"; tbl[RIP][1] = "%rip";
		tbl[RIP][2] = "%rip"; tbl[RIP][3] = "%rip";
	}

	if (rt < XMM0) {
		// 1->0, 2->1, 4->2, 8->3
		int i = (size & 7) ? size >> 1 : 3;
		return tbl[rt][i];

	} else {
		int i;
		switch (size) {
			case 4: case 8:
				i = 0; break;
			default:
				BOOST_ASSERT(false);
		}
		return tbl[rt][i];
	}
}

const char* PlnRegOperand::str(char* buf)
{
	return r(regid, size);
}

const char* PlnImmOperand::str(char* buf)
{
	sprintf(buf, "$%ld", value);
	return buf;
}

const char* PlnAdrsModeOperand::str(char* buf)
{
	char *buf2 = buf;
	if (displacement != 0)
		buf2 += sprintf(buf, "%d", displacement);
	if (index_regid == -1) sprintf(buf2, "(%s)", r(base_regid,8));
	else sprintf(buf2, "(%s,%s,%d)", r(base_regid,8), r(index_regid,8), scale);

	return buf;
}

const char* PlnLabelOperand::str(char* buf)
{
	if (id == -1) return label.c_str();
	sprintf(buf, "%s%d", label.c_str(), id);
	return buf;
}

const char* PlnLabelAdrsModeOperand::str(char* buf)
{
	sprintf(buf, "%s(%s)", label.c_str(), r(base_regid,8));
	return buf;
}

static vector<const char*> mnes;

PlnX86_64RegisterMachine::PlnX86_64RegisterMachine()
	:  imp(new PlnX86_64RegisterMachineImp())
{}

static void initMnes()
{
	mnes.reserve(MNE_SIZE);
	mnes[COMMENT] = "#";
	mnes[LABEL] = ":";

	mnes[CALL] = "call";
	mnes[SYSCALL] = "syscall";

	mnes[JMP] = "jmp";
	mnes[JNE] = "jne";
	mnes[JE] = "je";
	mnes[JGE] = "jge";
	mnes[JLE] = "jle";
	mnes[JG] = "jg";
	mnes[JL] = "jl";
	mnes[JAE] = "jae";
	mnes[JBE] = "jbe";
	mnes[JA] = "ja";
	mnes[JB] = "jb";

	mnes[LEA] = "lea";
	mnes[LEAVE] = "leave";
	mnes[RET] = "ret";

	mnes[POPQ] = "popq";
	mnes[PUSHQ] = "pushq";

	mnes[MOVABSQ] = "movabsq";
	mnes[MOVB] = "movb";
	mnes[MOVW] = "movw";
	mnes[MOVL] = "movl";
	mnes[MOVQ] = "movq";
	mnes[MOVSBQ] = "movsbq";
	mnes[MOVSWQ] = "movswq";
	mnes[MOVSLQ] = "movslq";
	mnes[MOVZBQ] = "movzbq";
	mnes[MOVZWQ] = "movzwq";
	mnes[MOVSS] = "movss";
	mnes[MOVSD] = "movsd";

	mnes[ADDSD] = "addsd";
	mnes[ADDSS] = "addss";
	mnes[INCQ] = "incq";
	mnes[ADDQ] = "addq";

	mnes[SUBSD] = "subsd";
	mnes[SUBSS] = "subss";
	mnes[DECQ] = "decq";
	mnes[SUBQ] = "subq";
	mnes[NEGQ] = "negq";

	mnes[MULSD] = "mulsd";
	mnes[MULSS] = "mulss";
	mnes[IMULQ] = "imulq";
	mnes[DIVSD] = "divsd";
	mnes[DIVSS] = "divss";
	mnes[DIVQ] = "divq";
	mnes[CQTO] = "cqto";
	mnes[IDIVQ] = "idivq";

	mnes[XORQ] = "xorq";
	mnes[XORPD] = "xorpd";
	mnes[XORPS] = "xorps";

	mnes[CVTTSD2SI] = "cvttsd2si";
	mnes[CVTTSS2SI] = "cvttss2si";
	mnes[CVTSD2SS] = "cvtsd2ss";
	mnes[CVTSI2SS] = "cvtsi2ss";
	mnes[CVTSI2SD] = "cvtsi2sd";
	mnes[CVTSS2SD] = "cvtss2sd";

	mnes[UCOMISS] = "ucomiss";
	mnes[UCOMISD] = "ucomisd";

	mnes[CMP] = "cmp";
	mnes[CMPB] = "cmpb";
	mnes[CMPW] = "cmpw";
	mnes[CMPL] = "cmpl";
	mnes[CMPQ] = "cmpq";

	mnes[SETE] = "sete";
	mnes[SETNE] = "setne";
	mnes[SETL] = "setl";
	mnes[SETG] = "setg";
	mnes[SETLE] = "setle";
	mnes[SETGE] = "setge";
	mnes[SETB] = "setb";
	mnes[SETA] = "seta";
	mnes[SETBE] = "setbe";
	mnes[SETAE] = "setae";

	mnes[REP_MOVSQ] = "rep movsq";
	mnes[REP_MOVSL] = "rep movsl";
	mnes[REP_MOVSW] = "rep movsw";
	mnes[REP_MOVSB] = "rep movsb";
	mnes[CLD] = "cld";
}

void PlnX86_64RegisterMachine::push(PlnX86_64Mnemonic mne, PlnOperandInfo *src, PlnOperandInfo* dst, string comment)
{
	imp->opecodes.push_back({mne, src, dst, comment});

	// collect optimise information.
	if (mne == CALL) imp->has_call = true;
	else if (mne == SYSCALL) imp->has_call = true;
	else if (mne == RET) imp->ret_num++;

	// Don't use PUSH/POP except RBP.
	BOOST_ASSERT(!((mne == PUSHQ || mne == POPQ) && regid_of(src) != RBP));
}

void PlnX86_64RegisterMachine::reserve(int num)
{
	for (int i=0; i<num; i++)
		imp->opecodes.push_back({MNE_NONE, NULL, NULL, ""});
}

void PlnX86_64RegisterMachine::addComment(const string& comment)
{
	imp->opecodes.back().comment = comment;
}

void PlnX86_64RegisterMachine::memoRequestedStackSize(int size)
{
	imp->requested_stack_size = size;
}

static ostream& operator<<(ostream& out, const PlnOpeCode& oc)
{
	char buf[256];

	if (oc.mne == COMMENT) {
		if (oc.comment != "") out << "# " << oc.comment;
		return out;
	}

	if (oc.mne == LABEL) {
		BOOST_ASSERT(oc.src->type == OP_LBL);
		out << oc.src->str(buf) << ":";
		if (oc.comment != "") out << "	# " << oc.comment;
		return out;
	}

	out << "	" << mnes[oc.mne];
	if (oc.src) out << " " << oc.src->str(buf);
	if (oc.dst) out << ", " << oc.dst->str(buf);
	if (oc.comment != "") out << "	# " << oc.comment;

	return out;
}

// Optimazations
static void removeStackArea(vector<PlnOpeCode> &opecodes);
static void removeOmittableMoveToReg(vector<PlnOpeCode> &opecodes);
static void asmOptimize(vector<PlnOpeCode> &opecodes);

void PlnX86_64RegisterMachine::popOpecodes(ostream& os)
{
	if (!mnes.size())
		initMnes();

	// Optimize
	removeOmittableMoveToReg(imp->opecodes);

	// Add registor save  // ret_num == 0: top level
	if (imp->ret_num == 1) addRegSave(imp->opecodes, imp->requested_stack_size);
	else if (imp->ret_num >= 2) addRegSaveWithCFAnalysis(imp->opecodes, imp->requested_stack_size);

	// Note: It may change RBP->RSP.
	// 		 So this should be execute after removeOmittableMoveToReg().
	if (!imp->has_call)
		removeStackArea(imp->opecodes);

	asmOptimize(imp->opecodes);

	os << ".balign 16\n";
	BOOST_ASSERT(imp->opecodes.front().mne == LABEL);
	PlnX86_64Mnemonic pre_mne = MNE_SIZE;
	for (PlnOpeCode& oc: imp->opecodes) {
		if (oc.mne == LABEL) {
			if (pre_mne == RET || pre_mne == JMP) {
				os << ".balign 2\n";
			}
		}
		if (oc.mne != MNE_NONE)
			os << oc << "\n";
		delete oc.src;
		delete oc.dst;
		if (!(oc.mne == MNE_NONE || oc.mne == COMMENT))
			pre_mne = oc.mne;
	}
	os.flush();
	// reset internal information.
	imp->opecodes.clear();
	imp->has_call = false;
	imp->ret_num = 0;
	imp->requested_stack_size = 0;
}

static void replaceRbp2Rsp(PlnOperandInfo* ope) {
	if (ope) {
		if (ope->type == OP_ADRS) {
			auto addr_ope = static_cast<PlnAdrsModeOperand*>(ope);
			if (addr_ope->base_regid == RBP) {
				addr_ope->base_regid = RSP;
				if (addr_ope->displacement > 0) {
					// adjust affect of remove push rbp
					addr_ope->displacement -= 8;
				}
			}
			BOOST_ASSERT(addr_ope->index_regid != RBP);
		}
		if (ope->type == OP_LBLADRS) {
			BOOST_ASSERT(false);
			// auto lbladdr_ope = static_cast<PlnLabelAdrsModeOperand*>(ope);
			// BOOST_ASSERT(lbladdr_ope->base_regid != RBP);
		}
	}
}

void removeStackArea(vector<PlnOpeCode> &opecodes)
{
	for (auto &opec: opecodes) {
		if ((opec.mne == SUBQ || opec.mne == ADDQ) && opec.dst->type == OP_REG && regid_of(opec.dst) == RSP)
			opec.mne = MNE_NONE;
		else if (opec.mne == MOVQ && opec.src->type == OP_REG && regid_of(opec.src) == RSP
				&& opec.dst->type == OP_REG && regid_of(opec.dst) == RBP)
			opec.mne = MNE_NONE;
		else if (opec.mne == PUSHQ && opec.src->type == OP_REG && regid_of(opec.src) == RBP)
			opec.mne = MNE_NONE;
		else if (opec.mne == POPQ && opec.src->type == OP_REG && regid_of(opec.src) == RBP)
			opec.mne = MNE_NONE;
		else {
			replaceRbp2Rsp(opec.src);
			replaceRbp2Rsp(opec.dst);
		}
	}
}

// Remove omiitalbe move.
enum RegState {
	RS_UNKONWN,
	RS_IMM_INT,
	RS_STACK_VAR,
	RS_REG_VAR
};

class Reg
{
public:
	RegState state;
	struct {
		int displacement;
		int regid;
	} src;
	int size;
};

static void breakRegsInfo(Reg *regs)
{
	// Same as PlnX86_64DataAllocator.cpp
	static const int DSTRY_TBL[] = { RAX, RDI, RSI, RDX, RCX, R8, R9, R10, R11};
	for (int id: DSTRY_TBL)
		regs[id].state = RS_UNKONWN;
	for (int id = XMM0; id<REG_NUM; id++)
		regs[id].state = RS_UNKONWN;

	for (int i=0; i<XMM0; i++) {
		if (regs[i].state == RS_REG_VAR) {
			auto &reg = regs[i];
			if (reg.src.regid >= XMM0) {
				reg.state = RS_UNKONWN;
				continue;
			}
			for (int id: DSTRY_TBL) {
				if (reg.src.regid == id) {
					reg.state = RS_UNKONWN;
					break;
				}
			}
		}
	}
}

void removeOmittableMoveToReg(vector<PlnOpeCode> &opecodes)
{
	Reg regs[REG_NUM];
	for (auto& r: regs)
		r.state = RS_UNKONWN;

	for (auto &opec: opecodes) {
		if (opec.mne == MNE_NONE)
			continue;

		if (opec.dst) {	// 2 params
			if (opec.dst->type == OP_REG) {
				int dst_regid = regid_of(opec.dst);
				auto &reg = regs[dst_regid];
				if (opec.mne == MOVQ) {
					if (opec.src->type == OP_ADRS) {
						auto src = static_cast<PlnAdrsModeOperand*>(opec.src);
						if (src->base_regid == RBP && src->index_regid==-1) {
							// Load local var to the register.
							if (reg.state == RS_STACK_VAR && reg.size == 8
									&& reg.src.displacement == src->displacement) {
								opec.mne = MNE_NONE;
								continue;

							} else {
								reg.state = RS_STACK_VAR;
								reg.size = 8;
								reg.src.displacement = src->displacement;
							}
						} else {
							reg.state = RS_UNKONWN;
						}
					} else if (opec.src->type == OP_REG) {
						auto src = static_cast<PlnRegOperand*>(opec.src);
						if (reg.state == RS_REG_VAR && reg.src.regid == src->regid && reg.size == 8) {
							opec.mne = MNE_NONE;
							continue;
						}
						reg.state = RS_REG_VAR;
						reg.size = 8;
						reg.src.regid = regid_of(opec.src);
					} else {
						reg.state = RS_UNKONWN;
					}
				} else {
					reg.state = RS_UNKONWN;
				}

				for (int i=0; i<REG_NUM; i++) {
					auto &r = regs[i];
					if (r.state == RS_REG_VAR && r.src.regid == dst_regid && i != dst_regid) {
						r.state = RS_UNKONWN;
					}
				}
				continue;
				// end of dst == reg
			} else if (opec.dst->type == OP_ADRS) {
				auto dst = static_cast<PlnAdrsModeOperand*>(opec.dst);
				if (dst->base_regid == RBP && dst->index_regid==-1) {
					// local var update
					for (auto& r: regs) {
						if (r.state == RS_STACK_VAR && r.src.displacement == dst->displacement)
							r.state = RS_UNKONWN;
					}
				}
			}

		} else if (opec.src) {	// 1 param
			if (opec.src->type == OP_REG) {
				switch (opec.mne) {
					case INCQ: case DECQ: case NEGQ:
					case SETE: case SETNE:
					case SETL: case SETG: case SETLE: case SETGE:
					case SETB: case SETA: case SETBE: case SETAE:
						regs[regid_of(opec.src)].state = RS_UNKONWN;
						break;
					case IMULQ: case DIVQ: case CQTO: case IDIVQ:
						regs[RAX].state = RS_UNKONWN;
						regs[RDX].state = RS_UNKONWN;
						break;
					case POPQ:
						regs[regid_of(opec.src)].state = RS_UNKONWN;
						regs[RSP].state = RS_UNKONWN;
						break;
					case PUSHQ:
						regs[RSP].state = RS_UNKONWN;
						break;
					default:
						BOOST_ASSERT(false);
						// break;
				}
			} else if (opec.mne == CALL) {
				breakRegsInfo(regs);
			} else if (opec.mne == LABEL) {
				// Clear all register value.
				for (auto& r: regs)
					r.state = RS_UNKONWN;
			}

		} else { // no param
			switch (opec.mne) {
				case SYSCALL:
					breakRegsInfo(regs);
					break;
				case REP_MOVSQ: case REP_MOVSL:
				case REP_MOVSW: case REP_MOVSB:
					regs[RSI].state = RS_UNKONWN;
					regs[RDI].state = RS_UNKONWN;
					regs[RCX].state = RS_UNKONWN;
					break;
				default:
					break;
			}
		}
	}
}

void asmOptimize(vector<PlnOpeCode> &opecodes)
{
	auto opec = opecodes.begin();
	while (opec != opecodes.end()) {
		if (opec->mne == ADDQ) {
			BOOST_ASSERT(opec->dst->type == OP_REG);
			auto src = opec->src;
			if (src->type == OP_IMM) {
				int64_t i = int64_of(src);
				if (i==0) {
					opec->mne = MNE_NONE;
					continue;
				} else if (i==1) {
					opec->mne = INCQ;
					opec->src = opec->dst;
					opec->dst = NULL;
					delete src;
				} else if (i==-1) {
					opec->mne = DECQ;
					opec->src = opec->dst;
					opec->dst = NULL;
					delete src;
				}
			}
		} else if (opec->mne == SUBQ) {
			BOOST_ASSERT(opec->dst->type == OP_REG);
			auto src = opec->src;
			if (src->type == OP_IMM) {
				int64_t i = int64_of(src);
				if (i==0) {
					opec->mne = MNE_NONE;
					continue;
				} else if (i==1) {
					opec->mne = DECQ;
					opec->src = opec->dst;
					opec->dst = NULL;
					delete src;
				}
			}
		}
		opec++;
	}
}

ext: cpp

max_stars_repo_name: tosyama/palan

max_issues_repo_name: tosyama/palan

max_forks_repo_name: tosyama/palan


text:
#define BOOST_TEST_MODULE FourierTransformTest
#include <boost/test/unit_test.hpp>

// For IO
#include <stdlib.h>
#include <math.h>
#include <cmath>
#include <iostream>
#include <unistd.h>
#include <vector>

// Plotting library
#include <boost/tuple/tuple.hpp>
#include "gnuplot-iostream.h"
#include <utility>

// For measuring elapsed time
#include <chrono>

// For Random Float Generator
#include <time.h>

// For object under test
#include "detector.h"
#include "qam-modulator.h"
#include "common.h"
#include "fftw3.h"

/**
* Test NYQUIST MODULATOR
*
*/
BOOST_AUTO_TEST_SUITE(DetectorTest)

/**
*
*/
BOOST_AUTO_TEST_CASE(CorrelatorTest)
{
    printf("\nTesting Correlator...\n");

    size_t nPoints = 512;
    size_t symbolSize = nPoints*2;
    size_t prefixSize = (int) (symbolSize / 8);
    size_t symbolSizeWithPrefx = symbolSize + prefixSize;
    size_t pilotToneStep = 8;
    size_t bitsPerSymbol = 2;
    double pilotToneAmplitude = 2.0;
    size_t energyDispersalSeed = 10;
    size_t nAvaiableifftPoints = (nPoints - (int)(nPoints/pilotToneStep));
    size_t nMaxEncodedBytes = (int)((nAvaiableifftPoints *  bitsPerSymbol)  / 8);
    size_t nData = nMaxEncodedBytes;

    // Setup random float generator
    srand( (unsigned)time( NULL ) );

    //double modulatorOutput[symbolSizeWithPrefx];
    DoubleVec modulatorOutput;
    modulatorOutput.resize(symbolSizeWithPrefx);

    // Create rx signal array to capable of holding 20 upsampled symbols with prefix
    size_t rxSignalSize = (symbolSizeWithPrefx * 10);
    size_t rxLastAllowedIndex = (symbolSizeWithPrefx * 9);

    DoubleVec rxSignal(rxSignalSize);
    DoubleVec corellatorOutput(rxSignalSize);
    ByteVec txBytes(nData);

    // Initialize Encoder objects
    QamModulator qam(nPoints, pilotToneStep, pilotToneAmplitude, energyDispersalSeed, bitsPerSymbol);
    ofdmFFT ifft(nPoints, FFTW_BACKWARD, pilotToneStep);
    NyquistModulator nyquistModulator(nPoints, ifft.out);

    // Initialize Decoder objects
    ofdmFFT fft(nPoints, FFTW_FORWARD, pilotToneStep);
    NyquistModulator nyquistDemodulator(nPoints, fft.in);
    Detector detector(nPoints, prefixSize, &fft, &nyquistDemodulator);

    // Generate Random Bytes
    for(size_t i = 0; i < nData; i++)
    {
        txBytes[i] = rand() % 255;
    }

    // Generate random index value for symbol start
    size_t  symbolStart = rand() % rxLastAllowedIndex;
    printf("Randomly Generated Symbol Start = %lu\n",symbolStart);

    // Encode one symbol
    qam.Modulate(txBytes, (DoubleVec &) ifft.in, nData);
    ifft.ComputeTransform( (fftw_complex *) &modulatorOutput[prefixSize]);
    nyquistModulator.Modulate( modulatorOutput, prefixSize);
    AddCyclicPrefix(modulatorOutput, symbolSize , prefixSize);
    // Check Prefix Has been added correctly
    for(size_t i = 0 ; i < prefixSize; i++)
    {
        //modulatorOutput[i] = modulatorOutput[symbolSize+i];

        if(modulatorOutput[i] != modulatorOutput[symbolSize + i])
        {
            printf("Missmatch symbolwithprefix[%lu]  = %f, modulatorOutput[%lu] = %f \n" , i , modulatorOutput[i], (symbolSize + i) , modulatorOutput[(symbolSize + i)]);
        }
    }

    // Copy the symbol with prefix to Rx signal array
    std::copy(modulatorOutput.begin(), modulatorOutput.begin()+symbolSizeWithPrefx, rxSignal.begin()+symbolStart);

    // Check if the symbol with prefix has been copied correctly
    for(size_t i = 0 ; i < symbolSizeWithPrefx ; i++)
    {
        if(rxSignal[symbolStart+i] != modulatorOutput[i])
        {
            printf("Missmatch rxSignal[%lu]  = %f, symbolwithprefix[%lu] = %f \n" , symbolStart+i , rxSignal[symbolStart+i], i , modulatorOutput[i]);
        }
    }

    auto start = std::chrono::steady_clock::now();
    for(size_t i = 0; i < rxLastAllowedIndex; i++)
    {
        corellatorOutput[i] = detector.ExecuteCorrelator(rxSignal, i);
    }
    auto end = std::chrono::steady_clock::now();

    std::cout << "Cross-Corellator elapsed time: "
    << std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count()
    << " ns" << std::endl;

    /*
    // Plot modulator output, symbol
    std::vector<double> modOutput(symbolSizeWithPrefx);
    for(uint32_t i = 0; i < symbolSizeWithPrefx; i++)
    {
        modOutput.at(i) = modulatorOutput[i];
    }

    // Plot Corellator output
    std::vector<double> corOutput(rxLastAllowedIndex);
    // Copy Correlator output to vector
    for(uint32_t i = 0; i < rxLastAllowedIndex; i++)
    {
        // Square Result to reduce noise
        corOutput.at(i) = corellatorOutput[i] * corellatorOutput[i];
    }

    Gnuplot gp;
    gp << "plot '-' with line title 'Correlation'\n";
    gp.send1d(corOutput);

    Gnuplot gp1;
    gp1 << "plot '-' with line title 'Symbol with prefix'\n";
    gp1.send1d(modOutput);
    */

    // Find Peak in correlation
    size_t peakIndex = 0;
    double max = 0.0;
    start = std::chrono::steady_clock::now();
    for (size_t i = 0; i < corellatorOutput.size(); i++)
    {
        if(corellatorOutput[i] > max)
        {
            max = corellatorOutput[i];
            peakIndex = i;
        }
    }
    end = std::chrono::steady_clock::now();

    std::cout << "Peak Search elapsed time: "
    << std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count()
    << " ns" << std::endl;

    // Check if the correlator max output is where the symbol was inserted
    BOOST_CHECK_MESSAGE( (peakIndex == symbolStart),
    "Symbol start has not been detected correctly, The max correlation occurs at index =  " << peakIndex );

}

BOOST_AUTO_TEST_CASE(SymbolStartTest)
{
    printf("\nTesting Symbol Start Search...\n");

    size_t nPoints = 512;
    size_t symbolSize = nPoints*2;
    size_t prefixSize = (int) (symbolSize / 8);
    size_t symbolSizeWithPrefx = symbolSize + prefixSize;
    size_t pilotToneStep = 8;
    double pilotToneAmplitude = 2.0;
    size_t energyDispersalSeed = 10;
    size_t bitsPerSymbol = 2;

    // Setup random float generator
    srand( (unsigned)time( NULL ) );

    // Create rx signal array to capable of holding 20 upsampled symbols with prefix
    size_t  rxSignalSize = (symbolSizeWithPrefx * 10);
    size_t  rxLastAllowedIndex = (symbolSizeWithPrefx * 9);

    // Generate random index value for symbol start
    size_t  symbolStart = rand() % rxLastAllowedIndex;
    printf("Randomly Generated Symbol Start = %lu\n",symbolStart);

    size_t nAvaiableifftPoints = (nPoints - (int)(nPoints/pilotToneStep));
    size_t nMaxEncodedBytes = (int)((nAvaiableifftPoints *  bitsPerSymbol)  / 8);
    size_t nData = nMaxEncodedBytes;

    ByteVec txBytes(nData);
    DoubleVec EncoderOutput(symbolSizeWithPrefx);
    DoubleVec rxSignal(rxSignalSize);

    // Initialize Encoder objects
    QamModulator qam(nPoints, pilotToneStep, pilotToneAmplitude, energyDispersalSeed, bitsPerSymbol);
    ofdmFFT ifft(nPoints, FFTW_BACKWARD, pilotToneStep);
    NyquistModulator nyquistModulator(nPoints, ifft.out);

    // Initialize Decoder objects
    ofdmFFT fft(nPoints, FFTW_FORWARD, pilotToneStep);
    NyquistModulator nyquistDemodulator(nPoints, fft.in);
    Detector detector(nPoints, prefixSize, &fft, &nyquistDemodulator);

    // Randomly fill ifft input
    for(size_t i = 0; i < nData; i++)
    {
        txBytes[i] = rand() % 255;
    }

    // Encode one symbol
    // (fftw_complex *) &output[GetSettings().cyclicPrefixSize]);
    qam.Modulate(txBytes, (DoubleVec &) ifft.in, nData);
    ifft.ComputeTransform( (fftw_complex *) &EncoderOutput[prefixSize]);
    nyquistModulator.Modulate( EncoderOutput, prefixSize);
    AddCyclicPrefix(EncoderOutput, symbolSize , prefixSize);

    // Copy the symbol with prefix to Rx signal array
    std::copy(EncoderOutput.begin(), EncoderOutput.begin()+symbolSizeWithPrefx, rxSignal.begin()+symbolStart);
    // Check if the symbol with prefix has been copied correctly
    for(size_t i = 0 ; i < symbolSizeWithPrefx ; i++)
    {
        if(rxSignal[symbolStart+i] != EncoderOutput[i])
        {
            printf("Missmatch rxSignal[%lu]  = %f, symbolwithprefix[%lu] = %f \n" , symbolStart+i , rxSignal[symbolStart+i], i , EncoderOutput[i]);
        }
    }

    size_t CoarseSearchIndex = 0;
    auto start = std::chrono::steady_clock::now();
    CoarseSearchIndex = detector.CoarseSearch(rxSignal);
    auto end = std::chrono::steady_clock::now();

    std::cout << "Coarse Search elapsed time: "
    << std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count()
    << " ns" << std::endl;

    // Check if the correlator max output is where the symbol was inserted
    BOOST_CHECK_MESSAGE( (CoarseSearchIndex == symbolStart),
    "Symbol start has not been detected correctly, The peak occurs at index: " << CoarseSearchIndex );

    printf("Coarse Search Index = %lu\n", CoarseSearchIndex);

    // Skip the prefix
    size_t symbolStartIndex = CoarseSearchIndex + prefixSize;
    printf("Symbol Start Index = %lu\n", symbolStartIndex);
    // Randomly change the Coarse Start by up to +/- 9 indexes
    size_t symbolStartOffsetIndex = symbolStartIndex + (rand() % 19 + (-9));

    start = std::chrono::steady_clock::now();
    size_t FineSearchSymbolIndex = detector.FineSearch(rxSignal, symbolStartOffsetIndex, nData);
    end = std::chrono::steady_clock::now();

    std::cout << "Fine Search elapsed time: "
    << std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count()
    << " ns" << std::endl;

    printf("Fine Search Index = %lu\n", FineSearchSymbolIndex);

    // Check if the fine search corresponds to symbol start
    BOOST_CHECK_MESSAGE( (FineSearchSymbolIndex == symbolStart+prefixSize),
    "Symbol start has not been detected correctly, The lowest img sum occurs at start index: " << FineSearchSymbolIndex );

}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: krogk/ofdmlib

max_issues_repo_name: krogk/ofdmlib

max_forks_repo_name: krogk/ofdmlib


text:
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    http://spirit.sourceforge.net/

  Distributed under the Boost Software License, Version 1.0. (See accompanying
  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_PARSER_HPP)
#define BOOST_SPIRIT_PARSER_HPP

#include <boost/config.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/scanner/scanner.hpp>
#include <boost/spirit/home/classic/core/nil.hpp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    template <typename ParserT, typename ActionT>
    class action; //  forward declaration

    ///////////////////////////////////////////////////////////////////////////
    //
    //  Parser categories
    //
    //      Helper template classes to distinguish different types of
    //      parsers. The following categories are the most generic. More
    //      specific types may inherit from these. Each parser has a typedef
    //      parser_category_t that defines its category. By default, if one
    //      is not specified, it will inherit from the base parser class
    //      which typedefs its parser_category_t as plain_parser_category.
    //
    //          - plain parser has nothing special
    //          - binary parser has subject a and b (e.g. alternative)
    //          - unary parser has single subject  (e.g. kleene star)
    //          - action parser has an attached action parser
    //
    ///////////////////////////////////////////////////////////////////////////
    struct plain_parser_category {};
    struct binary_parser_category       : plain_parser_category {};
    struct unary_parser_category        : plain_parser_category {};
    struct action_parser_category       : unary_parser_category {};

    ///////////////////////////////////////////////////////////////////////////
    //
    //  parser_result metafunction
    //
    //      Given a scanner type ScannerT and a parser type ParserT, the
    //      parser_result metafunction provides the actual result of the
    //      parser.
    //
    //  Usage:
    //
    //      typename parser_result<ParserT, ScannerT>::type
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename ParserT, typename ScannerT>
    struct parser_result
    {
        typedef typename boost::remove_reference<ParserT>::type parser_type;
        typedef typename parser_type::template result<ScannerT>::type type;
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  parser class
    //
    //      This class is a protocol base class for all parsers. This is
    //      essentially an interface contract. The parser class does not
    //      really know how to parse anything but instead relies on the
    //      template parameter DerivedT (which obviously is assumed to be a
    //      subclass) to do the actual parsing.
    //
    //      Concrete sub-classes inheriting from parser must have a
    //      corresponding member function parse(...) compatible with the
    //      conceptual Interface:
    //
    //          template <typename ScannerT>
    //          RT parse(ScannerT const& scan) const;
    //
    //      where RT is the desired return type of the parser and ScannerT
    //      scan is the scanner (see scanner.hpp).
    //
    //      Concrete sub-classes inheriting from parser in most cases need to
    //      have a nested meta-function result that returns the result type
    //      of the parser's parse member function, given a scanner type. The
    //      meta-function has the form:
    //
    //          template <typename ScannerT>
    //          struct result
    //          {
    //              typedef RT type;
    //          };
    //
    //      where RT is the desired return type of the parser. This is
    //      usually, but not always, dependent on the template parameter
    //      ScannerT. If a parser does not supply a result metafunction, a
    //      default is provided by the base parser class.
    //
    //      The parser's derived() member function returns a reference to the
    //      parser as its derived object.
    //
    //      An operator[] is provided. The operator returns a semantic action
    //      handler (see actions.hpp).
    //
    //      Each parser has a typedef embed_t. This typedef specifies how a
    //      parser is embedded in a composite (see composite.hpp). By
    //      default, if one is not specified, the parser will be embedded by
    //      value. That is, a copy of the parser is placed as a member
    //      variable of the composite. Most parsers are embedded by value. In
    //      certain situations however, this is not desirable or possible.
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename DerivedT>
    struct parser
    {
        typedef DerivedT                embed_t;
        typedef DerivedT                derived_t;
        typedef plain_parser_category   parser_category_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename match_result<ScannerT, nil_t>::type type;
        };

        DerivedT& derived()
        {
            return *static_cast<DerivedT*>(this);
        }

        DerivedT const& derived() const
        {
            return *static_cast<DerivedT const*>(this);
        }

        template <typename ActionT>
        action<DerivedT, ActionT>
        operator[](ActionT const& actor) const
        {
            return action<DerivedT, ActionT>(derived(), actor);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  parse_info
    //
    //      Results returned by the free parse functions:
    //
    //      stop:   points to the final parse position (i.e parsing
    //              processed the input up to this point).
    //
    //      hit:    true if parsing is successful. This may be full:
    //              the parser consumed all the input, or partial:
    //              the parser consumed only a portion of the input.
    //
    //      full:   true when we have a full hit (i.e the parser
    //              consumed all the input.
    //
    //      length: The number of characters consumed by the parser.
    //              This is valid only if we have a successful hit
    //              (either partial or full).
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename IteratorT = char const*>
    struct parse_info
    {
        IteratorT   stop;
        bool        hit;
        bool        full;
        std::size_t length;

        parse_info(
            IteratorT const& stop_ = IteratorT(),
            bool hit_ = false,
            bool full_ = false,
            std::size_t length_ = 0)
        : stop(stop_)
        , hit(hit_)
        , full(full_)
        , length(length_) {}

        template <typename ParseInfoT>
        parse_info(ParseInfoT const& pi)
        : stop(pi.stop)
        , hit(pi.hit)
        , full(pi.full)
        , length(pi.length) {}
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  Generic parse function
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename IteratorT, typename DerivedT>
    parse_info<IteratorT>
    parse(
        IteratorT const&        first,
        IteratorT const&        last,
        parser<DerivedT> const& p);

    ///////////////////////////////////////////////////////////////////////////
    //
    //  Parse function for null terminated strings
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename CharT, typename DerivedT>
    parse_info<CharT const*>
    parse(
        CharT const*            str,
        parser<DerivedT> const& p);

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#endif

#include <boost/spirit/home/classic/core/impl/parser.ipp>

ext: hpp

max_stars_repo_name: rudylee/expo

max_issues_repo_name: rudylee/expo

max_forks_repo_name: rudylee/expo


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

/**
 * @brief BibTeX entry.
 * @file bibtexentry.hpp
 * @author Sergiu Dotenco
 * @version 0.1
 */

#ifndef BIBTEXENTRY_HPP
#define BIBTEXENTRY_HPP

#pragma once

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

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/operators.hpp>
#include <boost/optional.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/typeof/typeof.hpp>

#ifndef BOOST_SPIRIT_AUTO
#define BOOST_SPIRIT_AUTO(domain_, name, expr)                \
    typedef boost::proto::result_of::                         \
        deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \
    BOOST_SPIRIT_ASSERT_MATCH(                                \
        boost::spirit::domain_::domain, name##_expr_type);    \
    BOOST_AUTO(const name, boost::proto::deep_copy(expr));
#endif // BOOST_SPIRIT_AUTO

namespace bibtex {

namespace detail {

namespace encoding = boost::spirit::standard_wide;

} // namespace detail

typedef std::vector<std::string> ValueVector;
typedef std::pair<std::string, ValueVector> KeyValue;
typedef std::vector<KeyValue> KeyValueVector;
typedef detail::encoding::space_type Space;

BOOST_SPIRIT_AUTO(qi, space, detail::encoding::space |
    '%' >> *(boost::spirit::qi::char_ - boost::spirit::qi::eol)
    >> boost::spirit::qi::eol)

/**
 * @brief Single BibTeX entry.
 */
struct BibTeXEntry
    : boost::equality_comparable<BibTeXEntry>
{
    //! Entry's tag.
    std::string tag;
    //! Entry's optional key.
    boost::optional<std::string> key;
    //! Entry's key/value pairs.
    KeyValueVector fields;
};

inline bool operator==(const BibTeXEntry& lhs, const BibTeXEntry& rhs)
{
    return lhs.tag == rhs.tag && lhs.tag == rhs.tag &&
        lhs.fields == rhs.fields;
}

} // namespace bibtex

BOOST_FUSION_ADAPT_STRUCT(
    bibtex::BibTeXEntry,
    (std::string, tag)
    (boost::optional<std::string>, key)
    (bibtex::KeyValueVector, fields)
)

#endif // BIBTEXENTRY_HPP

max_stars_repo_name: cdmh/bibtex-spirit

max_issues_repo_name: cdmh/bibtex-spirit

max_forks_repo_name: cdmh/bibtex-spirit


text:
//
//  eccGroup.hpp
//  kcalg
//
//  Created by knightc on 2019/7/26.
//  Copyright © 2019 knightc. All rights reserved.
//

#ifndef eccGroup_hpp
#define eccGroup_hpp

#include <stdio.h>

#include <NTL/ZZ.h>

using namespace std;
using namespace NTL;

class kc_eccGroup {

public:
    kc_eccGroup();

};

#endif /* eccGroup_hpp */


text:
/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

#ifndef MYSQLC_CONNECTION_HXX
#define MYSQLC_CONNECTION_HXX

#include "mysqlc_subcomponent.hxx"
#include "mysqlc_types.hxx"

#include <boost/shared_ptr.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/sdbc/ColumnSearch.hpp>
#include <com/sun/star/sdbc/ColumnValue.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/sdbc/SQLWarning.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
#include <com/sun/star/util/XStringSubstitution.hpp>

#include <preextstl.h>
#include <cppconn/driver.h>
#include <postextstl.h>
#include <cppuhelper/compbase3.hxx>
#include <cppuhelper/weakref.hxx>
#include <rtl/string.hxx>

#include <map>

#define UNUSED_PARAM __attribute__((unused))

namespace sql
{
    class SQLException;
}

namespace connectivity
{
	class OMetaConnection;
	class ODatabaseMetaData;

	namespace mysqlc
	{
		using ::rtl::OUString;
		using ::com::sun::star::sdbc::SQLWarning;
		using ::com::sun::star::sdbc::SQLException;
		using ::com::sun::star::uno::RuntimeException;
		typedef ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XStatement > my_XStatementRef;
		typedef ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > my_XPreparedStatementRef;
		typedef ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > my_XNameAccessRef;
		typedef ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData > my_XDatabaseMetaDataRef;

		typedef ::cppu::WeakComponentImplHelper3<	::com::sun::star::sdbc::XConnection,
													::com::sun::star::sdbc::XWarningsSupplier,
													::com::sun::star::lang::XServiceInfo
												> OMetaConnection_BASE;
		struct ConnectionSettings
		{
			rtl_TextEncoding encoding;
			std::auto_ptr<sql::Connection> cppConnection;
			OUString schema;
			OUString quoteIdentifier;
            OUString connectionURL;
			sal_Bool readOnly;
		};

		class MysqlCDriver;

		typedef OMetaConnection_BASE OConnection_BASE;

		typedef std::vector< ::com::sun::star::uno::WeakReferenceHelper > OWeakRefArray;

		class OConnection : public OBase_Mutex,
							public OConnection_BASE,
							public connectivity::mysqlc::OSubComponent<OConnection, OConnection_BASE>
		{
			friend class connectivity::mysqlc::OSubComponent<OConnection, OConnection_BASE>;

        private:
			ConnectionSettings  m_settings;

		private:
			::com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > m_typeMap;
            ::com::sun::star::uno::Reference< com::sun::star::util::XStringSubstitution > m_xParameterSubstitution;
		protected:

			//====================================================================
			// Data attributes
			//====================================================================
			::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData;

			OWeakRefArray	m_aStatements;	// vector containing a list
											// of all the Statement objects
											// for this Connection

			SQLWarning	    m_aLastWarning;	// Last SQLWarning generated by an operation
			OUString	    m_aURL;			// URL of connection
			OUString	    m_sUser;		// the user name
			MysqlCDriver&   m_rDriver;	    // Pointer to the owning driver object
			sql::Driver*    cppDriver;

			sal_Bool	m_bClosed;
			sal_Bool	m_bUseCatalog;	// should we use the catalog on filebased databases
			sal_Bool	m_bUseOldDateFormat;

			void		buildTypeInfo() throw(SQLException);
		public:
			OUString getMysqlVariable(const char *varname)
																throw(SQLException, RuntimeException);

			sal_Int32 getMysqlVersion()
																throw(SQLException, RuntimeException);

			virtual void construct(const OUString& url,const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info)
																throw(SQLException);

			OConnection(MysqlCDriver& _rDriver, sql::Driver * cppDriver);
			virtual ~OConnection();

			void closeAllStatements ()							throw(SQLException);

			rtl_TextEncoding getConnectionEncoding() { return m_settings.encoding; }

			// OComponentHelper
			virtual void SAL_CALL disposing(void);

			// XInterface
			virtual void SAL_CALL release()						throw();

			// XServiceInfo
			DECLARE_SERVICE_INFO();
			// XConnection
			my_XStatementRef SAL_CALL createStatement()
																throw(SQLException, RuntimeException);

			my_XPreparedStatementRef SAL_CALL prepareStatement(const OUString& sql)
																throw(SQLException, RuntimeException);

			my_XPreparedStatementRef SAL_CALL prepareCall(const OUString& sql)
																throw(SQLException, RuntimeException);

			OUString SAL_CALL nativeSQL(const OUString& sql)
																throw(SQLException, RuntimeException);

			void SAL_CALL setAutoCommit(sal_Bool autoCommit)
																throw(SQLException, RuntimeException);

			sal_Bool SAL_CALL getAutoCommit()
																throw(SQLException, RuntimeException);

			void SAL_CALL commit()
																throw(SQLException, RuntimeException);

			void SAL_CALL rollback()
																throw(SQLException, RuntimeException);

			sal_Bool SAL_CALL isClosed()
																throw(SQLException, RuntimeException);

			my_XDatabaseMetaDataRef SAL_CALL getMetaData()
																throw(SQLException, RuntimeException);

			void SAL_CALL setReadOnly(sal_Bool readOnly)
																throw(SQLException, RuntimeException);

			sal_Bool SAL_CALL isReadOnly()
																throw(SQLException, RuntimeException);

			void SAL_CALL setCatalog(const OUString& catalog)
																throw(SQLException, RuntimeException);

			OUString SAL_CALL getCatalog()
																throw(SQLException, RuntimeException);

			void SAL_CALL setTransactionIsolation(sal_Int32 level)
																throw(SQLException, RuntimeException);

			sal_Int32 SAL_CALL getTransactionIsolation()
																throw(SQLException, RuntimeException);

			my_XNameAccessRef SAL_CALL getTypeMap()
																throw(SQLException, RuntimeException);

			void SAL_CALL setTypeMap(const my_XNameAccessRef& typeMap)
																throw(SQLException, RuntimeException);
			// XCloseable
			void SAL_CALL close()
																throw(SQLException, RuntimeException);
			// XWarningsSupplier
			::com::sun::star::uno::Any SAL_CALL getWarnings()
																throw(SQLException, RuntimeException);
			void SAL_CALL clearWarnings()
																throw(SQLException, RuntimeException);

            // TODO: Not used
			//sal_Int32 sdbcColumnType(OUString typeName);
            inline const ConnectionSettings& getConnectionSettings() const { return m_settings; }
            ::rtl::OUString transFormPreparedStatement(const ::rtl::OUString& _sSQL);

			// should we use the catalog on filebased databases
            inline sal_Bool			    isCatalogUsed()     const { return m_bUseCatalog; }
            inline OUString			    getUserName()       const { return m_sUser; }
            inline const MysqlCDriver&  getDriver()			const { return m_rDriver;}
            inline rtl_TextEncoding	    getTextEncoding()	const { return m_settings.encoding; }

		}; /* OConnection */
        // TODO: Not used.
		//inline OUString getPattern(OUString p) { return (p.getLength()) ? p : ASC2OU("%"); }
	} /* mysqlc */
} /* connectivity */
#endif // MYSQLC_CONNECTION_HXX

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */

ext: hxx

max_stars_repo_name: Grosskopf/openoffice

max_issues_repo_name: Grosskopf/openoffice

max_forks_repo_name: Grosskopf/openoffice


text:
// Luaponte library

// Copyright (c) 2012 Peter Colberg

// Luaponte is based on Luabind, a library, inspired by and similar to
// Boost.Python, that helps you create bindings between C++ and Lua,
// Copyright (c) 2003-2010 Daniel Wallin and Arvid Norberg.

// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef LUAPONTE_VALUE_WRAPPER_HPP
#define LUAPONTE_VALUE_WRAPPER_HPP

#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/aux_/msvc_eti_base.hpp>

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
# define LUAPONTE_USE_VALUE_WRAPPER_TAG
#else
#endif

#ifdef LUAPONTE_USE_VALUE_WRAPPER_TAG
# include <boost/mpl/identity.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/has_xxx.hpp>
# include <boost/mpl/not.hpp>
# include <boost/mpl/and.hpp>
# include <boost/mpl/or.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/is_pointer.hpp>
# include <boost/type_traits/is_array.hpp>
#endif

namespace luaponte {

//
// Concept ``ValueWrapper``
//

#ifdef LUAPONTE_USE_VALUE_WRAPPER_TAG
template<class T>
struct value_wrapper_traits;

namespace detail {

  BOOST_MPL_HAS_XXX_TRAIT_DEF(value_wrapper_tag);

  struct unspecialized_value_wrapper_traits
  {
      typedef boost::mpl::false_ is_specialized;
  };

  template<class T>
  struct value_wrapper_traits_aux
  {
      typedef value_wrapper_traits<typename T::value_wrapper_tag> type;
  };

} // namespace detail
#endif

template<class T>
struct value_wrapper_traits
#ifdef LUAPONTE_USE_VALUE_WRAPPER_TAG
  : boost::mpl::eval_if<
        boost::mpl::and_<
            boost::mpl::not_<
                boost::mpl::or_<
                    boost::is_reference<T>
                  , boost::is_pointer<T>
                  , boost::is_array<T>
                >
            >
          , detail::has_value_wrapper_tag<T>
        >
      , detail::value_wrapper_traits_aux<T>
      , boost::mpl::identity<detail::unspecialized_value_wrapper_traits>
    >::type
{};
#else
{
    typedef boost::mpl::false_ is_specialized;
};
#endif

template<class T>
struct is_value_wrapper
  : boost::mpl::aux::msvc_eti_base<
        typename value_wrapper_traits<T>::is_specialized
    >::type
{};

} // namespace luaponte

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

# include <boost/type_traits/remove_const.hpp>
# include <boost/type_traits/remove_reference.hpp>

namespace luaponte {

template<class T>
struct is_value_wrapper_arg
  : is_value_wrapper<
      typename boost::remove_const<
          typename boost::remove_reference<T>::type
      >::type
    >
{};

} // namespace luaponte

#else

# include <luaponte/detail/yes_no.hpp>
# include <boost/type_traits/add_reference.hpp>

namespace luaponte {
namespace detail {

  template<class T>
  typename is_value_wrapper<T>::type is_value_wrapper_arg_check(T const*);

  yes_t to_yesno(boost::mpl::true_);
  no_t to_yesno(boost::mpl::false_);

  template<class T>
  struct is_value_wrapper_arg_aux
  {
      static typename boost::add_reference<T>::type x;

      BOOST_STATIC_CONSTANT(bool, value =
          sizeof(to_yesno(is_value_wrapper_arg_check(&x)))
            == sizeof(yes_t)
      );

      typedef boost::mpl::bool_<value> type;
  };

} // namespace detail

template<class T>
struct is_value_wrapper_arg
  : detail::is_value_wrapper_arg_aux<T>::type
{
};

} // namespace luaponte

#endif

#endif // LUAPONTE_VALUE_WRAPPER_HPP

max_stars_repo_name: jb--/luaponte

max_issues_repo_name: halmd-org/luaponte

max_forks_repo_name: halmd-org/luaponte


text:
//
//  monero_wallet_utils.cpp
//  MyMonero
//
//  Created by Paul Shapiro on 11/23/17.
//  Copyright (c) 2014-2018, MyMonero.com
//
//  All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without modification, are
//  permitted provided that the following conditions are met:
//
//  1. Redistributions of source code must retain the above copyright notice, this list of
//	conditions and the following disclaimer.
//
//  2. Redistributions in binary form must reproduce the above copyright notice, this list
//	of conditions and the following disclaimer in the documentation and/or other
//	materials provided with the distribution.
//
//  3. Neither the name of the copyright holder nor the names of its contributors may be
//	used to endorse or promote products derived from this software without specific
//	prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
//  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
//  THE COPYRIGHT 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.
//
//
//
#include "monero_wallet_utils.hpp"
#include <boost/algorithm/string.hpp>
#include "cryptonote_basic/account.h"
//
#include "string_tools.h"
using namespace epee;
//
extern "C" {
	#include "crypto-ops.h"
}
//
using namespace monero_wallet_utils;
using namespace crypto; // for extension
//
bool monero_wallet_utils::new_wallet(
    std::string mnemonic_language,
	WalletDescriptionRetVals &retVals,
	bool isTestnet
)
{
	retVals = {};
	//
	cryptonote::account_base account{}; // this initializes the wallet and should call the default constructor
	crypto::secret_key nonLegacy32B_sec_seed = account.generate();
	//
	const cryptonote::account_keys& keys = account.get_keys();
	std::string address_string = account.get_public_address_str(isTestnet); // getting the string here instead of leaving it to the consumer b/c get_public_address_str could potentially change in implementation (see TODO) so it's not right to duplicate that here
	//
	std::string mnemonic_string;
	bool r = crypto::ElectrumWords::bytes_to_words(nonLegacy32B_sec_seed, mnemonic_string, std::move(mnemonic_language));
	// ^-- it's OK to directly call ElectrumWords w/ crypto::secret_key as we are generating new wallet, not reading
	if (!r) {
		retVals.did_error = true;
		retVals.err_string = "Unable to create new wallet";
		// TODO: return code of unable to convert seed to mnemonic
		//
		return false;
	}
	retVals.optl__desc =
	{
		string_tools::pod_to_hex(nonLegacy32B_sec_seed),
		//
		address_string,
		//
		keys.m_spend_secret_key,
		keys.m_view_secret_key,
		keys.m_account_address.m_spend_public_key,
		keys.m_account_address.m_view_public_key,
		//
		mnemonic_string
	};
	return true;
}
//
bool monero_wallet_utils::decoded_seed(
	std::string mnemonic_string,
	std::string mnemonic_language,
	MnemonicDecodedSeed_RetVals &retVals
) {
	retVals = {};
	//
	// sanitize inputs
	if (mnemonic_string.empty()) {
		retVals.did_error = true;
		retVals.err_string = "Please enter a valid seed";
		//
		return false;
	}
	boost::algorithm::to_lower(mnemonic_string); // critical
	// TODO: strip wrapping whitespace? anything else?
	//
	std::stringstream stream(mnemonic_string); // to count words…
	unsigned long word_count = std::distance(std::istream_iterator<std::string>(stream), std::istream_iterator<std::string>());
	//	unsigned long word_count = boost::range::distance(boost::algorithm::make_split_iterator(mnemonic_string, boost::algorithm::is_space())); // TODO: get this workin
	//
	crypto::secret_key sec_seed;
	std::string sec_seed_string; // TODO/FIXME: needed this for shared ref outside of if branch below… not intending extra default constructor call but not sure how to get around it yet
	bool from_legacy16B_lw_seed = false;
	if (word_count == crypto::ElectrumWords::stable_32B_seed_mnemonic_word_count) {
		from_legacy16B_lw_seed = false; // to be clear
		bool r = crypto::ElectrumWords::words_to_bytes(mnemonic_string, sec_seed, mnemonic_language);
		if (!r) {
			retVals.did_error = true;
			retVals.err_string = "Invalid 25-word mnemonic";
			//
			return false;
		}
		sec_seed_string = string_tools::pod_to_hex(sec_seed);
	} else if (word_count == crypto::ElectrumWords::legacy_16B_seed_mnemonic_word_count) {
		from_legacy16B_lw_seed = true;
		crypto::legacy16B_secret_key legacy16B_sec_seed;
		bool r = crypto::ElectrumWords::words_to_bytes(mnemonic_string, legacy16B_sec_seed, mnemonic_language); // special 16 byte function
		if (!r) {
			retVals.did_error = true;
			retVals.err_string = "Invalid 13-word mnemonic";
			//
			return false;
		}
		crypto::coerce_valid_sec_key_from(legacy16B_sec_seed, sec_seed);
		sec_seed_string = string_tools::pod_to_hex(legacy16B_sec_seed); // <- NOTE: we are returning the _LEGACY_ seed as the string… this is important so we don't lose the fact it was 16B/13-word originally!
	} else {
		retVals.did_error = true;
		retVals.err_string = "Please enter a 25- or 13-word secret mnemonic.";
		//
		return false;
	}
	retVals.optl__sec_seed = sec_seed;
	retVals.optl__sec_seed_string = sec_seed_string;
	retVals.optl__mnemonic_string = mnemonic_string;
	retVals.from_legacy16B_lw_seed = from_legacy16B_lw_seed;
	//
	return true;
}
//
bool monero_wallet_utils::wallet_with(
	std::string mnemonic_string,
	std::string mnemonic_language,
	WalletDescriptionRetVals &retVals,
	bool isTestnet
) {
	retVals = {};
	//
	MnemonicDecodedSeed_RetVals decodedSeed_retVals;
	bool r = decoded_seed(std::move(mnemonic_string), std::move(mnemonic_language), decodedSeed_retVals);
	if (!r) {
		retVals.did_error = true;
		retVals.err_string = *decodedSeed_retVals.err_string; // TODO: assert?
		return false;
	}
	cryptonote::account_base account{}; // this initializes the wallet and should call the default constructor
	account.generate(
		*decodedSeed_retVals.optl__sec_seed, // is this an extra copy? maybe have consumer pass ref as arg instead
		true/*recover*/,
		false/*two_random*/,
		decodedSeed_retVals.from_legacy16B_lw_seed // assumed set if r
	);
	const cryptonote::account_keys& keys = account.get_keys();
	retVals.optl__desc =
	{
		*decodedSeed_retVals.optl__sec_seed_string, // assumed non nil if r
		//
		account.get_public_address_str(isTestnet),
		//
		keys.m_spend_secret_key,
		keys.m_view_secret_key,
		keys.m_account_address.m_spend_public_key,
		keys.m_account_address.m_view_public_key,
		//
		*decodedSeed_retVals.optl__mnemonic_string, // assumed non nil if r; copied for return
	};
	return true;
}

bool monero_wallet_utils::validate_wallet_components_with(
	const WalletComponentsToValidate &inputs,
	WalletComponentsValidationResults &outputs
)
{ // TODO: how can the err_strings be prepared for localization?
	outputs = {};
	bool r = false;
	//
	// Address
	cryptonote::address_parse_info decoded_address_info;
	r = cryptonote::get_account_address_from_str(
		decoded_address_info,
		inputs.isTestnet,
		inputs.address_string
	);
	if (r == false) {
		outputs.did_error = true;
		outputs.err_string = "Invalid address";
		//
		return false;
	}
	//
	// View key:
	crypto::secret_key sec_viewKey;
	r = string_tools::hex_to_pod(inputs.sec_viewKey_string, sec_viewKey);
	if (r == false) {
		outputs.did_error = true;
		outputs.err_string = "Invalid view key";
		//
		return false;
	}
	// Validate pub key derived from sec view key matches decoded_address-cached pub key
	crypto::public_key expected_pub_viewKey;
	r = crypto::secret_key_to_public_key(sec_viewKey, expected_pub_viewKey);
	if (r == false) {
		outputs.did_error = true;
		outputs.err_string = "Invalid view key";
		//
		return false;
	}
	if (decoded_address_info.address.m_view_public_key != expected_pub_viewKey) {
		outputs.did_error = true;
		outputs.err_string = "View key does not match address";
		//
		return false;
	}
	//
	// View-only vs spend-key/seed
	outputs.isInViewOnlyMode = true; // setting the ground state
	//
	crypto::secret_key sec_spendKey; // may be initialized
	if (inputs.optl__sec_spendKey_string) {
		// First check if spend key content actually exists before passing to valid_sec_key_from - so that a spend key decode error can be treated as a failure instead of detecting empty spend keys too
		if ((*inputs.optl__sec_spendKey_string).empty() == false) {
			r = string_tools::hex_to_pod(*inputs.optl__sec_spendKey_string, sec_spendKey);
			if (r == false) { // this is an actual parse error exit condition
				outputs.did_error = true;
				outputs.err_string = "Invalid spend key";
				//
				return false;
			}
			// Validate pub key derived from sec spend key matches decoded_address_info-cached pub key
			crypto::public_key expected_pub_spendKey;
			r = crypto::secret_key_to_public_key(sec_spendKey, expected_pub_spendKey);
			if (r == false) {
				outputs.did_error = true;
				outputs.err_string = "Invalid spend key";
				//
				return false;
			}
			if (decoded_address_info.address.m_spend_public_key != expected_pub_spendKey) {
				outputs.did_error = true;
				outputs.err_string = "Spend key does not match address";
				//
				return false;
			}
			outputs.isInViewOnlyMode = false;
		}
	}
	if (inputs.optl__sec_seed_string) {
		if ((*inputs.optl__sec_seed_string).empty() == false) {
			unsigned long sec_seed_string_length = (*inputs.optl__sec_seed_string).length();
			crypto::secret_key sec_seed;
			bool from_legacy16B_lw_seed = false;
			if (sec_seed_string_length == crypto::sec_seed_hex_string_length) { // normal seed
				from_legacy16B_lw_seed = false; // to be clear
				bool r = string_tools::hex_to_pod((*inputs.optl__sec_seed_string), sec_seed);
				if (!r) {
					outputs.did_error = true;
					outputs.err_string = "Invalid seed";
					//
					return false;
				}
			} else if (sec_seed_string_length == crypto::legacy16B__sec_seed_hex_string_length) {
				from_legacy16B_lw_seed = true;
				crypto::legacy16B_secret_key legacy16B_sec_seed;
				bool r = string_tools::hex_to_pod((*inputs.optl__sec_seed_string), legacy16B_sec_seed);
				if (!r) {
					outputs.did_error = true;
					outputs.err_string = "Invalid seed";
					//
					return false;
				}
				crypto::coerce_valid_sec_key_from(legacy16B_sec_seed, sec_seed);
			}
			cryptonote::account_base expected_account{}; // this initializes the wallet and should call the default constructor
			expected_account.generate(sec_seed, true/*recover*/, false/*two_random*/, from_legacy16B_lw_seed);
			const cryptonote::account_keys& expected_account_keys = expected_account.get_keys();
			// TODO: assert sec_spendKey initialized?
			if (expected_account_keys.m_view_secret_key != sec_viewKey) {
				outputs.did_error = true;
				outputs.err_string = "Private view key does not match generated key";
				//
				return false;
			}
			if (expected_account_keys.m_spend_secret_key != sec_spendKey) {
				outputs.did_error = true;
				outputs.err_string = "Private spend key does not match generated key";
				//
				return false;
			}
			if (expected_account_keys.m_account_address.m_view_public_key != decoded_address_info.address.m_view_public_key) {
				outputs.did_error = true;
				outputs.err_string = "Public view key does not match generated key";
				//
				return false;
			}
			if (expected_account_keys.m_account_address.m_spend_public_key != decoded_address_info.address.m_spend_public_key) {
				outputs.did_error = true;
				outputs.err_string = "Public spend key does not match generated key";
				//
				return false;
			}
			//
			outputs.isInViewOnlyMode = false; // TODO: should this ensure that sec_spendKey is not nil? spendKey should always be available if the seed is…
		}
	}
	outputs.pub_viewKey_string = string_tools::pod_to_hex(decoded_address_info.address.m_view_public_key);
	outputs.pub_spendKey_string = string_tools::pod_to_hex(decoded_address_info.address.m_spend_public_key);
	outputs.isValid = true;
	//
	return true;
}

max_stars_repo_name: mymonero/mymonero-core-cpp--old

max_issues_repo_name: mymonero/mymonero-core-cpp--old

max_forks_repo_name: mymonero/mymonero-core-cpp--old


text:
#pragma once

#include <iostream>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <fstream>
#include <string>
#include <array>

using namespace std;
using namespace Eigen;

bool writeToCSV(
	ofstream & outfile_,
	const string & file_name_,
	const array<Isometry3d, 2> & T_list_
);

Vector3d transCoord(
	const Vector3d & pos_,
	const Isometry3d & T_,
	const Matrix3d & Mat_intri_=Matrix3d::Zero()
);

array<Vector3d, 4> getHorPlanePosAnns(const Vector3d& anns_size_);


text:
/*
 *
 * Copyright (c) Toon Knapen & Kresimir Fresl 2003
 *
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 *
 * KF acknowledges the support of the Faculty of Civil Engineering,
 * University of Zagreb, Croatia.
 *
 */

#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_GESVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_GESVD_HPP

#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
#  include <boost/static_assert.hpp>
#  include <boost/type_traits/is_same.hpp>
#endif

#include <cassert>

namespace boost { namespace numeric { namespace bindings {

  namespace lapack {

    ///////////////////////////////////////////////////////////////////
    //
    // singular value decomposition
    //
    ///////////////////////////////////////////////////////////////////

    /*
     * (simple driver)
     * gesvd() computes the singular value decomposition (SVD) of
     * M-by-N matrix A, optionally computing the left and/or right
     * singular vectors. The SVD is written
     *
     *     A = U * S * V^T    or    A = U * S * V^H
     *
     * where S is an M-by-N matrix which is zero except for its min(m,n)
     * diagonal elements, U is an M-by-M orthogonal/unitary matrix, and V
     * is an N-by-N orthogonal/unitary matrix. The diagonal elements of S
     * are the singular values of A; they are real and non-negative, and
     * are returned in descending  order. The first min(m,n) columns of
     * U and V are the left and right singular vectors of A. (Note that
     * the routine returns V^T or V^H, not V.
     */

    namespace detail {

      inline
      void gesvd (char const jobu, char const jobvt,
                  int const m, int const n, float* a, int const lda,
                  float* s, float* u, int const ldu,
                  float* vt, int const ldvt,
                  float* work, int const lwork, float* /* dummy */,
                  int* info)
      {
        LAPACK_SGESVD (&jobu, &jobvt, &m, &n, a, &lda,
                       s, u, &ldu, vt, &ldvt, work, &lwork, info);
      }

      inline
      void gesvd (char const jobu, char const jobvt,
                  int const m, int const n, double* a, int const lda,
                  double* s, double* u, int const ldu,
                  double* vt, int const ldvt,
                  double* work, int const lwork, double* /* dummy */,
                  int* info)
      {
        LAPACK_DGESVD (&jobu, &jobvt, &m, &n, a, &lda,
                       s, u, &ldu, vt, &ldvt, work, &lwork, info);
      }

      inline
      void gesvd (char const jobu, char const jobvt,
                  int const m, int const n,
                  traits::complex_f* a, int const lda,
                  float* s, traits::complex_f* u, int const ldu,
                  traits::complex_f* vt, int const ldvt,
                  traits::complex_f* work, int const lwork,
                  float* rwork, int* info)
      {
        LAPACK_CGESVD (&jobu, &jobvt, &m, &n,
                       traits::complex_ptr (a), &lda, s,
                       traits::complex_ptr (u), &ldu,
                       traits::complex_ptr (vt), &ldvt,
                       traits::complex_ptr (work), &lwork, rwork, info);
      }

      inline
      void gesvd (char const jobu, char const jobvt,
                  int const m, int const n,
                  traits::complex_d* a, int const lda,
                  double* s, traits::complex_d* u, int const ldu,
                  traits::complex_d* vt, int const ldvt,
                  traits::complex_d* work, int const lwork,
                  double* rwork, int* info)
      {
        LAPACK_ZGESVD (&jobu, &jobvt, &m, &n,
                       traits::complex_ptr (a), &lda, s,
                       traits::complex_ptr (u), &ldu,
                       traits::complex_ptr (vt), &ldvt,
                       traits::complex_ptr (work), &lwork, rwork, info);
      }

      inline
      int gesvd_min_work (float, int m, int n) {
        int minmn = m < n ? m : n;
        int maxmn = m < n ? n : m;
        int m3x = 3 * minmn + maxmn;
        int m5 = 5 * minmn;
        return m3x < m5 ? m5 : m3x;
      }
      inline
      int gesvd_min_work (double, int m, int n) {
        int minmn = m < n ? m : n;
        int maxmn = m < n ? n : m;
        int m3x = 3 * minmn + maxmn;
        int m5 = 5 * minmn;
        return m3x < m5 ? m5 : m3x;
      }
      inline
      int gesvd_min_work (traits::complex_f, int m, int n) {
        int minmn = m < n ? m : n;
        int maxmn = m < n ? n : m;
        return 2 * minmn + maxmn;
      }
      inline
      int gesvd_min_work (traits::complex_d, int m, int n) {
        int minmn = m < n ? m : n;
        int maxmn = m < n ? n : m;
        return 2 * minmn + maxmn;
      }

      inline
      int gesvd_rwork (float, int, int) { return 1; }
      inline
      int gesvd_rwork (double, int, int) { return 1; }
      inline
      int gesvd_rwork (traits::complex_f, int m, int n) {
        return 5 * (m < n ? m : n);
      }
      inline
      int gesvd_rwork (traits::complex_d, int m, int n) {
        return 5 * (m < n ? m : n);
      }

    } // detail

    template <typename MatrA>
    inline
    int gesvd_work (char const q,
                    char const jobu, char const jobvt, MatrA const& a)
    {

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrA>::matrix_structure,
        traits::general_t
      >::value));
#endif

#ifdef BOOST_NUMERIC_BINDINGS_LAPACK_2
      assert (q == 'M');
#else
      assert (q == 'M' || q == 'O');
#endif
      assert (jobu == 'N' || jobu == 'O' || jobu == 'A' || jobu == 'S');
      assert (jobvt == 'N' || jobvt == 'O' || jobvt == 'A' || jobvt == 'S');
      assert (!(jobu == 'O' && jobvt == 'O'));

      int const m = traits::matrix_size1 (a);
      int const n = traits::matrix_size2 (a);
      int lw = -13;

#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
      typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
      typedef typename MatrA::value_type val_t;
#endif

      if (q == 'M')
        lw = detail::gesvd_min_work (val_t(), m, n);

#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_2
      MatrA& a2 = const_cast<MatrA&> (a);
      if (q == 'O') {
        // traits::detail::array<val_t> w (0);
        val_t w;
        int info;
        detail::gesvd (jobu, jobvt, m, n,
                       traits::matrix_storage (a2),
                       traits::leading_dimension (a2),
                       0, // traits::vector_storage (s),
                       0, // traits::matrix_storage (u),
                       m, // traits::leading_dimension (u),
                       0, // traits::matrix_storage (vt),
                       n, // traits::leading_dimension (vt),
                       &w, // traits::vector_storage (w),
                       -1, // traits::vector_size (w),
                       0, // traits::vector_storage (rw),
                       &info);
        assert (info == 0);
        lw = traits::detail::to_int (w);  // (w[0]);
      }
#endif

      return lw;
    }

    template <typename MatrA>
    inline
    int gesvd_rwork (MatrA const& a) {

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrA>::matrix_structure,
        traits::general_t
      >::value));
#endif

#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
      typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
      typedef typename MatrA::value_type val_t;
#endif

      return detail::gesvd_rwork (val_t(),
                                  traits::matrix_size1 (a),
                                  traits::matrix_size2 (a));
    }

    template <typename MatrA, typename VecS,
              typename MatrU, typename MatrV, typename VecW>
    inline
    int gesvd (char const jobu, char const jobvt,
               MatrA& a, VecS& s, MatrU& u, MatrV& vt, VecW& w)
    {

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrA>::matrix_structure,
        traits::general_t
      >::value));
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrU>::matrix_structure,
        traits::general_t
      >::value));
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrV>::matrix_structure,
        traits::general_t
      >::value));

      BOOST_STATIC_ASSERT(
        (boost::is_same<
          typename traits::matrix_traits<MatrA>::value_type, float
        >::value
        ||
        boost::is_same<
          typename traits::matrix_traits<MatrA>::value_type, double
        >::value));
#endif

      int const m = traits::matrix_size1 (a);
      int const n = traits::matrix_size2 (a);
#ifndef NDEBUG /* this variable is only used in assertions below */
      int const minmn = m < n ? m : n;
#endif

      assert (minmn == traits::vector_size (s));
      assert (!(jobu == 'O' && jobvt == 'O'));
      assert ((jobu == 'N')
              || (jobu == 'O')
              || (jobu == 'A' && m == traits::matrix_size2 (u))
              || (jobu == 'S' && minmn == traits::matrix_size2 (u)));
      assert ((jobu == 'N' && traits::leading_dimension (u) >= 1)
              || (jobu == 'O' && traits::leading_dimension (u) >= 1)
              || (jobu == 'A' && traits::leading_dimension (u) >= m)
              || (jobu == 'S' && traits::leading_dimension (u) >= m));
      assert (n == traits::matrix_size2 (vt));
      assert ((jobvt == 'N' && traits::leading_dimension (vt) >= 1)
              || (jobvt == 'O' && traits::leading_dimension (vt) >= 1)
              || (jobvt == 'A' && traits::leading_dimension (vt) >= n)
              || (jobvt == 'S' && traits::leading_dimension (vt) >= minmn));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
      typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
      typedef typename MatrA::value_type val_t;
#endif
      assert (traits::vector_size(w) >= detail::gesvd_min_work(val_t(),m,n));

      int info;
      detail::gesvd (jobu, jobvt, m, n,
                     traits::matrix_storage (a),
                     traits::leading_dimension (a),
                     traits::vector_storage (s),
                     traits::matrix_storage (u),
                     traits::leading_dimension (u),
                     traits::matrix_storage (vt),
                     traits::leading_dimension (vt),
                     traits::vector_storage (w),
                     traits::vector_size (w),
                     0, // dummy argument
                     &info);
      return info;
    }

    template <typename MatrA, typename VecS,
              typename MatrU, typename MatrV, typename VecW, typename VecRW>
    inline
    int gesvd (char const jobu, char const jobvt,
               MatrA& a, VecS& s, MatrU& u, MatrV& vt, VecW& w, VecRW& rw)
    {

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrA>::matrix_structure,
        traits::general_t
      >::value));
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrU>::matrix_structure,
        traits::general_t
      >::value));
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrV>::matrix_structure,
        traits::general_t
      >::value));
#endif

      int const m = traits::matrix_size1 (a);
      int const n = traits::matrix_size2 (a);
#ifndef NDEBUG /* this variable is only used in assertions below */
      int const minmn = m < n ? m : n;
#endif

      assert (minmn == traits::vector_size (s));
      assert (!(jobu == 'O' && jobvt == 'O'));
      assert ((jobu == 'N')
              || (jobu == 'O')
              || (jobu == 'A' && m == traits::matrix_size2 (u))
              || (jobu == 'S' && minmn == traits::matrix_size2 (u)));
      assert ((jobu == 'N' && traits::leading_dimension (u) >= 1)
              || (jobu == 'O' && traits::leading_dimension (u) >= 1)
              || (jobu == 'A' && traits::leading_dimension (u) >= m)
              || (jobu == 'S' && traits::leading_dimension (u) >= m));
      assert (n == traits::matrix_size2 (vt));
      assert ((jobvt == 'N' && traits::leading_dimension (vt) >= 1)
              || (jobvt == 'O' && traits::leading_dimension (vt) >= 1)
              || (jobvt == 'A' && traits::leading_dimension (vt) >= n)
              || (jobvt == 'S' && traits::leading_dimension (vt) >= minmn));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
      typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
      typedef typename MatrA::value_type val_t;
#endif
      assert (traits::vector_size(w) >= detail::gesvd_min_work(val_t(),m,n));
      assert (traits::vector_size(rw) >= detail::gesvd_rwork(val_t(),m,n));

      int info;
      detail::gesvd (jobu, jobvt, m, n,
                     traits::matrix_storage (a),
                     traits::leading_dimension (a),
                     traits::vector_storage (s),
                     traits::matrix_storage (u),
                     traits::leading_dimension (u),
                     traits::matrix_storage (vt),
                     traits::leading_dimension (vt),
                     traits::vector_storage (w),
                     traits::vector_size (w),
                     traits::vector_storage (rw),
                     &info);
      return info;
    }

    template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
    inline
    int gesvd (char const opt, char const jobu, char const jobvt,
               MatrA& a, VecS& s, MatrU& u, MatrV& vt)
    {

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrA>::matrix_structure,
        traits::general_t
      >::value));
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrU>::matrix_structure,
        traits::general_t
      >::value));
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrV>::matrix_structure,
        traits::general_t
      >::value));
#endif

      int const m = traits::matrix_size1 (a);
      int const n = traits::matrix_size2 (a);
#ifndef NDEBUG /* this variable is only used in assertions below */
      int const minmn = m < n ? m : n;
#endif

      assert (minmn == traits::vector_size (s));
      assert (!(jobu == 'O' && jobvt == 'O'));
      assert ((jobu == 'N')
              || (jobu == 'O')
              || (jobu == 'A' && m == traits::matrix_size2 (u))
              || (jobu == 'S' && minmn == traits::matrix_size2 (u)));
      assert ((jobu == 'N' && traits::leading_dimension (u) >= 1)
              || (jobu == 'O' && traits::leading_dimension (u) >= 1)
              || (jobu == 'A' && traits::leading_dimension (u) >= m)
              || (jobu == 'S' && traits::leading_dimension (u) >= m));
      assert ((jobvt == 'N' || traits::matrix_size2(vt) == n)) ;
      assert ((jobvt == 'N' && traits::leading_dimension (vt) >= 1)
              || (jobvt == 'O' && traits::leading_dimension (vt) >= 1)
              || (jobvt == 'A' && traits::leading_dimension (vt) >= n)
              || (jobvt == 'S' && traits::leading_dimension (vt) >= minmn));

#ifdef BOOST_NUMERIC_BINDINGS_LAPACK_2
      assert (opt == 'M');
#else
      assert (opt == 'M' || opt == 'O');
#endif

#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
      typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
      typedef typename MatrA::value_type val_t;
#endif
      typedef typename traits::type_traits<val_t>::real_type real_t;

      int const lw = gesvd_work (opt, jobu, jobvt, a);
      traits::detail::array<val_t> w (lw);
      if (!w.valid()) return -101;

      int const lrw = gesvd_rwork (a);
      traits::detail::array<real_t> rw (lrw);
      if (!rw.valid()) return -102;

      int info;
      detail::gesvd (jobu, jobvt, m, n,
                     traits::matrix_storage (a),
                     traits::leading_dimension (a),
                     traits::vector_storage (s),
                     traits::matrix_storage (u),
                     traits::leading_dimension (u),
                     traits::matrix_storage (vt),
                     traits::leading_dimension (vt),
                     traits::vector_storage (w),
                     traits::vector_size (w),
                     traits::vector_storage (rw),
                     &info);
      return info;
    }

#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_2

    template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
    inline
    int gesvd (char const jobu, char const jobvt,
               MatrA& a, VecS& s, MatrU& u, MatrV& vt)
    {
      return gesvd ('O', jobu, jobvt, a, s, u, vt);
    }

    template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
    inline
    int gesvd (MatrA& a, VecS& s, MatrU& u, MatrV& vt) {
      return gesvd ('O', 'S', 'S', a, s, u, vt);
    }

    template <typename MatrA, typename VecS>
    inline
    int gesvd (MatrA& a, VecS& s) {

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrA>::matrix_structure,
        traits::general_t
      >::value));
#endif

      int const m = traits::matrix_size1 (a);
      int const n = traits::matrix_size2 (a);
#ifndef NDEBUG /* this variable is only used in assertions below */
      int const minmn = m < n ? m : n;
#endif

      assert (minmn == traits::vector_size (s));

#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
      typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
      typedef typename MatrA::value_type val_t;
#endif
      typedef typename traits::type_traits<val_t>::real_type real_t;

      int const lw = gesvd_work ('O', 'N', 'N', a);
      traits::detail::array<val_t> w (lw);
      if (!w.valid()) return -101;

      int const lrw = gesvd_rwork (a);
      traits::detail::array<real_t> rw (lrw);
      if (!rw.valid()) return -102;

      int info;
      detail::gesvd ('N', 'N', m, n,
                     traits::matrix_storage (a),
                     traits::leading_dimension (a),
                     traits::vector_storage (s),
                     0, // traits::matrix_storage (u),
                     1, // traits::leading_dimension (u),
                     0, // traits::matrix_storage (vt),
                     1, // traits::leading_dimension (vt),
                     traits::vector_storage (w),
                     traits::vector_size (w),
                     traits::vector_storage (rw),
                     &info);
      return info;
    }

#endif

  } // namespace lapack

}}}

#endif

max_stars_repo_name: inducer/boost-numeric-bindings

max_issues_repo_name: jdsika/holy

max_forks_repo_name: jdsika/holy


text:
#include <boost/asio.hpp>

#include "server/server_data.hpp"
#include "server/server_constants.hpp"
#include "server/server_session_error.hpp"
#include "session/session_data.hpp"
#include "logger/log.hpp"
#include "authentication_request_message_handler.hpp"
#include "../message_parameter_validator.hpp"

using namespace boost;

namespace pgl {
	void authentication_request_message_handler::handle_message(const authentication_request_message& message,
		std::shared_ptr<message_handle_parameter> param) {

		authentication_reply_message reply{
			api_version,
			{},
			{}
		};

		const message_parameter_validator_with_reply<message_type::authentication_reply, authentication_reply_message>
			parameter_validator(param);

		// Check if player name is valid
		parameter_validator.validate_player_name(message.player_name, reply, false);

		// Check if the client version matches the server version. If not, send an error to the client
		if (message.version != api_version) {
			reply_message_header header{
				message_type::authentication_reply,
				message_error_code::api_version_mismatch,
			};
			send(param, header, reply);
			const auto error_message = minimal_serializer::generate_string(
				"Authentication failed. The client api version doesn't match to the server api version. (server api version: ",
				api_version, ", client api version: ", message.version, ")");
			throw server_session_error(server_session_error_code::not_continuable_error, error_message);
		}
		log_with_endpoint(log_level::info, param->socket.remote_endpoint(), "Authentication succeeded.");

		// Generate session key
		if (param->session_data.is_session_key_generated()) {
			throw server_session_error(server_session_error_code::not_continuable_error,
				"A session key is already generated. Multi time authentication is not allowed.");
		}
		reply.session_key = param->session_data.generate_session_key();
		log_with_endpoint(log_level::info, param->socket.remote_endpoint(), "A session key(", reply.session_key,
			") is generated.");

		// Generate player full name
		const auto player_full_name = param->server_data.get_player_name_container().assign_player_name(
			message.player_name);
		log_with_endpoint(log_level::info, param->socket.remote_endpoint(), "A player \"", player_full_name.name,
			"\" is registered with tag \"", player_full_name.tag, "\"");
		param->session_data.set_client_player_name(player_full_name);
		reply.player_tag = player_full_name.tag;

		// Reply to the client
		reply_message_header header{
			message_type::authentication_reply,
			message_error_code::ok,
		};
		log_with_endpoint(log_level::info, param->socket.remote_endpoint(), "Reply ",
			message_type::authentication_request, " message.");
		send(param, header, reply);
	}
}

max_stars_repo_name: InstytutXR/PlanetaMatchMaker

max_issues_repo_name: InstytutXR/PlanetaMatchMaker

max_forks_repo_name: InstytutXR/PlanetaMatchMaker


text:
#define IGNORE

#include <boost/multiprecision/cpp_int.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix.hpp>

using mpi = boost::multiprecision::int128_t;
// using mpi = boost::multiprecision::cpp_int // 任意桁

using namespace boost::numeric;
using imatrix = ublas::matrix<mpi>;
// 行列積は ublas::prod
// imatrix mat(N, M);
// mat(N, M) = 2;