<commit_before>/*
 * opencog/spatial/3DSpaceMap/Pathfinder3D.cc
 *
 * Copyright (C) 2002-2011 OpenCog Foundation
 * All Rights Reserved
 * Author(s): Shujing Ke
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "Pathfinder3D.h"
#include <set>
#include <map>
#include <iterator>

using namespace opencog;
using namespace opencog::spatial;

bool Pathfinder3D::AStar3DPathFinder(Octree3DMapManager *mapManager,  const BlockVector& begin, const BlockVector& target, vector<BlockVector>& path,
                                     BlockVector& nearestPos, BlockVector& bestPos, bool getNearestPos, bool getBestPos)
{
    BlockVector end = target;
    map<BlockVector,double> costMap;
    map<BlockVector,double>::const_iterator itercost;
    int searchTimes = 0;
    float nearestDis = begin - target;
    float bestHeuristic = nearestDis * 1.41421356f;
    nearestPos = begin;
    bestPos = begin;
    bool nostandable = false;

    // check if the begin and target pos standable first
    if ((! mapManager->checkStandable(begin)) || (! mapManager->checkStandable(target)))
    {
        nostandable = true;
        if ((! getNearestPos) && (! getBestPos))
        return false;
    }

    while(true)
    {
        set<BlockVector> searchedList;
        set<BlockVector>::const_iterator iter;
        BlockVector curPos;

        vector<BlockVector> currentPath;

        currentPath.push_back(begin);
        searchedList.insert(begin);
        int pathfindingSteps = 0;

        bool is_found = false;
        searchTimes ++;
        while(currentPath.size() != 0)
        {
            // successfully achieve the target
            if (currentPath.back() == end)
            {
                is_found = true;
                break;
            }

            // Calculate 24 neighbour cost and then pick the lowest one.
            double lowestCost = 999999.99;
            BlockVector lowestCostPos;
            double curCost;

            for (int i = -1; i < 2; i ++)
            {
                for (int j = -1; j < 2; j ++)
                {
                    for (int k = -1; k < 2; k ++)
                    {
                        // Will not calculate the pos just above or below  or equal to the begin position.
                        if ( (i == 0) && (j == 0))
                            continue;

                        curPos.x = currentPath.back().x + i;
                        curPos.y = currentPath.back().y + j;
                        curPos.z = currentPath.back().z + k;

                        iter = searchedList.find(curPos);
                        if (iter != searchedList.end())
                        {
                            // already searched!
                            continue;
                        }

                        // check if standable
                        if (! mapManager->checkStandable(curPos))
                        {
                            searchedList.insert(curPos);
                            continue;
                        }

                        if ( ! checkNeighbourAccessable(mapManager,currentPath.back() , i, j, k))
                            continue;

                        double costFromLastStep = 0.0;
                        if (k == 1) // this pos is higher than last pos, have to cost more to jump up
                            costFromLastStep = 0.2;
                        else if (k == -1) // this pos is lower than last pos, have to cost more to jump down
                            costFromLastStep = 0.1;

                        itercost = costMap.find(curPos);
                        if (itercost != costMap.end())
                        {
                            if ((double)(itercost->second) + costFromLastStep < lowestCost)
                            {
                                lowestCost = (double)(itercost->second) + costFromLastStep;
                                lowestCostPos = curPos;
                            }
                        }

                        // calculate the cost of this pos
                        curCost = calculateCostByDistance(begin, end, curPos,nearestDis,nearestPos,bestHeuristic,bestPos);

                        pathfindingSteps++;
                        costMap.insert(pair<BlockVector, int>(curPos,curCost));
                        if (curCost + costFromLastStep < lowestCost)
                        {
                            lowestCost = curCost +costFromLastStep;
                            lowestCostPos = curPos;
                        }
                    }
                }
            }

            // if the lowestCost still == 99999.99, it shows that all the neighbours have been searched and failed,
            // so we should return to last step
            if (lowestCost > 999999.0)
            {
                currentPath.pop_back();
            }
            else
            {
                // add the lowestcost neighbour pos to the currentPath
                currentPath.push_back(lowestCostPos);
                searchedList.insert(lowestCostPos);

            }

        }

        if (! is_found)
            return false;

        if ((currentPath.size() < 21) || (searchTimes > 4))
        {
            path.insert(path.begin(), currentPath.begin(), currentPath.end());
            if (nostandable)
                return false;
            else
                return true;
        }

        // find the farthest pos in this currrentPath from the end position
        vector<BlockVector>::iterator disIter, farPosIter;
        double farthestDis = 0.0;
        for(disIter = currentPath.begin(); disIter != currentPath.end(); ++ disIter)
        {
           double dis = (end - *disIter)  + (begin - *disIter);
           if ( dis > farthestDis)
           {
               farPosIter = disIter;
               farthestDis = dis;
           }
        }

        path.insert(path.begin(), farPosIter, currentPath.end());

        // The shortest way found!
        if (farPosIter == currentPath.begin())
        {
            if (nostandable)
                return false;
            else
                return true;
        }

        end = *(--farPosIter);

    }

}

double Pathfinder3D::calculateCostByDistance(const BlockVector& begin, const BlockVector& target,  const BlockVector& pos,
                                             float& nearestDis,BlockVector& nearestPos, float& bestHeuristic, BlockVector& bestPos)
{
    float dis = target - pos;
    if (dis < nearestDis)
    {
        nearestDis = dis;
        nearestPos = pos;
    }

    float heuristic = dis*1.41421356f + (begin - pos);
    if (heuristic < bestHeuristic )
    {
        bestHeuristic = heuristic;
        bestPos = pos;
    }

    return dis;
}

// before call this funciton, please make sure the pos want to access is standable first
bool Pathfinder3D::checkNeighbourAccessable(Octree3DMapManager *mapManager, BlockVector& lastPos, int i, int j, int k)
{
    // if want to access the pos 1 unit lower than last pos
    if (k == -1)
    {
        for (int h = 1; h <= mapManager->getAgentHeight(); h++)
        {
            if (i != 0)
            {
                BlockVector neighbour1(lastPos.x + i,lastPos.y,lastPos.z + h);
                if (mapManager->checkIsSolid(neighbour1))
                    return false;
            }

            if (j != 0)
            {
                BlockVector neighbour2(lastPos.x,lastPos.y + j,lastPos.z + h);
                if (mapManager->checkIsSolid(neighbour2))
                    return false;
            }

            if ( (i != 0) && (j != 0))
            {
                BlockVector neighbour3(lastPos.x + i,lastPos.y + j,lastPos.z + h);
                if (mapManager->checkIsSolid(neighbour3))
                    return false;
            }
        }

        return true;
    }

    // when the pos has the same z with the the last pos
    // or if want to access the pos 1 unit higher than the last pos
    // check if there are 2 blocks in the 45 degree directions block the way
    // e.g.: the B are blocks, one cannot access C,E,F,G from L
    //    CBE
    //    BLB
    //    FBG
    if ((i != 0) && (j != 0) ) // k == 0  or k == 1
    {
        // all the blocks in the two neighbour 45 direction inside the agentHeight will block the way
        for (int h = 0; h < mapManager->getAgentHeight(); h++)
        {
            BlockVector neighbour1(lastPos.x + i,lastPos.y,lastPos.z + h + k );
            if (mapManager->checkIsSolid(neighbour1))
                return false;

            BlockVector neighbour2(lastPos.x,lastPos.y + j,lastPos.z + h + k );
            if (mapManager->checkIsSolid(neighbour2))
                return false;
        }

        return true;
    }

    return true;
}
<commit_msg>Fixed a bug in pathfinder about checkNeighbourAccessable<commit_after>/*
 * opencog/spatial/3DSpaceMap/Pathfinder3D.cc
 *
 * Copyright (C) 2002-2011 OpenCog Foundation
 * All Rights Reserved
 * Author(s): Shujing Ke
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "Pathfinder3D.h"
#include <set>
#include <map>
#include <iterator>

using namespace opencog;
using namespace opencog::spatial;

bool Pathfinder3D::AStar3DPathFinder(Octree3DMapManager *mapManager,  const BlockVector& begin, const BlockVector& target, vector<BlockVector>& path,
                                     BlockVector& nearestPos, BlockVector& bestPos, bool getNearestPos, bool getBestPos)
{
    BlockVector end = target;
    map<BlockVector,double> costMap;
    map<BlockVector,double>::const_iterator itercost;
    int searchTimes = 0;
    float nearestDis = begin - target;
    float bestHeuristic = nearestDis * 1.41421356f;
    nearestPos = begin;
    bestPos = begin;
    bool nostandable = false;

    // check if the begin and target pos standable first
    if ((! mapManager->checkStandable(begin)) || (! mapManager->checkStandable(target)))
    {
        nostandable = true;
        if ((! getNearestPos) && (! getBestPos))
        return false;
    }

    while(true)
    {
        set<BlockVector> searchedList;
        set<BlockVector>::const_iterator iter;
        BlockVector curPos;

        vector<BlockVector> currentPath;

        currentPath.push_back(begin);
        searchedList.insert(begin);
        int pathfindingSteps = 0;

        bool is_found = false;
        searchTimes ++;
        while(currentPath.size() != 0)
        {
            // successfully achieve the target
            if (currentPath.back() == end)
            {
                is_found = true;
                break;
            }

            // Calculate 24 neighbour cost and then pick the lowest one.
            double lowestCost = 999999.99;
            BlockVector lowestCostPos;
            double curCost;

            for (int i = -1; i < 2; i ++)
            {
                for (int j = -1; j < 2; j ++)
                {
                    for (int k = -1; k < 2; k ++)
                    {
                        // Will not calculate the pos just above or below  or equal to the begin position.
                        if ( (i == 0) && (j == 0))
                            continue;

                        curPos.x = currentPath.back().x + i;
                        curPos.y = currentPath.back().y + j;
                        curPos.z = currentPath.back().z + k;

                        iter = searchedList.find(curPos);
                        if (iter != searchedList.end())
                        {
                            // already searched!
                            continue;
                        }

                        // check if standable
                        if (! mapManager->checkStandable(curPos))
                        {
                            searchedList.insert(curPos);
                            continue;
                        }

                        if ( ! checkNeighbourAccessable(mapManager,currentPath.back() , i, j, k))
                            continue;

                        double costFromLastStep = 0.0;
                        if (k == 1) // this pos is higher than last pos, have to cost more to jump up
                            costFromLastStep = 0.2;
                        else if (k == -1) // this pos is lower than last pos, have to cost more to jump down
                            costFromLastStep = 0.1;

                        itercost = costMap.find(curPos);
                        if (itercost != costMap.end())
                        {
                            if ((double)(itercost->second) + costFromLastStep < lowestCost)
                            {
                                lowestCost = (double)(itercost->second) + costFromLastStep;
                                lowestCostPos = curPos;
                            }
                        }

                        // calculate the cost of this pos
                        curCost = calculateCostByDistance(begin, end, curPos,nearestDis,nearestPos,bestHeuristic,bestPos);

                        pathfindingSteps++;
                        costMap.insert(pair<BlockVector, int>(curPos,curCost));
                        if (curCost + costFromLastStep < lowestCost)
                        {
                            lowestCost = curCost +costFromLastStep;
                            lowestCostPos = curPos;
                        }
                    }
                }
            }

            // if the lowestCost still == 99999.99, it shows that all the neighbours have been searched and failed,
            // so we should return to last step
            if (lowestCost > 999999.0)
            {
                currentPath.pop_back();
            }
            else
            {
                // add the lowestcost neighbour pos to the currentPath
                currentPath.push_back(lowestCostPos);
                searchedList.insert(lowestCostPos);

            }

        }

        if (! is_found)
            return false;

        if ((currentPath.size() < 21) || (searchTimes > 4))
        {
            path.insert(path.begin(), currentPath.begin(), currentPath.end());
            if (nostandable)
                return false;
            else
                return true;
        }

        // find the farthest pos in this currrentPath from the end position
        vector<BlockVector>::iterator disIter, farPosIter;
        double farthestDis = 0.0;
        for(disIter = currentPath.begin(); disIter != currentPath.end(); ++ disIter)
        {
           double dis = (end - *disIter)  + (begin - *disIter);
           if ( dis > farthestDis)
           {
               farPosIter = disIter;
               farthestDis = dis;
           }
        }

        path.insert(path.begin(), farPosIter, currentPath.end());

        // The shortest way found!
        if (farPosIter == currentPath.begin())
        {
            if (nostandable)
                return false;
            else
                return true;
        }

        end = *(--farPosIter);

    }

}

double Pathfinder3D::calculateCostByDistance(const BlockVector& begin, const BlockVector& target,  const BlockVector& pos,
                                             float& nearestDis,BlockVector& nearestPos, float& bestHeuristic, BlockVector& bestPos)
{
    float dis = target - pos;
    if (dis < nearestDis)
    {
        nearestDis = dis;
        nearestPos = pos;
    }

    float heuristic = dis*1.41421356f + (begin - pos);
    if (heuristic < bestHeuristic )
    {
        bestHeuristic = heuristic;
        bestPos = pos;
    }

    return dis;
}

// before call this funciton, please make sure the pos want to access is standable first
bool Pathfinder3D::checkNeighbourAccessable(Octree3DMapManager *mapManager, BlockVector& lastPos, int i, int j, int k)
{
    // if want to access the pos 1 unit lower than last pos
    if (k == -1)
    {
        for (int h = 1; h <= mapManager->getAgentHeight(); h++)
        {
            if (i != 0)
            {
                BlockVector neighbour1(lastPos.x + i,lastPos.y,lastPos.z + h);
                if (mapManager->checkIsSolid(neighbour1))
                    return false;
            }

            if (j != 0)
            {
                BlockVector neighbour2(lastPos.x,lastPos.y + j,lastPos.z + h);
                if (mapManager->checkIsSolid(neighbour2))
                    return false;
            }

            if ( (i != 0) && (j != 0))
            {
                BlockVector neighbour3(lastPos.x + i,lastPos.y + j,lastPos.z + h);
                if (mapManager->checkIsSolid(neighbour3))
                    return false;
            }
        }

        return true;
    }

    // when the pos has the same z with the the last pos
    // or if want to access the pos 1 unit higher than the last pos
    // check if there are 2 blocks in the 45 degree directions block the way
    // e.g.: the B are blocks, one cannot access C,E,F,G from L
    //    CBE
    //    BLB
    //    FBG
    if (k == 1) // if  want to access higer position
    {
        if (mapManager->checkIsSolid(lastPos.x,lastPos.y,lastPos.z + 1)) // if the block on top is solid
            return false;
    }

    if ((i != 0) && (j != 0) ) // k == 0  or k == 1
    {
        // all the blocks in the two neighbour 45 direction inside the agentHeight will block the way
        for (int h = 0; h < mapManager->getAgentHeight(); h++)
        {
            BlockVector neighbour1(lastPos.x + i,lastPos.y,lastPos.z + h + k );
            if (mapManager->checkIsSolid(neighbour1))
                return false;

            BlockVector neighbour2(lastPos.x,lastPos.y + j,lastPos.z + h + k );
            if (mapManager->checkIsSolid(neighbour2))
                return false;
        }

        return true;
    }

    return true;
}
<|endoftext|>


<commit_before>#ifndef GUARD_database_transaction_hpp
#define GUARD_database_transaction_hpp

#include "database_connection.hpp"
#include <boost/noncopyable.hpp>

namespace sqloxx
{

/**
 * Class for managing database transactions using RAII.
 * An instance of DatabaseTransaction, when created, causes
 * an SQL transaction to commenced on the DatabaseConnection with
 * which it is initialized. The SQL transaction can then
 * be finalized in one of three ways:\n
 * (a) We call the DatabaseTransaction's commit() method, causing
 * the transaction to be committed;
 * (b) We call the DatabaseTransaction's cancel() method, causing
 * the tranaction to be cancelled i.e. rolled back, or
 * (c) The DatabaseTransaction is destruced without commit() or
 * cancel() having been called - in which case the SQL transaction
 * is cancelled i.e. rolled back.
 *
 * (c) is intended as a balwark against programmer error, rather
 * than a way to avoid calling cancel() manually. See further
 * documentation of each for why.
 *
 * @todo Documentation and testing.
 */
