<commit_before>// stuff for metropolis
#include <chrono>
#include <random>
#include <functional>
#include <array>
#include <math.h>
#include <cmath>
#include <time.h>

// file I/O stuff
#include <iterator>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

// hyperparameters
#define ITERS 10
#define SIGMA 20
#define TEMPCOEFF 1/10

// image dimensions
// Luckily they are the same. I think I have them confused throughout -G
#define IMG_WIDTH 512
#define IMG_LENGTH 512

//uses brace initialization, so must use the C++11 compiler.
// call as g++ -std=c++11 file-name.pp -o file-handle

// functions for creating matrices
int **new_MatrixI(int row, int col){
		int ** matrix=new int *[row];
		int i,j;
		for(i=0; i<row; i++){
			matrix[i]=new int [col];
		}
		return (matrix);
	}
double **new_MatrixD(int row, int col){
	double ** matrix=new double *[row];
	int i,j;
	for(i=0; i<row; i++){
		matrix[i]=new double [col];
	}
	return (matrix);
}

// functions for deleting matrices (unused, I believe -G)
void del_MatrixI(int **mat, int row){
	int i;
	for(i=0; i<row; i++){
		delete[] mat[i];
	}
	delete[] mat;
}
void del_MatrixD(double **mat, int row){
	int i;
	for(i=0; i<row; i++){
		delete[] mat[i];
	}
	delete[] mat;
}

// functions for copying matrices
void set_eq_I(int* lhs, int* rhs){
	for (int i=0; i<DIM; i++){
		lhs[i]=rhs[i];
	}
}
void set_eq_D(double* lhs, double* rhs){
	for (int i=0; i<DIM; i++){
		lhs[i]=rhs[i];
	}
}

// Does sampling from distributions
class Sample
{
public:
	Sample():
	mt(std::random_device()()),
	G(0,SIGMA)
	{}
	int draw_bern(double);
	void randPerm(int*, int);
	double draw_gauss();
private:
  	std::mt19937 mt;
	std::normal_distribution<double> G;
}; //add constructor and destructor

// returns zero mean gaussian of variance SIGMA
double Sample::draw_gauss(){
	return G(mt);
}

// returns 1 with prob param
int Sample::draw_bern(double param){
	std::discrete_distribution<int> B {1-param, param};
	return B(mt);
}

// permutes a vector
void Sample::randPerm(int* vec, int len){
	// int index=len-1;
	srand(time(NULL));

	int temp, ind;

	for (int i=0; i<len; i++){
		ind=std::rand()%(len-i);
		temp=vec[len-i-1];
		vec[len-i-1]=vec[ind];
		vec[ind]=temp;
	}
}

void metSamp(int** observation, int** result){
	// define variables
	int i;
	int j;
	int val;

	// instantiate sampler
	Sample sampler;

	// randomization stuff (might need re-jigging)
	// int* s_I=new int[IMG_WIDTH];
	// int* s_J=new int[IMG_LENGTH];
	// for (int i=0; i<IMG_WIDTH; i++){
	// 	s_I[i]=i;
	// }
	// for (int i=0; i<IMG_LENGTH; i++){
	// 	s_J[i]=i;
	// }
	// sampler.randPerm(s_I, IMG_WIDTH);
	// sampler.randPerm(s_J, IMG_LENGTH);

	for(int sweep=2; sweep<ITERS; sweep++){
		for(int k=0; k<IMG_WIDTH*IMG_LENGTH; k++){
			// pick next site

			// calculate energies
			currentEnergy = localEnergy(observation, result, result[i][j], i, j);
			proposedEnergy = localEnergy(observation, result, val, i, j);

			if (proposedEnergy<=currentEnergy){
				// keep new pixel value
				// update energy for whole clique
			}
			else if(sampler.draw_bern(exp(-log(sweep)*TEMPCOEFF*(proposedEnergy-currentEnergy)))){
				// keep new pixel value
				// update energy for whole clique
			}
		}
	}
}

double localEnergy(int** observation, int** result, int val, int i, int j){
	return 0.5;
}

// Used for data I/O
class CSVRow
{
    public:
        std::string const& operator[](std::size_t index) const
        {
            return m_data[index];
        }
        std::size_t size() const
        {
            return m_data.size();
        }
        void readNextRow(std::istream& str)
        {
            std::string         line;
            std::getline(str,line);

            std::stringstream   lineStream(line);
            std::string         cell;

            m_data.clear();
            while(std::getline(lineStream,cell,','))
            {
                m_data.push_back(cell);
            }
        }
    private:
        std::vector<std::string>    m_data;
};

// Used for data I/O
std::istream& operator>>(std::istream& str,CSVRow& data)
{
    data.readNextRow(str);
    return str;
}

// Read data from CSV into matrix
void readDataInt(int ** data, int numrows, int numcols){
	std::ifstream file("foo.csv");
	CSVRow row;
	int i=0;
	while(file >> row && i<numrows)
    {
    	for (int j=0; j<numcols; j++){

		    data[i][j] = atoi(row[j].c_str());
		}
		i++;
    }
}

// write matrix into a CSV
void writeDataInt(int ** data, int row, int col){
	std::ofstream dataFile;
	dataFile.open("gaussianObs.csv");
	for (int i=0; i<row; i++){
		for (int j=0; j<col-1; j++){
			dataFile<<data[i][j]<<",";
		}
		dataFile<<data[i][col-1]<<"\n";
	}
	dataFile.close();
}

int main(){
	// Declare variables
	int** observation=new_MatrixI(IMG_WIDTH, IMG_LENGTH);
	int** result=new_MatrixI(IMG_WIDTH, IMG_LENGTH);

	// load csv data into observation
	readDataInt(observation, IMG_WIDTH, IMG_LENGTH);
	// initialize result = observation
	set_eq_I(result, observation);

	// run metropolis sampler
	metSamp(observation, result);

	// write result to csv
	writeDataInt(result, IMG_WIDTH,IMG_LENGTH);
	return 0;
}
<commit_msg>added index randomizer<commit_after>// stuff for metropolis
#include <chrono>
#include <random>
#include <functional>
#include <array>
#include <math.h>
#include <cmath>
#include <time.h>

// file I/O stuff
#include <iterator>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

// hyperparameters
#define ITERS 10
#define SIGMA 20
#define TEMPCOEFF 1/10

// image dimensions
// Luckily they are the same. I think I have them confused throughout -G
#define IMG_WIDTH 5
#define IMG_LENGTH 5

//uses brace initialization, so must use the C++11 compiler.
// call as g++ -std=c++11 file-name.pp -o file-handle

// functions for creating matrices
int **new_MatrixI(int row, int col){
		int ** matrix=new int *[row];
		int i,j;
		for(i=0; i<row; i++){
			matrix[i]=new int [col];
		}
		return (matrix);
	}
double **new_MatrixD(int row, int col){
	double ** matrix=new double *[row];
	int i,j;
	for(i=0; i<row; i++){
		matrix[i]=new double [col];
	}
	return (matrix);
}

// functions for deleting matrices (unused, I believe -G)
void del_MatrixI(int **mat, int row){
	int i;
	for(i=0; i<row; i++){
		delete[] mat[i];
	}
	delete[] mat;
}
void del_MatrixD(double **mat, int row){
	int i;
	for(i=0; i<row; i++){
		delete[] mat[i];
	}
	delete[] mat;
}

// functions for copying matrices
void set_eq_I(int* lhs, int* rhs){
	for (int i=0; i<DIM; i++){
		lhs[i]=rhs[i];
	}
}
void set_eq_D(double* lhs, double* rhs){
	for (int i=0; i<DIM; i++){
		lhs[i]=rhs[i];
	}
}

// Does sampling from distributions
class Sample
{
public:
	Sample():
	mt(std::random_device()()),
	G(0,SIGMA)
	{}
	int draw_bern(double);
	double draw_gauss();
private:
  	std::mt19937 mt;
	std::normal_distribution<double> G;
}; //add constructor and destructor

// returns zero mean gaussian of variance SIGMA
double Sample::draw_gauss(){
	return G(mt);
}

// returns 1 with prob param
int Sample::draw_bern(double param){
	std::discrete_distribution<int> B {1-param, param};
	return B(mt);
}

void metSamp(int** observation, int** result){
	// define variables
	int i, j, k;
	int val;

	// vector for randomly visitng sites
	std::vector<int> indices;
	for (k=0; k<IMG_WIDTH*IMG_LENGTH; k++){
		indices.push_back(k);
	}
	std::random_device random_dev;
	std::mt19937       generator(random_dev());

	// instantiate sampler
	Sample sampler;

	for(int sweep=2; sweep<ITERS; sweep++){
		// permute indices
		std::shuffle(indices.begin(), indices.end(), generator);
		for(int k=0; k<IMG_WIDTH*IMG_LENGTH; k++){
			// pick next site
			j = indices[k] % 512;
			i = (k-j) / 512

			// calculate energies
			currentEnergy = localEnergy(observation, result, result[i][j], i, j);
			proposedEnergy = localEnergy(observation, result, val, i, j);

			// acceptance stage (after denial, anger, bargaining, and depression)
			if (proposedEnergy<=currentEnergy){
				// keep new pixel value
				result[i][j] = val;
			}
			else if(sampler.draw_bern(exp(-log(sweep)*TEMPCOEFF*(proposedEnergy-currentEnergy)))){
				// keep new pixel value
				result[i][j] = val;
			}
		}
	}
}

double localEnergy(int** observation, int** result, int val, int i, int j){
	return 0.5;
}

// Used for data I/O
class CSVRow
{
    public:
        std::string const& operator[](std::size_t index) const
        {
            return m_data[index];
        }
        std::size_t size() const
        {
            return m_data.size();
        }
        void readNextRow(std::istream& str)
        {
            std::string         line;
            std::getline(str,line);

            std::stringstream   lineStream(line);
            std::string         cell;

            m_data.clear();
            while(std::getline(lineStream,cell,','))
            {
                m_data.push_back(cell);
            }
        }
    private:
        std::vector<std::string>    m_data;
};

// Used for data I/O
std::istream& operator>>(std::istream& str,CSVRow& data)
{
    data.readNextRow(str);
    return str;
}

// Read data from CSV into matrix
void readDataInt(int ** data, int numrows, int numcols){
	std::ifstream file("gemanIn.csv");
	CSVRow row;
	int i=0;
	while(file >> row && i<numrows)
    {
    	for (int j=0; j<numcols; j++){

		    data[i][j] = atoi(row[j].c_str());
		}
		i++;
    }
}

// write matrix into a CSV
void writeDataInt(int ** data, int row, int col){
	std::ofstream dataFile;
	dataFile.open("gemanOut.csv");
	for (int i=0; i<row; i++){
		for (int j=0; j<col-1; j++){
			dataFile<<data[i][j]<<",";
		}
		dataFile<<data[i][col-1]<<"\n";
	}
	dataFile.close();
}

int main(){
	// Declare variables
	int** observation=new_MatrixI(IMG_WIDTH, IMG_LENGTH);
	int** result=new_MatrixI(IMG_WIDTH, IMG_LENGTH);

	// load csv data into observation
	readDataInt(observation, IMG_WIDTH, IMG_LENGTH);
	// initialize result = observation
	set_eq_I(result, observation);

	// run metropolis sampler
	metSamp(observation, result);

	// write result to csv
	writeDataInt(result, IMG_WIDTH,IMG_LENGTH);
	return 0;
}
<|endoftext|>


