text:
/*
 * HitFitAnalyser.cpp
 *
 *  Created on: Jul 5, 2011
 *      Author: senkin
 */
#include "../../interface/Analysers/HitFitAnalyser.h"
#include "../../interface/LumiReWeighting.h"
#include "../../interface/EventWeightProvider.h"
#include "../../interface/PoissonMeanShifter.h"
#include "../../interface/GlobalVariables.h"
#include "../../interface/ReconstructionModules/ChiSquaredBasedTopPairReconstruction.h"
#include <boost/scoped_ptr.hpp>

//using namespace reweight;
using namespace BAT;

void HitFitAnalyser::analyse(const EventPtr event) {
	weight_ = event->weight() * prescale_ * scale_;
	//fit only the events that pass full ttbar selection
	if (!topEplusJetsRefSelection_->passesFullSelectionExceptLastTwoSteps(event))
		;
	return;

	const JetCollection jets = topEplusJetsRefSelection_->cleanedJets(event);
	LeptonPointer selectedLepton = topEplusJetsRefSelection_->signalLepton(event);
	METPointer met = event->MET();

	histMan_->H1D("m3_diff")->Fill(fabs(truthMatchEvent.M3() - TtbarHypothesis::M3(jets)));

	boost::scoped_ptr<ChiSquaredBasedTopPairReconstruction> chi2Reco(
			new ChiSquaredBasedTopPairReconstruction(selectedLepton, met, jets));
	if (!chi2Reco->meetsInitialCriteria()) { //reports details on failure and skips event
		cout << chi2Reco->getDetailsOnFailure();
		return;
	}
	TtbarHypothesisPointer bestTopHypothesis = chi2Reco->getBestSolution();

	//set MC matching flag
	if (event->getDataType() == DataType::TTJets)
		do_MC_matching = true;
	else
		do_MC_matching = false;

	//initialise pile-up shifters
	PoissonMeanShifter PShiftUp(0.6); // PU-systematic
	PoissonMeanShifter PShiftDown(-0.6); // PU-systematic

	//temporary file for jet fit info (ugly but works)
	string tempFileName = "temp.txt";
	ofstream tempFile(tempFileName.c_str());

	histMan_->setCurrentHistogramFolder("hitfitStudy");

	if (Globals::produceFitterASCIIoutput) {
		//write the event info into ASCII file
		outFile << "------------------------------------------" << endl;
		outFile << "BeginEvent" << endl;
		outFile << "RunNr: " << event->runnumber() << endl;
		outFile << "LumiSection: " << event->lumiblock() << endl;
		outFile << "EventNr: " << event->eventnumber() << endl;
		outFile << "EventWeight: " << weight_ << "  ";
		double nVertices(0);
		if (!event->isRealData()) {
			float lumiWeight = event->PileUpWeight();

			if (Globals::pileUpReweightingMethod == PileUpReweightingMethod::averagePileUp
					|| Globals::pileUpReweightingMethod == PileUpReweightingMethod::threeDReweighting)
				nVertices = event->averageNumberOfVertices();
			if (Globals::pileUpReweightingMethod == PileUpReweightingMethod::inTimePileUpOnly)
				nVertices = event->inTimeOnlyNumberOfVertices();
			float lumiWeightUp = lumiWeight * PShiftUp.ShiftWeight(nVertices);
			float lumiWeightDown = lumiWeight * PShiftDown.ShiftWeight(nVertices);
			outFile << lumiWeight << "  " << lumiWeightUp << "  " << lumiWeightDown;

		} else
			outFile << "1  1  1";

		outFile << endl;

		outFile << jets.size() << "  " << event->Vertices().size() << "  ";
		if (!event->isRealData()) {
			outFile << nVertices;
		} else
			outFile << "9999";

		outFile << "  ";
		if ((event->getDataType() == DataType::TTJets) or (event->getDataType() == DataType::ttbar161)
				or (event->getDataType() == DataType::ttbar163) or (event->getDataType() == DataType::ttbar166)
				or (event->getDataType() == DataType::ttbar169) or (event->getDataType() == DataType::ttbar175)
				or (event->getDataType() == DataType::ttbar178) or (event->getDataType() == DataType::ttbar181)
				or (event->getDataType() == DataType::ttbar184)) {
			outFile << "9999  9999  9999" << endl; //needs to be fixed
		} else
			outFile << "9999  9999  9999" << endl;
	}

	//prepare the jets collection
	// Copy jets into an array
	JetCollection jetCopy;
	for (JetCollection::const_iterator j = jets.begin(); j != jets.end(); ++j) {
		jetCopy.push_back(*j);
	}

	std::sort(jetCopy.begin(), jetCopy.end(), jetPtComp);

	jetsForFitting.clear();
	unsigned numJetsToFit = jetCopy.size();

	if (jetCopy.size() >= 4) {
		if (numJetsToFit > 4)
			numJetsToFit = 4;
		jetsForFitting.insert(jetsForFitting.begin(), jetCopy.begin(), jetCopy.begin() + numJetsToFit);
	}

	BatHitFit hhFitter(electronTranslator_, muonTranslator_, jetTranslator_, metTranslator_, hitfitDefault_,
			hitfitLepWMass_, hitfitHadWMass_, hitfitTopMass_);

	// Clear the internal state
	hhFitter.clear();

	const ElectronPointer signalElectron(boost::static_pointer_cast<Electron>(selectedLepton));
	//TODO: fix the fitter to accept lepton class OR particle!!
	hhFitter.AddLepton(*signalElectron);

	// Add jets into HitFit
	for (size_t jet = 0; jet != jetsForFitting.size(); ++jet) {
		hhFitter.AddJet(*jetsForFitting.at(jet));
	}

	//calculate all jets pt
	double all_jets_pt = 0;
	for (unsigned int i = 0; i != jetsForFitting.size(); ++i) {
		all_jets_pt = all_jets_pt + jetsForFitting[i]->pt();
	}

	histMan_->H1D("AllJetsPt")->Fill(all_jets_pt, weight_);

	// Add missing transverse energy into HitFit
	hhFitter.SetMet(*met);

	// Results of the fit for all jet permutation of the event
	std::vector<hitfit::Lepjets_Event> hitfitEventsInput;

	// Results of the fit for all jet permutation of the event
	std::vector<hitfit::Fit_Result> hitfitResult;
	//
	// R U N   H I T F I T
	//
	// Run the kinematic fit and get how many permutations is possible
	// in the fit

	size_t nHitFit = hhFitter.FitAllPermutation();

//   // Get the number of jets
//   nHitFitJet      = hhFitter.GetEvent().njets();

	// Get the input events for all permutations
	hitfitEventsInput = hhFitter.GetUnfittedEvent();

	// Get the fit results for all permutations
	hitfitResult = hhFitter.GetFitAllPermutation();

	double bestChi2 = 999.;
	unsigned bestX2pos = nHitFit + 1;

//   // Loop over all permutations and extract the information
	for (size_t fit = 0; fit != nHitFit; ++fit) {

		// Get the event before the fit
		hitfit::Lepjets_Event unfittedEvent = hitfitEventsInput[fit];

		// Get the event after the fit
		hitfit::Fit_Result fitResult = hitfitResult[fit];

		if (hitfitResult[fit].chisq() > 0.0) {
			histMan_->H1D("FittedTopMassAllSolutions")->Fill(fitResult.mt(), weight_);
			histMan_->H1D("FitChiSquaredAllSolutions")->Fill(fitResult.chisq(), weight_);
			histMan_->H1D("FitLogChiSqdAllSolutions")->Fill(log(fitResult.chisq()), weight_);
			const hitfit::Column_Vector &px = fitResult.pullx();
			const hitfit::Column_Vector &py = fitResult.pully();
			double sumPx = 0.0;
			for (int i = 0; i < px.num_row(); ++i) {
				histMan_->H1D("PullDistAllVarsAllSolutions")->Fill(px[i]);
				histMan_->H2D("PullDistPerVarAllSolutions")->Fill(px[i], i);
				sumPx += px[i] * px[i];
			}
			histMan_->H1D("PullSumSquaredAllSolutions")->Fill(sumPx);
			for (int i = 0; i < py.num_row(); ++i) {
				histMan_->H1D("PullDistYVarsAllSolutions")->Fill(py[i]);
			}

			if (Globals::produceFitterASCIIoutput) {
				if (fitResult.chisq() < 20) {
					tempFile << fitResult.mt() << "  " << fitResult.sigmt() << "  " << fitResult.chisq() << "  ";
					for (unsigned int i = 0; i != jetsForFitting.size(); ++i) {
						if (fitResult.jet_types()[i] == 13)
							tempFile << i;
					}
					tempFile << "  ";
					for (unsigned int i = 0; i != jetsForFitting.size(); ++i) {
						if (fitResult.jet_types()[i] == 14)
							tempFile << i;
					}
					tempFile << "  ";
					for (unsigned int i = 0; i != jetsForFitting.size(); ++i) {
						if (fitResult.jet_types()[i] == 12)
							tempFile << i;
					}
					tempFile << endl;
				}
			}

		}
		if (fitResult.chisq() > 0.0 && fitResult.chisq() < bestChi2) {
			bestChi2 = fitResult.chisq();
			bestX2pos = fit;
		}

	}

	//
	// END PART WHICH EXTRACTS INFORMATION FROM HITFIT
	//

	if (bestX2pos < nHitFit + 1) {
		histMan_->H1D("FittedTopMassBestSolution")->Fill(hitfitResult[bestX2pos].mt(), weight_);
		histMan_->H1D("FitChiSquaredBestSolution")->Fill(hitfitResult[bestX2pos].chisq(), weight_);
		histMan_->H1D("FitLogChiSqdBestSolution")->Fill(log(hitfitResult[bestX2pos].chisq()), weight_);

		const hitfit::Column_Vector &px = hitfitResult[bestX2pos].pullx();
		const hitfit::Column_Vector &py = hitfitResult[bestX2pos].pully();
		double sumPx = 0.0;
		for (int i = 0; i < px.num_row(); ++i) {
			histMan_->H1D("PullDistAllVarsBestSolution")->Fill(px[i]);
			histMan_->H2D("PullDistPerVarBestSolution")->Fill(px[i], i);
			sumPx += px[i] * px[i];
		}
		histMan_->H1D("PullSumSquaredBestSolution")->Fill(sumPx);
		for (int i = 0; i < py.num_row(); ++i) {
			histMan_->H1D("PullDistYVarsBestSolution")->Fill(py[i]);
		}

		//pass hitfit event into BAT format
		lepton_charge = selectedLepton->charge();
		BAT::TtbarHypothesis newHyp = BatEvent(hitfitResult[bestX2pos].ev());

		if (Globals::produceFitterASCIIoutput) {
			//outFile << "goodCombi: " << hitfitResult[bestX2pos].mt() << "  ";
			outFile << "goodCombi: ";

			for (unsigned int i = 0; i != jetsForFitting.size(); ++i) {
				if (hitfitResult[bestX2pos].jet_types()[i] == 13)
					outFile << i;
			}
			outFile << "  ";
			for (unsigned int i = 0; i != jetsForFitting.size(); ++i) {
				if (hitfitResult[bestX2pos].jet_types()[i] == 14)
					outFile << i;
			}
			outFile << "  ";
			for (unsigned int i = 0; i != jetsForFitting.size(); ++i) {
				if (hitfitResult[bestX2pos].jet_types()[i] == 12)
					outFile << i;
			}
			outFile << "  index: " << bestX2pos << endl;

			//copy temp file to outfile
			ifstream tempCopy(tempFileName.c_str());
			if (tempCopy.is_open()) {
				char c;
				while (tempCopy.get(c).good())
					outFile << c;
				tempCopy.close();
			}

			outFile << "FinishedEvent" << endl;
			outFile << "------------------------------------------" << endl;
		}
		tempFile.close();

	} else {
		if (Globals::produceFitterASCIIoutput)
			outFile << "No solutions found by HitFit for this event" << std::endl;
	}

}

