<commit_before>/*
 * Quantum++
 *
 * Copyright (c) 2013 - 2014 Vlad Gheorghiu (vgheorgh@gmail.com)
 *
 * This file is part of Quantum++.
 *
 * Quantum++ 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.
 *
 * Quantum++ 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 Quantum++.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qpp.h"

// #include "MATLAB/matlab.h" // support for MATLAB

using namespace qpp;

int main()
{
    // Qudit Teleportation
    {
        std::size_t D = 3; // size of the system
        std::cout << std::endl << "**** Qudit Teleportation, D = " << D << " ****" << std::endl;
        ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
        for (std::size_t i = 0; i < D; i++)
            mes_AB += mket({i, i}, D);
        mes_AB /= std::sqrt((double) D);
        // circuit that measures in the qudit Bell basis
        cmat Bell_aA = adjoint(gt.CTRL(gt.Xd(D), {0}, {1}, 2, D) * kron(gt.Fd(D), gt.Id(D)));
        ket psi_a = randket(D); // random state as input on a
        std::cout << ">> Initial state:" << std::endl;
        std::cout << disp(psi_a) << std::endl;
        ket input_aAB = kron(psi_a, mes_AB); // joint input state aAB
        // output before measurement
        ket output_aAB = apply(input_aAB, Bell_aA, {0, 1}, 3, D);
        auto measured_aA = measure(ptrace2(prj(output_aAB), {D * D, D}), gt.Id(D * D)); // measure on aA
        std::discrete_distribution<std::size_t> dd(measured_aA.first.begin(), measured_aA.first.end());
        std::cout << ">> Alice's measurement probabilities: ";
        std::cout << disp(measured_aA.first, ", ") << std::endl;
        std::size_t m = dd(rdevs._rng); // sample
        auto midx = n2multiidx(m, {D, D});
        std::cout << ">> Alice's measurement result: ";
        std::cout << disp(midx, " ") << std::endl;
        // conditional result on B before correction
        ket output_m_aAB = apply(output_aAB, prj(mket(midx, D)), {0, 1}, 3, D) / std::sqrt(measured_aA.first[m]);
        cmat correction_B = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]); // correction operator
        // apply correction on B
        output_aAB = apply(output_m_aAB, correction_B, {2}, 3, D);
        cmat rho_B = ptrace1(prj(output_aAB), {D * D, D});
        std::cout << ">> Bob's density operator: " << std::endl;
        std::cout << disp(rho_B) << std::endl;
        std::cout << ">> Norm difference: " << norm(rho_B - prj(psi_a)) << std::endl; // verification
    }

    // Qudit Dense Coding
    {
        std::size_t D = 3; // size of the system
        std::cout << std::endl << "**** Qudit Dense Coding, D = " << D << " ****" << std::endl;
        ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
        for (std::size_t i = 0; i < D; i++)
            mes_AB += mket({i, i}, D);
        mes_AB /= std::sqrt((double) D);
        // circuit that measures in the qudit Bell basis
        cmat Bell_AB = adjoint(gt.CTRL(gt.Xd(D), {0}, {1}, 2, D) * kron(gt.Fd(D), gt.Id(D)));
        // equal probabilities of choosing a message
        std::uniform_int_distribution<std::size_t> uid(0, D * D - 1);
        std::size_t m_A = uid(rdevs._rng); // sample, obtain the message index
        auto midx = n2multiidx(m_A, {D, D});
        std::cout << ">> Alice sent: ";
        std::cout << disp(midx, " ") << std::endl;
        // Alice's operation
        cmat U_A = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]);
        // Alice encodes the message
        ket psi_AB = apply(mes_AB, U_A, {0}, 2, D);
        // Bob measures the joint system in the qudit Bell basis
        psi_AB = apply(psi_AB, Bell_AB, {0, 1}, 2, D);
        auto measured = measure(psi_AB, gt.Id(D * D));
        std::cout << ">> Bob's measurement probabilities: ";
        std::cout << disp(measured.first, ", ") << std::endl;
        // Bob samples according to the measurement probabilities
        std::discrete_distribution<std::size_t> dd(measured.first.begin(), measured.first.end());
        std::size_t m_B = dd(rdevs._rng);
        std::cout << ">> Bob received: ";
        std::cout << disp(n2multiidx(m_B, {D, D}), " ") << std::endl;
    }

    // Grover's search algorithm, we time it
    {
        Timer t; // set a timer
        std::size_t n = 4; // number of qubits
        std::cout << std::endl << "**** Grover on n = " << n << " qubits ****" << std::endl;
        std::vector<std::size_t> dims(n, 2); // local dimensions
        std::size_t N = std::pow(2, n); // number of elements in the database
        std::cout << ">> Database size: " << N << std::endl;
        // mark an element randomly
        std::uniform_int_distribution<std::size_t> uid(0, N - 1);
        std::size_t marked = uid(rdevs._rng);
        std::cout << ">> Marked state: " << marked << " -> ";
        std::cout << disp(n2multiidx(marked, dims), " ") << std::endl;
        ket psi = mket(n2multiidx(0, dims)); // computational |0>^\otimes n
        psi = (kronpow(gt.H, n) * psi).eval(); // apply H^\otimes n, no aliasing
        cmat G = 2 * prj(psi) - gt.Id(N); // Diffusion operator
        // number of queries
        std::size_t nqueries = std::ceil(pi * std::sqrt(N) / 4.);
        std::cout << ">> We run " << nqueries << " queries" << std::endl;
        for (std::size_t i = 0; i < nqueries; i++)
        {
            psi(marked) = -psi(marked); // apply the oracle first, no aliasing
            psi = (G * psi).eval(); // then the diffusion operator, no aliasing
        }
        // we now measure the state in the computational basis
        auto measured = measure(psi, gt.Id(N));
        std::cout << ">> Probability of the marked state: " << measured.first[marked] << std::endl;
        std::cout << ">> Probability of all results: ";
        std::cout << disp(measured.first, ", ") << std::endl;
        std::cout << ">> Let's sample..." << std::endl;
        std::discrete_distribution<std::size_t> dd(measured.first.begin(), measured.first.end());
        std::size_t result = dd(rdevs._rng);
        if (result == marked)
            std::cout << ">> Hooray, we obtained the correct result: ";
        else
            std::cout << ">> Not there yet... we obtained: ";
        std::cout << result << " -> ";
        std::cout << disp(n2multiidx(result, dims), " ") << std::endl;
        // stop the timer and display it
        std::cout << ">> It took " << t.toc() << " seconds to simulate Grover on " << n << " qubits." << std::endl;
    }

    // Entanglement
    {
        std::cout << std::endl << "**** Entanglement ****" << std::endl;
        cmat rho = 0.2 * st.pb00 + 0.8 * st.pb11;
        std::cout << ">> rho: " << std::endl;
        std::cout << disp(rho) << std::endl;
        std::cout << ">> Concurrence of rho: " << concurrence(rho) << std::endl;
        std::cout << ">> Negativity of rho: " << negativity(rho, {2, 2}) << std::endl;
        std::cout << ">> Logarithimc negativity of rho: " << lognegativity(rho, {2, 2}) << std::endl;
        ket psi = 0.8 * mket({0, 0}) + 0.6 * mket({1, 1});
        // apply some local random unitaries
        psi = kron(randU(2), randU(2)) * psi;
        std::cout << ">> psi: " << std::endl;
        std::cout << disp(psi) << std::endl;
        std::cout << ">> Entanglement of psi: " << entanglement(psi, {2, 2}) << std::endl;
        std::cout << ">> Concurrence of psi: " << concurrence(prj(psi)) << std::endl;
        std::cout << ">> G-Concurrence of psi: " << gconcurrence(psi) << std::endl;
        std::cout << ">> Schmidt coefficients of psi: " << std::endl;
        std::cout << disp(schmidtcoeff(psi, {2, 2})) << std::endl;
        std::cout << ">> Schmidt probabilities of psi: " << std::endl;
        std::cout << disp(schmidtprob(psi, {2, 2})) << std::endl;
        cmat U = schmidtU(psi, {2, 2});
        cmat V = schmidtV(psi, {2, 2});
        std::cout << ">> Schmidt vectors on Alice's side: " << std::endl;
        std::cout << disp(U) << std::endl;
        std::cout << ">> Schmidt vectors on Bob's side: " << std::endl;
        std::cout << disp(V) << std::endl;
        std::cout << ">> State psi in the Schmidt basis: " << std::endl;
        std::cout << disp(adjoint(kron(U, V)) * psi) << std::endl;
        // reconstructed state
        ket psi_from_schmidt = schmidtcoeff(psi, {2, 2})(0) * kron(U.col(0), V.col(0)) +
                schmidtcoeff(psi, {2, 2})(1) * kron(U.col(1), V.col(1));
        std::cout << ">> State psi reconstructed from the Schmidt decomposition: " << std::endl;
        std::cout << disp(psi_from_schmidt) << std::endl;
        std::cout << ">> Norm difference: " << norm(psi - psi_from_schmidt) << std::endl;
    }

    // Quantum error correcting codes
    {
        std::cout << std::endl << "**** Quantum error correcting codes ****" << std::endl;
        ket a0 = codes.codeword(Codes::Type::FIVE_QUBIT, 0);
        ket a1 = codes.codeword(Codes::Type::FIVE_QUBIT, 1);
        ket b0 = codes.codeword(Codes::Type::SEVEN_QUBIT_STEANE, 0);
        ket b1 = codes.codeword(Codes::Type::SEVEN_QUBIT_STEANE, 1);
        ket c0 = codes.codeword(Codes::Type::NINE_QUBIT_SHOR, 0);
        ket c1 = codes.codeword(Codes::Type::NINE_QUBIT_SHOR, 1);
        std::cout << ">> Five qubit [[5, 1, 3]] code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> <0L | 1L> = ";
        std::cout << disp(adjoint(a0) * a1) << std::endl;
        std::cout << ">> Seven qubit [[7, 1, 3]] Steane code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> <0L | 1L> = ";
        std::cout << disp(adjoint(b0) * b1) << std::endl;
        std::cout << ">> Nine qubit [[9, 1, 3]] Shor code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> <0L | 1L> = ";
        std::cout << disp(adjoint(c0) * c1) << std::endl;
    }
}
<commit_msg>commit<commit_after>/*
 * Quantum++
 *
 * Copyright (c) 2013 - 2014 Vlad Gheorghiu (vgheorgh@gmail.com)
 *
 * This file is part of Quantum++.
 *
 * Quantum++ 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.
 *
 * Quantum++ 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 Quantum++.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qpp.h"

// #include "MATLAB/matlab.h" // support for MATLAB

using namespace qpp;

int main()
{
    // Qudit Teleportation
    {
        std::size_t D = 3; // size of the system
        std::cout << std::endl << "**** Qudit Teleportation, D = " << D << " ****" << std::endl;
        ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
        for (std::size_t i = 0; i < D; i++)
            mes_AB += mket({i, i}, D);
        mes_AB /= std::sqrt((double) D);
        // circuit that measures in the qudit Bell basis
        cmat Bell_aA = adjoint(gt.CTRL(gt.Xd(D), {0}, {1}, 2, D) * kron(gt.Fd(D), gt.Id(D)));
        ket psi_a = randket(D); // random state as input on a
        std::cout << ">> Initial state:" << std::endl;
        std::cout << disp(psi_a) << std::endl;
        ket input_aAB = kron(psi_a, mes_AB); // joint input state aAB
        // output before measurement
        ket output_aAB = apply(input_aAB, Bell_aA, {0, 1}, 3, D);
        auto measured_aA = measure(ptrace2(prj(output_aAB), {D * D, D}), gt.Id(D * D)); // measure on aA
        std::discrete_distribution<std::size_t> dd(measured_aA.first.begin(), measured_aA.first.end());
        std::cout << ">> Alice's measurement probabilities: ";
        std::cout << disp(measured_aA.first, ", ") << std::endl;
        std::size_t m = dd(rdevs._rng); // sample
        auto midx = n2multiidx(m, {D, D});
        std::cout << ">> Alice's measurement result: ";
        std::cout << disp(midx, " ") << std::endl;
        // conditional result on B before correction
        ket output_m_aAB = apply(output_aAB, prj(mket(midx, D)), {0, 1}, 3, D) / std::sqrt(measured_aA.first[m]);
        cmat correction_B = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]); // correction operator
        // apply correction on B
        output_aAB = apply(output_m_aAB, correction_B, {2}, 3, D);
        cmat rho_B = ptrace1(prj(output_aAB), {D * D, D});
        std::cout << ">> Bob's density operator: " << std::endl;
        std::cout << disp(rho_B) << std::endl;
        std::cout << ">> Norm difference: " << norm(rho_B - prj(psi_a)) << std::endl; // verification
    }

    // Qudit Dense Coding
    {
        std::size_t D = 3; // size of the system
        std::cout << std::endl << "**** Qudit Dense Coding, D = " << D << " ****" << std::endl;
        ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
        for (std::size_t i = 0; i < D; i++)
            mes_AB += mket({i, i}, D);
        mes_AB /= std::sqrt((double) D);
        // circuit that measures in the qudit Bell basis
        cmat Bell_AB = adjoint(gt.CTRL(gt.Xd(D), {0}, {1}, 2, D) * kron(gt.Fd(D), gt.Id(D)));
        // equal probabilities of choosing a message
        std::uniform_int_distribution<std::size_t> uid(0, D * D - 1);
        std::size_t m_A = uid(rdevs._rng); // sample, obtain the message index
        auto midx = n2multiidx(m_A, {D, D});
        std::cout << ">> Alice sent: ";
        std::cout << disp(midx, " ") << std::endl;
        // Alice's operation
        cmat U_A = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]);
        // Alice encodes the message
        ket psi_AB = apply(mes_AB, U_A, {0}, 2, D);
        // Bob measures the joint system in the qudit Bell basis
        psi_AB = apply(psi_AB, Bell_AB, {0, 1}, 2, D);
        auto measured = measure(psi_AB, gt.Id(D * D));
        std::cout << ">> Bob's measurement probabilities: ";
        std::cout << disp(measured.first, ", ") << std::endl;
        // Bob samples according to the measurement probabilities
        std::discrete_distribution<std::size_t> dd(measured.first.begin(), measured.first.end());
        std::size_t m_B = dd(rdevs._rng);
        std::cout << ">> Bob received: ";
        std::cout << disp(n2multiidx(m_B, {D, D}), " ") << std::endl;
    }

    // Grover's search algorithm, we time it
    {
        Timer t; // set a timer
        std::size_t n = 4; // number of qubits
        std::cout << std::endl << "**** Grover on n = " << n << " qubits ****" << std::endl;
        std::vector<std::size_t> dims(n, 2); // local dimensions
        std::size_t N = std::pow(2, n); // number of elements in the database
        std::cout << ">> Database size: " << N << std::endl;
        // mark an element randomly
        std::uniform_int_distribution<std::size_t> uid(0, N - 1);
        std::size_t marked = uid(rdevs._rng);
        std::cout << ">> Marked state: " << marked << " -> ";
        std::cout << disp(n2multiidx(marked, dims), " ") << std::endl;
        ket psi = mket(n2multiidx(0, dims)); // computational |0>^\otimes n
        psi = (kronpow(gt.H, n) * psi).eval(); // apply H^\otimes n, no aliasing
        cmat G = 2 * prj(psi) - gt.Id(N); // Diffusion operator
        // number of queries
        std::size_t nqueries = std::ceil(pi * std::sqrt(N) / 4.);
        std::cout << ">> We run " << nqueries << " queries" << std::endl;
        for (std::size_t i = 0; i < nqueries; i++)
        {
            psi(marked) = -psi(marked); // apply the oracle first, no aliasing
            psi = (G * psi).eval(); // then the diffusion operator, no aliasing
        }
        // we now measure the state in the computational basis
        auto measured = measure(psi, gt.Id(N));
        std::cout << ">> Probability of the marked state: " << measured.first[marked] << std::endl;
        std::cout << ">> Probability of all results: ";
        std::cout << disp(measured.first, ", ") << std::endl;
        std::cout << ">> Let's sample..." << std::endl;
        std::discrete_distribution<std::size_t> dd(measured.first.begin(), measured.first.end());
        std::size_t result = dd(rdevs._rng);
        if (result == marked)
            std::cout << ">> Hooray, we obtained the correct result: ";
        else
            std::cout << ">> Not there yet... we obtained: ";
        std::cout << result << " -> ";
        std::cout << disp(n2multiidx(result, dims), " ") << std::endl;
        // stop the timer and display it
        std::cout << ">> It took " << t.toc() << " seconds to simulate Grover on " << n << " qubits." << std::endl;
    }

    // Entanglement
    {
        std::cout << std::endl << "**** Entanglement ****" << std::endl;
        cmat rho = 0.2 * st.pb00 + 0.8 * st.pb11;
        std::cout << ">> rho: " << std::endl;
        std::cout << disp(rho) << std::endl;
        std::cout << ">> Concurrence of rho: " << concurrence(rho) << std::endl;
        std::cout << ">> Negativity of rho: " << negativity(rho, {2, 2}) << std::endl;
        std::cout << ">> Logarithimc negativity of rho: " << lognegativity(rho, {2, 2}) << std::endl;
        ket psi = 0.8 * mket({0, 0}) + 0.6 * mket({1, 1});
        // apply some local random unitaries
        psi = kron(randU(2), randU(2)) * psi;
        std::cout << ">> psi: " << std::endl;
        std::cout << disp(psi) << std::endl;
        std::cout << ">> Entanglement of psi: " << entanglement(psi, {2, 2}) << std::endl;
        std::cout << ">> Concurrence of psi: " << concurrence(prj(psi)) << std::endl;
        std::cout << ">> G-Concurrence of psi: " << gconcurrence(psi) << std::endl;
        std::cout << ">> Schmidt coefficients of psi: " << std::endl;
        std::cout << disp(schmidtcoeff(psi, {2, 2})) << std::endl;
        std::cout << ">> Schmidt probabilities of psi: " << std::endl;
        std::cout << disp(schmidtprob(psi, {2, 2})) << std::endl;
        cmat U = schmidtU(psi, {2, 2});
        cmat V = schmidtV(psi, {2, 2});
        std::cout << ">> Schmidt vectors on Alice's side: " << std::endl;
        std::cout << disp(U) << std::endl;
        std::cout << ">> Schmidt vectors on Bob's side: " << std::endl;
        std::cout << disp(V) << std::endl;
        std::cout << ">> State psi in the Schmidt basis: " << std::endl;
        std::cout << disp(adjoint(kron(U, V)) * psi) << std::endl;
        // reconstructed state
        ket psi_from_schmidt = schmidtcoeff(psi, {2, 2})(0) * kron(U.col(0), V.col(0)) +
                schmidtcoeff(psi, {2, 2})(1) * kron(U.col(1), V.col(1));
        std::cout << ">> State psi reconstructed from the Schmidt decomposition: " << std::endl;
        std::cout << disp(psi_from_schmidt) << std::endl;
        std::cout << ">> Norm difference: " << norm(psi - psi_from_schmidt) << std::endl;
    }

    // Quantum error correcting codes
    {
        std::cout << std::endl << "**** Quantum error correcting codes ****" << std::endl;
        ket a0 = codes.codeword(Codes::Type::FIVE_QUBIT, 0);
        ket a1 = codes.codeword(Codes::Type::FIVE_QUBIT, 1);
        ket b0 = codes.codeword(Codes::Type::SEVEN_QUBIT_STEANE, 0);
        ket b1 = codes.codeword(Codes::Type::SEVEN_QUBIT_STEANE, 1);
        ket c0 = codes.codeword(Codes::Type::NINE_QUBIT_SHOR, 0);
        ket c1 = codes.codeword(Codes::Type::NINE_QUBIT_SHOR, 1);
        std::cout << ">> [[5, 1, 3]] Five qubit code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> <0L | 1L> = ";
        std::cout << disp(adjoint(a0) * a1) << std::endl;
        std::cout << ">> [[7, 1, 3]] Seven qubit Steane code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> <0L | 1L> = ";
        std::cout << disp(adjoint(b0) * b1) << std::endl;
        std::cout << ">> [[9, 1, 3]] Nine qubit Shor code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> <0L | 1L> = ";
        std::cout << disp(adjoint(c0) * c1) << std::endl;
    }
}
<|endoftext|>


<commit_before>/*
 * UniversalContainer library.
 * Copyright Jason Denton, 2008,2010.
 * Made available under the new BSD license, as described in LICENSE
 *
 * Send comments and bug reports to jason.denton@gmail.com
 * http://www.greatpanic.com/code.html
 */