class DatabaseTransaction:
	public boost::noncopyable
{
public:
	explicit DatabaseTransaction(DatabaseConnection& p_database_connection);
	~DatabaseTransaction();
	void commit();
	void cancel();
private:
	bool m_is_active;
	DatabaseConnection& m_database_connection;

};  // DatabaseTransaction

}  // sqloxx

#endif  // GUARD_database_transaction_hpp
<commit_msg>Corrected minor typo in comment.<commit_after>#ifndef GUARD_database_transaction_hpp
#define GUARD_database_transaction_hpp

#include "database_connection.hpp"
#include <boost/noncopyable.hpp>

namespace sqloxx
{

/**
 * Class for managing database transactions using RAII.
 * An instance of DatabaseTransaction, when created, causes
 * an SQL transaction to be commenced on the DatabaseConnection with
 * which it is initialized. The SQL transaction can then
 * be finalized in one of three ways:\n
 * (a) We call the DatabaseTransaction's commit() method, causing
 * the transaction to be committed;
 * (b) We call the DatabaseTransaction's cancel() method, causing
 * the tranaction to be cancelled i.e. rolled back, or
 * (c) The DatabaseTransaction is destruced without commit() or
 * cancel() having been called - in which case the SQL transaction
 * is cancelled i.e. rolled back.
 *
 * (c) is intended as a balwark against programmer error, rather
 * than a way to avoid calling cancel() manually. See further
 * documentation of each for why.
 *
 * @todo Documentation and testing.
 */
class DatabaseTransaction:
	public boost::noncopyable
{
public:
	explicit DatabaseTransaction(DatabaseConnection& p_database_connection);
	~DatabaseTransaction();
	void commit();
	void cancel();
private:
	bool m_is_active;
	DatabaseConnection& m_database_connection;

};  // DatabaseTransaction

}  // sqloxx

#endif  // GUARD_database_transaction_hpp
<|endoftext|>


<commit_before>/*
 * Application.cpp
 *
 *  Created on: 30 avr. 2017
 *      Author: JulienCombattelli
 */

#include "Application/Application.h"
#include "Application/Events.h"
#include <exception>
#include <initializer_list>

Application::Application() : m_is_running(true)
{
	add_event_handler<Moving_Button_Pressed>(&Application::send_direction_command, this);
	add_event_handler<Tilt_Change>(&Application::send_tilt_command, this);
	add_event_handler<Spreading_Change>(&Application::send_spreading_command, this);
}

Application::~Application()
{
	std::cout << "Closing application" << std::endl;
}

void Application::run(int period_ms)
{
	m_socket.connect("B8:27:EB:7C:3D:9D", 1);
	std::cout << "Connected on B8:27:EB:7C:3D:9D" << std::endl;

	while(m_is_running)
	{
		if(m_timer.time_elapsed_ms() > period_ms)
		{
			m_timer.restart();
			try
			{
				m_window_manager.update();
			}
			catch(std::exception& e)
			{
				std::cerr << e.what() << std::endl;
				stop();
			}
		}
	}
}

void Application::stop()
{
	m_is_running = false;
}

void Application::send_direction_command(Sender& s, const Event& e)
{
	bt::Packet packet;
	packet.append(std::vector<char>{0x01, 0x02, 0x03, 0x04});
	m_socket.send(packet);
}

void Application::send_tilt_command(Sender& s, const Event& e)
{
	bt::Packet packet;
	packet.append(std::vector<char>{0x01, 0x02, 0x03, 0x04});
	m_socket.send(packet);
}

void Application::send_spreading_command(Sender& s, const Event& e)
{
	bt::Packet packet;
	packet.append(std::vector<char>{0x01, 0x02, 0x03, 0x04});
	m_socket.send(packet);
}

<commit_msg>creat packet for bt<commit_after>/*
 * Application.cpp
 *
 *  Created on: 30 avr. 2017
 *      Author: JulienCombattelli
 */

#include "Application/Application.h"
#include "Application/Events.h"
#include <exception>
#include <initializer_list>

Application::Application() : m_is_running(true)
{
	add_event_handler<Moving_Button_Pressed>(&Application::send_direction_command, this);
	add_event_handler<Tilt_Change>(&Application::send_tilt_command, this);
	add_event_handler<Spreading_Change>(&Application::send_spreading_command, this);
}

Application::~Application()
{
	std::cout << "Closing application" << std::endl;
}

void Application::run(int period_ms)
{
	m_socket.connect("B8:27:EB:7C:3D:9D", 1);
	std::cout << "Connected on B8:27:EB:7C:3D:9D" << std::endl;

	while(m_is_running)
	{
		if(m_timer.time_elapsed_ms() > period_ms)
		{
			m_timer.restart();
			try
			{
				m_window_manager.update();
			}
			catch(std::exception& e)
			{
				std::cerr << e.what() << std::endl;
				stop();
			}
		}
	}
}

void Application::stop()
{
	m_is_running = false;
}

void Application::send_direction_command(Sender& s, const Event& e)
{
	bt::Packet packet;
	switch(((Moving_Button_Pressed)e).m_dir)
	{
	case Moving_Button_Pressed::front : packet.append(std::vector<char>{0x01, 0x01}); break;
	case Moving_Button_Pressed::back : packet.append(std::vector<char>{0x01, 0x02}); break;
	case Moving_Button_Pressed::left : packet.append(std::vector<char>{0x01, 0x03}); break;
	case Moving_Button_Pressed::right : packet.append(std::vector<char>{0x01, 0x04}); break;
	default : packet.append(std::vector<char>{0x01, 0x00}); break;
	}
	m_socket.send(packet);
}

void Application::send_tilt_command(Sender& s, const Event& e)
{
	bt::Packet packet;
	int8_t pitch = ((Tilt_Change)e).m_x;
	if(pitch > 100)
		pitch = 100;
	else if(pitch < -100)
		pitch = -100;
	int8_t roll = ((Tilt_Change)e).m_y;
	if(roll > 100)
		roll = 100;
	else if(roll < -100)
		roll = -100;
	packet.append(std::vector<char>{0x02, pitch, roll});
	m_socket.send(packet);
}

void Application::send_spreading_command(Sender& s, const Event& e)
{
	bt::Packet packet;
	uint8_t heigth = ((Spreading_Change)e).m_heigth;
	heigth = heigth*255;
	uint8_t spread = ((Spreading_Change)e).m_spread;
	spread = spread*255;
	packet.append(std::vector<char>{0x02, spread, heigth});
	m_socket.send(packet);
}

<|endoftext|>


<commit_before>#include "server.hpp"
#include "AppLogger.hpp"
#include "ServerSettings.hpp"
#include "SystemMeasurement.hpp"
#include "SimpleHttpServer.hpp"
#include "DBBackEnd.hpp"
#include "SMTPAgent.hpp"
#include <QCoreApplication>
#include <QSettings>
#include <QFileInfo>
#include <QDir>
#include <QBuffer>
#include <QDebug>
#include <algorithm>

using namespace crossOver::server;
using namespace crossOver::common;
using namespace std;

