<commit_before>/*-------------Lanczos.cpp----------------------------------------------------//
*
* Purpose: To diagonalize a random matrix using the Lanczos algorithm
*
*   Notes: Compile with (for Arch systems):
*              g++ -I /usr/include/eigen3/ Lanczos.cpp
*          0's along the prime diagonal. I don't know what this means.
*
*-----------------------------------------------------------------------------*/

#include <iostream>
#include <Eigen/Core>
#include <Eigen/QR>
#include <random>
#include <vector>
#include <math.h>

using namespace Eigen;

// Function for the lanczos algorithm, returns Tri-diagonal matrix
MatrixXd lanczos(MatrixXd &d_matrix, int row_num);

// Function for QR decomposition
MatrixXd qrdecomp(MatrixXd &Tridiag);

// Function to perform the Power Method
void p_method(MatrixXd &Tridiag, MatrixXd &Q);

// Function to return sign of value (signum function)
int sign(double value);

// Function to check eigenvectors and values
void eigentest(MatrixXd &d_matrix, MatrixXd &Q);

/*----------------------------------------------------------------------------//
* MAIN
*-----------------------------------------------------------------------------*/

int main(){
/*
    int size = 200;
    MatrixXd d_matrix(size,size);

    // set up random device
    static std::random_device rd;
    int seed = rd();
    static std::mt19937 gen(seed);
    std::uniform_real_distribution<double> dist(0,1);

    for (size_t i = 0; i < d_matrix.rows(); ++i){
        for (size_t j = 0; j <= i; ++j){
            d_matrix(i,j) = dist(gen);
            d_matrix(j,i) = d_matrix(i,j);
        }
    }

    Tridiag = lanczos(d_matrix, 5);

    std::cout << '\n' << "Tridiagonal matrix is: \n";

    for (size_t i = 0; i < Tridiag.rows(); ++i){
        for (size_t j = 0; j < Tridiag.cols(); ++j){
            std::cout << Tridiag(i, j) << '\t';
        }
        std::cout << '\n';
    }

    std::cout << '\n';
*/

    MatrixXd Tridiag(4,4);
    Tridiag <<  2, 1, 3, 5,
                -1, 0, 7, 1,
                0,-1,-1,3,
                -3,7,4,3;

    Tridiag = lanczos(Tridiag, 3);

    MatrixXd Q = qrdecomp(Tridiag);

    MatrixXd Qtemp = Q;

    std::cout << "Q is: " << '\n';
    std::cout << Q << '\n';

    std::cout << "Finding eigenvalues: " << '\n';
    p_method(Tridiag, Q);

    Qtemp = Qtemp - Q;
    std::cout << "After the Power Method: " << Qtemp.squaredNorm() << '\n';
    eigentest(Tridiag, Q);

}

/*----------------------------------------------------------------------------//
* SUBROUTINE
*-----------------------------------------------------------------------------*/

// Function for the lanczos algorithm, returns Tri-diagonal matrix
MatrixXd lanczos(MatrixXd &d_matrix, int row_num){

    // Creating random device
    static std::random_device rd;
    int seed = rd();
    static std::mt19937 gen(seed);
    std::uniform_real_distribution<double> dist(0,1);

    // Defining values
    double threshold = 0.01;
    int j = 0;
    int size = d_matrix.rows();

    // Setting beta arbitrarily large for now
    double beta = 10;

    // generating the first rayleigh vector
    // alpha is actually just a double... sorry about that.
    MatrixXd rayleigh(d_matrix.rows(),1), q(d_matrix.rows(),1),
             alpha(1, 1);
    MatrixXd identity = MatrixXd::Identity(d_matrix.rows(), d_matrix.cols());

    // krylov is the krylovian subspace... Note, there might be a dynamic way to
    // do this. Something like:
    //std::vector <MatrixXd> krylov;
    MatrixXd krylov(d_matrix.rows(), row_num);

    for (size_t i = 0; i < size; ++i){
        rayleigh(i) = dist(gen);
    }

    //std::cout << rayleigh << '\n';

    //while (beta > threshold){
    for (size_t i = 0; i < row_num; ++i){
        beta = rayleigh.norm();
        //std::cout << "beta is: \n" << beta << '\n';

        q = rayleigh / beta;
        //std::cout << "q is: \n" << q << '\n';

        alpha = q.transpose() * d_matrix * q;
        //std::cout << "alpha is \n" << alpha << '\n';

        if (j == 0){
            rayleigh = (d_matrix - alpha(0,0) * identity) * q;
        }
        else{
            rayleigh = (d_matrix - alpha(0,0) * identity) * q
                       - beta * krylov.col(j - 1);

        }
        //std::cout << "rayleigh is: \n" << rayleigh <<'\n';
        //std::cout << "i is: " << i << '\n';

        //krylov.push_back(q);
        krylov.col(j) = q;
        j = j+1;
        // std::cout << j << '\n';
    }

    MatrixXd krylov_id = krylov.transpose() * krylov;
    std::cout << "The identity matrix from the krylov subspace is: \n"
              << krylov_id << '\n';

    MatrixXd T(row_num,row_num);
    T = krylov.transpose() * d_matrix * krylov;

    return T;
}

// Function for QR decomposition
// Because we only need Q for the power method, I will retun only Q
MatrixXd qrdecomp(MatrixXd &Tridiag){
    // Q is and orthonormal vector => Q'Q = 1
    MatrixXd Id = MatrixXd::Identity(Tridiag.rows(), Tridiag.cols());
    MatrixXd Q = Id;
    MatrixXd P(Tridiag.rows(), Tridiag.cols());

    // R is the upper triangular matrix
    MatrixXd R = Tridiag;

    int row_num = Tridiag.rows();
    int countx = 0, county = 0;

    // Scale R
    double sum = 0.0, sigma, tau, fak, max_val = 0;

    bool sing;

    // Defining vectors for algorithm
    MatrixXd diag(row_num,1);

    //std::cout << R << '\n';

    for (int i = 0; i < row_num-1; ++i){
        diag = MatrixXd::Zero(row_num, 1);

        sum = 0;
        for (size_t j = i; j < row_num; ++j){
            sum += R(j,i) * R(j,i);
            //std::cout << R(j,i) << '\n';
        }
        sum = sqrt(sum);

        if (R(i,i) > 0){
            sigma = -sum;
        }
        else{
            sigma = sum;
        }

        //std::cout << "sigma is: " << sigma << '\n';

        sum = 0;
        //diag = R.block(i,i, row_num - i, 1);
        //std::cout << "diag is: " << '\n';
        for (int j = i; j < row_num; ++j){
            //std::cout << i << '\t' << j << '\n';
            if (j == i){
                diag(j) = R(j,i) + sigma;
            }
            else{
                diag(j) = R(j, i);
            }
            //std::cout << diag(j) << '\n';
            sum = sum + diag(j) * diag(j);
        }
        sum = sqrt(sum);

        //std::cout << "sum is: " << sum << '\n';

        if (sum > 0.000000000000001){

            for (int j = i; j < row_num; ++j){
                diag(j) = diag(j) / sum;
            }

            //std::cout << "normalized diag is: " << '\n' << diag << '\n';

            P = Id - (diag * diag.transpose()) * 2.0;

            R = P * R;
            Q = Q * P;
        }

        //std::cout << "R is: " << R << '\n';

    }
    //std::cout << "R is: " << R << '\n';
    //std::cout << "Q is: " << Q << '\n';

    //std::cout << "QR is: " << '\n' << Q*R << '\n';

    std::cout << "Q^T * Q is: " << '\n' << Q.transpose() * Q << '\n' << '\n';
    std::cout << "QR - A is: " << '\n' << Q*R - Tridiag << '\n';
    //std::cout << "Q^T * A - R: " << '\n'
    //          << Q.transpose() * Tridiag - R << '\n' << '\n';

    return Q;
}

// Function to perform the Power Method
void p_method(MatrixXd &Tridiag, MatrixXd &Q){

    std::cout << "Q is: " << '\n' << Q << '\n';
    std::cout << "Tridiag is : " << '\n' << Tridiag << '\n';

    // Find all eigenvectors
    MatrixXd eigenvectors(Tridiag.rows(), Tridiag.cols());
    MatrixXd Z(Tridiag.rows(), Tridiag.cols());
    MatrixXd Qtemp = Q;

    // Iteratively defines eigenvectors
    for (int i = 0; i < Tridiag.rows(); ++i){
        Z = Tridiag * Q;
        Q = qrdecomp(Z);

    }

    Qtemp = Qtemp - Q;
    std::cout << "This should not be 0: " << Qtemp.squaredNorm() << '\n';

}

// Function to return sign of value (signum function)
int sign(double value){
    if (value < 0.0){
        return -1;
    }
    else if (value > 0){
        return 1;
    }
    else {
        return 0;
    }
}

// Function to check eigenvectors and values
void eigentest(MatrixXd &Tridiag, MatrixXd &Q){

    // Calculating the Rayleigh quotient (v^t * A * v) / (v^t * v)
    // Note, that this should be a representation of eigenvalues

    std::vector<double> eigenvalues(Tridiag.rows());
    MatrixXd checkvector(Tridiag.rows(),1);
    double QQ, QAQ;

    for (size_t i = 0; i < Tridiag.rows(); ++i){
        QQ = Q.col(i).transpose() * Q.col(i);
        QAQ = Q.col(i).transpose() * Tridiag * Q.col(i);
        eigenvalues[i] =  QAQ / QQ;
        std::cout << "eigenvalue is: " << eigenvalues[i] << '\n';

        checkvector = ((Tridiag * Q.col(i)) / eigenvalues[i]) - Q.col(i);
        std::cout << checkvector << '\n' << '\n';
        std::cout << "This should be 0: " << '\t'
                  << checkvector.squaredNorm() << '\n';

    }

}

<commit_msg>commenting out unnecessary cout statements.<commit_after>/*-------------Lanczos.cpp----------------------------------------------------//
*
* Purpose: To diagonalize a random matrix using the Lanczos algorithm
*
*   Notes: Compile with (for Arch systems):
*              g++ -I /usr/include/eigen3/ Lanczos.cpp
*          0's along the prime diagonal. I don't know what this means.
*
*-----------------------------------------------------------------------------*/

#include <iostream>
#include <Eigen/Core>
#include <Eigen/QR>
#include <random>
#include <vector>
#include <math.h>

using namespace Eigen;

// Function for the lanczos algorithm, returns Tri-diagonal matrix
MatrixXd lanczos(MatrixXd &d_matrix, int row_num);

// Function for QR decomposition
MatrixXd qrdecomp(MatrixXd &Tridiag);

// Function to perform the Power Method
void p_method(MatrixXd &Tridiag, MatrixXd &Q);

// Function to return sign of value (signum function)
int sign(double value);

// Function to check eigenvectors and values
void eigentest(MatrixXd &d_matrix, MatrixXd &Q);

/*----------------------------------------------------------------------------//
* MAIN
*-----------------------------------------------------------------------------*/

int main(){

    int size = 200;
    MatrixXd d_matrix(size,size);

    // set up random device
    static std::random_device rd;
    int seed = rd();
    static std::mt19937 gen(seed);
    std::uniform_real_distribution<double> dist(0,1);

    for (size_t i = 0; i < d_matrix.rows(); ++i){
        for (size_t j = 0; j <= i; ++j){
            d_matrix(i,j) = dist(gen);
            d_matrix(j,i) = d_matrix(i,j);
        }
    }

    MatrixXd Tridiag = lanczos(d_matrix, 20);

    //std::cout << '\n' << "Tridiagonal matrix is: \n" << Tridiag << '\n';

    /*
    // Testing for eigenvalue determination
    MatrixXd Tridiag(3,3);
    Tridiag << 1, 2, 0,
               2, 1, 0,
               0, 0, -3;

    MatrixXd Tridiag(5,5);
    Tridiag << 5, 0, 0, 0, 0,
               0, 4, 0, 0, 0,
               0, 0, 3, 0, 0,
               0, 0, 0, 2, 0,
               0, 0, 0, 0, 7;
    Tridiag = lanczos(Tridiag, 5);
    */

    //std::cout << "Tridiag is: " << '\n' << Tridiag << '\n';

    MatrixXd Q = qrdecomp(Tridiag);

    MatrixXd Qtemp = Q;

    //std::cout << "Q is: " << '\n';
    //std::cout << Q << '\n';

    std::cout << "Finding eigenvalues: " << '\n';
    p_method(Tridiag, Q);

    //std::cout << "Q is: " << '\n' << Q << '\n';

    Qtemp = Qtemp - Q;
    //std::cout << "After the Power Method: " << Qtemp.squaredNorm() << '\n';
    eigentest(Tridiag, Q);

}