#include <iostream>

//The header univcont.h includes all the different pieces of the libuc library.
#include "univcont.h"

using namespace std;

//UniversalContainer and friends are in the JAD namespace
using namespace JAD;

void print_person(UniversalContainer& uc)
{
  string name = uc["name"];
  string age = uc["age"];
  char sex = uc["sex"];

  cout << name << '\t' << sex << '\t' << age << endl;
}

/*
  A simple example that declares a record holding the personal records
  of a solider and his family.
 */
int main(int argc, char** argv)
{

  try {
    UniversalContainer solider;

    //Note all the different types of primitives that can be assigned to
    //arbitrary keys.
    solider["name"] = "Kansas Smith";
    solider["age"] = 23;
    solider["officer"] = false;
    solider["serial"] = 789456;
    solider["sex"] = "M";
    solider["wage"] = 25.75;

    //We can easily nest UniversalContainers
    solider["spouse"]["name"] = "Sue Smith";
    solider["spouse"]["sex"] = "F";
    solider["spouse"]["age"] = "Won't Say";

    //Or have a container act as an array.
    //In this case, the key "dependants" maps to a UniversalContainer that is an array of
    //other UniversalContainers, which in turn have their own keys.
    solider["dependants"][0]["name"] = "Joe Smith";
    solider["dependants"][0]["age"] = 3;
    solider["dependants"][0]["sex"] = "M";
    solider["dependants"][1]["name"] = "Ann Smith";
    solider["dependants"][1]["age"] = 1;
    solider["dependants"][1]["sex"] = "F";
    solider["dependants"][2]["name"] = "On the way";

    cout << "NAME" << "\t\t" << "SEX" << "\t" << "AGE" << endl;
    print_person(solider);

    //A UC can be a map between strings and other UCs.
    print_person(solider["spouse"]);

    //We can loop through the array of dependants
    for (unsigned i = 0; i < solider["dependants"].size(); i++)
      print_person(solider["dependants"][i]);

    //Here is an example of using dot notation to get at nested elements
    cout << "The litte girls name is " <<
      (string)solider["dependants.1.name"] << endl;

    //Here we show how a container may be cast as the type it is holding
    double combat_pay = (double)solider["wage"] + 5.35;
    cout << "Combat pay is " << combat_pay << endl;

    //This is essential what the print statement does,
    //we show it here as an example of using the serializer code.
    Buffer* buf = uc_encode_ini(solider);
    write_from_buffer(buf,stdout);
    delete buf;

  }
  //We shouldn't ever be here, but if we are, the exception will contain
  //key/value pairs describing what went wrong.
  catch(UniversalContainer uce) {
    cout << "An exception was thrown." << endl;
    print(uce);
  }
}
<commit_msg>just include what is needed for example<commit_after>/*
 * UniversalContainer library.
 * Copyright Jason Denton, 2008,2010.
 * Made available under the new BSD license, as described in LICENSE
 *
 * Send comments and bug reports to jason.denton@gmail.com
 * http://www.greatpanic.com/code.html
 */

