<commit_before>/**
 * \file Library.cpp
 * \author Matt Hammerly
 */

#include <string>
#include <iostream>
#include "Library.h"

/**
 * \brief Default constructor
 *
 * Todo: sanitize the db credentials I guess lol
 */
CLibrary::CLibrary()
{
    char connectionString[512];
    snprintf(connectionString, 512, "dbname=%s host=%s user=%s password=%s",
             DBNAME, DBHOST, DBUSER, DBPW);

    mConnection = PQconnectdb(connectionString);

    if (PQstatus(mConnection) == CONNECTION_BAD)
    {
        std::cout << "Failed to connect to the database" << std::endl;
        exit(0);
    }
}

/**
 * \brief Destructor
 *
 * Will close the database connection before exiting
 */
CLibrary::~CLibrary()
{
    PQfinish(mConnection);
}

/**
 * \brief Create the database tables for this application
 *
 * \returns -1 if something goes wrong
 *
 * Todo: Write database schema in this comment
 *       `create trigger IF NOT EXISTS` or similar
 */
int CLibrary::PrepareDatabase()
{
    PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS tracks (\
                id SERIAL NOT NULL PRIMARY KEY,\
                location TEXT NOT NULL,\
                flag INTEGER NOT NULL DEFAULT 0\
          )");
    PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS playlists (\
                id SERIAL NOT NULL PRIMARY KEY,\
                title TEXT NOT NULL,\
                length INTEGER NOT NULL,\
                flag INTEGER NOT NULL DEFAULT 0\
          )");
    PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS tracks_playlists (\
                id SERIAL NOT NULL PRIMARY KEY,\
                track_id INTEGER NOT NULL,\
                playlist_id INTEGER NOT NULL,\
                position FLOAT NOT NULL\
          )");

    // Create a function to adjust the length of a playlist
    PQexec(mConnection,
            "CREATE OR REPLACE FUNCTION tracks_playlists_insert_func() RETURNS TRIGGER\
            LANGUAGE plpgsql\
            AS $tracks_playlists_insert_func$\
            DECLARE\
                pid INTEGER;\
            BEGIN\
                pid=0;\
                IF (TG_OP = 'INSERT') THEN pid = NEW.playlist_id;\
                ELSIF (TG_OP = 'DELETE') THEN pid = OLD.playlist_id;\
                END IF;\
                WITH Sub AS (SELECT COUNT(id) AS c FROM tracks_playlists WHERE playlist_id = pid)\
                    UPDATE playlists AS Main SET length = Sub.c FROM Sub WHERE Main.id = pid AND 1=1;\
                RETURN NULL;\
            END;\
            $tracks_playlists_insert_func$;");

    // Create a trigger to adjust the length of a playlist on each insert or delete
    PQexec(mConnection,
            "CREATE TRIGGER tracks_playlists_insert_trg\
            AFTER INSERT OR DELETE ON tracks_playlists\
            FOR EACH ROW EXECUTE PROCEDURE tracks_playlists_insert_func();");

    return 0;
}

/**
 * \brief Destroy all database objects used in this application
 *
 * \returns -1 if something goes wrong? I don't know what or why, frankly.
 */
int CLibrary::DestroyDatabase()
{
    PQexec(mConnection, "DROP TRIGGER IF EXISTS tracks_playlists_insert_trg ON tracks_playlists;");
    PQexec(mConnection, "DROP FUNCTION IF EXISTS tracks_playlists_insert_func() CASCADE;");

    PQexec(mConnection, "DROP TABLE IF EXISTS tracks;");
    PQexec(mConnection, "DROP TABLE IF EXISTS playlists;");
    PQexec(mConnection, "DROP TABLE IF EXISTS tracks_playlists;");

    return 0;
}

/**
 * \brief Exposes the database connection status
 * \returns PostgreSQL connection status object
 *
 * Just in case.
 */
ConnStatusType CLibrary::GetStatus()
{
    return PQstatus(mConnection);
}

/**
 * \brief Returns a pointer to the connection object
 *
 * It makes tests easier. Might make this protected and
 * require a testing subclass to use this later, whatever.
 */
PGconn* CLibrary::GetConnection()
{
    return mConnection;
}
<commit_msg>added a date_added column to tracks table<commit_after>/**
 * \file Library.cpp
 * \author Matt Hammerly
 */

#include <string>
#include <iostream>
#include "Library.h"

/**
 * \brief Default constructor
 *
 * Todo: sanitize the db credentials I guess lol
 */
CLibrary::CLibrary()
{
    char connectionString[512];
    snprintf(connectionString, 512, "dbname=%s host=%s user=%s password=%s",
             DBNAME, DBHOST, DBUSER, DBPW);

    mConnection = PQconnectdb(connectionString);

    if (PQstatus(mConnection) == CONNECTION_BAD)
    {
        std::cout << "Failed to connect to the database" << std::endl;
        exit(0);
    }
}

/**
 * \brief Destructor
 *
 * Will close the database connection before exiting
 */
CLibrary::~CLibrary()
{
    PQfinish(mConnection);
}

/**
 * \brief Create the database tables for this application
 *
 * \returns -1 if something goes wrong
 *
 * Todo: Write database schema in this comment
 *       `create trigger IF NOT EXISTS` or similar
 */
int CLibrary::PrepareDatabase()
{
    PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS tracks (\
                id SERIAL NOT NULL PRIMARY KEY,\
                location TEXT NOT NULL,\
                date_added TIMESTAMPTZ NOT NULL DEFAULT NOW(),\
                flag INTEGER NOT NULL DEFAULT 0\
          )");
    PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS playlists (\
                id SERIAL NOT NULL PRIMARY KEY,\
                title TEXT NOT NULL,\
                length INTEGER NOT NULL,\
                flag INTEGER NOT NULL DEFAULT 0\
          )");
    PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS tracks_playlists (\
                id SERIAL NOT NULL PRIMARY KEY,\
                track_id INTEGER NOT NULL,\
                playlist_id INTEGER NOT NULL,\
                position FLOAT NOT NULL\
          )");

    // Create a function to adjust the length of a playlist
    PQexec(mConnection,
            "CREATE OR REPLACE FUNCTION tracks_playlists_insert_func() RETURNS TRIGGER\
            LANGUAGE plpgsql\
            AS $tracks_playlists_insert_func$\
            DECLARE\
                pid INTEGER;\
            BEGIN\
                pid=0;\
                IF (TG_OP = 'INSERT') THEN pid = NEW.playlist_id;\
                ELSIF (TG_OP = 'DELETE') THEN pid = OLD.playlist_id;\
                END IF;\
                WITH Sub AS (SELECT COUNT(id) AS c FROM tracks_playlists WHERE playlist_id = pid)\
                    UPDATE playlists AS Main SET length = Sub.c FROM Sub WHERE Main.id = pid AND 1=1;\
                RETURN NULL;\
            END;\
            $tracks_playlists_insert_func$;");

    // Create a trigger to adjust the length of a playlist on each insert or delete
    PQexec(mConnection,
            "CREATE TRIGGER tracks_playlists_insert_trg\
            AFTER INSERT OR DELETE ON tracks_playlists\
            FOR EACH ROW EXECUTE PROCEDURE tracks_playlists_insert_func();");

    return 0;
}

/**
 * \brief Destroy all database objects used in this application
 *
 * \returns -1 if something goes wrong? I don't know what or why, frankly.
 */
int CLibrary::DestroyDatabase()
{
    PQexec(mConnection, "DROP TRIGGER IF EXISTS tracks_playlists_insert_trg ON tracks_playlists;");
    PQexec(mConnection, "DROP FUNCTION IF EXISTS tracks_playlists_insert_func() CASCADE;");

    PQexec(mConnection, "DROP TABLE IF EXISTS tracks;");
    PQexec(mConnection, "DROP TABLE IF EXISTS playlists;");
    PQexec(mConnection, "DROP TABLE IF EXISTS tracks_playlists;");

    return 0;
}

/**
 * \brief Exposes the database connection status
 * \returns PostgreSQL connection status object
 *
 * Just in case.
 */
ConnStatusType CLibrary::GetStatus()
{
    return PQstatus(mConnection);
}

/**
 * \brief Returns a pointer to the connection object
 *
 * It makes tests easier. Might make this protected and
 * require a testing subclass to use this later, whatever.
 */
PGconn* CLibrary::GetConnection()
{
    return mConnection;
}
<|endoftext|>