namespace
{
	/// @brief Functor to sort containers of @c ClientConfiguration elements
	///  by their @c key field.
	struct RealmLessThanOnClientConfiguration                  // clang-format off
	{
		bool operator()(const ClientConfiguration &lh, const ClientConfiguration &rh) const noexcept
		{ return lh.key < rh.key; }
	};                                                         // clang-format on

	/// @brief It generates the list of messages when a system measurement @p sm
	/// exceds the configuration @p cc.
	QStringList generateAlertMessages (const ClientConfiguration &cc,
																		 const SystemMeasurement &sm)
	{
		QStringList alertMessages;

		if (sm.cpuLoad > cc.alerts.cpuLimit)
			alertMessages
					<< QString ("CPU alert: Current load is %1 %%, threshold = %2 %%)")
								 .arg (sm.cpuLoad)
								 .arg (cc.alerts.cpuLimit);

		const double freeRamPerc = (sm.freeRam * 100.0) / sm.totalRam;
		if (freeRamPerc < cc.alerts.memoryLimit)
			alertMessages << QString ("Free memory alert: Current free memory is %1 "
																"%% (%2), threshold = %3 %%)")
													 .arg (freeRamPerc)
													 .arg (sm.freeRam)
													 .arg (cc.alerts.memoryLimit);

		if (sm.numProcs > cc.alerts.processesLimit)
			alertMessages << QString ("Number of running processes alert: Current "
																"number of running processes is %1,  threshold "
																"= %2")
													 .arg (sm.numProcs)
													 .arg (cc.alerts.processesLimit);

		return alertMessages;
	}
}

Server::Server (QObject *parent) : QObject (parent)
{

	setupDBEngine();
	setupClientsAuthAndAlarms ();
	setupTcpServer ();
}

void Server::setupDBEngine ()
{
	qDebug() << ServerLog::header() << "Initializing database engine";
	m_dbBackEnd = new DBBackEnd (this);
}

void Server::setupClientsAuthAndAlarms ()
{
	qDebug() << ServerLog::header() << "Loading clients and alarms";

	//  Load Alarms and client conf
	QFileInfo xmlCCPath (QDir (QCoreApplication::applicationDirPath ()),
											 "clientDefaultConf.xml");
	m_clientsConf = loadClientConfFromXml (xmlCCPath.absoluteFilePath ());
	sort (begin (m_clientsConf), end (m_clientsConf),
				RealmLessThanOnClientConfiguration ());

	QSettings settings;
	const int clientCachedSize = settings.value (ServerSettings::clientCacheSize(), 200).toInt ();
	m_realm2ClientIdCache.setMaxCost (clientCachedSize);

	// Settup SMTP agent
	const QString smtpServer = settings.value( ServerSettings::smtpServer(), "smtp://smtp.gmail.com:587").toString();
	const QString smtpUser = settings.value( ServerSettings::smtpUser(), "crossoveru1@gmail.com").toString();
	const QString smtpPass = settings.value( ServerSettings::smtpPassword(), "oCaQNY8vJvqAdHOi8W5n4Q").toString();

	m_SMTPAgent = new SMTPAgent ( smtpServer, this);
	m_SMTPAgent->setUser( smtpUser);
	m_SMTPAgent->setPassword( smtpPass);
}

void Server::setupTcpServer ()
{
	qDebug() << ServerLog::header() << "Opening HTTP port and authorization keys";

	m_httpServer = new SimpleHttpServer (this);
	connect (m_httpServer, &SimpleHttpServer::payLoadReady, this,
					 &Server::processStatistics);
	for (const auto &cc : m_clientsConf)
		m_httpServer->addBasicAuthentication (cc.key);
}

void Server::processStatistics (QString realm, QByteArray data)
{
	SystemMeasurement sm;

	// 1. Deserialize stats from HTTP payload
	QBuffer buffer (&data);
	buffer.open (QIODevice::ReadOnly);
	sm.deserializeFrom (&buffer);

	qDebug () << ServerLog::header() << "Cpu: " << sm.cpuLoad
						<< " Free Ram: " << sm.freeRam << " Procs: " << sm.numProcs;
	const QString email = findClientMail (realm);

	// 2. Save stats into DB.
	m_dbBackEnd->addStatsToClient (realm, email, sm);

	// 3. Check alarms and send email.
	checkAlertForClient (realm, email, sm);
}

QString Server::findClientMail (const QString &realm) const
{
	QString email;
	const ClientConfiguration ccFindKey (realm);

	const auto itrRange =
			equal_range (begin (m_clientsConf), end (m_clientsConf), ccFindKey,
									 RealmLessThanOnClientConfiguration ());
	if (itrRange.first != itrRange.second)
		email = itrRange.first->mail;

	return email;
}

void Server::checkAlertForClient (QString realm, QString findClientMail,
																	SystemMeasurement sm)
{
	const ClientConfiguration ccFindKey (realm);

	const auto itrRange =
			equal_range (begin (m_clientsConf), end (m_clientsConf), ccFindKey,
									 RealmLessThanOnClientConfiguration ());
	if (itrRange.first != itrRange.second)
	{
		const ClientConfiguration &cc = *itrRange.first;
		const QStringList alertMessages = generateAlertMessages (cc, sm);

		if (!alertMessages.empty ())
		{
			QString emailBody;
			QTextStream eb(&emailBody);

			eb << "System has found the following alarms:" << endl;
			for (const QString& alert: alertMessages)
				eb << "\t" << alert <<  endl;

			m_SMTPAgent->send( m_SMTPAgent->user(), QStringList(cc.mail), QStringLiteral("[ALARMS] CrossOver Notification Deamon"),
								emailBody);
		}
	}
}

int main (int argc, char *argv[])
{
	// Configure app.
	QCoreApplication app (argc, argv);
	QCoreApplication::setOrganizationName ("CrossOver");
	QCoreApplication::setApplicationName ("server");
	QSettings::setPath (QSettings::NativeFormat, QSettings::SystemScope,
											QCoreApplication::applicationDirPath ());

	// Settup logger
	AppLogger::initialize( QFileInfo( QDir(QCoreApplication::applicationDirPath()), "server.log"));

	// Create server instance
	Server *server = new Server (&app);
	Q_UNUSED (server);

	return app.exec ();
}
<commit_msg>Internal documentation for server class<commit_after>#include "server.hpp"
#include "AppLogger.hpp"
#include "ServerSettings.hpp"
#include "SystemMeasurement.hpp"
#include "SimpleHttpServer.hpp"
#include "DBBackEnd.hpp"
#include "SMTPAgent.hpp"
#include <QCoreApplication>
#include <QSettings>
#include <QFileInfo>
#include <QDir>
#include <QBuffer>
#include <QDebug>
#include <algorithm>

using namespace crossOver::server;
using namespace crossOver::common;
using namespace std;

namespace
{
	/// @brief Functor to sort containers of @c ClientConfiguration elements
	///  by their @c key field.
	struct RealmLessThanOnClientConfiguration                  // clang-format off
	{
		bool operator()(const ClientConfiguration &lh, const ClientConfiguration &rh) const noexcept
		{ return lh.key < rh.key; }
	};                                                         // clang-format on

	/// @brief It generates the list of messages when a system measurement @p sm
	/// exceds the configuration @p cc.
	QStringList generateAlertMessages (const ClientConfiguration &cc,
																		 const SystemMeasurement &sm)
	{
		QStringList alertMessages;

		if (sm.cpuLoad > cc.alerts.cpuLimit)
			alertMessages
					<< QString ("CPU alert: Current load is %1 %%, threshold = %2 %%)")
								 .arg (sm.cpuLoad)
								 .arg (cc.alerts.cpuLimit);

		const double freeRamPerc = (sm.freeRam * 100.0) / sm.totalRam;
		if (freeRamPerc < cc.alerts.memoryLimit)
			alertMessages << QString ("Free memory alert: Current free memory is %1 "
																"%% (%2), threshold = %3 %%)")
													 .arg (freeRamPerc)
													 .arg (sm.freeRam)
													 .arg (cc.alerts.memoryLimit);

		if (sm.numProcs > cc.alerts.processesLimit)
			alertMessages << QString ("Number of running processes alert: Current "
																"number of running processes is %1,  threshold "
																"= %2")
													 .arg (sm.numProcs)
													 .arg (cc.alerts.processesLimit);

		return alertMessages;
	}
}

Server::Server (QObject *parent) : QObject (parent)
{
	setupDBEngine();
	setupClientsAuthAndAlarms ();
	setupTcpServer ();
}

void Server::setupDBEngine ()
{
	qDebug() << ServerLog::header() << "Initializing database engine";
	m_dbBackEnd = new DBBackEnd (this);
}

void Server::setupClientsAuthAndAlarms ()
{
	qDebug() << ServerLog::header() << "Loading clients and alarms";

	//  Load Alarms and client conf
	QFileInfo xmlCCPath (QDir (QCoreApplication::applicationDirPath ()),
											 "clientDefaultConf.xml");
	m_clientsConf = loadClientConfFromXml (xmlCCPath.absoluteFilePath ());
	sort (begin (m_clientsConf), end (m_clientsConf),
				RealmLessThanOnClientConfiguration ());

	QSettings settings;
	const int clientCachedSize = settings.value (ServerSettings::clientCacheSize(), 200).toInt ();
	m_realm2ClientIdCache.setMaxCost (clientCachedSize);

	// Settup SMTP agent
	const QString smtpServer = settings.value( ServerSettings::smtpServer(), "smtp://smtp.gmail.com:587").toString();
	const QString smtpUser = settings.value( ServerSettings::smtpUser(), "crossoveru1@gmail.com").toString();
	const QString smtpPass = settings.value( ServerSettings::smtpPassword(), "oCaQNY8vJvqAdHOi8W5n4Q").toString();

	m_SMTPAgent = new SMTPAgent ( smtpServer, this);
	m_SMTPAgent->setUser( smtpUser);
	m_SMTPAgent->setPassword( smtpPass);
}

void Server::setupTcpServer ()
{
	qDebug() << ServerLog::header() << "Opening HTTP port and authorization keys";

	m_httpServer = new SimpleHttpServer (this);
	connect (m_httpServer, &SimpleHttpServer::payLoadReady, this,
					 &Server::processStatistics);
	for (const auto &cc : m_clientsConf)
		m_httpServer->addBasicAuthentication (cc.key);
}

void Server::processStatistics (QString realm, QByteArray data)
{
	SystemMeasurement sm;

	// 1. Deserialize stats from HTTP payload
	QBuffer buffer (&data);
	buffer.open (QIODevice::ReadOnly);
	sm.deserializeFrom (&buffer);

	qDebug () << ServerLog::header() << "Cpu: " << sm.cpuLoad
						<< " Free Ram: " << sm.freeRam << " Procs: " << sm.numProcs;
	const QString email = findClientMail (realm);

	// 2. Save stats into DB.
	m_dbBackEnd->addStatsToClient (realm, email, sm);

	// 3. Check alarms and send email.
	checkAlertForClient (realm, email, sm);
}

QString Server::findClientMail (const QString &realm) const
{
	QString email;
	const ClientConfiguration ccFindKey (realm);

	const auto itrRange =
			equal_range (begin (m_clientsConf), end (m_clientsConf), ccFindKey,
									 RealmLessThanOnClientConfiguration ());
	if (itrRange.first != itrRange.second)
		email = itrRange.first->mail;

	return email;
}