/*----------------------------------------------------------------------------//
* SUBROUTINE
*-----------------------------------------------------------------------------*/

// Function for the lanczos algorithm, returns Tri-diagonal matrix
MatrixXd lanczos(MatrixXd &d_matrix, int row_num){

    // Creating random device
    static std::random_device rd;
    int seed = rd();
    static std::mt19937 gen(seed);
    std::uniform_real_distribution<double> dist(0,1);

    // Defining values
    double threshold = 0.01;
    int j = 0;
    int size = d_matrix.rows();

    // Setting beta arbitrarily large for now
    double beta = 10;

    // generating the first rayleigh vector
    // alpha is actually just a double... sorry about that.
    MatrixXd rayleigh(d_matrix.rows(),1), q(d_matrix.rows(),1),
             alpha(1, 1);
    MatrixXd identity = MatrixXd::Identity(d_matrix.rows(), d_matrix.cols());

    // krylov is the krylovian subspace... Note, there might be a dynamic way to
    // do this. Something like:
    //std::vector <MatrixXd> krylov;
    MatrixXd krylov(d_matrix.rows(), row_num);

    for (size_t i = 0; i < size; ++i){
        rayleigh(i) = dist(gen);
    }

    //std::cout << rayleigh << '\n';

    //while (beta > threshold){
    for (size_t i = 0; i < row_num; ++i){
        beta = rayleigh.norm();
        //std::cout << "beta is: \n" << beta << '\n';

        q = rayleigh / beta;
        //std::cout << "q is: \n" << q << '\n';

        alpha = q.transpose() * d_matrix * q;
        //std::cout << "alpha is \n" << alpha << '\n';

        if (j == 0){
            rayleigh = (d_matrix - alpha(0,0) * identity) * q;
        }
        else{
            rayleigh = (d_matrix - alpha(0,0) * identity) * q
                       - beta * krylov.col(j - 1);

        }
        //std::cout << "rayleigh is: \n" << rayleigh <<'\n';
        //std::cout << "i is: " << i << '\n';

        //krylov.push_back(q);
        krylov.col(j) = q;
        j = j+1;
        // std::cout << j << '\n';
    }

    /*
    MatrixXd krylov_id = krylov.transpose() * krylov;
    std::cout << "The identity matrix from the krylov subspace is: \n"
              << krylov_id << '\n';
    */

    MatrixXd T(row_num,row_num);
    T = krylov.transpose() * d_matrix * krylov;

    return T;
}

// Function for QR decomposition
// Because we only need Q for the power method, I will retun only Q
MatrixXd qrdecomp(MatrixXd &Tridiag){
    // Q is and orthonormal vector => Q'Q = 1
    MatrixXd Id = MatrixXd::Identity(Tridiag.rows(), Tridiag.cols());
    MatrixXd Q = Id;
    MatrixXd P(Tridiag.rows(), Tridiag.cols());

    // R is the upper triangular matrix
    MatrixXd R = Tridiag;

    int row_num = Tridiag.rows();
    int countx = 0, county = 0;

    // Scale R
    double sum = 0.0, sigma, tau, fak, max_val = 0;

    bool sing;

    // Defining vectors for algorithm
    MatrixXd diag(row_num,1);

    //std::cout << R << '\n';

    for (int i = 0; i < row_num-1; ++i){
        diag = MatrixXd::Zero(row_num, 1);

        sum = 0;
        for (size_t j = i; j < row_num; ++j){
            sum += R(j,i) * R(j,i);
            //std::cout << R(j,i) << '\n';
        }
        sum = sqrt(sum);

        if (R(i,i) > 0){
            sigma = -sum;
        }
        else{
            sigma = sum;
        }

        //std::cout << "sigma is: " << sigma << '\n';

        sum = 0;
        //diag = R.block(i,i, row_num - i, 1);
        //std::cout << "diag is: " << '\n';
        for (int j = i; j < row_num; ++j){
            //std::cout << i << '\t' << j << '\n';
            if (j == i){
                diag(j) = R(j,i) + sigma;
            }
            else{
                diag(j) = R(j, i);
            }
            //std::cout << diag(j) << '\n';
            sum = sum + diag(j) * diag(j);
        }
        sum = sqrt(sum);

        //std::cout << "sum is: " << sum << '\n';

        if (sum > 0.000000000000001){

            for (int j = i; j < row_num; ++j){
                diag(j) = diag(j) / sum;
            }

            //std::cout << "normalized diag is: " << '\n' << diag << '\n';

            P = Id - (diag * diag.transpose()) * 2.0;

            R = P * R;
            Q = Q * P;
        }

        //std::cout << "R is: " << R << '\n';

    }
    //std::cout << "R is: " << R << '\n';
    //std::cout << "Q is: " << Q << '\n';

    //std::cout << "QR is: " << '\n' << Q*R << '\n';

    //std::cout << "Q^T * Q is: " << '\n' << Q.transpose() * Q << '\n' << '\n';
    //std::cout << "QR - A is: " << '\n' << Q*R - Tridiag << '\n';
    //std::cout << "Q^T * A - R: " << '\n'
    //          << Q.transpose() * Tridiag - R << '\n' << '\n';

    return Q;
}

// Function to perform the Power Method
void p_method(MatrixXd &Tridiag, MatrixXd &Q){

    //std::cout << "Q is: " << '\n' << Q << '\n';
    //std::cout << "Tridiag is : " << '\n' << Tridiag << '\n';

    // Find all eigenvectors
    MatrixXd eigenvectors(Tridiag.rows(), Tridiag.cols());
    MatrixXd Z(Tridiag.rows(), Tridiag.cols());
    MatrixXd Qtemp = Q;

    // Iteratively defines eigenvectors
    for (int i = 0; i < Tridiag.rows(); ++i){
        Z = Tridiag * Q;
        Q = qrdecomp(Z);

    }

    Qtemp = Qtemp - Q;
    //std::cout << "This should not be 0: " << Qtemp.squaredNorm() << '\n';

}

// Function to return sign of value (signum function)
int sign(double value){
    if (value < 0.0){
        return -1;
    }
    else if (value > 0){
        return 1;
    }
    else {
        return 0;
    }
}

// Function to check eigenvectors and values
void eigentest(MatrixXd &Tridiag, MatrixXd &Q){

    // Calculating the Rayleigh quotient (v^t * A * v) / (v^t * v)
    // Note, that this should be a representation of eigenvalues

    std::vector<double> eigenvalues(Tridiag.rows());
    MatrixXd checkvector(Tridiag.rows(),1);
    double QQ, QAQ;

    for (size_t i = 0; i < Tridiag.rows(); ++i){
        QQ = Q.col(i).transpose() * Q.col(i);
        QAQ = Q.col(i).transpose() * Tridiag * Q.col(i);
        eigenvalues[i] =  QAQ / QQ;
        std::cout << "eigenvalue is: " << eigenvalues[i] << '\n';

        checkvector = ((Tridiag * Q.col(i)) / eigenvalues[i]) - Q.col(i);
        //std::cout << checkvector << '\n' << '\n';
        std::cout << "This should be 0: " << '\t'
                  << checkvector.squaredNorm() << '\n';

    }

}

<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// *       Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// *       Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// *       Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------
//
//	Add a preview image to an OpenEXR file.
//
//----------------------------------------------------------------------------

#include <makePreview.h>

#include <ImfInputFile.h>
#include <ImfOutputFile.h>
#include <ImfTiledOutputFile.h>
#include <ImfRgbaFile.h>
#include <ImfPreviewImage.h>
#include <ImfArray.h>
#include <ImathFun.h>
#include <math.h>
#include <iostream>

using namespace Imf;
using namespace Imath;
using namespace std;

namespace {

float
knee (float x, float f)
{
    return log (x * f + 1) / f;
}

unsigned char
gamma (half h, float m)
{
    //
    // Conversion from half to unsigned char pixel data,
    // with gamma correction.  The conversion is the same
    // as in the exrdisplay program's ImageView class,
    // except with defog, kneeLow, and kneeHigh fixed
    // at 0.0, 0.0, and 5.0 respectively.
    //

    float x = max (0.f, h * m);

    if (x > 1)
	x = 1 + knee (x - 1, 0.184874f);

    return (unsigned char) (clamp (pow (x, 0.4545f) * 84.66f, 0.f, 255.f));
}

void
generatePreview (const char inFileName[],
		 float exposure,
		 int previewWidth,
		 int &previewHeight,
		 Array2D <PreviewRgba> &previewPixels)
{
    //
    // Read the input file
    //

    RgbaInputFile in (inFileName);

    Box2i dw = in.dataWindow();
    float a = in.pixelAspectRatio();
    int w = dw.max.x - dw.min.x + 1;
    int h = dw.max.y - dw.min.y + 1;

    Array2D <Rgba> pixels (h, w);
    in.setFrameBuffer (&pixels[0][0] - dw.min.y * w - dw.min.x, 1, w);
    in.readPixels (dw.min.y, dw.max.y);

    //
    // Make a preview image
    //

    previewHeight = max (int (h / (w * a) * previewWidth + .5f), 1);
    previewPixels.resizeErase (previewHeight, previewWidth);

    float fx = (previewWidth  > 0)? (float (w - 1) / (previewWidth  - 1)): 1;
    float fy = (previewHeight > 0)? (float (h - 1) / (previewHeight - 1)): 1;
    float m  = pow (2.f, clamp (exposure + 2.47393f, -20.f, 20.f));

    for (int y = 0; y < previewHeight; ++y)
    {
	for (int x = 0; x < previewWidth; ++x)
	{
	    PreviewRgba &preview = previewPixels[y][x];
	    const Rgba &pixel = pixels[int (y * fy + .5f)][int (x * fx + .5f)];

	    preview.r = gamma (pixel.r, m);
	    preview.g = gamma (pixel.g, m);
	    preview.b = gamma (pixel.b, m);
	    preview.a = int (clamp (pixel.a * 255.f, 0.f, 255.f) * .5f);
	}
    }
}

} // namespace

void
makePreview (const char inFileName[],
	     const char outFileName[],
	     int previewWidth,
	     float exposure,
	     bool verbose)
{
    if (verbose)
	cout << "generating preview image" << endl;

    Array2D <PreviewRgba> previewPixels;
    int previewHeight;

    generatePreview (inFileName,
		     exposure,
		     previewWidth,
		     previewHeight,
		     previewPixels);

    InputFile in (inFileName);
    Header header = in.header();

    header.setPreviewImage
	(PreviewImage (previewWidth, previewHeight, &previewPixels[0][0]));

    if (verbose)
	cout << "copying " << inFileName << " to " << outFileName << endl;

    if (header.hasTileDescription())
    {
	TiledOutputFile out (outFileName, header);
	out.copyPixels (in);
    }
    else
    {
	OutputFile out (outFileName, header);
	out.copyPixels (in);
    }

    if (verbose)
	cout << "done." << endl;
}
<commit_msg><commit_after>///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// *       Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// *       Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// *       Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------
//
//	Add a preview image to an OpenEXR file.
//
//----------------------------------------------------------------------------

#include <makePreview.h>

