<commit_before>// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

#include <algorithm>
#include <QApplication>
#include <QTimer>
#include "QImageWidget.h"
#include "QKinectGrabber.h"
#include "QKinectIO.h"
#include "Timer.h"

namespace TestQtKinect
{
	TEST_CLASS(UnitTest1)
	{
	public:

		TEST_METHOD(TestKinectCapture)
		{
			int argc = 1;
			char* argv[] = { "TestKinectColor" };
			QApplication app(argc, argv);
			QTimer *timer = new QTimer();
			timer->start(5000);
			QApplication::connect(timer, SIGNAL(timeout()), &app, SLOT(quit()));

			QKinectGrabber k;
			k.start();

			Assert::IsTrue(k.isRunning(), L"\n<Kinect is not running>\n", LINE_INFO());

			QImageWidget colorWidget;
			colorWidget.setMinimumSize(720, 480);
			colorWidget.show();
			QApplication::connect(&k, SIGNAL(colorImage(QImage)), &colorWidget, SLOT(setImage(QImage)));

			QImageWidget depthWidget;
			depthWidget.setMinimumSize(512, 424);
			depthWidget.show();
			QApplication::connect(&k, SIGNAL(depthImage(QImage)), &depthWidget, SLOT(setImage(QImage)));

			int app_exit = app.exec();
			k.stop();

			Assert::AreEqual(EXIT_SUCCESS, app_exit, L"\n<TestKinectColor appplication did not finish properly>\n", LINE_INFO());
		}

		TEST_METHOD(TestKinectIO)
		{
			QKinectGrabber kinectCapture;
			kinectCapture.start();

			Timer::sleep_ms(3000);

			Assert::IsTrue(kinectCapture.isRunning(), L"\n<Kinect is not running>\n", LINE_INFO());

			QString filename("TestKinectIO.knt");

			std::vector<unsigned short> info_captured;
			std::vector<unsigned short> buffer_captured;

			kinectCapture.getDepthBuffer(info_captured, buffer_captured);

			QKinectIO::save(filename, info_captured, buffer_captured);

			std::vector<unsigned short> info_loaded;
			std::vector<unsigned short> buffer_loaded;

			QKinectIO::load(filename, info_loaded, buffer_loaded);

			Assert::AreEqual(info_captured.size(), info_loaded.size(), L"\n<The size of info vector captured from kinect and the info vector loaded from file are not equal>\n", LINE_INFO());
			Assert::AreEqual(buffer_captured.size(), buffer_loaded.size(), L"\n<The size of buffer captured from kinect and the buffer loaded from file are not equal>\n", LINE_INFO());

			bool info_are_equal = std::equal(info_captured.begin(), info_captured.end(), info_loaded.begin());
			bool buffer_are_equal = std::equal(buffer_captured.begin(), buffer_captured.end(), buffer_loaded.begin());

			Assert::IsTrue(info_are_equal, L"\n<Info captured from kinect and info loaded from file are not equal>\n", LINE_INFO());
			Assert::IsTrue(buffer_are_equal, L"\n<Buffer captured from kinect and buffer loaded from file are not equal>\n", LINE_INFO());
		}

		TEST_METHOD(TestKinectOBJ)
		{
			QString filenameKnt("TestKinectIO.knt");
			QString filenameObj("TestKinectIO.obj");

			std::vector<unsigned short> info_loaded;
			std::vector<unsigned short> buffer_loaded;

			QKinectIO::load(filenameKnt, info_loaded, buffer_loaded);
			QKinectIO::exportObj(filenameObj, info_loaded, buffer_loaded);

			Assert::IsTrue(true);
		}

	};
}<commit_msg>Inserted test for projection pipeline<commit_after>// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

#include <algorithm>
#include <sstream>
#include <fstream>
#include <QApplication>
#include <QTimer>
#include "QImageWidget.h"
#include "QKinectGrabber.h"
#include "QKinectIO.h"
#include "Timer.h"
#include "Eigen/Eigen"

static bool import_obj(const std::string& filename, std::vector<float>& points3d, int max_point_count = INT_MAX)
{
	std::ifstream inFile;
	inFile.open(filename);

	if (!inFile.is_open())
	{
		std::cerr << "Error: Could not open obj input file: " << filename << std::endl;
		return false;
	}

	points3d.clear();

	int i = 0;
	while (inFile)
	{
		std::string str;

		if (!std::getline(inFile, str))
		{
			if (inFile.eof())
				return true;

			std::cerr << "Error: Problems when reading obj file: " << filename << std::endl;
			return false;
		}

		if (str[0] == 'v')
		{
			std::stringstream ss(str);
			std::vector <std::string> record;

			char c;
			double x, y, z;
			ss >> c >> x >> y >> z;

			points3d.push_back(x);
			points3d.push_back(y);
			points3d.push_back(z);
		}

		if (i++ > max_point_count)
			break;
	}

	inFile.close();
	return true;
}

static Eigen::Matrix4f createPerspectiveMatrix(float fy, float in_aspect_ratio, float in_near_plane, float in_far_plane)
{
	Eigen::Matrix4f out = Eigen::Matrix4f::Zero();

	const float
		y_scale = (float)1.0 / tan((fy / 2.0)*(M_PI / 180.0)),
		x_scale = y_scale / in_aspect_ratio,
		frustum_length = in_far_plane - in_near_plane;

	out(0, 0) = x_scale;
	out(1, 1) = y_scale;
	out(2, 2) = -((in_far_plane + in_near_plane) / frustum_length);
	out(3, 2) = -1.0;
	out(2, 3) = -((2 * in_near_plane * in_far_plane) / frustum_length);

	return out;
}

namespace TestQtKinect
{
	TEST_CLASS(UnitTest1)
	{
	public:

		TEST_METHOD(TestKinectCapture)
		{
			int argc = 1;
			char* argv[] = { "TestKinectColor" };
			QApplication app(argc, argv);
			QTimer *timer = new QTimer();
			timer->start(5000);
			QApplication::connect(timer, SIGNAL(timeout()), &app, SLOT(quit()));

			QKinectGrabber k;
			k.start();

			Assert::IsTrue(k.isRunning(), L"\n<Kinect is not running>\n", LINE_INFO());

			QImageWidget colorWidget;
			colorWidget.setMinimumSize(720, 480);
			colorWidget.show();
			QApplication::connect(&k, SIGNAL(colorImage(QImage)), &colorWidget, SLOT(setImage(QImage)));

			QImageWidget depthWidget;
			depthWidget.setMinimumSize(512, 424);
			depthWidget.show();
			QApplication::connect(&k, SIGNAL(depthImage(QImage)), &depthWidget, SLOT(setImage(QImage)));

			int app_exit = app.exec();
			k.stop();

			Assert::AreEqual(EXIT_SUCCESS, app_exit, L"\n<TestKinectColor appplication did not finish properly>\n", LINE_INFO());
		}

		TEST_METHOD(TestKinectIO)
		{
			QKinectGrabber kinectCapture;
			kinectCapture.start();

			Timer::sleep_ms(3000);

			Assert::IsTrue(kinectCapture.isRunning(), L"\n<Kinect is not running>\n", LINE_INFO());

			QString filename("TestKinectIO.knt");

			std::vector<unsigned short> info_captured;
			std::vector<unsigned short> buffer_captured;

			kinectCapture.getDepthBuffer(info_captured, buffer_captured);

			QKinectIO::save(filename, info_captured, buffer_captured);

			std::vector<unsigned short> info_loaded;
			std::vector<unsigned short> buffer_loaded;

			QKinectIO::load(filename, info_loaded, buffer_loaded);

			Assert::AreEqual(info_captured.size(), info_loaded.size(), L"\n<The size of info vector captured from kinect and the info vector loaded from file are not equal>\n", LINE_INFO());
			Assert::AreEqual(buffer_captured.size(), buffer_loaded.size(), L"\n<The size of buffer captured from kinect and the buffer loaded from file are not equal>\n", LINE_INFO());

			bool info_are_equal = std::equal(info_captured.begin(), info_captured.end(), info_loaded.begin());
			bool buffer_are_equal = std::equal(buffer_captured.begin(), buffer_captured.end(), buffer_loaded.begin());

			Assert::IsTrue(info_are_equal, L"\n<Info captured from kinect and info loaded from file are not equal>\n", LINE_INFO());
			Assert::IsTrue(buffer_are_equal, L"\n<Buffer captured from kinect and buffer loaded from file are not equal>\n", LINE_INFO());
		}

		TEST_METHOD(TestKinectOBJ)
		{
			QString filenameKnt("TestKinectIO.knt");
			QString filenameObj("TestKinectIO.obj");

			std::vector<unsigned short> info_loaded;
			std::vector<unsigned short> buffer_loaded;

			QKinectIO::load(filenameKnt, info_loaded, buffer_loaded);
			QKinectIO::exportObj(filenameObj, info_loaded, buffer_loaded);

			Assert::IsTrue(true);
		}

		TEST_METHOD(TestProjectionPipelineKMatrix)
		{
			std::string filename("../../data/monkey/monkey.obj");

			std::vector<float> points3d;
			import_obj(filename, points3d);

			Eigen::Vector4f p3d(24.5292f, 21.9753f, 29.9848f, 1.0f);
			Eigen::Vector4f p2d;

			float fovy = 70.0f;
			float aspect_ratio = 512.0f / 424.0f;
			float y_scale = (float)1.0 / tan((fovy / 2.0)*(M_PI / 180.0));
			float x_scale = y_scale / aspect_ratio;

			Eigen::MatrixXf K = Eigen::MatrixXf(3, 4);
			K.setZero();
			K(0, 0) = x_scale;
			K(1, 1) = y_scale;
			K(2, 2) = 1;

			Eigen::MatrixXf K_inv = K;
			K_inv(0, 0) = 1.0f / K_inv(0, 0);
			K_inv(1, 1) = 1.0f / K_inv(1, 1);
			std::cout << K_inv << std::endl << std::endl;

			Eigen::Vector3f kp = K * p3d;
			kp /= kp.z();

			p2d = kp.homogeneous();
			p2d *= p3d.z();

			Eigen::Vector3f p3d_out = K_inv * p2d;

			std::cout << std::fixed
				<< "Input point 3d  : " << p3d.transpose() << std::endl
				<< "Projected point : " << kp.transpose() << std::endl
				<< "Input point 2d  : " << p2d.transpose() << std::endl
				<< "Output point 3d : " << p3d_out.transpose() << std::endl
				<< "Test Passed     : " << (p3d.isApprox(p3d_out.homogeneous()) ? "[ok]" : "[fail]") << std::endl;

			Assert::IsTrue(p3d.isApprox(p3d_out.homogeneous()));
		}

		TEST_METHOD(TestProjectionPipeline)
		{
			Eigen::Vector4f p3d(-0.5f, -0.5f, -0.88f, 1.0f);
			Eigen::Vector3f pixel(285.71f, 5.71f, 88.73f);

			float window_width = 1280.0f;
			float window_height = 720.0f;
			float near_plane = 0.1f;
			float far_plane = 100.0f;
			float fovy = 60.0f;
			float aspect_ratio = window_width / window_height;
			float y_scale = (float)1.0 / tan((fovy / 2.0)*(M_PI / 180.0));
			float x_scale = y_scale / aspect_ratio;
			float depth_length = far_plane - near_plane;

			Eigen::Matrix4f Mdv = Eigen::Matrix4f::Identity();
			Mdv.col(3) << 0.f, 0.f, 0.0f, 1.f;

			Eigen::Matrix4f Proj = createPerspectiveMatrix(fovy, aspect_ratio, near_plane, far_plane);

			Eigen::Vector4f p_clip = Proj * Mdv * p3d;

			Eigen::Vector3f p_ndc = (p_clip / p_clip.w()).head<3>();

			Eigen::Vector3f p_window;
			p_window.x() = window_width / 2.0f * p_ndc.x() + window_width / 2.0f;
			p_window.y() = window_height / 2.0f * p_ndc.y() + window_height / 2.0f;
			p_window.z() = (far_plane - near_plane) / 2.0f * p_ndc.z() + (far_plane + near_plane) / 2.0f;

			Assert::IsTrue(pixel.isApprox(p_window, 0.01f));
		}
	};
}<|endoftext|>