<commit_before>void Config()
{
    // 7-DEC-2000 09:00
    // Switch on Transition Radiation simulation. 6/12/00 18:00
    // iZDC=1  7/12/00 09:00
    // ThetaRange is (0., 180.). It was (0.28,179.72) 7/12/00 09:00

    // Set Random Number seed
    // gRandom->SetSeed(12345);

    new     AliGeant3("C++ Interface to Geant3");

    if (!gSystem->Getenv("CONFIG_FILE"))
    {
        TFile  *rootfile = new TFile("galice.root", "recreate");

        rootfile->SetCompressionLevel(2);
    }

    TGeant3 *geant3 = (TGeant3 *) gMC;

    //
    // Set External decayer
    AliDecayer *decayer = new AliDecayerPythia();

    decayer->SetForceDecay(kAll);
    decayer->Init();
    gMC->SetExternalDecayer(decayer);
    //
    //
    //=======================================================================
    // ******* GEANT STEERING parameters FOR ALICE SIMULATION *******
    geant3->SetTRIG(1);         //Number of events to be processed
    geant3->SetSWIT(4, 10);
    geant3->SetDEBU(0, 0, 1);
    //geant3->SetSWIT(2,2);
    geant3->SetDCAY(1);
    geant3->SetPAIR(1);
    geant3->SetCOMP(1);
    geant3->SetPHOT(1);
    geant3->SetPFIS(0);
    geant3->SetDRAY(0);
    geant3->SetANNI(1);
    geant3->SetBREM(1);
    geant3->SetMUNU(1);
    geant3->SetCKOV(1);
    geant3->SetHADR(1);         //Select pure GEANH (HADR 1) or GEANH/NUCRIN (HADR 3)
    geant3->SetLOSS(2);
    geant3->SetMULS(1);
    geant3->SetRAYL(1);
    geant3->SetAUTO(1);         //Select automatic STMIN etc... calc. (AUTO 1) or manual (AUTO 0)
    geant3->SetABAN(0);         //Restore 3.16 behaviour for abandoned tracks
    geant3->SetOPTI(2);         //Select optimisation level for GEANT geometry searches (0,1,2)
    geant3->SetERAN(5.e-7);

    Float_t cut = 1.e-3;        // 1MeV cut by default
    Float_t tofmax = 1.e10;

    //             GAM ELEC NHAD CHAD MUON EBREM MUHAB EDEL MUDEL MUPA TOFMAX
    geant3->SetCUTS(cut, cut, cut, cut, cut, cut, cut, cut, cut, cut,
                    tofmax);
    //
    //=======================================================================
    // ************* STEERING parameters FOR ALICE SIMULATION **************
    // --- Specify event type to be tracked through the ALICE setup
    // --- All positions are in cm, angles in degrees, and P and E in GeV
    if (gSystem->Getenv("CONFIG_NPARTICLES"))
    {
        int     nParticles = atoi(gSystem->Getenv("CONFIG_NPARTICLES"));
    } else
    {
        int     nParticles = 50;
    }
    AliGenHIJINGpara *gener = new AliGenHIJINGpara(nParticles);

    gener->SetMomentumRange(0, 999);
    gener->SetPhiRange(0, 360);
    //  gener->SetThetaRange(0.28,179.72);
    gener->SetThetaRange(0., 180.);
    gener->SetOrigin(0, 0, 0);  //vertex position
    gener->SetSigma(0, 0, 0);   //Sigma in (X,Y,Z) (cm) on IP position
    gener->Init();
    //
    // Activate this line if you want the vertex smearing to happen
    // track by track
    //
    //gener->SetVertexSmear(perTrack);

    gAlice->SetField(-999, 2);  //Specify maximum magnetic field in Tesla (neg. ==> default field)

    Int_t   iABSO = 1;
    Int_t   iCASTOR = 1;
    Int_t   iDIPO = 1;
    Int_t   iFMD = 1;
    Int_t   iFRAME = 1;
    Int_t   iHALL = 1;
    Int_t   iITS = 1;
    Int_t   iMAG = 1;
    Int_t   iMUON = 1;
    Int_t   iPHOS = 1;
    Int_t   iPIPE = 1;
    Int_t   iPMD = 1;
    Int_t   iRICH = 1;
    Int_t   iSHIL = 1;
    Int_t   iSTART = 1;
    Int_t   iTOF = 1;
    Int_t   iTPC = 1;
    Int_t   iTRD = 1;
    Int_t   iZDC = 1;

    //=================== Alice BODY parameters =============================
    AliBODY *BODY = new AliBODY("BODY", "Alice envelop");

    if (iMAG)
    {
        //=================== MAG parameters ============================
        // --- Start with Magnet since detector layouts may be depending ---
        // --- on the selected Magnet dimensions ---
        AliMAG *MAG = new AliMAG("MAG", "Magnet");
    }

    if (iABSO)
    {
        //=================== ABSO parameters ============================
        AliABSO *ABSO = new AliABSOv0("ABSO", "Muon Absorber");
    }

    if (iDIPO)
    {
        //=================== DIPO parameters ============================

        AliDIPO *DIPO = new AliDIPOv2("DIPO", "Dipole version 2");
    }

    if (iHALL)
    {
        //=================== HALL parameters ============================

        AliHALL *HALL = new AliHALL("HALL", "Alice Hall");
    }

    if (iFRAME)
    {
        //=================== FRAME parameters ============================

        AliFRAME *FRAME = new AliFRAMEv2("FRAME", "Space Frame");

    }

    if (iSHIL)
    {
        //=================== SHIL parameters ============================

        AliSHIL *SHIL = new AliSHILv0("SHIL", "Shielding");
    }

    if (iPIPE)
    {
        //=================== PIPE parameters ============================

        AliPIPE *PIPE = new AliPIPEv0("PIPE", "Beam Pipe");
    }

  if(iITS) {

//=================== ITS parameters ============================
    //
    // As the innermost detector in ALICE, the Inner Tracking System "impacts" on
    // almost all other detectors. This involves the fact that the ITS geometry
    // still has several options to be followed in parallel in order to determine
    // the best set-up which minimizes the induced background. All the geometries
    // available to date are described in the following. Read carefully the comments
    // and use the default version (the only one uncommented) unless you are making
    // comparisons and you know what you are doing. In this case just uncomment the
    // ITS geometry you want to use and run Aliroot.
    //
    // Detailed geometries:
    //
    //
    //AliITS *ITS  = new AliITSv5symm("ITS","Updated ITS TDR detailed version with symmetric services");
    //
    //AliITS *ITS  = new AliITSv5asymm("ITS","Updates ITS TDR detailed version with asymmetric services");
    //
    AliITSvPPRasymm *ITS  = new AliITSvPPRasymm("ITS","New ITS PPR detailed version with asymmetric services");
    ITS->SetMinorVersion(2);					 // don't touch this parameter if you're not an ITS developer
    ITS->SetReadDet(kFALSE);					 // don't touch this parameter if you're not an ITS developer
    //    ITS->SetWriteDet("$ALICE_ROOT/ITS/ITSgeometry_vPPRasymm2.det");  // don't touch this parameter if you're not an ITS developer
    ITS->SetThicknessDet1(200.);   // detector thickness on layer 1 must be in the range [100,300]
    ITS->SetThicknessDet2(200.);   // detector thickness on layer 2 must be in the range [100,300]
    ITS->SetThicknessChip1(200.);  // chip thickness on layer 1 must be in the range [150,300]
    ITS->SetThicknessChip2(200.);  // chip thickness on layer 2 must be in the range [150,300]
    ITS->SetRails(1);	     // 1 --> rails in ; 0 --> rails out
    ITS->SetCoolingFluid(1);   // 1 --> water ; 0 --> freon
    //
    //AliITSvPPRsymm *ITS  = new AliITSvPPRsymm("ITS","New ITS PPR detailed version with symmetric services");
    //ITS->SetMinorVersion(2);                                       // don't touch this parameter if you're not an ITS developer
    //ITS->SetReadDet(kFALSE);                                       // don't touch this parameter if you're not an ITS developer
    //ITS->SetWriteDet("$ALICE_ROOT/ITS/ITSgeometry_vPPRsymm2.det"); // don't touch this parameter if you're not an ITS developer
    //ITS->SetThicknessDet1(200.);   // detector thickness on layer 1 must be in the range [100,300]
    //ITS->SetThicknessDet2(200.);   // detector thickness on layer 2 must be in the range [100,300]
    //ITS->SetThicknessChip1(200.);  // chip thickness on layer 1 must be in the range [150,300]
    //ITS->SetThicknessChip2(200.);  // chip thickness on layer 2 must be in the range [150,300]
    //ITS->SetRails(1);              // 1 --> rails in ; 0 --> rails out
    //ITS->SetCoolingFluid(1);       // 1 --> water ; 0 --> freon
    //
    //
    // Coarse geometries (warning: no hits are produced with these coarse geometries and they unuseful
    // for reconstruction !):
    //
    //
    //AliITSvPPRcoarseasymm *ITS  = new AliITSvPPRcoarseasymm("ITS","New ITS PPR coarse version with asymmetric services");
    //ITS->SetRails(1);                // 1 --> rails in ; 0 --> rails out
    //ITS->SetSupportMaterial(0);      // 0 --> Copper ; 1 --> Aluminum ; 2 --> Carbon
    //
    //AliITS *ITS  = new AliITSvPPRcoarsesymm("ITS","New ITS PPR coarse version with symmetric services");
    //ITS->SetRails(1);                // 1 --> rails in ; 0 --> rails out
    //ITS->SetSupportMaterial(0);      // 0 --> Copper ; 1 --> Aluminum ; 2 --> Carbon
    //
    //
    //
    // Geant3 <-> EUCLID conversion
    // ============================
    //
    // SetEUCLID is a flag to output (=1) or not to output (=0) both geometry and
    // media to two ASCII files (called by default ITSgeometry.euc and
    // ITSgeometry.tme) in a format understandable to the CAD system EUCLID.
    // The default (=0) means that you dont want to use this facility.
    //
    ITS->SetEUCLID(0);
  }

    if (iTPC)
    {
        //============================ TPC parameters ================================
        // --- This allows the user to specify sectors for the SLOW (TPC geometry 2)
        // --- Simulator. SecAL (SecAU) <0 means that ALL lower (upper)
        // --- sectors are specified, any value other than that requires at least one
        // --- sector (lower or upper)to be specified!
        // --- Reminder: sectors 1-24 are lower sectors (1-12 -> z>0, 13-24 -> z<0)
        // ---           sectors 25-72 are the upper ones (25-48 -> z>0, 49-72 -> z<0)
        // --- SecLows - number of lower sectors specified (up to 6)
        // --- SecUps - number of upper sectors specified (up to 12)
        // --- Sens - sensitive strips for the Slow Simulator !!!
        // --- This does NOT work if all S or L-sectors are specified, i.e.
        // --- if SecAL or SecAU < 0
        //
        //
        //-----------------------------------------------------------------------------

        //  gROOT->LoadMacro("SetTPCParam.C");
        //  AliTPCParam *param = SetTPCParam();
        AliTPC *TPC = new AliTPCv2("TPC", "Default");

        // All sectors included
        TPC->SetSecAL(-1);
        TPC->SetSecAU(-1);

    }

    if (iTOF)
    {
        //=================== TOF parameters ============================
        AliTOF *TOF = new AliTOFv2("TOF", "normal TOF");
    }

    if (iRICH)
    {
        //=================== RICH parameters ===========================
        AliRICH *RICH = new AliRICHv1("RICH", "normal RICH");

    }

    if (iZDC)
    {
        //=================== ZDC parameters ============================

        AliZDC *ZDC = new AliZDCv1("ZDC", "normal ZDC");
    }

    if (iCASTOR)
    {
        //=================== CASTOR parameters ============================

        AliCASTOR *CASTOR = new AliCASTORv1("CASTOR", "normal CASTOR");
    }

    if (iTRD)
    {
        //=================== TRD parameters ============================

        AliTRD *TRD = new AliTRDv1("TRD", "TRD slow simulator");

        // Select the gas mixture (0: 97% Xe + 3% isobutane, 1: 90% Xe + 10% CO2)
        TRD->SetGasMix(1);

        // With hole in front of PHOS
        TRD->SetPHOShole();
        // With hole in front of RICH
        TRD->SetRICHhole();
        // Switch on TR
        AliTRDsim *TRDsim = TRD->CreateTR();
    }

    if (iFMD)
    {
        //=================== FMD parameters ============================

        AliFMD *FMD = new AliFMDv1("FMD", "normal FMD");
    }

    if (iMUON)
    {
        //=================== MUON parameters ===========================

        AliMUON *MUON = new AliMUONv1("MUON", "default");
    }
    //=================== PHOS parameters ===========================

    if (iPHOS)
    {
        AliPHOS *PHOS = new AliPHOSv1("PHOS", "GPS2");
    }

    if (iPMD)
    {
        //=================== PMD parameters ============================

        AliPMD *PMD = new AliPMDv1("PMD", "normal PMD");

        PMD->SetPAR(1., 1., 0.8, 0.02);
        PMD->SetIN(6., 18., -580., 27., 27.);
        PMD->SetGEO(0.0, 0.2, 4.);
        PMD->SetPadSize(0.8, 1.0, 1.0, 1.5);

    }

    if (iSTART)
    {
        //=================== START parameters ============================
        AliSTART *START = new AliSTARTv1("START", "START Detector");
    }

}
<commit_msg>Theta range given through pseudorapidity limits (M.Masera)<commit_after>void Config()
{
    // 7-DEC-2000 09:00
    // Switch on Transition Radiation simulation. 6/12/00 18:00
    // iZDC=1  7/12/00 09:00
    // ThetaRange is (0., 180.). It was (0.28,179.72) 7/12/00 09:00
    // Theta range given through pseudorapidity limits 22/6/2001

    // Set Random Number seed
    // gRandom->SetSeed(12345);

    new     AliGeant3("C++ Interface to Geant3");

    if (!gSystem->Getenv("CONFIG_FILE"))
    {
        TFile  *rootfile = new TFile("galice.root", "recreate");

        rootfile->SetCompressionLevel(2);
    }

    TGeant3 *geant3 = (TGeant3 *) gMC;

    //
    // Set External decayer
    AliDecayer *decayer = new AliDecayerPythia();

    decayer->SetForceDecay(kAll);
    decayer->Init();
    gMC->SetExternalDecayer(decayer);
    //
    //
    //=======================================================================
    // ******* GEANT STEERING parameters FOR ALICE SIMULATION *******
    geant3->SetTRIG(1);         //Number of events to be processed
    geant3->SetSWIT(4, 10);
    geant3->SetDEBU(0, 0, 1);
    //geant3->SetSWIT(2,2);
    geant3->SetDCAY(1);
    geant3->SetPAIR(1);
    geant3->SetCOMP(1);
    geant3->SetPHOT(1);
    geant3->SetPFIS(0);
    geant3->SetDRAY(0);
    geant3->SetANNI(1);
    geant3->SetBREM(1);
    geant3->SetMUNU(1);
    geant3->SetCKOV(1);
    geant3->SetHADR(1);         //Select pure GEANH (HADR 1) or GEANH/NUCRIN (HADR 3)
    geant3->SetLOSS(2);
    geant3->SetMULS(1);
    geant3->SetRAYL(1);
    geant3->SetAUTO(1);         //Select automatic STMIN etc... calc. (AUTO 1) or manual (AUTO 0)
    geant3->SetABAN(0);         //Restore 3.16 behaviour for abandoned tracks
    geant3->SetOPTI(2);         //Select optimisation level for GEANT geometry searches (0,1,2)
    geant3->SetERAN(5.e-7);

    Float_t cut = 1.e-3;        // 1MeV cut by default
    Float_t tofmax = 1.e10;

    //             GAM ELEC NHAD CHAD MUON EBREM MUHAB EDEL MUDEL MUPA TOFMAX
    geant3->SetCUTS(cut, cut, cut, cut, cut, cut, cut, cut, cut, cut,
                    tofmax);
    //
    //=======================================================================
    // ************* STEERING parameters FOR ALICE SIMULATION **************
    // --- Specify event type to be tracked through the ALICE setup
    // --- All positions are in cm, angles in degrees, and P and E in GeV
    if (gSystem->Getenv("CONFIG_NPARTICLES"))
    {
        int     nParticles = atoi(gSystem->Getenv("CONFIG_NPARTICLES"));
    } else
    {
        int     nParticles = 50;
    }
    AliGenHIJINGpara *gener = new AliGenHIJINGpara(nParticles);

    gener->SetMomentumRange(0, 999);
    gener->SetPhiRange(0, 360);
    // Set pseudorapidity range from -8 to 8.
    Float_t thmin = EtaToTheta(8);   // theta min. <---> eta max
    Float_t thmax = EtaToTheta(-8);  // theta max. <---> eta min
    gener->SetThetaRange(thmin,thmax);
    gener->SetOrigin(0, 0, 0);  //vertex position
    gener->SetSigma(0, 0, 0);   //Sigma in (X,Y,Z) (cm) on IP position
    gener->Init();
    //
    // Activate this line if you want the vertex smearing to happen
    // track by track
    //
    //gener->SetVertexSmear(perTrack);

    gAlice->SetField(-999, 2);  //Specify maximum magnetic field in Tesla (neg. ==> default field)

    Int_t   iABSO = 1;
    Int_t   iCASTOR = 1;
    Int_t   iDIPO = 1;
    Int_t   iFMD = 1;
    Int_t   iFRAME = 1;
    Int_t   iHALL = 1;
    Int_t   iITS = 1;
    Int_t   iMAG = 1;
    Int_t   iMUON = 1;
    Int_t   iPHOS = 1;
    Int_t   iPIPE = 1;
    Int_t   iPMD = 1;
    Int_t   iRICH = 1;
    Int_t   iSHIL = 1;
    Int_t   iSTART = 1;
    Int_t   iTOF = 1;
    Int_t   iTPC = 1;
    Int_t   iTRD = 1;
    Int_t   iZDC = 1;

    //=================== Alice BODY parameters =============================
    AliBODY *BODY = new AliBODY("BODY", "Alice envelop");

    if (iMAG)
    {
        //=================== MAG parameters ============================
        // --- Start with Magnet since detector layouts may be depending ---
        // --- on the selected Magnet dimensions ---
        AliMAG *MAG = new AliMAG("MAG", "Magnet");
    }

    if (iABSO)
    {
        //=================== ABSO parameters ============================
        AliABSO *ABSO = new AliABSOv0("ABSO", "Muon Absorber");
    }

    if (iDIPO)
    {
        //=================== DIPO parameters ============================

        AliDIPO *DIPO = new AliDIPOv2("DIPO", "Dipole version 2");
    }

    if (iHALL)
    {
        //=================== HALL parameters ============================

        AliHALL *HALL = new AliHALL("HALL", "Alice Hall");
    }

    if (iFRAME)
    {
        //=================== FRAME parameters ============================

        AliFRAME *FRAME = new AliFRAMEv2("FRAME", "Space Frame");

    }

    if (iSHIL)
    {
        //=================== SHIL parameters ============================

        AliSHIL *SHIL = new AliSHILv0("SHIL", "Shielding");
    }

    if (iPIPE)
    {
        //=================== PIPE parameters ============================

        AliPIPE *PIPE = new AliPIPEv0("PIPE", "Beam Pipe");
    }

  if(iITS) {

//=================== ITS parameters ============================
    //
    // As the innermost detector in ALICE, the Inner Tracking System "impacts" on
    // almost all other detectors. This involves the fact that the ITS geometry
    // still has several options to be followed in parallel in order to determine
    // the best set-up which minimizes the induced background. All the geometries
    // available to date are described in the following. Read carefully the comments
    // and use the default version (the only one uncommented) unless you are making
    // comparisons and you know what you are doing. In this case just uncomment the
    // ITS geometry you want to use and run Aliroot.
    //
    // Detailed geometries:
    //
    //
    //AliITS *ITS  = new AliITSv5symm("ITS","Updated ITS TDR detailed version with symmetric services");
    //
    //AliITS *ITS  = new AliITSv5asymm("ITS","Updates ITS TDR detailed version with asymmetric services");
    //
    AliITSvPPRasymm *ITS  = new AliITSvPPRasymm("ITS","New ITS PPR detailed version with asymmetric services");
    ITS->SetMinorVersion(2);					 // don't touch this parameter if you're not an ITS developer
    ITS->SetReadDet(kFALSE);					 // don't touch this parameter if you're not an ITS developer
    //    ITS->SetWriteDet("$ALICE_ROOT/ITS/ITSgeometry_vPPRasymm2.det");  // don't touch this parameter if you're not an ITS developer
    ITS->SetThicknessDet1(200.);   // detector thickness on layer 1 must be in the range [100,300]
    ITS->SetThicknessDet2(200.);   // detector thickness on layer 2 must be in the range [100,300]
    ITS->SetThicknessChip1(200.);  // chip thickness on layer 1 must be in the range [150,300]
    ITS->SetThicknessChip2(200.);  // chip thickness on layer 2 must be in the range [150,300]
    ITS->SetRails(1);	     // 1 --> rails in ; 0 --> rails out
    ITS->SetCoolingFluid(1);   // 1 --> water ; 0 --> freon
    //
    //AliITSvPPRsymm *ITS  = new AliITSvPPRsymm("ITS","New ITS PPR detailed version with symmetric services");
    //ITS->SetMinorVersion(2);                                       // don't touch this parameter if you're not an ITS developer
    //ITS->SetReadDet(kFALSE);                                       // don't touch this parameter if you're not an ITS developer
    //ITS->SetWriteDet("$ALICE_ROOT/ITS/ITSgeometry_vPPRsymm2.det"); // don't touch this parameter if you're not an ITS developer
    //ITS->SetThicknessDet1(200.);   // detector thickness on layer 1 must be in the range [100,300]
    //ITS->SetThicknessDet2(200.);   // detector thickness on layer 2 must be in the range [100,300]
    //ITS->SetThicknessChip1(200.);  // chip thickness on layer 1 must be in the range [150,300]
    //ITS->SetThicknessChip2(200.);  // chip thickness on layer 2 must be in the range [150,300]
    //ITS->SetRails(1);              // 1 --> rails in ; 0 --> rails out
    //ITS->SetCoolingFluid(1);       // 1 --> water ; 0 --> freon
    //
    //
    // Coarse geometries (warning: no hits are produced with these coarse geometries and they unuseful
    // for reconstruction !):
    //
    //
    //AliITSvPPRcoarseasymm *ITS  = new AliITSvPPRcoarseasymm("ITS","New ITS PPR coarse version with asymmetric services");
    //ITS->SetRails(1);                // 1 --> rails in ; 0 --> rails out
    //ITS->SetSupportMaterial(0);      // 0 --> Copper ; 1 --> Aluminum ; 2 --> Carbon
    //
    //AliITS *ITS  = new AliITSvPPRcoarsesymm("ITS","New ITS PPR coarse version with symmetric services");
    //ITS->SetRails(1);                // 1 --> rails in ; 0 --> rails out
    //ITS->SetSupportMaterial(0);      // 0 --> Copper ; 1 --> Aluminum ; 2 --> Carbon
    //
    //
    //
    // Geant3 <-> EUCLID conversion
    // ============================
    //
    // SetEUCLID is a flag to output (=1) or not to output (=0) both geometry and
    // media to two ASCII files (called by default ITSgeometry.euc and
    // ITSgeometry.tme) in a format understandable to the CAD system EUCLID.
    // The default (=0) means that you dont want to use this facility.
    //
    ITS->SetEUCLID(0);
  }

    if (iTPC)
    {
        //============================ TPC parameters ================================
        // --- This allows the user to specify sectors for the SLOW (TPC geometry 2)
        // --- Simulator. SecAL (SecAU) <0 means that ALL lower (upper)
        // --- sectors are specified, any value other than that requires at least one
        // --- sector (lower or upper)to be specified!
        // --- Reminder: sectors 1-24 are lower sectors (1-12 -> z>0, 13-24 -> z<0)
        // ---           sectors 25-72 are the upper ones (25-48 -> z>0, 49-72 -> z<0)
        // --- SecLows - number of lower sectors specified (up to 6)
        // --- SecUps - number of upper sectors specified (up to 12)
        // --- Sens - sensitive strips for the Slow Simulator !!!
        // --- This does NOT work if all S or L-sectors are specified, i.e.
        // --- if SecAL or SecAU < 0
        //
        //
        //-----------------------------------------------------------------------------

        //  gROOT->LoadMacro("SetTPCParam.C");
        //  AliTPCParam *param = SetTPCParam();
        AliTPC *TPC = new AliTPCv2("TPC", "Default");

        // All sectors included
        TPC->SetSecAL(-1);
        TPC->SetSecAU(-1);

    }

    if (iTOF)
    {
        //=================== TOF parameters ============================
        AliTOF *TOF = new AliTOFv2("TOF", "normal TOF");
    }

    if (iRICH)
    {
        //=================== RICH parameters ===========================
        AliRICH *RICH = new AliRICHv1("RICH", "normal RICH");

    }

    if (iZDC)
    {
        //=================== ZDC parameters ============================

        AliZDC *ZDC = new AliZDCv1("ZDC", "normal ZDC");
    }

    if (iCASTOR)
    {
        //=================== CASTOR parameters ============================

        AliCASTOR *CASTOR = new AliCASTORv1("CASTOR", "normal CASTOR");
    }

    if (iTRD)
    {
        //=================== TRD parameters ============================

        AliTRD *TRD = new AliTRDv1("TRD", "TRD slow simulator");

        // Select the gas mixture (0: 97% Xe + 3% isobutane, 1: 90% Xe + 10% CO2)
        TRD->SetGasMix(1);

        // With hole in front of PHOS
        TRD->SetPHOShole();
        // With hole in front of RICH
        TRD->SetRICHhole();
        // Switch on TR
        AliTRDsim *TRDsim = TRD->CreateTR();
    }

    if (iFMD)
    {
        //=================== FMD parameters ============================

        AliFMD *FMD = new AliFMDv1("FMD", "normal FMD");
    }

    if (iMUON)
    {
        //=================== MUON parameters ===========================

        AliMUON *MUON = new AliMUONv1("MUON", "default");
    }
    //=================== PHOS parameters ===========================

    if (iPHOS)
    {
        AliPHOS *PHOS = new AliPHOSv1("PHOS", "GPS2");
    }

    if (iPMD)
    {
        //=================== PMD parameters ============================

        AliPMD *PMD = new AliPMDv1("PMD", "normal PMD");

        PMD->SetPAR(1., 1., 0.8, 0.02);
        PMD->SetIN(6., 18., -580., 27., 27.);
        PMD->SetGEO(0.0, 0.2, 4.);
        PMD->SetPadSize(0.8, 1.0, 1.0, 1.5);

    }

    if (iSTART)
    {
        //=================== START parameters ============================
        AliSTART *START = new AliSTARTv1("START", "START Detector");
    }

}