<commit_before>/*
	This file is part of solidity.

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

	solidity is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Parser.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "Parser.h"

#if _MSC_VER
#pragma warning(disable:4348)
#endif

#define BOOST_RESULT_OF_USE_DECLTYPE
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/support_utree.hpp>

using namespace std;
using namespace dev;
using namespace dev::eth;
namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;
namespace sp = boost::spirit;

void dev::eth::killBigints(sp::utree const& _this)
{
	switch (_this.which())
	{
	case sp::utree_type::list_type: for (auto const& i: _this) killBigints(i); break;
	case sp::utree_type::any_type: delete _this.get<bigint*>(); break;
	default:;
	}
}

void dev::eth::debugOutAST(ostream& _out, sp::utree const& _this)
{
	switch (_this.which())
	{
	case sp::utree_type::list_type:
		switch (_this.tag())
		{
		case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
		case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
		case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
		case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
		case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
		case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
		case 6: _out << "$ "; debugOutAST(_out, _this.front()); break;
		default:;
		}

		break;
	case sp::utree_type::int_type: _out << _this.get<int>(); break;
	case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
	case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
	case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
	default: _out << "nil";
	}
}

namespace dev { namespace eth {
namespace parseTreeLLL_ {

template<unsigned N>
struct tagNode
{
	void operator()(sp::utree& n, qi::rule<string::const_iterator, qi::ascii::space_type, sp::utree()>::context_type& c) const
	{
		(boost::fusion::at_c<0>(c.attributes) = n).tag(N);
	}
};

}}}

void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
{
	using qi::standard::space;
	using qi::standard::space_type;
	using dev::eth::parseTreeLLL_::tagNode;
	using symbol_type = sp::basic_string<std::string, sp::utree_type::symbol_type>;
	using it = string::const_iterator;

	qi::rule<it, space_type, sp::utree()> element;
	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\0'))];
	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" $@[]{}:();\"\x01-\x1f\x7f") + '\0'))];
	qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> +qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
	qi::rule<it, sp::utree()> integer = intstr[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))];
	qi::rule<it, space_type, sp::utree()> atom = integer[qi::_val = qi::_1] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
	qi::rule<it, space_type, sp::utree::list_type()> seq = '{' > *element > '}';
	qi::rule<it, space_type, sp::utree::list_type()> mload = '@' > element;
	qi::rule<it, space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
	qi::rule<it, space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
	qi::rule<it, space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
	qi::rule<it, space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
	qi::rule<it, space_type, sp::utree::list_type()> list = '(' > +element > ')';

	qi::rule<it, space_type, sp::utree()> extra = sload[tagNode<2>()] | mload[tagNode<1>()] | sstore[tagNode<4>()] | mstore[tagNode<3>()] | seq[tagNode<5>()] | calldataload[tagNode<6>()];
	element = atom | list | extra;

	string s;
	s.reserve(_s.size());
	bool incomment = false;
	bool instring = false;
	bool insstring = false;
	for (auto i: _s)
	{
		if (i == ';' && !instring && !insstring)
			incomment = true;
		else if (i == '\n')
			incomment = instring = insstring = false;
		else if (i == '"' && !insstring)
			instring = !instring;
		else if (i == '\'')
			insstring = true;
		else if (i == ' ')
			insstring = false;
		if (!incomment)
			s.push_back(i);
	}
	auto ret = s.cbegin();
	try
	{
		qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
	}
	catch (qi::expectation_failure<it> const& e)
	{
		std::string fragment(e.first, e.last);
		std::string loc = std::to_string(std::distance(s.cbegin(), e.first) - 1);
		std::string reason("Lexer failure at " + loc + ": '" + fragment + "'");
		BOOST_THROW_EXCEPTION(ParserException() << errinfo_comment(reason));
	}
	for (auto i = ret; i != s.cend(); ++i)
		if (!isspace(*i)) {
			BOOST_THROW_EXCEPTION(ParserException() << errinfo_comment("Non-whitespace left in parser"));
		}
}
<commit_msg>liblll: allow macros with no arguments<commit_after>/*
	This file is part of solidity.

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

	solidity is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Parser.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "Parser.h"

#if _MSC_VER
#pragma warning(disable:4348)
#endif

#define BOOST_RESULT_OF_USE_DECLTYPE
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/support_utree.hpp>

using namespace std;
using namespace dev;
using namespace dev::eth;
namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;
namespace sp = boost::spirit;

void dev::eth::killBigints(sp::utree const& _this)
{
	switch (_this.which())
	{
	case sp::utree_type::list_type: for (auto const& i: _this) killBigints(i); break;
	case sp::utree_type::any_type: delete _this.get<bigint*>(); break;
	default:;
	}
}

void dev::eth::debugOutAST(ostream& _out, sp::utree const& _this)
{
	switch (_this.which())
	{
	case sp::utree_type::list_type:
		switch (_this.tag())
		{
		case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
		case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
		case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
		case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
		case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
		case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
		case 6: _out << "$ "; debugOutAST(_out, _this.front()); break;
		default:;
		}

		break;
	case sp::utree_type::int_type: _out << _this.get<int>(); break;
	case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
	case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
	case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
	default: _out << "nil";
	}
}

namespace dev { namespace eth {
namespace parseTreeLLL_ {

template<unsigned N>
struct tagNode
{
	void operator()(sp::utree& n, qi::rule<string::const_iterator, qi::ascii::space_type, sp::utree()>::context_type& c) const
	{
		(boost::fusion::at_c<0>(c.attributes) = n).tag(N);
	}
};

}}}

void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
{
	using qi::standard::space;
	using qi::standard::space_type;
	using dev::eth::parseTreeLLL_::tagNode;
	using symbol_type = sp::basic_string<std::string, sp::utree_type::symbol_type>;
	using it = string::const_iterator;

	qi::rule<it, space_type, sp::utree()> element;
	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\0'))];
	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" $@[]{}:();\"\x01-\x1f\x7f") + '\0'))];
	qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> +qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
	qi::rule<it, sp::utree()> integer = intstr[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))];
	qi::rule<it, space_type, sp::utree()> atom = integer[qi::_val = qi::_1] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
	qi::rule<it, space_type, sp::utree::list_type()> seq = '{' > *element > '}';
	qi::rule<it, space_type, sp::utree::list_type()> mload = '@' > element;
	qi::rule<it, space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
	qi::rule<it, space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
	qi::rule<it, space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
	qi::rule<it, space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
	qi::rule<it, space_type, sp::utree::list_type()> list = '(' > *element > ')';

	qi::rule<it, space_type, sp::utree()> extra = sload[tagNode<2>()] | mload[tagNode<1>()] | sstore[tagNode<4>()] | mstore[tagNode<3>()] | seq[tagNode<5>()] | calldataload[tagNode<6>()];
	element = atom | list | extra;

	string s;
	s.reserve(_s.size());
	bool incomment = false;
	bool instring = false;
	bool insstring = false;
	for (auto i: _s)
	{
		if (i == ';' && !instring && !insstring)
			incomment = true;
		else if (i == '\n')
			incomment = instring = insstring = false;
		else if (i == '"' && !insstring)
			instring = !instring;
		else if (i == '\'')
			insstring = true;
		else if (i == ' ')
			insstring = false;
		if (!incomment)
			s.push_back(i);
	}
	auto ret = s.cbegin();
	try
	{
		qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
	}
	catch (qi::expectation_failure<it> const& e)
	{
		std::string fragment(e.first, e.last);
		std::string loc = std::to_string(std::distance(s.cbegin(), e.first) - 1);
		std::string reason("Lexer failure at " + loc + ": '" + fragment + "'");
		BOOST_THROW_EXCEPTION(ParserException() << errinfo_comment(reason));
	}
	for (auto i = ret; i != s.cend(); ++i)
		if (!isspace(*i)) {
			BOOST_THROW_EXCEPTION(ParserException() << errinfo_comment("Non-whitespace left in parser"));
		}
}
<|endoftext|>


<commit_before><commit_msg>remove whitespaces<commit_after><|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkBaseProcess.h"
#include "mitkBaseData.h"

#define MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED

//##ModelId=3E8600DD0036
mitk::BaseProcess::BaseProcess() : m_Unregistering(false), m_CalculatingExternalReferenceCount(false), m_ExternalReferenceCount(-1)
{

}

//##ModelId=3E8600DD004A
mitk::BaseProcess::~BaseProcess()
{

}

//##ModelId=3E8600DD000E
int mitk::BaseProcess::GetExternalReferenceCount() const
{
  if(m_CalculatingExternalReferenceCount==false) //this is only needed because a smart-pointer to m_Outputs (private!!) must be created by calling GetOutputs.
  {
    m_CalculatingExternalReferenceCount = true;

    m_ExternalReferenceCount = -1;

    DataObjectPointerArray outputs = const_cast<mitk::BaseProcess*>(this)->GetOutputs();

    int realReferenceCount = GetReferenceCount();

    unsigned int idx;
    for (idx = 0; idx < outputs.size(); ++idx)
    {
      //references of outputs that are not referenced from someone else (reference additional to the reference from this BaseProcess object) are interpreted as non-existent
      if((outputs[idx]) && (outputs[idx]->GetReferenceCount()==2)) //2 because the outputs array also holds a reference!
        --realReferenceCount;
    }
    m_ExternalReferenceCount = realReferenceCount;
    if(m_ExternalReferenceCount<0)
      m_ExternalReferenceCount=0;
  }
  else
    return -1;
  m_CalculatingExternalReferenceCount = false; //do not move in if-part!!!
  return m_ExternalReferenceCount;
}

//##ModelId=3E8600DC03E2
void mitk::BaseProcess::UnRegister() const
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
  if((m_Unregistering==false) && (m_CalculatingExternalReferenceCount==false))
  {
    m_Unregistering=true;

    int realReferenceCount = GetExternalReferenceCount()-1; //-1 because someone is trying to unregister us
    if(realReferenceCount<0)
      m_ExternalReferenceCount=realReferenceCount=0;

    if(realReferenceCount==0)
    {
      DataObjectPointerArray& outputs = const_cast<mitk::BaseProcess*>(this)->GetOutputs();
      //disconnect all outputs from us
      //size of outputs will not change until the very last output
      //is removed, because we remove from front to back
      unsigned int idx;
      for (idx = 0; idx < outputs.size(); ++idx)
      {
        const_cast<mitk::BaseProcess*>(this)->RemoveOutput(outputs[idx]);
      }
      //now the referenceCount should be one!
      int testReferenceCount=GetReferenceCount();
      if(testReferenceCount!=1)
      {
        itkWarningMacro(<<"Reference count of process object unexpectedly "
          << "not 1 before final unregister but " << testReferenceCount);
      }
    }
    m_Unregistering=false;
  }
  else
  {
    if(GetReferenceCount()==1)
    {
      //the calling UnRegister will do the last cleanup
      return;
    }
  }
#endif
  Superclass::UnRegister();
}

/**
* Set an output of this filter. This method specifically
* does not do a Register()/UnRegister() because of the
* desire to break the reference counting loop.
*/
//##ModelId=3E8600DD0072
void mitk::BaseProcess::SetNthOutput(unsigned int idx, itk::DataObject *output)
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
  output = dynamic_cast<mitk::BaseData*>(output);

  // does this change anything?
  if ( idx < GetOutputs().size() && output == GetOutputs()[idx])
  {
    return;
  }

  if (output)
  {
    dynamic_cast<mitk::BaseData*>(output)->ConnectSource(this, idx);
  }
#endif
  this->Register();
  Superclass::SetNthOutput(idx, output);
  this->UnRegister();
}

/**
* Adds an output to the first null position in the output list.
* Expands the list memory if necessary
*/
//##ModelId=3E8600DD00F4
void mitk::BaseProcess::AddOutput(itk::DataObject *output)
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
  unsigned int idx=0;

  output = dynamic_cast<mitk::BaseData*>(output);

  if (output)
  {
    dynamic_cast<mitk::BaseData*>(output)->ConnectSource(this, idx);
  }
#endif
  Superclass::AddOutput(output);

}
<commit_msg>FIX: reference count problem on shrinking of output-array in ProcessObject::SetNumberOfOutputs: ouput is still in array after actual delete, array was copied which increased reference count again, resulting in a second deletion when freeing the copied array => do not copy, just reference<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkBaseProcess.h"
#include "mitkBaseData.h"

#define MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED

//##ModelId=3E8600DD0036
mitk::BaseProcess::BaseProcess() : m_Unregistering(false), m_CalculatingExternalReferenceCount(false), m_ExternalReferenceCount(-1)
{

}

//##ModelId=3E8600DD004A
mitk::BaseProcess::~BaseProcess()
{

}

//##ModelId=3E8600DD000E
int mitk::BaseProcess::GetExternalReferenceCount() const
{
  if(m_CalculatingExternalReferenceCount==false) //this is only needed because a smart-pointer to m_Outputs (private!!) must be created by calling GetOutputs.
  {
    m_CalculatingExternalReferenceCount = true;

    m_ExternalReferenceCount = -1;

    DataObjectPointerArray& outputs = const_cast<mitk::BaseProcess*>(this)->GetOutputs();

    int realReferenceCount = GetReferenceCount();

    unsigned int idx;
    for (idx = 0; idx < outputs.size(); ++idx)
    {
      //references of outputs that are not referenced from someone else (reference additional to the reference from this BaseProcess object) are interpreted as non-existent
      if((outputs[idx]) && (outputs[idx]->GetReferenceCount()==2)) //2 because the outputs array also holds a reference!
        --realReferenceCount;
    }
    m_ExternalReferenceCount = realReferenceCount;
    if(m_ExternalReferenceCount<0)
      m_ExternalReferenceCount=0;
  }
  else
    return -1;
  m_CalculatingExternalReferenceCount = false; //do not move in if-part!!!
  return m_ExternalReferenceCount;
}