<commit_before>#include "UASRawStatusView.h"
#include "MAVLinkDecoder.h"
#include "UASInterface.h"
#include "UAS.h"
#include <QTimer>
#include <QScrollBar>
UASRawStatusView::UASRawStatusView(QWidget *parent) : QWidget(parent)
{
    ui.setupUi(this);
    ui.tableWidget->setColumnCount(2);
    ui.tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    ui.tableWidget->setShowGrid(false);
    ui.tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QTimer *timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(updateTableTimerTick()));

    // FIXME reinstate once fixed.

    timer->start(2000);
}
void UASRawStatusView::addSource(MAVLinkDecoder *decoder)
{
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,double,quint64)),this,SLOT(valueChanged(int,QString,QString,double,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint8,quint64)),this,SLOT(valueChanged(int,QString,QString,qint8,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint16,quint64)),this,SLOT(valueChanged(int,QString,QString,qint16,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint32,quint64)),this,SLOT(valueChanged(int,QString,QString,qint32,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint64,quint64)),this,SLOT(valueChanged(int,QString,QString,qint64,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint8,quint64)),this,SLOT(valueChanged(int,QString,QString,quint8,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint16,quint64)),this,SLOT(valueChanged(int,QString,QString,qint16,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint32,quint64)),this,SLOT(valueChanged(int,QString,QString,quint32,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint64,quint64)),this,SLOT(valueChanged(int,QString,QString,quint64,quint64)));
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}

void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec)
{
    valueMap[name] = value;
    if (nameToUpdateWidgetMap.contains(name))
    {
        nameToUpdateWidgetMap[name]->setText(QString::number(value));
    }
    else
    {
        m_tableDirty = true;
    }
    return;
}
void UASRawStatusView::resizeEvent(QResizeEvent *event)
{
    m_tableDirty = true;
}

void UASRawStatusView::updateTableTimerTick()
{
    if (m_tableDirty)
    {
        m_tableDirty = false;
        int columncount = 2;
        bool good = false;
        while (!good)
        {
            ui.tableWidget->clear();
            ui.tableWidget->setRowCount(0);
            ui.tableWidget->setColumnCount(columncount);
            ui.tableWidget->horizontalHeader()->hide();
            ui.tableWidget->verticalHeader()->hide();
            int currcolumn = 0;
            int currrow = 0;
            int totalheight = 2 + ui.tableWidget->horizontalScrollBar()->height();
            bool broke = false;
            for (QMap<QString,double>::const_iterator i=valueMap.constBegin();i!=valueMap.constEnd();i++)
            {
                if (ui.tableWidget->rowCount() < currrow+1)
                {
                    ui.tableWidget->setRowCount(currrow+1);
                }
                ui.tableWidget->setItem(currrow,currcolumn,new QTableWidgetItem(i.key().split(".")[1]));
                QTableWidgetItem *item = new QTableWidgetItem(QString::number(i.value()));
                nameToUpdateWidgetMap[i.key()] = item;
                ui.tableWidget->setItem(currrow,currcolumn+1,item);
                ui.tableWidget->resizeRowToContents(currrow);
                totalheight += ui.tableWidget->rowHeight(currrow);
                currrow++;
                if ((totalheight + ui.tableWidget->rowHeight(currrow-1)) > ui.tableWidget->height())
                {
                    currcolumn+=2;
                    totalheight = 2 + ui.tableWidget->horizontalScrollBar()->height();
                    currrow = 0;
                    if (currcolumn >= columncount)
                    {
                        //We're over what we can do. Add a column and continue.
                        columncount+=2;
                        broke = true;
                        break;
                    }
                }
            }
            if (!broke)
            {
                good = true;
            }
        }
        ui.tableWidget->resizeColumnsToContents();
        //ui.tableWidget->columnCount()-2
    }
}

UASRawStatusView::~UASRawStatusView()
{
}
<commit_msg>Fix for a crash involving RawStatusView<commit_after>#include "UASRawStatusView.h"
#include "MAVLinkDecoder.h"
#include "UASInterface.h"
#include "UAS.h"
#include <QTimer>
#include <QScrollBar>
UASRawStatusView::UASRawStatusView(QWidget *parent) : QWidget(parent)
{
    ui.setupUi(this);
    ui.tableWidget->setColumnCount(2);
    ui.tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    ui.tableWidget->setShowGrid(false);
    ui.tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QTimer *timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(updateTableTimerTick()));

    // FIXME reinstate once fixed.

    timer->start(2000);
}
void UASRawStatusView::addSource(MAVLinkDecoder *decoder)
{
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,double,quint64)),this,SLOT(valueChanged(int,QString,QString,double,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint8,quint64)),this,SLOT(valueChanged(int,QString,QString,qint8,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint16,quint64)),this,SLOT(valueChanged(int,QString,QString,qint16,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint32,quint64)),this,SLOT(valueChanged(int,QString,QString,qint32,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint64,quint64)),this,SLOT(valueChanged(int,QString,QString,qint64,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint8,quint64)),this,SLOT(valueChanged(int,QString,QString,quint8,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint16,quint64)),this,SLOT(valueChanged(int,QString,QString,qint16,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint32,quint64)),this,SLOT(valueChanged(int,QString,QString,quint32,quint64)));
    connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint64,quint64)),this,SLOT(valueChanged(int,QString,QString,quint64,quint64)));
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}
void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec)
{
    valueChanged(uasId,name,unit,(double)value,msec);
}

void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec)
{
    valueMap[name] = value;
    if (nameToUpdateWidgetMap.contains(name))
    {
        nameToUpdateWidgetMap[name]->setText(QString::number(value));
    }
    else
    {
        m_tableDirty = true;
    }
    return;
}
void UASRawStatusView::resizeEvent(QResizeEvent *event)
{
    m_tableDirty = true;
}

void UASRawStatusView::updateTableTimerTick()
{
    if (m_tableDirty)
    {
        m_tableDirty = false;
        int columncount = 2;
        bool good = false;
        while (!good)
        {
            ui.tableWidget->clear();
            ui.tableWidget->setRowCount(0);
            ui.tableWidget->setColumnCount(columncount);
            ui.tableWidget->horizontalHeader()->hide();
            ui.tableWidget->verticalHeader()->hide();
            int currcolumn = 0;
            int currrow = 0;
            int totalheight = 2 + ui.tableWidget->horizontalScrollBar()->height();
            bool broke = false;
            for (QMap<QString,double>::const_iterator i=valueMap.constBegin();i!=valueMap.constEnd();i++)
            {
                if (ui.tableWidget->rowCount() < currrow+1)
                {
                    ui.tableWidget->setRowCount(currrow+1);
                }
                ui.tableWidget->setItem(currrow,currcolumn,new QTableWidgetItem(i.key().split(".")[1]));
                QTableWidgetItem *item = new QTableWidgetItem(QString::number(i.value()));
                nameToUpdateWidgetMap[i.key()] = item;
                ui.tableWidget->setItem(currrow,currcolumn+1,item);
                ui.tableWidget->resizeRowToContents(currrow);
                totalheight += ui.tableWidget->rowHeight(currrow);
                currrow++;
                if ((totalheight + ui.tableWidget->rowHeight(currrow-1)) > ui.tableWidget->height())
                {
                    currcolumn+=2;
                    totalheight = 2 + ui.tableWidget->horizontalScrollBar()->height();
                    currrow = 0;
                    if (currcolumn >= columncount)
                    {
                        //We're over what we can do. Add a column and continue.
                        columncount+=2;
                        broke = true;
                        i = valueMap.constEnd(); // Ensure loop breakout.
                        break;
                    }
                }
            }
            if (!broke)
            {
                good = true;
            }
        }
        ui.tableWidget->resizeColumnsToContents();
        //ui.tableWidget->columnCount()-2
    }
}

UASRawStatusView::~UASRawStatusView()
{
}
<|endoftext|>


<commit_before>#include "CompositePath.hpp"

using namespace std;
using namespace Geometry2d;
namespace Planning
{
	CompositePath::CompositePath(unique_ptr<Path> path) {
		append(std::move(path));
	}

	CompositePath::CompositePath(Path *path) {
		append(path);
	}

	void CompositePath::append(Path *path) {
		append(std::unique_ptr<Path>(path));
	}

	void CompositePath::append(unique_ptr<Path> path) {
		if (duration < std::numeric_limits<float>::infinity()) {
			float pathDuration = path->getDuration();
			if (pathDuration > 0) {
				duration += pathDuration;
				paths.push_back(std::move(path));
			} else {
				debugThrow(invalid_argument("The path passed is invalid"));
			}
		} else {
			debugThrow(runtime_error("You can't append to this path. It is already infinitely long."));
		}
	}