Float_t EtaToTheta(Float_t arg){
  return (180./TMath::Pi())*2.*atan(exp(-arg));
}
<|endoftext|>


<commit_before>#ifndef WIN_HPP
#define WIN_HPP

#include "tile.h"
#include <set>
#include <list>
#include <iterator>
#include <algorithm>

namespace mj {

/**
 * @brief find_1_1_1
 * @param first
 * @return bool
 *
 * for Triplet
 */
template<typename Iter>
inline bool find_1_1_1(Iter first)
{
    auto second = first;
    std::advance(second, 1);
    auto third  = first;
    std::advance(third, 2);

    return *first   ==  *second    &&      *first  ==  *third;
}

/**
 * @brief find_1_1
 * @param first
 * @return bool
 *
 * for eyes
 */
template<typename Iter>
inline bool find_1_1(Iter first)
{
    auto second = first;
    std::advance(second, 1);

    return *first   ==  *second;
}

/**
 * @brief check_if_win
 * @param first
 * @param last
 * @note    sort the sequence first before calling this function
 */
template<typename Iter>
bool check_if_win(Iter first, Iter last)
{
    auto size = std::distance(first, last);

    //! trivial case
    if(size == 0)
        return true;

    //! case 1  :   1 1 1
    bool case_1 = find_1_1_1(first);
    if(case_1)
    {
        auto next = first;
        std::advance(next, 3);
        case_1 = check_if_win(next, last);
    }

    //! case 2  :   1 2 3
    using ValueType =   typename std::iterator_traits<Iter>::value_type;
    std::list<ValueType> list {first, last};

    bool case_2 = false;
    {
        auto second = std::find(list.begin(), list.end(), *first + 1);
        auto third  = std::find(list.begin(), list.end(), *first + 2);
        if(second != list.end()  &&  third != list.end())
        {
            list.erase(list.begin());
            list.erase(second);
            list.erase(third);
            case_2 = check_if_win(list.begin(), list.end());
        }
    }

    //! case 3  :   1 1
    bool case_3 {size % 3    &&  find_1_1(first)};
    if(case_3)
    {
        auto next = first;
        std::advance(next, 2);
        case_3  =   check_if_win(next, last);
    }

    return case_1   ||  case_2  ||  case_3;
}

}//namespace
#endif // WIN_HPP