#include <ImfInputFile.h>
#include <ImfOutputFile.h>
#include <ImfTiledOutputFile.h>
#include <ImfRgbaFile.h>
#include <ImfPreviewImage.h>
#include <ImfArray.h>
#include <ImathMath.h>
#include <ImathFun.h>
#include <math.h>
#include <iostream>

using namespace Imf;
using namespace Imath;
using namespace std;

namespace {

float
knee (float x, float f)
{
    return log (x * f + 1) / f;
}

unsigned char
gamma (half h, float m)
{
    //
    // Conversion from half to unsigned char pixel data,
    // with gamma correction.  The conversion is the same
    // as in the exrdisplay program's ImageView class,
    // except with defog, kneeLow, and kneeHigh fixed
    // at 0.0, 0.0, and 5.0 respectively.
    //

    float x = max (0.f, h * m);

    if (x > 1)
	x = 1 + knee (x - 1, 0.184874f);

    return (unsigned char) (clamp (Math<float>::pow (x, 0.4545f) * 84.66f,
				   0.f,
				   255.f));
}

void
generatePreview (const char inFileName[],
		 float exposure,
		 int previewWidth,
		 int &previewHeight,
		 Array2D <PreviewRgba> &previewPixels)
{
    //
    // Read the input file
    //

    RgbaInputFile in (inFileName);

    Box2i dw = in.dataWindow();
    float a = in.pixelAspectRatio();
    int w = dw.max.x - dw.min.x + 1;
    int h = dw.max.y - dw.min.y + 1;

    Array2D <Rgba> pixels (h, w);
    in.setFrameBuffer (&pixels[0][0] - dw.min.y * w - dw.min.x, 1, w);
    in.readPixels (dw.min.y, dw.max.y);

    //
    // Make a preview image
    //

    previewHeight = max (int (h / (w * a) * previewWidth + .5f), 1);
    previewPixels.resizeErase (previewHeight, previewWidth);

    float fx = (previewWidth  > 0)? (float (w - 1) / (previewWidth  - 1)): 1;
    float fy = (previewHeight > 0)? (float (h - 1) / (previewHeight - 1)): 1;
    float m  = Math<float>::pow (2.f, clamp (exposure + 2.47393f, -20.f, 20.f));

    for (int y = 0; y < previewHeight; ++y)
    {
	for (int x = 0; x < previewWidth; ++x)
	{
	    PreviewRgba &preview = previewPixels[y][x];
	    const Rgba &pixel = pixels[int (y * fy + .5f)][int (x * fx + .5f)];

	    preview.r = gamma (pixel.r, m);
	    preview.g = gamma (pixel.g, m);
	    preview.b = gamma (pixel.b, m);
	    preview.a = int (clamp (pixel.a * 255.f, 0.f, 255.f) * .5f);
	}
    }
}

} // namespace

void
makePreview (const char inFileName[],
	     const char outFileName[],
	     int previewWidth,
	     float exposure,
	     bool verbose)
{
    if (verbose)
	cout << "generating preview image" << endl;

    Array2D <PreviewRgba> previewPixels;
    int previewHeight;

    generatePreview (inFileName,
		     exposure,
		     previewWidth,
		     previewHeight,
		     previewPixels);

    InputFile in (inFileName);
    Header header = in.header();

    header.setPreviewImage
	(PreviewImage (previewWidth, previewHeight, &previewPixels[0][0]));

    if (verbose)
	cout << "copying " << inFileName << " to " << outFileName << endl;

    if (header.hasTileDescription())
    {
	TiledOutputFile out (outFileName, header);
	out.copyPixels (in);
    }
    else
    {
	OutputFile out (outFileName, header);
	out.copyPixels (in);
    }

    if (verbose)
	cout << "done." << endl;
}
<|endoftext|>


<commit_before>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
#include <memory>

class bitset
{
public:
	explicit
	bitset(size_t size);

	bitset(bitset const & other) = delete;
	auto operator =(bitset const & other)->bitset & = delete;

	bitset(bitset && other) = delete;
	auto operator =(bitset && other)->bitset & = delete;

	auto set(size_t index) -> void;
	auto reset(size_t index) -> void;
	auto test(size_t index) -> bool;

	auto size() const -> size_t;
	auto counter() const -> size_t;

private:
	std::unique_ptr<bool[]>  ptr_;
	size_t size_;
	size_t counter_;
};

bitset::bitset(size_t size) : ptr_(std::make_unique<bool[]>(size)), size_(size), counter_(0) {}

auto bitset::set(size_t index) -> void
{
	if (index < size_)
	{
		ptr_[index] = true;
		++counter_;
	}
	else throw("false_index");
}

auto bitset::reset(size_t index) -> void
{	if (index < size_)
	{
		ptr_[index] = false;
		--counter_;
	}
	else throw("false_index");
}

auto bitset::test(size_t index) -> bool
{
	if (index < size_)
	{
		return !ptr_[index];
	}
	else throw("false_index");

}

auto bitset::size() const -> size_t
{
	return size_;
}

auto bitset::counter() const -> size_t
{
	return counter_;
}

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

template <typename T>
class allocator
{
public:
	explicit
	allocator( std::size_t size = 0 );
	allocator( allocator const & other );
	auto operator =( allocator const & other ) -> allocator & = delete;
	~allocator();
	auto resize() -> void;
	auto construct(T * ptr, T const & value ) -> void;
	auto destroy( T * ptr ) -> void;
	auto get() -> T *;
	auto get() const -> T const *;
	auto count() const -> size_t;
	auto full() const -> bool;
	auto empty() const -> bool;
private:
	auto destroy(T * first, T * last) -> void;
	auto swap(allocator & other) -> void;
	T * ptr_;
	size_t size_;
	std::unique_ptr<bitset> map_;

};

template <typename T>
allocator<T>::allocator(size_t size) : ptr_((T*)(operator new(size*sizeof(T)))), size_(size), map_(std::make_unique<bitset>(size)) {};

template<typename T>
allocator<T>::allocator(allocator const& other) :
allocator<T>(other.size_)
{
	for (size_t i=0; i < size_; ++i)
		if (other.map_->test(i))
		construct(ptr_ + i, other.ptr_[i]);
}

template<typename T>
allocator<T>::~allocator()
{
	destroy(ptr_, ptr_+size_);
	operator delete(ptr_);
}

template<typename T>
auto allocator<T>::resize() -> void
{
	allocator<T> buff(size_ * 2 + (size_ == 0));
	for (size_t i = 0; i < size_; ++i) construct(buff.ptr_ + i, ptr_[i]);
	this->swap(buff);
}

template<typename T>
auto allocator<T>::construct(T * ptr, T const & value)->void
{
	if (ptr >= ptr_&&ptr < ptr_ + size_&&map_->test(ptr - ptr_))
	{
		new(ptr)T(value);
		map_->set(ptr - ptr_);
	}
	else throw("error");
}

template<typename T>
auto allocator<T>::destroy(T * ptr) -> void
{
	if(ptr>=ptr_&&ptr<=ptr_+this->count())
	{
		if (!map_->test(ptr-ptr_))
		{
		ptr->~T();
		map_->reset(ptr-ptr_);
		}
	}
	else throw("error");
}

template<typename T>
auto allocator<T>::destroy(T * first, T * last) -> void
{
	if(first>=ptr_&&last<=ptr_+this->count())
	for (; first != last; ++first)
	{
		destroy(&*first);
	}
}

template<typename T>
auto allocator<T>::get()-> T*
{
	return ptr_;
}

template<typename T>
auto allocator<T>::get() const -> T const *
{
	return ptr_;
}

template<typename T>
auto allocator<T>::count() const -> size_t
{
	return map_->counter();
}

template<typename T>
auto allocator<T>::full() const -> bool
{
	return map_->counter()==size_;
}

template<typename T>
auto allocator<T>::empty() const -> bool
{
	return map_->counter()==0;
}

template<typename T>
auto allocator<T>::swap(allocator & other) -> void
{
	std::swap(ptr_, other.ptr_);
	std::swap(count_, other.count_);
	std::swap(size_, other.size_);
}

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

template <typename T>
class stack : private allocator<T>
{
public:
	explicit
	stack(size_t size = 0);								//noexcept
	auto pop() -> void;
	auto top() -> T &;
	auto top() const -> T const &;
	auto push(T const &vaule) -> void;							//strong
	auto operator=(stack const & right)->stack &;					//strong
	auto empty() const -> bool; 							//noexcept
	auto count() const -> size_t;
private:
	allocator<T> allocator_;
	auto throw_is_empty() const -> void;
};

template <typename T>
size_t stack<T>::count() const
{
	return allocator_.count();
}
template <typename T>
stack<T>::stack(size_t size):allocator_(size){}

template <typename T>
void stack<T>::push(T const &item)
{
	if (allocator_.full()) allocator_.resize();
	allocator_.construct(allocator_.get() + this->count(), item);
}
template<typename T>
void stack<T>::pop()
{
	if (this->count() > 0)
		allocator_.destroy(allocator_.get() + (this->count()-1));
	else
		throw_is_empty();
}

template<typename T>
auto stack<T>::top() -> T &
{
	if (allocator_.count() == 0) {
		throw_is_empty();
	}
	return (*(allocator_.get() + allocator_.count() - 1));
}

template<typename T>
auto stack<T>::top() const -> T const &
{
	if (allocator_.count() == 0)
	{
		throw_is_empty();
	}
	return (*(allocator_.get() + allocator_.count() - 1));
}

template<typename T>
auto stack<T>::operator=(stack const & right)-> stack &
{
	if (this != &right)
	{
		(allocator<T>(right.allocator_)).swap(allocator_);
	}
	return *this;
}

template<typename T>
auto stack<T>::empty() const -> bool
{
	return allocator_.empty();
}

template<typename T>
auto stack<T>::throw_is_empty() const -> void
{
		throw("Stack is empty!");
}
#endif
<commit_msg>Update stack.cpp<commit_after>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
#include <memory>

class bitset
{
public:
	explicit
	bitset(size_t size);

	bitset(bitset const & other) = delete;
	auto operator =(bitset const & other)->bitset & = delete;

	bitset(bitset && other) = delete;
	auto operator =(bitset && other)->bitset & = delete;

	auto set(size_t index) -> void;
	auto reset(size_t index) -> void;
	auto test(size_t index) -> bool;

	auto size() const -> size_t;
	auto counter() const -> size_t;

private:
	std::unique_ptr<bool[]>  ptr_;
	size_t size_;
	size_t counter_;
};

bitset::bitset(size_t size) : ptr_(std::make_unique<bool[]>(size)), size_(size), counter_(0) {}

auto bitset::set(size_t index) -> void
{
	if (index < size_)
	{
		ptr_[index] = true;
		++counter_;
	}
	else throw("false_index");
}

auto bitset::reset(size_t index) -> void
{	if (index < size_)
	{
		ptr_[index] = false;
		--counter_;
	}
	else throw("false_index");
}

auto bitset::test(size_t index) -> bool
{
	if (index < size_)
	{
		return !ptr_[index];
	}
	else throw("false_index");

}

auto bitset::size() const -> size_t
{
	return size_;
}

auto bitset::counter() const -> size_t
{
	return counter_;
}

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

template <typename T>
class allocator
{
public:
	explicit
	allocator( std::size_t size = 0 );
	allocator( allocator const & other );
	auto operator =( allocator const & other ) -> allocator & = delete;
	~allocator();
	auto resize() -> void;
	auto construct(T * ptr, T const & value ) -> void;
	auto destroy( T * ptr ) -> void;
	auto get() -> T *;
	auto get() const -> T const *;
	auto count() const -> size_t;
	auto full() const -> bool;
	auto empty() const -> bool;
private:
	auto destroy(T * first, T * last) -> void;
	auto swap(allocator & other) -> void;
	T * ptr_;
	size_t size_;
	std::unique_ptr<bitset> map_;

};