	bool CompositePath::evaluate(float t, Point &targetPosOut, Point &targetVelOut) const
	{
		if (paths.empty()) {
			return false;
		}
		if (t<0) {
			return false;
		}
		for (const std::unique_ptr<Path> &path: paths)
		{
			float timeLength = path->getDuration();
			t -= timeLength;
			if (t<=0 || timeLength == -1) {
				t += timeLength;
				path->evaluate(t, targetPosOut, targetVelOut);
				return true;
			}
		}
		targetPosOut = destination().get();
		targetVelOut = Point(0,0);
		return false;
	}

	bool CompositePath::hit(const CompositeShape &shape, float startTime) const
	{
		if (paths.empty()) {
			return false;
		}
		int start = 0;
		for (const std::unique_ptr<Path> &path: paths)
		{
			start++;
			float timeLength = path->getDuration();
			if (timeLength == -1) {
				return path->hit(shape, startTime);
			}
			startTime -= timeLength;
			if (startTime<=0) {
				startTime += timeLength;
				if (path->hit(shape, startTime)) {
					return true;
				}
				break;
			}
		}

		for (;start<paths.size(); start++) {
			if (paths[start]->hit(shape)) {
				return true;
			}
		}
		return false;
	}

	void CompositePath::draw(SystemState * const state, const QColor &color, const QString &layer) const
	{
		for (const std::unique_ptr<Path> &path: paths)
		{
			path->draw(state, color, layer);
		}
	}

	float CompositePath::getDuration() const
	{
		return duration;
	}

	boost::optional<Point> CompositePath::destination() const
	{
		if (paths.empty()) {
			return boost::none;
		}
		return paths.back()->destination();
	}

	unique_ptr<Path> CompositePath::subPath(float startTime, float endTime) const
	{
		//Check for valid arguments
		if (startTime<0) {
			throw invalid_argument("CompositePath::subPath(): startTime(" + to_string(startTime) + ") can't be less than zero");
		}

		if (endTime<0) {
			throw invalid_argument("CompositePath::subPath(): endTime(" + to_string(endTime) + ") can't be less than zero");
		}

		if (startTime > endTime) {
			throw invalid_argument("CompositePath::subPath(): startTime(" + to_string(startTime) + ") can't be after endTime(" + to_string(endTime) + ")");
		}

		if (startTime >= duration) {
			debugThrow(invalid_argument("CompositePath::subPath(): startTime(" + to_string(startTime) + ") can't be greater than the duration(" + to_string(duration) + ") of the path"));
			return unique_ptr<Path>(new CompositePath());
		}

		if (startTime == 0 && endTime>=duration) {
			return this->clone();
		}

		//Find the first Path in the vector of paths which will be included in the subPath
		size_t start = 0;
		float time = 0;
		float lastTime = 0;
		while (time <= startTime) {
			lastTime = paths[start]->getDuration();
			time += lastTime;
			start++;
		}

		//Get the time into the Path in the vector of paths which the subPath will start
		float firstStartTime = (time - lastTime);

		//If the path will only contain that one Path just return a subPath of that Path
		if (time >= endTime) {
			return paths[start-1]->subPath(startTime - firstStartTime, endTime - firstStartTime );
		} else {
			//Create a CompositePath initialized with only that first path.
			CompositePath *path = new CompositePath(paths[start-1]->subPath(startTime - firstStartTime));
			unique_ptr<Path> lastPath;
			size_t end;

			//Find the last Path in the vector of paths which will be included in the subPath and store it in lastPath
			if (endTime>= duration) {
				lastPath = paths.back()->clone();
				end = paths.size()-1;
			} else {
				end = start;
				while (time<endTime) {
					lastTime = paths[start]->getDuration();
					time += lastTime;
					end++;
				}
				end--;
				lastPath = paths[end]->subPath(0, endTime - (time - lastTime));
			}

			//Add the ones in the middle
			while (start<end) {
				path->append(paths[start]->clone());
				start++;
			}

			//Add the last one
			path->append(std::move(lastPath));

			return unique_ptr<Path>(path);
		}
	}

	unique_ptr<Path> CompositePath::clone() const{
		CompositePath *newPath = new CompositePath();
		for (const unique_ptr<Path> &path: paths) {
			newPath->append(path->clone());
		}
		return unique_ptr<Path>(newPath);
	}
}<commit_msg>Get rid of unnecessary std::<commit_after>#include "CompositePath.hpp"

using namespace std;
using namespace Geometry2d;
namespace Planning
{
	CompositePath::CompositePath(unique_ptr<Path> path) {
		append(std::move(path));
	}

	CompositePath::CompositePath(Path *path) {
		append(path);
	}

	void CompositePath::append(Path *path) {
		append(std::unique_ptr<Path>(path));
	}

	void CompositePath::append(unique_ptr<Path> path) {
		if (duration < numeric_limits<float>::infinity()) {
			float pathDuration = path->getDuration();
			if (pathDuration > 0) {
				duration += pathDuration;
				paths.push_back(std::move(path));
			} else {
				debugThrow(invalid_argument("The path passed is invalid"));
			}
		} else {
			debugThrow(runtime_error("You can't append to this path. It is already infinitely long."));
		}
	}

	bool CompositePath::evaluate(float t, Point &targetPosOut, Point &targetVelOut) const
	{
		if (paths.empty()) {
			return false;
		}
		if (t<0) {
			return false;
		}
		for (const std::unique_ptr<Path> &path: paths)
		{
			float timeLength = path->getDuration();
			t -= timeLength;
			if (t<=0 || timeLength == -1) {
				t += timeLength;
				path->evaluate(t, targetPosOut, targetVelOut);
				return true;
			}
		}
		targetPosOut = destination().get();
		targetVelOut = Point(0,0);
		return false;
	}

	bool CompositePath::hit(const CompositeShape &shape, float startTime) const
	{
		if (paths.empty()) {
			return false;
		}
		int start = 0;
		for (const std::unique_ptr<Path> &path: paths)
		{
			start++;
			float timeLength = path->getDuration();
			if (timeLength == -1) {
				return path->hit(shape, startTime);
			}
			startTime -= timeLength;
			if (startTime<=0) {
				startTime += timeLength;
				if (path->hit(shape, startTime)) {
					return true;
				}
				break;
			}
		}

		for (;start<paths.size(); start++) {
			if (paths[start]->hit(shape)) {
				return true;
			}
		}
		return false;
	}

	void CompositePath::draw(SystemState * const state, const QColor &color, const QString &layer) const
	{
		for (const std::unique_ptr<Path> &path: paths)
		{
			path->draw(state, color, layer);
		}
	}

	float CompositePath::getDuration() const
	{
		return duration;
	}

	boost::optional<Point> CompositePath::destination() const
	{
		if (paths.empty()) {
			return boost::none;
		}
		return paths.back()->destination();
	}

	unique_ptr<Path> CompositePath::subPath(float startTime, float endTime) const
	{
		//Check for valid arguments
		if (startTime<0) {
			throw invalid_argument("CompositePath::subPath(): startTime(" + to_string(startTime) + ") can't be less than zero");
		}

		if (endTime<0) {
			throw invalid_argument("CompositePath::subPath(): endTime(" + to_string(endTime) + ") can't be less than zero");
		}

		if (startTime > endTime) {
			throw invalid_argument("CompositePath::subPath(): startTime(" + to_string(startTime) + ") can't be after endTime(" + to_string(endTime) + ")");
		}

		if (startTime >= duration) {
			debugThrow(invalid_argument("CompositePath::subPath(): startTime(" + to_string(startTime) + ") can't be greater than the duration(" + to_string(duration) + ") of the path"));
			return unique_ptr<Path>(new CompositePath());
		}

		if (startTime == 0 && endTime>=duration) {
			return this->clone();
		}

		//Find the first Path in the vector of paths which will be included in the subPath
		size_t start = 0;
		float time = 0;
		float lastTime = 0;
		while (time <= startTime) {
			lastTime = paths[start]->getDuration();
			time += lastTime;
			start++;
		}

		//Get the time into the Path in the vector of paths which the subPath will start
		float firstStartTime = (time - lastTime);

		//If the path will only contain that one Path just return a subPath of that Path
		if (time >= endTime) {
			return paths[start-1]->subPath(startTime - firstStartTime, endTime - firstStartTime );
		} else {
			//Create a CompositePath initialized with only that first path.
			CompositePath *path = new CompositePath(paths[start-1]->subPath(startTime - firstStartTime));
			unique_ptr<Path> lastPath;
			size_t end;

			//Find the last Path in the vector of paths which will be included in the subPath and store it in lastPath
			if (endTime>= duration) {
				lastPath = paths.back()->clone();
				end = paths.size()-1;
			} else {
				end = start;
				while (time<endTime) {
					lastTime = paths[start]->getDuration();
					time += lastTime;
					end++;
				}
				end--;
				lastPath = paths[end]->subPath(0, endTime - (time - lastTime));
			}

			//Add the ones in the middle
			while (start<end) {
				path->append(paths[start]->clone());
				start++;
			}

			//Add the last one
			path->append(std::move(lastPath));

			return unique_ptr<Path>(path);
		}
	}

	unique_ptr<Path> CompositePath::clone() const{
		CompositePath *newPath = new CompositePath();
		for (const unique_ptr<Path> &path: paths) {
			newPath->append(path->clone());
		}
		return unique_ptr<Path>(newPath);
	}
}<|endoftext|>


<commit_before><commit_msg>Revert 56241 - Add an exceptionbarrier in Hook_Start(Ex). This is an attempt to reduce the amount of false positive crash reports - when exception is swallowed and is almost always not a problem due ChromeFrame code. BUG=51830<commit_after><|endoftext|>


<commit_before>#include <sstream>

#include "Tools/Exception/exception.hpp"

#include "matrix.h"