#include <iostream>

//The header univcont.h includes all the different pieces of the libuc library.
//#include "univcont.h"
#include "ucontainer.h"
#include "ucio.h"
#include "buffer.h"

using namespace std;

//UniversalContainer and friends are in the JAD namespace
using namespace JAD;

void print_person(UniversalContainer& uc)
{
  string name = uc["name"];
  string age = uc["age"];
  char sex = uc["sex"];

  cout << name << '\t' << sex << '\t' << age << endl;
}

/*
  A simple example that declares a record holding the personal records
  of a solider and his family.
 */
int main(int argc, char** argv)
{

  try {
    UniversalContainer solider;

    //Note all the different types of primitives that can be assigned to
    //arbitrary keys.
    solider["name"] = "Kansas Smith";
    solider["age"] = 23;
    solider["officer"] = false;
    solider["serial"] = 789456;
    solider["sex"] = "M";
    solider["wage"] = 25.75;

    //We can easily nest UniversalContainers
    solider["spouse"]["name"] = "Sue Smith";
    solider["spouse"]["sex"] = "F";
    solider["spouse"]["age"] = "Won't Say";

    //Or have a container act as an array.
    //In this case, the key "dependants" maps to a UniversalContainer that is an array of
    //other UniversalContainers, which in turn have their own keys.
    solider["dependants"][0]["name"] = "Joe Smith";
    solider["dependants"][0]["age"] = 3;
    solider["dependants"][0]["sex"] = "M";
    solider["dependants"][1]["name"] = "Ann Smith";
    solider["dependants"][1]["age"] = 1;
    solider["dependants"][1]["sex"] = "F";
    solider["dependants"][2]["name"] = "On the way";

    cout << "NAME" << "\t\t" << "SEX" << "\t" << "AGE" << endl;
    print_person(solider);

    //A UC can be a map between strings and other UCs.
    print_person(solider["spouse"]);

    //We can loop through the array of dependants
    for (unsigned i = 0; i < solider["dependants"].size(); i++)
      print_person(solider["dependants"][i]);

    //Here is an example of using dot notation to get at nested elements
    cout << "The litte girls name is " <<
      (string)solider["dependants.1.name"] << endl;

    //Here we show how a container may be cast as the type it is holding
    double combat_pay = (double)solider["wage"] + 5.35;
    cout << "Combat pay is " << combat_pay << endl;

    //This is essential what the print statement does,
    //we show it here as an example of using the serializer code.
    Buffer* buf = uc_encode_ini(solider);
    write_from_buffer(buf,stdout);
    delete buf;

  }
  //We shouldn't ever be here, but if we are, the exception will contain
  //key/value pairs describing what went wrong.
  catch(UniversalContainer uce) {
    cout << "An exception was thrown." << endl;
    print(uce);
  }
}
<|endoftext|>


<commit_before>#include <cthun-agent/agent.hpp>
#include <cthun-agent/errors.hpp>
#include <cthun-agent/file_utils.hpp>
#include <cthun-agent/configuration.hpp>

#define LEATHERMAN_LOGGING_NAMESPACE "puppetlabs.cthun_agent.main"
#include <leatherman/logging/logging.hpp>

#include <fstream>

#include <horsewhisperer/horsewhisperer.h>

namespace CthunAgent {

namespace HW = HorseWhisperer;

int startAgent(std::vector<std::string> arguments) {
    std::string logfile { HW::GetFlag<std::string>("logfile") };
    std::ofstream file_stream;

    if (!logfile.empty()) {
        file_stream.open(logfile);
        leatherman::logging::setup_logging(file_stream);
    } else {
        leatherman::logging::setup_logging(std::cout);
        leatherman::logging::set_colorization(true);
    }

    switch (HW::GetFlag<int>("vlevel")) {
        case 0:
            leatherman::logging::set_level(leatherman::logging::log_level::info);
            break;
        case 1:
            leatherman::logging::set_level(leatherman::logging::log_level::debug);
            break;
        case 2:
            leatherman::logging::set_level(leatherman::logging::log_level::trace);
            break;
        default:
            leatherman::logging::set_level(leatherman::logging::log_level::trace);
    }

    try {
        Agent agent { Configuration::Instance().get<std::string>("modules-dir"),
                      Configuration::Instance().get<std::string>("server"),
                      Configuration::Instance().get<std::string>("ca"),
                      Configuration::Instance().get<std::string>("cert"),
                      Configuration::Instance().get<std::string>("key"),
                      Configuration::Instance().get<std::string>("spool-dir") };

        agent.start();
    } catch (fatal_error& e) {
        LOG_ERROR("fatal error: %1%", e.what());
        return 1;
    } catch (std::exception& e) {
        LOG_ERROR("unexpected error: %1%", e.what());
        return 1;
    } catch (...) {
        LOG_ERROR("unexpected error");
        return 1;
    }

    return 0;
}

int main(int argc, char *argv[]) {
    Configuration::Instance().setStartFunction(startAgent);

    HW::ParseResult parse_result;

    try {
        parse_result = Configuration::Instance().initialize(argc, argv);
    } catch (HW::flag_validation_error& e) {
        std::cout << "Invalid command line arguments:\n"
                  << e.what() << std::endl;
        return 1;
    } catch(configuration_error& e) {
        std::cout << "An error occurred while parsing your configuration.\n"
                  << e.what() << std::endl;
        return 1;
    }

    switch (parse_result) {
        case HW::ParseResult::OK:
            return HW::Start();
        case HW::ParseResult::HELP:
            HorseWhisperer::ShowHelp();
            return 0;
        case HW::ParseResult::VERSION:
            HorseWhisperer::ShowVersion();
            return 0;
        default:
            std::cout << "An unexpected code was returned when trying to parse"
                      << "command line arguments - "
                      << static_cast<int>(parse_result) << ". Aborting"
                      << std::endl;
            return 1;
    }
}

}  // namespace CthunAgent

int main(int argc, char** argv) {
    return CthunAgent::main(argc, argv);
}
<commit_msg>(CTH-263) Append log messages to logfile<commit_after>#include <cthun-agent/agent.hpp>
#include <cthun-agent/errors.hpp>
#include <cthun-agent/file_utils.hpp>
#include <cthun-agent/configuration.hpp>

#define LEATHERMAN_LOGGING_NAMESPACE "puppetlabs.cthun_agent.main"
#include <leatherman/logging/logging.hpp>

#include <fstream>

#include <horsewhisperer/horsewhisperer.h>

namespace CthunAgent {

namespace HW = HorseWhisperer;

int startAgent(std::vector<std::string> arguments) {
    std::string logfile { HW::GetFlag<std::string>("logfile") };
    std::ofstream file_stream;

    if (!logfile.empty()) {
        file_stream.open(logfile, std::ios_base::app);
        leatherman::logging::setup_logging(file_stream);
    } else {
        leatherman::logging::setup_logging(std::cout);
        leatherman::logging::set_colorization(true);
    }

    switch (HW::GetFlag<int>("vlevel")) {
        case 0:
            leatherman::logging::set_level(leatherman::logging::log_level::info);
            break;
        case 1:
            leatherman::logging::set_level(leatherman::logging::log_level::debug);
            break;
        case 2:
            leatherman::logging::set_level(leatherman::logging::log_level::trace);
            break;
        default:
            leatherman::logging::set_level(leatherman::logging::log_level::trace);
    }

    try {
        Agent agent { Configuration::Instance().get<std::string>("modules-dir"),
                      Configuration::Instance().get<std::string>("server"),
                      Configuration::Instance().get<std::string>("ca"),
                      Configuration::Instance().get<std::string>("cert"),
                      Configuration::Instance().get<std::string>("key"),
                      Configuration::Instance().get<std::string>("spool-dir") };

        agent.start();
    } catch (fatal_error& e) {
        LOG_ERROR("fatal error: %1%", e.what());
        return 1;
    } catch (std::exception& e) {
        LOG_ERROR("unexpected error: %1%", e.what());
        return 1;
    } catch (...) {
        LOG_ERROR("unexpected error");
        return 1;
    }

    return 0;
}

int main(int argc, char *argv[]) {
    Configuration::Instance().setStartFunction(startAgent);

    HW::ParseResult parse_result;

    try {
        parse_result = Configuration::Instance().initialize(argc, argv);
    } catch (HW::flag_validation_error& e) {
        std::cout << "Invalid command line arguments:\n"
                  << e.what() << std::endl;
        return 1;
    } catch(configuration_error& e) {
        std::cout << "An error occurred while parsing your configuration.\n"
                  << e.what() << std::endl;
        return 1;
    }

    switch (parse_result) {
        case HW::ParseResult::OK:
            return HW::Start();
        case HW::ParseResult::HELP:
            HorseWhisperer::ShowHelp();
            return 0;
        case HW::ParseResult::VERSION:
            HorseWhisperer::ShowVersion();
            return 0;
        default:
            std::cout << "An unexpected code was returned when trying to parse"
                      << "command line arguments - "
                      << static_cast<int>(parse_result) << ". Aborting"
                      << std::endl;
            return 1;
    }
}

}  // namespace CthunAgent

int main(int argc, char** argv) {
    return CthunAgent::main(argc, argv);
}
<|endoftext|>


<commit_before>/** **************************************************************************
 * Copyright (C) 2016 Adrien Devresse
 *
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 ** ***************************************************************************/
#ifndef MPI_CPP_MPI_HPP
#define MPI_CPP_MPI_HPP

#include <mpi.h>

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

namespace mpi {

class mpi_comm;
class mpi_scope_env;

/**
 * @brief mpi environment scoper
 *
 *  initialize MPI when constructed, finalize MPI when destroyed
 */
class mpi_scope_env : private boost::noncopyable{
public:
    inline mpi_scope_env(int* argc, char*** argv);

    inline virtual ~mpi_scope_env();

private:
    int initialized;
};

/**
 * @brief mpi communicator
 *
 * bridge to all the MPI functions
 */
class mpi_comm : private boost::noncopyable
{
public:

    class message_handle{
    public:
        inline message_handle();

        ///
        /// \brief get_tag
        /// \return tag associated to the message
        ///
        inline int tag() const;

        ///
        /// \brief get_rank
        /// \return rank of the sending node associated with the message
        ///
        inline int rank() const;