template <typename T>
allocator<T>::allocator(size_t size) : ptr_((T*)(operator new(size*sizeof(T)))), size_(size), map_(std::make_unique<bitset>(size)) {};

template<typename T>
allocator<T>::allocator(allocator const& other) :
allocator<T>(other.size_)
{
	for (size_t i=0; i < size_; ++i)
		if (other.map_->test(i))
		construct(ptr_ + i, other.ptr_[i]);
}

template<typename T>
allocator<T>::~allocator()
{
	destroy(ptr_, ptr_+size_);
	operator delete(ptr_);
}

template<typename T>
auto allocator<T>::resize() -> void
{
	allocator<T> buff(size_ * 2 + (size_ == 0));
	for (size_t i = 0; i < size_; ++i) construct(buff.ptr_ + i, ptr_[i]);
	this->swap(buff);
}

template<typename T>
auto allocator<T>::construct(T * ptr, T const & value)->void
{
	if (ptr >= ptr_&&ptr < ptr_ + size_&&map_->test(ptr - ptr_))
	{
		new(ptr)T(value);
		map_->set(ptr - ptr_);
	}
	else throw("error");
}

template<typename T>
auto allocator<T>::destroy(T * ptr) -> void
{
	if(ptr>=ptr_&&ptr<=ptr_+this->count())
	{
		if (!map_->test(ptr-ptr_))
		{
		ptr->~T();
		map_->reset(ptr-ptr_);
		}
	}
	else throw("error");
}

template<typename T>
auto allocator<T>::destroy(T * first, T * last) -> void
{
	if(first>=ptr_&&last<=ptr_+this->count())
	for (; first != last; ++first)
	{
		destroy(&*first);
	}
}

template<typename T>
auto allocator<T>::get()-> T*
{
	return ptr_;
}

template<typename T>
auto allocator<T>::get() const -> T const *
{
	return ptr_;
}

template<typename T>
auto allocator<T>::count() const -> size_t
{
	return map_->counter();
}

template<typename T>
auto allocator<T>::full() const -> bool
{
	return map_->counter()==size_;
}

template<typename T>
auto allocator<T>::empty() const -> bool
{
	return map_->counter()==0;
}

template<typename T>
auto allocator<T>::swap(allocator & other) -> void
{
	std::swap(ptr_, other.ptr_);
	std::swap(map_, other.map_);
	std::swap(size_, other.size_);
}

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

template <typename T>
class stack : private allocator<T>
{
public:
	explicit
	stack(size_t size = 0);								//noexcept
	auto pop() -> void;
	auto top() -> T &;
	auto top() const -> T const &;
	auto push(T const &vaule) -> void;							//strong
	auto operator=(stack const & right)->stack &;					//strong
	auto empty() const -> bool; 							//noexcept
	auto count() const -> size_t;
private:
	allocator<T> allocator_;
	auto throw_is_empty() const -> void;
};

template <typename T>
size_t stack<T>::count() const
{
	return allocator_.count();
}
template <typename T>
stack<T>::stack(size_t size):allocator_(size){}

template <typename T>
void stack<T>::push(T const &item)
{
	if (allocator_.full()) allocator_.resize();
	allocator_.construct(allocator_.get() + this->count(), item);
}
template<typename T>
void stack<T>::pop()
{
	if (this->count() > 0)
		allocator_.destroy(allocator_.get() + (this->count()-1));
	else
		throw_is_empty();
}

template<typename T>
auto stack<T>::top() -> T &
{
	if (allocator_.count() == 0) {
		throw_is_empty();
	}
	return (*(allocator_.get() + allocator_.count() - 1));
}

template<typename T>
auto stack<T>::top() const -> T const &
{
	if (allocator_.count() == 0)
	{
		throw_is_empty();
	}
	return (*(allocator_.get() + allocator_.count() - 1));
}

template<typename T>
auto stack<T>::operator=(stack const & right)-> stack &
{
	if (this != &right)
	{
		(allocator<T>(right.allocator_)).swap(allocator_);
	}
	return *this;
}

template<typename T>
auto stack<T>::empty() const -> bool
{
	return allocator_.empty();
}

template<typename T>
auto stack<T>::throw_is_empty() const -> void
{
		throw("Stack is empty!");
}
#endif
<|endoftext|>


<commit_before>#ifndef NEW_AIO_H
#define NEW_AIO_H

/*Defines virtual AIO objects to be instantiated
by concrete implementation in the src/ file.
*/

#include<string>
#include<stdexcept>

#include<boost/shared_ptr.hpp>

class Process;
class Symbol;

/*
The "new" AIO is based on event objects.  Event
objects are just passive requests; in order to
"arm" an event, it should be added to the global
event waiting set object.

Events are:
1.  Write-to-I/O event
2.  Read-from-I/O event
3.  Accept-from-I/O Socket event
4.  Sleep Event
5.  System Event (i.e. spawn child OS process)
*/

/*Details are handled by the AIO implementation
This include file deals only in abstractions;
we don't care how they are actually implemented.
*/

class Event;
class ProcessInvoker;

/*Errors in I/O should throw this class*/
/*Could use a Maybe T type I suppose though*/
class IOError : public std::runtime_error {
};

/*-----------------------------------------------------------------------------
Implementation-specific
-----------------------------------------------------------------------------*/

/*I/O Ports*/
class IOPort {
public:
	void close(void);

	virtual boost::shared_ptr<Event> read(
		boost::shared_ptr<ProcessInvoker>, size_t
	) =0;
	virtual boost::shared_ptr<Event> write(boost::shared_ptr<ProcessInvoker>,
		std::vector<unsigned char> const&
	) =0;
	virtual boost::shared_ptr<Event> accept(
		boost::shared_ptr<ProcessInvoker>
	) =0;

	virtual ~IOPort() { }
};

/*Will only be called once, at init*/
boost::shared_ptr<IOPort> ioport_stdin(void);
boost::shared_ptr<IOPort> ioport_stdout(void);
boost::shared_ptr<IOPort> ioport_stderr(void);

boost::shared_ptr<IOPort> infile(std::string);
boost::shared_ptr<IOPort> outfile(std::string);
boost::shared_ptr<IOPort> appendfile(std::string);

class Event {
public:

	virtual ~Event() { }
};

boost::shared_ptr<Event> system_event(boost::shared_ptr<ProcessInvoker>,std::string);
boost::shared_ptr<Event> sleep_event(boost::shared_ptr<ProcessInvoker>,size_t);

/*used as a Singleton, although we don't enforce it*/
class EventSetImpl;
class EventSet {
private:
	EventSetImpl* pimpl;

public:
	void add_event(boost::shared_ptr<Event>);
	void remove_event(boost::shared_ptr<Event>);

	EventSet(void);
	~EventSet();
};

/*-----------------------------------------------------------------------------
Shared across Implementations
-----------------------------------------------------------------------------*/

/*implementations in src/new_aio.cpp*/

class ProcessInvoker {
private:
	Process* P;
public:
	void read_respond(
		boost::shared_ptr<IOPort>, std::vector<unsigned char> const&
	);
	void write_respond(
		boost::shared_ptr<IOPort>, std::vector<unsigned char> const&
	);
	void accept_respond(
		boost::shared_ptr<IOPort> socket, boost::shared_ptr<IOPort> new_socket
	);
	void sleep_respond(
		boost::shared_ptr<Event>, size_t
	);
	void system_respond(
		boost::shared_ptr<Event>, int term_code
	);
};

#endif // NEW_AIO_H

<commit_msg>inc/new_aio.hpp: Moved development of new AIO to its own branch, new_aio<commit_after><|endoftext|>


<commit_before>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
using namespace std;
template <typename T>
class stack
{
public:
	stack();
	stack(stack const &);
	~stack();
	size_t count() const;
	auto push(T const &) -> void;
	auto copy_(T * item, size_t size, size_t count) -> T*;
	T pop();
	auto operator=(stack const & right)->stack &;
private:
	T * array_;
	size_t array_size_;
	size_t count_;
};

template <typename T>
size_t stack<T>::count() const
{
	return count_;
}
template <typename T>
stack<T>::stack()
{
	array_size_ = 0;
	array_ = new T[array_size_];
	count_ = 0;
}

template<typename T>
stack<T>::stack(stack const & item):array_size_(item.array_size_), count_(item.count_),array_(copy_(item.array_, item.array_size_,item.count_))
{

}

template <typename T>
stack<T>::~stack()
{
	delete[] array_;
}

template<typename T>
auto stack<T>::push(T const & item) -> void {
	if (count_ == array_size_) {
		size_t size = array_size_ * 2 + (array_size_ == 0) ;
		delete[] array_;
		array_ = copy_(array_, size, array_size_);
		array_size_ = size;
	}
	++count_;
	array_[count_ - 1] = item;
}
template<typename T>
auto stack<T>::copy_(T * item, size_t size, size_t count) -> T* {
	T * buff = new T[size];
	copy(item, item + count, buff);
	return buff;
}

template<typename T>
T stack<T>::pop() {
	if (count_ == 0) {
		throw std::logic_error("Stack is empty!");
	}
	return array_[--count_];
}
template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right) {
	delete[] array_;
	count_ = right.count_;
	array_size_ = right.array_size_;
	copy_(right.array_, array_size_, count_);
	}
	return *this;
}

#endif
<commit_msg>Update stack.cpp<commit_after>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
using namespace std;
template<typename>
auto newcopy(T * item, size_t size, size_t count) -> T*
{
	T * buff = new T[size];
	copy(item, item + count, buff);
	return buff;
}
template <typename T>
class stack
{
public:
	stack();
	stack(stack const &);
	~stack();
	size_t count() const;
	auto push(T const &) -> void;
	T pop();
	auto operator=(stack const & right)->stack &;
private:
	T * array_;
	size_t array_size_;
	size_t count_;
};
template <typename T>
size_t stack<T>::count() const
{
	return count_;
}
template <typename T>
stack<T>::stack():array_size_(0), count(0), array_(new T[array_size_])
{

}

template<typename T>
stack<T>::stack(stack const & item):array_size_(item.array_size_), count_(item.count_),array_(newcopy(item.array_, item.array_size_,item.count_))
{

}

template <typename T>
stack<T>::~stack()
{
	delete[] array_;
}

template<typename T>
auto stack<T>::push(T const & item) -> void {
	if (count_ == array_size_) {
		size_t size = array_size_ * 2 + (array_size_ == 0) ;
		delete[] array_;
		array_ = newcopy(array_, size, array_size_);
		array_size_ = size;
	}
	++count_;
	array_[count_ - 1] = item;
}

template<typename T>
T stack<T>::pop() {
	if (count_ == 0) {
		throw std::logic_error("Stack is empty!");
	}
	return array_[--count_];
}
template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right) {
	delete[] array_;
	count_ = right.count_;
	array_size_ = right.array_size_;
	newcopy(right.array_, array_size_, count_);
	}
	return *this;
}

#endif
<|endoftext|>


<commit_before><commit_msg>Creation of the Map.hpp.<commit_after>/*******************************************************************************************
 * This file is created to implement the class Duck for our game called PapraGame.	*
 * This file will allow us to have all the method to control the duck for the game.		*
 * This file are under licence Mozilla Public License Version 2.0					*
 * Author : Barbier Julien, julien.barbier@utbm.fr								*
 * Date of creation : 01/19/2016											*
 * *****************************************************************************************/

 #ifndef MAP_HPP_INCLUDED
 #define MAP_HPP_INCLUDED

 #include <Coord>
 #include <SFML/Graphics>
 #include <enum>

 #define NB_TEXTURE 8

 class Map {

	 public :

		/**
		 * @brief Destroy the class Map
		 */

		~Map();

		/**
		 * @brief Creation of Map by default.
		 */

		Map () {};

		/**
		 * @brief Creation of map with all the parametre needed.
		 * @param x The lenght of the map
		 * @param y The width of the map
		 * @param smap[x][y] The map himself with the lenght and the width.
		 * @param texture[NB_TEXTURE] Array which will contain the texture for this game.
		 * @param egg_texture Contain the texture of the egg.
		 */

		Map(unsigned char x, unsigned char y, Area smap[x][y], const String& texture[NB_TEXTURE], const String& egg_texture);

		/**
		 * @brief Change the coordinates of the egg and print him.
		 * @param egg_coord The coordinate of the egg to initialize coordinate_egg(Map) and
		 */

		void popEgg (Coord egg_coord);

		/**
		 * @brief Print a send case in the screen.
		 * @param coord The coordinate of the case we want to convert.
		 */

		void print(Coord coord);

		/**
		 * @brief printAll Print all the map.
		 */

		void printAll();

	 private :

		unsigned char x_size;
		unsigned char y_size;
		sf::Texture sprites[NB_TEXTURE];
		Coord coordinate_egg;
		sf::Texture egg_sprite;
		Area map [] [];
 };

 #endif /* MAPP_HPP_INCLUDED*/

 <|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <stdexcept>