HitFitAnalyser::HitFitAnalyser(boost::shared_ptr<HistogramManager> histMan, std::string histogramFolder) :
		BasicAnalyser(histMan, histogramFolder), //
		outFileName("FitResults.txt"), //
		outFile(outFileName.c_str()), //
		// The following five initializers read the config parameters for the
		// ASCII text files which contains the physics object resolutions.
		FitterPath_(Globals::TQAFPath), //
		hitfitDefault_(FitterPath_ + "TopQuarkAnalysis/TopHitFit/data/setting/RunHitFitConfiguration.txt"), //
		hitfitElectronResolution_(
				FitterPath_ + "TopQuarkAnalysis/TopHitFit/data/resolution/tqafElectronResolution.txt"), //
		hitfitMuonResolution_(FitterPath_ + "TopQuarkAnalysis/TopHitFit/data/resolution/tqafMuonResolution.txt"), //
		hitfitUdscJetResolution_(FitterPath_ + "TopQuarkAnalysis/TopHitFit/data/resolution/tqafUdscJetResolution.txt"), //
		hitfitBJetResolution_(FitterPath_ + "TopQuarkAnalysis/TopHitFit/data/resolution/tqafBJetResolution.txt"), //
		hitfitMETResolution_(FitterPath_ + "TopQuarkAnalysis/TopHitFit/data/resolution/tqafKtResolution.txt"), //
		// The following three initializers read the config parameters for the
		// values to which the leptonic W, hadronic W, and top quark masses are to
		// be constrained to.
		hitfitLepWMass_(80.4), //
		hitfitHadWMass_(80.4), //
		hitfitTopMass_(0.0), //
		// The following three initializers instantiate the translator between PAT objects
		// and HitFit objects using the ASCII text files which contains the resolutions.
		electronTranslator_(hitfitElectronResolution_), //
		muonTranslator_(hitfitMuonResolution_), //
		jetTranslator_(hitfitUdscJetResolution_, hitfitBJetResolution_), //
		metTranslator_(hitfitMETResolution_), //
		topEplusJetsRefSelection_(new TopPairEPlusJetsReferenceSelection())

{

}

BAT::TtbarHypothesis HitFitAnalyser::BatEvent(const hitfit::Lepjets_Event& ev) {
	// Do the electron
	//BAT::ElectronPointer newEle(new BAT::Electron(*truthMatchEvent.electronFromW));
	BAT::ElectronPointer newEle(new BAT::Electron());
	if (ev.nleps() > 0) {
		newEle->setFourVector(fourVectorFromHitFit(ev.lep(0).p()));
	} else {
		std::cout << "No electron in HitFit event!" << std::endl;
	}

	// Do the neutrino
	//BAT::ParticlePointer newMet(new BAT::Particle(*truthMatchEvent.neutrinoFromW));
	BAT::ParticlePointer newMet(new BAT::Particle());
	newMet->setFourVector(fourVectorFromHitFit(ev.met()));

	// Do the jets
	BAT::JetPointer newLep(new BAT::Jet());
	BAT::JetPointer newHad(new BAT::Jet());
	BAT::JetPointer newWj1(new BAT::Jet());
	BAT::JetPointer newWj2(new BAT::Jet());

	// We need to match up the jets in the HitFit event against the input ones
	// Assume that HitFit has preserved the jet order
	std::vector<hitfit::Lepjets_Event_Jet>::size_type i = 0;
	for (BAT::JetCollection::const_iterator j = jetsForFitting.begin(); j != jetsForFitting.end(); ++i, ++j) {
		FourVector hfJet = fourVectorFromHitFit(ev.jet(i).p());
		int hfJType = ev.jet(i).type();
//    if ((*j)->getFourVector().DeltaR(hfJet) < 0.005) {
		if (hfJType != hitfit::unknown_label) {
			BAT::Jet newJet(**j);
			newJet.setFourVector(hfJet);

			if (hfJType == hitfit::lepb_label)
				*newLep = newJet;
			if (hfJType == hitfit::hadb_label)
				*newHad = newJet;
			if (hfJType == hitfit::hadw1_label)
				*newWj1 = newJet;
			if (hfJType == hitfit::hadw2_label)
				*newWj2 = newJet;
		}
	}

	BAT::TtbarHypothesis hyp(newEle, newMet, newLep, newHad, newWj1, newWj2);

	// do MC matching study
	if (do_MC_matching) {
		//Particle Pointers for best fitted hypothesis
		BAT::ParticlePointer hadronicTop, leptonicTop, leptonicW, hadronicW;
		leptonicW = ParticlePointer(new Particle(*newMet + *newEle));
		if (newWj1 != newWj2)
			hadronicW = ParticlePointer(new Particle(*newWj1 + *newWj2));
		else
			hadronicW = newWj1;
		leptonicTop = ParticlePointer(new Particle(*newLep + *leptonicW));
		hadronicTop = ParticlePointer(new Particle(*newHad + *hadronicW));

		double deltaRelectron, deltaRhadronicBjet, deltaRleptonicBjet, deltaRWjet1, deltaRWjet2, sumDeltaR;
		deltaRelectron = truthMatchEvent.leptonFromW->deltaR(hyp.leptonFromW);
		deltaRhadronicBjet = truthMatchEvent.hadronicBJet->deltaR(hyp.hadronicBJet);
		deltaRleptonicBjet = truthMatchEvent.leptonicBjet->deltaR(hyp.leptonicBjet);

		histMan_->H1D("deltaPtElectron")->Fill(
				(truthMatchEvent.leptonFromW->pt() - hyp.leptonFromW->pt()) / truthMatchEvent.leptonFromW->pt());
		histMan_->H1D("deltaRelectron")->Fill(truthMatchEvent.leptonFromW->deltaR(hyp.leptonFromW));
		histMan_->H1D("deltaPtHadronicBjet")->Fill(
				(truthMatchEvent.hadronicBJet->pt() - hyp.hadronicBJet->pt()) / truthMatchEvent.hadronicBJet->pt());
		histMan_->H1D("deltaRhadronicBjet")->Fill(truthMatchEvent.hadronicBJet->deltaR(hyp.hadronicBJet));
		histMan_->H1D("deltaPtLeptonicBjet")->Fill(
				(truthMatchEvent.leptonicBjet->pt() - hyp.leptonicBjet->pt()) / truthMatchEvent.leptonicBjet->pt());
		histMan_->H1D("deltaRleptonicBjet")->Fill(truthMatchEvent.leptonicBjet->deltaR(hyp.leptonicBjet));
		if (truthMatchEvent.jet1FromW->deltaR(hyp.jet1FromW) < truthMatchEvent.jet1FromW->deltaR(hyp.jet2FromW)) {
			deltaRWjet1 = truthMatchEvent.jet1FromW->deltaR(hyp.jet1FromW);
			deltaRWjet2 = truthMatchEvent.jet2FromW->deltaR(hyp.jet2FromW);
			histMan_->H1D("deltaPtWjet1")->Fill(
					(truthMatchEvent.jet1FromW->pt() - hyp.jet1FromW->pt()) / truthMatchEvent.jet1FromW->pt());
			histMan_->H1D("deltaRWjet1")->Fill(truthMatchEvent.jet1FromW->deltaR(hyp.jet1FromW));
			histMan_->H1D("deltaPtWjet2")->Fill(
					(truthMatchEvent.jet2FromW->pt() - hyp.jet2FromW->pt()) / truthMatchEvent.jet2FromW->pt());
			histMan_->H1D("deltaRWjet2")->Fill(truthMatchEvent.jet2FromW->deltaR(hyp.jet2FromW));
		} else {
			deltaRWjet1 = truthMatchEvent.jet1FromW->deltaR(hyp.jet2FromW);
			deltaRWjet2 = truthMatchEvent.jet2FromW->deltaR(hyp.jet1FromW);
			histMan_->H1D("deltaPtWjet1")->Fill(
					(truthMatchEvent.jet1FromW->pt() - hyp.jet2FromW->pt()) / truthMatchEvent.jet1FromW->pt());
			histMan_->H1D("deltaRWjet1")->Fill(truthMatchEvent.jet1FromW->deltaR(hyp.jet2FromW));
			histMan_->H1D("deltaPtWjet2")->Fill(
					(truthMatchEvent.jet2FromW->pt() - hyp.jet1FromW->pt()) / truthMatchEvent.jet2FromW->pt());
			histMan_->H1D("deltaRWjet2")->Fill(truthMatchEvent.jet2FromW->deltaR(hyp.jet1FromW));
		}

		sumDeltaR = deltaRelectron + deltaRhadronicBjet + deltaRleptonicBjet + deltaRWjet1 + deltaRWjet2;
		histMan_->H1D("SumDeltaR")->Fill(sumDeltaR);

		histMan_->H1D("deltaLeptonicTopMass")->Fill(
				(truthMatchEvent.leptonicTop->mass() - leptonicTop->mass()) / truthMatchEvent.leptonicTop->mass());
		histMan_->H1D("deltaHadronicTopMass")->Fill(
				(truthMatchEvent.hadronicTop->mass() - hadronicTop->mass()) / truthMatchEvent.hadronicTop->mass());

		if (sumDeltaR < 0.4) {
			if (truthMatchEvent.jet1FromW->deltaR(hyp.jet1FromW) < truthMatchEvent.jet1FromW->deltaR(hyp.jet2FromW)) {
				histMan_->H1D("deltaPtWjet1Best")->Fill(
						(truthMatchEvent.jet1FromW->pt() - hyp.jet1FromW->pt()) / truthMatchEvent.jet1FromW->pt());
				histMan_->H1D("deltaPtWjet2Best")->Fill(
						(truthMatchEvent.jet2FromW->pt() - hyp.jet2FromW->pt()) / truthMatchEvent.jet2FromW->pt());
			} else {
				histMan_->H1D("deltaPtWjet1")->Fill(
						(truthMatchEvent.jet1FromW->pt() - hyp.jet2FromW->pt()) / truthMatchEvent.jet1FromW->pt());
				histMan_->H1D("deltaPtWjet2")->Fill(
						(truthMatchEvent.jet2FromW->pt() - hyp.jet1FromW->pt()) / truthMatchEvent.jet2FromW->pt());
			}
			histMan_->H1D("deltaPtElectronBest")->Fill(
					(truthMatchEvent.leptonFromW->pt() - hyp.leptonFromW->pt()) / truthMatchEvent.leptonFromW->pt());
			histMan_->H1D("deltaPtHadronicBjetBest")->Fill(
					(truthMatchEvent.hadronicBJet->pt() - hyp.hadronicBJet->pt()) / truthMatchEvent.hadronicBJet->pt());
			histMan_->H1D("deltaPtLeptonicBjetBest")->Fill(
					(truthMatchEvent.leptonicBjet->pt() - hyp.leptonicBjet->pt()) / truthMatchEvent.leptonicBjet->pt());
			histMan_->H1D("deltaLeptonicTopMassBest")->Fill(
					(truthMatchEvent.leptonicTop->mass() - leptonicTop->mass()) / truthMatchEvent.leptonicTop->mass());
			histMan_->H1D("deltaHadronicTopMassBest")->Fill(
					(truthMatchEvent.hadronicTop->mass() - hadronicTop->mass()) / truthMatchEvent.hadronicTop->mass());
		}
	}

	if (Globals::produceFitterASCIIoutput) {
		outFile << newEle->phi() << "  " << newEle->eta() << "  " << newEle->pt() << "  " << lepton_charge << "  "
				<< newMet->px() << "  " << newMet->py() << endl;
		outFile << jetsForFitting[0]->pt() << "  " << jetsForFitting[0]->eta() << "  " << jetsForFitting[0]->phi()
				<< "  " << jetsForFitting[0]->btagSSVHE() << "  ";
		outFile << jetsForFitting[1]->pt() << "  " << jetsForFitting[1]->eta() << "  " << jetsForFitting[1]->phi()
				<< "  " << jetsForFitting[1]->btagSSVHE() << "  ";
		outFile << jetsForFitting[2]->pt() << "  " << jetsForFitting[2]->eta() << "  " << jetsForFitting[2]->phi()
				<< "  " << jetsForFitting[2]->btagSSVHE() << "  ";
		outFile << jetsForFitting[3]->pt() << "  " << jetsForFitting[3]->eta() << "  " << jetsForFitting[3]->phi()
				<< "  " << jetsForFitting[3]->btagSSVHE() << endl;
	}
	return hyp;
}

FourVector HitFitAnalyser::fourVectorFromHitFit(const hitfit::Fourvec& v) {
	FourVector result(v.x(), v.y(), v.z(), v.t());
	return result;
}

void HitFitAnalyser::setMCTTbarHypothesis(const TtbarHypothesis& mcEvent) {
	truthMatchEvent = mcEvent;
}

void HitFitAnalyser::printFile(const string filename) {
	ifstream fin; // Initialise filestream object.
	char c;

	fin.open(filename.c_str(), ios::in); // Open an input filestream.

	// Check if file opened.
	// fin.fail() returns 1 if there is a fail in the filestream.
	if (fin.fail()) {
		cout << "Error: Unable to open " << filename << ".\n";
		exit(1);
	}

	fin.get(c); // Get first character for kicks.

	// While the stream hasn't failed or reached the end of file, read and display.
	while (!fin.fail() && !fin.eof()) {
		cout << c; // Display character.
		fin.get(c); // Get the next character from the stream.
	}

	fin.close(); // Always close the stream once done.
}

HitFitAnalyser::~HitFitAnalyser() {
	outFile.close();
}