//! @test
//!
//#include <iostream>
//#include "game_master.h"
//#include "win.hpp"

//int main()
//{
//    //! init and sort
//    mj::GameMaster gm;
//    std::vector<mj::Tile> tiles{
//        {false, "Bai"},
//        {false, "Bai"},
//        {false, "Zho"},
//        {false, "Zho"},
//        {false, "Zho"},
//        {true , "dot", 1},
//        {true , "dot", 2},
//        {true , "dot", 3},
//        {true , "bam", 5},
//        {true , "bam", 6},
//        {true , "bam", 7},
//        {true , "bam", 2},
//        {true , "bam", 3},
//        {true , "bam", 4},
//    };
//    std::sort(tiles.begin(), tiles.end());

//    //! print
//    for(const auto& elem : tiles)
//        elem.print()<< "\n";

//    //! check if win
//    if(mj::check_if_win(tiles.begin(),tiles.end()))
//        std::cout << "you win\n";
//    else
//        std::cout << "not won yet\n";

//    std::cout << "\nexit normally\n";
//    return 0;
//}
//! @output
//!
//Bai
//Bai
//Zho
//Zho
//Zho
//bam2
//bam3
//bam4
//bam5
//bam6
//bam7
//dot1
//dot2
//dot3
//you win

//exit normally
<commit_msg>operator + for iterators in std,tested. 	modified:   win.hpp<commit_after>#ifndef WIN_HPP
#define WIN_HPP

#include "tile.h"
#include <set>
#include <list>
#include <iterator>
#include <algorithm>

namespace std {

//! @typedef
template<typename Iter>
using DifferenceType = typename std::iterator_traits<Iter>::difference_type;

/**
 * @brief operator +
 * @param lhs   iterator
 * @param rhs   offset
 * @return iterator
 *
 * extend std for simplicity.
 */
template<typename Iter>
Iter operator +(Iter lhs, DifferenceType<Iter> rhs )
{
    std::advance(lhs,rhs);
    return lhs;
}

/**
 * @brief operator +
 * @param lhs   offset
 * @param rhs   iterator
 * @return  iterator
 *
 * extend std for simplicity.
 */
template<typename Iter>
Iter operator +(DifferenceType<Iter> lhs,Iter rhs)
{
    return rhs + lhs;
}

}//namespace std

namespace mj {

/**
 * @brief find_1_1_1
 * @param first
 * @return bool
 *
 * for Triplet
 */
template<typename Iter>
inline bool find_1_1_1(Iter first)
{
    return *first   ==  *(first + 1)    &&      *first  ==  *(first + 2);
}

/**
 * @brief find_1_1
 * @param first
 * @return bool
 *
 * for eyes
 */
template<typename Iter>
inline bool find_1_1(Iter first)
{
    return *first   ==  *(first + 1);
}

/**
 * @brief check_if_win
 * @param first
 * @param last
 * @note    sort the sequence first before calling this function
 * @complx  O(3^n)  quit slow, but n == 4 in this case.
 */
template<typename Iter>
bool check_if_win(Iter first, Iter last)
{
    auto size = std::distance(first, last);

    //! trivial case
    if(size == 0)
        return true;

    //! case 1  :   1 1 1
    bool case_1 = find_1_1_1(first)     &&  check_if_win(first + 3, last);  //recur

    //! case 2  :   1 2 3
    using ValueType =   typename std::iterator_traits<Iter>::value_type;
    std::list<ValueType> list {first, last};

    bool case_2 = false;
    {
        auto second = std::find(list.begin(), list.end(), *first + 1);
        auto third  = std::find(list.begin(), list.end(), *first + 2);
        if(second != list.end()  &&  third != list.end())
        {
            list.erase(list.begin());
            list.erase(second);
            list.erase(third);
            case_2 = check_if_win(list.begin(), list.end());                //recur
        }
    }

    //! case 3  :   1 1
    bool case_3 {size % 3    &&  find_1_1(first)};
    if(case_3)
        case_3  =   check_if_win(first + 2, last);                          //recur

    return case_1   ||  case_2  ||  case_3;
}

}//namespace
#endif // WIN_HPP

//! @test
//!
//#include <iostream>
//#include "game_master.h"
//#include "win.hpp"

//int main()
//{
//    //! init and sort
//    mj::GameMaster gm;
//    std::vector<mj::Tile> tiles{
//        {false, "Bai"},
//        {false, "Bai"},
//        {false, "Zho"},
//        {false, "Zho"},
//        {false, "Zho"},
//        {true , "dot", 1},
//        {true , "dot", 2},
//        {true , "dot", 3},
//        {true , "bam", 5},
//        {true , "bam", 6},
//        {true , "bam", 7},
//        {true , "bam", 2},
//        {true , "bam", 3},
//        {true , "bam", 4},
//    };
//    std::sort(tiles.begin(), tiles.end());

//    //! print
//    for(const auto& elem : tiles)
//        elem.print()<< "\n";