        ///
        /// \brief get_size
        /// \return number of elements of type T part of the message.
        ///  In case of T being a container ( vector, string ), get_size() return the number of container elements
        ///  part of the message
        ///
        template<typename T>
        inline std::size_t count() const;

        ///
        /// \brief test message_handle validity
        /// \return return true if message handle is valid, false if the probe operation has been aborted
        ///
        inline bool is_valid() const;

    private:
        MPI_Status _status;
        MPI_Message _msg;
        friend class mpi_comm;
    };

    /**
     * @brief mpi_comm
     *
     * construct an MPI communication channel
     *
     * MPI operation
     */

    inline mpi_comm();
    inline virtual ~mpi_comm();

    /**
     * @brief rank
     * @return mpi rank of the process
     */
    inline int rank() const{
        return _rank;
    }

    /**
     * @brief size
     * @return size of the mpi communication domain
     */
    inline int size() const{
        return _size;
    }

    /**
     * @brief isMaster
     * @return true if current node is root ( 0 )
     */
    inline bool is_master() const{
        return _rank ==0;
    }

    /// @brief synchronization barrier
    ///
    /// blocking until all the nodes reach it
    inline void barrier();

    /// send local_value to node dest
    /// @param local_value value to send
    /// @param dest node id of the reciver
    /// @param tag identity tag
    template <typename T>
    inline void send(const T & local_value, int dest_node, int tag);

    template <typename T>
    inline void send(const T * value, std::size_t n_value ,
                     int dest_node, int tag);

    /// check for incoming messages, without actual receipt of them
    /// @param src_node node of the sender
    /// @param tag identity tag of the message
    /// @return messange_handle associated with the incoming message.
    ///         It muse be used with recv(message_handle) to recv the associated
    ///         message
    inline message_handle probe(int src_node, int tag);

    ///
    /// check for incoming messages, without actual receipt of them
    /// if not message are received after a specified time, the function
    /// return an invalid message_handle that need to be tested with
    /// message_handle::is_valid()
    ///
    /// \param src_node node of the sender
    /// \param tag tag of the message
    /// \param us_time time in micro seconds
    /// \return message_handle, validity test is necessary
    ///
    inline message_handle probe(int src_node, int tag, std::size_t us_time);

    /// received data from an other node
    /// @param src node id of the sender
    /// @param tag identity tag
    /// @return value received
    template <typename T>
    inline void recv(int src_node, int tag, T & value);

    template <typename T>
    inline void recv(const message_handle & handle, T & value);

    template <typename T>
    inline void recv(int src_node, int tag, T* value, std::size_t n_value);

    /// return gathered information from all nodes
    /// to all nodes
    ///
    /// @return vector of all the gathered values
    ///
    /// collective operation
    template <typename T, typename Y>
    inline void all_gather(const T & input, std::vector<Y> & output);

    template <typename T, typename Y>
    inline void all_gather(const T* ivalues, std::size_t nvalues, Y* ovalues);

    template <typename T, typename Y>
    inline void all_gather(const T* ivalues, std::size_t nvalues,
                                     Y* ovalues, const std::size_t * ovalues_per_node);

    /// @brief MPI broadcast
    ///
    ///  @param value to broadcast
    ///  @param root node
    ///
    ///  Broadcast a value from node root to all the nodes of
    ///  the communication handle
    ///
    ///
    template <typename T>
    inline void broadcast(T & values, int root);

    template <typename T>
    inline void broadcast(T* buffer, std::size_t nvalues, int root);

    /// @brief return the highest element of the nodes
    /// @param local_value value to compare
    /// @return highest element between all nodes
    ///
    /// collective operation
    template <typename T>
    inline T all_max(const T & elems);

    template <typename T>
    inline void all_max(const T* ivalue, std::size_t n_value, T* ovalue);

    /// @brief return the sum of all the elements of the nodes
    /// @param local_value value to sum
    /// @return sum of all the elements
    ///
    /// collective operation
    template <typename T>
    inline T all_sum(const T & local_value);

    template <typename T>
    inline void all_sum(const T* ivalue, std::size_t n_value, T* ovalue);

private:
    int _rank;
    int _size;
    MPI_Comm _comm;
};

/// various const definitions
const int any_tag = MPI_ANY_TAG;
const int any_source = MPI_ANY_SOURCE;

}

#include "impl/mpi.tcc"

#endif
<commit_msg>Fix missing include<commit_after>/** **************************************************************************
 * Copyright (C) 2016 Adrien Devresse
 *
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 ** ***************************************************************************/
#ifndef MPI_CPP_MPI_HPP
#define MPI_CPP_MPI_HPP

#include <vector>
#include <string>
#include <boost/noncopyable.hpp>

#include <mpi.h>

#include "mpi_exception.hpp"

namespace mpi {

class mpi_comm;
class mpi_scope_env;

/**
 * @brief mpi environment scoper
 *
 *  initialize MPI when constructed, finalize MPI when destroyed
 */
class mpi_scope_env : private boost::noncopyable{
public:
    inline mpi_scope_env(int* argc, char*** argv);

    inline virtual ~mpi_scope_env();

private:
    int initialized;
};

/**
 * @brief mpi communicator
 *
 * bridge to all the MPI functions
 */
class mpi_comm : private boost::noncopyable
{
public:

    class message_handle{
    public:
        inline message_handle();

        ///
        /// \brief get_tag
        /// \return tag associated to the message
        ///
        inline int tag() const;

        ///
        /// \brief get_rank
        /// \return rank of the sending node associated with the message
        ///
        inline int rank() const;

        ///
        /// \brief get_size
        /// \return number of elements of type T part of the message.
        ///  In case of T being a container ( vector, string ), get_size() return the number of container elements
        ///  part of the message
        ///
        template<typename T>
        inline std::size_t count() const;

        ///
        /// \brief test message_handle validity
        /// \return return true if message handle is valid, false if the probe operation has been aborted
        ///
        inline bool is_valid() const;

    private:
        MPI_Status _status;
        MPI_Message _msg;
        friend class mpi_comm;
    };

    /**
     * @brief mpi_comm
     *
     * construct an MPI communication channel
     *
     * MPI operation
     */

    inline mpi_comm();
    inline virtual ~mpi_comm();

    /**
     * @brief rank
     * @return mpi rank of the process
     */
    inline int rank() const{
        return _rank;
    }

    /**
     * @brief size
     * @return size of the mpi communication domain
     */
    inline int size() const{
        return _size;
    }

    /**
     * @brief isMaster
     * @return true if current node is root ( 0 )
     */
    inline bool is_master() const{
        return _rank ==0;
    }

    /// @brief synchronization barrier
    ///
    /// blocking until all the nodes reach it
    inline void barrier();

    /// send local_value to node dest
    /// @param local_value value to send
    /// @param dest node id of the reciver
    /// @param tag identity tag
    template <typename T>
    inline void send(const T & local_value, int dest_node, int tag);

    template <typename T>
    inline void send(const T * value, std::size_t n_value ,
                     int dest_node, int tag);

    /// check for incoming messages, without actual receipt of them
    /// @param src_node node of the sender
    /// @param tag identity tag of the message
    /// @return messange_handle associated with the incoming message.
    ///         It muse be used with recv(message_handle) to recv the associated
    ///         message
    inline message_handle probe(int src_node, int tag);

    ///
    /// check for incoming messages, without actual receipt of them
    /// if not message are received after a specified time, the function
    /// return an invalid message_handle that need to be tested with
    /// message_handle::is_valid()
    ///
    /// \param src_node node of the sender
    /// \param tag tag of the message
    /// \param us_time time in micro seconds
    /// \return message_handle, validity test is necessary
    ///
    inline message_handle probe(int src_node, int tag, std::size_t us_time);

    /// received data from an other node
    /// @param src node id of the sender
    /// @param tag identity tag
    /// @return value received
    template <typename T>
    inline void recv(int src_node, int tag, T & value);

    template <typename T>
    inline void recv(const message_handle & handle, T & value);

    template <typename T>
    inline void recv(int src_node, int tag, T* value, std::size_t n_value);

    /// return gathered information from all nodes
    /// to all nodes
    ///
    /// @return vector of all the gathered values
    ///
    /// collective operation
    template <typename T, typename Y>
    inline void all_gather(const T & input, std::vector<Y> & output);

    template <typename T, typename Y>
    inline void all_gather(const T* ivalues, std::size_t nvalues, Y* ovalues);

    template <typename T, typename Y>
    inline void all_gather(const T* ivalues, std::size_t nvalues,
                                     Y* ovalues, const std::size_t * ovalues_per_node);

    /// @brief MPI broadcast
    ///
    ///  @param value to broadcast
    ///  @param root node
    ///
    ///  Broadcast a value from node root to all the nodes of
    ///  the communication handle
    ///
    ///
    template <typename T>
    inline void broadcast(T & values, int root);

    template <typename T>
    inline void broadcast(T* buffer, std::size_t nvalues, int root);

    /// @brief return the highest element of the nodes
    /// @param local_value value to compare
    /// @return highest element between all nodes
    ///
    /// collective operation
    template <typename T>
    inline T all_max(const T & elems);

    template <typename T>
    inline void all_max(const T* ivalue, std::size_t n_value, T* ovalue);

    /// @brief return the sum of all the elements of the nodes
    /// @param local_value value to sum
    /// @return sum of all the elements
    ///
    /// collective operation
    template <typename T>
    inline T all_sum(const T & local_value);

    template <typename T>
    inline void all_sum(const T* ivalue, std::size_t n_value, T* ovalue);

private:
    int _rank;
    int _size;
    MPI_Comm _comm;
};

/// various const definitions
const int any_tag = MPI_ANY_TAG;
const int any_source = MPI_ANY_SOURCE;

}

#include "impl/mpi.tcc"

#endif
<|endoftext|>


<commit_before>#ifndef __RANK_FILTER_BASE__
#define __RANK_FILTER_BASE__

#include <deque>
#include <cassert>
#include <functional>
#include <iostream>
#include <iterator>

#include <boost/array.hpp>
#include <boost/container/set.hpp>
#include <boost/container/node_allocator.hpp>
#include <boost/math/special_functions/round.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