namespace aff3ct
{
namespace tools
{
template <typename T, class AT = std::allocator<T>>
inline void rgemm(const int M, const int N, const int K,
                  const std::vector<T,AT> &A,
                  const std::vector<T,AT> &tB,
                        std::vector<T,AT> &tC)
{
	if (A.size() != unsigned(M * K))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'K' ('A.size()' = " << A.size()  << ", 'M' = " << M
		        << ", 'K' = " << K << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tB.size() != unsigned(K * N))
	{
		std::stringstream message;
		message << "'tB.size()' has to be equal to 'K' * 'N' ('tB.size()' = " << tB.size() << ", 'K' = " << K
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tC.size() != unsigned(M * N))
	{
		std::stringstream message;
		message << "'tC.size()' has to be equal to 'M' * 'N' ('tC.size()' = " << tC.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	rgemm(M, N, K, A.data(), tB.data(), tC.data());
}

template <typename T>
inline void rgemm(const int M, const int N, const int K,
                  const T *A,
                  const T *tB,
                        T *tC)
{
	for (auto i = 0; i < M; i++)
		for (auto j = 0; j < N; j++)
		{
			T sum_r = 0;
			for (auto k = 0; k < K; k++)
				sum_r += A[i * K + k] * tB[j * K + k];

			tC[j * M + i] = sum_r;
		}
}

template <typename T, class AT = std::allocator<T>>
inline void cgemm(const int M, const int N, const int K,
                  const std::vector<T,AT> &A,
                  const std::vector<T,AT> &tB,
                        std::vector<T,AT> &tC)
{
	if (A.size() != unsigned(M * K * 2))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'K' * 2 ('A.size()' = " << A.size() << ", 'M' = " << M
		        << ", 'K' = " << K << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tB.size() != unsigned(K * N * 2))
	{
		std::stringstream message;
		message << "'tB.size()' has to be equal to 'K' * 'N' * 2 ('tB.size()' = " << tB.size() << ", 'K' = " << K
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tC.size() != unsigned(M * N * 2))
	{
		std::stringstream message;
		message << "'tC.size()' has to be equal to 'M' * 'N' * 2 ('tC.size()' = " << tC.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	cgemm(M, N, K, A.data(), tB.data(), tC.data());
}

template <typename T>
inline void cgemm(const int M, const int N, const int K,
                  const T *A,
                  const T *tB,
                        T *tC)
{
	const T*  A_real =  A;
	const T*  A_imag =  A + ((M * K) >> 1);
	const T* tB_real = tB;
	const T* tB_imag = tB + ((N * K) >> 1);
	      T* tC_real = tC;
	      T* tC_imag = tC + ((M * N) >> 1);

	for (auto i = 0; i < M; i++)
	{
		for (auto j = 0; j < N; j++)
		{
			T sum_r = 0, sum_i = 0;
			for (auto k = 0; k < K; k++)
			{
				sum_r += A_real[i * K + k] * tB_real[j * K + k] - A_imag[i * K + k] * tB_imag[j * K + k];
				sum_i += A_imag[i * K + k] * tB_real[j * K + k] + A_real[i * K + k] * tB_imag[j * K + k];
			}

			tC_real[j * M + i] = sum_r;
			tC_imag[j * M + i] = sum_i;
		}
	}
}

template <typename T, class AT = std::allocator<T>>
inline void cgemm_r(const int M, const int N, const int K,
                    const std::vector<T,AT> &A,
                    const std::vector<T,AT> &tB,
                          std::vector<T,AT> &tC)
{
	if (A.size() != unsigned(M * K * 2))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'K' * 2 ('A.size()' = " << A.size() << ", 'M' = " << M
		        << ", 'K' = " << K << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tB.size() != unsigned(K * N * 2))
	{
		std::stringstream message;
		message << "'tB.size()' has to be equal to 'K' * 'N' * 2 ('tB.size()' = " << tB.size() << ", 'K' = " << K
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tC.size() != unsigned(M * N * 1))
	{
		std::stringstream message;
		message << "'tC.size()' has to be equal to 'M' * 'N' * 1 ('tC.size()' = " << tC.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	cgemm_r(M, N, K, A.data(), tB.data(), tC.data());
}

template <typename T>
inline void cgemm_r(const int M, const int N, const int K,
                    const T *A,
                    const T *tB,
                          T *tC)
{
	const T*  A_real =  A;
	const T*  A_imag =  A + ((M * K) >> 1);
	const T* tB_real = tB;
	const T* tB_imag = tB + ((N * K) >> 1);
	      T* tC_real = tC;

	for (auto i = 0; i < M; i++)
	{
		for (auto j = 0; j < N; j++)
		{
			T sum_r = 0;
			for (auto k = 0; k < K; k++)
				sum_r += A_real[i * K + k] * tB_real[j * K + k] - A_imag[i * K + k] * tB_imag[j * K + k];

			tC_real[j * M + i] = sum_r;
		}
	}
}

template <typename T, class AT = std::allocator<T>>
inline void real_transpose(const int M, const int N,
                           const std::vector<T,AT> &A,
                                 std::vector<T,AT> &B)
{
	if (A.size() != unsigned(M * N))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'N' ('A.size()' = " << A.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (B.size() != unsigned(N * M))
	{
		std::stringstream message;
		message << "'B.size()' has to be equal to 'N' * 'M' ('B.size()' = " << B.size() << ", 'N' = " << N
		        << ", 'M' = " << M << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	real_transpose(M, N, A.data(), B.data());
}

template <typename T>
inline void real_transpose(const int M, const int N,
                           const T *A,
                                 T *B)
{
	for (auto i = 0; i < M; i++)
		for (auto j = 0; j < N; j++)
			B[j*M+i] =  A[i*N+j];
}

template <typename T, class AT = std::allocator<T>>
inline void complex_transpose(const int M, const int N,
                              const std::vector<T,AT> &A,
                                    std::vector<T,AT> &B)
{
	if (A.size() != unsigned(M * N * 2))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'N' * 2 ('A.size()' = " << A.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (B.size() != unsigned(N * M * 2))
	{
		std::stringstream message;
		message << "'B.size()' has to be equal to 'N' * 'M' * 2 ('B.size()' = " << B.size() << ", 'N' = " << N
		        << ", 'M' = " << M << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	complex_transpose(M, N, A.data(), B.data());
}

template <typename T>
inline void complex_transpose(const int M, const int N,
                              const T *A,
                                    T *B)
{
	const T* A_real = A;
	const T* A_imag = A + M * N;
	      T* B_real = B;
	      T* B_imag = B + M * N;

	for (auto i = 0; i < M; i++)
	{
		for (auto j = 0; j < N; j++)
		{
			B_real[j*M+i] =  A_real[i*N+j];
			B_imag[j*M+i] = -A_imag[i*N+j];
		}
	}
}
}
}
<commit_msg>Fix compilation errors on MSVC.<commit_after>#include <sstream>

#include "Tools/Exception/exception.hpp"

#include "matrix.h"

namespace aff3ct
{
namespace tools
{
template <typename T, class AT>
inline void rgemm(const int M, const int N, const int K,
                  const std::vector<T,AT> &A,
                  const std::vector<T,AT> &tB,
                        std::vector<T,AT> &tC)
{
	if (A.size() != unsigned(M * K))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'K' ('A.size()' = " << A.size()  << ", 'M' = " << M
		        << ", 'K' = " << K << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tB.size() != unsigned(K * N))
	{
		std::stringstream message;
		message << "'tB.size()' has to be equal to 'K' * 'N' ('tB.size()' = " << tB.size() << ", 'K' = " << K
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tC.size() != unsigned(M * N))
	{
		std::stringstream message;
		message << "'tC.size()' has to be equal to 'M' * 'N' ('tC.size()' = " << tC.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	rgemm(M, N, K, A.data(), tB.data(), tC.data());
}

template <typename T>
inline void rgemm(const int M, const int N, const int K,
                  const T *A,
                  const T *tB,
                        T *tC)
{
	for (auto i = 0; i < M; i++)
		for (auto j = 0; j < N; j++)
		{
			T sum_r = 0;
			for (auto k = 0; k < K; k++)
				sum_r += A[i * K + k] * tB[j * K + k];

			tC[j * M + i] = sum_r;
		}
}

template <typename T, class AT>
inline void cgemm(const int M, const int N, const int K,
                  const std::vector<T,AT> &A,
                  const std::vector<T,AT> &tB,
                        std::vector<T,AT> &tC)
{
	if (A.size() != unsigned(M * K * 2))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'K' * 2 ('A.size()' = " << A.size() << ", 'M' = " << M
		        << ", 'K' = " << K << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tB.size() != unsigned(K * N * 2))
	{
		std::stringstream message;
		message << "'tB.size()' has to be equal to 'K' * 'N' * 2 ('tB.size()' = " << tB.size() << ", 'K' = " << K
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tC.size() != unsigned(M * N * 2))
	{
		std::stringstream message;
		message << "'tC.size()' has to be equal to 'M' * 'N' * 2 ('tC.size()' = " << tC.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	cgemm(M, N, K, A.data(), tB.data(), tC.data());
}

template <typename T>
inline void cgemm(const int M, const int N, const int K,
                  const T *A,
                  const T *tB,
                        T *tC)
{
	const T*  A_real =  A;
	const T*  A_imag =  A + ((M * K) >> 1);
	const T* tB_real = tB;
	const T* tB_imag = tB + ((N * K) >> 1);
	      T* tC_real = tC;
	      T* tC_imag = tC + ((M * N) >> 1);

	for (auto i = 0; i < M; i++)
	{
		for (auto j = 0; j < N; j++)
		{
			T sum_r = 0, sum_i = 0;
			for (auto k = 0; k < K; k++)
			{
				sum_r += A_real[i * K + k] * tB_real[j * K + k] - A_imag[i * K + k] * tB_imag[j * K + k];
				sum_i += A_imag[i * K + k] * tB_real[j * K + k] + A_real[i * K + k] * tB_imag[j * K + k];
			}

			tC_real[j * M + i] = sum_r;
			tC_imag[j * M + i] = sum_i;
		}
	}
}

template <typename T, class AT>
inline void cgemm_r(const int M, const int N, const int K,
                    const std::vector<T,AT> &A,
                    const std::vector<T,AT> &tB,
                          std::vector<T,AT> &tC)
{
	if (A.size() != unsigned(M * K * 2))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'K' * 2 ('A.size()' = " << A.size() << ", 'M' = " << M
		        << ", 'K' = " << K << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tB.size() != unsigned(K * N * 2))
	{
		std::stringstream message;
		message << "'tB.size()' has to be equal to 'K' * 'N' * 2 ('tB.size()' = " << tB.size() << ", 'K' = " << K
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (tC.size() != unsigned(M * N * 1))
	{
		std::stringstream message;
		message << "'tC.size()' has to be equal to 'M' * 'N' * 1 ('tC.size()' = " << tC.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	cgemm_r(M, N, K, A.data(), tB.data(), tC.data());
}

template <typename T>
inline void cgemm_r(const int M, const int N, const int K,
                    const T *A,
                    const T *tB,
                          T *tC)
{
	const T*  A_real =  A;
	const T*  A_imag =  A + ((M * K) >> 1);
	const T* tB_real = tB;
	const T* tB_imag = tB + ((N * K) >> 1);
	      T* tC_real = tC;

	for (auto i = 0; i < M; i++)
	{
		for (auto j = 0; j < N; j++)
		{
			T sum_r = 0;
			for (auto k = 0; k < K; k++)
				sum_r += A_real[i * K + k] * tB_real[j * K + k] - A_imag[i * K + k] * tB_imag[j * K + k];

			tC_real[j * M + i] = sum_r;
		}
	}
}

template <typename T, class AT>
inline void real_transpose(const int M, const int N,
                           const std::vector<T,AT> &A,
                                 std::vector<T,AT> &B)
{
	if (A.size() != unsigned(M * N))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'N' ('A.size()' = " << A.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (B.size() != unsigned(N * M))
	{
		std::stringstream message;
		message << "'B.size()' has to be equal to 'N' * 'M' ('B.size()' = " << B.size() << ", 'N' = " << N
		        << ", 'M' = " << M << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	real_transpose(M, N, A.data(), B.data());
}

template <typename T>
inline void real_transpose(const int M, const int N,
                           const T *A,
                                 T *B)
{
	for (auto i = 0; i < M; i++)
		for (auto j = 0; j < N; j++)
			B[j*M+i] =  A[i*N+j];
}

template <typename T, class AT>
inline void complex_transpose(const int M, const int N,
                              const std::vector<T,AT> &A,
                                    std::vector<T,AT> &B)
{
	if (A.size() != unsigned(M * N * 2))
	{
		std::stringstream message;
		message << "'A.size()' has to be equal to 'M' * 'N' * 2 ('A.size()' = " << A.size() << ", 'M' = " << M
		        << ", 'N' = " << N << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (B.size() != unsigned(N * M * 2))
	{
		std::stringstream message;
		message << "'B.size()' has to be equal to 'N' * 'M' * 2 ('B.size()' = " << B.size() << ", 'N' = " << N
		        << ", 'M' = " << M << ").";
		throw length_error(__FILE__, __LINE__, __func__, message.str());
	}

	complex_transpose(M, N, A.data(), B.data());
}

template <typename T>
inline void complex_transpose(const int M, const int N,
                              const T *A,
                                    T *B)
{
	const T* A_real = A;
	const T* A_imag = A + M * N;
	      T* B_real = B;
	      T* B_imag = B + M * N;

	for (auto i = 0; i < M; i++)
	{
		for (auto j = 0; j < N; j++)
		{
			B_real[j*M+i] =  A_real[i*N+j];
			B_imag[j*M+i] = -A_imag[i*N+j];
		}
	}
}
}
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Andre Hartmann <aha_1980@gmx.de>
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include <utils/ansiescapecodehandler.h>

#include <QString>
#include <QtTest>

using namespace Utils;

typedef QList<StringFormatPair> ResultList;

Q_DECLARE_METATYPE(QTextCharFormat);
Q_DECLARE_METATYPE(StringFormatPair);
Q_DECLARE_METATYPE(ResultList);

static QString ansiEscape(const QByteArray &sequence)
{
    return QString::fromLatin1("\x1b[" + sequence);
}

class tst_AnsiEscapeCodeHandler : public QObject
{
    Q_OBJECT

public:
    tst_AnsiEscapeCodeHandler();

private Q_SLOTS:
    void testCase1();
    void testCase1_data();

private:
    const QString red;
    const QString bold;
    const QString normal;
    const QString normal1;
};

tst_AnsiEscapeCodeHandler::tst_AnsiEscapeCodeHandler() :
    red(ansiEscape("31m")),
    bold(ansiEscape("1m")),
    normal(ansiEscape("0m")),
    normal1(ansiEscape("m"))
{
}

void tst_AnsiEscapeCodeHandler::testCase1()
{
    QFETCH(QString, text);
    QFETCH(QTextCharFormat, format);
    QFETCH(ResultList, expected);

    AnsiEscapeCodeHandler handler;
    ResultList result = handler.parseText(text, format);
    handler.endFormatScope();

    QVERIFY(result.size() == expected.size());
    for (int i = 0; i < result.size(); ++i) {
        QVERIFY(result[i].first == expected[i].first);
        QVERIFY(result[i].second == expected[i].second);
    }
}

void tst_AnsiEscapeCodeHandler::testCase1_data()
{
    QTest::addColumn<QString>("text");
    QTest::addColumn<QTextCharFormat>("format");
    QTest::addColumn<ResultList>("expected");

    // Test pass-through
    QTextCharFormat defaultFormat;
    QTest::newRow("Pass-through") << "Hello World" << defaultFormat
                       << (ResultList() << StringFormatPair("Hello World", defaultFormat));

    // Test text-color change
    QTextCharFormat redFormat;
    redFormat.setForeground(QColor(170, 0, 0));
    const QString text2 = "This is " + red + "red" + normal + " text";
    QTest::newRow("Text-color change") << text2 << QTextCharFormat()
                       << (ResultList()
                            << StringFormatPair("This is ", defaultFormat)
                            << StringFormatPair("red", redFormat)
                            << StringFormatPair(" text", defaultFormat));

    // Test text format change to bold
    QTextCharFormat boldFormat;
    boldFormat.setFontWeight(QFont::Bold);
    const QString text3 = "A line of " + bold + "bold" + normal + " text";
    QTest::newRow("Text-format change") << text3 << QTextCharFormat()
                       << (ResultList()
                            << StringFormatPair("A line of ", defaultFormat)
                            << StringFormatPair("bold", boldFormat)
                            << StringFormatPair(" text", defaultFormat));

    // Test resetting format to normal with other reset pattern
    const QString text4 = "A line of " + bold + "bold" + normal1 + " text";
    QTest::newRow("Alternative reset pattern (QTCREATORBUG-10132)") << text4 << QTextCharFormat()
                       << (ResultList()
                            << StringFormatPair("A line of ", defaultFormat)
                            << StringFormatPair("bold", boldFormat)
                            << StringFormatPair(" text", defaultFormat));
}

QTEST_APPLESS_MAIN(tst_AnsiEscapeCodeHandler)

#include "tst_ansiescapecodehandler.moc"
<commit_msg>ANSI: Use QCOMPARE instead of QVERIFY<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Andre Hartmann <aha_1980@gmx.de>
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include <utils/ansiescapecodehandler.h>

#include <QString>
#include <QtTest>

using namespace Utils;

typedef QList<StringFormatPair> ResultList;

Q_DECLARE_METATYPE(QTextCharFormat);
Q_DECLARE_METATYPE(StringFormatPair);
Q_DECLARE_METATYPE(ResultList);

static QString ansiEscape(const QByteArray &sequence)
{
    return QString::fromLatin1("\x1b[" + sequence);
}

class tst_AnsiEscapeCodeHandler : public QObject
{
    Q_OBJECT

public:
    tst_AnsiEscapeCodeHandler();

private Q_SLOTS:
    void testCase1();
    void testCase1_data();

private:
    const QString red;
    const QString bold;
    const QString normal;
    const QString normal1;
};

tst_AnsiEscapeCodeHandler::tst_AnsiEscapeCodeHandler() :
    red(ansiEscape("31m")),
    bold(ansiEscape("1m")),
    normal(ansiEscape("0m")),
    normal1(ansiEscape("m"))
{
}

void tst_AnsiEscapeCodeHandler::testCase1()
{
    QFETCH(QString, text);
    QFETCH(QTextCharFormat, format);
    QFETCH(ResultList, expected);

    AnsiEscapeCodeHandler handler;
    ResultList result = handler.parseText(text, format);
    handler.endFormatScope();

    QCOMPARE(result.size(), expected.size());
    for (int i = 0; i < result.size(); ++i) {
        QCOMPARE(result[i].first, expected[i].first);
        QCOMPARE(result[i].second, expected[i].second);
    }
}

void tst_AnsiEscapeCodeHandler::testCase1_data()
{
    QTest::addColumn<QString>("text");
    QTest::addColumn<QTextCharFormat>("format");
    QTest::addColumn<ResultList>("expected");

    // Test pass-through
    QTextCharFormat defaultFormat;
    QTest::newRow("Pass-through") << "Hello World" << defaultFormat
                       << (ResultList() << StringFormatPair("Hello World", defaultFormat));

    // Test text-color change
    QTextCharFormat redFormat;
    redFormat.setForeground(QColor(170, 0, 0));
    const QString text2 = "This is " + red + "red" + normal + " text";
    QTest::newRow("Text-color change") << text2 << QTextCharFormat()
                       << (ResultList()
                            << StringFormatPair("This is ", defaultFormat)
                            << StringFormatPair("red", redFormat)
                            << StringFormatPair(" text", defaultFormat));

    // Test text format change to bold
    QTextCharFormat boldFormat;
    boldFormat.setFontWeight(QFont::Bold);
    const QString text3 = "A line of " + bold + "bold" + normal + " text";
    QTest::newRow("Text-format change") << text3 << QTextCharFormat()
                       << (ResultList()
                            << StringFormatPair("A line of ", defaultFormat)
                            << StringFormatPair("bold", boldFormat)
                            << StringFormatPair(" text", defaultFormat));

    // Test resetting format to normal with other reset pattern
    const QString text4 = "A line of " + bold + "bold" + normal1 + " text";
    QTest::newRow("Alternative reset pattern (QTCREATORBUG-10132)") << text4 << QTextCharFormat()
                       << (ResultList()
                            << StringFormatPair("A line of ", defaultFormat)
                            << StringFormatPair("bold", boldFormat)
                            << StringFormatPair(" text", defaultFormat));
}

QTEST_APPLESS_MAIN(tst_AnsiEscapeCodeHandler)

#include "tst_ansiescapecodehandler.moc"
<|endoftext|>


<commit_before><commit_msg>planning: add check upon mkstemp() return value<commit_after><|endoftext|>


<commit_before>#include <boost/lexical_cast.hpp>
#include <sstream>
#include <limits>
#include <string>
#include "util/numconversions.h"
#include <iostream>
#include "zorba/common.h"

namespace xqp {
  bool NumConversions::isNegZero(const xqpString& aStr) {
    xqpString lStr = aStr.trim(" \n\r\t", 4);
    size_t lLength = aStr.length();
    const char* lChars = aStr.c_str();
    if (lChars[0] == '-') {
      for(size_t i = 1; i < lLength; ++i) {
        if (lChars[i] != '0') {
          return false;
        }
      }
      return true;
    } else {
      return false;
    }
  }

  short NumConversions::isInfOrNan(const char* aCharStar) {
#ifdef HAVE_STRCASECMP_FUNCTION
      if (strcasecmp(aCharStar, "inf") == 0 || strcasecmp(aCharStar, "+inf") == 0 )
#else
      if (_stricmp(aCharStar, "inf") == 0 || _stricmp(aCharStar, "+inf") == 0 )
#endif
      {
        return 1;
      }
#ifdef HAVE_STRCASECMP_FUNCTION
      else if (strcasecmp(aCharStar, "-inf") == 0 )
#else
      else if (_stricmp(aCharStar, "-inf") == 0 )
#endif
      {
        return -1;
      }
#ifdef HAVE_STRCASECMP_FUNCTION
      else if (strcasecmp(aCharStar, "nan") == 0 )
#else
      else if (_stricmp(aCharStar, "nan") == 0 )
#endif
      {
        return 0;
      }
      else
      {
        return -2;
      }
  }

  bool NumConversions::strToInteger(const xqpString& aStr, xqp_integer& aInteger){
    try {
      aInteger = boost::lexical_cast<xqp_integer>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::integerToStr(xqp_integer aInteger){
    return boost::lexical_cast<std::string>(aInteger);
  }
  bool NumConversions::strToUInteger(const xqpString& aStr, xqp_uinteger& aUInteger){
    try {
      aUInteger = boost::lexical_cast<xqp_uinteger>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::uintegerToStr(xqp_uinteger aUInteger){
    return boost::lexical_cast<std::string>(aUInteger);
  }
  bool NumConversions::starCharToInt(const char* aStarChar, xqp_int& aInt){
    try {
      aInt =  boost::lexical_cast<xqp_int>(aStarChar);
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  bool NumConversions::strToInt(const xqpString& aStr, xqp_int& aInt) {
    return starCharToInt(aStr.c_str(), aInt);
  }
  xqpString NumConversions::intToStr(xqp_int aInt){
    return boost::lexical_cast<std::string>(aInt);
  }
  bool NumConversions::strToUInt(const xqpString& aStr, xqp_uint& aUInt){
    if ( isNegZero(aStr)) {
      aUInt = 0;
      return true;
    }
    try {
      aUInt =  boost::lexical_cast<xqp_uint>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::uintToStr(xqp_uint aUInt){
    return boost::lexical_cast<std::string>(aUInt);
  }
  bool NumConversions::strToLong(const xqpString& aStr, xqp_long& aLong){
    try {
      aLong = boost::lexical_cast<xqp_long>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::longToStr(xqp_long aLong){
    return boost::lexical_cast<std::string>(aLong);
  }
  bool NumConversions::strToULong(const xqpString& aStr, xqp_ulong& aULong){
    if ( isNegZero(aStr)) {
      aULong = 0;
      return true;
    }
    try {
      aULong = boost::lexical_cast<xqp_ulong>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::ulongToStr(xqp_ulong aULong){
    return boost::lexical_cast<std::string>(aULong);
  }
  bool NumConversions::strToShort(const xqpString& aStr, xqp_short& aShort){
    try {
      aShort = boost::lexical_cast<xqp_short>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::shortToStr(xqp_short aShort){
    return boost::lexical_cast<std::string>(aShort);
  }
  bool NumConversions::strToUShort(const xqpString& aStr, xqp_ushort& aUShort){
    if ( isNegZero(aStr )) {
      aUShort = 0;
      return true;
    }
    try {
      aUShort = boost::lexical_cast<xqp_ushort>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::ushortToStr(xqp_ushort aUShort){
    return boost::lexical_cast<std::string>(aUShort);
  }
  bool NumConversions::starCharToDecimal(const char* aStarChar, xqp_decimal& aDecimal){
    try {
      aDecimal = boost::lexical_cast<xqp_decimal>(aStarChar);
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  bool NumConversions::strToDecimal(const xqpString& aStr, xqp_decimal& aDecimal) {
    return starCharToDecimal(aStr.c_str(), aDecimal);
  }
  xqpString NumConversions::decimalToStr(xqp_decimal aDecimal){
    return boost::lexical_cast<std::string>(aDecimal);
  }

  bool NumConversions::starCharToFloat(const char* aCharStar, xqp_float& aFloat) {
    char* lEndPtr;

    // Not all systems support strtof
#ifdef HAVE_STRTOF_FUNCTION
    aFloat = strtof(aCharStar, &lEndPtr);
#else
    // If strtof is not supported, zorba uses strtod
    // and makes a max, min check before casting to float
    xqp_double lTmpDouble = strtod(aCharStar, &lEndPtr);
    if (*lEndPtr == '\0') {
// undef's are used because Windows has some makro definitions on min and max
// => without undef, 'min()' and 'max()' would be replace by something
#  undef max
#  undef min
      if ( lTmpDouble > std::numeric_limits<xqp_float>::max() )
        aFloat = std::numeric_limits<xqp_float>::infinity();
      else if ( lTmpDouble < std::numeric_limits<xqp_float>::min() )
        aFloat = -std::numeric_limits<xqp_float>::infinity();
      else
        aFloat = static_cast<xqp_float>(lTmpDouble);
    }
#endif

    if (*lEndPtr != '\0') {
#ifdef UNIX
      return false;
#else
      // Only for unix systems, we are sure that they can parse 'inf' and '-inf' correclty
      // => we try to do it by hand for all other systems in case of a parsing error
      short lInf = NumConversions::isInfOrNan(aCharStar);
      if (lInf == -1) {
        aFloat = -std::numeric_limits<xqp_float>::infinity();
        return true;
      } else if (lInf == 1) {
        aFloat = std::numeric_limits<xqp_float>::infinity();
        return true;
      } else if (lInf == 0) {
        Assert(std::numeric_limits<xqp_double>::has_quiet_NaN());
        aFloat = std::numeric_limits<xqp_float>::quiet_NaN();
      } else {
        return false;
      }
#endif
    }
    return true;
  }

  bool NumConversions::strToFloat(const xqpString& aStr, xqp_float& aFloat){
    return NumConversions::starCharToFloat(aStr.c_str(), aFloat);
  }
  xqpString NumConversions::floatToStr(xqp_float aFloat){
    if (aFloat == std::numeric_limits<xqp_float>::infinity())
      return "INF";
    else if (aFloat == -std::numeric_limits<xqp_float>::infinity())
      return "-INF";
    else if (aFloat != aFloat)
      return "NaN";
    else {
      std::stringstream lStream;
      lStream << aFloat;
      return lStream.str();
    }
  }
  bool NumConversions::starCharToDouble(const char* aCharStar, xqp_double& aDouble){
    char* lEndPtr;
    aDouble = strtod(aCharStar, &lEndPtr);
    if (*lEndPtr != '\0') {
#ifdef UNIX
      return false;
#else
      // Only for unix systems, we are sure that they can parse 'inf' and '-inf' correclty
      // => we try to do it by hand for all other systems in case of a parsing error
      short lInf = NumConversions::isInfOrNan(aCharStar);
      if (lInf == -1) {
        aDouble = -std::numeric_limits<xqp_double>::infinity();
        return true;
      } else if (lInf == 1) {
        aDouble = std::numeric_limits<xqp_double>::infinity();
        return true;
      } else if (lInf == 0) {
        Assert(std::numeric_limits<xqp_double>::has_quiet_NaN());
        aDouble = std::numeric_limits<xqp_double>::quiet_NaN();
      } else {
        return false;
      }
#endif
    }
    return true;
  }
  bool NumConversions::strToDouble(const xqpString& aStr, xqp_double& aDouble) {
    return starCharToDouble(aStr.c_str(), aDouble);
  }
  xqpString NumConversions::doubleToStr(xqp_double aDouble){
    if (aDouble == std::numeric_limits<xqp_double>::infinity())
      return "INF";
    else if (aDouble == -std::numeric_limits<xqp_double>::infinity())
      return "-INF";
    else if (aDouble != aDouble)
      return "NaN";
    else {
      std::stringstream lStream;
      lStream << aDouble;
      return lStream.str();
    }
  }
  bool NumConversions::strToByte(const xqpString& aStr, xqp_byte& aByte){
    try {
      xqp_int lInt = boost::lexical_cast<xqp_int>(aStr.c_str());
      if (lInt >= -128 && lInt <= 127) {
        aByte = lInt;
        return true;
      } else {
        return false;
      }
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::byteToStr(xqp_byte aByte){
    xqp_int lInt = aByte;
    return boost::lexical_cast<std::string>(lInt);
  }
  bool NumConversions::strToUByte(const xqpString& aStr, xqp_ubyte& aUByte){
    if ( isNegZero(aStr)) {
      aUByte = 0;
      return true;
    }
    try {
      xqp_uint lUInt = boost::lexical_cast<xqp_uint>(aStr.c_str());
      if (lUInt >= 0 && lUInt <= 255) {
        aUByte = lUInt;
        return true;
      } else {
        return false;
      }
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::ubyteToStr(xqp_ubyte aUByte){
    xqp_uint lUInt = aUByte;
    return boost::lexical_cast<std::string>(lUInt);
  }

  bool NumConversions::isNaN(xqp_double aDouble) {
    return aDouble != aDouble;
  }

  bool NumConversions::isNaN(xqp_float aFloat) {
    return aFloat != aFloat;
  }

  bool NumConversions::isPosOrNegInf(xqp_double aDouble) {
    return (aDouble == std::numeric_limits<xqp_double>::infinity()
      || aDouble == -std::numeric_limits<xqp_double>::infinity());
  }

  bool NumConversions::isPosOrNegInf(xqp_float aFloat) {
    return (aFloat == std::numeric_limits<xqp_float>::infinity()
      || aFloat == -std::numeric_limits<xqp_float>::infinity());
  }
} /* namespace xqp */
<commit_msg>Comments added<commit_after>#include <boost/lexical_cast.hpp>
#include <sstream>
#include <limits>
#include <string>
#include "util/numconversions.h"
#include <iostream>
#include "zorba/common.h"

namespace xqp {
  bool NumConversions::isNegZero(const xqpString& aStr) {
    xqpString lStr = aStr.trim(" \n\r\t", 4);
    size_t lLength = aStr.length();
    const char* lChars = aStr.c_str();
    if (lChars[0] == '-') {
      for(size_t i = 1; i < lLength; ++i) {
        if (lChars[i] != '0') {
          return false;
        }
      }
      return true;
    } else {
      return false;
    }
  }

  short NumConversions::isInfOrNan(const char* aCharStar) {
#ifdef HAVE_STRCASECMP_FUNCTION
      if (strcasecmp(aCharStar, "inf") == 0 || strcasecmp(aCharStar, "+inf") == 0 )
#else
      if (_stricmp(aCharStar, "inf") == 0 || _stricmp(aCharStar, "+inf") == 0 )
#endif
      {
        return 1;
      }
#ifdef HAVE_STRCASECMP_FUNCTION
      else if (strcasecmp(aCharStar, "-inf") == 0 )
#else
      else if (_stricmp(aCharStar, "-inf") == 0 )
#endif
      {
        return -1;
      }
#ifdef HAVE_STRCASECMP_FUNCTION
      else if (strcasecmp(aCharStar, "nan") == 0 )
#else
      else if (_stricmp(aCharStar, "nan") == 0 )
#endif
      {
        return 0;
      }
      else
      {
        return -2;
      }
  }

  bool NumConversions::strToInteger(const xqpString& aStr, xqp_integer& aInteger){
    try {
      aInteger = boost::lexical_cast<xqp_integer>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::integerToStr(xqp_integer aInteger){
    return boost::lexical_cast<std::string>(aInteger);
  }
  bool NumConversions::strToUInteger(const xqpString& aStr, xqp_uinteger& aUInteger){
    try {
      aUInteger = boost::lexical_cast<xqp_uinteger>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::uintegerToStr(xqp_uinteger aUInteger){
    return boost::lexical_cast<std::string>(aUInteger);
  }
  bool NumConversions::starCharToInt(const char* aStarChar, xqp_int& aInt){
    try {
      aInt =  boost::lexical_cast<xqp_int>(aStarChar);
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  bool NumConversions::strToInt(const xqpString& aStr, xqp_int& aInt) {
    return starCharToInt(aStr.c_str(), aInt);
  }
  xqpString NumConversions::intToStr(xqp_int aInt){
    return boost::lexical_cast<std::string>(aInt);
  }
  bool NumConversions::strToUInt(const xqpString& aStr, xqp_uint& aUInt){
    if ( isNegZero(aStr)) {
      aUInt = 0;
      return true;
    }
    try {
      aUInt =  boost::lexical_cast<xqp_uint>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::uintToStr(xqp_uint aUInt){
    return boost::lexical_cast<std::string>(aUInt);
  }
  bool NumConversions::strToLong(const xqpString& aStr, xqp_long& aLong){
    try {
      aLong = boost::lexical_cast<xqp_long>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::longToStr(xqp_long aLong){
    return boost::lexical_cast<std::string>(aLong);
  }
  bool NumConversions::strToULong(const xqpString& aStr, xqp_ulong& aULong){
    if ( isNegZero(aStr)) {
      aULong = 0;
      return true;
    }
    try {
      aULong = boost::lexical_cast<xqp_ulong>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::ulongToStr(xqp_ulong aULong){
    return boost::lexical_cast<std::string>(aULong);
  }
  bool NumConversions::strToShort(const xqpString& aStr, xqp_short& aShort){
    try {
      aShort = boost::lexical_cast<xqp_short>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::shortToStr(xqp_short aShort){
    return boost::lexical_cast<std::string>(aShort);
  }
  bool NumConversions::strToUShort(const xqpString& aStr, xqp_ushort& aUShort){
    if ( isNegZero(aStr )) {
      aUShort = 0;
      return true;
    }
    try {
      aUShort = boost::lexical_cast<xqp_ushort>(aStr.c_str());
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::ushortToStr(xqp_ushort aUShort){
    return boost::lexical_cast<std::string>(aUShort);
  }
  bool NumConversions::starCharToDecimal(const char* aStarChar, xqp_decimal& aDecimal){
    try {
      aDecimal = boost::lexical_cast<xqp_decimal>(aStarChar);
      return true;
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  bool NumConversions::strToDecimal(const xqpString& aStr, xqp_decimal& aDecimal) {
    return starCharToDecimal(aStr.c_str(), aDecimal);
  }
  xqpString NumConversions::decimalToStr(xqp_decimal aDecimal){
    return boost::lexical_cast<std::string>(aDecimal);
  }

  bool NumConversions::starCharToFloat(const char* aCharStar, xqp_float& aFloat) {
    char* lEndPtr;

    // Not all systems support strtof
#ifdef HAVE_STRTOF_FUNCTION
    aFloat = strtof(aCharStar, &lEndPtr);
#else
    // If strtof is not supported, zorba uses strtod
    // and makes a max, min check before casting to float
    xqp_double lTmpDouble = strtod(aCharStar, &lEndPtr);
    if (*lEndPtr == '\0') {
// undef's are used because Windows has some makro definitions on min and max
// => without undef, 'min()' and 'max()' would be replace by something
#  undef max
#  undef min
      if ( lTmpDouble > std::numeric_limits<xqp_float>::max() )
        aFloat = std::numeric_limits<xqp_float>::infinity();
      else if ( lTmpDouble < std::numeric_limits<xqp_float>::min() )
        aFloat = -std::numeric_limits<xqp_float>::infinity();
      else
        aFloat = static_cast<xqp_float>(lTmpDouble);
    }
#endif

    if (*lEndPtr != '\0') {
#ifdef UNIX
      return false;
#else
      // Only for unix systems, we are sure that they can parse 'inf' and '-inf' correclty
      // => we try to do it by hand for all other systems in case of a parsing error
      short lInf = NumConversions::isInfOrNan(aCharStar);
      if (lInf == -1) {
        aFloat = -std::numeric_limits<xqp_float>::infinity();
        return true;
      } else if (lInf == 1) {
        aFloat = std::numeric_limits<xqp_float>::infinity();
        return true;
      } else if (lInf == 0) {
        // TODO Handling when compiler does not support quiet_NaN
        Assert(std::numeric_limits<xqp_double>::has_quiet_NaN());
        aFloat = std::numeric_limits<xqp_float>::quiet_NaN();
      } else {
        return false;
      }
#endif
    }
    return true;
  }

  bool NumConversions::strToFloat(const xqpString& aStr, xqp_float& aFloat){
    return NumConversions::starCharToFloat(aStr.c_str(), aFloat);
  }
  xqpString NumConversions::floatToStr(xqp_float aFloat){
    if (aFloat == std::numeric_limits<xqp_float>::infinity())
      return "INF";
    else if (aFloat == -std::numeric_limits<xqp_float>::infinity())
      return "-INF";
    else if (aFloat != aFloat)
      return "NaN";
    else {
      std::stringstream lStream;
      lStream << aFloat;
      return lStream.str();
    }
  }
  bool NumConversions::starCharToDouble(const char* aCharStar, xqp_double& aDouble){
    char* lEndPtr;
    aDouble = strtod(aCharStar, &lEndPtr);
    if (*lEndPtr != '\0') {
#ifdef UNIX
      return false;
#else
      // Only for unix systems, we are sure that they can parse 'inf' and '-inf' correclty
      // => we try to do it by hand for all other systems in case of a parsing error
      short lInf = NumConversions::isInfOrNan(aCharStar);
      if (lInf == -1) {
        aDouble = -std::numeric_limits<xqp_double>::infinity();
        return true;
      } else if (lInf == 1) {
        aDouble = std::numeric_limits<xqp_double>::infinity();
        return true;
      } else if (lInf == 0) {
        // TODO Handling when compiler does not suppoert quiet_NaN
        Assert(std::numeric_limits<xqp_double>::has_quiet_NaN());
        aDouble = std::numeric_limits<xqp_double>::quiet_NaN();
      } else {
        return false;
      }
#endif
    }
    return true;
  }
  bool NumConversions::strToDouble(const xqpString& aStr, xqp_double& aDouble) {
    return starCharToDouble(aStr.c_str(), aDouble);
  }
  xqpString NumConversions::doubleToStr(xqp_double aDouble){
    if (aDouble == std::numeric_limits<xqp_double>::infinity())
      return "INF";
    else if (aDouble == -std::numeric_limits<xqp_double>::infinity())
      return "-INF";
    else if (aDouble != aDouble)
      return "NaN";
    else {
      std::stringstream lStream;
      lStream << aDouble;
      return lStream.str();
    }
  }
  bool NumConversions::strToByte(const xqpString& aStr, xqp_byte& aByte){
    try {
      xqp_int lInt = boost::lexical_cast<xqp_int>(aStr.c_str());
      if (lInt >= -128 && lInt <= 127) {
        aByte = lInt;
        return true;
      } else {
        return false;
      }
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::byteToStr(xqp_byte aByte){
    xqp_int lInt = aByte;
    return boost::lexical_cast<std::string>(lInt);
  }
  bool NumConversions::strToUByte(const xqpString& aStr, xqp_ubyte& aUByte){
    if ( isNegZero(aStr)) {
      aUByte = 0;
      return true;
    }
    try {
      xqp_uint lUInt = boost::lexical_cast<xqp_uint>(aStr.c_str());
      if (lUInt >= 0 && lUInt <= 255) {
        aUByte = lUInt;
        return true;
      } else {
        return false;
      }
    } catch (boost::bad_lexical_cast &) {
      return false;
    }
  }
  xqpString NumConversions::ubyteToStr(xqp_ubyte aUByte){
    xqp_uint lUInt = aUByte;
    return boost::lexical_cast<std::string>(lUInt);
  }

  bool NumConversions::isNaN(xqp_double aDouble) {
    return aDouble != aDouble;
  }

  bool NumConversions::isNaN(xqp_float aFloat) {
    return aFloat != aFloat;
  }

  bool NumConversions::isPosOrNegInf(xqp_double aDouble) {
    return (aDouble == std::numeric_limits<xqp_double>::infinity()
      || aDouble == -std::numeric_limits<xqp_double>::infinity());
  }

  bool NumConversions::isPosOrNegInf(xqp_float aFloat) {
    return (aFloat == std::numeric_limits<xqp_float>::infinity()
      || aFloat == -std::numeric_limits<xqp_float>::infinity());
  }
} /* namespace xqp */
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "test/test_main_lib.h"

#include <fstream>
#include <string>

#include "absl/memory/memory.h"
#include "rtc_base/checks.h"
#include "rtc_base/flags.h"
#include "rtc_base/logging.h"
#include "rtc_base/thread.h"
#include "system_wrappers/include/field_trial.h"
#include "system_wrappers/include/metrics.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"
#include "test/testsupport/perf_test.h"

#if defined(WEBRTC_WIN)
#include "rtc_base/win32socketinit.h"
#endif

#if defined(WEBRTC_IOS)
#include "test/ios/test_support.h"

WEBRTC_DEFINE_string(NSTreatUnknownArgumentsAsOpen,
                     "",
                     "Intentionally ignored flag intended for iOS simulator.");
WEBRTC_DEFINE_string(ApplePersistenceIgnoreState,
                     "",
                     "Intentionally ignored flag intended for iOS simulator.");
WEBRTC_DEFINE_bool(
    save_chartjson_result,
    false,
    "Store the perf results in Documents/perf_result.json in the format "
    "described by "
    "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/"
    "data-format.md.");

#else

WEBRTC_DEFINE_string(
    isolated_script_test_output,
    "",
    "Path to output an empty JSON file which Chromium infra requires.");

WEBRTC_DEFINE_string(
    isolated_script_test_perf_output,
    "",
    "Path where the perf results should be stored in the JSON format described "
    "by "
    "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/"
    "data-format.md.");

#endif

WEBRTC_DEFINE_bool(logs, false, "print logs to stderr");

WEBRTC_DEFINE_string(
    force_fieldtrials,
    "",
    "Field trials control experimental feature code which can be forced. "
    "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
    " will assign the group Enable to field trial WebRTC-FooFeature.");

WEBRTC_DEFINE_bool(help, false, "Print this message.");

namespace webrtc {

namespace {

class TestMainImpl : public TestMain {
 public:
  int Init(int* argc, char* argv[]) override {
    ::testing::InitGoogleMock(argc, argv);

    // Default to LS_INFO, even for release builds to provide better test
    // logging.
    // TODO(pbos): Consider adding a command-line override.
    if (rtc::LogMessage::GetLogToDebug() > rtc::LS_INFO)
      rtc::LogMessage::LogToDebug(rtc::LS_INFO);

    if (rtc::FlagList::SetFlagsFromCommandLine(argc, argv, false)) {
      return 1;
    }
    if (FLAG_help) {
      rtc::FlagList::Print(nullptr, false);
      return 0;
    }

    // TODO(bugs.webrtc.org/9792): we need to reference something from
    // fileutils.h so that our downstream hack where we replace fileutils.cc
    // works. Otherwise the downstream flag implementation will take over and
    // botch the flag introduced by the hack. Remove this awful thing once the
    // downstream implementation has been eliminated.
    (void)webrtc::test::JoinFilename("horrible", "hack");

    webrtc::test::ValidateFieldTrialsStringOrDie(FLAG_force_fieldtrials);
    // InitFieldTrialsFromString stores the char*, so the char array must
    // outlive the application.
    webrtc::field_trial::InitFieldTrialsFromString(FLAG_force_fieldtrials);
    webrtc::metrics::Enable();

#if defined(WEBRTC_WIN)
    winsock_init_ = absl::make_unique<rtc::WinsockInitializer>();
#endif

    rtc::LogMessage::SetLogToStderr(FLAG_logs);

    // Ensure that main thread gets wrapped as an rtc::Thread.
    // TODO(bugs.webrt.org/9714): It might be better to avoid wrapping the main
    // thread, or leave it to individual tests that need it. But as long as we
    // have automatic thread wrapping, we need this to avoid that some other
    // random thread (which one depending on which tests are run) gets
    // automatically wrapped.
    rtc::ThreadManager::Instance()->WrapCurrentThread();
    RTC_CHECK(rtc::Thread::Current());
    return 0;
  }

  int Run(int argc, char* argv[]) override {
#if defined(WEBRTC_IOS)
    rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv,
                             FLAG_save_chartjson_result);
    rtc::test::RunTestsFromIOSApp();
    return 0;
#else
    int exit_code = RUN_ALL_TESTS();

    std::string chartjson_result_file = FLAG_isolated_script_test_perf_output;
    if (!chartjson_result_file.empty()) {
      webrtc::test::WritePerfResults(chartjson_result_file);
    }

    std::string result_filename = FLAG_isolated_script_test_output;
    if (!result_filename.empty()) {
      std::ofstream result_file(result_filename);
      result_file << "{\"version\": 3}";
      result_file.close();
    }

#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) ||  \
    defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
    defined(UNDEFINED_SANITIZER)
    // We want the test flagged as failed only for sanitizer defects,
    // in which case the sanitizer will override exit code with 66.
    return 0;
#endif

    return exit_code;
#endif
  }

  ~TestMainImpl() override = default;

 private:
#if defined(WEBRTC_WIN)
  std::unique_ptr<rtc::WinsockInitializer> winsock_init_;
#endif
};

}  // namespace

std::unique_ptr<TestMain> TestMain::Create() {
  return absl::make_unique<TestMainImpl>();
}

}  // namespace webrtc
<commit_msg>Add --verbose flag to test_main<commit_after>/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "test/test_main_lib.h"

#include <fstream>
#include <string>

#include "absl/memory/memory.h"
#include "rtc_base/checks.h"
#include "rtc_base/flags.h"
#include "rtc_base/logging.h"
#include "rtc_base/thread.h"
#include "system_wrappers/include/field_trial.h"
#include "system_wrappers/include/metrics.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"
#include "test/testsupport/perf_test.h"

#if defined(WEBRTC_WIN)
#include "rtc_base/win32socketinit.h"
#endif

#if defined(WEBRTC_IOS)
#include "test/ios/test_support.h"

WEBRTC_DEFINE_string(NSTreatUnknownArgumentsAsOpen,
                     "",
                     "Intentionally ignored flag intended for iOS simulator.");
WEBRTC_DEFINE_string(ApplePersistenceIgnoreState,
                     "",
                     "Intentionally ignored flag intended for iOS simulator.");
WEBRTC_DEFINE_bool(
    save_chartjson_result,
    false,
    "Store the perf results in Documents/perf_result.json in the format "
    "described by "
    "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/"
    "data-format.md.");

#else

WEBRTC_DEFINE_string(
    isolated_script_test_output,
    "",
    "Path to output an empty JSON file which Chromium infra requires.");

WEBRTC_DEFINE_string(
    isolated_script_test_perf_output,
    "",
    "Path where the perf results should be stored in the JSON format described "
    "by "
    "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/"
    "data-format.md.");

#endif

WEBRTC_DEFINE_bool(logs, false, "print logs to stderr");
WEBRTC_DEFINE_bool(verbose, false, "verbose logs to stderr");

WEBRTC_DEFINE_string(
    force_fieldtrials,
    "",
    "Field trials control experimental feature code which can be forced. "
    "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
    " will assign the group Enable to field trial WebRTC-FooFeature.");

WEBRTC_DEFINE_bool(help, false, "Print this message.");

namespace webrtc {

namespace {

class TestMainImpl : public TestMain {
 public:
  int Init(int* argc, char* argv[]) override {
    ::testing::InitGoogleMock(argc, argv);

    // Default to LS_INFO, even for release builds to provide better test
    // logging.
    if (rtc::LogMessage::GetLogToDebug() > rtc::LS_INFO)
      rtc::LogMessage::LogToDebug(rtc::LS_INFO);

    if (rtc::FlagList::SetFlagsFromCommandLine(argc, argv, false)) {
      return 1;
    }
    if (FLAG_help) {
      rtc::FlagList::Print(nullptr, false);
      return 0;
    }

    if (FLAG_verbose)
      rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE);

    rtc::LogMessage::SetLogToStderr(FLAG_logs || FLAG_verbose);

    // TODO(bugs.webrtc.org/9792): we need to reference something from
    // fileutils.h so that our downstream hack where we replace fileutils.cc
    // works. Otherwise the downstream flag implementation will take over and
    // botch the flag introduced by the hack. Remove this awful thing once the
    // downstream implementation has been eliminated.
    (void)webrtc::test::JoinFilename("horrible", "hack");

    webrtc::test::ValidateFieldTrialsStringOrDie(FLAG_force_fieldtrials);
    // InitFieldTrialsFromString stores the char*, so the char array must
    // outlive the application.
    webrtc::field_trial::InitFieldTrialsFromString(FLAG_force_fieldtrials);
    webrtc::metrics::Enable();

#if defined(WEBRTC_WIN)
    winsock_init_ = absl::make_unique<rtc::WinsockInitializer>();
#endif

    // Ensure that main thread gets wrapped as an rtc::Thread.
    // TODO(bugs.webrt.org/9714): It might be better to avoid wrapping the main
    // thread, or leave it to individual tests that need it. But as long as we
    // have automatic thread wrapping, we need this to avoid that some other
    // random thread (which one depending on which tests are run) gets
    // automatically wrapped.
    rtc::ThreadManager::Instance()->WrapCurrentThread();
    RTC_CHECK(rtc::Thread::Current());
    return 0;
  }

  int Run(int argc, char* argv[]) override {
#if defined(WEBRTC_IOS)
    rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv,
                             FLAG_save_chartjson_result);
    rtc::test::RunTestsFromIOSApp();
    return 0;
#else
    int exit_code = RUN_ALL_TESTS();

    std::string chartjson_result_file = FLAG_isolated_script_test_perf_output;
    if (!chartjson_result_file.empty()) {
      webrtc::test::WritePerfResults(chartjson_result_file);
    }

    std::string result_filename = FLAG_isolated_script_test_output;
    if (!result_filename.empty()) {
      std::ofstream result_file(result_filename);
      result_file << "{\"version\": 3}";
      result_file.close();
    }

#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) ||  \
    defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
    defined(UNDEFINED_SANITIZER)
    // We want the test flagged as failed only for sanitizer defects,
    // in which case the sanitizer will override exit code with 66.
    return 0;
#endif

    return exit_code;
#endif
  }

  ~TestMainImpl() override = default;

 private:
#if defined(WEBRTC_WIN)
  std::unique_ptr<rtc::WinsockInitializer> winsock_init_;
#endif
};

}  // namespace

std::unique_ptr<TestMain> TestMain::Create() {
  return absl::make_unique<TestMainImpl>();
}

}  // namespace webrtc
<|endoftext|>