//    //! check if win
//    if(mj::check_if_win(tiles.begin(),tiles.end()))
//        std::cout << "you win\n";
//    else
//        std::cout << "not won yet\n";

//    std::cout << "\nexit normally\n";
//    return 0;
//}
//! @output
//!
//Bai
//Bai
//Zho
//Zho
//Zho
//bam2
//bam3
//bam4
//bam5
//bam6
//bam7
//dot1
//dot2
//dot3
//you win

//exit normally
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	ASCII ソフトキーボード
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2022 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "gui/widget.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	ASCII ソフトキー・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct key_asc : public widget {

		typedef key_asc value_type;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	loc		ロケーション
		*/
		//-----------------------------------------------------------------//
		key_asc(const vtx::srect& loc = vtx::srect(0), const char* str = nullptr) noexcept :
			widget(loc, str)
		{
			insert_widget(this);
		}

		key_asc(const key_asc& th) = delete;
		key_asc& operator = (const key_asc& th) = delete;

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクタ
		*/
		//-----------------------------------------------------------------//
		virtual ~key_asc() noexcept { remove_widget(this); }

		//-----------------------------------------------------------------//
		/*!
			@brief	型整数を取得
			@return 型整数
		*/
		//-----------------------------------------------------------------//
		const char* get_name() const noexcept override { return "KeyAscii"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ID を取得
			@return ID
		*/
		//-----------------------------------------------------------------//
		ID get_id() const noexcept override { return ID::KEY_ASC; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void init() noexcept override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ判定を更新
			@param[in]	pos		判定位置
			@param[in]	num		タッチ数
			@param[in]	slt		スライド・タイプの場合「true」
		*/
		//-----------------------------------------------------------------//
		void update_touch(const vtx::spos& pos, uint16_t num) noexcept override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	選択推移
		*/
		//-----------------------------------------------------------------//
		void exec_select() noexcept override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	許可・不許可
			@param[in]	ena		不許可の場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool ena = true) override
		{
			if(ena) {
				set_state(STATE::ENABLE);
			} else {
				set_state(STATE::DISABLE);
				reset_touch_state();
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	描画
		*/
		//-----------------------------------------------------------------//
		template<class RDR>
		void draw(RDR& rdr) noexcept
		{
		}
	};
}

<commit_msg>Update: Design and function implementation<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	ASCII ソフトキーボード
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2022 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "gui/widget.hpp"

namespace gui {

	namespace key_asc_base {

		struct location_t {
			vtx::srect	rect;
			char		code;  // normal-code
			char		shift; // shift-code
			constexpr location_t(const vtx::srect& r, char c, char s) :
				rect(r),
				code(c), shift(s)
			{ }
		};

	}

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	ASCII ソフトキー・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct key_asc : public widget {

		typedef key_asc value_type;

		typedef std::function<void(char)> SELECT_FUNC_TYPE;

	private:
		static constexpr int16_t space = 2;

		static constexpr int16_t sz_x = 30;  // 通常幅
		static constexpr int16_t sz1x = 43;  // TAB 幅
		static constexpr int16_t sz2x = 56;  // バックスペース幅
		static constexpr int16_t sz3x = 52;  // CAPS LOCK 幅
		static constexpr int16_t sz4x = 68;  // LEFT-SHIFT 幅
		static constexpr int16_t sz5x = 82;  // RIGHT-SHIFT 幅
		static constexpr int16_t sz6x = 43;  // back slash 幅
		static constexpr int16_t sz7x = 66;  // ENTER 幅
		static constexpr int16_t sz8x = 56;  // CTRL, ALT, FN 幅
		static constexpr int16_t sz9x = 150; // SPACE 幅
		static constexpr int16_t szax = 35;  // ARROW 幅

		static constexpr int16_t g0_x = 0;
		static constexpr int16_t g1_x = g0_x + sz1x + space;
		static constexpr int16_t g2_x = g0_x + sz3x + space;
		static constexpr int16_t g3_x = g0_x + sz4x + space;
		static constexpr int16_t g4_x = g0_x + sz8x * 2 + sz9x + space * 3;
		static constexpr int16_t g5_x = g4_x + sz8x + space;

		static constexpr int16_t sp_x = sz_x + space;
		static constexpr int16_t sp3x = sz8x + space;
		static constexpr int16_t sp5x = szax + space;

		static constexpr int16_t g0_y = 0;
		static constexpr int16_t sz_y = 30;
		static constexpr int16_t sp_y = sz_y + space;

		static constexpr char KEY_BACK_SPACE  = 0x08;
		static constexpr char KEY_TAB         = 0x09;
		static constexpr char KEY_ENTER       = 0x0D;

		static constexpr char KEY_CAPS_LOCK   = 0x80;
		static constexpr char KEY_SHIFT_LEFT  = 0x81;
		static constexpr char KEY_SHIFT_RIGHT = 0x82;
		static constexpr char KEY_CTRL        = 0x83;
		static constexpr char KEY_ALT         = 0x84;
		static constexpr char KEY_FN          = 0x85;
		static constexpr char KEY_ARROW_LEFT  = 0x86;
		static constexpr char KEY_ARROW_DOWN  = 0x87;
		static constexpr char KEY_ARROW_RIGHT = 0x88;
		static constexpr char KEY_ARROW_UP    = 0x89;

		static constexpr key_asc_base::location_t key_locations_[] = {
			{ { g0_x + sp_x *  0, g0_y + sp_y * 0, sz_x, sz_y }, '`', '~' },
			{ { g0_x + sp_x *  1, g0_y + sp_y * 0, sz_x, sz_y }, '1', '!' },
			{ { g0_x + sp_x *  2, g0_y + sp_y * 0, sz_x, sz_y }, '2', '@' },
			{ { g0_x + sp_x *  3, g0_y + sp_y * 0, sz_x, sz_y }, '3', '#' },
			{ { g0_x + sp_x *  4, g0_y + sp_y * 0, sz_x, sz_y }, '4', '$' },
			{ { g0_x + sp_x *  5, g0_y + sp_y * 0, sz_x, sz_y }, '5', '%' },
			{ { g0_x + sp_x *  6, g0_y + sp_y * 0, sz_x, sz_y }, '6', '^' },
			{ { g0_x + sp_x *  7, g0_y + sp_y * 0, sz_x, sz_y }, '7', '&' },
			{ { g0_x + sp_x *  8, g0_y + sp_y * 0, sz_x, sz_y }, '8', '*' },
			{ { g0_x + sp_x *  9, g0_y + sp_y * 0, sz_x, sz_y }, '9', '(' },
			{ { g0_x + sp_x * 10, g0_y + sp_y * 0, sz_x, sz_y }, '0', ')' },
			{ { g0_x + sp_x * 11, g0_y + sp_y * 0, sz_x, sz_y }, '-', '_' },
			{ { g0_x + sp_x * 12, g0_y + sp_y * 0, sz_x, sz_y }, '=', '+' },
			{ { g0_x + sp_x * 13, g0_y + sp_y * 0, sz2x, sz_y }, KEY_BACK_SPACE, KEY_BACK_SPACE },

			{ { g0_x,             g0_y + sp_y * 1, sz1x, sz_y }, KEY_TAB, KEY_TAB },
			{ { g1_x + sp_x *  0, g0_y + sp_y * 1, sz_x, sz_y }, 'Q', 'q' },
			{ { g1_x + sp_x *  1, g0_y + sp_y * 1, sz_x, sz_y }, 'W', 'w' },
			{ { g1_x + sp_x *  2, g0_y + sp_y * 1, sz_x, sz_y }, 'E', 'e' },
			{ { g1_x + sp_x *  3, g0_y + sp_y * 1, sz_x, sz_y }, 'R', 'r' },
			{ { g1_x + sp_x *  4, g0_y + sp_y * 1, sz_x, sz_y }, 'T', 't' },
			{ { g1_x + sp_x *  5, g0_y + sp_y * 1, sz_x, sz_y }, 'Y', 'y' },
			{ { g1_x + sp_x *  6, g0_y + sp_y * 1, sz_x, sz_y }, 'U', 'u' },
			{ { g1_x + sp_x *  7, g0_y + sp_y * 1, sz_x, sz_y }, 'I', 'i' },
			{ { g1_x + sp_x *  8, g0_y + sp_y * 1, sz_x, sz_y }, 'O', 'o' },
			{ { g1_x + sp_x *  9, g0_y + sp_y * 1, sz_x, sz_y }, 'P', 'p' },
			{ { g1_x + sp_x * 10, g0_y + sp_y * 1, sz_x, sz_y }, '[', '{' },
			{ { g1_x + sp_x * 11, g0_y + sp_y * 1, sz_x, sz_y }, ']', '}' },
			{ { g1_x + sp_x * 12, g0_y + sp_y * 1, sz6x, sz_y }, '\\', '|' },

			{ { g0_x,             g0_y + sp_y * 2, sz3x, sz_y }, KEY_CAPS_LOCK, KEY_CAPS_LOCK },
			{ { g2_x + sp_x *  0, g0_y + sp_y * 2, sz_x, sz_y }, 'A', 'a' },
			{ { g2_x + sp_x *  1, g0_y + sp_y * 2, sz_x, sz_y }, 'S', 's' },
			{ { g2_x + sp_x *  2, g0_y + sp_y * 2, sz_x, sz_y }, 'D', 'd' },
			{ { g2_x + sp_x *  3, g0_y + sp_y * 2, sz_x, sz_y }, 'F', 'f' },
			{ { g2_x + sp_x *  4, g0_y + sp_y * 2, sz_x, sz_y }, 'G', 'g' },
			{ { g2_x + sp_x *  5, g0_y + sp_y * 2, sz_x, sz_y }, 'H', 'h' },
			{ { g2_x + sp_x *  6, g0_y + sp_y * 2, sz_x, sz_y }, 'J', 'j' },
			{ { g2_x + sp_x *  7, g0_y + sp_y * 2, sz_x, sz_y }, 'K', 'k' },
			{ { g2_x + sp_x *  8, g0_y + sp_y * 2, sz_x, sz_y }, 'L', 'l' },
			{ { g2_x + sp_x *  9, g0_y + sp_y * 2, sz_x, sz_y }, ';', ':' },
			{ { g2_x + sp_x * 10, g0_y + sp_y * 2, sz_x, sz_y }, '\'', '"' },
			{ { g2_x + sp_x * 11, g0_y + sp_y * 2, sz7x, sz_y }, KEY_ENTER, KEY_ENTER },

			{ { g0_x,             g0_y + sp_y * 3, sz4x, sz_y }, KEY_SHIFT_LEFT, KEY_SHIFT_LEFT },
			{ { g3_x + sp_x *  0, g0_y + sp_y * 3, sz_x, sz_y }, 'Z', 'z' },
			{ { g3_x + sp_x *  1, g0_y + sp_y * 3, sz_x, sz_y }, 'X', 'x' },
			{ { g3_x + sp_x *  2, g0_y + sp_y * 3, sz_x, sz_y }, 'C', 'c' },
			{ { g3_x + sp_x *  3, g0_y + sp_y * 3, sz_x, sz_y }, 'V', 'v' },
			{ { g3_x + sp_x *  4, g0_y + sp_y * 3, sz_x, sz_y }, 'B', 'b' },
			{ { g3_x + sp_x *  5, g0_y + sp_y * 3, sz_x, sz_y }, 'N', 'n' },
			{ { g3_x + sp_x *  6, g0_y + sp_y * 3, sz_x, sz_y }, 'M', 'm' },
			{ { g3_x + sp_x *  7, g0_y + sp_y * 3, sz_x, sz_y }, ',', '<' },
			{ { g3_x + sp_x *  8, g0_y + sp_y * 3, sz_x, sz_y }, '.', '>' },
			{ { g3_x + sp_x *  9, g0_y + sp_y * 3, sz_x, sz_y }, '/', '?' },
			{ { g3_x + sp_x * 10, g0_y + sp_y * 3, sz5x, sz_y }, KEY_SHIFT_RIGHT, KEY_SHIFT_RIGHT },

			{ { g0_x + sp3x *  0, g0_y + sp_y * 4, sz8x, sz_y }, KEY_CTRL, KEY_CTRL },
			{ { g0_x + sp3x *  1, g0_y + sp_y * 4, sz8x, sz_y }, KEY_ALT,  KEY_ALT },
			{ { g0_x + sp3x *  2, g0_y + sp_y * 4, sz9x, sz_y }, ' ', ' ' },
			{ { g4_x            , g0_y + sp_y * 4, sz8x, sz_y }, KEY_FN, KEY_FN },
			{ { g5_x + sp5x *  0, g0_y + sp_y * 4, szax, sz_y }, KEY_ARROW_LEFT,  KEY_ARROW_LEFT  },
			{ { g5_x + sp5x *  1, g0_y + sp_y * 4, szax, sz_y }, KEY_ARROW_DOWN,  KEY_ARROW_DOWN  },
			{ { g5_x + sp5x *  2, g0_y + sp_y * 4, szax, sz_y }, KEY_ARROW_RIGHT, KEY_ARROW_RIGHT },
			{ { g5_x + sp5x *  3, g0_y + sp_y * 4, szax, sz_y }, KEY_ARROW_UP,    KEY_ARROW_UP    }
		};

		struct key_t {
			bool	level;
			bool	positive;
			bool	negative;
			bool	draw;
			key_t() noexcept : level(false), positive(false), negative(true), draw(true) { }
		};
		key_t	key_[14 + 14 + 13 + 12 + 8];

		SELECT_FUNC_TYPE	select_func_;
		char	code_;
		bool	shift_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	loc		ロケーション
		*/
		//-----------------------------------------------------------------//
		key_asc(const vtx::srect& loc = vtx::srect(0), const char* str = nullptr) noexcept :
			widget(loc, str), key_{ },
			select_func_(), code_(0), shift_(false)
		{
			at_location().size.x = 13 * sp_x + sz2x + space;
			at_location().size.y = sp_y * 5;
			insert_widget(this);
		}

		key_asc(const key_asc& th) = delete;
		key_asc& operator = (const key_asc& th) = delete;

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクタ
		*/
		//-----------------------------------------------------------------//
		virtual ~key_asc() noexcept { remove_widget(this); }

		//-----------------------------------------------------------------//
		/*!
			@brief	型整数を取得
			@return 型整数
		*/
		//-----------------------------------------------------------------//
		const char* get_name() const noexcept override { return "KeyAsc"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ID を取得
			@return ID
		*/
		//-----------------------------------------------------------------//
		ID get_id() const noexcept override { return ID::KEY_ASC; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void init() noexcept override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ判定を更新
			@param[in]	pos		判定位置
			@param[in]	num		タッチ数
		*/
		//-----------------------------------------------------------------//
		void update_touch(const vtx::spos& pos, uint16_t num) noexcept override
		{
			update_touch_def(pos, num);

			auto loc = vtx::srect(get_final_position(), widget::get_location().size);
			uint32_t i = 0;
			bool all = false;
			for(auto& k : key_) {
				vtx::srect r(loc.org + key_locations_[i].rect.org, key_locations_[i].rect.size);
				auto level = false;
				if(r.is_focus(pos)) {
					level = num > 0;
				}
				k.positive = ( level && !k.level);
				k.negative = (!level &&  k.level);
				k.level = level;
				if(k.positive) {
					auto code = key_locations_[i].code;
					if(code == KEY_SHIFT_RIGHT || code == KEY_SHIFT_LEFT) {
						shift_ = !shift_;
						all = true;
					} else if(code == KEY_CAPS_LOCK) {
					} else if(code == KEY_CTRL) {
					} else if(code == KEY_ALT) {
					} else if(code == KEY_FN) {
					} else {
						if(shift_) {
							code_ = key_locations_[i].shift;
						} else {
							code_ = key_locations_[i].code;
						}
					}
					k.draw = true;
				}
				if(k.negative) {
					k.draw = true;
				}
				++i;
			}
			if(all) {
				uint32_t i = 0;
				for(auto& k : key_) {
					auto code = key_locations_[i].code;
					if(code > 0x20 && code < 0x80) {
						k.draw = true;
					}
					++i;
				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	選択推移
		*/
		//-----------------------------------------------------------------//
		void exec_select() noexcept override
		{
			if(code_ != 0) {
				if(select_func_) {
					select_func_(code_);
				}
				code_ = 0;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	許可・不許可
			@param[in]	ena		不許可の場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool ena = true) override
		{
			if(ena) {
				set_state(STATE::ENABLE);
			} else {
				set_state(STATE::DISABLE);
				reset_touch_state();
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト関数への参照
			@return	セレクト関数
		*/
		//-----------------------------------------------------------------//
		SELECT_FUNC_TYPE& at_select_func() noexcept { return select_func_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	描画
		*/
		//-----------------------------------------------------------------//
		template<class RDR>
		void draw(RDR& rdr) noexcept
		{
			auto r = vtx::srect(get_final_position(), get_location().size);

			uint32_t i = 0;
			for(auto& k : key_) {
				uint8_t inten = 64;
				if(k.level) {
					inten = 192;
				}
				if(k.draw) {
					k.draw = false;
					graphics::share_color sc;
					sc.set_color(get_base_color().rgba8, inten);
					rdr.set_fore_color(sc);
					auto rr = key_locations_[i].rect;
					rr.org += r.org;
					if(k.level) {
						rr.org += 1;
						rr.size -= 2;
					}
					rdr.round_box(rr, 3);

					rdr.set_fore_color(get_font_color());
					char cha;
					if(shift_) {
						cha = key_locations_[i].shift;
					} else {
						cha = key_locations_[i].code;
					}
					switch(cha) {
					case KEY_BACK_SPACE: {
						vtx::spos sz(8 * 2, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "BS");
						}
						break;
					case KEY_TAB: {
						vtx::spos sz(8 * 3, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "TAB");
						}
						break;
					case KEY_CAPS_LOCK: {
						vtx::spos sz(8 * 3, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "[A]");
						}
						break;
					case KEY_ENTER: {
						vtx::spos sz(8 * 5, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "Enter");
						}
						break;
					case KEY_SHIFT_LEFT:
					case KEY_SHIFT_RIGHT: {
						vtx::spos sz(8 * 5, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "Shift");
						}
						break;
					case KEY_CTRL: {
						vtx::spos sz(8 * 4, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "CTRL");
						}
						break;
					case KEY_ALT: {
						vtx::spos sz(8 * 3, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "ALT");
						}
						break;
					case KEY_FN: {
						vtx::spos sz(8 * 2, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "Fn");
						}
						break;
					case KEY_ARROW_LEFT: {
						vtx::spos sz(8 * 2, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "Lt");
						}
						break;
					case KEY_ARROW_DOWN: {
						vtx::spos sz(8 * 2, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "Dn");
						}
						break;
					case KEY_ARROW_RIGHT: {
						vtx::spos sz(8 * 2, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "Ri");
						}
						break;
					case KEY_ARROW_UP: {
						vtx::spos sz(8 * 2, 16);
						rdr.draw_text(rr.org + (rr.size - sz) / 2, "Up");
						}
						break;
					default: {
						vtx::spos sz(8, 16);
						rdr.draw_font(rr.org + (rr.size - sz) / 2, cha);
						}
						break;
					}
				}
				++i;
			}
		}
	};
}

<|endoftext|>


<commit_before>// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://code.google.com/p/protobuf/
//
// 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 Google Inc. 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.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <stack>
#include <google/protobuf/stubs/hash.h>

#include <google/protobuf/message.h>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/map-util.h>
#include <google/protobuf/stubs/stl_util-inl.h>

namespace google {
namespace protobuf {

using internal::WireFormat;
using internal::ReflectionOps;

Message::~Message() {}

void Message::MergeFrom(const Message& from) {
  const Descriptor* descriptor = GetDescriptor();
  GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
    << ": Tried to merge from a message with a different type.  "
       "to: " << descriptor->full_name() << ", "
       "from:" << from.GetDescriptor()->full_name();
  ReflectionOps::Merge(from, this);
}

void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
  MergeFrom(*down_cast<const Message*>(&other));
}

void Message::CopyFrom(const Message& from) {
  const Descriptor* descriptor = GetDescriptor();
  GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
    << ": Tried to copy from a message with a different type."
       "to: " << descriptor->full_name() << ", "
       "from:" << from.GetDescriptor()->full_name();
  ReflectionOps::Copy(from, this);
}

string Message::GetTypeName() const {
  return GetDescriptor()->full_name();
}

void Message::Clear() {
  ReflectionOps::Clear(this);
}

bool Message::IsInitialized() const {
  return ReflectionOps::IsInitialized(*this);
}

void Message::FindInitializationErrors(vector<string>* errors) const {
  return ReflectionOps::FindInitializationErrors(*this, "", errors);
}

string Message::InitializationErrorString() const {
  vector<string> errors;
  FindInitializationErrors(&errors);
  return JoinStrings(errors, ", ");
}

void Message::CheckInitialized() const {
  GOOGLE_CHECK(IsInitialized())
    << "Message of type \"" << GetDescriptor()->full_name()
    << "\" is missing required fields: " << InitializationErrorString();
}

void Message::DiscardUnknownFields() {
  return ReflectionOps::DiscardUnknownFields(this);
}

bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) {
  return WireFormat::ParseAndMergePartial(input, this);
}

bool Message::ParseFromFileDescriptor(int file_descriptor) {
  io::FileInputStream input(file_descriptor);
  return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0;
}

bool Message::ParsePartialFromFileDescriptor(int file_descriptor) {
  io::FileInputStream input(file_descriptor);
  return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0;
}

bool Message::ParseFromIstream(istream* input) {
  io::IstreamInputStream zero_copy_input(input);
  return ParseFromZeroCopyStream(&zero_copy_input) && input->eof();
}

bool Message::ParsePartialFromIstream(istream* input) {
  io::IstreamInputStream zero_copy_input(input);
  return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof();
}

void Message::SerializeWithCachedSizes(
    io::CodedOutputStream* output) const {
  WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output);
}

int Message::ByteSize() const {
  int size = WireFormat::ByteSize(*this);
  SetCachedSize(size);
  return size;
}

void Message::SetCachedSize(int size) const {
  GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name()
             << "\" implements neither SetCachedSize() nor ByteSize().  "
                "Must implement one or the other.";
}

int Message::SpaceUsed() const {
  return GetReflection()->SpaceUsed(*this);
}

bool Message::SerializeToFileDescriptor(int file_descriptor) const {
  io::FileOutputStream output(file_descriptor);
  return SerializeToZeroCopyStream(&output);
}

bool Message::SerializePartialToFileDescriptor(int file_descriptor) const {
  io::FileOutputStream output(file_descriptor);
  return SerializePartialToZeroCopyStream(&output);
}

bool Message::SerializeToOstream(ostream* output) const {
  {
    io::OstreamOutputStream zero_copy_output(output);
    if (!SerializeToZeroCopyStream(&zero_copy_output)) return false;
  }
  return output->good();
}

bool Message::SerializePartialToOstream(ostream* output) const {
  io::OstreamOutputStream zero_copy_output(output);
  return SerializePartialToZeroCopyStream(&zero_copy_output);
}

Reflection::~Reflection() {}

// ===================================================================
// MessageFactory

MessageFactory::~MessageFactory() {}

namespace {

class GeneratedMessageFactory : public MessageFactory {
 public:
  GeneratedMessageFactory();
  ~GeneratedMessageFactory();

  static GeneratedMessageFactory* singleton();

  typedef void RegistrationFunc(const string&);
  void RegisterFile(const char* file, RegistrationFunc* registration_func);
  void RegisterType(const Descriptor* descriptor, const Message* prototype);

  // implements MessageFactory ---------------------------------------
  const Message* GetPrototype(const Descriptor* type);

 private:
  // Only written at static init time, so does not require locking.
  hash_map<const char*, RegistrationFunc*,
           hash<const char*>, streq> file_map_;

  // Initialized lazily, so requires locking.
  Mutex mutex_;
  hash_map<const Descriptor*, const Message*> type_map_;
};

GeneratedMessageFactory* generated_message_factory_ = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_);

void ShutdownGeneratedMessageFactory() {
  delete generated_message_factory_;
}

void InitGeneratedMessageFactory() {
  generated_message_factory_ = new GeneratedMessageFactory;
  internal::OnShutdown(&ShutdownGeneratedMessageFactory);
}

GeneratedMessageFactory::GeneratedMessageFactory() {}
GeneratedMessageFactory::~GeneratedMessageFactory() {}

GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
  ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_,
                 &InitGeneratedMessageFactory);
  return generated_message_factory_;
}

void GeneratedMessageFactory::RegisterFile(
    const char* file, RegistrationFunc* registration_func) {
  if (!InsertIfNotPresent(&file_map_, file, registration_func)) {
    GOOGLE_LOG(FATAL) << "File is already registered: " << file;
  }
}

void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor,
                                           const Message* prototype) {
  GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool())
    << "Tried to register a non-generated type with the generated "
       "type registry.";

  // This should only be called as a result of calling a file registration
  // function during GetPrototype(), in which case we already have locked
  // the mutex.
  mutex_.AssertHeld();
  if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) {
    GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name();
  }
}

const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
  {
    ReaderMutexLock lock(&mutex_);
    const Message* result = FindPtrOrNull(type_map_, type);
    if (result != NULL) return result;
  }

  // If the type is not in the generated pool, then we can't possibly handle
  // it.
  if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL;

  // Apparently the file hasn't been registered yet.  Let's do that now.
  RegistrationFunc* registration_func =
      FindPtrOrNull(file_map_, type->file()->name().c_str());
  if (registration_func == NULL) {
    GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't "
                   "registered: " << type->file()->name();
    return NULL;
  }

  WriterMutexLock lock(&mutex_);

  // Check if another thread preempted us.
  const Message* result = FindPtrOrNull(type_map_, type);
  if (result == NULL) {
    // Nope.  OK, register everything.
    registration_func(type->file()->name());
    // Should be here now.
    result = FindPtrOrNull(type_map_, type);
  }

  if (result == NULL) {
    GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't "
                << "registered: " << type->full_name();
  }

  return result;
}

}  // namespace

MessageFactory* MessageFactory::generated_factory() {
  return GeneratedMessageFactory::singleton();
}

void MessageFactory::InternalRegisterGeneratedFile(
    const char* filename, void (*register_messages)(const string&)) {
  GeneratedMessageFactory::singleton()->RegisterFile(filename,
                                                     register_messages);
}

void MessageFactory::InternalRegisterGeneratedMessage(
    const Descriptor* descriptor, const Message* prototype) {
  GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype);
}

}  // namespace protobuf
}  // namespace google
<commit_msg>Fix compile error.<commit_after>// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://code.google.com/p/protobuf/
//
// 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 Google Inc. 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.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <stack>
#include <istream>