//##ModelId=3E8600DC03E2
void mitk::BaseProcess::UnRegister() const
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
  if((m_Unregistering==false) && (m_CalculatingExternalReferenceCount==false))
  {
    m_Unregistering=true;

    int realReferenceCount = GetExternalReferenceCount()-1; //-1 because someone is trying to unregister us
    if(realReferenceCount<0)
      m_ExternalReferenceCount=realReferenceCount=0;

    if(realReferenceCount==0)
    {
      DataObjectPointerArray& outputs = const_cast<mitk::BaseProcess*>(this)->GetOutputs();
      //disconnect all outputs from us
      //size of outputs will not change until the very last output
      //is removed, because we remove from front to back
      unsigned int idx;
      for (idx = 0; idx < outputs.size(); ++idx)
      {
        const_cast<mitk::BaseProcess*>(this)->RemoveOutput(outputs[idx]);
      }
      //now the referenceCount should be one!
      int testReferenceCount=GetReferenceCount();
      if(testReferenceCount!=1)
      {
        itkWarningMacro(<<"Reference count of process object unexpectedly "
          << "not 1 before final unregister but " << testReferenceCount);
      }
    }
    m_Unregistering=false;
  }
  else
  {
    if(GetReferenceCount()==1)
    {
      //the calling UnRegister will do the last cleanup
      return;
    }
  }
#endif
  Superclass::UnRegister();
}

/**
* Set an output of this filter. This method specifically
* does not do a Register()/UnRegister() because of the
* desire to break the reference counting loop.
*/
//##ModelId=3E8600DD0072
void mitk::BaseProcess::SetNthOutput(unsigned int idx, itk::DataObject *output)
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
  output = dynamic_cast<mitk::BaseData*>(output);

  // does this change anything?
  if ( idx < GetOutputs().size() && output == GetOutputs()[idx])
  {
    return;
  }

  if (output)
  {
    dynamic_cast<mitk::BaseData*>(output)->ConnectSource(this, idx);
  }
#endif
  this->Register();
  Superclass::SetNthOutput(idx, output);
  this->UnRegister();
}

/**
* Adds an output to the first null position in the output list.
* Expands the list memory if necessary
*/
//##ModelId=3E8600DD00F4
void mitk::BaseProcess::AddOutput(itk::DataObject *output)
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
  unsigned int idx=0;

  output = dynamic_cast<mitk::BaseData*>(output);

  if (output)
  {
    dynamic_cast<mitk::BaseData*>(output)->ConnectSource(this, idx);
  }
#endif
  Superclass::AddOutput(output);

}
<|endoftext|>


<commit_before>#include <QStringList>
#include "ilwis.h"
#include "angle.h"
#include "point.h"
#include "box.h"
#include "line.h"
#include <type_traits>
#include <boost/geometry.hpp>
#include "polygon.h"
#include "geometry.h"

using namespace Ilwis;

Geometry::Geometry(const GeometryType& geom) : _geometry(geom){

}

bool Geometry::isValid() const {
    //TODO
    return true;
}

Box2D<double> Geometry::envelope() const{
    if (!_bounds.isValid()) {
        return const_cast<Geometry *>(this)->envelope();
    }
    return _bounds;
}

Box2D<double> Geometry::envelope() {
    if (!_bounds.isValid()) {
        switch(_geometry.which()){
        case 0:
        {
            Point2D<double> p = (boost::get<Point2D<> >(_geometry));
            _bounds = Box2D<double>(p,p);
            break;
        }
        case 1:
        {
            Point3D<double> p = (boost::get<Point2D<double> >(_geometry));
            _bounds =  Box2D<double>(p,p);
            break;
        }
        case 2:
        {
            Point3D<double> p = (boost::get<Point3D<double> >(_geometry));
            _bounds =  Box2D<double>(p,p);
            break;
        }
        case 3:
        {
            const Line2D<Coordinate2d>& line = (boost::get<Line2D<Coordinate2d> >(_geometry));
            _bounds = boost::geometry::return_envelope<Box2Dd>(line);
            break;
        }
        case 4:
        {
            //TODO create line3d
            const Line2D<Coordinate2d>& line = (boost::get<Line2D<Coordinate2d> >(_geometry));
            _bounds = boost::geometry::return_envelope<Box2D<double> >(line);
            break;
        }
        case 5:
        {
            Polygon& pol = (boost::get<Polygon >(_geometry));
            _bounds = boost::geometry::return_envelope<Box2D<double> >(pol);
        }

        case 6:
        case 7:
            return Box2D<double>();
        }
    }
    return _bounds;
}

IlwisTypes Geometry::ilwisType() const {
    switch(_geometry.which()){
    case 0:
    case 1:
    case 2:
        return itPOINT;
    case 3:
    case 4:
        return itLINE;
    case 5:
    case 6:
        return itPOLYGON;
    }
    return itUNKNOWN;
}
<commit_msg>bounds is now initialized to a invalid valid instead of to a 0 (but valid) value<commit_after>#include <QStringList>
#include "ilwis.h"
#include "angle.h"
#include "point.h"
#include "box.h"
#include "line.h"
#include <type_traits>
#include <boost/geometry.hpp>
#include "polygon.h"
#include "geometry.h"

using namespace Ilwis;

Geometry::Geometry(const GeometryType& geom) : _geometry(geom), _bounds(Coordinate2d(rUNDEF, rUNDEF), Coordinate2d(rUNDEF, rUNDEF)){

}

bool Geometry::isValid() const {
    //TODO
    return true;
}

Box2D<double> Geometry::envelope() const{
    if (!_bounds.isValid()) {
        return const_cast<Geometry *>(this)->envelope();
    }
    return _bounds;
}

Box2D<double> Geometry::envelope() {
    if (!_bounds.isValid()) {
        switch(_geometry.which()){
        case 0:
        {
            Point2D<double> p = (boost::get<Point2D<> >(_geometry));
            _bounds = Box2D<double>(p,p);
            break;
        }
        case 1:
        {
            Point3D<double> p = (boost::get<Point2D<double> >(_geometry));
            _bounds =  Box2D<double>(p,p);
            break;
        }
        case 2:
        {
            Point3D<double> p = (boost::get<Point3D<double> >(_geometry));
            _bounds =  Box2D<double>(p,p);
            break;
        }
        case 3:
        {
            const Line2D<Coordinate2d>& line = (boost::get<Line2D<Coordinate2d> >(_geometry));
            _bounds = boost::geometry::return_envelope<Box2Dd>(line);
            break;
        }
        case 4:
        {
            //TODO create line3d
            const Line2D<Coordinate2d>& line = (boost::get<Line2D<Coordinate2d> >(_geometry));
            _bounds = boost::geometry::return_envelope<Box2D<double> >(line);
            break;
        }
        case 5:
        {
            Polygon& pol = (boost::get<Polygon >(_geometry));
            _bounds = boost::geometry::return_envelope<Box2D<double> >(pol);
        }

        case 6:
        case 7:
            return Box2D<double>();
        }
    }
    return _bounds;
}

IlwisTypes Geometry::ilwisType() const {
    switch(_geometry.which()){
    case 0:
    case 1:
    case 2:
        return itPOINT;
    case 3:
    case 4:
        return itLINE;
    case 5:
    case 6:
        return itPOLYGON;
    }
    return itUNKNOWN;
}
<|endoftext|>


<commit_before>/*
	Conrad 'Condzi' Kubacki 2017
	https://github.com/condzi
*/

#pragma once

#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderTexture.hpp>

#include <Core/components/Script.hpp>
#include <Core/components/Drawable.hpp>
#include <Core/ecs/Entity.hpp>

namespace con
{
	/*
	===============================================================================
	Created by: Condzi
		Not inheritable. Simple draws given text (set DrawableTextScript::textToDraw
		pointer to some sf::Text value from resourceCache).

	===============================================================================
	*/
	struct DrawableTextScript final :
		ScriptComponent
	{
		sf::RenderTexture texture;
		sf::Sprite* spriteToRender = nullptr;
		sf::Text* textToDraw = nullptr;

		void Init() override
		{
			// Try to set sprite. If DrawableTextScript is added before DrawableComponent we are accepting it to fail.
			this->setSpriteToRender( false );
		}

		void Update() override
		{
			if ( !this->spriteToRender )
				this->setSpriteToRender( true );
			if ( !this->textToDraw )
			{
				LOG( "Text to draw for DrawableTextScript is not set", WARNING, CONSOLE );
				return;
			}

			if ( this->previousText == this->textToDraw->getString() )
				return;

			this->previousText = this->textToDraw->getString();

			this->texture.create( static_cast<uint32_t>( this->textToDraw->getGlobalBounds().width ), static_cast<uint32_t>( this->textToDraw->getGlobalBounds().height * 2 ) );
			this->texture.clear( sf::Color::Transparent );
			this->texture.draw( *this->textToDraw );
			this->texture.display();

			// POSSIBLE_ERROR: Maybe use here that magic offset formula for text bounds from prototype code
			this->spriteToRender->setTextureRect( { 0,0, static_cast<int>( this->textToDraw->getGlobalBounds().width ), static_cast<int>( this->textToDraw->getGlobalBounds().height * 2 ) } );
			this->spriteToRender->setTexture( this->texture.getTexture() );
		}

	private:
		// Keep track of text - if previous text is different from current textToDraw's then recreate texture.
		sf::String previousText = "";

		void setSpriteToRender( bool testAssert )
		{
			if ( testAssert )
				CON_ASSERT( this->entity->HasComponent<DrawableComponent>(), "Entity with DrawableTextScript must have DrawableComponent" );

			if ( !testAssert && !this->entity->HasComponent<DrawableComponent>() )
				return;

			auto& drawableComponent = this->entity->GetComponent<DrawableComponent>();
			this->spriteToRender = &drawableComponent.sprite;
		}
	};
}<commit_msg>fix drawable text bug<commit_after>/*
	Conrad 'Condzi' Kubacki 2017
	https://github.com/condzi
*/

#pragma once

#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderTexture.hpp>

#include <Core/components/Script.hpp>
#include <Core/components/Drawable.hpp>
#include <Core/ecs/Entity.hpp>

#include <Core/Config.hpp>