template <typename T>
class stack
{
public:
	stack() noexcept;
	~stack() noexcept;
	stack(stack<T> const&)/*no safety*/;
	stack& operator=(stack<T> const&)/*no safety*/;
	size_t count()const noexcept;
	void push(T const&)/*no safety*/;
	void pop()/*no safety*/;
	T top()const /*no safety*/;
	void print(std::ostream&stream)const /*strong*/;
	void swap(stack<T>&)noexcept;
	bool empty()const noexcept;
private:
	T * array_;
	size_t array_size_;
	size_t count_;
};

template <typename T>
stack<T>::stack() noexcept : array_{ nullptr }, array_size_{ 0 }, count_{ 0 } {}
template <typename T>
stack<T>::~stack()noexcept
{
	delete[] array_;
}
template <typename T>
stack<T>::stack(stack<T> const& other)
{
	array_size_ = other.array_size_;
	count_ = other.count_;
	std::copy(other.array_, other.array_ + count_, array_);
}
template <typename T>
stack<T>& stack<T>::operator=(stack<T> const & other)
{
	if (&other != this)
		stack(other).swap(*this);
	return *this;
}
template <typename T>
size_t stack<T>::count()const noexcept
{
	return count_;
}
template <typename T>
void stack<T>::push(T const & value)
{
	if (empty())
	{
		array_size_ = 1;
		array_ = new T[array_size_]();
	}
	else if (array_size_ == count_)
	{
		array_size_ *= 2;
		T * new_array = new T[array_size_]();
		std::copy(array_, array_ + count_, new_array);
		delete[] array_;
		array_ = new_array;
	}
	array_[count_++] = value;
}
template <typename T>
void stack<T>::pop()
{
	if (empty())
		throw std::logic_error("Stack is empty");
	--count_;
}
template <typename T>
T stack<T>::top()const
{
	if (empty())
		throw std::logic_error("Stack is empty");
	else return array_[count_ - 1];
}
template <typename T>
void stack<T>::print(std::ostream&stream)const
{
	if(!empty())
	{
	        for (unsigned int i = 0; i < count_; ++i)
		        stream << array_[i] << " ";
	        stream << std::endl;
	}
}
template <typename T>
void stack<T>::swap(stack<T>& other)noexcept
{
	std::swap(array_, other.array_);
	std::swap(array_size_, other.array_size_);
	std::swap(count_, other.count_);
}
template <typename T>
bool stack<T>::empty()const noexcept
{
	return (count_ == 0);
}
<commit_msg>Update stack.hpp<commit_after>#include <iostream>
#include <algorithm>
#include <stdexcept>

template <typename T>
class stack
{
public:
	stack() noexcept;
	~stack() noexcept;
	stack(stack<T> const&)/*no safety*/;
	stack& operator=(stack<T> const&)/*no safety*/;
	size_t count()const noexcept;
	void push(T const&)/*no safety*/;
	void pop()/*strong*/;
	T top()const /*strong*/;
	void print(std::ostream&stream)const /*strong*/;
	void swap(stack<T>&)noexcept;
	bool empty()const noexcept;
private:
	T * array_;
	size_t array_size_;
	size_t count_;
};