void HitFitAnalyser::createHistograms() {
	histMan_->setCurrentHistogramFolder("hitfitStudy");
	histMan_->addH1D("AllJetsPt", "All jets Pt", 100, 0., 600.);
	histMan_->addH1D("FittedTopMassAllSolutions", "Fitted top mass all solutions", 100, 0., 400.);
	histMan_->addH1D("FitChiSquaredAllSolutions", "Fit chi-squared all solutions", 100, 0., 20.);
	histMan_->addH1D("FitLogChiSqdAllSolutions", "Fit log(chi-sqd) all solutions", 100, -5., 5.);
	histMan_->addH1D("FittedTopMassBestSolution", "Fitted top mass best solution", 100, 0., 400.);
	histMan_->addH1D("FitChiSquaredBestSolution", "Fit chi-squared best solution", 100, 0., 20.);
	histMan_->addH1D("FitLogChiSqdBestSolution", "Fit log(chi-sqd) best solutions", 100, -5., 5.);

	histMan_->addH1D("PullDistAllVarsAllSolutions", "Pulls well measured all solutions", 100, -10., 10.);
	histMan_->addH1D("PullSumSquaredAllSolutions", "Sum-squared pulls all solutions", 100, 0, 500.);
	histMan_->addH2D("PullDistPerVarAllSolutions", "Pulls well measured vs varno all", 100, -10., 10., 25, 0., 25.);
	histMan_->addH1D("PullDistYVarsAllSolutions", "Pulls poorly measured all", 100, -10., 10.);
	histMan_->addH1D("PullDistAllVarsBestSolution", "Pulls well measured best solution", 100, -10., 10.);
	histMan_->addH1D("PullSumSquaredBestSolution", "Sum-squared pulls best solution", 100, 0, 500.);
	histMan_->addH2D("PullDistPerVarBestSolution", "Pulls well measured vs varno best", 100, -10., 10., 25, 0., 25.);
	histMan_->addH1D("PullDistYVarsBestSolution", "Pulls poorly measured best", 100, -10., 10.);

	// MC matching study histograms
	histMan_->addH1D("deltaPtElectron", "Pt difference between truth and fitted electrons", 100, -1.5, 1.5);
	histMan_->addH1D("deltaRelectron", "DeltaR between truth and fitted electrons", 100, 0., 2.);
	histMan_->addH1D("deltaPtHadronicBjet", "Pt difference between truth and fitted b-jets from hadronic top", 100,
			-1.5, 1.5);
	histMan_->addH1D("deltaRhadronicBjet", "DeltaR between truth and fitted b-jets from hadronic top", 100, 0., 5.);
	histMan_->addH1D("deltaPtLeptonicBjet", "Pt difference between truth and fitted b-jets from leptonic top", 100,
			-1.5, 1.5);
	histMan_->addH1D("deltaRleptonicBjet", "DeltaR between truth and fitted b-jets from leptonic top", 100, 0., 5.);
	histMan_->addH1D("deltaPtWjet1", "Pt difference between truth and fitted W jets 1", 100, -1.5, 1.5);
	histMan_->addH1D("deltaRWjet1", "DeltaR between truth and fitted W jets 1", 100, 0., 5.);
	histMan_->addH1D("deltaPtWjet2", "Pt difference between truth and fitted W jets 2", 100, -1.5, 1.5);
	histMan_->addH1D("deltaRWjet2", "DeltaR between truth and fitted W jets 2", 100, 0., 5.);
	histMan_->addH1D("SumDeltaR", "Summarised deltaR of all e+jets", 100, 0., 25.);
	histMan_->addH1D("deltaPtElectronBest", "Pt difference between truth and fitted electrons for matched solutions",
			100, -1.5, 1.5);
	histMan_->addH1D("deltaPtHadronicBjetBest",
			"Pt difference between truth and fitted b-jets from hadronic top for matched solutions", 100, -1.5, 1.5);
	histMan_->addH1D("deltaPtLeptonicBjetBest",
			"Pt difference between truth and fitted b-jets from leptonic top for matched solutions", 100, -1.5, 1.5);
	histMan_->addH1D("deltaPtWjet1Best", "Pt difference between truth and fitted W jets 1 for matched solutions", 100,
			-1.5, 1.5);
	histMan_->addH1D("deltaPtWjet2Best", "Pt difference between truth and fitted W jets 2 for matched solutions", 100,
			-1.5, 1.5);
	histMan_->addH1D("deltaMET", "Delta MET between truth and fitted solutions", 100, -50., 50.);
	histMan_->addH1D("deltaMETbest", "Delta MET between truth and fitted matched solutions", 100, -50., 50.);
	histMan_->addH1D("deltaLeptonicTopMass", "Difference between truth and fitted leptonic top masses", 100, -1.5, 1.5);
	histMan_->addH1D("deltaHadronicTopMass", "Difference between truth and fitted hadronic top masses", 100, -1.5, 1.5);
	histMan_->addH1D("deltaLeptonicTopMassBest",
			"Difference between truth and fitted leptonic top masses for matched solutions", 100, -1.5, 1.5);
	histMan_->addH1D("deltaHadronicTopMassBest",
			"Difference between truth and fitted hadronic top masses for matched solutions", 100, -1.5, 1.5);

}

max_stars_repo_name: jjacob/AnalysisSoftware

max_issues_repo_name: jjacob/AnalysisSoftware

max_forks_repo_name: jjacob/AnalysisSoftware


text:
#include "NlMeans.hpp"

#include "thread/ThreadUtils.hpp"
#include "thread/ThreadPool.hpp"

#include "Logging.hpp"

#include <Eigen/Dense>
#include <iostream>
#include <vector>

namespace Tungsten {

Pixmap3f collaborativeRegression(const Pixmap3f &image, const Pixmap3f &guide,
        const std::vector<PixmapF> &features, const Pixmap3f &imageVariance,
        int F, int R, float k)
{
    int w = image.w();
    int h = image.h();
    int d = features.size() + 3;

    // We parallellize by dicing up the image into 32x32 tiles
    const int TileSize = 32;
    int padSize = TileSize + 2*F;

    struct Tile
    {
        Vec2i pos;
        Box2i dstRect;
        Pixmap3f result;
        PixmapF resultWeights;
        Tile(int x, int y) : pos(x, y) {}
    };

    std::vector<Tile> tiles;
    for (int tileY : range(0, h, TileSize))
        for (int tileX : range(0, w, TileSize))
            tiles.emplace_back(tileX, tileY);

    struct PerThreadData { Pixmap3f tmpBufA, tmpBufB; std::vector<PixmapF> weights; };
    std::vector<std::unique_ptr<PerThreadData>> threadData(ThreadUtils::idealThreadCount());

    ThreadUtils::pool->enqueue([&](uint32 i, uint32, uint32 threadId) {
        printProgressBar(i, tiles.size());

        if (!threadData[threadId]) {
            threadData[threadId].reset(new PerThreadData());
            threadData[threadId]->tmpBufA = Pixmap3f(padSize, padSize);
            threadData[threadId]->tmpBufB = Pixmap3f(padSize, padSize);
            for (int i = 0; i < (2*R + 1)*(2*R + 1); ++i)
                threadData[threadId]->weights.emplace_back(TileSize, TileSize);
        }
        auto &data = *threadData[threadId];
        Tile &tile = tiles[i];

        for (auto &w : data.weights)
            w.clear();

        Box2i srcRect(tile.pos, min(tile.pos + TileSize, Vec2i(w, h)));
        tile.dstRect = srcRect;
        tile.dstRect.grow(R);
        tile.dstRect.intersect(Box2i(Vec2i(0), Vec2i(w, h)));
        int dstW = tile.dstRect.diagonal().x(), dstH = tile.dstRect.diagonal().y();

        tile.result = Pixmap3f(dstW, dstH);
        tile.resultWeights = PixmapF(dstW, dstH);

        // Precompute weights for entire tile
        for (int dy = -R, idxW = 0; dy <= R; ++dy)
            for (int dx = -R; dx <= R; ++dx, ++idxW)
                nlMeansWeights(data.weights[idxW], data.tmpBufA, data.tmpBufB, guide, imageVariance,
                        srcRect, F, k, dx, dy, 2.0f);

        for (int y = srcRect.min().y(); y < srcRect.max().y(); ++y) {
            for (int x = srcRect.min().x(); x < srcRect.max().x(); ++x) {
                int x0 = max(x - R, 0), x1 = min(w, x + R + 1);
                int y0 = max(y - R, 0), y1 = min(h, y + R + 1);
                int n = (x1 - x0)*(y1 - y0);

                // Build weight matrix (W), feature matrix (X) and RHS (Y)
                Eigen::VectorXf W(n);
                Eigen::MatrixXf Y(n, 3);
                Eigen::MatrixXf X(n, d);

                for (int iy = y0; iy < y1; ++iy) {
                    for (int ix = x0; ix < x1; ++ix) {
                        int idxP = ix + iy*w;
                        int idx = (ix - x0) + (iy - y0)*(x1 - x0);

                        for (int i = 0; i < 3; ++i)
                            Y(idx, i) = image[idxP][i];

                        X(idx, 0) = 1.0f;
                        X(idx, 1) = ix - x;
                        X(idx, 2) = iy - y;
                        for (size_t i = 0; i < features.size(); ++i)
                            X(idx, i + 3) = features[i][idxP] - features[i][x + y*w];

                        int idxW = (ix - x + R) + (iy - y + R)*(2*R + 1);
                        W[idx] = data.weights[idxW][Vec2i(x, y) - tile.pos];
                    }
                }

                // Solve least squares system
                Eigen::VectorXf wSqrt = W.cwiseSqrt();
                Eigen::MatrixXf denoised = X*(wSqrt.asDiagonal()*X).colPivHouseholderQr().solve(wSqrt.asDiagonal()*Y);

                // Accumulate denoised patch into image
                for (int iy = y0; iy < y1; ++iy) {
                    for (int ix = x0; ix < x1; ++ix) {
                        Vec2i p = Vec2i(ix, iy) - tile.dstRect.min();
                        int idx = (ix - x0) + (iy - y0)*(x1 - x0);
                        tile.result       [p] += W[idx]*Vec3f(denoised(idx, 0), denoised(idx, 1), denoised(idx, 2));
                        tile.resultWeights[p] += W[idx];
                    }
                }
            }
        }

    }, tiles.size())->wait();

    // Gather results from all threads and divide by weights
    Pixmap3f result(w, h);
    PixmapF resultWeights(w, h);
    for (const auto &tile : tiles) {
        for (int y  : tile.dstRect.range(1)) {
            for (int x  : tile.dstRect.range(0)) {
                Vec2i p(x, y);
                result       [p] += tile.result       [p - tile.dstRect.min()];
                resultWeights[p] += tile.resultWeights[p - tile.dstRect.min()];
            }
        }
    }
    for (int j = 0; j < w*h; ++j)
        result[j] /= resultWeights[j];

    printProgressBar(tiles.size(), tiles.size());

    return std::move(result);
}

}

ext: cpp

max_stars_repo_name: chaosink/tungsten

max_issues_repo_name: chaosink/tungsten

max_forks_repo_name: chaosink/tungsten


text:
/*
 * Copyright (c) 2011, Peter Thorson. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the WebSocket++ Project 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 PETER THORSON 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.
 *
 */

#ifndef CHAT_HPP
#define CHAT_HPP

// com.zaphoyd.websocketpp.chat protocol
//
// client messages:
// alias [UTF8 text, 16 characters max]
// msg [UTF8 text]
//
// server messages:
// {"type":"msg","sender":"<sender>","value":"<msg>" }
// {"type":"participants","value":[<participant>,...]}

#include <boost/shared_ptr.hpp>
#include "../../src/websocketpp.hpp"
#include "../../src/websocket_connection_handler.hpp"

#include <map>
#include <string>
#include <vector>

namespace websocketchat {

class chat_server_handler : public websocketpp::connection_handler {
public:
	chat_server_handler() {}
	virtual ~chat_server_handler() {}

	void validate(websocketpp::session_ptr client);

	// add new connection to the lobby
	void on_open(websocketpp::session_ptr client);

	// someone disconnected from the lobby, remove them
	void on_close(websocketpp::session_ptr client);

	void on_message(websocketpp::session_ptr client,const std::string &msg);

	// lobby will ignore binary messages
	void on_message(websocketpp::session_ptr client,
		const std::vector<unsigned char> &data) {}
private:
	std::string serialize_state();
	std::string encode_message(std::string sender,std::string msg,bool escape = true);
	std::string get_con_id(websocketpp::session_ptr s);

	void send_to_all(std::string data);

	// list of outstanding connections
	std::map<websocketpp::session_ptr,std::string> m_connections;
};

typedef boost::shared_ptr<chat_server_handler> chat_server_handler_ptr;

}
#endif // CHAT_HPP

ext: hpp

max_stars_repo_name: urbenlegend/WebStreamer

max_issues_repo_name: cqzhanghy/WebStreamer

max_forks_repo_name: cqzhanghy/WebStreamer


text:
//  fstream_test.cpp  --------------------------------------------------------//

//  (C) Copyright Beman Dawes 2002. Permission to copy, use, modify, sell and
//  distribute this software is granted provided this copyright notice appears
//  in all copies. This software is provided "as is" without express or implied
//  warranty, and with no claim as to its suitability for any purpose.