#include <google/protobuf/stubs/hash.h>

#include <google/protobuf/message.h>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/map-util.h>
#include <google/protobuf/stubs/stl_util-inl.h>

namespace google {
namespace protobuf {

using internal::WireFormat;
using internal::ReflectionOps;

Message::~Message() {}

void Message::MergeFrom(const Message& from) {
  const Descriptor* descriptor = GetDescriptor();
  GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
    << ": Tried to merge from a message with a different type.  "
       "to: " << descriptor->full_name() << ", "
       "from:" << from.GetDescriptor()->full_name();
  ReflectionOps::Merge(from, this);
}

void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
  MergeFrom(*down_cast<const Message*>(&other));
}

void Message::CopyFrom(const Message& from) {
  const Descriptor* descriptor = GetDescriptor();
  GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
    << ": Tried to copy from a message with a different type."
       "to: " << descriptor->full_name() << ", "
       "from:" << from.GetDescriptor()->full_name();
  ReflectionOps::Copy(from, this);
}

string Message::GetTypeName() const {
  return GetDescriptor()->full_name();
}

void Message::Clear() {
  ReflectionOps::Clear(this);
}

bool Message::IsInitialized() const {
  return ReflectionOps::IsInitialized(*this);
}

void Message::FindInitializationErrors(vector<string>* errors) const {
  return ReflectionOps::FindInitializationErrors(*this, "", errors);
}

string Message::InitializationErrorString() const {
  vector<string> errors;
  FindInitializationErrors(&errors);
  return JoinStrings(errors, ", ");
}

void Message::CheckInitialized() const {
  GOOGLE_CHECK(IsInitialized())
    << "Message of type \"" << GetDescriptor()->full_name()
    << "\" is missing required fields: " << InitializationErrorString();
}

void Message::DiscardUnknownFields() {
  return ReflectionOps::DiscardUnknownFields(this);
}

bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) {
  return WireFormat::ParseAndMergePartial(input, this);
}