namespace rank_filter
{

template<class I1,
         class I2>
inline void lineRankOrderFilter1D(const I1& src_begin, const I1& src_end,
        I2& dest_begin, I2& dest_end,
        size_t half_length, double rank)
{
    // Types in use.
    typedef typename std::iterator_traits<I1>::value_type T1;
    typedef typename std::iterator_traits<I2>::value_type T2;
    typedef typename std::iterator_traits<I1>::difference_type I1_diff_t;
    typedef typename std::iterator_traits<I2>::difference_type I2_diff_t;

    // Establish common types to work with source and destination values.
    BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
    typedef T1 T;
    typedef typename boost::common_type<I1_diff_t, I2_diff_t>::type I_diff_t;

    // Rank must be in the range 0 to 1
    assert((0 <= rank) && (rank <= 1));

    const I_diff_t rank_pos = static_cast<I_diff_t>(boost::math::round(rank * (2 * half_length)));

    // The position of the window.
    I_diff_t window_begin = 0;

    // Lengths.
    const I_diff_t src_size = std::distance(src_begin, src_end);
    const I_diff_t dest_size = std::distance(dest_begin, dest_end);

    typedef boost::container::multiset< T,
            std::less<T>,
            boost::container::node_allocator<T>,
            boost::container::tree_assoc_options< boost::container::tree_type<boost::container::scapegoat_tree> >::type> multiset;

    typedef std::deque< typename multiset::iterator > deque;

    multiset sorted_window;
    deque window_iters(2 * half_length + 1);

    // Get the initial sorted window.
    // Include the reflection.
    for (I_diff_t j = 0; j < half_length; j++)
    {
        window_iters[j] = sorted_window.insert(src_begin[window_begin + half_length - j]);
    }
    for (I_diff_t j = half_length; j < (2 * half_length + 1); j++)
    {
        window_iters[j] = sorted_window.insert(src_begin[window_begin + j - half_length]);
    }

    typename multiset::iterator rank_point = sorted_window.begin();

    for (I_diff_t i = 0; i < rank_pos; i++)
    {
        rank_point++;
    }

    typename multiset::iterator prev_iter;
    T prev_value;
    T next_value;
    while ( window_begin < src_size )
    {
        dest_begin[window_begin] = *rank_point;

        prev_iter = window_iters.front();
        prev_value = *prev_iter;
        window_iters.pop_front();

        window_begin++;

        if ( window_begin == src_size )
        {
            next_value = prev_value;
        }
        else if ( window_begin < (src_size - half_length) )
        {
            next_value = src_begin[window_begin + half_length];
        }
        else
        {
            next_value = *(window_iters[(2 * (src_size - (window_begin + 1)))]);
        }

        if ( ( *rank_point < prev_value ) && ( *rank_point <= next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point > next_value ) )
        {
            if ( rank_point == prev_iter )
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point--;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));
            }
        }
        else if ( ( *rank_point < prev_value ) && ( *rank_point > next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));

            rank_point--;
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point <= next_value ) )
        {
            if (rank_point == prev_iter)
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point++;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));

                rank_point++;
            }
        }
    }
}

}

namespace std
{
    template <class T, size_t N>
    ostream& operator<<(ostream& out, const boost::array<T, N>& that)
    {
        out << "{ ";
        for (unsigned int i = 0; i < (N - 1); i++)
        {
            out << that[i] << ", ";
        }
        out << that[N - 1] << " }";

        return(out);
    }
}

#endif //__RANK_FILTER_BASE__
<commit_msg>Rename __RANK_FILTER_BASE__ to __RANK_FILTER__<commit_after>#ifndef __RANK_FILTER__
#define __RANK_FILTER__

#include <deque>
#include <cassert>
#include <functional>
#include <iostream>
#include <iterator>

#include <boost/array.hpp>
#include <boost/container/set.hpp>
#include <boost/container/node_allocator.hpp>
#include <boost/math/special_functions/round.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

namespace rank_filter
{

template<class I1,
         class I2>
inline void lineRankOrderFilter1D(const I1& src_begin, const I1& src_end,
        I2& dest_begin, I2& dest_end,
        size_t half_length, double rank)
{
    // Types in use.
    typedef typename std::iterator_traits<I1>::value_type T1;
    typedef typename std::iterator_traits<I2>::value_type T2;
    typedef typename std::iterator_traits<I1>::difference_type I1_diff_t;
    typedef typename std::iterator_traits<I2>::difference_type I2_diff_t;

    // Establish common types to work with source and destination values.
    BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
    typedef T1 T;
    typedef typename boost::common_type<I1_diff_t, I2_diff_t>::type I_diff_t;

    // Rank must be in the range 0 to 1
    assert((0 <= rank) && (rank <= 1));

    const I_diff_t rank_pos = static_cast<I_diff_t>(boost::math::round(rank * (2 * half_length)));

    // The position of the window.
    I_diff_t window_begin = 0;

    // Lengths.
    const I_diff_t src_size = std::distance(src_begin, src_end);
    const I_diff_t dest_size = std::distance(dest_begin, dest_end);

    typedef boost::container::multiset< T,
            std::less<T>,
            boost::container::node_allocator<T>,
            boost::container::tree_assoc_options< boost::container::tree_type<boost::container::scapegoat_tree> >::type> multiset;

    typedef std::deque< typename multiset::iterator > deque;

    multiset sorted_window;
    deque window_iters(2 * half_length + 1);

    // Get the initial sorted window.
    // Include the reflection.
    for (I_diff_t j = 0; j < half_length; j++)
    {
        window_iters[j] = sorted_window.insert(src_begin[window_begin + half_length - j]);
    }
    for (I_diff_t j = half_length; j < (2 * half_length + 1); j++)
    {
        window_iters[j] = sorted_window.insert(src_begin[window_begin + j - half_length]);
    }

    typename multiset::iterator rank_point = sorted_window.begin();

    for (I_diff_t i = 0; i < rank_pos; i++)
    {
        rank_point++;
    }

    typename multiset::iterator prev_iter;
    T prev_value;
    T next_value;
    while ( window_begin < src_size )
    {
        dest_begin[window_begin] = *rank_point;

        prev_iter = window_iters.front();
        prev_value = *prev_iter;
        window_iters.pop_front();

        window_begin++;

        if ( window_begin == src_size )
        {
            next_value = prev_value;
        }
        else if ( window_begin < (src_size - half_length) )
        {
            next_value = src_begin[window_begin + half_length];
        }
        else
        {
            next_value = *(window_iters[(2 * (src_size - (window_begin + 1)))]);
        }

        if ( ( *rank_point < prev_value ) && ( *rank_point <= next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point > next_value ) )
        {
            if ( rank_point == prev_iter )
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point--;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));
            }
        }
        else if ( ( *rank_point < prev_value ) && ( *rank_point > next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));

            rank_point--;
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point <= next_value ) )
        {
            if (rank_point == prev_iter)
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point++;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));

                rank_point++;
            }
        }
    }
}

}

namespace std
{
    template <class T, size_t N>
    ostream& operator<<(ostream& out, const boost::array<T, N>& that)
    {
        out << "{ ";
        for (unsigned int i = 0; i < (N - 1); i++)
        {
            out << that[i] << ", ";
        }
        out << that[N - 1] << " }";

        return(out);
    }
}

#endif //__RANK_FILTER__
<|endoftext|>


<commit_before>/*
 * xares.hpp
 *
 * eXploration module for Autonomous Robotic Embedded Systems
 *
 * author:  Cyril Robin <cyril.robin@laas.fr>
 * created: 2013-09-19
 * license: BSD
 */
#ifndef XARES_HPP
#define XARES_HPP

#include <vector>
//#include <ostream>

//#include "gladys/point.hpp"
#include "gladys/frontier_exploration.hpp"

namespace xares {

/*{{{ xares class
 ****************************************************************************/

/* Decison making for frontier attirbutes :
 *
 * Use to sort attributes (thus frontiers) to plan exploration.
 * The lesser, the better.
 *
 */
struct {//{{{
    bool operator()( gladys::f_attributes l, gladys::f_attributes r) {

        // First criteria is proximity (the lesser, the better)
        if (l.proximity == r.proximity ) {
            // 2nd & 3rd criterias are :
            // - size (the bigger, the better)
            // - and cost (distance) : the cheaper, the better
            // We use a ratio
            return (r.size * r.size * l.distance ) < ( l.size * l.size * r.distance );
        }
        return l.proximity < r.proximity ;
    }
} decision_making;//}}}

/* xares class */
class xares{//{{{

private :
    /* internal data */
    gladys::frontier_detector fd ;                      // use to compute frontiers

    std::vector< gladys::points_t > frontiers ;         // the list of the frontiers
    std::vector< gladys::f_attributes > attributes ;    // the frontiers attributes

    gladys::point_xy_t goal ;                           // the current goal chosen by the planner
    gladys::path_t path ;                               // the path to the goal

    /* internal parameters */
    size_t max_nf = 10 ;                                // max nbr of frontiers to consider
    size_t min_size = 2 ;                               // minimal size of the frontier to consider
    gladys::frontier_detector::algo_t algo = gladys::frontier_detector::WFD ; // algo use to compute frontiers

    /* hidden computing functions */

public:
    xares () ;
    /** xares constructor
     *
     * Create a frontier_detector which loads region and robot model
     *
     * @param f_region path to a region.tif file
     * (multi-layers terrains classification probabilities, float32)
     *
     * @param f_robot_model to generate the weight map (at least its size)
     *
     */
    xares( const std::string& f_region, const std::string& f_robot_model ) ;

    /** load a new frontier detect
     *
     * Reset internal data (keep the internal parameters)
     *
     * @param f_region path to a region.tif file
     * (multi-layers terrains classification probabilities, float32)
     *
     * @param f_robot_model to generate the weight map (at least its size)
     *
     */
    void load( const std::string& f_region, const std::string& f_robot_model ) ;

    /** set the internal parameters
     *
     * Keep the internal data.
     *
     * @param _max_nf : max nbr of frontiers to consider
     *
     * @param _min_size : minimal size of the frontier to consider
     *
     * @param _algo : algo use to compute frontiers
     *
     */
    void set_params(//{{{
        size_t _max_nf = 10,
        size_t _min_size = 2,
        gladys::frontier_detector::algo_t _algo = gladys::frontier_detector::WFD
    ){
        max_nf      = _max_nf ;
        min_size    = _min_size ;
        algo        = _algo ;
    }//}}}

    /** plan a goal and a path
     *
     * Compute the frontiers with the given algorithm and parameters.
     * Compute their attributes.
     * Choose a goal.
     *
     * @param r_pos : the position of all the robot in the team. The first one
     * is assume to be the robot running the algorithm.
     *
     */
    void plan( const gladys::points_t &r_pos) ;

    /* getters */
    const std::vector< gladys::f_attributes >&  get_attributes() const {//{{{
        return attributes;
    }//}}}
    const gladys::point_xy_t& get_goal() const {//{{{
        return goal;
    }//}}}
    const gladys::path_t& get_path() const {//{{{
        return path;
    }//}}}

};//}}}

} // namespace  xares

#endif // XARES_HPP

<commit_msg>[decision making] Use size s (not s*s)<commit_after>/*
 * xares.hpp
 *
 * eXploration module for Autonomous Robotic Embedded Systems
 *
 * author:  Cyril Robin <cyril.robin@laas.fr>
 * created: 2013-09-19
 * license: BSD
 */
#ifndef XARES_HPP
#define XARES_HPP

#include <vector>
//#include <ostream>

//#include "gladys/point.hpp"
#include "gladys/frontier_exploration.hpp"

namespace xares {

/* Decison making for frontier attirbutes :
 *
 * Use to sort attributes (thus frontiers) to plan exploration.
 * The lesser, the better.
 *
 */
struct {//{{{
    bool operator()( gladys::f_attributes l, gladys::f_attributes r) {

        // First criteria is proximity (the lesser, the better)
        if (l.proximity == r.proximity ) {
            // 2nd & 3rd criterias are :
            // - size (the bigger, the better)
            // - and cost (distance) : the cheaper, the better
            // We use a ratio
            //return (r.size * r.size * l.distance ) < ( l.size * l.size * r.distance );
            return (r.size * l.distance ) < ( l.size * r.distance );
        }
        return l.proximity < r.proximity ;
    }
} decision_making;//}}}

/*{{{ xares class
 ****************************************************************************/
/* xares class */
class xares{//{{{

private :
    /* internal data */
    gladys::frontier_detector fd ;                      // use to compute frontiers