template <typename T>
stack<T>::stack() noexcept : array_{ nullptr }, array_size_{ 0 }, count_{ 0 } {}
template <typename T>
stack<T>::~stack()noexcept
{
	delete[] array_;
}
template <typename T>
stack<T>::stack(stack<T> const& other)
{
	array_size_ = other.array_size_;
	count_ = other.count_;
	std::copy(other.array_, other.array_ + count_, array_);
}
template <typename T>
stack<T>& stack<T>::operator=(stack<T> const & other)
{
	if (&other != this)
		stack(other).swap(*this);
	return *this;
}
template <typename T>
size_t stack<T>::count()const noexcept
{
	return count_;
}
template <typename T>
void stack<T>::push(T const & value)
{
	if (empty())
	{
		array_size_ = 1;
		array_ = new T[array_size_]();
	}
	else if (array_size_ == count_)
	{
		array_size_ *= 2;
		T * new_array = new T[array_size_]();
		std::copy(array_, array_ + count_, new_array);
		delete[] array_;
		array_ = new_array;
	}
	array_[count_++] = value;
}
template <typename T>
void stack<T>::pop()
{
	if (empty())
		throw std::logic_error("Stack is empty");
	--count_;
}
template <typename T>
T stack<T>::top()const
{
	if (empty())
		throw std::logic_error("Stack is empty");
	else return array_[count_ - 1];
}
template <typename T>
void stack<T>::print(std::ostream&stream)const
{
	if(!empty())
	{
	        for (unsigned int i = 0; i < count_; ++i)
		        stream << array_[i] << " ";
	        stream << std::endl;
	}
}
template <typename T>
void stack<T>::swap(stack<T>& other)noexcept
{
	std::swap(array_, other.array_);
	std::swap(array_size_, other.array_size_);
	std::swap(count_, other.count_);
}
template <typename T>
bool stack<T>::empty()const noexcept
{
	return (count_ == 0);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <stdexcept>

template <typename T>
class stack
{
public:
	stack();
	~stack()noexcept;
	stack(stack<T> const&)noexcept;
	stack& operator=(stack<T> const&)noexcept;
	size_t count()const noexcept;
	size_t array_size()const noexcept;
	void push(T const&)noexcept;
	void pop()noexcept;
	T top()noexcept;
	void print(std::ostream&stream)const noexcept;
	void swap(stack<T>&)noexcept;
	bool empty()noexcept;
private:
	T * array_;
	size_t array_size_;
	size_t count_;
};

template <typename T>
stack<T>::stack() : array_{ nullptr }, array_size_{ 0 }, count_{ 0 } {}
template <typename T>
stack<T>::~stack()noexcept
{
	delete[] array_;
}
template <typename T>
stack<T>::stack(stack<T> const& other)noexcept
{
	array_size_ = other.array_size_;
	count_ = other.count_;
	std::copy(other.array_, other.array_ + count_, array_);
}
template <typename T>
stack<T>& stack<T>::operator=(stack<T> const & other)noexcept
{
	if (&other != this)
		stack(other).swap(*this);
	return *this;
}
template <typename T>
size_t stack<T>::array_size()const noexcept
{
	return array_size_;
}
template <typename T>
size_t stack<T>::count()const noexcept
{
	return count_;
}
template <typename T>
void stack<T>::push(T const & value)noexcept
{
	if (empty())
	{
		array_size_ = 1;
		array_ = new T[array_size_]();
	}
	else if (array_size_ == count_)
	{
		array_size_ *= 2;
		T * new_array = new T[array_size_]();
		std::copy(array_, array_ + count_, new_array);
		delete[] array_;
		array_ = new_array;
	}
	array_[count_++] = value;
}
template <typename T>
void stack<T>::pop()noexcept
{
	if (empty())
		throw std::logic_error("Stack is empty");
	else
	{
		T * new_array = new T[array_size_]();
		--count_;
		std::copy(array_, array_ + count_, new_array);
		delete[] array_;
		array_ = new_array;
	}
}
template <typename T>
T stack<T>::top()noexcept
{
	if (empty())
		throw std::logic_error("Stack is empty");
	else return array_[count_ - 1];
}
template <typename T>
void stack<T>::print(std::ostream&stream)const noexcept
{
	for (unsigned int i = 0; i < count_; ++i)
		stream << array_[i] << " ";
	stream << std::endl;
}
template <typename T>
void stack<T>::swap(stack<T>& other)noexcept
{
	std::swap(array_, other.array_);
	std::swap(array_size_, other.array_size_);
	std::swap(count_, other.count_);
}
template <typename T>
bool stack<T>::empty()noexcept
{
	return (count_ == 0);
}
<commit_msg>Update stack.hpp<commit_after>#include <iostream>
#include <algorithm>
#include <stdexcept>

template <typename T>
class stack
{
public:
	stack();
	~stack()noexcept;
	stack(stack<T> const&)basic;
	stack& operator=(stack<T> const&)noexcept;
	size_t count()const noexcept;
	size_t array_size()const noexcept;
	void push(T const&)basic;
	void pop()basic;
	T top()const noexcept;
	void print(std::ostream&stream)const noexcept;
	void swap(stack<T>&)noexcept;
	bool empty()const noexcept;
private:
	T * array_;
	size_t array_size_;
	size_t count_;
};

template <typename T>
stack<T>::stack() : array_{ nullptr }, array_size_{ 0 }, count_{ 0 } {}
template <typename T>
stack<T>::~stack()noexcept
{
	delete[] array_;
}
template <typename T>
stack<T>::stack(stack<T> const& other)basic
{
	array_size_ = other.array_size_;
	count_ = other.count_;
	std::copy(other.array_, other.array_ + count_, array_);
}
template <typename T>
stack<T>& stack<T>::operator=(stack<T> const & other)noexcept
{
	if (&other != this)
		stack(other).swap(*this);
	return *this;
}
template <typename T>
size_t stack<T>::array_size()const noexcept
{
	return array_size_;
}
template <typename T>
size_t stack<T>::count()const noexcept
{
	return count_;
}
template <typename T>
void stack<T>::push(T const & value)basic
{
	if (empty())
	{
		array_size_ = 1;
		array_ = new T[array_size_]();
	}
	else if (array_size_ == count_)
	{
		array_size_ *= 2;
		T * new_array = new T[array_size_]();
		std::copy(array_, array_ + count_, new_array);
		delete[] array_;
		array_ = new_array;
	}
	array_[count_++] = value;
}
template <typename T>
void stack<T>::pop()basic
{
	if (empty())
		throw std::logic_error("Stack is empty");
	else
	{
		T * new_array = new T[array_size_]();
		--count_;
		std::copy(array_, array_ + count_, new_array);
		delete[] array_;
		array_ = new_array;
	}
}
template <typename T>
T stack<T>::top()const noexcept
{
	if (empty())
		throw std::logic_error("Stack is empty");
	else return array_[count_ - 1];
}
template <typename T>
void stack<T>::print(std::ostream&stream)const noexcept
{
	for (unsigned int i = 0; i < count_; ++i)
		stream << array_[i] << " ";
	stream << std::endl;
}
template <typename T>
void stack<T>::swap(stack<T>& other)noexcept
{
	std::swap(array_, other.array_);
	std::swap(array_size_, other.array_size_);
	std::swap(count_, other.count_);
}
template <typename T>
bool stack<T>::empty()const noexcept
{
	return (count_ == 0);
}
<|endoftext|>


<commit_before>// Simple version of std::bind that doesn't support placeholders

#pragma once

#include <tuple>
#include <utility>

// __bind_call generates a list of integers 0 .. N-1 ...
template <int N, typename F, typename Res, typename TArgs, int... list>
struct __bind_call {
  static Res call(F& f, TArgs& t) {
    return __bind_call<N - 1, F, Res, TArgs, N - 1, list...>::call(f, t);
  }
};

// ... which the __bind_call base case unpacks to get a sequence of
// tuple indexes to pass to std::get to extract the saved arguments
// from the tuple t.
template <typename F, typename Res, typename TArgs, int... list>
struct __bind_call<0, F, Res, TArgs, list...> {
  static Res call(F& f, TArgs& t) {
    return f(std::get<list>(t)...);
  }
};

template <typename F, typename Res, typename... Args>
struct __bind_helper
{
  typedef std::tuple<Args...> TArgs;

  F f_;
  TArgs args_;

  __bind_helper(F&& f, Args&&... args) : f_(f), args_(args...) { }

  Res operator()()
  {
    return __bind_call<sizeof...(Args), F, Res, TArgs>::
      call(f_, args_);
  }
};

template <typename F, typename... Args>
auto bind_simple(F&& f, Args&&... args)
  -> __bind_helper<F, decltype(f(args...)), Args...>
{
  return __bind_helper<F, decltype(f(args...)), Args...>(
    std::forward<F>(f), std::forward<Args>(args)...);
}
<commit_msg>lib: Decay argument types to bind_simple<commit_after>// Simple version of std::bind that doesn't support placeholders

#pragma once

#include <tuple>
#include <utility>

// __bind_call generates a list of integers 0 .. N-1 ...
template <int N, typename F, typename Res, typename TArgs, int... list>
struct __bind_call {
  static Res call(F& f, TArgs& t) {
    return __bind_call<N - 1, F, Res, TArgs, N - 1, list...>::call(f, t);
  }
};

// ... which the __bind_call base case unpacks to get a sequence of
// tuple indexes to pass to std::get to extract the saved arguments
// from the tuple t.
template <typename F, typename Res, typename TArgs, int... list>
struct __bind_call<0, F, Res, TArgs, list...> {
  static Res call(F& f, TArgs& t) {
    return f(std::get<list>(t)...);
  }
};

template <typename F, typename Res, typename... Args>
struct __bind_helper
{
  typedef std::tuple<typename std::decay<Args>::type...> TArgs;

  F f_;
  TArgs args_;

  __bind_helper(F&& f, Args&&... args) : f_(f), args_(args...) { }

  Res operator()()
  {
    return __bind_call<sizeof...(Args), F, Res, TArgs>::
      call(f_, args_);
  }
};

template <typename F, typename... Args>
auto bind_simple(F&& f, Args&&... args)
  -> __bind_helper<F, decltype(f(args...)), Args...>
{
  return __bind_helper<F, decltype(f(args...)), Args...>(
    std::forward<F>(f), std::forward<Args>(args)...);
}
<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include <iterator>

namespace helene
{

template <class NodeType, class EdgeType>
class dag
{
public:
    ////////////////////////////////////////////////////////////////////////////
    // public typedefs

    typedef NodeType value_type;
    typedef NodeType& reference;
    typedef const NodeType& const_reference;

    typedef typename std::vector<NodeType>::difference_type difference_type;
    typedef typename std::vector<NodeType>::size_type size_type;

    typedef typename std::vector<NodeType>::iterator iterator;
    typedef typename std::vector<NodeType>::const_iterator const_iterator;

    typedef EdgeType edge_value_type;
    typedef EdgeType& edge_reference;
    typedef const EdgeType& const_edge_reference;

    typedef typename std::vector<EdgeType>::size_type edge_size_type;
    typedef
        typename std::vector<EdgeType>::difference_type edge_difference_type;

    typedef typename std::vector<EdgeType>::iterator edge_iterator;
    typedef typename std::vector<EdgeType>::const_iterator edge_const_iterator;

private:
    ////////////////////////////////////////////////////////////////////////////
    // internal classes

    // indices to properties of the associated edge
    struct edge
    {
        edge(size_type from, size_type to, edge_size_type edge_index)
            : from_property(from), to_property(to), edge_property(edge_index)
        {
        }

        size_type from_property;
        size_type to_property;
        edge_size_type edge_property;

        bool
        operator==(const edge& other) const
        {
            return (from_property == other.from_property) &&
                   (to_property == other.to_property) &&
                   (edge_property == other.edge_property);
        }
    };

public:
    ////////////////////////////////////////////////////////////////////////////
    // Container concept member functions

    dag() = default;
    dag(const dag&) = default;

    dag& operator=(const dag&) = default;

    iterator
    begin()
    {
        return node_properties_.begin();
    }

    iterator
    end()
    {
        return node_properties_.end();
    }

    const_iterator
    cbegin() const
    {
        return node_properties_.cbegin();
    }

    const_iterator
    cend() const
    {
        return node_properties_.cend();
    }

    edge_iterator
    edge_begin()
    {
        return edge_properties_.begin();
    }

    edge_iterator
    edge_end()
    {
        return edge_properties_.end();
    }

    edge_const_iterator
    edge_cbegin() const
    {
        return edge_properties_.cbegin();
    }

    edge_const_iterator
    edge_cend() const
    {
        return edge_properties_.cend();
    }

    bool
    operator==(const dag& other) const
    {
        return (node_properties_ == other.node_properties_) &&
               (edge_properties_ == other.edge_properties_) &&
               (edges_ == other.edges_);
    }

    bool
    operator!=(const dag& other) const
    {
        return !(*this == other);
    }

    void
    swap(dag& other)
    {
        node_properties_.swap(other.node_properties_);
        edge_properties_.swap(other.edge_properties_);
        edges_.swap(other.edges_);
    }

public:
    ////////////////////////////////////////////////////////////////////////////
    // dag specific member functions

    // Add node
    iterator
    add_node(const NodeType& prop)
    {
        node_properties_.push_back(prop);
        return std::prev(node_properties_.end());
    }

    // Add edge between nodes.
    // If edge introduces cycle edge will not be inserted.
    // Returns iterator to edge property or edge_end() if edge was prevented
    // from being inserted.
    edge_iterator
    add_edge(const_iterator from, const_iterator to, const EdgeType& prop)
    {
        // TODO: check for cycle
        edges_.emplace_back(from - cbegin(), to - cbegin(), edges_.size());
        edge_properties_.push_back(prop);
        return std::prev(edge_properties_.end());
    }

private:
    std::vector<NodeType> node_properties_;
    std::vector<EdgeType> edge_properties_;

    std::vector<edge> edges_;
};
}
<commit_msg>Add empty declaration of start_node_iterator_ and typedefs in dag. 	modified:   include/dag.hpp<commit_after>#pragma once

#include <vector>
#include <iterator>

namespace helene
{

class start_node_iterator_
{
};

template <class NodeType, class EdgeType>
class dag
{
public:
    ////////////////////////////////////////////////////////////////////////////
    // public typedefs

    typedef NodeType value_type;
    typedef NodeType& reference;
    typedef const NodeType& const_reference;

    typedef typename std::vector<NodeType>::difference_type difference_type;
    typedef typename std::vector<NodeType>::size_type size_type;

    typedef typename std::vector<NodeType>::iterator iterator;
    typedef typename std::vector<NodeType>::const_iterator const_iterator;

    typedef EdgeType edge_value_type;
    typedef EdgeType& edge_reference;
    typedef const EdgeType& const_edge_reference;

    typedef typename std::vector<EdgeType>::size_type edge_size_type;
    typedef
        typename std::vector<EdgeType>::difference_type edge_difference_type;

    typedef typename std::vector<EdgeType>::iterator edge_iterator;
    typedef typename std::vector<EdgeType>::const_iterator edge_const_iterator;

    // iterator typedefs
    typedef start_node_iterator_ start_node_iterator;
    typedef const start_node_iterator const_start_node_iterator;

private:
    ////////////////////////////////////////////////////////////////////////////
    // internal classes

    // indices to properties of the associated edge
    struct edge
    {
        edge(size_type from, size_type to, edge_size_type edge_index)
            : from_property(from), to_property(to), edge_property(edge_index)
        {
        }

        size_type from_property;
        size_type to_property;
        edge_size_type edge_property;

        bool
        operator==(const edge& other) const
        {
            return (from_property == other.from_property) &&
                   (to_property == other.to_property) &&
                   (edge_property == other.edge_property);
        }
    };

public:
    ////////////////////////////////////////////////////////////////////////////
    // Container concept member functions

    dag() = default;
    dag(const dag&) = default;

    dag& operator=(const dag&) = default;

    iterator
    begin()
    {
        return node_properties_.begin();
    }

    iterator
    end()
    {
        return node_properties_.end();
    }

    const_iterator
    cbegin() const
    {
        return node_properties_.cbegin();
    }

    const_iterator
    cend() const
    {
        return node_properties_.cend();
    }

    edge_iterator
    edge_begin()
    {
        return edge_properties_.begin();
    }

    edge_iterator
    edge_end()
    {
        return edge_properties_.end();
    }

    edge_const_iterator
    edge_cbegin() const
    {
        return edge_properties_.cbegin();
    }

    edge_const_iterator
    edge_cend() const
    {
        return edge_properties_.cend();
    }

    bool
    operator==(const dag& other) const
    {
        return (node_properties_ == other.node_properties_) &&
               (edge_properties_ == other.edge_properties_) &&
               (edges_ == other.edges_);
    }

    bool
    operator!=(const dag& other) const
    {
        return !(*this == other);
    }

    void
    swap(dag& other)
    {
        node_properties_.swap(other.node_properties_);
        edge_properties_.swap(other.edge_properties_);
        edges_.swap(other.edges_);
    }

public:
    ////////////////////////////////////////////////////////////////////////////
    // dag specific member functions

    // Add node
    iterator
    add_node(const NodeType& prop)
    {
        node_properties_.push_back(prop);
        return std::prev(node_properties_.end());
    }

    // Add edge between nodes.
    // If edge introduces cycle edge will not be inserted.
    // Returns iterator to edge property or edge_end() if edge was prevented
    // from being inserted.
    edge_iterator
    add_edge(const_iterator from, const_iterator to, const EdgeType& prop)
    {
        // TODO: check for cycle
        edges_.emplace_back(from - cbegin(), to - cbegin(), edges_.size());
        edge_properties_.push_back(prop);
        return std::prev(edge_properties_.end());
    }

private:
    std::vector<NodeType> node_properties_;
    std::vector<EdgeType> edge_properties_;

    std::vector<edge> edges_;
};
}
<|endoftext|>


<commit_before>/* Copyright 2017 Istio Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "src/grpc_transport.h"
#include <mutex>
#include <thread>

namespace istio {
namespace mixer_client {
namespace {

// A gRPC stream
template <class RequestType, class ResponseType>
class GrpcStream final : public WriteInterface<RequestType> {
 public:
  typedef std::unique_ptr<
      ::grpc::ClientReaderWriterInterface<RequestType, ResponseType>>
      StreamPtr;
  typedef std::function<StreamPtr(::grpc::ClientContext&)> StreamNewFunc;

  GrpcStream(ReadInterface<ResponseType>* reader, StreamNewFunc create_func)
      : reader_(reader), write_closed_(false) {
    context_.set_fail_fast(true);
    stream_ = create_func(context_);
  }

  static void Start(
      std::shared_ptr<GrpcStream<RequestType, ResponseType>> grpc_stream) {
    std::thread t([grpc_stream]() { grpc_stream->ReadMainLoop(); });
    t.detach();
  }

  void Write(const RequestType& request) override {
    std::lock_guard<std::mutex> lock(write_mutex_);
    if (!stream_->Write(request)) {
      write_closed_ = true;
    }
  }

  void WritesDone() override {
    std::lock_guard<std::mutex> lock(write_mutex_);
    stream_->WritesDone();
    write_closed_ = true;
  }

  bool is_write_closed() const override { return write_closed_; }

 private:
  // The worker loop to read response messages.
  void ReadMainLoop() {
    ResponseType response;
    while (stream_->Read(&response)) {
      reader_->OnRead(response);
    }
    ::grpc::Status status = stream_->Finish();
    // Convert grpc status to protobuf status.
    ::google::protobuf::util::Status pb_status(
        ::google::protobuf::util::error::Code(status.error_code()),
        ::google::protobuf::StringPiece(status.error_message()));
    reader_->OnClose(pb_status);
  }

  // The client context.
  ::grpc::ClientContext context_;
  // Mutex to make sure not calling stream_->Write() parallelly.
  std::mutex write_mutex_;
  // The reader writer stream.
  StreamPtr stream_;
  // The reader interface from caller.
  ReadInterface<ResponseType>* reader_;
  // Indicates if write is closed.
  bool write_closed_;
};

typedef GrpcStream<::istio::mixer::v1::CheckRequest,
                   ::istio::mixer::v1::CheckResponse>
    CheckGrpcStream;
typedef GrpcStream<::istio::mixer::v1::ReportRequest,
                   ::istio::mixer::v1::ReportResponse>
    ReportGrpcStream;
typedef GrpcStream<::istio::mixer::v1::QuotaRequest,
                   ::istio::mixer::v1::QuotaResponse>
    QuotaGrpcStream;

}  // namespace

GrpcTransport::GrpcTransport(const std::string& mixer_server) {
  channel_ = CreateChannel(mixer_server, ::grpc::InsecureChannelCredentials());
  stub_ = ::istio::mixer::v1::Mixer::NewStub(channel_);
}

CheckWriterPtr GrpcTransport::NewStream(CheckReaderRawPtr reader) {
  auto writer = std::make_shared<CheckGrpcStream>(
      reader,
      [this](::grpc::ClientContext& context) -> CheckGrpcStream::StreamPtr {
        return stub_->Check(&context);
      });
  CheckGrpcStream::Start(writer);
  return writer;
}

ReportWriterPtr GrpcTransport::NewStream(ReportReaderRawPtr reader) {
  auto writer = std::make_shared<ReportGrpcStream>(
      reader,
      [this](::grpc::ClientContext& context) -> ReportGrpcStream::StreamPtr {
        return stub_->Report(&context);
      });
  ReportGrpcStream::Start(writer);
  return writer;
}

QuotaWriterPtr GrpcTransport::NewStream(QuotaReaderRawPtr reader) {
  auto writer = std::make_shared<QuotaGrpcStream>(
      reader,
      [this](::grpc::ClientContext& context) -> QuotaGrpcStream::StreamPtr {
        return stub_->Quota(&context);
      });
  QuotaGrpcStream::Start(writer);
  return writer;
}

}  // namespace mixer_client
}  // namespace istio
<commit_msg>Log message when Stream close. (#66)<commit_after>/* Copyright 2017 Istio Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "src/grpc_transport.h"
#include <mutex>
#include <thread>

namespace istio {
namespace mixer_client {
namespace {

// A gRPC stream
template <class RequestType, class ResponseType>
class GrpcStream final : public WriteInterface<RequestType> {
 public:
  typedef std::unique_ptr<
      ::grpc::ClientReaderWriterInterface<RequestType, ResponseType>>
      StreamPtr;
  typedef std::function<StreamPtr(::grpc::ClientContext&)> StreamNewFunc;

  GrpcStream(ReadInterface<ResponseType>* reader, StreamNewFunc create_func)
      : reader_(reader), write_closed_(false) {
    context_.set_fail_fast(true);
    stream_ = create_func(context_);
  }

  static void Start(
      std::shared_ptr<GrpcStream<RequestType, ResponseType>> grpc_stream) {
    std::thread t([grpc_stream]() { grpc_stream->ReadMainLoop(); });
    t.detach();
  }

  void Write(const RequestType& request) override {
    std::lock_guard<std::mutex> lock(write_mutex_);
    if (!stream_->Write(request)) {
      GOOGLE_LOG(INFO) << "Stream Write failed: half close";
      write_closed_ = true;
    }
  }

  void WritesDone() override {
    std::lock_guard<std::mutex> lock(write_mutex_);
    stream_->WritesDone();
    write_closed_ = true;
  }

  bool is_write_closed() const override { return write_closed_; }

 private:
  // The worker loop to read response messages.
  void ReadMainLoop() {
    ResponseType response;
    while (stream_->Read(&response)) {
      reader_->OnRead(response);
    }
    ::grpc::Status status = stream_->Finish();
    GOOGLE_LOG(INFO) << "Stream Finished with status: "
                     << status.error_message();
    // Convert grpc status to protobuf status.
    ::google::protobuf::util::Status pb_status(
        ::google::protobuf::util::error::Code(status.error_code()),
        ::google::protobuf::StringPiece(status.error_message()));
    reader_->OnClose(pb_status);
  }

  // The client context.
  ::grpc::ClientContext context_;
  // Mutex to make sure not calling stream_->Write() parallelly.
  std::mutex write_mutex_;
  // The reader writer stream.
  StreamPtr stream_;
  // The reader interface from caller.
  ReadInterface<ResponseType>* reader_;
  // Indicates if write is closed.
  bool write_closed_;
};

typedef GrpcStream<::istio::mixer::v1::CheckRequest,
                   ::istio::mixer::v1::CheckResponse>
    CheckGrpcStream;
typedef GrpcStream<::istio::mixer::v1::ReportRequest,
                   ::istio::mixer::v1::ReportResponse>
    ReportGrpcStream;
typedef GrpcStream<::istio::mixer::v1::QuotaRequest,
                   ::istio::mixer::v1::QuotaResponse>
    QuotaGrpcStream;

}  // namespace

GrpcTransport::GrpcTransport(const std::string& mixer_server) {
  channel_ = CreateChannel(mixer_server, ::grpc::InsecureChannelCredentials());
  stub_ = ::istio::mixer::v1::Mixer::NewStub(channel_);
}

CheckWriterPtr GrpcTransport::NewStream(CheckReaderRawPtr reader) {
  auto writer = std::make_shared<CheckGrpcStream>(
      reader,
      [this](::grpc::ClientContext& context) -> CheckGrpcStream::StreamPtr {
        return stub_->Check(&context);
      });
  CheckGrpcStream::Start(writer);
  return writer;
}

ReportWriterPtr GrpcTransport::NewStream(ReportReaderRawPtr reader) {
  auto writer = std::make_shared<ReportGrpcStream>(
      reader,
      [this](::grpc::ClientContext& context) -> ReportGrpcStream::StreamPtr {
        return stub_->Report(&context);
      });
  ReportGrpcStream::Start(writer);
  return writer;
}

QuotaWriterPtr GrpcTransport::NewStream(QuotaReaderRawPtr reader) {
  auto writer = std::make_shared<QuotaGrpcStream>(
      reader,
      [this](::grpc::ClientContext& context) -> QuotaGrpcStream::StreamPtr {
        return stub_->Quota(&context);
      });
  QuotaGrpcStream::Start(writer);
  return writer;
}

}  // namespace mixer_client
}  // namespace istio
<|endoftext|>


<commit_before>#ifndef MJOLNIR_READ_INPUT_FILE
#define MJOLNIR_READ_INPUT_FILE
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/BoundaryCondition.hpp>
#include <mjolnir/core/constants.hpp>
#include <mjolnir/core/SimulatorBase.hpp>
#include <mjolnir/core/SimulatorTraits.hpp>
#include <mjolnir/util/get_toml_value.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/input/read_units.hpp>
#include <memory>

namespace mjolnir
{

template<typename realT>
std::unique_ptr<SimulatorBase>
read_boundary(const toml::Table& data)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_boundary(const toml::Table& data), 0);

    const auto& general = get_toml_value<toml::Table>(data, "general", "<root>");
    const auto boundary =
        get_toml_value<std::string>(general, "boundary", "[general]");

    if(boundary == "Unlimited")
    {
        MJOLNIR_LOG_INFO("boundary is UnlimitedBoundary");
        return read_units<SimulatorTraits<realT, UnlimitedBoundary>>(data);
    }
    else if(boundary == "PeriodicCuboid")
    {
        MJOLNIR_LOG_INFO("boundary is CuboidalPeriodicBoudanry");
        return read_units<SimulatorTraits<realT, CuboidalPeriodicBoundary>>(data);
    }
    else
    {
        throw std::runtime_error(
            "invalid boundary setting (Unlimited|PeriodicCuboid): " + boundary);
    }
}

inline std::unique_ptr<SimulatorBase>
read_precision(const toml::Table& data)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_precision(const toml::Table& data), 0);

    const auto& general = get_toml_value<toml::Table>(data, "general", "<root>");
    const auto prec =
        get_toml_value<std::string>(general, "precision", "[general]");

    if(prec == "double")
    {
        MJOLNIR_LOG_INFO("precision is double");
        return read_boundary<double>(data);
    }
    else if(prec == "float")
    {
        MJOLNIR_LOG_INFO("precision is float");
        return read_boundary<float>(data);
    }
    else
    {
        throw std::runtime_error(
                "invalid precision setting (double|float): " + prec);
    }
}

inline std::unique_ptr<SimulatorBase>
read_input_file(const std::string& filename)
{
    const auto data = toml::parse(filename);

    // setting logger ...
    const auto& general = get_toml_value<toml::Table>(data, "general", "<root>");
    std::string path = get_toml_value<std::string>(general, "output_path", "[general]");
    if(path.back() != '/') {path += '/';/*XXX assuming posix */}

    const std::string logger_name = path + get_toml_value<std::string>(
            general, "output_prefix", "[general]") + ".log";
    MJOLNIR_SET_DEFAULT_LOGGER(logger_name);

    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_input_file(const toml::Table& data), 0);

    return read_precision(data); // read all the settings recursively...
}

}// mjolnir
#endif// MJOLNIR_READ_INPUT_FILE
<commit_msg>update top level read_input_file<commit_after>#ifndef MJOLNIR_READ_INPUT_FILE
#define MJOLNIR_READ_INPUT_FILE
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/BoundaryCondition.hpp>
#include <mjolnir/core/constants.hpp>
#include <mjolnir/core/SimulatorBase.hpp>
#include <mjolnir/core/SimulatorTraits.hpp>
#include <mjolnir/util/get_toml_value.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/input/read_units.hpp>
#include <memory>