bool Message::ParseFromFileDescriptor(int file_descriptor) {
  io::FileInputStream input(file_descriptor);
  return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0;
}

bool Message::ParsePartialFromFileDescriptor(int file_descriptor) {
  io::FileInputStream input(file_descriptor);
  return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0;
}

bool Message::ParseFromIstream(istream* input) {
  io::IstreamInputStream zero_copy_input(input);
  return ParseFromZeroCopyStream(&zero_copy_input) && input->eof();
}

bool Message::ParsePartialFromIstream(istream* input) {
  io::IstreamInputStream zero_copy_input(input);
  return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof();
}

void Message::SerializeWithCachedSizes(
    io::CodedOutputStream* output) const {
  WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output);
}

int Message::ByteSize() const {
  int size = WireFormat::ByteSize(*this);
  SetCachedSize(size);
  return size;
}

void Message::SetCachedSize(int size) const {
  GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name()
             << "\" implements neither SetCachedSize() nor ByteSize().  "
                "Must implement one or the other.";
}

int Message::SpaceUsed() const {
  return GetReflection()->SpaceUsed(*this);
}

bool Message::SerializeToFileDescriptor(int file_descriptor) const {
  io::FileOutputStream output(file_descriptor);
  return SerializeToZeroCopyStream(&output);
}

bool Message::SerializePartialToFileDescriptor(int file_descriptor) const {
  io::FileOutputStream output(file_descriptor);
  return SerializePartialToZeroCopyStream(&output);
}

bool Message::SerializeToOstream(ostream* output) const {
  {
    io::OstreamOutputStream zero_copy_output(output);
    if (!SerializeToZeroCopyStream(&zero_copy_output)) return false;
  }
  return output->good();
}

bool Message::SerializePartialToOstream(ostream* output) const {
  io::OstreamOutputStream zero_copy_output(output);
  return SerializePartialToZeroCopyStream(&zero_copy_output);
}

Reflection::~Reflection() {}

// ===================================================================
// MessageFactory

MessageFactory::~MessageFactory() {}

namespace {

class GeneratedMessageFactory : public MessageFactory {
 public:
  GeneratedMessageFactory();
  ~GeneratedMessageFactory();

  static GeneratedMessageFactory* singleton();

  typedef void RegistrationFunc(const string&);
  void RegisterFile(const char* file, RegistrationFunc* registration_func);
  void RegisterType(const Descriptor* descriptor, const Message* prototype);

  // implements MessageFactory ---------------------------------------
  const Message* GetPrototype(const Descriptor* type);

 private:
  // Only written at static init time, so does not require locking.
  hash_map<const char*, RegistrationFunc*,
           hash<const char*>, streq> file_map_;

  // Initialized lazily, so requires locking.
  Mutex mutex_;
  hash_map<const Descriptor*, const Message*> type_map_;
};

GeneratedMessageFactory* generated_message_factory_ = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_);

void ShutdownGeneratedMessageFactory() {
  delete generated_message_factory_;
}

void InitGeneratedMessageFactory() {
  generated_message_factory_ = new GeneratedMessageFactory;
  internal::OnShutdown(&ShutdownGeneratedMessageFactory);
}

GeneratedMessageFactory::GeneratedMessageFactory() {}
GeneratedMessageFactory::~GeneratedMessageFactory() {}

GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
  ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_,
                 &InitGeneratedMessageFactory);
  return generated_message_factory_;
}

void GeneratedMessageFactory::RegisterFile(
    const char* file, RegistrationFunc* registration_func) {
  if (!InsertIfNotPresent(&file_map_, file, registration_func)) {
    GOOGLE_LOG(FATAL) << "File is already registered: " << file;
  }
}

void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor,
                                           const Message* prototype) {
  GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool())
    << "Tried to register a non-generated type with the generated "
       "type registry.";

  // This should only be called as a result of calling a file registration
  // function during GetPrototype(), in which case we already have locked
  // the mutex.
  mutex_.AssertHeld();
  if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) {
    GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name();
  }
}

const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
  {
    ReaderMutexLock lock(&mutex_);
    const Message* result = FindPtrOrNull(type_map_, type);
    if (result != NULL) return result;
  }

  // If the type is not in the generated pool, then we can't possibly handle
  // it.
  if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL;

  // Apparently the file hasn't been registered yet.  Let's do that now.
  RegistrationFunc* registration_func =
      FindPtrOrNull(file_map_, type->file()->name().c_str());
  if (registration_func == NULL) {
    GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't "
                   "registered: " << type->file()->name();
    return NULL;
  }

  WriterMutexLock lock(&mutex_);

  // Check if another thread preempted us.
  const Message* result = FindPtrOrNull(type_map_, type);
  if (result == NULL) {
    // Nope.  OK, register everything.
    registration_func(type->file()->name());
    // Should be here now.
    result = FindPtrOrNull(type_map_, type);
  }

  if (result == NULL) {
    GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't "
                << "registered: " << type->full_name();
  }

  return result;
}

}  // namespace

MessageFactory* MessageFactory::generated_factory() {
  return GeneratedMessageFactory::singleton();
}

void MessageFactory::InternalRegisterGeneratedFile(
    const char* filename, void (*register_messages)(const string&)) {
  GeneratedMessageFactory::singleton()->RegisterFile(filename,
                                                     register_messages);
}

void MessageFactory::InternalRegisterGeneratedMessage(
    const Descriptor* descriptor, const Message* prototype) {
  GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype);
}

}  // namespace protobuf
}  // namespace google
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2009-2014, MAV'RIC Development Team
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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.
 ******************************************************************************/