    std::vector< gladys::points_t > frontiers ;         // the list of the frontiers
    std::vector< gladys::f_attributes > attributes ;    // the frontiers attributes

    gladys::point_xy_t goal ;                           // the current goal chosen by the planner
    gladys::path_t path ;                               // the path to the goal

    /* internal parameters */
    size_t max_nf = 10 ;                                // max nbr of frontiers to consider
    size_t min_size = 2 ;                               // minimal size of the frontier to consider
    gladys::frontier_detector::algo_t algo = gladys::frontier_detector::WFD ; // algo use to compute frontiers

    /* hidden computing functions */

public:
    xares () ;
    /** xares constructor
     *
     * Create a frontier_detector which loads region and robot model
     *
     * @param f_region path to a region.tif file
     * (multi-layers terrains classification probabilities, float32)
     *
     * @param f_robot_model to generate the weight map (at least its size)
     *
     */
    xares( const std::string& f_region, const std::string& f_robot_model ) ;

    /** load a new frontier detect
     *
     * Reset internal data (keep the internal parameters)
     *
     * @param f_region path to a region.tif file
     * (multi-layers terrains classification probabilities, float32)
     *
     * @param f_robot_model to generate the weight map (at least its size)
     *
     */
    void load( const std::string& f_region, const std::string& f_robot_model ) ;

    /** set the internal parameters
     *
     * Keep the internal data.
     *
     * @param _max_nf : max nbr of frontiers to consider
     *
     * @param _min_size : minimal size of the frontier to consider
     *
     * @param _algo : algo use to compute frontiers
     *
     */
    void set_params(//{{{
        size_t _max_nf = 10,
        size_t _min_size = 2,
        gladys::frontier_detector::algo_t _algo = gladys::frontier_detector::WFD
    ){
        max_nf      = _max_nf ;
        min_size    = _min_size ;
        algo        = _algo ;
    }//}}}

    /** plan a goal and a path
     *
     * Compute the frontiers with the given algorithm and parameters.
     * Compute their attributes.
     * Choose a goal.
     *
     * @param r_pos : the position of all the robot in the team. The first one
     * is assume to be the robot running the algorithm.
     *
     */
    void plan( const gladys::points_t &r_pos) ;

    /* getters */
    const std::vector< gladys::f_attributes >&  get_attributes() const {//{{{
        return attributes;
    }//}}}
    const gladys::point_xy_t& get_goal() const {//{{{
        return goal;
    }//}}}
    const gladys::path_t& get_path() const {//{{{
        return path;
    }//}}}

};//}}}

} // namespace  xares

#endif // XARES_HPP

<|endoftext|>


<commit_before>/*
 * libtins is a net packet wrapper library for crafting and
 * interpreting sniffed packets.
 *
 * Copyright (C) 2011 Nasel
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <stdexcept>
#include "sniffer.h"
#include "ethernetII.h"
#include "radiotap.h"

using namespace std;

/** \cond */

struct LoopData {
    pcap_t *handle;
    Tins::AbstractSnifferHandler *c_handler;
    bool wired;

    LoopData(pcap_t *_handle, Tins::AbstractSnifferHandler *_handler, bool is_wired) : handle(_handle), c_handler(_handler), wired(is_wired) { }
};

/** \endcond */

Tins::Sniffer::Sniffer(const string &device, unsigned max_packet_size) {
    char error[PCAP_ERRBUF_SIZE];
    if (pcap_lookupnet(device.c_str(), &ip, &mask, error) == -1) {
        ip = 0;
        mask = 0;
    }
    handle = pcap_open_live(device.c_str(), max_packet_size, 0, 0, error);
    if(!handle)
        throw runtime_error(error);
    wired = (pcap_datalink (handle) != DLT_IEEE802_11_RADIO); //better plx
    actual_filter.bf_insns = 0;
}

Tins::Sniffer::~Sniffer() {
    if(actual_filter.bf_insns)
        pcap_freecode(&actual_filter);
    if(handle)
        pcap_close(handle);
}

bool Tins::Sniffer::compile_set_filter(const string &filter, bpf_program &prog) {
    return (pcap_compile(handle, &prog, filter.c_str(), 0, ip) != -1 && pcap_setfilter(handle, &prog) != -1);
}

Tins::PDU *Tins::Sniffer::next_packet(const string &filter) {
    if(filter.size())
        set_filter(filter);
    pcap_pkthdr header;
    PDU *ret = 0;
    while(!ret) {
        const u_char *content = pcap_next(handle, &header);
        try {
            if(wired)
                ret = new EthernetII((const uint8_t*)content, header.caplen);
            else
                ret = new RadioTap((const uint8_t*)content, header.caplen);
        }
        catch(...) {
            ret = 0;
        }
    }
    return ret;
}

void Tins::Sniffer::stop_sniff() {
    pcap_breakloop(handle);
}

void Tins::Sniffer::sniff_loop(AbstractSnifferHandler *cback_handler, const string &filter, uint32_t max_packets) {
    if(filter.size())
        set_filter(filter);
    LoopData data(handle, cback_handler, wired);
    pcap_loop(handle, max_packets, Sniffer::callback_handler, (u_char*)&data);
}

bool Tins::Sniffer::set_filter(const std::string &filter) {
    if(actual_filter.bf_insns)
        pcap_freecode(&actual_filter);
    return compile_set_filter(filter, actual_filter);
}

// Static
void Tins::Sniffer::callback_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
    try {
        PDU *pdu = 0;
        LoopData *data = reinterpret_cast<LoopData*>(args);
        if(data->wired)
            pdu = new EthernetII((const uint8_t*)packet, header->caplen);
        else
            pdu = new RadioTap((const uint8_t*)packet, header->caplen);
        bool ret_val = data->c_handler->handle(pdu);
        delete pdu;
        if(!ret_val)
            pcap_breakloop(data->handle);
    }
    catch(...) {

    }
}

<commit_msg>Fixed bug in Sniffer::next_packet.<commit_after>/*
 * libtins is a net packet wrapper library for crafting and
 * interpreting sniffed packets.
 *
 * Copyright (C) 2011 Nasel
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <stdexcept>
#include "sniffer.h"
#include "ethernetII.h"
#include "radiotap.h"

using namespace std;

/** \cond */

struct LoopData {
    pcap_t *handle;
    Tins::AbstractSnifferHandler *c_handler;
    bool wired;

    LoopData(pcap_t *_handle, Tins::AbstractSnifferHandler *_handler, bool is_wired) : handle(_handle), c_handler(_handler), wired(is_wired) { }
};

/** \endcond */

Tins::Sniffer::Sniffer(const string &device, unsigned max_packet_size) {
    char error[PCAP_ERRBUF_SIZE];
    if (pcap_lookupnet(device.c_str(), &ip, &mask, error) == -1) {
        ip = 0;
        mask = 0;
    }
    handle = pcap_open_live(device.c_str(), max_packet_size, 0, 0, error);
    if(!handle)
        throw runtime_error(error);
    wired = (pcap_datalink (handle) != DLT_IEEE802_11_RADIO); //better plx
    actual_filter.bf_insns = 0;
}

Tins::Sniffer::~Sniffer() {
    if(actual_filter.bf_insns)
        pcap_freecode(&actual_filter);
    if(handle)
        pcap_close(handle);
}

bool Tins::Sniffer::compile_set_filter(const string &filter, bpf_program &prog) {
    return (pcap_compile(handle, &prog, filter.c_str(), 0, ip) != -1 && pcap_setfilter(handle, &prog) != -1);
}

Tins::PDU *Tins::Sniffer::next_packet(const string &filter) {
    if(filter.size())
        set_filter(filter);
    pcap_pkthdr header;
    PDU *ret = 0;
    while(!ret) {
        const u_char *content = pcap_next(handle, &header);
        if(content) {
            try {
                if(wired)
                    ret = new EthernetII((const uint8_t*)content, header.caplen);
                else
                    ret = new RadioTap((const uint8_t*)content, header.caplen);
            }
            catch(...) {
                ret = 0;
            }
        }
    }
    return ret;
}

void Tins::Sniffer::stop_sniff() {
    pcap_breakloop(handle);
}

void Tins::Sniffer::sniff_loop(AbstractSnifferHandler *cback_handler, const string &filter, uint32_t max_packets) {
    if(filter.size())
        set_filter(filter);
    LoopData data(handle, cback_handler, wired);
    pcap_loop(handle, max_packets, Sniffer::callback_handler, (u_char*)&data);
}

bool Tins::Sniffer::set_filter(const std::string &filter) {
    if(actual_filter.bf_insns)
        pcap_freecode(&actual_filter);
    return compile_set_filter(filter, actual_filter);
}