namespace con
{
	/*
	===============================================================================
	Created by: Condzi
		Not inheritable. Simple draws given text (set DrawableTextScript::textToDraw
		pointer to some sf::Text value from resourceCache).

	===============================================================================
	*/
	struct DrawableTextScript final :
		ScriptComponent
	{
		sf::RenderTexture texture;
		sf::Sprite* spriteToRender = nullptr;
		sf::Text* textToDraw = nullptr;

		void Init() override
		{
			// Try to set sprite. If DrawableTextScript is added before DrawableComponent we are accepting it to fail.
			this->setSpriteToRender( false );
		}

		void Update() override
		{
			if ( !this->spriteToRender )
				this->setSpriteToRender( true );
			if ( !this->textToDraw )
			{
				LOG( "Text to draw for DrawableTextScript is not set", WARNING, CONSOLE );
				return;
			}

			if ( this->previousText == this->textToDraw->getString() )
				return;

			this->previousText = this->textToDraw->getString();

			this->texture.create( static_cast<uint32_t>( this->textToDraw->getGlobalBounds().width ), static_cast<uint32_t>( this->textToDraw->getGlobalBounds().height * 2 ) );
			this->textToDraw->setPosition( 0, 0 );
			this->texture.clear( sf::Color::Transparent );
			this->texture.draw( *this->textToDraw );
			this->texture.display();

			this->spriteToRender->setTexture( this->texture.getTexture(), true );
		}

	private:
		// Keep track of text - if previous text is different from current textToDraw's then recreate texture.
		sf::String previousText = "";

		void setSpriteToRender( bool testAssert )
		{
			if ( testAssert )
				CON_ASSERT( this->entity->HasComponent<DrawableComponent>(), "Entity with DrawableTextScript must have DrawableComponent" );

			if ( !testAssert && !this->entity->HasComponent<DrawableComponent>() )
				return;

			auto& drawableComponent = this->entity->GetComponent<DrawableComponent>();
			this->spriteToRender = &drawableComponent.sprite;
		}
	};
}<|endoftext|>


<commit_before>#include "MyModel.h"
#include "RandomNumberGenerator.h"
#include "Utils.h"
#include <cmath>

using namespace std;
using namespace DNest3;

MyModel::MyModel()
:num_layers(3)
,num_neurons(num_layers)
,weights()
{
	// Input layer
	num_neurons[0] = 1;

	// Hidden layer
	num_neurons[1] = 10;

	// Output layer
	num_neurons[2] = 1;

	// Weights
	for(int i=0; i<(num_layers - 1); i++)
		weights.push_back(RJObject<MyDistribution>(1, num_neurons[i]*num_neurons[i+1], true, MyDistribution()));
}

void MyModel::fromPrior()
{
	for(size_t i=0; i<weights.size(); i++)
		weights[i].fromPrior();
}

double MyModel::perturb()
{
	double logH = 0.;

	int which = randInt(weights.size());
	logH += weights[which].perturb();

	return logH;
}

double MyModel::logLikelihood() const
{
	return 0.;
}

vector<double> MyModel::compute_output(const vector<double>& input) const
{
	return vector<double>();
}

void MyModel::print(std::ostream& out) const
{
	// Activity

//	weights.print(out);
}

string MyModel::description() const
{
	return string("");
}

<commit_msg>Activities<commit_after>#include "MyModel.h"
#include "RandomNumberGenerator.h"
#include "Utils.h"
#include <cmath>

using namespace std;
using namespace DNest3;

MyModel::MyModel()
:num_layers(3)
,num_neurons(num_layers)
,weights()
{
	// Input layer
	num_neurons[0] = 100;

	// Hidden layer
	num_neurons[1] = 10;

	// Output layer
	num_neurons[2] = 1;

	// Weights
	for(int i=0; i<(num_layers - 1); i++)
		weights.push_back(RJObject<MyDistribution>(1, num_neurons[i]*num_neurons[i+1], true, MyDistribution()));
}

void MyModel::fromPrior()
{
	for(size_t i=0; i<weights.size(); i++)
		weights[i].fromPrior();
}

double MyModel::perturb()
{
	double logH = 0.;

	int which = randInt(weights.size());
	logH += weights[which].perturb();

	return logH;
}

double MyModel::logLikelihood() const
{
	return 0.;
}

vector<double> MyModel::compute_output(const vector<double>& input) const
{
	vector< vector<double> > output(num_layers);
	output[0] = input;

	// Compute each layer (except input layer)
	for(int i=1; i<num_layers; i++)
	{
		const vector< vector<double> >& components = weights[i-1].get_components();

		// Calculate activations for this layer
		output[i].assign(num_neurons[i], 0.);
		for(int j=0; j<num_neurons[i]; j++)
		{
			for(int k=0; k<num_neurons[i-1]; k++)
				output[i][j] += components[j*num_neurons[i-1] + k][0]*output[i-1][k];
			output[i][j] = tanh(output[i][j]);
		}
	}

	return output.back();
}

void MyModel::print(std::ostream& out) const
{
	vector<double> input(101);
	for(int i=0; i<101; i++)
		input[i] = 0.01*i;

	vector<double> output = compute_output(input);
	for(size_t i=0; i<output.size(); i++)
		out<<output[i]<<' ';
}

string MyModel::description() const
{
	return string("");
}

<|endoftext|>


<commit_before>#include "Network.h"
#include <stdio.h>
#include<vector>

Network::Network() {
    init();
}

void Network::init() {
    for (int i = 0; i < num_cities; i++) {
        cities[i] = City(i);
        for (int j = 0; j < num_cities; j++) {
            adjacency_table[i][j] = false;
        }
    }
}

Network::~Network() {}

void Network::addPath(int a, int b) {
    changePath(a, b, true);
}

void Network::destroyNode(int n) {
    for (int i = 0; i < num_cities; i++) {
        changePath(n, i, false);
    }
}

void Network::changePath(int a, int b, bool value) {
    adjacency_table[a][b] = b;
    adjacency_table[b][a] = b;
}

// Crec que hauria de funcionar, no n'estic gens segur per aixo haha
bool Network::isValidPath(std::vector<int> path) {
    bool adj_table[num_cities][num_cities];
    memcpy(adj_table, adjacency_table, sizeof(adjacency_table));

    int previous = path[0];
    std::vector<int>::iterator it = path.begin(); it++;
    for (; it != path.end(); it++) {
        if (adj_table[*it][previous] == true) {
            changePath(*it, previous, false);
            previous = *it;
        }
        else {
            return false;
        }
    }
    return true;
}

// Tampoc tinc molt clar si funcionara, estava parlant de kung fu
std::vector<int> Network::getNeighbours(int id) {
    std::vector<int> yoloswag;

    for (int i = 0; i < num_cities; i++) {
        if (adjacency_table[id][i] == true) {
            yoloswag.push_back(i);
        }
    }

    return yoloswag;
}<commit_msg>#include <multiplatform2.0><commit_after>#include"Network.h"
#include<string.h>
#include<vector>

Network::Network() {
    init();
}

void Network::init() {
    for (int i = 0; i < num_cities; i++) {
        cities[i] = City(i);
        for (int j = 0; j < num_cities; j++) {
            adjacency_table[i][j] = false;
        }
    }
}

Network::~Network() {}

void Network::addPath(int a, int b) {
    changePath(a, b, true);
}

void Network::destroyNode(int n) {
    for (int i = 0; i < num_cities; i++) {
        changePath(n, i, false);
    }
}

void Network::changePath(int a, int b, bool value) {
    adjacency_table[a][b] = b;
    adjacency_table[b][a] = b;
}

// Crec que hauria de funcionar, no n'estic gens segur per aixo haha
bool Network::isValidPath(std::vector<int> path) {
    bool adj_table[num_cities][num_cities];
    memcpy(adj_table, adjacency_table, sizeof(adjacency_table));

    int previous = path[0];
    std::vector<int>::iterator it = path.begin(); it++;
    for (; it != path.end(); it++) {
        if (adj_table[*it][previous] == true) {
            changePath(*it, previous, false);
            previous = *it;
        }
        else {
            return false;
        }
    }
    return true;
}

// Tampoc tinc molt clar si funcionara, estava parlant de kung fu
std::vector<int> Network::getNeighbours(int id) {
    std::vector<int> yoloswag;

    for (int i = 0; i < num_cities; i++) {
        if (adjacency_table[id][i] == true) {
            yoloswag.push_back(i);
        }
    }

    return yoloswag;
}<|endoftext|>


<commit_before>class Solution {
public:
    /**
     * @param prices: Given an integer array
     * @return: Maximum profit
     */
    int maxProfit(vector<int> &prices) {
        if (prices.size() == 0) {
            return 0;
        }

        vector<int> profit(prices.size());
        int buy = 0;
        buy = prices[0];
        profit[0] = 0;
        for (int i = 1; i < prices.size(); i++) {
            profit[i] = max(profit[i - 1], prices[i] - buy);
            buy = min(buy, prices[i]);
        }

        int sell = prices[prices.size() - 1];
        int best = 0;
        for (int i = prices.size() - 2; i >= 0; i--) {
            best = max(best, sell - prices[i] + profit[i]);
            sell = max(sell, prices[i]);
        }

        return best;
    }
};<commit_msg>AC 151<commit_after>class Solution {
public:
    /**
     * @param prices: Given an integer array
     * @return: Maximum profit
     */
    int maxProfit(vector<int> &prices) {
        if (prices.size() == 0) {
            return 0;
        }

        vector<int> profit(prices.size());
        int buy = 0;
        buy = prices[0];
        profit[0] = 0;

        //from the left
        for (int i = 1; i < prices.size(); i++) {
            profit[i] = max(profit[i - 1], prices[i] - buy);
            buy = min(buy, prices[i]);
        }

        //from the right

        int sell = prices[prices.size() - 1];
        int best = 0;
        for (int i = prices.size() - 2; i >= 0; i--) {
            best = max(best, sell - prices[i] + profit[i]);
            sell = max(sell, prices[i]);
        }

        return best;
    }
};<|endoftext|>


<commit_before>class Solution {
public:
    /**
     * @param x the base number
     * @param n the power number
     * @return the result
     */
    double myPow(double x, int n) {
        // Write your code here
        double rt_x=1;
        if (x==0) return 0;
        int i,j;

        for (i=0;i<n;i++){
        	rt_x *= rt_x;
        }

        return rt_x;
    }
};<commit_msg>Fixed the bug<commit_after>class Solution {
public:
    /**
     * @param x the base number
     * @param n the power number
     * @return the result
     */
    double myPow(double x, int n) {
        // Write your code here
        double rt_x=1;
        if (x==0) return 0;
        int i,j;

        for (i=0;i<n;i++){
        	rt_x *= x;
        }

        return rt_x;
    }
};<|endoftext|>


<commit_before>#include <ignition/math/Pose3.hh>
#include "gazebo/physics/physics.hh"
#include "gazebo/common/common.hh"
#include "gazebo/gazebo.hh"

#include <ros/ros.h>
#include <boost/bind/bind.hpp>
#include <tf2_msgs/TFMessage.h>

#include <tf/transform_listener.h>

#include <boost/thread.hpp>