//  See http://www.boost.org for most recent version including documentation.

#include <boost/filesystem/fstream.hpp>
#include <string>
#include <cstdio> // for std::remove

namespace fs = boost::filesystem;

#include <boost/config.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
  namespace std { using ::remove; }
#endif

#include <boost/test/minimal.hpp>

int test_main( int, char*[] )
{
  { // basic_filebuf runtime results are ignored; as long as they don't crash
    // or throw we are satisfied
    fs::basic_filebuf<char> bfb;
    fs::filebuf cfb;

    bfb.open( "fstream_test_bffoo", std::ios_base::in );
    cfb.open( "fstream_test_bffoo", std::ios_base::in );

#   ifndef BOOST_NO_STD_WSTRING
    fs::wfilebuf wfb;
    wfb.open( "fstream_test_bffoo", std::ios_base::in );
#   endif
  }

  std::remove( "fstream_test_bfoo" );
  std::remove( "fstream_test_cfoo" );
# ifndef BOOST_NO_STD_WSTRING
  std::remove( "fstream_test_wfoo" );
# endif
  {
    fs::basic_ofstream<char> bofs( "fstream_test_bfoo" );
    fs::ofstream cofs( "fstream_test_cfoo" );

    BOOST_TEST( bofs.is_open() );
    BOOST_TEST( cofs.is_open() );

    bofs << "fstream_test_bfoo";
    cofs << "fstream_test_cfoo";

    // these will fail, but they still test the interface
    bofs.open( "fstream_test_bfoo" );
    cofs.open( "fstream_test_cfoo" );

#   ifndef BOOST_NO_STD_WSTRING
    fs::wofstream wofs( "fstream_test_wfoo" );
    BOOST_TEST( wofs.is_open() );
    wofs << L"fstream_test_wfoo";
    wofs.open( "fstream_test_wfoo" ); // expected to fail
#   endif
  }

  {
    fs::basic_ifstream<char> bifs( "fstream_test_bfoo" );
    fs::ifstream cifs( "fstream_test_cfoo" );

    BOOST_TEST( bifs.is_open() );
    BOOST_TEST( cifs.is_open() );

    std::string b;
    std::string c;

    bifs >> b;
    cifs >> c;

    BOOST_TEST( b == "fstream_test_bfoo" );
    BOOST_TEST( c == "fstream_test_cfoo" );

    // these will fail, but they still test the interface
    bifs.open( "fstream_test_bfoo" );
    cifs.open( "fstream_test_cfoo" );

#   ifndef BOOST_NO_STD_WSTRING
    fs::wifstream wifs( "fstream_test_wfoo" );
    BOOST_TEST( wifs.is_open() );
    std::wstring w;
    wifs >> w;
    BOOST_TEST( w == L"fstream_test_wfoo" );
    wifs.open( "fstream_test_wfoo" ); // expected to fail
#   endif
  }

  {
    fs::basic_fstream<char> bfs( "fstream_test_bfoo" );
    fs::fstream cfs( "fstream_test_cfoo" );

    BOOST_TEST( bfs.is_open() );
    BOOST_TEST( cfs.is_open() );

    std::string b;
    std::string c;

    bfs >> b;
    cfs >> c;

    BOOST_TEST( b == "fstream_test_bfoo" );
    BOOST_TEST( c == "fstream_test_cfoo" );

    // these will fail, but they still test the interface
    bfs.open( "fstream_test_bfoo" );
    cfs.open( "fstream_test_cfoo" );

#   ifndef BOOST_NO_STD_WSTRING
    fs::wfstream wfs( "fstream_test_wfoo" );
    BOOST_TEST( wfs.is_open() );
    std::wstring w;
    wfs >> w;
    BOOST_TEST( w == L"fstream_test_wfoo" );
    wfs.open( "fstream_test_wfoo" ); // expected to fail
#   endif
  }

//  std::remove( "fstream_test_bfoo" );
//  std::remove( "fstream_test_cfoo" );
//  #   ifndef BOOST_NO_STD_WSTRING
//  std::remove( "fstream_test_wfoo" );
//  #   endif
  return 0;
}


text:
#include <iostream>
#include <math.h>

#include <boost/bind/bind.hpp>
#include "boost/math/special_functions/pow.hpp"
#include <boost/numeric/ublas/lu.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/math/special_functions/factorials.hpp>
#include <boost/tuple/tuple.hpp>

#include "Filtering.hpp"

using namespace boost::math;
using namespace boost::numeric::ublas;

#define POW(a,b) pow(a,b)

class AbstractRadarCoordinates {
public:

	RealMatrix ENU2AER(RealVector E, RealVector N, RealVector U) {
		RealMatrix AER(E.size(), 3);
		AER(0, 0) = fmod(atan2(N(0), E(0)), (2.0*constants::pi<double>()));  // azimuth
		AER(0, 1) = atan2(U(0), sqrt(pow<2>(E(0)) + pow<2>(N(0))));
		AER(0, 2) = sqrt(pow<2>(E(0)) + pow<2>(N(0)) + pow<2>(U(0)));
		return AER;
	};