// Static
void Tins::Sniffer::callback_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
    try {
        PDU *pdu = 0;
        LoopData *data = reinterpret_cast<LoopData*>(args);
        if(data->wired)
            pdu = new EthernetII((const uint8_t*)packet, header->caplen);
        else
            pdu = new RadioTap((const uint8_t*)packet, header->caplen);
        bool ret_val = data->c_handler->handle(pdu);
        delete pdu;
        if(!ret_val)
            pcap_breakloop(data->handle);
    }
    catch(...) {

    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2013-2017 mogemimi. Distributed under the MIT license.

#include "Simple2DGameEngine.hpp"
#include "Pomdog.Experimental/Gameplay2D/ActorComponent.hpp"
#include "Pomdog.Experimental/Gameplay2D/GraphicsComponent.hpp"
#include "Pomdog.Experimental/Rendering/Processors/PrimitiveCommandProcessor.hpp"
#include "Pomdog.Experimental/Rendering/Processors/PrimitivePolygonCommandProcessor.hpp"
#include "Pomdog.Experimental/Rendering/Processors/SpriteBatchCommandProcessor.hpp"

namespace Pomdog {

Simple2DGameEngine::Simple2DGameEngine(const std::shared_ptr<GameHost>& gameHostIn)
    : gameHost(gameHostIn)
    , gameTimer(gameHostIn->GetClock())
    , postProcessCompositor(
        gameHost->GetGraphicsDevice(),
        gameHost->GetWindow()->GetClientBounds().Width,
        gameHost->GetWindow()->GetClientBounds().Height,
        SurfaceFormat::R8G8B8A8_UNorm)
    , needToUpdateViewProjectionMatrix(true)
{
    auto graphicsDevice = gameHost->GetGraphicsDevice();
    auto assets = gameHost->GetAssetManager();
    auto window = gameHost->GetWindow();

    auto clientBounds = window->GetClientBounds();

    postProcessCompositor.SetViewportSize(
        *graphicsDevice, clientBounds.Width, clientBounds.Height);

    {
        renderer = std::make_unique<Renderer>(graphicsDevice);

        renderer->AddProcessor(std::make_unique<
            Rendering::PrimitiveCommandProcessor>(graphicsDevice, *assets));
        renderer->AddProcessor(std::make_unique<
            Rendering::PrimitivePolygonCommandProcessor>(graphicsDevice, *assets));
        renderer->AddProcessor(std::make_unique<
            Rendering::SpriteBatchCommandProcessor>(graphicsDevice, *assets));
    }
    {
        commandListPreRender = std::make_shared<GraphicsCommandList>(*graphicsDevice);
        commandListPostRender = std::make_shared<GraphicsCommandList>(*graphicsDevice);

        connections(window->ClientSizeChanged, [this](int width, int height) {
            this->OnViewportSizeChanged(width, height);
        });

        auto bounds = window->GetClientBounds();
        viewport = {0, 0, bounds.Width, bounds.Height};
        OnViewportSizeChanged(bounds.Width, bounds.Height);
    }
}

Simple2DGameEngine::~Simple2DGameEngine()
{
    entityManager.Clear();
}

void Simple2DGameEngine::OnViewportSizeChanged(int width, int height)
{
    auto graphicsDevice = gameHost->GetGraphicsDevice();

    viewport.Width = width;
    viewport.Height = height;

    renderTarget = std::make_shared<RenderTarget2D>(
        graphicsDevice, width, height, false,
        SurfaceFormat::R8G8B8A8_UNorm,
        DepthFormat::Depth24Stencil8);

    postProcessCompositor.SetViewportSize(*graphicsDevice, width, height);

    if (mainCamera) {
        mainCamera->SetViewportSize(width, height);
    }

    needToUpdateViewProjectionMatrix = true;
}

void Simple2DGameEngine::Update()
{
    for (auto & entity : entityManager.QueryComponents<ActorComponent>()) {
        auto actor = entity.GetComponent<ActorComponent>();
        actor->Act(entity, gameTimer.GetFrameDuration());
    }

    entityManager.Refresh();

    // TODO: bad code
    needToUpdateViewProjectionMatrix = true;
}

void Simple2DGameEngine::Draw()
{
    if (needToUpdateViewProjectionMatrix) {
        auto viewMatrix = [&]() -> Matrix4x4 {
            if (mainCamera && mainCameraTransform) {
                auto rotation = Matrix4x4::CreateFromQuaternion(mainCameraTransform->GetRotation());
                return Matrix4x4::CreateLookAtLH(
                    mainCameraTransform->GetPosition(),
                    mainCameraTransform->GetPosition() + Vector3::Transform(Vector3::UnitZ, rotation),
                    Vector3::UnitY);
            }
            return Matrix4x4::Identity;
        }();

        auto projectionMatrix = [&]() -> Matrix4x4 {
            if (mainCamera) {
                return mainCamera->ComputeProjectionMatrix();
            }
            constexpr float distanceToNearPlane = 0.001f;
            constexpr float distanceToFarPlane = 1000.0f;
            return Matrix4x4::CreatePerspectiveFieldOfViewLH(
                MathHelper::ToRadians<float>(45.0f),
                viewport.GetAspectRatio(),
                distanceToNearPlane,
                distanceToFarPlane);
        }();

        this->viewProjection = viewMatrix * projectionMatrix;

        renderer->SetViewMatrix(viewMatrix);
        renderer->SetProjectionMatrix(projectionMatrix);

        needToUpdateViewProjectionMatrix = false;
    }

    renderer->Reset();

    for (auto & entity : entityManager.QueryComponents<GraphicsComponent>()) {
        auto graphicsComponent = entity.GetComponent<GraphicsComponent>();
        POMDOG_ASSERT(graphicsComponent);
        graphicsComponent->Visit(entity, *renderer);
    }

    const bool canSkipPostProcess = postProcessCompositor.CanSkipPostProcess();

    {
        // Reset graphics commands
        commandListPreRender->Reset();

        // Fill background color
        auto backgroundColor = [&]()-> Color {
            if (mainCamera) {
                return mainCamera->GetBackgroundColor();
            }
            return Color::CornflowerBlue;
        }();

        // Set the render pass
        RenderPass renderPass;
        if (canSkipPostProcess) {
            renderPass.RenderTargets.emplace_back(nullptr, backgroundColor.ToVector4());
        }
        else {
            renderPass.RenderTargets.emplace_back(renderTarget, backgroundColor.ToVector4());
        }
        renderPass.Viewport = viewport;
        renderPass.ScissorRect = viewport.GetBounds();
        renderPass.ClearDepth = 1.0f;
        renderPass.ClearStencil = 0;
        commandListPreRender->SetRenderPass(std::move(renderPass));

        // Close graphics command list
        commandListPreRender->Close();
    }

    if (!canSkipPostProcess)
    {
        // Reset graphics commands
        commandListPostRender->Reset();

        // Set the back buffer as the target
        RenderPass renderPass;
        renderPass.RenderTargets.emplace_back(nullptr, NullOpt);
        renderPass.Viewport = viewport;
        renderPass.ScissorRect = viewport.GetBounds();
        renderPass.ClearDepth = NullOpt;
        renderPass.ClearStencil = NullOpt;
        commandListPostRender->SetRenderPass(std::move(renderPass));

        // Post processing
        postProcessCompositor.Draw(*commandListPostRender, renderTarget);

        // Close graphics command list
        commandListPostRender->Close();
    }

    auto commandQueue = gameHost->GetGraphicsCommandQueue();
    commandQueue->Reset();
    commandQueue->PushbackCommandList(commandListPreRender);
    commandQueue->PushbackCommandList(renderer->Render());
    if (!canSkipPostProcess) {
        commandQueue->PushbackCommandList(commandListPostRender);
    }
    commandQueue->ExecuteCommandLists();
    commandQueue->Present();
}

void Simple2DGameEngine::Composite(
    std::vector<std::shared_ptr<ImageEffectBase>> && imageEffects)
{
    postProcessCompositor.Composite(std::move(imageEffects));
}

void Simple2DGameEngine::SetCamera(const Entity& cameraObject)
{
    POMDOG_ASSERT(cameraObject);
    POMDOG_ASSERT(cameraObject.HasComponent<CameraComponent>());
    POMDOG_ASSERT(cameraObject.HasComponent<Transform>());

    this->mainCamera = cameraObject.GetComponent<CameraComponent>();
    this->mainCameraTransform = cameraObject.GetComponent<Transform>();
}

} // namespace Pomdog
<commit_msg>Remove duplicate render pass from command list<commit_after>// Copyright (c) 2013-2017 mogemimi. Distributed under the MIT license.

#include "Simple2DGameEngine.hpp"
#include "Pomdog.Experimental/Gameplay2D/ActorComponent.hpp"
#include "Pomdog.Experimental/Gameplay2D/GraphicsComponent.hpp"
#include "Pomdog.Experimental/Rendering/Processors/PrimitiveCommandProcessor.hpp"
#include "Pomdog.Experimental/Rendering/Processors/PrimitivePolygonCommandProcessor.hpp"
#include "Pomdog.Experimental/Rendering/Processors/SpriteBatchCommandProcessor.hpp"

namespace Pomdog {

Simple2DGameEngine::Simple2DGameEngine(const std::shared_ptr<GameHost>& gameHostIn)
    : gameHost(gameHostIn)
    , gameTimer(gameHostIn->GetClock())
    , postProcessCompositor(
        gameHost->GetGraphicsDevice(),
        gameHost->GetWindow()->GetClientBounds().Width,
        gameHost->GetWindow()->GetClientBounds().Height,
        SurfaceFormat::R8G8B8A8_UNorm)
    , needToUpdateViewProjectionMatrix(true)
{
    auto graphicsDevice = gameHost->GetGraphicsDevice();
    auto assets = gameHost->GetAssetManager();
    auto window = gameHost->GetWindow();

    auto clientBounds = window->GetClientBounds();

    postProcessCompositor.SetViewportSize(
        *graphicsDevice, clientBounds.Width, clientBounds.Height);

    {
        renderer = std::make_unique<Renderer>(graphicsDevice);

        renderer->AddProcessor(std::make_unique<
            Rendering::PrimitiveCommandProcessor>(graphicsDevice, *assets));
        renderer->AddProcessor(std::make_unique<
            Rendering::PrimitivePolygonCommandProcessor>(graphicsDevice, *assets));
        renderer->AddProcessor(std::make_unique<
            Rendering::SpriteBatchCommandProcessor>(graphicsDevice, *assets));
    }
    {
        commandListPreRender = std::make_shared<GraphicsCommandList>(*graphicsDevice);
        commandListPostRender = std::make_shared<GraphicsCommandList>(*graphicsDevice);

        connections(window->ClientSizeChanged, [this](int width, int height) {
            this->OnViewportSizeChanged(width, height);
        });

        auto bounds = window->GetClientBounds();
        viewport = {0, 0, bounds.Width, bounds.Height};
        OnViewportSizeChanged(bounds.Width, bounds.Height);
    }
}

Simple2DGameEngine::~Simple2DGameEngine()
{
    entityManager.Clear();
}

void Simple2DGameEngine::OnViewportSizeChanged(int width, int height)
{
    auto graphicsDevice = gameHost->GetGraphicsDevice();

    viewport.Width = width;
    viewport.Height = height;

    renderTarget = std::make_shared<RenderTarget2D>(
        graphicsDevice, width, height, false,
        SurfaceFormat::R8G8B8A8_UNorm,
        DepthFormat::Depth24Stencil8);

    postProcessCompositor.SetViewportSize(*graphicsDevice, width, height);

    if (mainCamera) {
        mainCamera->SetViewportSize(width, height);
    }

    needToUpdateViewProjectionMatrix = true;
}

void Simple2DGameEngine::Update()
{
    for (auto & entity : entityManager.QueryComponents<ActorComponent>()) {
        auto actor = entity.GetComponent<ActorComponent>();
        actor->Act(entity, gameTimer.GetFrameDuration());
    }

    entityManager.Refresh();

    // TODO: bad code
    needToUpdateViewProjectionMatrix = true;
}

void Simple2DGameEngine::Draw()
{
    if (needToUpdateViewProjectionMatrix) {
        auto viewMatrix = [&]() -> Matrix4x4 {
            if (mainCamera && mainCameraTransform) {
                auto rotation = Matrix4x4::CreateFromQuaternion(mainCameraTransform->GetRotation());
                return Matrix4x4::CreateLookAtLH(
                    mainCameraTransform->GetPosition(),
                    mainCameraTransform->GetPosition() + Vector3::Transform(Vector3::UnitZ, rotation),
                    Vector3::UnitY);
            }
            return Matrix4x4::Identity;
        }();

        auto projectionMatrix = [&]() -> Matrix4x4 {
            if (mainCamera) {
                return mainCamera->ComputeProjectionMatrix();
            }
            constexpr float distanceToNearPlane = 0.001f;
            constexpr float distanceToFarPlane = 1000.0f;
            return Matrix4x4::CreatePerspectiveFieldOfViewLH(
                MathHelper::ToRadians<float>(45.0f),
                viewport.GetAspectRatio(),
                distanceToNearPlane,
                distanceToFarPlane);
        }();

        this->viewProjection = viewMatrix * projectionMatrix;

        renderer->SetViewMatrix(viewMatrix);
        renderer->SetProjectionMatrix(projectionMatrix);

        needToUpdateViewProjectionMatrix = false;
    }

    renderer->Reset();

    for (auto & entity : entityManager.QueryComponents<GraphicsComponent>()) {
        auto graphicsComponent = entity.GetComponent<GraphicsComponent>();
        POMDOG_ASSERT(graphicsComponent);
        graphicsComponent->Visit(entity, *renderer);
    }

    const bool canSkipPostProcess = postProcessCompositor.CanSkipPostProcess();

    {
        // Reset graphics commands
        commandListPreRender->Reset();

        // Fill background color
        auto backgroundColor = [&]()-> Color {
            if (mainCamera) {
                return mainCamera->GetBackgroundColor();
            }
            return Color::CornflowerBlue;
        }();

        // Set the render pass
        RenderPass renderPass;
        if (canSkipPostProcess) {
            renderPass.RenderTargets.emplace_back(nullptr, backgroundColor.ToVector4());
        }
        else {
            renderPass.RenderTargets.emplace_back(renderTarget, backgroundColor.ToVector4());
        }
        renderPass.Viewport = viewport;
        renderPass.ScissorRect = viewport.GetBounds();
        renderPass.ClearDepth = 1.0f;
        renderPass.ClearStencil = 0;
        commandListPreRender->SetRenderPass(std::move(renderPass));

        // Close graphics command list
        commandListPreRender->Close();
    }

    if (!canSkipPostProcess)
    {
        // Reset graphics commands
        commandListPostRender->Reset();

        // Post processing
        postProcessCompositor.Draw(*commandListPostRender, renderTarget);

        // Close graphics command list
        commandListPostRender->Close();
    }

    auto commandQueue = gameHost->GetGraphicsCommandQueue();
    commandQueue->Reset();
    commandQueue->PushbackCommandList(commandListPreRender);
    commandQueue->PushbackCommandList(renderer->Render());
    if (!canSkipPostProcess) {
        commandQueue->PushbackCommandList(commandListPostRender);
    }
    commandQueue->ExecuteCommandLists();
    commandQueue->Present();
}

void Simple2DGameEngine::Composite(
    std::vector<std::shared_ptr<ImageEffectBase>> && imageEffects)
{
    postProcessCompositor.Composite(std::move(imageEffects));
}

void Simple2DGameEngine::SetCamera(const Entity& cameraObject)
{
    POMDOG_ASSERT(cameraObject);
    POMDOG_ASSERT(cameraObject.HasComponent<CameraComponent>());
    POMDOG_ASSERT(cameraObject.HasComponent<Transform>());

    this->mainCamera = cameraObject.GetComponent<CameraComponent>();
    this->mainCameraTransform = cameraObject.GetComponent<Transform>();
}

} // namespace Pomdog
<|endoftext|>


<commit_before>#include "ANGLETest.h"

class ReadPixelsTest : public ANGLETest
{
protected:
    ReadPixelsTest()
    {
        setWindowWidth(32);
        setWindowHeight(32);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }
};

TEST_F(ReadPixelsTest, out_of_bounds)
{
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_GL_NO_ERROR();

    GLsizei pixelsWidth = 32;
    GLsizei pixelsHeight = 32;
    GLint offset = 16;
    std::vector<GLubyte> pixels((pixelsWidth + offset) * (pixelsHeight + offset) * 4);

    glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
    EXPECT_GL_NO_ERROR();

    for (int y = pixelsHeight / 2; y < pixelsHeight; y++)
    {
        for (int x = pixelsWidth / 2; x < pixelsWidth; x++)
        {
            const GLubyte* pixel = pixels.data() + ((y * (pixelsWidth + offset) + x) * 4);
            unsigned int r = static_cast<unsigned int>(pixel[0]);
            unsigned int g = static_cast<unsigned int>(pixel[1]);
            unsigned int b = static_cast<unsigned int>(pixel[2]);
            unsigned int a = static_cast<unsigned int>(pixel[3]);

            // Expect that all pixels which fell within the framebuffer are red
            EXPECT_EQ(255, r);
            EXPECT_EQ(0,   g);
            EXPECT_EQ(0,   b);
            EXPECT_EQ(255, a);
        }
    }
}
<commit_msg>Add tests for pack buffer corner cases.<commit_after>#include "ANGLETest.h"

class ReadPixelsTest : public ANGLETest
{
protected:
    ReadPixelsTest()
    {
        setClientVersion(3);
        setWindowWidth(32);
        setWindowHeight(32);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    virtual void SetUp()
    {
        ANGLETest::SetUp();

        glGenBuffers(1, &mPBO);
        glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
        glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), NULL, GL_STATIC_DRAW);
        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

        const char *vertexShaderSrc = SHADER_SOURCE
        (
            attribute vec4 aTest;
            attribute vec2 aPosition;
            varying vec4 vTest;

            void main()
            {
                vTest = aTest;
                gl_Position = vec4(aPosition, 0.0, 1.0);
                gl_PointSize = 1.0;
            }
        );

        const char *fragmentShaderSrc = SHADER_SOURCE
        (
            precision mediump float;
            varying vec4 vTest;

            void main()
            {
                gl_FragColor = vTest;
            }
        );

        mProgram = compileProgram(vertexShaderSrc, fragmentShaderSrc);

        glGenTextures(1, &mTexture);
        glBindTexture(GL_TEXTURE_2D, mTexture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);

        glGenFramebuffers(1, &mFBO);
        glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        glGenBuffers(1, &mPositionVBO);
        glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
        glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        ASSERT_GL_NO_ERROR();
    }

    virtual void TearDown()
    {
        ANGLETest::TearDown();

        glDeleteBuffers(1, &mPBO);
        glDeleteProgram(mProgram);
        glDeleteTextures(1, &mTexture);
        glDeleteFramebuffers(1, &mFBO);
    }

    GLuint mPBO;
    GLuint mProgram;
    GLuint mTexture;
    GLuint mFBO;
    GLuint mPositionVBO;
};