namespace gazebo
{

struct tokens: std::ctype<char>
{
    tokens(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        typedef std::ctype<char> cctype;
        static const cctype::mask *const_rc= cctype::classic_table();

        static cctype::mask rc[cctype::table_size];
        std::memcpy(rc, const_rc, cctype::table_size * sizeof(cctype::mask));

        rc[','] = std::ctype_base::space;
        rc[' '] = std::ctype_base::space;
        return &rc[0];
    }
};

typedef struct
{
    physics::WorldPtr parentWorld;
    std::vector<std::string> phantoms;
    tf::TransformListener listener;
}tPhantomContext;

tPhantomContext PhantomContext;

class LabPhantoms;
void onTFData2(const tf2_msgs::TFMessage::ConstPtr& msg);
void onTFData(const tf2_msgs::TFMessage::ConstPtr& msg);//, LabPhantoms *plugin);

math::Pose Msg2Pose(geometry_msgs::Transform const& msg)
{
    math::Pose pose;
    math::Vector3 v;
    math::Quaternion q;

    v.x = msg.translation.x;
    v.y = msg.translation.y;
    v.z = msg.translation.z;
    q.w = msg.rotation.w;
    q.x = msg.rotation.x;
    q.y = msg.rotation.y;
    q.z = msg.rotation.z;

    pose.Set(v, q);
    return pose;
}

math::Pose StampedTransform2Pose(tf::StampedTransform const& transform)
{
    tf::Vector3 vt = transform.getOrigin();
    tf::Quaternion qt = transform.getRotation();
    math::Vector3 v;
    math::Quaternion q;

    v.x = vt.x();
    v.y = vt.y();
    v.z = vt.z();
    /*SUPER DIRTY HAXX*/
    if(0.755 > v.z)
        v.z = 0.755;
    q.w = qt.w();
    q.x = qt.x();
    q.y = qt.y();
    q.z = qt.z();

    math::Pose pose;
    pose.Set(v, q);
    return pose;
}

class LabPhantoms : public WorldPlugin
{
  protected:
  bool havePhantom(std::string const& name)
  {
      bool retq = false;
      int maxK = phantoms.size();
      for(int k = 0; (!retq) && (k < maxK); k++)
          retq = (phantoms[k] == name);
      return retq;
  }

  public:
  LabPhantoms()
  {
      n = 0;
      parentWorld.reset();
  }
  ~LabPhantoms()
  {
      running = false;
      if(n)
          delete n;
  }

  void monitorTFThread(void)
  {
      ros::Rate rate(0.5);
      while(running)
      {
          physics::WorldPtr world = parentWorld;
          std::vector<std::string> phantomsL = phantoms;
          tf::TransformListener listenerL;

          int maxK = phantomsL.size();

          listenerL.waitForTransform("bottle_250ml_0_frame", "/map", ros::Time::now(), ros::Duration(5.0));
          for(int k = 0; k < maxK; k++)
          {
              std::string childFrame = "/";
              childFrame += phantomsL[k] + "_frame";

              tf::StampedTransform transform;
              try
              {
                  ros::Time now = ros::Time::now();
                  listenerL.lookupTransform("/map", childFrame, ros::Time(), transform);

                  if(phantomsL[k] == "pipette_accumax")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "PIPETTE TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "bottle_250ml")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "BOTTLE_250ML TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "mixer_ikamag")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "MIXER_IKAMAG TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "flask_400ml_0")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "FLASK_400ml_0 TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  physics::ModelPtr childModel = world->GetModel(phantomsL[k]);
                  if(childModel.get())
                  {
                      math::Pose world2Child = StampedTransform2Pose(transform);
                      childModel->SetWorldPose(world2Child);
                      childModel->SetStatic(true);
                      childModel->SetGravityMode(false);
                  }
              }
              catch (tf::TransformException ex)
              {
                  ROS_ERROR("%s", ex.what());
              }
          }
          rate.sleep();
      }
  }

  void onTFData(const tf2_msgs::TFMessageConstPtr& msg)
  {
      if(!(parentWorld.get()))
          return;
      physics::WorldPtr world = parentWorld;

      int maxK = msg->transforms.size();

      for(int k = 0; k < maxK; k++)
      {
          geometry_msgs::TransformStamped transform = msg->transforms[k];
          std::string parentFrame = transform.header.frame_id;
          std::string childFrame = transform.child_frame_id;

          /*DIRTY HAXXXXX TO BE REMOVED.*/
          if("in_r_gripper_tool_frame" == parentFrame)
              parentFrame = "r_gripper_tool_frame";
          if("in_l_gripper_tool_frame" == parentFrame)
              parentFrame = "l_gripper_tool_frame";

          if(havePhantom(childFrame))
          {
              physics::ModelPtr childModel = world->GetModel(childFrame);
              physics::ModelPtr parentModel = world->GetModel(parentFrame);

              if((childModel.get()) && (parentModel.get()))
              {
                  math::Pose parent2Child = Msg2Pose(transform.transform);
                  math::Pose world2Parent = parentModel->GetWorldPose();
                  childModel->SetWorldPose(parent2Child*world2Parent);
              }
          }
      }
  }

  void Load(physics::WorldPtr _parent, sdf::ElementPtr _sdf)
  {
    parentWorld = _parent;
    pluginParameters = _sdf;
    char nodeName[] = "labphantoms";
    char* argv[] = {nodeName};
    int argc = 1;
    ros::init(argc, argv, "labphantoms");
    n = new ros::NodeHandle();

    //ros::Subscriber sub = n->subscribe("/tf", 1, &LabPhantoms::onTFData, this);

    if(pluginParameters->HasElement("trackedModels"))
    {
        std::string trackedModels = pluginParameters->Get<std::string>("trackedModels");
        std::string dbgStr = "Tracked Models as given by launch file: ";
        dbgStr = dbgStr + trackedModels;
        std::cerr << dbgStr << "\n";

        std::stringstream ss(trackedModels);
        ss.imbue(std::locale(std::locale(), new tokens()));
        std::istream_iterator<std::string> begin(ss);
        std::istream_iterator<std::string> end;
        std::vector<std::string> vstrings(begin, end);
        std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cerr, "\n"));
        phantoms = vstrings;
    }

    running = true;
    boost::thread(&LabPhantoms::monitorTFThread, this);
  }

  protected:
    bool running;
    ros::NodeHandle *n;
    physics::WorldPtr parentWorld;
    sdf::ElementPtr pluginParameters;
    std::vector<std::string> phantoms;
    tf::TransformListener listener;
};

// Register this plugin with the simulator
GZ_REGISTER_WORLD_PLUGIN(LabPhantoms)
}
<commit_msg>Undid a dirty hack.<commit_after>#include <ignition/math/Pose3.hh>
#include "gazebo/physics/physics.hh"
#include "gazebo/common/common.hh"
#include "gazebo/gazebo.hh"

#include <ros/ros.h>
#include <boost/bind/bind.hpp>
#include <tf2_msgs/TFMessage.h>

#include <tf/transform_listener.h>

#include <boost/thread.hpp>

namespace gazebo
{

struct tokens: std::ctype<char>
{
    tokens(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        typedef std::ctype<char> cctype;
        static const cctype::mask *const_rc= cctype::classic_table();

        static cctype::mask rc[cctype::table_size];
        std::memcpy(rc, const_rc, cctype::table_size * sizeof(cctype::mask));

        rc[','] = std::ctype_base::space;
        rc[' '] = std::ctype_base::space;
        return &rc[0];
    }
};

typedef struct
{
    physics::WorldPtr parentWorld;
    std::vector<std::string> phantoms;
    tf::TransformListener listener;
}tPhantomContext;

tPhantomContext PhantomContext;

class LabPhantoms;
void onTFData2(const tf2_msgs::TFMessage::ConstPtr& msg);
void onTFData(const tf2_msgs::TFMessage::ConstPtr& msg);//, LabPhantoms *plugin);

math::Pose Msg2Pose(geometry_msgs::Transform const& msg)
{
    math::Pose pose;
    math::Vector3 v;
    math::Quaternion q;

    v.x = msg.translation.x;
    v.y = msg.translation.y;
    v.z = msg.translation.z;
    q.w = msg.rotation.w;
    q.x = msg.rotation.x;
    q.y = msg.rotation.y;
    q.z = msg.rotation.z;

    pose.Set(v, q);
    return pose;
}

math::Pose StampedTransform2Pose(tf::StampedTransform const& transform)
{
    tf::Vector3 vt = transform.getOrigin();
    tf::Quaternion qt = transform.getRotation();
    math::Vector3 v;
    math::Quaternion q;

    v.x = vt.x();
    v.y = vt.y();
    v.z = vt.z();
    /*SUPER DIRTY HAXX*/
    if(0.755 > v.z)
        v.z = 0.755;
    q.w = qt.w();
    q.x = qt.x();
    q.y = qt.y();
    q.z = qt.z();

    math::Pose pose;
    pose.Set(v, q);
    return pose;
}

class LabPhantoms : public WorldPlugin
{
  protected:
  bool havePhantom(std::string const& name)
  {
      bool retq = false;
      int maxK = phantoms.size();
      for(int k = 0; (!retq) && (k < maxK); k++)
          retq = (phantoms[k] == name);
      return retq;
  }

  public:
  LabPhantoms()
  {
      n = 0;
      parentWorld.reset();
  }
  ~LabPhantoms()
  {
      running = false;
      if(n)
          delete n;
  }

  void monitorTFThread(void)
  {
      ros::Rate rate(0.5);
      while(running)
      {
          physics::WorldPtr world = parentWorld;
          std::vector<std::string> phantomsL = phantoms;
          tf::TransformListener listenerL;

          int maxK = phantomsL.size();

          listenerL.waitForTransform("bottle_250ml_0_frame", "/map", ros::Time::now(), ros::Duration(3.0));
          for(int k = 0; k < maxK; k++)
          {
              std::string childFrame = "/";
              childFrame += phantomsL[k] + "_frame";

              tf::StampedTransform transform;
              try
              {
                  ros::Time now = ros::Time::now();
                  listenerL.lookupTransform("/map", childFrame, ros::Time(), transform);

                  if(phantomsL[k] == "pipette_accumax")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "PIPETTE TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "bottle_250ml")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "BOTTLE_250ML TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "mixer_ikamag")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "MIXER_IKAMAG TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "flask_400ml_0")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "FLASK_400ml_0 TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  physics::ModelPtr childModel = world->GetModel(phantomsL[k]);
                  if(childModel.get())
                  {
                      math::Pose world2Child = StampedTransform2Pose(transform);
                      childModel->SetWorldPose(world2Child);
                      childModel->SetStatic(true);
                      childModel->SetGravityMode(false);
                  }
              }
              catch (tf::TransformException ex)
              {
                  ROS_ERROR("%s", ex.what());
              }
          }
          rate.sleep();
      }
  }