void Server::checkAlertForClient (QString realm, QString findClientMail,
																	SystemMeasurement sm)
{
	const ClientConfiguration ccFindKey (realm);

	const auto itrRange =
			equal_range (begin (m_clientsConf), end (m_clientsConf), ccFindKey,
									 RealmLessThanOnClientConfiguration ());
	if (itrRange.first != itrRange.second)
	{
		const ClientConfiguration &cc = *itrRange.first;
		const QStringList alertMessages = generateAlertMessages (cc, sm);

		if (!alertMessages.empty ())
		{
			QString emailBody;
			QTextStream eb(&emailBody);

			eb << "System has found the following alarms:" << endl;
			for (const QString& alert: alertMessages)
				eb << "\t" << alert <<  endl;

			m_SMTPAgent->send( m_SMTPAgent->user(), QStringList(cc.mail), QStringLiteral("[ALARMS] CrossOver Notification Deamon"),
								emailBody);
		}
	}
}

int main (int argc, char *argv[])
{
	// Configure app.
	QCoreApplication app (argc, argv);
	QCoreApplication::setOrganizationName ("CrossOver");
	QCoreApplication::setApplicationName ("server");
	QSettings::setPath (QSettings::NativeFormat, QSettings::SystemScope,
											QCoreApplication::applicationDirPath ());

	// Settup logger
	AppLogger::initialize( QFileInfo( QDir(QCoreApplication::applicationDirPath()), "server.log"));

	// Create server instance
	Server *server = new Server (&app);
	Q_UNUSED (server);

	return app.exec ();
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include "RegViewVU.h"
#include "../PS2VM.h"

CRegViewVU::CRegViewVU(HWND hParent, const RECT& rect, CVirtualMachine& virtualMachine, CMIPS* pCtx)
: CRegViewPage(hParent, rect)
, m_pCtx(pCtx)
{
	virtualMachine.OnMachineStateChange.connect(boost::bind(&CRegViewVU::Update, this));
	virtualMachine.OnRunningStateChange.connect(boost::bind(&CRegViewVU::Update, this));

	Update();
}

CRegViewVU::~CRegViewVU()
{

}

void CRegViewVU::Update()
{
	SetDisplayText(GetDisplayText().c_str());
	CRegViewPage::Update();
}

std::string CRegViewVU::GetDisplayText()
{
	char sLine[256];
	std::string result;

	result += "              x               y       \r\n";
	result += "              z               w       \r\n";

	MIPSSTATE* pState = &m_pCtx->m_State;

	for(unsigned int i = 0; i < 32; i++)
	{
		char sReg1[32];

		if(i < 10)
		{
			sprintf(sReg1, "VF%i  ", i);
		}
		else
		{
			sprintf(sReg1, "VF%i ", i);
		}

		sprintf(sLine, "%s: %+.7e %+.7e\r\n       %+.7e %+.7e\r\n", sReg1, \
			*(float*)&pState->nCOP2[i].nV0, \
			*(float*)&pState->nCOP2[i].nV1, \
			*(float*)&pState->nCOP2[i].nV2, \
			*(float*)&pState->nCOP2[i].nV3);

		result += sLine;
	}

	sprintf(sLine, "ACC  : %+.7e %+.7e\r\n       %+.7e %+.7e\r\n", \
		*(float*)&pState->nCOP2A.nV0, \
		*(float*)&pState->nCOP2A.nV1, \
		*(float*)&pState->nCOP2A.nV2, \
		*(float*)&pState->nCOP2A.nV3);

	result += sLine;

	sprintf(sLine, "Q    : %+.7e\r\n", *(float*)&pState->nCOP2Q);
	result += sLine;

	sprintf(sLine, "I    : %+.7e\r\n", *(float*)&pState->nCOP2I);
	result += sLine;

	sprintf(sLine, "P    : %+.7e\r\n", *(float*)&pState->nCOP2P);
	result += sLine;

	sprintf(sLine, "R    : %+.7e (0x%0.8X)\r\n", *(float*)&pState->nCOP2R, pState->nCOP2R);
	result += sLine;

	sprintf(sLine, "MACF : 0x%0.4X\r\n", pState->nCOP2MF);
	result += sLine;

	sprintf(sLine, "CLIP : 0x%0.6X\r\n", pState->nCOP2CF);
	result += sLine;

	sprintf(sLine, "PIPEQ: 0x%0.4X - %+.7e\r\n", pState->pipeQ.counter, *(float*)&pState->pipeQ.heldValue);
	result += sLine;

	unsigned int currentPipeMacCounter = pState->pipeMac.index - 1;

	uint32 macFlagPipeValues[MACFLAG_PIPELINE_SLOTS];
	uint32 macFlagPipeTimes[MACFLAG_PIPELINE_SLOTS];
	for(unsigned int i = 0; i < MACFLAG_PIPELINE_SLOTS; i++)
	{
		unsigned int currIndex = (currentPipeMacCounter - i) & (MACFLAG_PIPELINE_SLOTS - 1);
		macFlagPipeValues[i] = pState->pipeMac.values[currIndex];
		macFlagPipeTimes[i] = pState->pipeMac.pipeTimes[currIndex];
	}

	sprintf(sLine, "PIPEM: 0x%0.4X:0x%0.4X, 0x%0.4X:0x%0.4X\r\n",
		macFlagPipeTimes[0], macFlagPipeValues[0],
		macFlagPipeTimes[1], macFlagPipeValues[1]);
	result += sLine;

	sprintf(sLine, "       0x%0.4X:0x%0.4X, 0x%0.4X:0x%0.4X\r\n",
		macFlagPipeTimes[2], macFlagPipeValues[2],
		macFlagPipeTimes[3], macFlagPipeValues[3]);
	result += sLine;

	for(unsigned int i = 0; i < 16; i += 2)
	{
		char sReg1[32];
		char sReg2[32];

		if(i < 10)
		{
			sprintf(sReg1, "VI%i  ", i);
			sprintf(sReg2, "VI%i  ", i + 1);
		}
		else
		{
			sprintf(sReg1, "VI%i ", i);
			sprintf(sReg2, "VI%i ", i + 1);
		}

		sprintf(sLine, "%s: 0x%0.4X    %s: 0x%0.4X\r\n", sReg1, pState->nCOP2VI[i] & 0xFFFF, sReg2, pState->nCOP2VI[i + 1] & 0xFFFF);
		result += sLine;
	}

	return result;
}
<commit_msg>Display VU pipe time in regview.<commit_after>#include <stdio.h>
#include "RegViewVU.h"
#include "../PS2VM.h"

CRegViewVU::CRegViewVU(HWND hParent, const RECT& rect, CVirtualMachine& virtualMachine, CMIPS* pCtx)
: CRegViewPage(hParent, rect)
, m_pCtx(pCtx)
{
	virtualMachine.OnMachineStateChange.connect(boost::bind(&CRegViewVU::Update, this));
	virtualMachine.OnRunningStateChange.connect(boost::bind(&CRegViewVU::Update, this));

	Update();
}

CRegViewVU::~CRegViewVU()
{

}

void CRegViewVU::Update()
{
	SetDisplayText(GetDisplayText().c_str());
	CRegViewPage::Update();
}

std::string CRegViewVU::GetDisplayText()
{
	char sLine[256];
	std::string result;

	result += "              x               y       \r\n";
	result += "              z               w       \r\n";

	MIPSSTATE* pState = &m_pCtx->m_State;

	for(unsigned int i = 0; i < 32; i++)
	{
		char sReg1[32];

		if(i < 10)
		{
			sprintf(sReg1, "VF%i  ", i);
		}
		else
		{
			sprintf(sReg1, "VF%i ", i);
		}

		sprintf(sLine, "%s: %+.7e %+.7e\r\n       %+.7e %+.7e\r\n", sReg1, \
			*(float*)&pState->nCOP2[i].nV0, \
			*(float*)&pState->nCOP2[i].nV1, \
			*(float*)&pState->nCOP2[i].nV2, \
			*(float*)&pState->nCOP2[i].nV3);

		result += sLine;
	}

	sprintf(sLine, "ACC  : %+.7e %+.7e\r\n       %+.7e %+.7e\r\n", \
		*(float*)&pState->nCOP2A.nV0, \
		*(float*)&pState->nCOP2A.nV1, \
		*(float*)&pState->nCOP2A.nV2, \
		*(float*)&pState->nCOP2A.nV3);

	result += sLine;

	sprintf(sLine, "Q    : %+.7e\r\n", *(float*)&pState->nCOP2Q);
	result += sLine;

	sprintf(sLine, "I    : %+.7e\r\n", *(float*)&pState->nCOP2I);
	result += sLine;

	sprintf(sLine, "P    : %+.7e\r\n", *(float*)&pState->nCOP2P);
	result += sLine;

	sprintf(sLine, "R    : %+.7e (0x%0.8X)\r\n", *(float*)&pState->nCOP2R, pState->nCOP2R);
	result += sLine;

	sprintf(sLine, "MACF : 0x%0.4X\r\n", pState->nCOP2MF);
	result += sLine;

	sprintf(sLine, "CLIP : 0x%0.6X\r\n", pState->nCOP2CF);
	result += sLine;

	sprintf(sLine, "PIPE : 0x%0.4X\r\n", pState->pipeTime);
	result += sLine;

	sprintf(sLine, "PIPEQ: 0x%0.4X - %+.7e\r\n", pState->pipeQ.counter, *(float*)&pState->pipeQ.heldValue);
	result += sLine;

	unsigned int currentPipeMacCounter = pState->pipeMac.index - 1;

	uint32 macFlagPipeValues[MACFLAG_PIPELINE_SLOTS];
	uint32 macFlagPipeTimes[MACFLAG_PIPELINE_SLOTS];
	for(unsigned int i = 0; i < MACFLAG_PIPELINE_SLOTS; i++)
	{
		unsigned int currIndex = (currentPipeMacCounter - i) & (MACFLAG_PIPELINE_SLOTS - 1);
		macFlagPipeValues[i] = pState->pipeMac.values[currIndex];
		macFlagPipeTimes[i] = pState->pipeMac.pipeTimes[currIndex];
	}

	sprintf(sLine, "PIPEM: 0x%0.4X:0x%0.4X, 0x%0.4X:0x%0.4X\r\n",
		macFlagPipeTimes[0], macFlagPipeValues[0],
		macFlagPipeTimes[1], macFlagPipeValues[1]);
	result += sLine;

	sprintf(sLine, "       0x%0.4X:0x%0.4X, 0x%0.4X:0x%0.4X\r\n",
		macFlagPipeTimes[2], macFlagPipeValues[2],
		macFlagPipeTimes[3], macFlagPipeValues[3]);
	result += sLine;

	for(unsigned int i = 0; i < 16; i += 2)
	{
		char sReg1[32];
		char sReg2[32];

		if(i < 10)
		{
			sprintf(sReg1, "VI%i  ", i);
			sprintf(sReg2, "VI%i  ", i + 1);
		}
		else
		{
			sprintf(sReg1, "VI%i ", i);
			sprintf(sReg2, "VI%i ", i + 1);
		}

		sprintf(sLine, "%s: 0x%0.4X    %s: 0x%0.4X\r\n", sReg1, pState->nCOP2VI[i] & 0xFFFF, sReg2, pState->nCOP2VI[i + 1] & 0xFFFF);
		result += sLine;
	}

	return result;
}
<|endoftext|>


<commit_before>#pragma once
#include <vector>
#include <But/Format/detail/ParsedFormat.hpp>
#include <But/Format/detail/common.hpp>
#include <But/Mpl/parse.hpp>

namespace But
{
namespace Format
{
namespace detail
{

inline constexpr auto skipUntilEndOfComment(char const* fmt)
{
  while( not isEos(*fmt) && *fmt!='}' )
    ++fmt;
  return throwOnInvalidSyntax( *fmt!='}', "variable does not end with closing brace", fmt );
}

inline constexpr auto parseBraceVariable(Segment& st, char const* fmt)
{
  st.type_ = Segment::Type::Value;
  st.end_ = fmt;
  while( isDigit(*st.end_) )
    ++st.end_;
  const auto numberEnd = st.end_;
  if( *st.end_ == '#' )
    st.end_ = skipUntilEndOfComment(st.end_);
  throwOnInvalidSyntax( *st.end_!='}', "variable does not end with closing brace", st.end_ );
  ++st.end_;
  const auto beginOffset = 2;
  st.referencedArgument_ = Mpl::parseUnsigned<unsigned>(st.begin_ + beginOffset, numberEnd);
  return st.end_;
}

inline constexpr auto parseBrace(Segment& st, char const* fmt)
{
  throwOnInvalidSyntax( isEos(*fmt), "brace variable declaration is not complete", fmt );
  if( *fmt == 'V' )
    ++fmt;
  if( isDigit(*fmt) )
    return parseBraceVariable(st, fmt+1);
  return throwOnInvalidSyntax(true, "invalid brace variable init sequence", fmt);
}

inline constexpr auto parseSimpleVariable(Segment& st, char const* fmt)
{
  throwOnInvalidSyntax( not isDigit(*fmt), "simple variable declaration is not followed by a number", fmt );
  st.type_ = Segment::Type::Value;
  st.end_  = fmt+1;
  while( isDigit(*st.end_) )
    ++st.end_;
  throwOnInvalidSyntax( not isEos(*st.end_) && not isSpace(*st.end_), "variable does not end with end of data or space", st.end_ );
  st.referencedArgument_ = Mpl::parseUnsigned<unsigned>(st.begin_+1, st.end_);
  return st.end_;
}

inline constexpr auto parseStringVariable(Segment& st, char const* fmt)
{
  st.type_ = Segment::Type::String;
  st.end_ = fmt;
  return fmt+1;
}

inline constexpr auto parseVariable(Segment& st, char const* fmt)
{
  st.begin_ = fmt;
  ++fmt;
  throwOnInvalidSyntax( isEos(*fmt), "end of data while declaring a variable", fmt );
  if( isVariableBegin(*fmt) )   // "$$" case
    return parseStringVariable(st, fmt);
  if( *fmt=='{' )
    return parseBrace(st, fmt+1);
  return parseSimpleVariable(st, fmt);
}

inline constexpr auto parseString(Segment& st, char const* fmt)
{
  st.type_ = Segment::Type::String;
  st.begin_ = fmt;
  st.end_  = fmt;
  while( not isEos(*st.end_) && not isVariableBegin(*st.end_) )
    ++st.end_;
  return st.end_;
}

template<typename Pf>
constexpr auto parse(Pf&& pf, char const* fmt)
{
  while( not isEos(*fmt) )
  {
    throwOnInvalidSyntax( pf.segments_.max_size() == pf.segments_.size(), "format too long for a declared states count - expected end", fmt );
    Segment st;
    if( isVariableBegin(*fmt) )
      fmt = parseVariable(st, fmt);
    else
      fmt = parseString(st, fmt);

    pf.segments_.push_back( std::move(st) );
  }
  return std::move(pf);
}

template<size_t N>
constexpr auto parseCt(char const* fmt) { return parse( ParsedFormatCt<N>{}, fmt ); }

inline auto parseRt(char const* fmt) { return parse( ParsedFormatRt{}, fmt ); }
inline auto parseRt(std::string const& fmt) { return parseRt( fmt.c_str() ); }

}
}
}
<commit_msg>std::move -> std::forward as it should be<commit_after>#pragma once
#include <vector>
#include <But/Format/detail/ParsedFormat.hpp>
#include <But/Format/detail/common.hpp>
#include <But/Mpl/parse.hpp>

namespace But
{
namespace Format
{
namespace detail
{

inline constexpr auto skipUntilEndOfComment(char const* fmt)
{
  while( not isEos(*fmt) && *fmt!='}' )
    ++fmt;
  return throwOnInvalidSyntax( *fmt!='}', "variable does not end with closing brace", fmt );
}

inline constexpr auto parseBraceVariable(Segment& st, char const* fmt)
{
  st.type_ = Segment::Type::Value;
  st.end_ = fmt;
  while( isDigit(*st.end_) )
    ++st.end_;
  const auto numberEnd = st.end_;
  if( *st.end_ == '#' )
    st.end_ = skipUntilEndOfComment(st.end_);
  throwOnInvalidSyntax( *st.end_!='}', "variable does not end with closing brace", st.end_ );
  ++st.end_;
  const auto beginOffset = 2;
  st.referencedArgument_ = Mpl::parseUnsigned<unsigned>(st.begin_ + beginOffset, numberEnd);
  return st.end_;
}

inline constexpr auto parseBrace(Segment& st, char const* fmt)
{
  throwOnInvalidSyntax( isEos(*fmt), "brace variable declaration is not complete", fmt );
  if( *fmt == 'V' )
    ++fmt;
  if( isDigit(*fmt) )
    return parseBraceVariable(st, fmt+1);
  return throwOnInvalidSyntax(true, "invalid brace variable init sequence", fmt);
}

inline constexpr auto parseSimpleVariable(Segment& st, char const* fmt)
{
  throwOnInvalidSyntax( not isDigit(*fmt), "simple variable declaration is not followed by a number", fmt );
  st.type_ = Segment::Type::Value;
  st.end_  = fmt+1;
  while( isDigit(*st.end_) )
    ++st.end_;
  throwOnInvalidSyntax( not isEos(*st.end_) && not isSpace(*st.end_), "variable does not end with end of data or space", st.end_ );
  st.referencedArgument_ = Mpl::parseUnsigned<unsigned>(st.begin_+1, st.end_);
  return st.end_;
}

inline constexpr auto parseStringVariable(Segment& st, char const* fmt)
{
  st.type_ = Segment::Type::String;
  st.end_ = fmt;
  return fmt+1;
}

inline constexpr auto parseVariable(Segment& st, char const* fmt)
{
  st.begin_ = fmt;
  ++fmt;
  throwOnInvalidSyntax( isEos(*fmt), "end of data while declaring a variable", fmt );
  if( isVariableBegin(*fmt) )   // "$$" case
    return parseStringVariable(st, fmt);
  if( *fmt=='{' )
    return parseBrace(st, fmt+1);
  return parseSimpleVariable(st, fmt);
}

inline constexpr auto parseString(Segment& st, char const* fmt)
{
  st.type_ = Segment::Type::String;
  st.begin_ = fmt;
  st.end_  = fmt;
  while( not isEos(*st.end_) && not isVariableBegin(*st.end_) )
    ++st.end_;
  return st.end_;
}

template<typename Pf>
constexpr auto parse(Pf&& pf, char const* fmt)
{
  while( not isEos(*fmt) )
  {
    throwOnInvalidSyntax( pf.segments_.max_size() == pf.segments_.size(), "format too long for a declared states count - expected end", fmt );
    Segment st;
    if( isVariableBegin(*fmt) )
      fmt = parseVariable(st, fmt);
    else
      fmt = parseString(st, fmt);

    pf.segments_.push_back( std::move(st) );
  }
  return std::forward<Pf>(pf);
}

template<size_t N>
constexpr auto parseCt(char const* fmt) { return parse( ParsedFormatCt<N>{}, fmt ); }

inline auto parseRt(char const* fmt) { return parse( ParsedFormatRt{}, fmt ); }
inline auto parseRt(std::string const& fmt) { return parseRt( fmt.c_str() ); }

}
}
}
<|endoftext|>


<commit_before>
/**
 * @file ComputeMelbourneWubbena.hpp
 * This class eases computing Melbourne-Wubbena combination for GNSS data structures.
 */

#ifndef Compute_MELBOURNEWUBBENA_GPSTK
#define Compute_MELBOURNEWUBBENA_GPSTK

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Dagoberto Salazar - gAGE ( http://www.gage.es ). 2007
//
//============================================================================

#include "ComputeCombination.hpp"

namespace gpstk
{

    /** @addtogroup DataStructures */
    //@{

    /** This class eases computing Melbourne-Wubbena combination for GNSS data structures.
     * This class is meant to be used with the GNSS data structures objects
     * found in "DataStructures" class.
     *
     * A typical way to use this class follows:
     *
     * @code
     *   RinexObsStream rin("ebre0300.02o");
     *
     *   gnssRinex gRin;
     *   ComputeMelbourne-Wubbena getMW;
     *
     *   while(rin >> gRin) {
     *      gRin >> getMW;
     *   }
     * @endcode
     *
     * The "ComputeMelbourne-Wubbena" object will visit every satellite in the
     * GNSS data structure that is "gRin" and will try to compute its
     * Melbourne-Wubbena combination.
     *
     * When used with the ">>" operator, this class returns the same incoming
     * data structure with the Melbourne-Wubbena combinations inserted along their
     * corresponding satellites. Be warned that if a given satellite does not
     * have the observations required, it will be summarily deleted from the data
     * structure.
     *
     * Sometimes, the Rinex observations file does not have P1, but provides C1
     * instead. In such cases, you must use the useC1() method.
     *
     */
    class ComputeMelbourneWubbena : public ComputeCombination
    {
    public:

        /// Default constructor
        ComputeMelbourneWubbena() : type3(TypeID::L1), type4(TypeID::L2), DEN1(L1_FREQ + L2_FREQ), DEN2(L1_FREQ - L2_FREQ)
        {
            type1 = TypeID::P1;
            type2 = TypeID::P2;
            resultType = TypeID::MWubbena;
        };

        /** Returns a satTypeValueMap object, adding the new data generated when calling this object.
         *
         * @param gData     Data object holding the data.
         */
        virtual satTypeValueMap& Combine(satTypeValueMap& gData)
        {
            double value1(0.0);
            double value2(0.0);
            double value3(0.0);
            double value4(0.0);

            SatIDSet satRejectedSet;

            // Loop through all the satellites
            satTypeValueMap::iterator it;
            for (it = gData.begin(); it != gData.end(); ++it)
            {
                try
                {
                    // Try to extract the values
                    value1 = (*it).second(type1);
                    value2 = (*it).second(type2);
                    value3 = (*it).second(type3);
                    value4 = (*it).second(type4);
                }
                catch(...)
                {
                    // If some value is missing, then schedule this satellite for removal
                    satRejectedSet.insert( (*it).first );
                    continue;
                }
                // If everything is OK, then get the new value inside the structure
                (*it).second[resultType] = getCombination(value1, value2, value3, value4);
            }
            // Remove satellites with missing data
            gData.removeSatID(satRejectedSet);

            return gData;
        };

        /// Some Rinex data files provide C1 instead of P1. Use this method in those cases.
        void useC1() { type1 = TypeID::C1; };

        /// Destructor
        virtual ~ComputeMelbourneWubbena() {};

    protected:
        /// Compute the combination of observables.
        virtual double getCombination(const double& p1, const double& p2, const double& l1, const double& l2)
        {
            return ( ( L1_FREQ*l1 - L2_FREQ*l2 ) / ( DEN2 ) - ( L1_FREQ*p1 + L2_FREQ*p2 ) / ( DEN1 ) );
        };

        /// Dummy function.
        virtual double getCombination(const double& obs1, const double& obs2) { return 0.0; };

    private:

        /// Type of observation to be combined. Nro 3.
        TypeID type3;

        /// Type of observation to be combined. Nro 4.
        TypeID type4;

        const double DEN1;      // DEN1 = L1_FREQ + L2_FREQ
        const double DEN2;      // DEN2 = L1_FREQ - L2_FREQ

   }; // end class ComputeMelbourneWubbena

   //@}

}

#endif
<commit_msg>Very minor change in documentation.<commit_after>
/**
 * @file ComputeMelbourneWubbena.hpp
 * This class eases computing Melbourne-Wubbena combination for GNSS data structures.
 */

#ifndef Compute_MELBOURNEWUBBENA_GPSTK
#define Compute_MELBOURNEWUBBENA_GPSTK

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Dagoberto Salazar - gAGE ( http://www.gage.es ). 2007
//
//============================================================================

#include "ComputeCombination.hpp"

namespace gpstk
{

    /** @addtogroup DataStructures */
    //@{

    /** This class eases computing Melbourne-Wubbena combination for GNSS data structures.
     * This class is meant to be used with the GNSS data structures objects
     * found in "DataStructures" class.
     *
     * A typical way to use this class follows:
     *
     * @code
     *   RinexObsStream rin("ebre0300.02o");
     *
     *   gnssRinex gRin;
     *   ComputeMelbourneWubbena getMW;
     *
     *   while(rin >> gRin) {
     *      gRin >> getMW;
     *   }
     * @endcode
     *
     * The "ComputeMelbourne-Wubbena" object will visit every satellite in the
     * GNSS data structure that is "gRin" and will try to compute its
     * Melbourne-Wubbena combination.
     *
     * When used with the ">>" operator, this class returns the same incoming
     * data structure with the Melbourne-Wubbena combinations inserted along their
     * corresponding satellites. Be warned that if a given satellite does not
     * have the observations required, it will be summarily deleted from the data
     * structure.
     *
     * Sometimes, the Rinex observations file does not have P1, but provides C1
     * instead. In such cases, you must use the useC1() method.
     *
     */
    class ComputeMelbourneWubbena : public ComputeCombination
    {
    public:

        /// Default constructor
        ComputeMelbourneWubbena() : type3(TypeID::L1), type4(TypeID::L2), DEN1(L1_FREQ + L2_FREQ), DEN2(L1_FREQ - L2_FREQ)
        {
            type1 = TypeID::P1;
            type2 = TypeID::P2;
            resultType = TypeID::MWubbena;
        };

        /** Returns a satTypeValueMap object, adding the new data generated when calling this object.
         *
         * @param gData     Data object holding the data.
         */
        virtual satTypeValueMap& Combine(satTypeValueMap& gData)
        {
            double value1(0.0);
            double value2(0.0);
            double value3(0.0);
            double value4(0.0);

            SatIDSet satRejectedSet;

            // Loop through all the satellites
            satTypeValueMap::iterator it;
            for (it = gData.begin(); it != gData.end(); ++it)
            {
                try
                {
                    // Try to extract the values
                    value1 = (*it).second(type1);
                    value2 = (*it).second(type2);
                    value3 = (*it).second(type3);
                    value4 = (*it).second(type4);
                }
                catch(...)
                {
                    // If some value is missing, then schedule this satellite for removal
                    satRejectedSet.insert( (*it).first );
                    continue;
                }
                // If everything is OK, then get the new value inside the structure
                (*it).second[resultType] = getCombination(value1, value2, value3, value4);
            }
            // Remove satellites with missing data
            gData.removeSatID(satRejectedSet);

            return gData;
        };

        /// Some Rinex data files provide C1 instead of P1. Use this method in those cases.
        void useC1() { type1 = TypeID::C1; };

        /// Destructor
        virtual ~ComputeMelbourneWubbena() {};

    protected:
        /// Compute the combination of observables.
        virtual double getCombination(const double& p1, const double& p2, const double& l1, const double& l2)
        {
            return ( ( L1_FREQ*l1 - L2_FREQ*l2 ) / ( DEN2 ) - ( L1_FREQ*p1 + L2_FREQ*p2 ) / ( DEN1 ) );
        };

        /// Dummy function.
        virtual double getCombination(const double& obs1, const double& obs2) { return 0.0; };

    private:

        /// Type of observation to be combined. Nro 3.
        TypeID type3;

        /// Type of observation to be combined. Nro 4.
        TypeID type4;

        const double DEN1;      // DEN1 = L1_FREQ + L2_FREQ
        const double DEN2;      // DEN2 = L1_FREQ - L2_FREQ

   }; // end class ComputeMelbourneWubbena

   //@}

}

#endif
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "BitFunnel/Index/IFactSet.h"  // For FactHandle.
#include "BitFunnel/Index/ITermTable.h"
#include "BitFunnel/Index/PackedRowIdSequence.h"
#include "BitFunnel/Index/RowId.h"
#include "BitFunnel/Index/RowIdSequence.h"
#include "BitFunnel/Term.h"
#include "LoggerInterfaces/Logging.h"

namespace BitFunnel
{
    //*************************************************************************
    //
    // RowIdSequence
    //
    //*************************************************************************
    // TODO: should GetRawHash be GetClassifiedHash or GetGeneralHash?
    RowIdSequence::RowIdSequence(Term const & term, ITermTable const & termTable)
      : m_hash(term.GetRawHash()),
        m_termTable(termTable)
    {
        // TODO: Get rid of out parameter for m_termKind. Consider returning an std::pair.
        // TODO: See if there is any way this can run in the initializer so that members
        // can be const.
        // TODO: Eliminate Shard and Tier from RowId.
        const PackedRowIdSequence packed(termTable.GetRows(term));
        Initialize(packed);
    }

    //// TODO: Implement this constructor.
    RowIdSequence::RowIdSequence(FactHandle fact, ITermTable const & termTable)
    : m_hash(0),
      m_termTable(termTable)
    {
       throw fact;
      // // TODO: Figure out how to eliminate StreamId::Metaword for facts.
      // // Do we just create c_MetaWordStreamId? Can user's use this StreamId?
      // const Term term(static_cast<Term::Hash>(fact),
      //                 StreamId::MetaWord,
      //                 static_cast<Term::IdfX10>(0));

      // const PackedTermInfo info = termTable.GetTermInfo(term, m_termKind);
      // Initialize(info);
    }

    RowIdSequence::const_iterator RowIdSequence::begin() const
    {
        return const_iterator(*this, 0ull);
    }

    RowIdSequence::const_iterator RowIdSequence::end() const
    {
        return const_iterator(*this, m_rowIdCount);
    }

    RowId RowIdSequence::GetRow(size_t row) const
    {
        if (row >= m_rowIdCount)
        {
            RecoverableError error("RowIdSequence::GetRow(): row out of range.");
            throw error;
        }

        if (m_type == PackedRowIdSequence::Type::Explicit)
        {
            return m_termTable.GetRowIdExplicit(m_rowIdStart + row);
        }
        else if(m_type == PackedRowIdSequence::Type::Adhoc)
        {
            // TODO: can hash variant be created here in order to eliminate
            // third argument.
            return m_termTable.GetRowIdAdhoc(m_hash,
                                             m_rowIdStart + row,
                                             row);
        }
        else
        {
            return m_termTable.GetRowIdFact(m_rowIdStart + row);
        }

        // No special clause for ITermTable::Disposed as they return an empty
        // PackedTermInfo which does not support enumeration.
    }

    void RowIdSequence::Initialize(PackedRowIdSequence const & packed)
    {
        m_rowIdStart = packed.GetStart();
        m_rowIdCount = packed.GetEnd() - packed.GetStart();
        m_type = packed.GetType();
    }
}
<commit_msg>Add hack for build failure on Windows.<commit_after>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "BitFunnel/Index/IFactSet.h"  // For FactHandle.
#include "BitFunnel/Index/ITermTable.h"
#include "BitFunnel/Index/PackedRowIdSequence.h"
#include "BitFunnel/Index/RowId.h"
#include "BitFunnel/Index/RowIdSequence.h"
#include "BitFunnel/Term.h"
#include "LoggerInterfaces/Logging.h"

namespace BitFunnel
{
    //*************************************************************************
    //
    // RowIdSequence
    //
    //*************************************************************************
    // TODO: should GetRawHash be GetClassifiedHash or GetGeneralHash?
    RowIdSequence::RowIdSequence(Term const & term, ITermTable const & termTable)
      : m_hash(term.GetRawHash()),
        m_termTable(termTable)
    {
        // TODO: Get rid of out parameter for m_termKind. Consider returning an std::pair.
        // TODO: See if there is any way this can run in the initializer so that members
        // can be const.
        // TODO: Eliminate Shard and Tier from RowId.
        const PackedRowIdSequence packed(termTable.GetRows(term));
        Initialize(packed);
    }

    //// TODO: Implement this constructor.
    RowIdSequence::RowIdSequence(FactHandle fact, ITermTable const & termTable)
    : m_hash(0),
      m_termTable(termTable)
    {
        // We're throwing because this isn't implemented yet.  This if is
        // because, on some configurations of VC++, throwing causes the build to
        // error out. For reasons we don't understand, this doesn't happen in
        // AppVeyor CI.
        if (fact != 17u)
        {
            throw fact;
        }
      // // TODO: Figure out how to eliminate StreamId::Metaword for facts.
      // // Do we just create c_MetaWordStreamId? Can user's use this StreamId?
      // const Term term(static_cast<Term::Hash>(fact),
      //                 StreamId::MetaWord,
      //                 static_cast<Term::IdfX10>(0));

      // const PackedTermInfo info = termTable.GetTermInfo(term, m_termKind);
      // Initialize(info);
    }

    RowIdSequence::const_iterator RowIdSequence::begin() const
    {
        return const_iterator(*this, 0ull);
    }

    RowIdSequence::const_iterator RowIdSequence::end() const
    {
        return const_iterator(*this, m_rowIdCount);
    }

    RowId RowIdSequence::GetRow(size_t row) const
    {
        if (row >= m_rowIdCount)
        {
            RecoverableError error("RowIdSequence::GetRow(): row out of range.");
            throw error;
        }

        if (m_type == PackedRowIdSequence::Type::Explicit)
        {
            return m_termTable.GetRowIdExplicit(m_rowIdStart + row);
        }
        else if(m_type == PackedRowIdSequence::Type::Adhoc)
        {
            // TODO: can hash variant be created here in order to eliminate
            // third argument.
            return m_termTable.GetRowIdAdhoc(m_hash,
                                             m_rowIdStart + row,
                                             row);
        }
        else
        {
            return m_termTable.GetRowIdFact(m_rowIdStart + row);
        }

        // No special clause for ITermTable::Disposed as they return an empty
        // PackedTermInfo which does not support enumeration.
    }

    void RowIdSequence::Initialize(PackedRowIdSequence const & packed)
    {
        m_rowIdStart = packed.GetStart();
        m_rowIdCount = packed.GetEnd() - packed.GetStart();
        m_type = packed.GetType();
    }
}
<|endoftext|>


<commit_before>#include "KEngine/Core/Entity.hpp"
#include "KEngine/Interfaces/IEntityComponent.hpp"
#include "KEngine/Log/Log.hpp"

#include <cassert>

namespace ke
{
    Entity::Entity(const ke::EntityId p_ID)
        : m_EntityID(p_ID)
    {}

    Entity::Entity(ke::Entity && p_rrEntity)
        : m_Components(std::move(p_rrEntity.m_Components))
        , m_ComponentSPMap(std::move(p_rrEntity.m_ComponentSPMap))
        , m_EntityID(std::move(p_rrEntity.getId()))
    {}

    Entity & Entity::operator=(ke::Entity && p_rrEntity)
    {
        m_Components = std::move(p_rrEntity.m_Components);
        m_ComponentSPMap = std::move(p_rrEntity.m_ComponentSPMap);
        m_EntityID = p_rrEntity.getId();
        return *this;
    }

    Entity::~Entity(void)
    {
        assert(this->m_ComponentSPMap.empty()); // component must be empty (all circular references removed).
    }

    void Entity::addComponent(ke::EntityComponentSptr p_spEntityComponent)
    {
        assert(p_spEntityComponent != nullptr); // should not be null.
        const auto result = m_ComponentSPMap.insert(std::make_pair(p_spEntityComponent->getType(), p_spEntityComponent));
        assert(result.second); // fails if insertion failed.
        if (!result.second)
        {
            ke::Log::instance()->error("Attempted to add entity component of duplicate type: {0:#x}", p_spEntityComponent->getType());
            return;
        }
        m_Components.push_back(p_spEntityComponent);
    }

    bool Entity::initialise(void)
    {
        bool result = true;
        for (auto & it : m_ComponentSPMap)
            if (!it.second->isInitialised())
            {
                if (it.second->initialise())
                {
                    it.second->postInitialise();
                }
                else
                {
                    ke::Log::instance()->error("Entity named '{}'({}) failed to initialise its component: '{}'",
                        this->getName(), this->getId(), it.second->getName());
                    result = false;
                }
            }

        return result;
    }

    void Entity::updateAll(const ke::Time & p_ElapsedTime)
    {
        if (!this->m_Initialised)
        {
            this->m_Initialised = this->initialise();
        }

        for (auto & it : m_Components)
            it->update(p_ElapsedTime);
    }

}<commit_msg>Fix components added to a Entity after it's been initialised will not be initialised<commit_after>#include "KEngine/Core/Entity.hpp"
#include "KEngine/Interfaces/IEntityComponent.hpp"
#include "KEngine/Log/Log.hpp"

#include <cassert>

namespace ke
{
    Entity::Entity(const ke::EntityId p_ID)
        : m_EntityID(p_ID)
    {}

    Entity::Entity(ke::Entity && p_rrEntity)
        : m_Components(std::move(p_rrEntity.m_Components))
        , m_ComponentSPMap(std::move(p_rrEntity.m_ComponentSPMap))
        , m_EntityID(std::move(p_rrEntity.getId()))
    {}

    Entity & Entity::operator=(ke::Entity && p_rrEntity)
    {
        m_Components = std::move(p_rrEntity.m_Components);
        m_ComponentSPMap = std::move(p_rrEntity.m_ComponentSPMap);
        m_EntityID = p_rrEntity.getId();
        return *this;
    }

    Entity::~Entity(void)
    {
        assert(this->m_ComponentSPMap.empty()); // component must be empty (all circular references removed).
    }

    void Entity::addComponent(ke::EntityComponentSptr p_spEntityComponent)
    {
        assert(p_spEntityComponent != nullptr); // should not be null.
        const auto result = m_ComponentSPMap.insert(std::make_pair(p_spEntityComponent->getType(), p_spEntityComponent));
        assert(result.second); // fails if insertion failed.
        if (!result.second)
        {
            ke::Log::instance()->error("Attempted to add entity component of duplicate type: {0:#x}", p_spEntityComponent->getType());
            return;
        }
        m_Components.push_back(p_spEntityComponent);
        if (m_Initialised)
        {
            if (!this->initialise())
            {
                ke::Log::instance()->error("Failed to initialised entity component of type {0:#x} after adding it to entity '{}'({})",
                    p_spEntityComponent->getType(), this->getName(), this->getId());
            }
        }
    }

    bool Entity::initialise(void)
    {
        bool result = true;
        for (auto & it : m_ComponentSPMap)
            if (!it.second->isInitialised())
            {
                if (it.second->initialise())
                {
                    it.second->postInitialise();
                }
                else
                {
                    ke::Log::instance()->error("Entity named '{}'({}) failed to initialise its component: '{}'",
                        this->getName(), this->getId(), it.second->getName());
                    result = false;
                }
            }

        return result;
    }

    void Entity::updateAll(const ke::Time & p_ElapsedTime)
    {
        if (!this->m_Initialised)
        {
            this->m_Initialised = this->initialise();
        }

        for (auto & it : m_Components)
            it->update(p_ElapsedTime);
    }

}<|endoftext|>


<commit_before><commit_msg>fix -Wmaybe-uninitialized<commit_after><|endoftext|>


<commit_before><commit_msg>Planning: add TODO item for avoiding off-road.<commit_after><|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** 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 "resizeindicator.h"

#include "formeditoritem.h"

namespace QmlDesigner {

ResizeIndicator::ResizeIndicator(LayerItem *layerItem)
    : m_layerItem(layerItem)
{
    Q_ASSERT(layerItem);
}

ResizeIndicator::~ResizeIndicator()
{
    m_itemControllerHash.clear();
}

void ResizeIndicator::show()
{
    QHashIterator<FormEditorItem*, ResizeController> itemControllerIterator(m_itemControllerHash);
    while (itemControllerIterator.hasNext()) {
        ResizeController controller = itemControllerIterator.next().value();
        controller.show();
    }
}
void ResizeIndicator::hide()
{
    QHashIterator<FormEditorItem*, ResizeController> itemControllerIterator(m_itemControllerHash);
    while (itemControllerIterator.hasNext()) {
        ResizeController controller = itemControllerIterator.next().value();
        controller.hide();
    }
}

void ResizeIndicator::clear()
{
    m_itemControllerHash.clear();
}

bool itemIsResizable(const QmlItemNode &qmlItemNode)
{
    return qmlItemNode.isValid()
            && qmlItemNode.instanceIsResizable()
            && qmlItemNode.modelIsMovable()
            && qmlItemNode.modelIsResizable()
            && !qmlItemNode.instanceHasRotationTransform()
            && !qmlItemNode.instanceIsInLayoutable();
}

void ResizeIndicator::setItems(const QList<FormEditorItem*> &itemList)
{
    clear();

    foreach (FormEditorItem* item, itemList) {
        if (item && itemIsResizable(item->qmlItemNode())) {
            ResizeController controller(m_layerItem, item);
            m_itemControllerHash.insert(item, controller);
        }
    }
}

void ResizeIndicator::updateItems(const QList<FormEditorItem*> &itemList)
{
    foreach (FormEditorItem* item, itemList) {
        if (m_itemControllerHash.contains(item)) {
            if (!item || !itemIsResizable(item->qmlItemNode())) {
                m_itemControllerHash.take(item);
            } else {
                ResizeController controller(m_itemControllerHash.value(item));
                controller.updatePosition();
            }
        }
    }
}

}
<commit_msg>QmlDesigner: After removing xy bindings item should be resizable again<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** 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 "resizeindicator.h"

#include "formeditoritem.h"

namespace QmlDesigner {

ResizeIndicator::ResizeIndicator(LayerItem *layerItem)
    : m_layerItem(layerItem)
{
    Q_ASSERT(layerItem);
}

ResizeIndicator::~ResizeIndicator()
{
    m_itemControllerHash.clear();
}

void ResizeIndicator::show()
{
    QHashIterator<FormEditorItem*, ResizeController> itemControllerIterator(m_itemControllerHash);
    while (itemControllerIterator.hasNext()) {
        ResizeController controller = itemControllerIterator.next().value();
        controller.show();
    }
}
void ResizeIndicator::hide()
{
    QHashIterator<FormEditorItem*, ResizeController> itemControllerIterator(m_itemControllerHash);
    while (itemControllerIterator.hasNext()) {
        ResizeController controller = itemControllerIterator.next().value();
        controller.hide();
    }
}

void ResizeIndicator::clear()
{
    m_itemControllerHash.clear();
}

bool itemIsResizable(const QmlItemNode &qmlItemNode)
{
    return qmlItemNode.isValid()
            && qmlItemNode.instanceIsResizable()
            && qmlItemNode.modelIsMovable()
            && qmlItemNode.modelIsResizable()
            && !qmlItemNode.instanceHasRotationTransform()
            && !qmlItemNode.instanceIsInLayoutable();
}

void ResizeIndicator::setItems(const QList<FormEditorItem*> &itemList)
{
    clear();

    foreach (FormEditorItem* item, itemList) {
        if (item && itemIsResizable(item->qmlItemNode())) {
            ResizeController controller(m_layerItem, item);
            m_itemControllerHash.insert(item, controller);
        }
    }
}

void ResizeIndicator::updateItems(const QList<FormEditorItem*> &itemList)
{
    foreach (FormEditorItem* item, itemList) {
        if (m_itemControllerHash.contains(item)) {
            if (!item || !itemIsResizable(item->qmlItemNode())) {
                m_itemControllerHash.take(item);
            } else {
                ResizeController controller(m_itemControllerHash.value(item));
                controller.updatePosition();
            }
        } else if (item && itemIsResizable(item->qmlItemNode())) {
            ResizeController controller(m_layerItem, item);
            m_itemControllerHash.insert(item, controller);
        }
    }
}

}
<|endoftext|>


<commit_before>#include <limits>
#include <vector>
#include <gtest/gtest.h>

#include <boost/random/mersenne_twister.hpp>
#include <boost/math/distributions.hpp>
#include <boost/math/tools/promotion.hpp>

#include <stan/math/rev.hpp>
#include <stan/math/prim/fun/sign.hpp>
#include <stan/math/prim/fun/fabs.hpp>
#include <stan/math/prim/fun/log1m.hpp>

template <typename T1, typename T2, typename T3, typename T4>
inline typename boost::math::tools::promote_args<T1, T2, T3, T4>::type
skew_de_cdf_test(const T1& y, const T2& mu, const T3& sigma, const T4& tau) {
  using stan::math::log1m;
  using std::exp;
  using std::log;

  if (y < mu) {
    return log(tau) - 2 / sigma * (1 - tau) * (mu - y);
  } else {
    return log1m((1 - tau) * exp(-2 / sigma * tau * (y - mu)));
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_computes_correct_gradients) {
  using stan::math::skew_double_exponential_lcdf;

  for (double ys : {-1.7, 0.2, 0.5, 0.9, 1.1, 3.2, 8.3}) {
    for (double mus : {-1.8, 0.1, 0.55, 0.89, 1.3, 4.2, 9.3}) {
      for (double sigmas : {0.1, 1.1, 3.2}) {
        for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
          stan::math::var y = ys;
          stan::math::var mu = mus;
          stan::math::var sigma = sigmas;
          stan::math::var tau = taus;

          stan::math::var lp = skew_double_exponential_lcdf(y, mu, sigma, tau);
          std::vector<stan::math::var> theta;
          theta.push_back(y);
          theta.push_back(mu);
          theta.push_back(sigma);
          theta.push_back(tau);
          std::vector<double> grads;
          lp.grad(theta, grads);

          stan::math::var y_true = ys;
          stan::math::var mu_true = mus;
          stan::math::var sigma_true = sigmas;
          stan::math::var tau_true = taus;

          stan::math::var lp_test
              = skew_de_cdf_test(y_true, mu_true, sigma_true, tau_true);
          std::vector<stan::math::var> theta_true;
          theta_true.push_back(y_true);
          theta_true.push_back(mu_true);
          theta_true.push_back(sigma_true);
          theta_true.push_back(tau_true);
          std::vector<double> grads_true;
          lp_test.grad(theta_true, grads_true);

          EXPECT_NEAR(grads_true[0], grads[0], 0.001);
          EXPECT_NEAR(grads_true[1], grads[1], 0.001);
          EXPECT_NEAR(grads_true[2], grads[2], 0.001);
          EXPECT_NEAR(grads_true[3], grads[3], 0.001);
        }
      }
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential, lcdf_works_on_scalar_arguments) {
  using stan::math::skew_double_exponential_lcdf;

  for (double ys : {0.2, 0.9, 1.1, 3.2}) {
    for (double mus : {0.1, 1.3, 3.0}) {
      for (double sigmas : {0.1, 1.1, 3.2}) {
        for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
          EXPECT_NEAR(skew_de_cdf_test(ys, mus, sigmas, taus),
                      skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                      0.001);
        }
      }
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential, lcdf_works_on_vector_arguments) {
  using stan::math::skew_double_exponential_lcdf;

  std::vector<double> ys{0.2, 0.9, 1.1, 3.2};

  for (double mus : {0.1, 1.3, 3.0}) {
    for (double sigmas : {0.1, 1.1, 3.2}) {
      for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
        double x = 0.0;
        for (double y : ys)
          x += skew_de_cdf_test(y, mus, sigmas, taus);

        EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                    0.001);
      }
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_works_on_vectorial_y_and_mu) {
  using stan::math::skew_double_exponential_lcdf;
  std::vector<double> ys{0.2, 0.9, 1.1};
  std::vector<double> mus{0.1, 1.3, 3.0};

  for (double sigmas : {0.1, 1.1, 3.2}) {
    for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
      double x = 0.0;
      for (int i = 0; i < 3; i++)
        x += skew_de_cdf_test(ys[i], mus[i], sigmas, taus);

      EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                  0.001);
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_works_on_vectorial_y_and_sigma) {
  using stan::math::skew_double_exponential_lcdf;
  std::vector<double> ys{0.2, 0.9, 1.1};
  std::vector<double> sigmas{0.1, 1.1, 3.2};

  for (double mus : {0.1, 1.3, 3.0}) {
    for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
      double x = 0.0;
      for (int i = 0; i < 3; i++)
        x += skew_de_cdf_test(ys[i], mus, sigmas[i], taus);

      EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                  0.001);
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_works_on_vectorial_y_and_tau) {
  using stan::math::skew_double_exponential_lcdf;
  std::vector<double> ys{0.2, 0.9, 1.1};
  std::vector<double> taus{0.1, 0.5, 0.9};

  for (double mus : {0.1, 1.3, 3.0}) {
    for (double sigmas : {0.1, 1.1, 3.2}) {
      double x = 0.0;
      for (int i = 0; i < 3; i++)
        x += skew_de_cdf_test(ys[i], mus, sigmas, taus[i]);

      EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                  0.001);
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_works_on_vectorial_mu_sigma_and_tau) {
  using stan::math::skew_double_exponential_lcdf;

  std::vector<double> mus{0.1, 1.3, 3.0};
  std::vector<double> sigmas{0.1, 1.1, 3.2};
  std::vector<double> taus{0.1, 0.5, 0.9};

  for (double ys : {0.1, 1.3, 3.0}) {
    double x = 0.0;
    for (int i = 0; i < 3; i++)
      x += skew_de_cdf_test(ys, mus[i], sigmas[i], taus[i]);
    EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus), 0.001);
  }
}

TEST(ProbDistributionsSkewedDoubleExponential, lcdf_check_errors) {
  using stan::math::skew_double_exponential_lcdf;
  static double inff = std::numeric_limits<double>::infinity();
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(1.0, 0.0, -1, 0.5),
               std::domain_error);
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(1.0, 0.0, 0.1, -0.5),
               std::domain_error);
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(inff, 0.0, 0.1, 1.5),
               std::domain_error);
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(1.0, inff, 0.1, 1.5),
               std::domain_error);
}

TEST(ProbDistributionsSkewedDoubleExponential, lcdf_check_inconsistent_size) {
  using stan::math::skew_double_exponential_lcdf;

  std::vector<double> mus{0.1, 1.3, 3.0};
  std::vector<double> sigmas{0.1, 1.1, 3.2, 1.0};
  std::vector<double> taus{0.1, 0.5, 0.9};
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(1.0, mus, sigmas, taus),
               std::invalid_argument);
}