TEST_F(ReadPixelsTest, out_of_bounds)
{
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_GL_NO_ERROR();

    GLsizei pixelsWidth = 32;
    GLsizei pixelsHeight = 32;
    GLint offset = 16;
    std::vector<GLubyte> pixels((pixelsWidth + offset) * (pixelsHeight + offset) * 4);

    glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
    EXPECT_GL_NO_ERROR();

    for (int y = pixelsHeight / 2; y < pixelsHeight; y++)
    {
        for (int x = pixelsWidth / 2; x < pixelsWidth; x++)
        {
            const GLubyte* pixel = pixels.data() + ((y * (pixelsWidth + offset) + x) * 4);
            unsigned int r = static_cast<unsigned int>(pixel[0]);
            unsigned int g = static_cast<unsigned int>(pixel[1]);
            unsigned int b = static_cast<unsigned int>(pixel[2]);
            unsigned int a = static_cast<unsigned int>(pixel[3]);

            // Expect that all pixels which fell within the framebuffer are red
            EXPECT_EQ(255, r);
            EXPECT_EQ(0,   g);
            EXPECT_EQ(0,   b);
            EXPECT_EQ(255, a);
        }
    }
}

TEST_F(ReadPixelsTest, pbo_with_other_target)
{
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_GL_NO_ERROR();

    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);

    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, mPBO);

    GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
    unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
    EXPECT_GL_NO_ERROR();

    EXPECT_EQ(255, dataPtr[0]);
    EXPECT_EQ(0,   dataPtr[1]);
    EXPECT_EQ(0,   dataPtr[2]);
    EXPECT_EQ(255, dataPtr[3]);

    glUnmapBuffer(GL_ARRAY_BUFFER);
    EXPECT_GL_NO_ERROR();
}
<|endoftext|>


<commit_before>/*
 * author: Max Kellermann <mk@cm4all.com>
 */

#ifndef BENG_PROXY_SSL_CTX_HXX
#define BENG_PROXY_SSL_CTX_HXX

#include "Error.hxx"

#include <openssl/ssl.h>

#include <utility>

/**
 * A wrapper for SSL_CTX which takes advantage of OpenSSL's reference
 * counting.
 */
class SslCtx {
    SSL_CTX *ssl_ctx = nullptr;

public:
    SslCtx() = default;

    explicit SslCtx(const SSL_METHOD *meth)
        :ssl_ctx(SSL_CTX_new(meth)) {
        if (ssl_ctx == nullptr)
            throw SslError("SSL_CTX_new() failed");
    }

    SslCtx(const SslCtx &src)
        :ssl_ctx(src.ssl_ctx) {
        SSL_CTX_up_ref(ssl_ctx);
    }

    SslCtx(SslCtx &&src)
        :ssl_ctx(src.release()) {}

    ~SslCtx() {
        if (ssl_ctx != nullptr)
            SSL_CTX_free(ssl_ctx);
    }

    SslCtx &operator=(const SslCtx &src) {
        /* this check is important because it protects against
           self-assignment */
        if (ssl_ctx != src.ssl_ctx) {
            if (ssl_ctx != nullptr)
                SSL_CTX_free(ssl_ctx);

            ssl_ctx = src.ssl_ctx;
            if (ssl_ctx != nullptr)
                SSL_CTX_up_ref(ssl_ctx);
        }

        return *this;
    }

    SslCtx &operator=(SslCtx &&src) {
        std::swap(ssl_ctx, src.ssl_ctx);
        return *this;
    }

    operator bool() const {
        return ssl_ctx != nullptr;
    }

    SSL_CTX *get() const {
        return ssl_ctx;
    }

    SSL_CTX &operator*() const {
        return *ssl_ctx;
    }

    SSL_CTX *release() {
        return std::exchange(ssl_ctx, nullptr);
    }
};

#endif
<commit_msg>ssl/Ctx: add method reset()<commit_after>/*
 * author: Max Kellermann <mk@cm4all.com>
 */

#ifndef BENG_PROXY_SSL_CTX_HXX
#define BENG_PROXY_SSL_CTX_HXX

#include "Error.hxx"

#include <openssl/ssl.h>

#include <utility>

/**
 * A wrapper for SSL_CTX which takes advantage of OpenSSL's reference
 * counting.
 */
class SslCtx {
    SSL_CTX *ssl_ctx = nullptr;

public:
    SslCtx() = default;

    explicit SslCtx(const SSL_METHOD *meth)
        :ssl_ctx(SSL_CTX_new(meth)) {
        if (ssl_ctx == nullptr)
            throw SslError("SSL_CTX_new() failed");
    }

    SslCtx(const SslCtx &src)
        :ssl_ctx(src.ssl_ctx) {
        SSL_CTX_up_ref(ssl_ctx);
    }

    SslCtx(SslCtx &&src)
        :ssl_ctx(src.release()) {}

    ~SslCtx() {
        if (ssl_ctx != nullptr)
            SSL_CTX_free(ssl_ctx);
    }

    SslCtx &operator=(const SslCtx &src) {
        /* this check is important because it protects against
           self-assignment */
        if (ssl_ctx != src.ssl_ctx) {
            if (ssl_ctx != nullptr)
                SSL_CTX_free(ssl_ctx);

            ssl_ctx = src.ssl_ctx;
            if (ssl_ctx != nullptr)
                SSL_CTX_up_ref(ssl_ctx);
        }

        return *this;
    }

    SslCtx &operator=(SslCtx &&src) {
        std::swap(ssl_ctx, src.ssl_ctx);
        return *this;
    }

    operator bool() const {
        return ssl_ctx != nullptr;
    }

    SSL_CTX *get() const {
        return ssl_ctx;
    }

    SSL_CTX &operator*() const {
        return *ssl_ctx;
    }

    void reset() {
        if (ssl_ctx != nullptr)
            SSL_CTX_free(ssl_ctx);
        ssl_ctx = nullptr;
    }

    SSL_CTX *release() {
        return std::exchange(ssl_ctx, nullptr);
    }
};

#endif
<|endoftext|>