  void onTFData(const tf2_msgs::TFMessageConstPtr& msg)
  {
      if(!(parentWorld.get()))
          return;
      physics::WorldPtr world = parentWorld;

      int maxK = msg->transforms.size();

      for(int k = 0; k < maxK; k++)
      {
          geometry_msgs::TransformStamped transform = msg->transforms[k];
          std::string parentFrame = transform.header.frame_id;
          std::string childFrame = transform.child_frame_id;

          /*DIRTY HAXXXXX TO BE REMOVED.*/
          if("in_r_gripper_tool_frame" == parentFrame)
              parentFrame = "r_gripper_tool_frame";
          if("in_l_gripper_tool_frame" == parentFrame)
              parentFrame = "l_gripper_tool_frame";

          if(havePhantom(childFrame))
          {
              physics::ModelPtr childModel = world->GetModel(childFrame);
              physics::ModelPtr parentModel = world->GetModel(parentFrame);

              if((childModel.get()) && (parentModel.get()))
              {
                  math::Pose parent2Child = Msg2Pose(transform.transform);
                  math::Pose world2Parent = parentModel->GetWorldPose();
                  childModel->SetWorldPose(parent2Child*world2Parent);
              }
          }
      }
  }

  void Load(physics::WorldPtr _parent, sdf::ElementPtr _sdf)
  {
    parentWorld = _parent;
    pluginParameters = _sdf;
    char nodeName[] = "labphantoms";
    char* argv[] = {nodeName};
    int argc = 1;
    ros::init(argc, argv, "labphantoms");
    n = new ros::NodeHandle();

    //ros::Subscriber sub = n->subscribe("/tf", 1, &LabPhantoms::onTFData, this);

    if(pluginParameters->HasElement("trackedModels"))
    {
        std::string trackedModels = pluginParameters->Get<std::string>("trackedModels");
        std::string dbgStr = "Tracked Models as given by launch file: ";
        dbgStr = dbgStr + trackedModels;
        std::cerr << dbgStr << "\n";

        std::stringstream ss(trackedModels);
        ss.imbue(std::locale(std::locale(), new tokens()));
        std::istream_iterator<std::string> begin(ss);
        std::istream_iterator<std::string> end;
        std::vector<std::string> vstrings(begin, end);
        std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cerr, "\n"));
        phantoms = vstrings;
    }

    running = true;
    boost::thread(&LabPhantoms::monitorTFThread, this);
  }

  protected:
    bool running;
    ros::NodeHandle *n;
    physics::WorldPtr parentWorld;
    sdf::ElementPtr pluginParameters;
    std::vector<std::string> phantoms;
    tf::TransformListener listener;
};

// Register this plugin with the simulator
GZ_REGISTER_WORLD_PLUGIN(LabPhantoms)
}
<|endoftext|>


<commit_before>
#include <utest.hpp>
#include <test.hpp>

int
main(void)
{
	int rc = 0;

	lib_active();
	std::cout << "Hello World!" << std::endl;

	return rc;
}//main()

<commit_msg>some initialzer tests<commit_after>
#include <utest.hpp>
#include <test.hpp>

typedef struct bar {
    int       a;
    int       b;
    long long c;
} bar_t;

typedef enum why {
    zero,
    one,
    two,
    three,
    four
} why_t;

void
test_init(void)
{
    bar_t b = {1};
    why_t w = {};
    //why_t w = {two};

	std::cout << "Here!" << std::endl;
	std::cout << w << std::endl;
    return;
} //test_init()

int
main(void)
{
	int rc = 0;

	lib_active();
	std::cout << "Hello World!" << std::endl;

    test_init();

	return rc;
}//main()

<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include "CTRStatsServlet.h"
#include "CTRCounter.h"
#include "fnord-base/Language.h"
#include "fnord-base/wallclock.h"
#include "fnord-base/io/fileutil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/SSTableScan.h"

using namespace fnord;

namespace cm {

CTRStatsServlet::CTRStatsServlet(VFS* vfs) : vfs_(vfs) {}

void CTRStatsServlet::handleHTTPRequest(
    http::HTTPRequest* req,
    http::HTTPResponse* res) {
  URI uri(req->uri());
  const auto& params = uri.queryParams();

  Set<String> test_groups;
  Set<String> device_types;
  Set<String> pages;
  auto end_time = WallClock::unixMicros();
  auto start_time = end_time - 30 * kMicrosPerDay;

  /* arguments */
  String customer;
  if (!URI::getParam(params, "customer", &customer)) {
    res->addBody("error: missing ?customer=... parameter");
    res->setStatus(http::kStatusBadRequest);
    return;
  }

  String lang_str;
  if (!URI::getParam(params, "lang", &lang_str)) {
    res->addBody("error: missing ?lang=... parameter");
    res->setStatus(http::kStatusBadRequest);
    return;
  }

  for (const auto& p : params) {
    if (p.first == "from") {
      start_time = std::stoul(p.second) * kMicrosPerSecond;
      continue;
    }

    if (p.first == "until") {
      end_time = std::stoul(p.second) * kMicrosPerSecond;
      continue;
    }

    if (p.first == "test_group") {
      test_groups.emplace(p.second);
      continue;
    }

    if (p.first == "device_type") {
      device_types.emplace(p.second);
      continue;
    }

    if (p.first == "page_type") {
      pages.emplace(p.second);
      continue;
    }

  }

  if (test_groups.size() == 0) {
    test_groups.emplace("all");
  }

  if (device_types.size() == 0) {
    device_types = Set<String> { "unknown", "desktop", "tablet", "phone" };
  }

  /* prepare prefix filters for scanning */
  String scan_common_prefix = lang_str + "~";
  if (test_groups.size() == 1) {
    scan_common_prefix += *test_groups.begin() + "~";

    if (device_types.size() == 1) {
      scan_common_prefix += *device_types.begin() + "~";

      if (pages.size() == 1) {
        scan_common_prefix += *pages.begin();
      }
    }
  }

  /* scan input tables */
  HashMap<uint64_t, CTRCounterData> counters;
  CTRCounterData aggr_counter;
  for (uint64_t i = end_time; i >= start_time; i -= kMicrosPerDay) {
    auto tbl = StringUtil::format(
        "$0_ctr_stats_daily.$1.sstable",
        customer,
        i / kMicrosPerDay);

    if (!vfs_->exists(tbl)) {
      continue;
    }

    sstable::SSTableReader reader(vfs_->openFile(tbl));
    if (reader.bodySize() == 0 || reader.isFinalized() == 0) {
      continue;
    }

    sstable::SSTableScan scan;
    scan.setKeyPrefix(scan_common_prefix);

    auto& ctr_ref = counters[i];
    auto cursor = reader.getCursor();
    scan.execute(cursor.get(), [&] (const Vector<String> row) {
      if (row.size() != 2) {
        RAISEF(kRuntimeError, "invalid row length: $0", row.size());
      }

      auto dims = StringUtil::split(row[0], "~");
      if (dims.size() != 4) {
        RAISEF(kRuntimeError, "invalid row key: $0", row[0]);
      }

      if (dims[0] != lang_str) {
        return;
      }

      if (test_groups.count(dims[1]) == 0) {
        return;
      }

      if (device_types.count(dims[2]) == 0) {
        return;
      }

      if (pages.size() > 0 && pages.count(dims[3]) == 0) {
        return;
      }

      auto counter = CTRCounterData::load(row[1]);
      ctr_ref.merge(counter);
      aggr_counter.merge(counter);
    });
  }

  /* write response */
  res->setStatus(http::kStatusOK);
  res->addHeader("Content-Type", "application/json; charset=utf-8");
  json::JSONOutputStream json(res->getBodyOutputStream());

  json.beginObject();
  json.addObjectEntry("aggregate");

  json.beginObject();
  json.addObjectEntry("views");
  json.addInteger(aggr_counter.num_views);
  json.addComma();
  json.addObjectEntry("clicks");
  json.addInteger(aggr_counter.num_clicks);
  json.addComma();
  json.addObjectEntry("ctr");
  json.addFloat(aggr_counter.num_clicks / (double) aggr_counter.num_views);
  json.addComma();
  json.addObjectEntry("cpq");
  json.addFloat(aggr_counter.num_clicked / (double) aggr_counter.num_views);
  json.endObject();

  json.addComma();
  json.addObjectEntry("timeseries");
  json.beginArray();
  int n = 0;
  for (const auto& c : counters) {
    if (++n > 1) {
      json.addComma();
    }

    json.beginObject();
    json.addObjectEntry("time");
    json.addInteger(c.first);
    json.addComma();
    json.addObjectEntry("views");
    json.addInteger(c.second.num_views);
    json.addComma();
    json.addObjectEntry("clicks");
    json.addInteger(c.second.num_clicks);
    json.addComma();
    json.addObjectEntry("ctr");
    json.addFloat(c.second.num_clicks / (double) c.second.num_views);
    json.addComma();
    json.addObjectEntry("cpq");
    json.addFloat(c.second.num_clicked / (double) c.second.num_views);
    json.endObject();
  }

  json.endArray();
  json.endObject();
}

}
<commit_msg>return all requested day counters<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include "CTRStatsServlet.h"
#include "CTRCounter.h"
#include "fnord-base/Language.h"
#include "fnord-base/wallclock.h"
#include "fnord-base/io/fileutil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/SSTableScan.h"

using namespace fnord;