/*******************************************************************************
 * \file 	serial_avr32.hpp
 *
 * \author 	MAV'RIC Team
 *
 * \brief 	Implementation of serial peripheral for avr32
 *
 ******************************************************************************/

#ifndef SERIAL_AVR32_H_
#define SERIAL_AVR32_H_

#include "serial.hpp"
#include "buffer.hpp"

extern "C"
{
	#include "usart.h"
}

/**
 * \brief 	Enumerate the possible UARTs
 */
typedef enum
{
	AVR32_SERIAL_0 		 	= 0,
	AVR32_SERIAL_1 			= 1,
	AVR32_SERIAL_2 			= 2,
	AVR32_SERIAL_3 			= 3,
	AVR32_SERIAL_4 			= 4,
	AVR32_SERIAL_MAX_NUMBER = 5,
} serial_avr32_devices_t;

/**
 * \brief 	UART modes
 */
typedef enum
{
	AVR32_SERIAL_OFF 	= 0,
	AVR32_SERIAL_IN 	= 1,
	AVR32_SERIAL_OUT 	= 2,
	AVR32_SERIAL_IN_OUT = 3,
} serial_avr32_mode_t;

/**
 * \brief 	Gpio map
 */
typedef struct
{
	uint8_t  pin;						///< Module pin.
	uint8_t  function;					///< Module function.
} serial_avr32_gpio_map_t;

/**
 * \brief 	Configuration structure
 */
typedef struct
{
	serial_avr32_devices_t 	serial_device;
	serial_avr32_mode_t		mode;
	usart_options_t 		options;
	serial_avr32_gpio_map_t rx_pin_map;
	serial_avr32_gpio_map_t tx_pin_map;
} serial_avr32_conf_t;

/**
 * \brief 	Typedef for interrupt handler function
 */
typedef void(*serial_avr32_irq_func_t)(void);

/**
 * \brief 	Implementation of serial peripheral for avr32
 */
class Serial_avr32: public Serial
{
public:

	/**
	 * \brief  	Initialises the peripheral
	 *
	 * \param 	config 		Device configuration
	 */
	Serial_avr32(serial_avr32_conf_t config);

	/**
	 * \brief 	Hardware initialization
	 *
	 * \return  true Success
	 * \return  false Error
	 */
	bool init(void);

	/**
	 * \brief 	Test if there are bytes available to read
	 *
	 * \return 	Number of incoming bytes available
	 */
	uint32_t readable(void);

	/**
	 * \brief 	Test if there is space available to write bytes
	 *
	 * \return 	Number of bytes available for writing
	 */
	uint32_t writeable(void);

	/**
	 * \brief 	Sends instantaneously all outgoing bytes
	 *
	 * \return 	Number of bytes available for writing
	 */
	void flush(void);

	/**
	 * \brief 	Attach a function to call after a receive interrupt is generated
	 *
	 * \details A default handler should be provided by the implementation to
	 * 			add the incoming data in a buffer, so is not mandatory to call
	 * 			this method. The function callback will be called after the
	 * 			interrupt handler
	 *
	 * \param  	func	 	Pointer to the callback function
	 *
	 * \return 	true		Success
	 * \return 	false		Failed
	 */
	bool attach(serial_interrupt_callback_t func);

	/**
	 * \brief 	Write bytes on the serial line
	 *
	 * \param 	byte 		Outgoing bytes
	 * \param 	size 		Number of bytes to write
	 *
	 * \return 	true		Data successfully written
	 * \return 	false		Data not written
	 */
	bool write(const uint8_t* bytes, const uint32_t size=1);

	/**
	 * \brief 	Read bytes from the serial line
	 *
	 * \param 	bytes 		Incoming bytes
	 * \param 	size 		Number of bytes to read
	 *
	 * \return 	true		Data successfully read
	 * \return 	false		Data not read
	 */
	bool read(uint8_t* bytes, const uint32_t size=1);

private:
	serial_avr32_conf_t			config_;			///< Configuration
	volatile avr32_usart_t* 	uart_;				///< Hardware peripheral
	Buffer_tpl<1024>			tx_buffer_;			///< Transmission buffer
	Buffer						rx_buffer_;			///< Reception buffer
	// Buffer_tpl<1024>			rx_buffer_;			///< Reception buffer

	static Serial_avr32*		handlers_[AVR32_SERIAL_MAX_NUMBER]; 	///< Array of 'this' pointers used for interrupt handling

	/**
	 * \brief 		Default interrupt-handling function
	 *
	 * \details 	This function is called by Serial_avr32::irq(), it is not
	 * 				static, thus has access to object members
	 */
	void irq_handler(void);

	/**
	 * \brief 		Callback function to be called after an interrupt
	 *
	 * \details 	By default NULL, can be modified via the 'attach' method
	 */
	serial_interrupt_callback_t irq_callback;

	/**
	 * \brief 		Main irq function
	 *
	 * \details 	This function has to be static in order to be registerable
	 * 				as interrupt handler. It does internally the dispatch to
	 * 				call the 'irq_handler' function on the right object instance
	 */
	static void irq0(void);
	static void irq1(void);
	static void irq2(void);
	static void irq3(void);
	static void irq4(void);
};

#endif /* SERIAL_AVR32_H_ */<commit_msg>Increase rx buffer size in serial_avr32<commit_after>/*******************************************************************************
 * Copyright (c) 2009-2014, MAV'RIC Development Team
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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.
 ******************************************************************************/

/*******************************************************************************
 * \file 	serial_avr32.hpp
 *
 * \author 	MAV'RIC Team
 *
 * \brief 	Implementation of serial peripheral for avr32
 *
 ******************************************************************************/

#ifndef SERIAL_AVR32_H_
#define SERIAL_AVR32_H_

#include "serial.hpp"
#include "buffer.hpp"

extern "C"
{
	#include "usart.h"
}

/**
 * \brief 	Enumerate the possible UARTs
 */
typedef enum
{
	AVR32_SERIAL_0 		 	= 0,
	AVR32_SERIAL_1 			= 1,
	AVR32_SERIAL_2 			= 2,
	AVR32_SERIAL_3 			= 3,
	AVR32_SERIAL_4 			= 4,
	AVR32_SERIAL_MAX_NUMBER = 5,
} serial_avr32_devices_t;

/**
 * \brief 	UART modes
 */
typedef enum
{
	AVR32_SERIAL_OFF 	= 0,
	AVR32_SERIAL_IN 	= 1,
	AVR32_SERIAL_OUT 	= 2,
	AVR32_SERIAL_IN_OUT = 3,
} serial_avr32_mode_t;

/**
 * \brief 	Gpio map
 */
typedef struct
{
	uint8_t  pin;						///< Module pin.
	uint8_t  function;					///< Module function.
} serial_avr32_gpio_map_t;

/**
 * \brief 	Configuration structure
 */
typedef struct
{
	serial_avr32_devices_t 	serial_device;
	serial_avr32_mode_t		mode;
	usart_options_t 		options;
	serial_avr32_gpio_map_t rx_pin_map;
	serial_avr32_gpio_map_t tx_pin_map;
} serial_avr32_conf_t;

/**
 * \brief 	Typedef for interrupt handler function
 */
typedef void(*serial_avr32_irq_func_t)(void);

/**
 * \brief 	Implementation of serial peripheral for avr32
 */
class Serial_avr32: public Serial
{
public:

	/**
	 * \brief  	Initialises the peripheral
	 *
	 * \param 	config 		Device configuration
	 */
	Serial_avr32(serial_avr32_conf_t config);

	/**
	 * \brief 	Hardware initialization
	 *
	 * \return  true Success
	 * \return  false Error
	 */
	bool init(void);

	/**
	 * \brief 	Test if there are bytes available to read
	 *
	 * \return 	Number of incoming bytes available
	 */
	uint32_t readable(void);

	/**
	 * \brief 	Test if there is space available to write bytes
	 *
	 * \return 	Number of bytes available for writing
	 */
	uint32_t writeable(void);

	/**
	 * \brief 	Sends instantaneously all outgoing bytes
	 *
	 * \return 	Number of bytes available for writing
	 */
	void flush(void);

	/**
	 * \brief 	Attach a function to call after a receive interrupt is generated
	 *
	 * \details A default handler should be provided by the implementation to
	 * 			add the incoming data in a buffer, so is not mandatory to call
	 * 			this method. The function callback will be called after the
	 * 			interrupt handler
	 *
	 * \param  	func	 	Pointer to the callback function
	 *
	 * \return 	true		Success
	 * \return 	false		Failed
	 */
	bool attach(serial_interrupt_callback_t func);

	/**
	 * \brief 	Write bytes on the serial line
	 *
	 * \param 	byte 		Outgoing bytes
	 * \param 	size 		Number of bytes to write
	 *
	 * \return 	true		Data successfully written
	 * \return 	false		Data not written
	 */
	bool write(const uint8_t* bytes, const uint32_t size=1);

	/**
	 * \brief 	Read bytes from the serial line
	 *
	 * \param 	bytes 		Incoming bytes
	 * \param 	size 		Number of bytes to read
	 *
	 * \return 	true		Data successfully read
	 * \return 	false		Data not read
	 */
	bool read(uint8_t* bytes, const uint32_t size=1);

private:
	serial_avr32_conf_t			config_;			///< Configuration
	volatile avr32_usart_t* 	uart_;				///< Hardware peripheral
	Buffer_tpl<1024>			tx_buffer_;			///< Transmission buffer
	// Buffer						rx_buffer_;			///< Reception buffer
	Buffer_tpl<1024>			rx_buffer_;			///< Reception buffer

	static Serial_avr32*		handlers_[AVR32_SERIAL_MAX_NUMBER]; 	///< Array of 'this' pointers used for interrupt handling

	/**
	 * \brief 		Default interrupt-handling function
	 *
	 * \details 	This function is called by Serial_avr32::irq(), it is not
	 * 				static, thus has access to object members
	 */
	void irq_handler(void);

	/**
	 * \brief 		Callback function to be called after an interrupt
	 *
	 * \details 	By default NULL, can be modified via the 'attach' method
	 */
	serial_interrupt_callback_t irq_callback;

	/**
	 * \brief 		Main irq function
	 *
	 * \details 	This function has to be static in order to be registerable
	 * 				as interrupt handler. It does internally the dispatch to
	 * 				call the 'irq_handler' function on the right object instance
	 */
	static void irq0(void);
	static void irq1(void);
	static void irq2(void);
	static void irq3(void);
	static void irq4(void);
};

#endif /* SERIAL_AVR32_H_ */<|endoftext|>


<commit_before>#ifndef VPP_COPY_HH__
# define VPP_COPY_HH__

# include <vpp/parallel_for.hh>

namespace vpp
{

  template <typename V, unsigned N>
  void copy(imageNd<V, N>& src, imageNd<V, N>& dst)
  {
    pixel_wise(src, dst) << [=] (auto& in, auto& out) { out = in; };
  }

};

#endif
<commit_msg>Fix copy.<commit_after>#ifndef VPP_COPY_HH__
# define VPP_COPY_HH__

# include <vpp/parallel_for.hh>

namespace vpp
{

  template <typename I, typename J>
  void copy(I& src, J& dst)
  {
    pixel_wise(src, dst) << [=] (auto& in, auto& out) { out = in; };
  }

};

#endif
<|endoftext|>