namespace mjolnir
{

template<typename realT>
std::unique_ptr<SimulatorBase>
read_boundary(const toml::Table& data)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_boundary(const toml::Table& data), 0);

    // [simulator] can be provided in a different file. in that case, the table
    // has `file_name` field. In that case, input_path is also needed to
    // determine the location of the file.

    std::string boundary;

    const auto& simulator =
        get_toml_value<toml::Table>(data, "simulator", "<root>");

    if(simulator.count("file_name") == 1)
    {
        const auto filename = toml::get<std::string>(simulator.at("file_name"));
        std::string input_path; //default: empty

        const auto& files = get_toml_value<toml::Table>(data, "files", "<root>");
        if(files.count("input_path") == 1)
        {
            input_path = toml::get<std::string>(files.at("input_path"));
        }

        const auto& sim = toml::parse(input_path + filename);
        boundary = get_toml_value<std::string>(
                sim, "boundary_type", "[simulator]");
    }
    else
    {
        boundary = get_toml_value<std::string>(
                simulator, "boundary_type", "[simulator]");
    }

    if(boundary == "Unlimited")
    {
        MJOLNIR_LOG_INFO("boundary is UnlimitedBoundary");
        return read_units<SimulatorTraits<realT, UnlimitedBoundary>>(data);
    }
    else if(boundary == "PeriodicCuboid")
    {
        MJOLNIR_LOG_INFO("boundary is CuboidalPeriodicBoudanry");
        return read_units<SimulatorTraits<realT, CuboidalPeriodicBoundary>>(data);
    }
    else
    {
        throw_exception<std::runtime_error>("mjolnir::read_boundary: "
            "invalid boundary: neither 'Unlimited' or 'PeriodicCuboid' -> ",
            boundary);
    }
}