namespace cm {

CTRStatsServlet::CTRStatsServlet(VFS* vfs) : vfs_(vfs) {}

void CTRStatsServlet::handleHTTPRequest(
    http::HTTPRequest* req,
    http::HTTPResponse* res) {
  URI uri(req->uri());
  const auto& params = uri.queryParams();

  Set<String> test_groups;
  Set<String> device_types;
  Set<String> pages;
  auto end_time = WallClock::unixMicros();
  auto start_time = end_time - 30 * kMicrosPerDay;

  /* arguments */
  String customer;
  if (!URI::getParam(params, "customer", &customer)) {
    res->addBody("error: missing ?customer=... parameter");
    res->setStatus(http::kStatusBadRequest);
    return;
  }

  String lang_str;
  if (!URI::getParam(params, "lang", &lang_str)) {
    res->addBody("error: missing ?lang=... parameter");
    res->setStatus(http::kStatusBadRequest);
    return;
  }

  for (const auto& p : params) {
    if (p.first == "from") {
      start_time = std::stoul(p.second) * kMicrosPerSecond;
      continue;
    }

    if (p.first == "until") {
      end_time = std::stoul(p.second) * kMicrosPerSecond;
      continue;
    }

    if (p.first == "test_group") {
      test_groups.emplace(p.second);
      continue;
    }

    if (p.first == "device_type") {
      device_types.emplace(p.second);
      continue;
    }

    if (p.first == "page_type") {
      pages.emplace(p.second);
      continue;
    }

  }

  if (test_groups.size() == 0) {
    test_groups.emplace("all");
  }

  if (device_types.size() == 0) {
    device_types = Set<String> { "unknown", "desktop", "tablet", "phone" };
  }

  /* prepare prefix filters for scanning */
  String scan_common_prefix = lang_str + "~";
  if (test_groups.size() == 1) {
    scan_common_prefix += *test_groups.begin() + "~";

    if (device_types.size() == 1) {
      scan_common_prefix += *device_types.begin() + "~";

      if (pages.size() == 1) {
        scan_common_prefix += *pages.begin();
      }
    }
  }

  /* scan input tables */
  HashMap<uint64_t, CTRCounterData> counters;
  CTRCounterData aggr_counter;
  for (uint64_t i = end_time; i >= start_time; i -= kMicrosPerDay) {
    auto& ctr_ref = counters[i];
    auto tbl = StringUtil::format(
        "$0_ctr_stats_daily.$1.sstable",
        customer,
        i / kMicrosPerDay);

    if (!vfs_->exists(tbl)) {
      continue;
    }

    sstable::SSTableReader reader(vfs_->openFile(tbl));
    if (reader.bodySize() == 0 || reader.isFinalized() == 0) {
      continue;
    }

    sstable::SSTableScan scan;
    scan.setKeyPrefix(scan_common_prefix);

    auto cursor = reader.getCursor();
    scan.execute(cursor.get(), [&] (const Vector<String> row) {
      if (row.size() != 2) {
        RAISEF(kRuntimeError, "invalid row length: $0", row.size());
      }

      auto dims = StringUtil::split(row[0], "~");
      if (dims.size() != 4) {
        RAISEF(kRuntimeError, "invalid row key: $0", row[0]);
      }

      if (dims[0] != lang_str) {
        return;
      }

      if (test_groups.count(dims[1]) == 0) {
        return;
      }

      if (device_types.count(dims[2]) == 0) {
        return;
      }

      if (pages.size() > 0 && pages.count(dims[3]) == 0) {
        return;
      }

      auto counter = CTRCounterData::load(row[1]);
      ctr_ref.merge(counter);
      aggr_counter.merge(counter);
    });
  }

  /* write response */
  res->setStatus(http::kStatusOK);
  res->addHeader("Content-Type", "application/json; charset=utf-8");
  json::JSONOutputStream json(res->getBodyOutputStream());

  json.beginObject();
  json.addObjectEntry("aggregate");

  json.beginObject();
  json.addObjectEntry("views");
  json.addInteger(aggr_counter.num_views);
  json.addComma();
  json.addObjectEntry("clicks");
  json.addInteger(aggr_counter.num_clicks);
  json.addComma();
  json.addObjectEntry("ctr");
  json.addFloat(aggr_counter.num_clicks / (double) aggr_counter.num_views);
  json.addComma();
  json.addObjectEntry("cpq");
  json.addFloat(aggr_counter.num_clicked / (double) aggr_counter.num_views);
  json.endObject();

  json.addComma();
  json.addObjectEntry("timeseries");
  json.beginArray();
  int n = 0;
  for (const auto& c : counters) {
    if (++n > 1) {
      json.addComma();
    }

    json.beginObject();
    json.addObjectEntry("time");
    json.addInteger(c.first);
    json.addComma();
    json.addObjectEntry("views");
    json.addInteger(c.second.num_views);
    json.addComma();
    json.addObjectEntry("clicks");
    json.addInteger(c.second.num_clicks);
    json.addComma();
    json.addObjectEntry("ctr");
    json.addFloat(c.second.num_clicks / (double) c.second.num_views);
    json.addComma();
    json.addObjectEntry("cpq");
    json.addFloat(c.second.num_clicked / (double) c.second.num_views);
    json.endObject();
  }

  json.endArray();
  json.endObject();
}

}
<|endoftext|>


<commit_before>#pragma once

#include <algorithm>
#include <utility>
#include <memory>
#include <string>
#include <vector>
#include <uv.h>
#include "handle.hpp"
#include "stream.hpp"
#include "util.hpp"
#include "loop.hpp"

namespace uvw {

namespace details {

enum class UVProcessFlags: std::underlying_type_t<uv_process_flags> {
    SETUID = UV_PROCESS_SETUID,
    SETGID = UV_PROCESS_SETGID,
    WINDOWS_VERBATIM_ARGUMENTS = UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
    DETACHED = UV_PROCESS_DETACHED,
    WINDOWS_HIDE = UV_PROCESS_WINDOWS_HIDE
};

enum class UVStdIOFlags: std::underlying_type_t<uv_stdio_flags> {
    IGNORE_STREAM = UV_IGNORE,
    CREATE_PIPE = UV_CREATE_PIPE,
    INHERIT_FD = UV_INHERIT_FD,
    INHERIT_STREAM = UV_INHERIT_STREAM,
    READABLE_PIPE = UV_READABLE_PIPE,
    WRITABLE_PIPE = UV_WRITABLE_PIPE
};

}

/**
 * @brief ExitEvent event.
 *
 * It will be emitted by ProcessHandle according with its functionalities.
 */
struct ExitEvent {
    explicit ExitEvent(int64_t code, int sig) noexcept
        : status{code}, signal{sig}
    {}

    int64_t status; /*!< The exit status. */
    int signal; /*!< The signal that caused the process to terminate, if any. */
};

/**
 * @brief The ProcessHandle handle.
 *
 * Process handles will spawn a new process and allow the user to control it and
 * establish communication channels with it using streams.
 */
class ProcessHandle final: public Handle<ProcessHandle, uv_process_t> {
    static void exitCallback(uv_process_t *handle, int64_t exitStatus, int termSignal) {
        ProcessHandle &process = *(static_cast<ProcessHandle*>(handle->data));
        process.publish(ExitEvent{exitStatus, termSignal});
    }

public:
    using Process = details::UVProcessFlags;
    using StdIO = details::UVStdIOFlags;

    ProcessHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref)
        : Handle{std::move(ca), std::move(ref)}, poFdStdio{1}
    {
        // stdin container default initialization
        poFdStdio[0].flags = static_cast<uv_stdio_flags>(StdIO::IGNORE_STREAM);
    }

    /**
     * @brief Disables inheritance for file descriptors/handles.
     *
     * Disables inheritance for file descriptors/handles that this process
     * inherited from its parent. The effect is that child processes spawned by
     * this process don’t accidentally inherit these handles.

     * It is recommended to call this function as early in your program as
     * possible, before the inherited file descriptors can be closed or
     * duplicated.
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_disable_stdio_inheritance)
     * for further details.
     */
    static void disableStdIOInheritance() noexcept {
        uv_disable_stdio_inheritance();
    }

    /**
     * @brief kill Sends the specified signal to the given PID.
     * @param pid A valid process id.
     * @param signum A valid signal identifier.
     * @return True in case of success, false otherwise.
     */
    static bool kill(int pid, int signum) noexcept {
        return (0 == uv_kill(pid, signum));
    }

    /**
     * @brief Initializes the handle.
     * @return True in case of success, false otherwise.
     */
    bool init() const noexcept { return true; }

    /**
     * @brief spawn Starts the process.
     *
     * If the process isn't successfully spawned, an ErrorEvent event will be
     * emitted by the handle.
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html)
     * for further details.
     *
     * @param file Path pointing to the program to be executed.
     * @param args Command line arguments.
     * @param env Optional environment for the new process.
     */
    void spawn(const char *file, char **args, char **env = nullptr) {
        uv_process_options_t po;

        po.exit_cb = &exitCallback;

        po.file = file;
        po.args = args;
        po.env = env;
        po.cwd = poCwd.empty() ? nullptr : poCwd.data();
        po.flags = poFlags;
        po.uid = poUid;
        po.gid = poGid;

        /**
         * See the constructor, poFdStdio[0] is stdin. It must be poStdio[0] by
         * convention. From the official documentation:
         *
         * > The convention is that stdio[0] points to stdin, fd 1 is used
         * > for stdout, and fd 2 is stderr.
         */
        po.stdio_count = poStreamStdio.size() + poFdStdio.size();
        uv_stdio_container_t stdio[po.stdio_count];
        std::copy(poFdStdio.cbegin(), poFdStdio.cend(), stdio);
        std::copy(poStreamStdio.cbegin(), poStreamStdio.cend(), stdio + poFdStdio.size());
        po.stdio = stdio;

        invoke(&uv_spawn, parent(), get(), &po);
    }

    /**
     * @brief Sends the specified signal to the internal process handle.
     * @param signum A valid signal identifier.
     */
    void kill(int signum) {
        invoke(&uv_process_kill, get(), signum);
    }

    /**
     * @brief Gets the PID of the spawned process.
     *
     * It’s set after calling `spawn()`.
     *
     * @return The PID of the spawned process.
     */
    int pid() noexcept {
        return get()->pid;
    }

    /**
     * @brief Sets the current working directory for the subprocess.
     * @param path The working directory to be used when `spawn()` is invoked.
     * @return A reference to this process handle.
     */
    ProcessHandle& cwd(std::string &path) noexcept {
        poCwd = path;
        return *this;
    }

    /**
     * @brief Sets flags that control how `spawn()` behaves.
     *
     * Available flags are:
     *
     * * `ProcessHandle::Process::SETUID`
     * * `ProcessHandle::Process::SETGID`
     * * `ProcessHandle::Process::WINDOWS_VERBATIM_ARGUMENTS`
     * * `ProcessHandle::Process::DETACHED`
     * * `ProcessHandle::Process::WINDOWS_HIDE`
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_process_flags)
     * for further details.
     *
     * @param flags A valid set of flags.
     * @return A reference to this process handle.
     */
    ProcessHandle& flags(Flags<Process> flags) noexcept {
        poFlags = flags;
        return *this;
    }

    /**
     * @brief Makes a `stdio` handle available to the child process.
     *
     * Available flags are:
     *
     * * `ProcessHandle::StdIO::IGNORE_STREAM`
     * * `ProcessHandle::StdIO::CREATE_PIPE`
     * * `ProcessHandle::StdIO::INHERIT_FD`
     * * `ProcessHandle::StdIO::INHERIT_STREAM`
     * * `ProcessHandle::StdIO::READABLE_PIPE`
     * * `ProcessHandle::StdIO::WRITABLE_PIPE`
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_stdio_flags)
     * for further details.
     *
     * @param stream A valid `stdio` handle.
     * @param flags A valid set of flags.
     * @return A reference to this process handle.
     */
    template<typename T, typename U>
    ProcessHandle& stdio(StreamHandle<T, U> &stream, Flags<StdIO> flags) {
        uv_stdio_container_t container;
        Flags<StdIO>::Type fgs = flags;
        container.flags = static_cast<uv_stdio_flags>(fgs);
        container.data.stream = get<uv_stream_t>(stream);
        poStreamStdio.push_back(std::move(container));
        return *this;
    }

    /**
     * @brief Makes a file descriptor available to the child process.
     *
     * Available flags are:
     *
     * * `ProcessHandle::StdIO::IGNORE_STREAM`
     * * `ProcessHandle::StdIO::CREATE_PIPE`
     * * `ProcessHandle::StdIO::INHERIT_FD`
     * * `ProcessHandle::StdIO::INHERIT_STREAM`
     * * `ProcessHandle::StdIO::READABLE_PIPE`
     * * `ProcessHandle::StdIO::WRITABLE_PIPE`
     *
     * Default file descriptors are:
     *     * `uvw::StdIN` for `stdin`
     *     * `uvw::StdOUT` for `stdout`
     *     * `uvw::StdERR` for `stderr`
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_stdio_flags)
     * for further details.
     *
     * @param fd A valid file descriptor.
     * @param flags A valid set of flags.
     * @return A reference to this process handle.
     */
    ProcessHandle& stdio(FileHandle fd, Flags<StdIO> flags) {
        auto fgs = static_cast<uv_stdio_flags>(Flags<StdIO>::Type{flags});

        auto actual = FileHandle::Type{fd};

        if(actual == FileHandle::Type{StdIN}) {
            poFdStdio[0].flags = fgs;
        } else {
            auto it = std::find_if(poFdStdio.begin(), poFdStdio.end(), [actual](auto &&container){
                return container.data.fd == actual;
            });

            if(it == poFdStdio.cend()) {
                uv_stdio_container_t container;
                container.flags = fgs;
                container.data.fd = actual;
                poFdStdio.push_back(std::move(container));
            } else {
                it->flags = fgs;
                it->data.fd = actual;
            }
        }

        return *this;
    }