#include <stan/math/prim.hpp>
#include <gtest/gtest.h>

TEST(ProbDistributionsSkewedDoubleExponential, cdf_log_matches_lcdf) {
  double y = 0.8;
  double mu = 2;
  double sigma = 2.3;
  double tau = 0.1;

  EXPECT_FLOAT_EQ(
      (stan::math::skew_double_exponential_lcdf(y, mu, sigma, tau)),
      (stan::math::skew_double_exponential_cdf_log(y, mu, sigma, tau)));

  EXPECT_FLOAT_EQ(
      (stan::math::skew_double_exponential_lcdf<double, double, double, double>(
          y, mu, sigma, tau)),
      (stan::math::skew_double_exponential_cdf_log<double, double, double,
                                                   double>(y, mu, sigma, tau)));
}
<commit_msg>Remove double include statement<commit_after>#include <limits>
#include <vector>
#include <gtest/gtest.h>

#include <boost/random/mersenne_twister.hpp>
#include <boost/math/distributions.hpp>
#include <boost/math/tools/promotion.hpp>

#include <stan/math/rev.hpp>
#include <stan/math/prim/fun/sign.hpp>
#include <stan/math/prim/fun/fabs.hpp>
#include <stan/math/prim/fun/log1m.hpp>

template <typename T1, typename T2, typename T3, typename T4>
inline typename boost::math::tools::promote_args<T1, T2, T3, T4>::type
skew_de_cdf_test(const T1& y, const T2& mu, const T3& sigma, const T4& tau) {
  using stan::math::log1m;
  using std::exp;
  using std::log;

  if (y < mu) {
    return log(tau) - 2 / sigma * (1 - tau) * (mu - y);
  } else {
    return log1m((1 - tau) * exp(-2 / sigma * tau * (y - mu)));
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_computes_correct_gradients) {
  using stan::math::skew_double_exponential_lcdf;

  for (double ys : {-1.7, 0.2, 0.5, 0.9, 1.1, 3.2, 8.3}) {
    for (double mus : {-1.8, 0.1, 0.55, 0.89, 1.3, 4.2, 9.3}) {
      for (double sigmas : {0.1, 1.1, 3.2}) {
        for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
          stan::math::var y = ys;
          stan::math::var mu = mus;
          stan::math::var sigma = sigmas;
          stan::math::var tau = taus;

          stan::math::var lp = skew_double_exponential_lcdf(y, mu, sigma, tau);
          std::vector<stan::math::var> theta;
          theta.push_back(y);
          theta.push_back(mu);
          theta.push_back(sigma);
          theta.push_back(tau);
          std::vector<double> grads;
          lp.grad(theta, grads);

          stan::math::var y_true = ys;
          stan::math::var mu_true = mus;
          stan::math::var sigma_true = sigmas;
          stan::math::var tau_true = taus;

          stan::math::var lp_test
              = skew_de_cdf_test(y_true, mu_true, sigma_true, tau_true);
          std::vector<stan::math::var> theta_true;
          theta_true.push_back(y_true);
          theta_true.push_back(mu_true);
          theta_true.push_back(sigma_true);
          theta_true.push_back(tau_true);
          std::vector<double> grads_true;
          lp_test.grad(theta_true, grads_true);

          EXPECT_NEAR(grads_true[0], grads[0], 0.001);
          EXPECT_NEAR(grads_true[1], grads[1], 0.001);
          EXPECT_NEAR(grads_true[2], grads[2], 0.001);
          EXPECT_NEAR(grads_true[3], grads[3], 0.001);
        }
      }
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential, lcdf_works_on_scalar_arguments) {
  using stan::math::skew_double_exponential_lcdf;

  for (double ys : {0.2, 0.9, 1.1, 3.2}) {
    for (double mus : {0.1, 1.3, 3.0}) {
      for (double sigmas : {0.1, 1.1, 3.2}) {
        for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
          EXPECT_NEAR(skew_de_cdf_test(ys, mus, sigmas, taus),
                      skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                      0.001);
        }
      }
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential, lcdf_works_on_vector_arguments) {
  using stan::math::skew_double_exponential_lcdf;

  std::vector<double> ys{0.2, 0.9, 1.1, 3.2};

  for (double mus : {0.1, 1.3, 3.0}) {
    for (double sigmas : {0.1, 1.1, 3.2}) {
      for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
        double x = 0.0;
        for (double y : ys)
          x += skew_de_cdf_test(y, mus, sigmas, taus);

        EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                    0.001);
      }
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_works_on_vectorial_y_and_mu) {
  using stan::math::skew_double_exponential_lcdf;
  std::vector<double> ys{0.2, 0.9, 1.1};
  std::vector<double> mus{0.1, 1.3, 3.0};

  for (double sigmas : {0.1, 1.1, 3.2}) {
    for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
      double x = 0.0;
      for (int i = 0; i < 3; i++)
        x += skew_de_cdf_test(ys[i], mus[i], sigmas, taus);

      EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                  0.001);
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_works_on_vectorial_y_and_sigma) {
  using stan::math::skew_double_exponential_lcdf;
  std::vector<double> ys{0.2, 0.9, 1.1};
  std::vector<double> sigmas{0.1, 1.1, 3.2};

  for (double mus : {0.1, 1.3, 3.0}) {
    for (double taus : {0.01, 0.1, 0.5, 0.9, 0.99}) {
      double x = 0.0;
      for (int i = 0; i < 3; i++)
        x += skew_de_cdf_test(ys[i], mus, sigmas[i], taus);

      EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                  0.001);
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_works_on_vectorial_y_and_tau) {
  using stan::math::skew_double_exponential_lcdf;
  std::vector<double> ys{0.2, 0.9, 1.1};
  std::vector<double> taus{0.1, 0.5, 0.9};

  for (double mus : {0.1, 1.3, 3.0}) {
    for (double sigmas : {0.1, 1.1, 3.2}) {
      double x = 0.0;
      for (int i = 0; i < 3; i++)
        x += skew_de_cdf_test(ys[i], mus, sigmas, taus[i]);

      EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus),
                  0.001);
    }
  }
}

TEST(ProbDistributionsSkewedDoubleExponential,
     lcdf_works_on_vectorial_mu_sigma_and_tau) {
  using stan::math::skew_double_exponential_lcdf;

  std::vector<double> mus{0.1, 1.3, 3.0};
  std::vector<double> sigmas{0.1, 1.1, 3.2};
  std::vector<double> taus{0.1, 0.5, 0.9};

  for (double ys : {0.1, 1.3, 3.0}) {
    double x = 0.0;
    for (int i = 0; i < 3; i++)
      x += skew_de_cdf_test(ys, mus[i], sigmas[i], taus[i]);
    EXPECT_NEAR(x, skew_double_exponential_lcdf(ys, mus, sigmas, taus), 0.001);
  }
}

TEST(ProbDistributionsSkewedDoubleExponential, lcdf_check_errors) {
  using stan::math::skew_double_exponential_lcdf;
  static double inff = std::numeric_limits<double>::infinity();
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(1.0, 0.0, -1, 0.5),
               std::domain_error);
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(1.0, 0.0, 0.1, -0.5),
               std::domain_error);
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(inff, 0.0, 0.1, 1.5),
               std::domain_error);
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(1.0, inff, 0.1, 1.5),
               std::domain_error);
}

TEST(ProbDistributionsSkewedDoubleExponential, lcdf_check_inconsistent_size) {
  using stan::math::skew_double_exponential_lcdf;

  std::vector<double> mus{0.1, 1.3, 3.0};
  std::vector<double> sigmas{0.1, 1.1, 3.2, 1.0};
  std::vector<double> taus{0.1, 0.5, 0.9};
  EXPECT_THROW(stan::math::skew_double_exponential_lcdf(1.0, mus, sigmas, taus),
               std::invalid_argument);
}

TEST(ProbDistributionsSkewedDoubleExponential, cdf_log_matches_lcdf) {
  double y = 0.8;
  double mu = 2;
  double sigma = 2.3;
  double tau = 0.1;

  EXPECT_FLOAT_EQ(
      (stan::math::skew_double_exponential_lcdf(y, mu, sigma, tau)),
      (stan::math::skew_double_exponential_cdf_log(y, mu, sigma, tau)));

  EXPECT_FLOAT_EQ(
      (stan::math::skew_double_exponential_lcdf<double, double, double, double>(
          y, mu, sigma, tau)),
      (stan::math::skew_double_exponential_cdf_log<double, double, double,
                                                   double>(y, mu, sigma, tau)));
}
<|endoftext|>