	RealMatrix AER2ENU(RealVector A, RealVector E, RealVector R) {
		RealMatrix ENU(A.size(), 3);
		ENU(0, 0) = R(0) * cos(E(0)) * sin(A(0));
		ENU(0, 1) = R(0) * cos(E(0)) * cos(A(0));
		ENU(0, 2) = R(0) * sin(E(0));
		return ENU;
	};

protected:
	virtual double d1AzimuthdENU1(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d2AzimuthdENU2(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d3AzimuthdENU3(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d4AzimuthdENU4(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d5AzimuthdENU5(const RealVector E, const RealVector N, const RealVector U) = 0;

	virtual double d1ElevationdENU1(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d2ElevationdENU2(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d3ElevationdENU3(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d4ElevationdENU4(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d5ElevationdENU5(const RealVector E, const RealVector N, const RealVector U) = 0;

	virtual double d1RangedENU1(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d2RangedENU2(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d3RangedENU3(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d4RangedENU4(const RealVector E, const RealVector N, const RealVector U) = 0;
	virtual double d5RangedENU5(const RealVector E, const RealVector N, const RealVector U) = 0;

	virtual double d1EastdAER1(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d2EastdAER2(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d3EastdAER3(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d4EastdAER4(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d5EastdAER5(const RealVector A, const RealVector E, const RealVector R) = 0;

	virtual double d1NorthdAER1(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d2NorthdAER2(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d3NorthdAER3(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d4NorthdAER4(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d5NorthdAER5(const RealVector A, const RealVector E, const RealVector R) = 0;

	virtual double d1UpdAER1(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d2UpdAER2(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d3UpdAER3(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d4UpdAER4(const RealVector A, const RealVector E, const RealVector R) = 0;
	virtual double d5UpdAER5(const RealVector A, const RealVector E, const RealVector R) = 0;

};

max_stars_repo_name: lintondf/MorrisonPolynomialFiltering

max_issues_repo_name: lintondf/MorrisonPolynomialFiltering

max_forks_repo_name: lintondf/MorrisonPolynomialFiltering


text:
//
// Copyright (c) 2020 Kasper Laudrup (laudrup at stacktrace dot dk)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_WINTLS_DETAIL_ASYNC_SHUTDOWN_IMPL_HPP
#define BOOST_WINTLS_DETAIL_ASYNC_SHUTDOWN_IMPL_HPP

#include <boost/wintls/detail/sspi_shutdown.hpp>

#include <boost/asio/coroutine.hpp>

namespace boost {
namespace wintls {
namespace detail {

template <typename NextLayer>
struct async_shutdown_impl : boost::asio::coroutine {
  async_shutdown_impl(NextLayer& next_layer, detail::sspi_shutdown& shutdown)
    : next_layer_(next_layer)
    , shutdown_(shutdown)
    , entry_count_(0) {
  }

  template <typename Self>
  void operator()(Self& self, boost::system::error_code ec = {}, std::size_t size_written = 0) {
    if (ec) {
      self.complete(ec);
      return;
    }

    ++entry_count_;
    auto is_continuation = [this] {
      return entry_count_ > 1;
    };

    ec = shutdown_();

    BOOST_ASIO_CORO_REENTER(*this) {
      if (!ec) {
        BOOST_ASIO_CORO_YIELD {
          net::async_write(next_layer_, shutdown_.buffer(), std::move(self));
        }
        shutdown_.size_written(size_written);
        self.complete({});
        return;
      } else {
        if (!is_continuation()) {
          BOOST_ASIO_CORO_YIELD {
            auto e = self.get_executor();
            net::post(e, [self = std::move(self), ec, size_written]() mutable { self(ec, size_written); });
          }
        }
        self.complete(ec);
        return;
      }
    }
  }

private:
  NextLayer& next_layer_;
  detail::sspi_shutdown& shutdown_;
  int entry_count_;
};

} // namespace detail
} // namespace wintls
} // namespace boost

#endif // BOOST_WINTLS_DETAIL_ASYNC_SHUTDOWN_IMPL_HPP

max_stars_repo_name: Larsjep/boost-wintls

max_issues_repo_name: Larsjep/boost-wintls

max_forks_repo_name: Larsjep/boost-wintls


text:
#pragma once

#include <beasty-tepee/response.hpp>
#include <beasty-tepee/header.hpp>

#include <beasty-tepee/request_body_handler.hpp>

#include <boost/beast/core/error.hpp>
#include <boost/beast/core/span.hpp>
#include <memory>
#include <functional>
#include <optional>

namespace tepee::server
{
  class request_body_handler;

  class request_header_handler
  {
 public:
    using opt_request_body_handler_ref = std::optional<std::reference_wrapper<tepee::server::request_body_handler>>;
    virtual opt_request_body_handler_ref parse_header(const tepee::server::header& header_request) = 0;
  };

class test_header_handler : public tepee::server::request_header_handler
{
 public:
  template <typename F>
  test_header_handler(F&& stream_handler) : stream_body_parser_(stream_handler)
  {
  }

  virtual opt_request_body_handler_ref parse_header(const tepee::server::header& header_request) override
  {
    if(header_request.method() == boost::beast::http::verb::get)
    {
      return stream_body_parser_;
    }
    return std::nullopt;
  }

  stream_request_body_handler stream_body_parser_;
};

} // tepee::server

max_stars_repo_name: syoliver/beasty-tepee

max_issues_repo_name: syoliver/beasty-tepee

max_forks_repo_name: syoliver/beasty-tepee


text:
#ifndef PRE_FUSION_FOR_EACH_MEMBER_HPP
#define PRE_FUSION_FOR_EACH_MEMBER_HPP

#include <type_traits>
#include <functional>

#include <boost/fusion/include/adapt_struct.hpp>

#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/intrinsic/front.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/distance.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/include/tag_of.hpp>
#include <boost/mpl/bool.hpp>

namespace pre { namespace fusion {

namespace detail {

  template <typename First, typename Last, typename F, typename Sequence>
  inline void
  for_each_member_linear(First const& first,
      Last const& last,
      F const& f,
      Sequence&,
      boost::mpl::true_) {}

  template <typename First, typename Last, typename F, typename Sequence,
  typename std::enable_if<
    std::is_same<
      typename boost::fusion::traits::tag_of<Sequence>::type,
      boost::fusion::struct_tag
    >::value
  >::type* = nullptr>
  inline void
  for_each_member_linear(First & first,
      Last const& last,
      F const& f,
      Sequence& seq,
      boost::mpl::false_) {

      f(
				boost::fusion::extension::struct_member_name<
					typename std::remove_cv< typename First::seq_type>::type , First::index::value
				>::call(),
				*first
			);

      for_each_member_linear(
          next(first),
          last,
          f,
          seq,
          boost::fusion::result_of::equal_to< typename boost::fusion::result_of::next<First>::type, Last>()
      );
  }

 template <typename First, typename Last, typename F, typename Sequence,
  typename std::enable_if<
    std::is_same<
      typename boost::fusion::traits::tag_of<Sequence>::type,
      boost::fusion::boost_tuple_tag
    >::value
  >::type* = nullptr>
  inline void
  for_each_member_linear(First & first,
      Last const& last,
      F const& f,
      Sequence& seq,
      boost::mpl::false_) {

      auto index = boost::fusion::result_of::distance<
                     typename boost::fusion::result_of::begin<Sequence>::type,
                     First
                   >::type::value;
      std::string name =  typeid(decltype(*first)).name();

      f(
				 (name + std::string("_") + std::to_string(index)).data(),
				*first
			);

      for_each_member_linear(
          next(first),
          last,
          f,
          seq,
          boost::fusion::result_of::equal_to< typename boost::fusion::result_of::next<First>::type, Last>()
      );
  }

  template <typename Sequence, typename F>
  inline void
  for_each_member(Sequence& seq, F const& f) {

    detail::for_each_member_linear(
      boost::fusion::begin(seq),
      boost::fusion::end(seq),
      f,
      seq,
      boost::fusion::result_of::equal_to<
        typename boost::fusion::result_of::begin<Sequence>::type,
        typename boost::fusion::result_of::end<Sequence>::type>()
    );
  }

}

  template <typename Sequence, typename F>
  inline void
  for_each_member(Sequence& seq, F f) {
    detail::for_each_member(seq, f);
  }

}}

#endif

max_stars_repo_name: gorilux/pre-json

max_issues_repo_name: gorilux/pre-json

max_forks_repo_name: gorilux/pre-json


text:
// -*- C++ -*-
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//                                   Jiao Lin
//                      California Institute of Technology
//                         (C) 2007 All Rights Reserved
//
// {LicenseText}
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

#include <sstream>
#include <boost/python.hpp>
#include "mccomponents/kernels/sample/phonon/IncoherentElastic.h"
#include "mccomponents/boostpython_binding/wrap_kernel.h"

namespace wrap_mccomponents {

  void wrap_Phonon_IncoherentElastic_kernel()
  {
    using namespace boost::python;
    using namespace mccomponents::boostpython_binding;

    typedef mccomponents::kernels::phonon::IncoherentElastic w_t;

    kernel_wrapper<w_t>::wrap
      ( "Phonon_IncoherentElastic_kernel",
	init<
	const w_t::atoms_t &, // atoms
	w_t::float_t, // unitcell_vol. AA**3
	w_t::float_t, // dw_core. AA**2
	w_t::float_t, // scattering_xs. barn
	w_t::float_t  // absorption_xs. barn
	> ()
	[with_custodian_and_ward<1,2> () ]
	)
      ;

  }

}

// version
// $Id: wrap_Phonon_IncoherentElastic_kernel.cc 603 2010-10-04 15:58:16Z linjiao $

// End of file

ext: cc

max_stars_repo_name: mcvine/mcvine

max_issues_repo_name: mcvine/mcvine

max_forks_repo_name: mcvine/mcvine


text:
#define BOOST_TEST_MODULE ColdnessAttributeTestSuite
#define BOOST_TEST_DYN_LINK

#include <boost/test/included/unit_test.hpp>
#include <Eigen/Core>
#include <hops/MarkovChain/ParallelTempering/ColdnessAttribute.hpp>

BOOST_AUTO_TEST_SUITE(ColdnessAttribute)

BOOST_AUTO_TEST_CASE( getColdness) {
        double expectedColdness = 0.5;

        class ModelMock {
        public:
            using VectorType = Eigen::VectorXd;
            using MatrixType = Eigen::MatrixXd;
        } modelMock;

        hops::ColdnessAttribute markovChainWithColdnessAttribute(modelMock, expectedColdness);

        double actualColdness = markovChainWithColdnessAttribute.getColdness();
        BOOST_CHECK(actualColdness == expectedColdness);
    }

    BOOST_AUTO_TEST_CASE( setColdness) {
        double expectedColdness = 0.5;

        class ModelMock {
        public:
            using VectorType = Eigen::VectorXd;
            using MatrixType = Eigen::MatrixXd;
        } modelMock;

        hops::ColdnessAttribute markovChainWithColdnessAttribute(modelMock, 1.);

        markovChainWithColdnessAttribute.setColdness(expectedColdness);

        double actualColdness = markovChainWithColdnessAttribute.getColdness();
        BOOST_CHECK(actualColdness == expectedColdness);
    }

    BOOST_AUTO_TEST_CASE( constructorWithColdnessLargerThan1) {
        double expectedColdness = 1;

        class ModelMock {
        public:
            using VectorType = Eigen::VectorXd;
            using MatrixType = Eigen::MatrixXd;
        } modelMock;

        hops::ColdnessAttribute markovChainWithColdnessAttribute(modelMock, 1.5);

        double actualColdness = markovChainWithColdnessAttribute.getColdness();
        BOOST_CHECK(actualColdness == expectedColdness);
    }

    BOOST_AUTO_TEST_CASE( constructorWithColdnessLessThan0) {
        double expectedColdness = 0;

        class ModelMock {
        public:
            using VectorType = Eigen::VectorXd;
            using MatrixType = Eigen::MatrixXd;
        } modelMock;

        hops::ColdnessAttribute markovChainWithColdnessAttribute(modelMock, -1.5);

        double actualColdness = markovChainWithColdnessAttribute.getColdness();
        BOOST_CHECK(actualColdness == expectedColdness);
    }

    BOOST_AUTO_TEST_CASE( setColdnessToMoreThan1G) {
        double expectedColdness = 1;

        class ModelMock {
        public:
            using VectorType = Eigen::VectorXd;
            using MatrixType = Eigen::MatrixXd;
        } modelMock;

        hops::ColdnessAttribute markovChainWithColdnessAttribute(modelMock, 1.5);

        markovChainWithColdnessAttribute.setColdness(1.5);

        double actualColdness = markovChainWithColdnessAttribute.getColdness();
        BOOST_CHECK(actualColdness == expectedColdness);
    }

    BOOST_AUTO_TEST_CASE( setColdnessToLessThan0) {
        double expectedColdness = 0;

        class ModelMock {
        public:
            using VectorType = Eigen::VectorXd;
            using MatrixType = Eigen::MatrixXd;
        } modelMock;

        hops::ColdnessAttribute markovChainWithColdnessAttribute(modelMock, -1.5);

        markovChainWithColdnessAttribute.setColdness(-1.5);

        double actualColdness = markovChainWithColdnessAttribute.getColdness();
        BOOST_CHECK(actualColdness == expectedColdness);
    }

    BOOST_AUTO_TEST_CASE( computeNegativeLogLikelihood) {
        double expectedNegativeLogLikelihood = -250;

        class ModelMock {
        public:
            using VectorType = Eigen::VectorXd;
            using MatrixType = Eigen::MatrixXd;

            [[maybe_unused]] double computeNegativeLogLikelihood(const VectorType &) {
                return -1000;
            }
        } modelMock;

        hops::ColdnessAttribute markovChainWithColdnessAttribute(modelMock, 0.25);

        hops::ColdnessAttribute<ModelMock>::VectorType mockState = Eigen::VectorXd::Zero(1);
        double actualNegativeLogLikelihood = markovChainWithColdnessAttribute.computeNegativeLogLikelihood(mockState);
        BOOST_CHECK(actualNegativeLogLikelihood == expectedNegativeLogLikelihood);
    }

    BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: modsim/hops

max_issues_repo_name: modsim/hops

max_forks_repo_name: modsim/hops


text:
#include <boost/regex.hpp>
#include <dlfcn.h>
#include <fstream>
#include <stdexcept>

#define LOG_HEADER "PlatformManager"
#include <glog/logging.h>
#include <stdexcept>

#include "blaze/BlockManager.h"
#include "blaze/Platform.h"
#include "blaze/PlatformManager.h"
#include "blaze/QueueManager.h"
#include "blaze/TaskManager.h"

namespace blaze {

PlatformManager::PlatformManager(ManagerConf *conf)
{
  for (int i=0; i<conf->platform_size(); i++) {

    AccPlatform platform_conf = conf->platform(i);

    std::string id   = platform_conf.id();
    std::string path = platform_conf.path();

    // check platform id for special characters
    boost::regex special_char_test("\\w+", boost::regex::perl);
    if (!boost::regex_match(id.begin(), id.end(), special_char_test)) {
      LOG(ERROR) << "Platform id [" << id << "] cannot contain "
        << "special characters beside alphanumeric and '_'";
      continue;
    }

    try {
      // generic Platform configuration
      if (platform_table.find(id) != platform_table.end()) {
        throw std::runtime_error("Duplicated platform found: " + id);
      }

      int cache_limit   = platform_conf.cache_limit();
      int scratch_limit = platform_conf.scratch_limit();

      std::string cache_loc = platform_conf.has_cache_loc() ?
                                platform_conf.cache_loc() : id;

      // extended Platform configurations
      std::map<std::string, std::string> conf_table;
      for (int i=0; i<platform_conf.param_size(); i++) {
        std::string conf_key   = platform_conf.param(i).key();
        std::string conf_value = platform_conf.param(i).value();
        conf_table[conf_key]   = conf_value;
      }

      // create Platform
      Platform_ptr platform = this->create(path, conf_table);

      platform_table.insert(std::make_pair(id, platform));

      // create block manager
      if (cache_table.find(cache_loc) == cache_table.end())
      {
        if (cache_loc.compare(id) != 0) {
          LOG(WARNING) << "Unspecificed cache location, use private instead";
          cache_loc = id;
        }
        // if the cache is not shared with another platform
        // create a block manager in current platform
        platform->createBlockManager(
            (size_t)cache_limit << 20,
            (size_t)scratch_limit << 20);

        DLOG(INFO) << "Create a block manager for " << cache_loc;
      }
      else {
        platform->block_manager = platform_table[cache_loc]->block_manager;
        DLOG(INFO) << "Use block manager on " << cache_loc;
      }

      cache_table.insert(std::make_pair(id, cache_loc));
      DLOG(INFO) << "Config platform " << id <<
        " to use device memory on " << cache_loc;

      // print extend configs
      if (!conf_table.empty()) {
        VLOG(1) << "Extra Configurations for the platform:";
        std::map<std::string, std::string>::iterator iter;
        for (iter  = conf_table.begin();
            iter != conf_table.end();
            iter ++)
        {
          VLOG(1) << "[""" << iter->first << """] = "
            << iter->second;
        }
      }

      // add accelerators to the platform
      for (int j=0; j<platform_conf.acc_size(); j++) {

        AccWorker acc_conf = platform_conf.acc(j);
        try {
          registerAcc(id, acc_conf);
        }
        catch (std::exception &e) {
          LOG(ERROR) << "Cannot create ACC " <<
              acc_conf.id() <<
              ": " << e.what();
        }
      }
    }
    catch (std::runtime_error &e) {
      LOG(ERROR) << "Cannot create platform " << id <<
        ": " << e.what();
    }
  }
}

bool PlatformManager::accExists(std::string acc_id) {
  boost::lock_guard<PlatformManager> guard(*this);
  return acc_table.find(acc_id) != acc_table.end();
}

bool PlatformManager::platformExists(std::string platform_id) {
  // boost::lock_guard<PlatformManager> guard(*this);
  return platform_table.find(platform_id) != platform_table.end();
}

Platform* PlatformManager::getPlatformByAccId(std::string acc_id) {

  boost::lock_guard<PlatformManager> guard(*this);
  if (acc_table.find(acc_id) == acc_table.end()) {
    return NULL;
  } else {
    return platform_table[acc_table[acc_id]].get();
  }
}

Platform* PlatformManager::getPlatformById(std::string platform_id) {

  boost::lock_guard<PlatformManager> guard(*this);
  if (platform_table.find(platform_id) == platform_table.end()) {
    return NULL;
  } else {
    return platform_table[platform_id].get();
  }
}

TaskManager_ref PlatformManager::getTaskManager(std::string acc_id) {
  // lock all tables to guarantee exclusive access
  boost::lock_guard<PlatformManager> guard(*this);
  if (acc_table.find(acc_id) == acc_table.end()) {
    TaskManager_ref ret;
    return ret;
  } else {
    return platform_table[acc_table[acc_id]]->getTaskManager(acc_id);
  }
}

void PlatformManager::registerAcc(
    std::string platform_id,
    AccWorker &acc_conf)
{
  // lock all tables to guarantee exclusive access
  boost::lock_guard<PlatformManager> guard(*this);

  DLOG(INFO) << "Adding acc: " << acc_conf.id();

  // check if acc of the same already exists
  if (acc_table.find(acc_conf.id()) != acc_table.end()) {
    throw commError(
        "Accelerator already exists");
  }
  Platform_ptr platform = platform_table[platform_id];

  if (!platform) {
    throw commError(
        "Required platform does not exist");
  }

  // setup the task environment with ACC conf
  platform->addQueue(acc_conf);

  // add acc mapping to table
  acc_table.insert(std::make_pair(
        acc_conf.id(), platform_id));

  // add cache mapping to table
  cache_table.insert(std::make_pair(
        acc_conf.id(), platform_id));

  VLOG(1) << "Added an accelerator queue "
          << "[" << acc_conf.id() << "] "
          << "for platform: " << platform_id;
}

void PlatformManager::removeAcc(
    std::string requester,  // TODO: used to verify client ID
    std::string acc_id,
    std::string platform_id)
{
  // lock all tables to guarantee exclusive access
  boost::lock_guard<PlatformManager> guard(*this);

  // check if acc of the same already exists
  if (acc_table.find(acc_id) == acc_table.end()) {
    return;
  }
  Platform_ptr platform = platform_table[platform_id];

  if (!platform) {
    throw std::runtime_error(
        "required platform does not exist");
  }

  // remove mappings of acc_id
  acc_table.erase(acc_id);
  cache_table.erase(acc_id);

  // setup the task environment with ACC conf
  platform->removeQueue(acc_id);

  VLOG(1) << "Removed an accelerator queue "
          << "[" << acc_id << "] "
          << "for platform: " << platform_id;
}

// create a new platform
Platform_ptr PlatformManager::create(
    std::string path,
    std::map<std::string, std::string> &conf_table)
{
  if (path.compare("")==0) {
    Platform_ptr platform(new Platform(conf_table));
    return platform;
  }
  else {
    void* handle = dlopen(path.c_str(), RTLD_LAZY|RTLD_LOCAL);

    if (handle == NULL) {
      throw std::runtime_error(dlerror());
    }

    // reset errors
    dlerror();

    // load the symbols
    Platform* (*create_func)(std::map<std::string, std::string>&);
    void (*destroy_func)(Platform*);

    // read the custom constructor and destructor
    create_func = (Platform* (*)(std::map<std::string, std::string>&))
                    dlsym(handle, "create");
    destroy_func = (void (*)(Platform*))dlsym(handle, "destroy");

    const char* error = dlerror();
    if (error) {
      throw std::runtime_error(error);
    }

    Platform_ptr platform(create_func(conf_table), destroy_func);

    return platform;
  }
}

void PlatformManager::removeShared(int64_t block_id)
{
  try {
    for (std::map<std::string, std::string>::iterator
        iter = cache_table.begin();
        iter != cache_table.end();
        iter ++)
    {
      platform_table[iter->second]->remove(block_id);
    }
  }
  catch (std::runtime_error &e) {
    throw(e);
  }
}

std::vector<std::pair<std::string, std::string> > PlatformManager::getLabels()
{
  std::vector<std::pair<std::string, std::string> > ret;
  std::map<std::string, std::string>::iterator iter;
  for (iter = acc_table.begin();
       iter != acc_table.end();
       iter ++ )
  {
    ret.push_back(std::make_pair(iter->first, iter->second));
  }
  return ret;
}

} // namespace blaze

max_stars_repo_name: UCLA-VAST/Blaze

max_issues_repo_name: UCLA-VAST/Blaze

max_forks_repo_name: UCLA-VAST/Blaze


text:
// Copyright (c) 2019 Cambricon Authors. All Rights Reserved.

#include <Eigen/Core>
#include "lite/backends/mlu/target_wrapper.h"
#include "lite/core/kernel.h"
#include "lite/core/op_lite.h"
#include "lite/core/op_registry.h"
#include "lite/core/type_system.h"

namespace paddle {
namespace lite {
namespace kernels {
namespace mlu {

using TargetW = TargetWrapper<TARGET(kMLU)>;

// Host to MLU memory.
void CopyFromHostSync(void* target, const void* source, size_t size) {
  TargetW::MemcpySync(target, source, size, IoDirection::HtoD);
}

// MLU to Host memory.
void CopyToHostSync(void* target, const void* source, size_t size) {
  TargetW::MemcpySync(target, source, size, IoDirection::DtoH);
}

/*
 * This kernel copies a tensor from host to MLU space.
 */
template <PrecisionType Precision>
class IoCopyHostToMluCompute
    : public KernelLite<TARGET(kMLU), Precision, DATALAYOUT(kNHWC)> {
 public:
  using handler_t = KernelBase::type_infer_handler_t;
  using param_t = operators::IoCopyParam;

  void Run() override {
    auto& param = this->template Param<param_t>();
    CHECK(param.x->target() == TARGET(kHost) ||
          param.x->target() == TARGET(kX86));
    auto mem_size = param.x->memory_size();
    // LOG(INFO) << "copy size " << mem_size;
    auto* data = param.y->mutable_data(TARGET(kMLU), mem_size);
    CopyFromHostSync(data, param.x->raw_data(), mem_size);
  }

  std::unique_ptr<handler_t> GetTypeInferHandler() override {
    std::unique_ptr<handler_t> res(new handler_t);
    *res = [](const std::map<std::string, const Type*>& inputs,
              const std::string& out) -> const Type* {
      CHECK(!inputs.empty());
      auto* type = inputs.at("Input");
      CHECK(type->target() == TARGET(kHost));

      auto out_place = type->place();
      out_place.target = TARGET(kMLU);
      auto* out_type = Type::Get(type->id(),
                                 out_place.target,
                                 out_place.precision,
                                 out_place.layout,
                                 out_place.device);
      return out_type;
    };
    return res;
  }

  std::string doc() const override { return "Copy IO from HOST to MLU"; }
};

/*
 * This kernel copies a tensor from MLU to host space.
 */
template <PrecisionType Precision>
class IoCopyMluToHostCompute
    : public KernelLite<TARGET(kMLU), Precision, DATALAYOUT(kNHWC)> {
 public:
  void Run() override {
    auto& param = this->template Param<operators::IoCopyParam>();
    CHECK(param.x->target() == TARGET(kMLU));
    auto mem_size = param.x->memory_size();
    auto* data = param.y->mutable_data(TARGET(kHost), mem_size);
    CopyToHostSync(data, param.x->raw_data(), mem_size);
  }

  std::string doc() const override { return "Copy IO from MLU to HOST"; }
};

}  // namespace mlu
}  // namespace kernels
}  // namespace lite
}  // namespace paddle

REGISTER_LITE_KERNEL(
    io_copy,
    kMLU,
    kFloat,
    kNHWC,
    paddle::lite::kernels::mlu::IoCopyHostToMluCompute<PRECISION(kFloat)>,
    host_to_device_kFloat)
    .BindInput("Input", {LiteType::GetTensorTy(TARGET(kHost))})
    .BindOutput("Out", {LiteType::GetTensorTy(TARGET(kMLU))})
    .Finalize();

REGISTER_LITE_KERNEL(
    io_copy,
    kMLU,
    kFP16,
    kNHWC,
    paddle::lite::kernels::mlu::IoCopyHostToMluCompute<PRECISION(kFP16)>,
    host_to_device_kFP16)
    .BindInput("Input", {LiteType::GetTensorTy(TARGET(kHost))})
    .BindOutput("Out", {LiteType::GetTensorTy(TARGET(kMLU))})
    .Finalize();

REGISTER_LITE_KERNEL(
    io_copy,
    kMLU,
    kFloat,
    kNHWC,
    paddle::lite::kernels::mlu::IoCopyMluToHostCompute<PRECISION(kFloat)>,
    device_to_host_kFloat)
    .BindInput("Input", {LiteType::GetTensorTy(TARGET(kMLU))})
    .BindOutput("Out", {LiteType::GetTensorTy(TARGET(kHost))})
    .Finalize();

REGISTER_LITE_KERNEL(
    io_copy,
    kMLU,
    kFP16,
    kNHWC,
    paddle::lite::kernels::mlu::IoCopyMluToHostCompute<PRECISION(kFP16)>,
    device_to_host_kFP16)
    .BindInput("Input", {LiteType::GetTensorTy(TARGET(kMLU))})
    .BindOutput("Out", {LiteType::GetTensorTy(TARGET(kHost))})
    .Finalize();

max_stars_repo_name: smilejames/Paddle-Lite

max_issues_repo_name: smilejames/Paddle-Lite

max_forks_repo_name: smilejames/Paddle-Lite


text:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2021 The Bitcoin Core developers
// Copyright (c) 2021 The PIVX Core developers
// Copyright (c) 2021 The BlackHat developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php.

#include "blockassembler.h"

#include "amount.h"
#include "blocksignature.h"
#include "chain.h"
#include "chainparams.h"
#include "consensus/consensus.h"
#include "consensus/merkle.h"
#include "consensus/upgrades.h"
#include "consensus/validation.h"
#include "masternode-payments.h"
#include "policy/policy.h"
#include "pow.h"
#include "primitives/transaction.h"
#include "spork.h"
#include "timedata.h"
#include "util/system.h"
#include "util/validation.h"
#include "validationinterface.h"

#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#endif

#include <algorithm>
#include <boost/thread.hpp>

// Unconfirmed transactions in the memory pool often depend on other
// transactions in the memory pool. When we select transactions from the
// pool, we select by highest priority or fee rate, so we might consider
// transactions that depend on transactions that aren't yet in the block.

uint64_t nLastBlockTx = 0;
uint64_t nLastBlockSize = 0;

int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
{
    int64_t nOldTime = pblock->nTime;
    int64_t nNewTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());

    if (nOldTime < nNewTime)
        pblock->nTime = nNewTime;

    // Updating time can change work required on testnet:
    if (consensusParams.fPowAllowMinDifficultyBlocks)
        pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);

    return nNewTime - nOldTime;
}

static CMutableTransaction NewCoinbase(const int nHeight, const CScript* pScriptPubKey = nullptr)
{
    CMutableTransaction txCoinbase;
    txCoinbase.vout.emplace_back();
    txCoinbase.vout[0].SetEmpty();
    if (pScriptPubKey) txCoinbase.vout[0].scriptPubKey = *pScriptPubKey;
    txCoinbase.vin.emplace_back();
    txCoinbase.vin[0].scriptSig = CScript() << nHeight << OP_0;
    return txCoinbase;
}

bool SolveProofOfStake(CBlock* pblock, CBlockIndex* pindexPrev, CWallet* pwallet,
                       std::vector<CStakeableOutput>* availableCoins, bool stopPoSOnNewBlock)
{
    boost::this_thread::interruption_point();

    assert(pindexPrev);
    pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);

    // Sync wallet before create coinstake
    pwallet->BlockUntilSyncedToCurrentChain();

    CMutableTransaction txCoinStake;
    int64_t nTxNewTime = 0;
    if (!pwallet->CreateCoinStake(pindexPrev,
                                  pblock->nBits,
                                  txCoinStake,
                                  nTxNewTime,
                                  availableCoins,
                                  stopPoSOnNewBlock
                                  )) {
        LogPrint(BCLog::STAKING, "%s : stake not found\n", __func__);
        return false;
    }
    // Stake found

    // Create coinbase tx and add masternode/budget payments
    CMutableTransaction txCoinbase = NewCoinbase(pindexPrev->nHeight + 1);
    FillBlockPayee(txCoinbase, txCoinStake, pindexPrev, true);

    // Sign coinstake
    if (!pwallet->SignCoinStake(txCoinStake)) {
        const COutPoint& stakeIn = txCoinStake.vin[0].prevout;
        return error("Unable to sign coinstake with input %s-%d", stakeIn.hash.ToString(), stakeIn.n);
    }

    pblock->vtx.emplace_back(MakeTransactionRef(txCoinbase));
    pblock->vtx.emplace_back(MakeTransactionRef(txCoinStake));
    pblock->nTime = nTxNewTime;
    return true;
}

CMutableTransaction CreateCoinbaseTx(const CScript& scriptPubKeyIn, CBlockIndex* pindexPrev)
{
    assert(pindexPrev);
    const int nHeight = pindexPrev->nHeight + 1;

    // Create coinbase tx
    CMutableTransaction txCoinbase = NewCoinbase(nHeight, &scriptPubKeyIn);

    //Masternode and general budget payments
    CMutableTransaction txDummy;    // POW blocks have no coinstake
    FillBlockPayee(txCoinbase, txDummy, pindexPrev, false);

    // If no payee was detected, then the whole block value goes to the first output.
    if (txCoinbase.vout.size() == 1) {
        txCoinbase.vout[0].nValue = GetBlockValue(nHeight);
    }

    return txCoinbase;
}

bool CreateCoinbaseTx(CBlock* pblock, const CScript& scriptPubKeyIn, CBlockIndex* pindexPrev)
{
    pblock->vtx.emplace_back(MakeTransactionRef(CreateCoinbaseTx(scriptPubKeyIn, pindexPrev)));
    return true;
}

BlockAssembler::BlockAssembler(const CChainParams& _chainparams, const bool _defaultPrintPriority)
        : chainparams(_chainparams), defaultPrintPriority(_defaultPrintPriority)
{
    // Largest block you're willing to create:
    nBlockMaxSize = gArgs.GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
    // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity:
    nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE_CURRENT - 1000), nBlockMaxSize));
}

void BlockAssembler::resetBlock()
{
    inBlock.clear();

    // Reserve space for coinbase tx
    nBlockSize = 1000;
    nBlockSigOps = 100;

    // These counters do not include coinbase tx
    nBlockTx = 0;
    nFees = 0;
}

std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn,
                                               CWallet* pwallet,
                                               bool fProofOfStake,
                                               std::vector<CStakeableOutput>* availableCoins,
                                               bool fNoMempoolTx,
                                               bool fTestValidity,
                                               CBlockIndex* prevBlock,
                                               bool stopPoSOnNewBlock)
{
    resetBlock();

    pblocktemplate.reset(new CBlockTemplate());

    if(!pblocktemplate) return nullptr;
    pblock = &pblocktemplate->block; // pointer for convenience

    pblocktemplate->vTxFees.push_back(-1); // updated at end
    pblocktemplate->vTxSigOps.push_back(-1); // updated at end

    CBlockIndex* pindexPrev = prevBlock ? prevBlock : WITH_LOCK(cs_main, return chainActive.Tip());
    assert(pindexPrev);
    nHeight = pindexPrev->nHeight + 1;

    pblock->nVersion = ComputeBlockVersion(chainparams.GetConsensus(), nHeight);
    // -regtest only: allow overriding block.nVersion with
    // -blockversion=N to test forking scenarios
    if (Params().IsRegTestNet()) {
        pblock->nVersion = gArgs.GetArg("-blockversion", pblock->nVersion);
    }

    // Depending on the tip height, try to find a coinstake who solves the block or create a coinbase tx.
    if (!(fProofOfStake ? SolveProofOfStake(pblock, pindexPrev, pwallet, availableCoins, stopPoSOnNewBlock)
                        : CreateCoinbaseTx(pblock, scriptPubKeyIn, pindexPrev))) {
        return nullptr;
    }

    if (!fNoMempoolTx) {
        // Add transactions from mempool
        LOCK2(cs_main,mempool.cs);
        addPackageTxs();
    }

    if (!fProofOfStake) {
        // Coinbase can get the fees.
        CMutableTransaction txCoinbase(*pblock->vtx[0]);
        txCoinbase.vout[0].nValue += nFees;
        pblock->vtx[0] = MakeTransactionRef(txCoinbase);
        pblocktemplate->vTxFees[0] = -nFees;
    }

    nLastBlockTx = nBlockTx;
    nLastBlockSize = nBlockSize;
    LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOps);

    const Consensus::Params& consensus = Params().GetConsensus();
    // Fill in header
    pblock->hashPrevBlock = pindexPrev->GetBlockHash();
    if (!fProofOfStake) UpdateTime(pblock, consensus, pindexPrev);
    pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
    pblock->nNonce = 0;
    pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(*(pblock->vtx[0]));
    appendSaplingTreeRoot();

    if (fProofOfStake) { // this is only for PoS because the IncrementExtraNonce does it for PoW
        pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
        LogPrintf("CPUMiner : proof-of-stake block found %s \n", pblock->GetHash().GetHex());
        if (!SignBlock(*pblock, *pwallet)) {
            LogPrintf("%s: Signing new block with UTXO key failed \n", __func__);
            return nullptr;
        }
    }

    {
        LOCK(cs_main);
        if (prevBlock == nullptr && chainActive.Tip() != pindexPrev) return nullptr; // new block came in, move on

        CValidationState state;
        if (fTestValidity &&
            !TestBlockValidity(state, *pblock, pindexPrev, false, false, false)) {
            throw std::runtime_error(
                    strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state)));
        }
    }

    return std::move(pblocktemplate);
}

void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet)
{
    for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) {
        // Only test txs not already in the block
        if (inBlock.count(*iit)) {
            testSet.erase(iit++);
        }
        else {
            iit++;
        }
    }
}

bool BlockAssembler::TestPackage(uint64_t packageSize, unsigned int packageSigOps)
{
    if (nBlockSize + packageSize >= nBlockMaxSize)
        return false;
    if (nBlockSigOps + packageSigOps >= MAX_BLOCK_SIGOPS_CURRENT)
        return false;
    return true;
}

// Block size and sigops have already been tested.  Check that all transactions
// are final.
bool BlockAssembler::TestPackageFinality(const CTxMemPool::setEntries& package)
{
    for (const CTxMemPool::txiter& it : package) {
        if (!IsFinalTx(it->GetSharedTx(), nHeight))
            return false;
    }
    return true;
}

void BlockAssembler::AddToBlock(CTxMemPool::txiter iter)
{
    pblock->vtx.emplace_back(iter->GetSharedTx());
    pblocktemplate->vTxFees.push_back(iter->GetFee());
    pblocktemplate->vTxSigOps.push_back(iter->GetSigOpCount());
    nBlockSize += iter->GetTxSize();
    ++nBlockTx;
    nBlockSigOps += iter->GetSigOpCount();
    nFees += iter->GetFee();
    inBlock.insert(iter);

    bool fPrintPriority = gArgs.GetBoolArg("-printpriority", defaultPrintPriority);
    if (fPrintPriority) {
        LogPrintf("feerate %s txid %s\n",
                  CFeeRate(iter->GetModifiedFee(), iter->GetTxSize()).ToString(),
                  iter->GetTx().GetHash().ToString());
    }
}

void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded,
                                            indexed_modified_transaction_set& mapModifiedTx)
{
    for (const CTxMemPool::txiter& it : alreadyAdded) {
        CTxMemPool::setEntries descendants;
        mempool.CalculateDescendants(it, descendants);
        // Insert all descendants (not yet in block) into the modified set
        for (CTxMemPool::txiter desc : descendants) {
            if (alreadyAdded.count(desc))
                continue;
            modtxiter mit = mapModifiedTx.find(desc);
            if (mit == mapModifiedTx.end()) {
                CTxMemPoolModifiedEntry modEntry(desc);
                modEntry.nSizeWithAncestors -= it->GetTxSize();
                modEntry.nModFeesWithAncestors -= it->GetModifiedFee();
                modEntry.nSigOpCountWithAncestors -= it->GetSigOpCount();
                mapModifiedTx.insert(modEntry);
            } else {
                mapModifiedTx.modify(mit, update_for_parent_inclusion(it));
            }
        }
    }
}

// Skip entries in mapTx that are already in a block or are present
// in mapModifiedTx (which implies that the mapTx ancestor state is
// stale due to ancestor inclusion in the block)
// Also skip transactions that we've already failed to add. This can happen if
// we consider a transaction in mapModifiedTx and it fails: we can then
// potentially consider it again while walking mapTx.  It's currently
// guaranteed to fail again, but as a belt-and-suspenders check we put it in
// failedTx and avoid re-evaluation, since the re-evaluation would be using
// cached size/sigops/fee values that are not actually correct.
bool BlockAssembler::SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx)
{
    assert (it != mempool.mapTx.end());
    if (mapModifiedTx.count(it) || inBlock.count(it) || failedTx.count(it))
        return true;
    return false;
}

void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector<CTxMemPool::txiter>& sortedEntries)
{
    // Sort package by ancestor count
    // If a transaction A depends on transaction B, then A's ancestor count
    // must be greater than B's.  So this is sufficient to validly order the
    // transactions for block inclusion.
    sortedEntries.clear();
    sortedEntries.insert(sortedEntries.begin(), package.begin(), package.end());
    std::sort(sortedEntries.begin(), sortedEntries.end(), CompareTxIterByAncestorCount());
}

// This transaction selection algorithm orders the mempool based
// on feerate of a transaction including all unconfirmed ancestors.
// Since we don't remove transactions from the mempool as we select them
// for block inclusion, we need an alternate method of updating the feerate
// of a transaction with its not-yet-selected ancestors as we go.
// This is accomplished by walking the in-mempool descendants of selected
// transactions and storing a temporary modified state in mapModifiedTxs.
// Each time through the loop, we compare the best transaction in
// mapModifiedTxs with the next transaction in the mempool to decide what
// transaction package to work on next.
void BlockAssembler::addPackageTxs()
{
    // mapModifiedTx will store sorted packages after they are modified
    // because some of their txs are already in the block
    indexed_modified_transaction_set mapModifiedTx;
    // Keep track of entries that failed inclusion, to avoid duplicate work
    CTxMemPool::setEntries failedTx;

    // Start by adding all descendants of previously added txs to mapModifiedTx
    // and modifying them for their already included ancestors
    UpdatePackagesForAdded(inBlock, mapModifiedTx);

    CTxMemPool::indexed_transaction_set::index<ancestor_score>::type::iterator mi = mempool.mapTx.get<ancestor_score>().begin();
    CTxMemPool::txiter iter;
    while (mi != mempool.mapTx.get<ancestor_score>().end() || !mapModifiedTx.empty())
    {
        // First try to find a new transaction in mapTx to evaluate.
        if (mi != mempool.mapTx.get<ancestor_score>().end() &&
                SkipMapTxEntry(mempool.mapTx.project<0>(mi), mapModifiedTx, failedTx)) {
            ++mi;
            continue;
        }

        // Now that mi is not stale, determine which transaction to evaluate:
        // the next entry from mapTx, or the best from mapModifiedTx?
        bool fUsingModified = false;

        modtxscoreiter modit = mapModifiedTx.get<ancestor_score>().begin();
        if (mi == mempool.mapTx.get<ancestor_score>().end()) {
            // We're out of entries in mapTx; use the entry from mapModifiedTx
            iter = modit->iter;
            fUsingModified = true;
        } else {
            // Try to compare the mapTx entry to the mapModifiedTx entry
            iter = mempool.mapTx.project<0>(mi);
            if (modit != mapModifiedTx.get<ancestor_score>().end() &&
                    CompareModifiedEntry()(*modit, CTxMemPoolModifiedEntry(iter))) {
                // The best entry in mapModifiedTx has higher score
                // than the one from mapTx.
                // Switch which transaction (package) to consider
                iter = modit->iter;
                fUsingModified = true;
            } else {
                // Either no entry in mapModifiedTx, or it's worse than mapTx.
                // Increment mi for the next loop iteration.
                ++mi;
            }
        }

        // We skip mapTx entries that are inBlock, and mapModifiedTx shouldn't
        // contain anything that is inBlock.
        assert(!inBlock.count(iter));

        uint64_t packageSize = iter->GetSizeWithAncestors();
        CAmount packageFees = iter->GetModFeesWithAncestors();
        unsigned int packageSigOps = iter->GetSigOpCountWithAncestors();
        if (fUsingModified) {
            packageSize = modit->nSizeWithAncestors;
            packageFees = modit->nModFeesWithAncestors;
            packageSigOps = modit->nSigOpCountWithAncestors;
        }

        if (packageFees < ::minRelayTxFee.GetFee(packageSize)) {
            // Everything else we might consider has a lower fee rate
            return;
        }

        if (!TestPackage(packageSize, packageSigOps)) {
            if (fUsingModified) {
                // Since we always look at the best entry in mapModifiedTx,
                // we must erase failed entries so that we can consider the
                // next best entry on the next loop iteration
                mapModifiedTx.get<ancestor_score>().erase(modit);
                failedTx.insert(iter);
            }
            continue;
        }

        CTxMemPool::setEntries ancestors;
        uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
        std::string dummy;
        mempool.CalculateMemPoolAncestors(*iter, ancestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);

        onlyUnconfirmed(ancestors);
        ancestors.insert(iter);

        // Test if all tx's are Final
        if (!TestPackageFinality(ancestors)) {
            if (fUsingModified) {
                mapModifiedTx.get<ancestor_score>().erase(modit);
                failedTx.insert(iter);
            }
            continue;
        }

        // Package can be added. Sort the entries in a valid order.
        std::vector<CTxMemPool::txiter> sortedEntries;
        SortForBlock(ancestors, iter, sortedEntries);

        for (size_t i = 0; i < sortedEntries.size(); ++i) {
            CTxMemPool::txiter& iterSortedEntries = sortedEntries[i];
            if (iterSortedEntries->IsShielded()) {
                // Don't add SHIELD transactions if in maintenance (SPORK_20)
                if (sporkManager.IsSporkActive(SPORK_20_SAPLING_MAINTENANCE)) {
                    break;
                }
                // Don't add SHIELD transactions if there's no reserved space left in the block
                if (nSizeShielded + iterSortedEntries->GetTxSize() > MAX_BLOCK_SHIELDED_TXES_SIZE) {
                    break;
                }
                // Update cumulative size of SHIELD transactions in this block
                nSizeShielded += iterSortedEntries->GetTxSize();
            }
            AddToBlock(iterSortedEntries);
            // Erase from the modified set, if present
            mapModifiedTx.erase(iterSortedEntries);
        }

        // Update transactions that depend on each of these
        UpdatePackagesForAdded(ancestors, mapModifiedTx);
    }
}

void BlockAssembler::appendSaplingTreeRoot()
{
    // Update header
    pblock->hashFinalSaplingRoot = CalculateSaplingTreeRoot(pblock, nHeight, chainparams);
}

uint256 CalculateSaplingTreeRoot(CBlock* pblock, int nHeight, const CChainParams& chainparams)
{
    if (NetworkUpgradeActive(nHeight, chainparams.GetConsensus(), Consensus::UPGRADE_V5_0)) {
        SaplingMerkleTree sapling_tree;
        assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(), sapling_tree));

        // Update the Sapling commitment tree.
        for (const auto &tx : pblock->vtx) {
            if (tx->IsShieldedTx()) {
                for (const OutputDescription &odesc : tx->sapData->vShieldedOutput) {
                    sapling_tree.append(odesc.cmu);
                }
            }
        }
        return sapling_tree.root();
    }
    return UINT256_ZERO;
}

bool SolveBlock(std::shared_ptr<CBlock>& pblock, int nHeight)
{
    unsigned int extraNonce = 0;
    IncrementExtraNonce(pblock, nHeight, extraNonce);
    while (pblock->nNonce < std::numeric_limits<uint32_t>::max() &&
           !CheckProofOfWork(pblock->GetHash(), pblock->nBits)) {
        ++pblock->nNonce;
    }
    return pblock->nNonce != std::numeric_limits<uint32_t>::max();
}

void IncrementExtraNonce(std::shared_ptr<CBlock>& pblock, int nHeight, unsigned int& nExtraNonce)
{
    // Update nExtraNonce
    static uint256 hashPrevBlock;
    if (hashPrevBlock != pblock->hashPrevBlock) {
        nExtraNonce = 0;
        hashPrevBlock = pblock->hashPrevBlock;
    }
    ++nExtraNonce;
    CMutableTransaction txCoinbase(*pblock->vtx[0]);
    txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce)) + COINBASE_FLAGS;
    assert(txCoinbase.vin[0].scriptSig.size() <= 100);

    pblock->vtx[0] = MakeTransactionRef(txCoinbase);
    pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
}

int32_t ComputeBlockVersion(const Consensus::Params& consensus, int nHeight)
{
    if (NetworkUpgradeActive(nHeight, consensus, Consensus::UPGRADE_V5_0)) {
        return CBlockHeader::CURRENT_VERSION;       // v11 (since 5.2.99)
    } else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V4_0)) {
        return 7;
    } else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V3_4)) {
        return 6;
    } else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BIP65)) {
        return 5;
    } else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_ZC)) {
        return 4;
    } else {
        return 3;
    }
}

max_stars_repo_name: BlackHatCoin/BlackHatWallet

max_issues_repo_name: BlackHatCoin/BlackHatWallet

max_forks_repo_name: BlackHatCoin/BlackHatWallet


text:
// Copyright (C) 2020 T. Zachary Laine
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARSER_DETAIL_HL_HPP
#define BOOST_PARSER_DETAIL_HL_HPP

#include <boost/parser/config.hpp>
#include <boost/parser/tuple.hpp>
#include <boost/parser/detail/detection.hpp>

#include <type_traits>
#include <utility>

namespace boost { namespace parser { namespace detail::hl {

    // Boost.Hana lite.  These functions work with boost::hana::tuple and
    // std::tuple.

    struct forward
    {
        template<typename T>
        decltype(auto) operator()(T && t)
        {
            return (T &&) t;
        }
    };

    template<typename... Args>
    constexpr auto make_tuple(Args &&... args)
    {
#if BOOST_PARSER_USE_STD_TUPLE
        return std::make_tuple((Args &&) args...);
#else
        return hana::make_tuple((Args &&) args...);
#endif
    }

    template<typename T, typename U>
    constexpr auto make_pair(T && t, U && u)
    {
        return hl::make_tuple((T &&) t, (U &&) u);
    }

    template<typename Tuple1, typename Tuple2>
    constexpr auto concat(Tuple1 const & t1, Tuple2 const & t2)
    {
#if BOOST_PARSER_USE_STD_TUPLE
        return std::tuple_cat(t1, t2);
#else
        // Hana's concat does not seem to do what it says on the tin.
        // Concatenating (int, string) with (double, int) yields (int, string,
        // double).  I maybe don't understand it well enough.
        return hana::insert_range(t1, hana::size(t1), t2);
#endif
    }

    // for_each

    template<typename F, typename Tuple, std::size_t... I>
    constexpr void for_each_impl(
        Tuple const & t, F && f, std::integer_sequence<std::size_t, I...>)
    {
        int _[] = {0, (f(parser::get(t, llong<I>{})), 0)...};
        (void)_;
    }
    template<
        typename F,
        typename Tuple,
        std::size_t... I,
        typename Enable = std::enable_if_t<!std::is_reference_v<Tuple>>>
    constexpr void
    for_each_impl(Tuple && t, F && f, std::integer_sequence<std::size_t, I...>)
    {
        int _[] = {0, (f(std::move(parser::get(t, llong<I>{}))), 0)...};
        (void)_;
    }

    template<typename F, typename... Args>
    constexpr void for_each(tuple<Args...> && t, F && f)
    {
        hl::for_each_impl(
            std::move(t),
            (F &&) f,
            std::make_integer_sequence<std::size_t, sizeof...(Args)>());
    }
    template<typename F, typename... Args>
    constexpr void for_each(tuple<Args...> const & t, F && f)
    {
        hl::for_each_impl(
            t,
            (F &&) f,
            std::make_integer_sequence<std::size_t, sizeof...(Args)>());
    }

    // transform

    template<int offset, typename F, typename Tuple, std::size_t... I>
    constexpr auto transform_impl(
        Tuple const & t, F && f, std::integer_sequence<std::size_t, I...>)
    {
        return tuple<
            std::decay_t<decltype(f(parser::get(t, llong<I + offset>{})))>...>{
            f(parser::get(t, llong<I + offset>{}))...};
    }
    template<
        int offset,
        typename F,
        typename Tuple,
        std::size_t... I,
        typename Enable = std::enable_if_t<!std::is_reference_v<Tuple>>>
    auto constexpr transform_impl(
        Tuple && t, F && f, std::integer_sequence<std::size_t, I...>)
    {
        return tuple<std::decay_t<decltype(
            f(std::move(parser::get(t, llong<I + offset>{}))))>...>{
            f(std::move(parser::get(t, llong<I + offset>{})))...};
    }

    template<typename F, typename... Args>
    constexpr auto transform(tuple<Args...> && t, F && f)
    {
        return hl::transform_impl<0>(
            std::move(t),
            (F &&) f,
            std::make_integer_sequence<std::size_t, sizeof...(Args)>());
    }
    template<typename F, typename... Args>
    constexpr auto transform(tuple<Args...> const & t, F && f)
    {
        return hl::transform_impl<0>(
            t,
            (F &&) f,
            std::make_integer_sequence<std::size_t, sizeof...(Args)>());
    }

    // fold_left

    template<std::size_t I, std::size_t N>
    struct fold_left_dispatch
    {
        template<typename F, typename State, typename... Args>
        constexpr static auto
        call(tuple<Args...> const & t, State && s, F const & f)
        {
            return fold_left_dispatch<I + 1, N>::call(
                t, f((State &&) s, parser::get(t, llong<I>{})), f);
        }
    };
    template<std::size_t I>
    struct fold_left_dispatch<I, I>
    {
        template<typename F, typename State, typename... Args>
        constexpr static auto
        call(tuple<Args...> const & t, State && s, F const & f)
        {
            return (State &&) s;
        }
    };

    template<typename F, typename State, typename... Args>
    constexpr auto fold_left(tuple<Args...> const & t, State && s, F const & f)
    {
        return hl::fold_left_dispatch<0, sizeof...(Args)>::call(
            t, (State &&) s, (F &&) f);
    }

    // size

    template<typename... Args>
    constexpr auto size(tuple<Args...> const & t)
    {
        return llong<sizeof...(Args)>{};
    }

    template<typename... Args>
    constexpr auto size_minus_one(tuple<Args...> const & t)
    {
        return llong<sizeof...(Args) - 1>{};
    }

    // contains

    template<typename T, typename U>
    using comparable = decltype(std::declval<T>() == std::declval<U>());

    struct typesafe_equals
    {
        template<typename T, typename U>
        constexpr bool operator()(T const & t, U const & u)
        {
            if constexpr (detail::is_detected<comparable, T, U>::value) {
                return t == u;
            } else {
                return false;
            }
        }
    };

    template<typename T, typename Tuple, std::size_t... I>
    constexpr bool contains_impl(
        Tuple const & t, T const & x, std::integer_sequence<std::size_t, I...>)
    {
        typesafe_equals eq;
        (void)eq;
        return (eq(parser::get(t, llong<I>{}), x) || ...);
    }

    template<typename T, typename... Args>
    constexpr bool contains(tuple<Args...> & t, T const & x)
    {
        return contains_impl(
            t, x, std::make_integer_sequence<std::size_t, sizeof...(Args)>());
    }

    // front, back

    template<typename Arg, typename... Args>
    constexpr decltype(auto) front(tuple<Arg, Args...> & t)
    {
        return parser::get(t, llong<0>{});
    }
    template<typename Arg, typename... Args>
    constexpr decltype(auto) front(tuple<Arg, Args...> const & t)
    {
        return parser::get(t, llong<0>{});
    }
    template<typename Arg, typename... Args>
    constexpr decltype(auto) back(tuple<Arg, Args...> & t)
    {
        return parser::get(t, llong<sizeof...(Args)>{});
    }
    template<typename Arg, typename... Args>
    constexpr decltype(auto) back(tuple<Arg, Args...> const & t)
    {
        return parser::get(t, llong<sizeof...(Args)>{});
    }

    // drop_front

    template<typename Arg, typename... Args>
    constexpr auto drop_front(tuple<Arg, Args...> && t)
    {
        return hl::transform_impl<1>(
            std::move(t),
            forward{},
            std::make_integer_sequence<std::size_t, sizeof...(Args)>());
    }
    template<typename Arg, typename... Args>
    constexpr auto drop_front(tuple<Arg, Args...> const & t)
    {
        return hl::transform_impl<1>(
            t,
            forward{},
            std::make_integer_sequence<std::size_t, sizeof...(Args)>());
    }

    // drop_back

    template<typename Arg, typename... Args>
    constexpr auto drop_back(tuple<Arg, Args...> && t)
    {
        return hl::transform_impl<0>(
            std::move(t),
            forward{},
            std::make_integer_sequence<std::size_t, sizeof...(Args)>());
    }
    template<typename Arg, typename... Args>
    constexpr auto drop_back(tuple<Arg, Args...> const & t)
    {
        return hl::transform_impl<0>(
            t,
            forward{},
            std::make_integer_sequence<std::size_t, sizeof...(Args)>());
    }

    // first, second

    template<typename T, typename U>
    constexpr decltype(auto) first(tuple<T, U> & t)
    {
        return parser::get(t, llong<0>{});
    }
    template<typename T, typename U>
    constexpr decltype(auto) first(tuple<T, U> const & t)
    {
        return parser::get(t, llong<0>{});
    }
    template<typename T, typename U>
    constexpr decltype(auto) second(tuple<T, U> & t)
    {
        return parser::get(t, llong<1>{});
    }
    template<typename T, typename U>
    constexpr decltype(auto) second(tuple<T, U> const & t)
    {
        return parser::get(t, llong<1>{});
    }

    // zip

    template<std::size_t I, typename... Tuples>
    constexpr decltype(auto) make_zip_elem(Tuples const &... ts)
    {
        return hl::make_tuple(parser::get(ts, llong<I>{})...);
    }

    template<std::size_t... I, typename... Tuples>
    constexpr auto zip_impl(std::index_sequence<I...>, Tuples const &... ts)
    {
        return hl::make_tuple(hl::make_zip_elem<I>(ts...)...);
    }

    template<typename T>
    struct tuplesize;
    template<typename... Args>
    struct tuplesize<tuple<Args...>>
    {
        constexpr static std::size_t value = sizeof...(Args);
    };

    template<typename Tuple, typename... Tuples>
    constexpr auto zip(Tuple const & t, Tuples const &... ts)
    {
        return hl::zip_impl(
            std::make_integer_sequence<
                std::size_t,
                tuplesize<std::remove_reference_t<Tuple>>::value>(),
            t,
            ts...);
    }

    // append

    template<typename... Args, typename T>
    constexpr auto append(tuple<Args...> && t, T && x)
    {
#if BOOST_PARSER_USE_STD_TUPLE
        return std::tuple_cat(std::move(t), std::make_tuple((T &&) x));
#else
        return hana::append(std::move(t), (T &&) x);
#endif
    }
    template<typename... Args, typename T>
    constexpr auto append(tuple<Args...> const & t, T && x)
    {
#if BOOST_PARSER_USE_STD_TUPLE
        return std::tuple_cat(t, std::make_tuple((T &&) x));
#else
        return hana::append(t, (T &&) x);
#endif
    }

    // prepend

    template<typename... Args, typename T>
    constexpr auto prepend(tuple<Args...> && t, T && x)
    {
#if BOOST_PARSER_USE_STD_TUPLE
        return std::tuple_cat(std::make_tuple((T &&) x), std::move(t));
#else
        return hana::prepend(std::move(t), (T &&) x);
#endif
    }
    template<typename... Args, typename T>
    constexpr auto prepend(tuple<Args...> const & t, T && x)
    {
#if BOOST_PARSER_USE_STD_TUPLE
        return std::tuple_cat(std::make_tuple((T &&) x), t);
#else
        return hana::prepend(t, (T &&) x);
#endif
    }

}}}

#endif

max_stars_repo_name: tzlaine/parser

max_issues_repo_name: tzlaine/parser

max_forks_repo_name: tzlaine/parser