    /**
     * @brief Sets the child process' user id.
     * @param id A valid user id to be used.
     * @return A reference to this process handle.
     */
    ProcessHandle& uid(Uid id) {
        poUid = id;
        return *this;
    }

    /**
     * @brief Sets the child process' group id.
     * @param id A valid group id to be used.
     * @return A reference to this process handle.
     */
    ProcessHandle& gid(Gid id) {
        poGid = id;
        return *this;
    }

private:
    std::string poCwd;
    Flags<Process> poFlags;
    std::vector<uv_stdio_container_t> poFdStdio;
    std::vector<uv_stdio_container_t> poStreamStdio;
    Uid poUid;
    Gid poGid;
};

}
<commit_msg>accomodating window requirements...<commit_after>#pragma once

#include <algorithm>
#include <utility>
#include <memory>
#include <string>
#include <vector>
#include <uv.h>
#include "handle.hpp"
#include "stream.hpp"
#include "util.hpp"
#include "loop.hpp"

namespace uvw {

namespace details {

enum class UVProcessFlags: std::underlying_type_t<uv_process_flags> {
    SETUID = UV_PROCESS_SETUID,
    SETGID = UV_PROCESS_SETGID,
    WINDOWS_VERBATIM_ARGUMENTS = UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
    DETACHED = UV_PROCESS_DETACHED,
    WINDOWS_HIDE = UV_PROCESS_WINDOWS_HIDE
};

enum class UVStdIOFlags: std::underlying_type_t<uv_stdio_flags> {
    IGNORE_STREAM = UV_IGNORE,
    CREATE_PIPE = UV_CREATE_PIPE,
    INHERIT_FD = UV_INHERIT_FD,
    INHERIT_STREAM = UV_INHERIT_STREAM,
    READABLE_PIPE = UV_READABLE_PIPE,
    WRITABLE_PIPE = UV_WRITABLE_PIPE
};

}

/**
 * @brief ExitEvent event.
 *
 * It will be emitted by ProcessHandle according with its functionalities.
 */
struct ExitEvent {
    explicit ExitEvent(int64_t code, int sig) noexcept
        : status{code}, signal{sig}
    {}

    int64_t status; /*!< The exit status. */
    int signal; /*!< The signal that caused the process to terminate, if any. */
};

/**
 * @brief The ProcessHandle handle.
 *
 * Process handles will spawn a new process and allow the user to control it and
 * establish communication channels with it using streams.
 */
class ProcessHandle final: public Handle<ProcessHandle, uv_process_t> {
    static void exitCallback(uv_process_t *handle, int64_t exitStatus, int termSignal) {
        ProcessHandle &process = *(static_cast<ProcessHandle*>(handle->data));
        process.publish(ExitEvent{exitStatus, termSignal});
    }

public:
    using Process = details::UVProcessFlags;
    using StdIO = details::UVStdIOFlags;

    ProcessHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref)
        : Handle{std::move(ca), std::move(ref)}, poFdStdio{1}
    {
        // stdin container default initialization
        poFdStdio[0].flags = static_cast<uv_stdio_flags>(StdIO::IGNORE_STREAM);
    }

    /**
     * @brief Disables inheritance for file descriptors/handles.
     *
     * Disables inheritance for file descriptors/handles that this process
     * inherited from its parent. The effect is that child processes spawned by
     * this process don’t accidentally inherit these handles.

     * It is recommended to call this function as early in your program as
     * possible, before the inherited file descriptors can be closed or
     * duplicated.
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_disable_stdio_inheritance)
     * for further details.
     */
    static void disableStdIOInheritance() noexcept {
        uv_disable_stdio_inheritance();
    }

    /**
     * @brief kill Sends the specified signal to the given PID.
     * @param pid A valid process id.
     * @param signum A valid signal identifier.
     * @return True in case of success, false otherwise.
     */
    static bool kill(int pid, int signum) noexcept {
        return (0 == uv_kill(pid, signum));
    }

    /**
     * @brief Initializes the handle.
     * @return True in case of success, false otherwise.
     */
    bool init() const noexcept { return true; }

    /**
     * @brief spawn Starts the process.
     *
     * If the process isn't successfully spawned, an ErrorEvent event will be
     * emitted by the handle.
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html)
     * for further details.
     *
     * @param file Path pointing to the program to be executed.
     * @param args Command line arguments.
     * @param env Optional environment for the new process.
     */
    void spawn(const char *file, char **args, char **env = nullptr) {
        uv_process_options_t po;

        po.exit_cb = &exitCallback;

        po.file = file;
        po.args = args;
        po.env = env;
        po.cwd = poCwd.empty() ? nullptr : poCwd.data();
        po.flags = poFlags;
        po.uid = poUid;
        po.gid = poGid;

        /**
         * See the constructor, poFdStdio[0] is stdin. It must be poStdio[0] by
         * convention. From the official documentation:
         *
         * > The convention is that stdio[0] points to stdin, fd 1 is used
         * > for stdout, and fd 2 is stderr.
         */
        std::vector<uv_stdio_container_t> poStdio{poFdStdio.size() + poStreamStdio.size()};
        poStdio.insert(poStdio.begin(), poStreamStdio.cbegin(), poStreamStdio.cend());
        poStdio.insert(poStdio.begin(), poFdStdio.cbegin(), poFdStdio.cend());
        po.stdio_count = poStdio.size();
        po.stdio = poStdio.data();

        invoke(&uv_spawn, parent(), get(), &po);
    }

    /**
     * @brief Sends the specified signal to the internal process handle.
     * @param signum A valid signal identifier.
     */
    void kill(int signum) {
        invoke(&uv_process_kill, get(), signum);
    }

    /**
     * @brief Gets the PID of the spawned process.
     *
     * It’s set after calling `spawn()`.
     *
     * @return The PID of the spawned process.
     */
    int pid() noexcept {
        return get()->pid;
    }

    /**
     * @brief Sets the current working directory for the subprocess.
     * @param path The working directory to be used when `spawn()` is invoked.
     * @return A reference to this process handle.
     */
    ProcessHandle& cwd(std::string &path) noexcept {
        poCwd = path;
        return *this;
    }

    /**
     * @brief Sets flags that control how `spawn()` behaves.
     *
     * Available flags are:
     *
     * * `ProcessHandle::Process::SETUID`
     * * `ProcessHandle::Process::SETGID`
     * * `ProcessHandle::Process::WINDOWS_VERBATIM_ARGUMENTS`
     * * `ProcessHandle::Process::DETACHED`
     * * `ProcessHandle::Process::WINDOWS_HIDE`
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_process_flags)
     * for further details.
     *
     * @param flags A valid set of flags.
     * @return A reference to this process handle.
     */
    ProcessHandle& flags(Flags<Process> flags) noexcept {
        poFlags = flags;
        return *this;
    }

    /**
     * @brief Makes a `stdio` handle available to the child process.
     *
     * Available flags are:
     *
     * * `ProcessHandle::StdIO::IGNORE_STREAM`
     * * `ProcessHandle::StdIO::CREATE_PIPE`
     * * `ProcessHandle::StdIO::INHERIT_FD`
     * * `ProcessHandle::StdIO::INHERIT_STREAM`
     * * `ProcessHandle::StdIO::READABLE_PIPE`
     * * `ProcessHandle::StdIO::WRITABLE_PIPE`
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_stdio_flags)
     * for further details.
     *
     * @param stream A valid `stdio` handle.
     * @param flags A valid set of flags.
     * @return A reference to this process handle.
     */
    template<typename T, typename U>
    ProcessHandle& stdio(StreamHandle<T, U> &stream, Flags<StdIO> flags) {
        uv_stdio_container_t container;
        Flags<StdIO>::Type fgs = flags;
        container.flags = static_cast<uv_stdio_flags>(fgs);
        container.data.stream = get<uv_stream_t>(stream);
        poStreamStdio.push_back(std::move(container));
        return *this;
    }

    /**
     * @brief Makes a file descriptor available to the child process.
     *
     * Available flags are:
     *
     * * `ProcessHandle::StdIO::IGNORE_STREAM`
     * * `ProcessHandle::StdIO::CREATE_PIPE`
     * * `ProcessHandle::StdIO::INHERIT_FD`
     * * `ProcessHandle::StdIO::INHERIT_STREAM`
     * * `ProcessHandle::StdIO::READABLE_PIPE`
     * * `ProcessHandle::StdIO::WRITABLE_PIPE`
     *
     * Default file descriptors are:
     *     * `uvw::StdIN` for `stdin`
     *     * `uvw::StdOUT` for `stdout`
     *     * `uvw::StdERR` for `stderr`
     *
     * See the official
     * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_stdio_flags)
     * for further details.
     *
     * @param fd A valid file descriptor.
     * @param flags A valid set of flags.
     * @return A reference to this process handle.
     */
    ProcessHandle& stdio(FileHandle fd, Flags<StdIO> flags) {
        auto fgs = static_cast<uv_stdio_flags>(Flags<StdIO>::Type{flags});

        auto actual = FileHandle::Type{fd};

        if(actual == FileHandle::Type{StdIN}) {
            poFdStdio[0].flags = fgs;
        } else {
            auto it = std::find_if(poFdStdio.begin(), poFdStdio.end(), [actual](auto &&container){
                return container.data.fd == actual;
            });

            if(it == poFdStdio.cend()) {
                uv_stdio_container_t container;
                container.flags = fgs;
                container.data.fd = actual;
                poFdStdio.push_back(std::move(container));
            } else {
                it->flags = fgs;
                it->data.fd = actual;
            }
        }

        return *this;
    }

    /**
     * @brief Sets the child process' user id.
     * @param id A valid user id to be used.
     * @return A reference to this process handle.
     */
    ProcessHandle& uid(Uid id) {
        poUid = id;
        return *this;
    }

    /**
     * @brief Sets the child process' group id.
     * @param id A valid group id to be used.
     * @return A reference to this process handle.
     */
    ProcessHandle& gid(Gid id) {
        poGid = id;
        return *this;
    }

private:
    std::string poCwd;
    Flags<Process> poFlags;
    std::vector<uv_stdio_container_t> poFdStdio;
    std::vector<uv_stdio_container_t> poStreamStdio;
    Uid poUid;
    Gid poGid;
};

}
<|endoftext|>