inline std::unique_ptr<SimulatorBase>
read_precision(const toml::Table& data)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_precision(const toml::Table& data), 0);

    // [simulator] can be provided in a different file. in that case, the table
    // has `file_name` field. In that case, input_path is also needed to
    // determine the location of the file.

    std::string prec;

    const auto& simulator =
        get_toml_value<toml::Table>(data, "simulator", "<root>");

    if(simulator.count("file_name") == 1)
    {
        const auto filename = toml::get<std::string>(simulator.at("file_name"));
        std::string input_path; //default: empty

        const auto& files = get_toml_value<toml::Table>(data, "files", "<root>");
        if(files.count("input_path") == 1)
        {
            input_path = toml::get<std::string>(files.at("input_path"));
        }

        const auto& sim = toml::parse(input_path + filename);
        prec = get_toml_value<std::string>(sim, "precision", "[simulator]");
    }
    else
    {
        prec = get_toml_value<std::string>(simulator, "precision", "[simulator]");
    }

    if(prec == "double")
    {
        MJOLNIR_LOG_INFO("precision is double");
        return read_boundary<double>(data);
    }
    else if(prec == "float")
    {
        MJOLNIR_LOG_INFO("precision is float");
        return read_boundary<float>(data);
    }
    else
    {
        throw_exception<std::runtime_error>("mjolnir::read_precision: "
            "invalid precision: neither 'double' or 'float' -> ", prec);
    }
}

inline std::unique_ptr<SimulatorBase>
read_input_file(const std::string& filename)
{
    const auto data = toml::parse(filename);

    // initializing logger by using output_path and output_prefix ...
    const auto& files = get_toml_value<toml::Table>(data, "files", "<root>");
    const auto  path  = get_toml_value<std::string>(files, "output_path", "[files]");

    // XXX:  Here, this code assumes POSIX. it does not support windows.
    // TODO: Consider using Boost.filesystem to manage path and files
    //       in more elegant and powerful way? After switching C++17,
    //       we can re-write that into std::filesystem.

    const std::string logger_name = path + get_toml_value<std::string>(
            files, "output_prefix", "[files]") + ".log";
    MJOLNIR_SET_DEFAULT_LOGGER(logger_name);

    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_input_file(const toml::Table& data), 0);

    return read_precision(data); // read all the settings recursively...
}

}// mjolnir
#endif// MJOLNIR_READ_INPUT_FILE
<|endoftext|>


<commit_before>#include "Globals.h"
#include "Application.h"
#include "ModuleInput.h"
#include "ImGui/imgui_impl_sdl_gl3.h"

#define MAX_KEYS 300

ModuleInput::ModuleInput(Application* app, bool start_enabled) : Module(app, start_enabled)
{
	keyboard = new KEY_STATE[MAX_KEYS];
	memset(keyboard, KEY_IDLE, sizeof(KEY_STATE) * MAX_KEYS);
	memset(mouseButtons, KEY_IDLE, sizeof(KEY_STATE) * MAX_MOUSE_BUTTONS);
}

// Destructor
ModuleInput::~ModuleInput()
{
	delete[] keyboard;
}

// Called before render is available
bool ModuleInput::Init()
{
	MYLOG("Init SDL input event system");
	bool ret = true;
	SDL_Init(0);

	if(SDL_InitSubSystem(SDL_INIT_EVENTS) < 0)
	{
		MYLOG("SDL_EVENTS could not initialize! SDL_Error: %s\n", SDL_GetError());
		ret = false;
	}

	return ret;
}

// Called every draw update
update_status ModuleInput::PreUpdate(float dt)
{
	SDL_PumpEvents();

	const Uint8* keys = SDL_GetKeyboardState(NULL);

	for(int i = 0; i < MAX_KEYS; ++i)
	{
		if(keys[i] == 1)
		{
			if(keyboard[i] == KEY_IDLE)
				keyboard[i] = KEY_DOWN;
			else
				keyboard[i] = KEY_REPEAT;
		}
		else
		{
			if(keyboard[i] == KEY_REPEAT || keyboard[i] == KEY_DOWN)
				keyboard[i] = KEY_UP;
			else
				keyboard[i] = KEY_IDLE;
		}
	}

	Uint32 buttons = SDL_GetMouseState(&mouseX, &mouseY);

	mouseX /= SCREEN_SIZE;
	mouseY /= SCREEN_SIZE;
	mouseZ = 0;

	for(int i = 0; i < 5; ++i)
	{
		if(buttons & SDL_BUTTON(i))
		{
			if(mouseButtons[i] == KEY_IDLE)
				mouseButtons[i] = KEY_DOWN;
			else
				mouseButtons[i] = KEY_REPEAT;
		}
		else
		{
			if(mouseButtons[i] == KEY_REPEAT || mouseButtons[i] == KEY_DOWN)
				mouseButtons[i] = KEY_UP;
			else
				mouseButtons[i] = KEY_IDLE;
		}
	}

	mouseXMotion = mouseYMotion = 0;

	bool quit = false;
	SDL_Event e;
	while(SDL_PollEvent(&e))
	{
		ImGui_ImplSdlGL3_ProcessEvent(&e);

		switch(e.type)
		{
			case SDL_MOUSEWHEEL:
			mouseZ = e.wheel.y;
			break;

			case SDL_MOUSEMOTION:
			{
				mouseX = e.motion.x / SCREEN_SIZE;
				mouseY = e.motion.y / SCREEN_SIZE;

				mouseXMotion = e.motion.xrel / SCREEN_SIZE;
				mouseYMotion = e.motion.yrel / SCREEN_SIZE;
			break;
			}

			case SDL_DROPFILE:
			{
				file_path = e.drop.file; //BE ES LA RUTA
				has_dropped = true;
				SDL_free(e.drop.file);
				break;
			}

			case SDL_QUIT:
			quit = true;
			break;

			case SDL_WINDOWEVENT:
			{
				if (e.window.event == SDL_WINDOWEVENT_RESIZED)
				{
					App->window->UpdateWindowSize();
					App->renderer3D->OnResize(e.window.data1, e.window.data2);
				}
			}
		}
	}

	if(quit == true || keyboard[SDL_SCANCODE_ESCAPE] == KEY_UP)
		return UPDATE_STOP;

	return UPDATE_CONTINUE;
}

void ModuleInput::AddImGui()
{

}

// Called before quitting
bool ModuleInput::CleanUp()
{
	MYLOG("Quitting SDL input event subsystem");
	SDL_QuitSubSystem(SDL_INIT_EVENTS);
	return true;
}

const char * ModuleInput::GetFileDropped()
{
	if (has_dropped)
	{
		return file_path;
	}
	else return nullptr;
	return nullptr;
}
<commit_msg>ModuleInput finished<commit_after>#include "Globals.h"
#include "Application.h"
#include "ModuleInput.h"
#include "ImGui/imgui_impl_sdl_gl3.h"

#define MAX_KEYS 300

ModuleInput::ModuleInput(Application* app, bool start_enabled) : Module(app, start_enabled)
{
	keyboard = new KEY_STATE[MAX_KEYS];
	memset(keyboard, KEY_IDLE, sizeof(KEY_STATE) * MAX_KEYS);
	memset(mouseButtons, KEY_IDLE, sizeof(KEY_STATE) * MAX_MOUSE_BUTTONS);
}

// Destructor
ModuleInput::~ModuleInput()
{
	delete[] keyboard;
}

// Called before render is available
bool ModuleInput::Init()
{
	MYLOG("Init SDL input event system");
	bool ret = true;
	SDL_Init(0);

	if(SDL_InitSubSystem(SDL_INIT_EVENTS) < 0)
	{
		MYLOG("SDL_EVENTS could not initialize! SDL_Error: %s\n", SDL_GetError());
		ret = false;
	}

	return ret;
}

// Called every draw update
update_status ModuleInput::PreUpdate(float dt)
{
	SDL_PumpEvents();

	const Uint8* keys = SDL_GetKeyboardState(NULL);

	for(int i = 0; i < MAX_KEYS; ++i)
	{
		if(keys[i] == 1)
		{
			if(keyboard[i] == KEY_IDLE)
				keyboard[i] = KEY_DOWN;
			else
				keyboard[i] = KEY_REPEAT;
		}
		else
		{
			if(keyboard[i] == KEY_REPEAT || keyboard[i] == KEY_DOWN)
				keyboard[i] = KEY_UP;
			else
				keyboard[i] = KEY_IDLE;
		}
	}

	Uint32 buttons = SDL_GetMouseState(&mouseX, &mouseY);

	mouseX /= SCREEN_SIZE;
	mouseY /= SCREEN_SIZE;
	mouseZ = 0;

	for(int i = 0; i < 5; ++i)
	{
		if(buttons & SDL_BUTTON(i))
		{
			if(mouseButtons[i] == KEY_IDLE)
				mouseButtons[i] = KEY_DOWN;
			else
				mouseButtons[i] = KEY_REPEAT;
		}
		else
		{
			if(mouseButtons[i] == KEY_REPEAT || mouseButtons[i] == KEY_DOWN)
				mouseButtons[i] = KEY_UP;
			else
				mouseButtons[i] = KEY_IDLE;
		}
	}

	mouseXMotion = mouseYMotion = 0;

	bool quit = false;
	SDL_Event e;
	while(SDL_PollEvent(&e))
	{
		ImGui_ImplSdlGL3_ProcessEvent(&e);

		switch(e.type)
		{
			case SDL_MOUSEWHEEL:
			mouseZ = e.wheel.y;
			break;

			case SDL_MOUSEMOTION:
			{
				mouseX = e.motion.x / SCREEN_SIZE;
				mouseY = e.motion.y / SCREEN_SIZE;

				mouseXMotion = e.motion.xrel / SCREEN_SIZE;
				mouseYMotion = e.motion.yrel / SCREEN_SIZE;
			break;
			}

			case SDL_DROPFILE:
			{
				file_path = e.drop.file; //BE ES LA RUTA
				has_dropped = true;
				SDL_free(e.drop.file);
				break;
			}

			case SDL_QUIT:
			quit = true;
			break;

			case SDL_WINDOWEVENT:
			{
				if (e.window.event == SDL_WINDOWEVENT_RESIZED)
				{
					App->window->UpdateWindowSize();
					App->renderer3D->OnResize(e.window.data1, e.window.data2);
				}
			}
		}
	}

	if(quit == true || keyboard[SDL_SCANCODE_ESCAPE] == KEY_UP)
		return UPDATE_STOP;

	return UPDATE_CONTINUE;
}

void ModuleInput::AddImGui()
{
	static char* name = "";
	if (GetFileDropped() != nullptr)
	{
		name = (char*)GetFileDropped();
	}

	if (ImGui::CollapsingHeader("Input"))
	{
		if (ImGui::TreeNodeEx("Mouse", ImGuiTreeNodeFlags_DefaultOpen))
		{
			ImGui::BeginGroup();
			{
				ImGui::Text("Mouse position:");
				ImGui::Text("Mouse motion:");
				ImGui::Text("Mouse wheel:");
				ImGui::EndGroup();
			}
			ImGui::SameLine();
			ImGui::BeginGroup();
			{
				ImGui::Text("%i, %i", GetMouseX(), GetMouseY());
				ImGui::Text("%i, %i", GetMouseXMotion(), GetMouseYMotion());
				ImGui::Text("%i", GetMouseZ());
				ImGui::EndGroup();
			}
			ImGui::TreePop();
		}
		if (ImGui::TreeNodeEx("Files", ImGuiTreeNodeFlags_DefaultOpen))
		{
			ImGui::TextWrapped("Latest dropped file:\n%s", name);
			ImGui::TreePop();
		}
	}
}

// Called before quitting
bool ModuleInput::CleanUp()
{
	MYLOG("Quitting SDL input event subsystem");
	SDL_QuitSubSystem(SDL_INIT_EVENTS);
	return true;
}

const char * ModuleInput::GetFileDropped()
{
	if (has_dropped)
	{
		return file_path;
	}
	else return nullptr;
	return nullptr;
}
<|endoftext|>