<commit_before>/*
 * GibbsSampler.hpp
 *
 *  Created on: Jul 25, 2013
 *      Author: Brandon C. Kelly
 */

#ifndef GIBBSSAMPLER_HPP_
#define GIBBSSAMPLER_HPP_

// std includes
#include <exception>
#include <sstream>

// boost includes
#include <boost/shared_ptr.hpp>

// local includes
#include "parameters.cuh"

template<int mfeat, int pchi, int dtheta>
class GibbsSampler
{
public:
	// constructor
	GibbsSampler(vecvec& meas, vecvec& meas_unc, int niter, int nburnin, int nthin_chi=100, int nthin_theta=1,
			int nThreads=256) :
				niter_(niter), nburnin_(nburnin), nthin_theta_(nthin_theta), nthin_chi_(nthin_chi)
		{
			int ndata = meas.size();
			// first do CUDA grid launch
			dim3 nT(nThreads);
			nT_ = nT;
			dim3 nB((ndata + nT.x-1) / nT.x);
			nB_ = nB;
			if (nB.x > 65535)
			{
				std::stringstream errmsg;
				errmsg << "ERROR: Block is too large:\n";
				errmsg << nB.x << " blocks. Max is 65535.\n";
				throw std::runtime_error(errmsg.str());
			}

			// construct DataAugmentation and PopulationPar objects
			Daug_.reset(new DataAugmentation<mfeat, pchi, dtheta>(meas, meas_unc, nB_, nT_));
			PopPar_.reset(new PopulationPar<mfeat, pchi, dtheta>(nB_, nT_));
			Daug_->SetPopulationPtr(PopPar_);
			PopPar_->SetDataAugPtr(Daug_);

			// set container sizes
			int nchi_samples = niter / nthin_chi;
			int ntheta_samples = niter / nthin_theta;
			ChiSamples_.resize(nchi_samples);
			ThetaSamples_.resize(ntheta_samples);
			LogDensMeas_Samples_.resize(nchi_samples);
			LogDensPop_Samples_.resize(ntheta_samples);

			ntheta_samples_ = 0;
			nchi_samples_ = 0;
			current_iter_ = 1;
			fix_poppar = false; // default is to sample both the population parameters and characteristics
			fix_char = false;

			// Set the initial values of the characteristics and thetas, as well as their proposal covariances
			Initialize();
		}

	// fix the population parameters throughout the sampler?
	void FixPopPar(bool fix=true) { fix_poppar = fix; }

	// fix the characteristics throughout the sampler?
	void FixChar(bool fix=true) { fix_char = fix; }

	// perform a single iterations of the Gibbs Sampler
	virtual void Iterate() {
		if (!fix_char) Daug_->Update();
		if (!fix_poppar) PopPar_->Update();
		current_iter_++;
	}

	// Initialize the parameter values, their proposal covariances, and the log-densities
	void Initialize() {
		if (!fix_char) Daug_->Initialize();
		if (!fix_poppar) PopPar_->Initialize();
	}

	// run the MCMC sampler
	void Run() {
		// first run for a burn-in period
		std::cout << "Doing " << nburnin_ << " iterations of burnin..." << std::endl;

		for (int i = 0; i < nburnin_; ++i) {
			if (i % 1000 == 0) {
				std::cout << i << "..." << std::endl;
			}
			Iterate();
		}
		// TODO: add timer
		// TODO: add a progress bar

		// Burn-in stage is finished, so reset the current iteration and acceptance rates
		std::cout << "Burnin finished." << std::endl;
		Report();
		std::cout << std::endl;

		current_iter_ = 1;
		Daug_->ResetAcceptance();
		PopPar_->ResetAcceptance();

		// run the main MCMC sampler
		std::cout << "Now doing " << niter_ << " iterations of the Gibbs Sampler..." << std::endl;

		for (int i = 0; i < niter_; ++i) {
			if (i % 1000 == 0) {
				std::cout << i << "..." << std::endl;
			}
			Iterate();
			// TODO: How long does saving the values take? Maybe replace these with iterators?
			if (!fix_poppar && (current_iter_ % nthin_theta_ == 0)) {
				// save the value of the population parameter since we've done nthin_theta_ iterations since the last save
				ThetaSamples_[ntheta_samples_] = PopPar_->GetTheta();
				LogDensPop_Samples_[ntheta_samples_] = PopPar_->GetLogDens();
				ntheta_samples_++;
			}
			if (!fix_char && (current_iter_ % nthin_chi_ == 0) && Daug_->SaveTrace()) {
				// save the value of the characteristics
				ChiSamples_[nchi_samples_] = Daug_->GetChi();
				LogDensMeas_Samples_[nchi_samples_] = Daug_->GetLogDens();
				nchi_samples_++;
			}
		}
		// report on the results
		Report();
	}

	// print out useful information on the MCMC sampler results
	virtual void Report() {
		int naccept_theta = PopPar_->GetNaccept();
		double arate_theta = double(naccept_theta) / (current_iter_ - 1);
		std::cout << "Acceptance rate for Population Parameter is " << arate_theta << std::endl;
		thrust::host_vector<int> naccept_chi = Daug_->GetNaccept();
		double arate_mean = 0.0;
		double arate_max = 0.0;
		double arate_min = 1.0;
		for (int i = 0; i < naccept_chi.size(); ++i) {
			double this_arate = double(naccept_chi[i]) / (current_iter_ - 1.0);
			arate_mean += this_arate / naccept_chi.size();
			arate_min = std::min(this_arate, arate_min);
			arate_max = std::max(this_arate, arate_max);
		}
		std::cout << "Mean acceptance rate for characteristics is " << arate_mean << std::endl;
		std::cout << "Minimum acceptance rate for characteristics is " << arate_min << std::endl;
		std::cout << "Maximum acceptance rate for characteristics is " << arate_max << std::endl;
	}

	// save the sampled characteristic values? not saving them can speed up the sampler since we do not need to
	// read the values from the GPU
	void NoCharSave(bool nosave = true) {
		if (nosave) {
			Daug_->SetSaveTrace(false);
		} else {
			Daug_->SetSaveTrace(true);
		}
	}

	// grab the pointers to the DataAugmentation and PopulationPar objects
	boost::shared_ptr<DataAugmentation<mfeat, pchi, dtheta> > GetDaugPtr() { return Daug_; }
	boost::shared_ptr<PopulationPar<mfeat, pchi, dtheta> > GetThetaPtr() { return PopPar_; }

	// grab the MCMC samples
	const vecvec& GetPopSamples() const { return ThetaSamples_; }
	const std::vector<vecvec>& GetCharSamples() const { return ChiSamples_; }
	const std::vector<double>& GetLogDensPop() const { return LogDensPop_Samples_; }
	const std::vector<double>& GetLogDensMeas() const { return LogDensMeas_Samples_; }

protected:
	dim3 nB_, nT_;  // CUDA grid launch parameters
	int niter_, nburnin_, nthin_chi_, nthin_theta_; // total # of iterations, # of burnin iterations, and thinning amount
	int current_iter_, ntheta_samples_, nchi_samples_;
	bool fix_poppar, fix_char; // is set to true, then keep the values fixed throughout the MCMC sampler
	boost::shared_ptr<DataAugmentation<mfeat, pchi, dtheta> > Daug_;
	boost::shared_ptr<PopulationPar<mfeat, pchi, dtheta> > PopPar_;
	std::vector<vecvec> ChiSamples_;
	vecvec ThetaSamples_;
	std::vector<double> LogDensMeas_Samples_;
	std::vector<double> LogDensPop_Samples_;
};

#endif /* GIBBSSAMPLER_HPP_ */

<commit_msg>added GibbsSampler constructor for subclassed objects<commit_after>/*
 * GibbsSampler.hpp
 *
 *  Created on: Jul 25, 2013
 *      Author: Brandon C. Kelly
 */

#ifndef GIBBSSAMPLER_HPP_
#define GIBBSSAMPLER_HPP_

// std includes
#include <exception>
#include <sstream>

// boost includes
#include <boost/shared_ptr.hpp>

// local includes
#include "parameters.cuh"

template<int mfeat, int pchi, int dtheta>
class GibbsSampler
{
public:
	// constructor for default DataAugmentation and PopulationPar classes
	GibbsSampler(vecvec& meas, vecvec& meas_unc, int niter, int nburnin, int nthin_chi=100, int nthin_theta=1,
			int nThreads=256) :
				niter_(niter), nburnin_(nburnin), nthin_theta_(nthin_theta), nthin_chi_(nthin_chi)
		{
			_InitializeMembers(meas.size(), nThreads)
			// construct DataAugmentation and PopulationPar objects
			Daug_.reset(new DataAugmentation<mfeat, pchi, dtheta>(meas, meas_unc, nB_, nT_));
			PopPar_.reset(new PopulationPar<mfeat, pchi, dtheta>(nB_, nT_));
			Daug_->SetPopulationPtr(PopPar_);
			PopPar_->SetDataAugPtr(Daug_);

			// Set the initial values of the characteristics and thetas, as well as their proposal covariances
			Initialize();
		}

	// Constructor for subclassed DataAugmentation and PopulationPar classes. In this case the user must supply the
	// pointers to the instantiated subclasses of DataAugmentation and PopulatinPar.
	GibbsSampler(boost::shared_ptr<DataAugmentation<mfeat, pchi, dtheta> >& Daug,
			boost::shared_ptr<PopulationPar<mfeat, pchi, dtheta> >& Theta,
			int niter, int nburnin, int nthin_chi=100, int nthin_theta=1, int nThreads=256) :
				niter_(niter), nburnin_(nburnin), nthin_theta_(nthin_theta), nthin_chi_(nthin_chi)
		{
			int ndata = Daug->GetDataDim();
			_InitializeMembers(ndata, nThreads);
			// construct DataAugmentation and PopulationPar objects
			Daug_ = Daug;
			PopPar_ = Theta;
			Daug_->SetPopulationPtr(PopPar_);
			PopPar_->SetDataAugPtr(Daug_);

			// Set the initial values of the characteristics and thetas, as well as their proposal covariances
			Initialize();
		}

	// fix the population parameters throughout the sampler?
	void FixPopPar(bool fix=true) { fix_poppar = fix; }

	// fix the characteristics throughout the sampler?
	void FixChar(bool fix=true) { fix_char = fix; }

	// perform a single iterations of the Gibbs Sampler
	virtual void Iterate() {
		if (!fix_char) Daug_->Update();
		if (!fix_poppar) PopPar_->Update();
		current_iter_++;
	}

	// Initialize the parameter values, their proposal covariances, and the log-densities
	void Initialize() {
		if (!fix_char) Daug_->Initialize();
		if (!fix_poppar) PopPar_->Initialize();
	}

	// run the MCMC sampler
	void Run() {
		// first run for a burn-in period
		std::cout << "Doing " << nburnin_ << " iterations of burnin..." << std::endl;

		for (int i = 0; i < nburnin_; ++i) {
			if (i % 1000 == 0) {
				std::cout << i << "..." << std::endl;
			}
			Iterate();
		}
		// TODO: add timer
		// TODO: add a progress bar

		// Burn-in stage is finished, so reset the current iteration and acceptance rates
		std::cout << "Burnin finished." << std::endl;
		Report();
		std::cout << std::endl;

		current_iter_ = 1;
		Daug_->ResetAcceptance();
		PopPar_->ResetAcceptance();

		// run the main MCMC sampler
		std::cout << "Now doing " << niter_ << " iterations of the Gibbs Sampler..." << std::endl;

		for (int i = 0; i < niter_; ++i) {
			if (i % 1000 == 0) {
				std::cout << i << "..." << std::endl;
			}
			Iterate();
			// TODO: How long does saving the values take? Maybe replace these with iterators?
			if (!fix_poppar && (current_iter_ % nthin_theta_ == 0)) {
				// save the value of the population parameter since we've done nthin_theta_ iterations since the last save
				ThetaSamples_[ntheta_samples_] = PopPar_->GetTheta();
				LogDensPop_Samples_[ntheta_samples_] = PopPar_->GetLogDens();
				ntheta_samples_++;
			}
			if (!fix_char && (current_iter_ % nthin_chi_ == 0) && Daug_->SaveTrace()) {
				// save the value of the characteristics
				ChiSamples_[nchi_samples_] = Daug_->GetChi();
				LogDensMeas_Samples_[nchi_samples_] = Daug_->GetLogDens();
				nchi_samples_++;
			}
		}
		// report on the results
		Report();
	}

	// print out useful information on the MCMC sampler results
	virtual void Report() {
		int naccept_theta = PopPar_->GetNaccept();
		double arate_theta = double(naccept_theta) / (current_iter_ - 1);
		std::cout << "Acceptance rate for Population Parameter is " << arate_theta << std::endl;
		thrust::host_vector<int> naccept_chi = Daug_->GetNaccept();
		double arate_mean = 0.0;
		double arate_max = 0.0;
		double arate_min = 1.0;
		for (int i = 0; i < naccept_chi.size(); ++i) {
			double this_arate = double(naccept_chi[i]) / (current_iter_ - 1.0);
			arate_mean += this_arate / naccept_chi.size();
			arate_min = std::min(this_arate, arate_min);
			arate_max = std::max(this_arate, arate_max);
		}
		std::cout << "Mean acceptance rate for characteristics is " << arate_mean << std::endl;
		std::cout << "Minimum acceptance rate for characteristics is " << arate_min << std::endl;
		std::cout << "Maximum acceptance rate for characteristics is " << arate_max << std::endl;
	}

	// save the sampled characteristic values? not saving them can speed up the sampler since we do not need to
	// read the values from the GPU
	void NoCharSave(bool nosave = true) {
		if (nosave) {
			Daug_->SetSaveTrace(false);
		} else {
			Daug_->SetSaveTrace(true);
		}
	}

	// grab the pointers to the DataAugmentation and PopulationPar objects
	boost::shared_ptr<DataAugmentation<mfeat, pchi, dtheta> > GetDaugPtr() { return Daug_; }
	boost::shared_ptr<PopulationPar<mfeat, pchi, dtheta> > GetThetaPtr() { return PopPar_; }

	// grab the MCMC samples
	const vecvec& GetPopSamples() const { return ThetaSamples_; }
	const std::vector<vecvec>& GetCharSamples() const { return ChiSamples_; }
	const std::vector<double>& GetLogDensPop() const { return LogDensPop_Samples_; }
	const std::vector<double>& GetLogDensMeas() const { return LogDensMeas_Samples_; }

protected:
	dim3 nB_, nT_;  // CUDA grid launch parameters
	int niter_, nburnin_, nthin_chi_, nthin_theta_; // total # of iterations, # of burnin iterations, and thinning amount
	int current_iter_, ntheta_samples_, nchi_samples_;
	bool fix_poppar, fix_char; // is set to true, then keep the values fixed throughout the MCMC sampler
	boost::shared_ptr<DataAugmentation<mfeat, pchi, dtheta> > Daug_;
	boost::shared_ptr<PopulationPar<mfeat, pchi, dtheta> > PopPar_;
	std::vector<vecvec> ChiSamples_;
	vecvec ThetaSamples_;
	std::vector<double> LogDensMeas_Samples_;
	std::vector<double> LogDensPop_Samples_;

	// initialize the values and sizes of the data members, called by the constructor
	void _InitializeMembers(int ndata, int nThreads) {
		// first do CUDA grid launch
		dim3 nT(nThreads);
		nT_ = nT;
		dim3 nB((ndata + nT.x-1) / nT.x);
		nB_ = nB;
		if (nB.x > 65535)
		{
			std::stringstream errmsg;
			errmsg << "ERROR: Block is too large:\n";
			errmsg << nB.x << " blocks. Max is 65535.\n";
			throw std::runtime_error(errmsg.str());
		}
		// set container sizes
		int nchi_samples = niter_ / nthin_chi_;
		int ntheta_samples = niter_ / nthin_theta_;
		ChiSamples_.resize(nchi_samples);
		ThetaSamples_.resize(ntheta_samples);
		LogDensMeas_Samples_.resize(nchi_samples);
		LogDensPop_Samples_.resize(ntheta_samples);

		ntheta_samples_ = 0;
		nchi_samples_ = 0;
		current_iter_ = 1;
		fix_poppar = false; // default is to sample both the population parameters and characteristics
		fix_char = false;
	}
};

#endif /* GIBBSSAMPLER_HPP_ */

<|endoftext|>


<commit_before>#include "QxHoloPyramidWidget.h"

#include <QHBoxLayout>

#include <Inventor/Qt/viewers/SoQtViewer.h>
#include <Inventor/nodes/SoCamera.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoViewport.h>
#include <Inventor/sensors/SoNodeSensor.h>

#include <hxcore/HxController.h>
#include <hxcore/HxViewer.h>

class QxHoloViewer : public SoQtViewer
{
public:
    QxHoloViewer(QWidget* parent) : SoQtViewer(parent, "holoviewer", true, SoQtViewer::BROWSER, true)
    {
        root = new SoSeparator;
        camera = new SoPerspectiveCamera;
        viewport = new SoViewport;

        sensor = new SoNodeSensor;
        sensor->setPriority(0);
        sensor->setFunction(cameraChangedCB, this);
    }

    ~QxHoloViewer()
    {
        delete sensor;
    }

    virtual void setSceneGraph (SoNode *newScene)
    {
        HxViewer* hxviewer = theController->viewer(0);

        root->removeAllChildren();
        root->addChild(viewport);
        root->addChild(camera);
        root->addChild(newScene);

        sensor->attach(hxviewer->getCamera());

        SoQtViewer::setSceneGraph(root);
    }

    void actualRedraw()
    {
        int width = getSize()[0];
        int height = getSize()[1];

        int vpsize = height / 2;

        SoCamera* camera = getCamera();
        camera->enableNotify(false);

        viewport->enableNotify(false);
        viewport->size.setValue(vpsize, vpsize);

        // Front View
        adjustCameraClippingPlanes();

        viewport->origin.setValue((width - vpsize) / 2, height - vpsize);

        getSceneManager()->render(true, true);

        // Left View
        rotate(SbRotation(SbVec3f(0,1,0), M_PI/2));

        adjustCameraClippingPlanes();

        viewport->origin.setValue(width / 2, (height/2) - vpsize/2);

        getSceneManager()->render(false, false);

        // Right View
        rotate(SbRotation(SbVec3f(0,1,0), M_PI));

        adjustCameraClippingPlanes();

        viewport->origin.setValue(width / 2 - vpsize, (height/2) - vpsize/2);

        getSceneManager()->render(false, false);

        camera->enableNotify(true);
        viewport->enableNotify(true);
    }

    void rotate(const SbRotation &rot)
    {
        SoCamera* camera = getCamera();

        // get center of rotation
        float radius = camera->focalDistance.getValue();

        SbVec3f forward;
        camera->orientation.getValue().multVec(SbVec3f(0,0,-1), forward);

        SbVec3f center = camera->position.getValue() + radius * forward;

        // apply new rotation to the camera
        camera->orientation = rot * camera->orientation.getValue();

        // reposition camera to look at pt of interest
        camera->orientation.getValue().multVec(SbVec3f(0,0,-1), forward);
        camera->position = center - radius * forward;
    }

    // Callback that reports whenever the camera changes.
    static void cameraChangedCB(void *data, SoSensor *)
    {
        QxHoloViewer* _this = (QxHoloViewer*)data;

        HxViewer* hxviewer = theController->viewer(0);

        _this->camera->copyFieldValues(hxviewer->getCamera());
    }

private:
    McHandle<SoSeparator> root;
    McHandle<SoPerspectiveCamera> camera;
    McHandle<SoViewport> viewport;

    SoNodeSensor* sensor;
};

QxHoloPyramidWidget::QxHoloPyramidWidget(QWidget* parent)
    : QWidget(parent)
{
    setWindowFlags(Qt::Window);

    viewer = new QxHoloViewer(this);

    QHBoxLayout* layout = new QHBoxLayout(this);
    layout->setMargin(0);
    layout->addWidget(viewer->getWidget());

    viewer->setSceneGraph(theController->viewer(0)->getSceneGraph());
}

QxHoloPyramidWidget::~QxHoloPyramidWidget()
{
    delete viewer;
}
<commit_msg>hxholopyramid: Fix left/right rotation.<commit_after>#include "QxHoloPyramidWidget.h"

#include <QHBoxLayout>

#include <Inventor/Qt/viewers/SoQtViewer.h>
#include <Inventor/nodes/SoCamera.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoViewport.h>
#include <Inventor/sensors/SoNodeSensor.h>

#include <hxcore/HxController.h>
#include <hxcore/HxViewer.h>

class QxHoloViewer : public SoQtViewer
{
public:
    QxHoloViewer(QWidget* parent) : SoQtViewer(parent, "holoviewer", true, SoQtViewer::BROWSER, true)
    {
        root = new SoSeparator;
        camera = new SoPerspectiveCamera;
        viewport = new SoViewport;

        sensor = new SoNodeSensor;
        sensor->setPriority(0);
        sensor->setFunction(cameraChangedCB, this);
    }

    ~QxHoloViewer()
    {
        delete sensor;
    }

    virtual void setSceneGraph (SoNode *newScene)
    {
        HxViewer* hxviewer = theController->viewer(0);

        root->removeAllChildren();
        root->addChild(viewport);
        root->addChild(camera);
        root->addChild(newScene);

        sensor->attach(hxviewer->getCamera());

        SoQtViewer::setSceneGraph(root);
    }

    void actualRedraw()
    {
        int width = getSize()[0];
        int height = getSize()[1];

        int vpsize = height / 2;

        SoCamera* camera = getCamera();
        camera->enableNotify(false);

        viewport->enableNotify(false);
        viewport->size.setValue(vpsize, vpsize);

        // Front View
        adjustCameraClippingPlanes();

        viewport->origin.setValue((width - vpsize) / 2, height - vpsize);

        getSceneManager()->render(true, true);

        // Left View
        SbRotation r1(SbVec3f(0,0,1), M_PI/2);

        rotate(r1*SbRotation(SbVec3f(0,1,0), M_PI/2));

        adjustCameraClippingPlanes();

        viewport->origin.setValue(width / 2, (height/2) - vpsize/2);

        getSceneManager()->render(false, false);

        // Right View
        rotate(SbRotation(SbVec3f(0,1,0), M_PI));

        adjustCameraClippingPlanes();

        viewport->origin.setValue(width / 2 - vpsize, (height/2) - vpsize/2);

        getSceneManager()->render(false, false);

        camera->enableNotify(true);
        viewport->enableNotify(true);
    }

    void rotate(const SbRotation &rot)
    {
        SoCamera* camera = getCamera();

        // get center of rotation
        float radius = camera->focalDistance.getValue();

        SbVec3f forward;
        camera->orientation.getValue().multVec(SbVec3f(0,0,-1), forward);

        SbVec3f center = camera->position.getValue() + radius * forward;

        // apply new rotation to the camera
        camera->orientation = rot * camera->orientation.getValue();

        // reposition camera to look at pt of interest
        camera->orientation.getValue().multVec(SbVec3f(0,0,-1), forward);
        camera->position = center - radius * forward;
    }

    // Callback that reports whenever the camera changes.
    static void cameraChangedCB(void *data, SoSensor *)
    {
        QxHoloViewer* _this = (QxHoloViewer*)data;

        HxViewer* hxviewer = theController->viewer(0);

        _this->camera->copyFieldValues(hxviewer->getCamera());
    }

private:
    McHandle<SoSeparator> root;
    McHandle<SoPerspectiveCamera> camera;
    McHandle<SoViewport> viewport;

    SoNodeSensor* sensor;
};

QxHoloPyramidWidget::QxHoloPyramidWidget(QWidget* parent)
    : QWidget(parent)
{
    setWindowFlags(Qt::Window);

    viewer = new QxHoloViewer(this);

    QHBoxLayout* layout = new QHBoxLayout(this);
    layout->setMargin(0);
    layout->addWidget(viewer->getWidget());

    viewer->setSceneGraph(theController->viewer(0)->getSceneGraph());
}

QxHoloPyramidWidget::~QxHoloPyramidWidget()
{
    delete viewer;
}
<|endoftext|>


<commit_before><commit_msg>tdf#89665: i18npool: speed up TextSearch::searchForward()<commit_after><|endoftext|>


<commit_before>#pragma once

#include <functional>

#include <Transform/UnitVector.hpp>
#include <Transform/Units.hpp>
#include <Types/Togglable.hpp>

namespace obe::Collision
{
    class TrajectoryNode;
    class Trajectory;
    class PolygonalCollider;

    using OnCollideCallback
        = std::function<void(Trajectory&, Transform::UnitVector, Transform::UnitVector)>;
    using TrajectoryCheckFunction
        = std::function<void(Trajectory&, Transform::UnitVector&, PolygonalCollider*)>;

    /**
     * \brief A Trajectory makes a TrajectoryNode moves using angle, speed and
     *        acceleration (Linear Trajectory)
     * \bind{Trajectory}
     */
    class Trajectory : public Types::Togglable
    {
    private:
        double m_acceleration = 0;
        double m_angle = 0;
        std::vector<TrajectoryCheckFunction> m_checks {};
        OnCollideCallback m_onCollideCallback;
        double m_speed = 0;
        bool m_static = false;
        Transform::Units m_unit;
        friend class TrajectoryNode;

    public:
        Trajectory(Transform::Units unit = Transform::Units::SceneUnits);
        Trajectory& addAcceleration(double acceleration);
        Trajectory& addAngle(double angle);
        void addCheck(const TrajectoryCheckFunction& check);
        Trajectory& addSpeed(double speed);
        [[nodiscard]] double getAcceleration() const;
        [[nodiscard]] double getAngle() const;
        std::vector<TrajectoryCheckFunction>& getChecks();
        OnCollideCallback& getOnCollideCallback();
        [[nodiscard]] double getSpeed() const;
        [[nodiscard]] bool getStatic() const;
        [[nodiscard]] Transform::Units getUnit() const;
        void onCollide(const OnCollideCallback& callback);
        Trajectory& setAcceleration(double acceleration);
        Trajectory& setAngle(double angle);
        Trajectory& setSpeed(double speed);
        Trajectory& setStatic(bool tStatic);
    };
} // namespace obe::Collision
<commit_msg>Yet another missing include<commit_after>#pragma once

#include <functional>
#include <vector>

#include <Transform/UnitVector.hpp>
#include <Transform/Units.hpp>
#include <Types/Togglable.hpp>

namespace obe::Collision
{
    class TrajectoryNode;
    class Trajectory;
    class PolygonalCollider;

    using OnCollideCallback
        = std::function<void(Trajectory&, Transform::UnitVector, Transform::UnitVector)>;
    using TrajectoryCheckFunction
        = std::function<void(Trajectory&, Transform::UnitVector&, PolygonalCollider*)>;

    /**
     * \brief A Trajectory makes a TrajectoryNode moves using angle, speed and
     *        acceleration (Linear Trajectory)
     * \bind{Trajectory}
     */
    class Trajectory : public Types::Togglable
    {
    private:
        double m_acceleration = 0;
        double m_angle = 0;
        std::vector<TrajectoryCheckFunction> m_checks {};
        OnCollideCallback m_onCollideCallback;
        double m_speed = 0;
        bool m_static = false;
        Transform::Units m_unit;
        friend class TrajectoryNode;

    public:
        Trajectory(Transform::Units unit = Transform::Units::SceneUnits);
        Trajectory& addAcceleration(double acceleration);
        Trajectory& addAngle(double angle);
        void addCheck(const TrajectoryCheckFunction& check);
        Trajectory& addSpeed(double speed);
        [[nodiscard]] double getAcceleration() const;
        [[nodiscard]] double getAngle() const;
        std::vector<TrajectoryCheckFunction>& getChecks();
        OnCollideCallback& getOnCollideCallback();
        [[nodiscard]] double getSpeed() const;
        [[nodiscard]] bool getStatic() const;
        [[nodiscard]] Transform::Units getUnit() const;
        void onCollide(const OnCollideCallback& callback);
        Trajectory& setAcceleration(double acceleration);
        Trajectory& setAngle(double angle);
        Trajectory& setSpeed(double speed);
        Trajectory& setStatic(bool tStatic);
    };
} // namespace obe::Collision
<|endoftext|>


<commit_before>/************************************************
 *  partial_sum.hpp
 *  DICT
 *
 *  Copyright (c) 2015-2017, Chi-En Wu
 *  Distributed under The BSD 3-Clause License
 ************************************************/

#ifndef DICT_INTERNAL_PARTIAL_SUM_HPP_
#define DICT_INTERNAL_PARTIAL_SUM_HPP_

#include <functional>
#include <stdexcept>
#include <utility>

#include "rbtree.hpp"

namespace dict {

namespace internal {

/************************************************
 * Declaration: class partial_sum<K, T>
 ************************************************/

template <typename Key, typename T>
class partial_sum {
 public:  // Public Type(s)
    using key_type = Key;
    using value_type = T;

 public:  // Public Method(s)
    ~partial_sum();

    void increase(key_type k, value_type x);
    void decrease(key_type k, value_type x);

    value_type sum() const;
    value_type sum(key_type k) const;
    key_type search(value_type x) const;
    std::pair<key_type, value_type> search_and_sum(value_type x) const;

 private:  // Private Type(s)
    struct key_and_sum;
    struct sums_updater;
    using bstree = rbtree<key_and_sum, sums_updater>;

 private:  // Private Static Method(s)
    template <typename Op>
    void update(key_type k, value_type x, Op op);
    static void update_sums(typename bstree::iterator it);

 private:  // Private Property(ies)
    bstree tree_;
};  // class partial_sum<K, T>

/************************************************
 * Declaration: struct partial_sum<K, T>::key_and_sum
 ************************************************/

template <typename K, typename T>
struct partial_sum<K, T>::key_and_sum {
    key_type key;
    value_type sum;
};  // struct partial_sum<K, T>::key_and_sum

/************************************************
 * Declaration: struct partial_sum<K, T>::sums_updater
 ************************************************/

template <typename K, typename T>
struct partial_sum<K, T>::sums_updater {
    void operator()(typename bstree::iterator it) const {
        update_sums(it);
    }
};  // struct partial_sum<K, T>::sums_updater

/************************************************
 * Implementation: class partial_sum<K, T>
 ************************************************/

template <typename K, typename T>
inline partial_sum<K, T>::~partial_sum() {
    // do nothing
}

template <typename K, typename T>
inline void partial_sum<K, T>::increase(key_type k, value_type x) {
    update(k, x, std::plus<T>());
}

template <typename K, typename T>
inline void partial_sum<K, T>::decrease(key_type k, value_type x) {
    update(k, x, std::minus<T>());
}

template <typename K, typename T>
typename partial_sum<K, T>::value_type partial_sum<K, T>::sum() const {
    auto it = tree_.root();
    auto sum = 0;
    while (it) {
        sum += it->sum;
        it.go_right();
    }

    return sum;
}

template <typename K, typename T>
typename partial_sum<K, T>::value_type partial_sum<K, T>::sum(key_type k) const {
    value_type sum = 0;
    auto it = tree_.root();
    while (it) {
        if (k < it->key) {
            it.go_left();
        } else {
            sum += it->sum;
            if (k == it->key) {
                break;
            } else {
                it.go_right();
            }
        }
    }

    return sum;
}

template <typename K, typename T>
typename partial_sum<K, T>::key_type partial_sum<K, T>::search(value_type x) const {
    auto pair = search_and_sum(x);
    return pair.first;
}

template <typename K, typename T>
std::pair<typename partial_sum<K, T>::key_type, typename partial_sum<K, T>::value_type>
partial_sum<K, T>::search_and_sum(value_type x) const {
    auto it = tree_.root();

    decltype(x) sum = 0;
    bool found = false;
    key_type key;
    while (it) {
        if (x - sum > it->sum) {
            sum += it->sum;
            it.go_right();
        } else {
            key = it->key;
            found = true;

            it.go_left();
        }
    }

    if (!found) {
        throw std::invalid_argument("not found");
    }

    return std::make_pair(key, sum);
}

template <typename K, typename T>
template <typename Op>
void partial_sum<K, T>::update(key_type k, value_type x, Op op) {
    auto it = tree_.root();
    if (!it) {
        tree_.insert_before(it, {k, op(0, x)});
        return;
    }

    while (1) {
        if (k == it->key) {
            it->sum = op(it->sum, x);
            break;
        } else if (k < it->key) {
            it->sum = op(it->sum, x);
            if (it.has_left()) {
                it.go_left();
            } else {
                tree_.insert_before(it, {k, op(0, x)});
                break;
            }
        } else {
            if (it.has_right()) {
                it.go_right();
            } else {
                tree_.insert_before(++it, {k, op(0, x)});
                break;
            }
        }
    }
}

template <typename K, typename T>
inline void partial_sum<K, T>::update_sums(typename bstree::iterator it) {
    if (it.has_parent()) {
        if (it == it.parent().left()) {
            it.parent()->sum += it->sum;
        } else {
            it->sum -= it.parent()->sum;
        }
    }
}

}  // namespace internal

}  // namespace dict

#endif  // DICT_INTERNAL_PARTIAL_SUM_HPP_
<commit_msg>:art: Merge `partial_sum<>::update_sums()` into `partial_sum<>::sum_updater`<commit_after>/************************************************
 *  partial_sum.hpp
 *  DICT
 *
 *  Copyright (c) 2015-2017, Chi-En Wu
 *  Distributed under The BSD 3-Clause License
 ************************************************/

#ifndef DICT_INTERNAL_PARTIAL_SUM_HPP_
#define DICT_INTERNAL_PARTIAL_SUM_HPP_

#include <functional>
#include <stdexcept>
#include <utility>

#include "rbtree.hpp"

namespace dict {

namespace internal {

/************************************************
 * Declaration: class partial_sum<K, T>
 ************************************************/

template <typename Key, typename T>
class partial_sum {
 public:  // Public Type(s)
    using key_type = Key;
    using value_type = T;

 public:  // Public Method(s)
    ~partial_sum();

    void increase(key_type k, value_type x);
    void decrease(key_type k, value_type x);

    value_type sum() const;
    value_type sum(key_type k) const;
    key_type search(value_type x) const;
    std::pair<key_type, value_type> search_and_sum(value_type x) const;

 private:  // Private Type(s)
    struct key_and_sum;
    struct sums_updater;
    using bstree = rbtree<key_and_sum, sums_updater>;

 private:  // Private Static Method(s)
    template <typename Op>
    void update(key_type k, value_type x, Op op);

 private:  // Private Property(ies)
    bstree tree_;
};  // class partial_sum<K, T>

/************************************************
 * Declaration: struct partial_sum<K, T>::key_and_sum
 ************************************************/

template <typename K, typename T>
struct partial_sum<K, T>::key_and_sum {
    key_type key;
    value_type sum;
};  // struct partial_sum<K, T>::key_and_sum

/************************************************
 * Declaration: struct partial_sum<K, T>::sums_updater
 ************************************************/

template <typename K, typename T>
struct partial_sum<K, T>::sums_updater {
    void operator()(typename bstree::iterator it) const {
        if (it.has_parent()) {
            if (it == it.parent().left()) {
                it.parent()->sum += it->sum;
            } else {
                it->sum -= it.parent()->sum;
            }
        }
    }
};  // struct partial_sum<K, T>::sums_updater

/************************************************
 * Implementation: class partial_sum<K, T>
 ************************************************/

template <typename K, typename T>
inline partial_sum<K, T>::~partial_sum() {
    // do nothing
}

template <typename K, typename T>
inline void partial_sum<K, T>::increase(key_type k, value_type x) {
    update(k, x, std::plus<T>());
}

template <typename K, typename T>
inline void partial_sum<K, T>::decrease(key_type k, value_type x) {
    update(k, x, std::minus<T>());
}

template <typename K, typename T>
typename partial_sum<K, T>::value_type partial_sum<K, T>::sum() const {
    auto it = tree_.root();
    auto sum = 0;
    while (it) {
        sum += it->sum;
        it.go_right();
    }

    return sum;
}

template <typename K, typename T>
typename partial_sum<K, T>::value_type partial_sum<K, T>::sum(key_type k) const {
    value_type sum = 0;
    auto it = tree_.root();
    while (it) {
        if (k < it->key) {
            it.go_left();
        } else {
            sum += it->sum;
            if (k == it->key) {
                break;
            } else {
                it.go_right();
            }
        }
    }

    return sum;
}

template <typename K, typename T>
typename partial_sum<K, T>::key_type partial_sum<K, T>::search(value_type x) const {
    auto pair = search_and_sum(x);
    return pair.first;
}

template <typename K, typename T>
std::pair<typename partial_sum<K, T>::key_type, typename partial_sum<K, T>::value_type>
partial_sum<K, T>::search_and_sum(value_type x) const {
    auto it = tree_.root();

    decltype(x) sum = 0;
    bool found = false;
    key_type key;
    while (it) {
        if (x - sum > it->sum) {
            sum += it->sum;
            it.go_right();
        } else {
            key = it->key;
            found = true;

            it.go_left();
        }
    }

    if (!found) {
        throw std::invalid_argument("not found");
    }

    return std::make_pair(key, sum);
}

template <typename K, typename T>
template <typename Op>
void partial_sum<K, T>::update(key_type k, value_type x, Op op) {
    auto it = tree_.root();
    if (!it) {
        tree_.insert_before(it, {k, op(0, x)});
        return;
    }

    while (1) {
        if (k == it->key) {
            it->sum = op(it->sum, x);
            break;
        } else if (k < it->key) {
            it->sum = op(it->sum, x);
            if (it.has_left()) {
                it.go_left();
            } else {
                tree_.insert_before(it, {k, op(0, x)});
                break;
            }
        } else {
            if (it.has_right()) {
                it.go_right();
            } else {
                tree_.insert_before(++it, {k, op(0, x)});
                break;
            }
        }
    }
}

}  // namespace internal

}  // namespace dict

#endif  // DICT_INTERNAL_PARTIAL_SUM_HPP_
<|endoftext|>


<commit_before>/*

Copyright (c) 2006, Arvid Norberg
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 author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_SESSION_STATUS_HPP_INCLUDED
#define TORRENT_SESSION_STATUS_HPP_INCLUDED

namespace libtorrent
{

#ifndef TORRENT_DISABLE_DHT

	struct dht_lookup
	{
		char const* type;
		int outstanding_requests;
		int timeouts;
		int responses;
		int branch_factor;
	};

#endif

	struct TORRENT_EXPORT session_status
	{
		bool has_incoming_connections;

		float upload_rate;
		float download_rate;
		size_type total_download;
		size_type total_upload;

		float payload_upload_rate;
		float payload_download_rate;
		size_type total_payload_download;
		size_type total_payload_upload;

		float ip_overhead_upload_rate;
		float ip_overhead_download_rate;
		size_type total_ip_overhead_download;
		size_type total_ip_overhead_upload;

		float dht_upload_rate;
		float dht_download_rate;
		size_type total_dht_download;
		size_type total_dht_upload;

		float tracker_upload_rate;
		float tracker_download_rate;
		size_type total_tracker_download;
		size_type total_tracker_upload;

		size_type total_redundant_bytes;
		size_type total_failed_bytes;

		int num_peers;
		int num_unchoked;
		int allowed_upload_slots;

		int up_bandwidth_queue;
		int down_bandwidth_queue;

		int optimistic_unchoke_counter;
		int unchoke_counter;

#ifndef TORRENT_DISABLE_DHT
		int dht_nodes;
		int dht_node_cache;
		int dht_torrents;
		size_type dht_global_nodes;
		std::vector<dht_lookup> active_requests;
#endif
	};

}

#endif // TORRENT_SESSION_STATUS_HPP_INCLUDED

<commit_msg>fixed missing includes in header<commit_after>/*

Copyright (c) 2006, Arvid Norberg
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 author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_SESSION_STATUS_HPP_INCLUDED
#define TORRENT_SESSION_STATUS_HPP_INCLUDED

#include "libtorrent/config.hpp"
#include "libtorrent/size_type.hpp"

namespace libtorrent
{

#ifndef TORRENT_DISABLE_DHT

	struct dht_lookup
	{
		char const* type;
		int outstanding_requests;
		int timeouts;
		int responses;
		int branch_factor;
	};

#endif

	struct TORRENT_EXPORT session_status
	{
		bool has_incoming_connections;

		float upload_rate;
		float download_rate;
		size_type total_download;
		size_type total_upload;

		float payload_upload_rate;
		float payload_download_rate;
		size_type total_payload_download;
		size_type total_payload_upload;

		float ip_overhead_upload_rate;
		float ip_overhead_download_rate;
		size_type total_ip_overhead_download;
		size_type total_ip_overhead_upload;

		float dht_upload_rate;
		float dht_download_rate;
		size_type total_dht_download;
		size_type total_dht_upload;

		float tracker_upload_rate;
		float tracker_download_rate;
		size_type total_tracker_download;
		size_type total_tracker_upload;

		size_type total_redundant_bytes;
		size_type total_failed_bytes;

		int num_peers;
		int num_unchoked;
		int allowed_upload_slots;

		int up_bandwidth_queue;
		int down_bandwidth_queue;

		int optimistic_unchoke_counter;
		int unchoke_counter;

#ifndef TORRENT_DISABLE_DHT
		int dht_nodes;
		int dht_node_cache;
		int dht_torrents;
		size_type dht_global_nodes;
		std::vector<dht_lookup> active_requests;
#endif
	};

}

#endif // TORRENT_SESSION_STATUS_HPP_INCLUDED

<|endoftext|>


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

#ifndef MAPNIK_XML_ATTRIBUTE_CAST_HPP
#define MAPNIK_XML_ATTRIBUTE_CAST_HPP

//mapnik
#include <mapnik/debug.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/xml_tree.hpp>
#include <mapnik/enumeration.hpp>
#include <mapnik/boolean.hpp>
#include <mapnik/color.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/expression.hpp>
#include <mapnik/util/conversions.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/text/font_feature_settings.hpp>

// boost
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#include <boost/optional.hpp>
#pragma GCC diagnostic pop

// stl
#include <string>
#include <map>
#include <typeinfo>
#include <utility>
#include <stdexcept>

namespace mapnik { namespace detail {

template <typename T>
struct do_xml_attribute_cast
{
    static inline boost::optional<T> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& /*source*/)
    {
        std::string err_msg("No conversion from std::string to");
        err_msg += std::string(typeid(T).name());
        throw std::runtime_error(err_msg);
    }
};

// specialization for mapnik::boolean_type
template <>
struct do_xml_attribute_cast<mapnik::boolean_type>
{
    static inline boost::optional<mapnik::boolean_type> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        bool result;
        if (mapnik::util::string2bool(source, result))
            return boost::optional<mapnik::boolean_type>(result);
        return boost::optional<mapnik::boolean_type>();
    }
};

// specialization for int
template <>
struct do_xml_attribute_cast<int>
{
    static inline boost::optional<int> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        int result;
        if (mapnik::util::string2int(source, result))
            return boost::optional<int>(result);
        return boost::optional<int>();
    }
};

#ifdef BIGINT
// specialization for long long
template <>
struct do_xml_attribute_cast<mapnik::value_integer>
{
    static inline boost::optional<mapnik::value_integer> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        int result;
        if (mapnik::util::string2int(source, result))
            return boost::optional<mapnik::value_integer>(result);
        return boost::optional<mapnik::value_integer>();
    }
};

#endif

// specialization for unsigned

template <>
struct do_xml_attribute_cast<unsigned>
{
    static inline boost::optional<unsigned> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        int result;
        if (mapnik::util::string2int(source, result))
            return boost::optional<unsigned>(result);
        return boost::optional<unsigned>();
    }
};

// specialization for float
template <>
struct do_xml_attribute_cast<float>
{
    static inline boost::optional<float> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        float result;
        if (mapnik::util::string2float(source, result))
            return boost::optional<float>(result);
        return boost::optional<float>();
    }
};

// specialization for double
template <>
struct do_xml_attribute_cast<double>
{
    static inline boost::optional<double> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        double result;
        if (mapnik::util::string2double(source, result))
            return boost::optional<double>(result);
        return boost::optional<double>();
    }
};

// specialization for mapnik::enumeration<T,int>
template <typename T, int MAX>
struct do_xml_attribute_cast<mapnik::enumeration<T,MAX> >
{
    static inline boost::optional<mapnik::enumeration<T,MAX> > xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        using result_type = typename boost::optional<mapnik::enumeration<T,MAX> >;
        try
        {
            mapnik::enumeration<T,MAX> e;
            e.from_string(source);
            return result_type(e);
        }
        catch (illegal_enum_value const& ex)
        {
            MAPNIK_LOG_ERROR(do_xml_attribute_cast) << ex.what();
            return result_type();
        }
    }
};

// specialization for mapnik::color
template <>
struct do_xml_attribute_cast<mapnik::color>
{
    static inline boost::optional<mapnik::color> xml_attribute_cast_impl(xml_tree const&, std::string const& source)
    {
        return parse_color(source);
    }
};

// specialization for std::string
template <>
struct do_xml_attribute_cast<std::string>
{
    static inline boost::optional<std::string> xml_attribute_cast_impl(xml_tree const&, std::string const& source)
    {
        return boost::optional<std::string>(source);
    }
};

// specialization for mapnik::expression_ptr
template <>
struct do_xml_attribute_cast<mapnik::expression_ptr>
{
    static inline boost::optional<mapnik::expression_ptr> xml_attribute_cast_impl(xml_tree const& tree, std::string const& source)
    {
        std::map<std::string,mapnik::expression_ptr>::const_iterator itr = tree.expr_cache_.find(source);
        if (itr != tree.expr_cache_.end())
        {
            return itr->second;
        }
        else
        {
            mapnik::expression_ptr expr = parse_expression(source);
            tree.expr_cache_.emplace(source,expr);
            return expr;
        }
    }
};

// specialization for mapnik::font_feature_settings
template <>
struct do_xml_attribute_cast<mapnik::font_feature_settings>
{
    static inline boost::optional<mapnik::font_feature_settings> xml_attribute_cast_impl(xml_tree const&, std::string const& source)
    {
        return mapnik::font_feature_settings(source);
    }
};

} // end namespace detail

template <typename T>
boost::optional<T> xml_attribute_cast(xml_tree const& tree, std::string const& source)
{
    return detail::do_xml_attribute_cast<T>::xml_attribute_cast_impl(tree, source);
}

} // end namespace mapnik

#endif // MAPNIK_XML_ATTRIBUTE_CAST_HPP
<commit_msg>safer conversion of unsigned in xml_attribute cast<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_XML_ATTRIBUTE_CAST_HPP
#define MAPNIK_XML_ATTRIBUTE_CAST_HPP

//mapnik
#include <mapnik/debug.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/xml_tree.hpp>
#include <mapnik/enumeration.hpp>
#include <mapnik/boolean.hpp>
#include <mapnik/color.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/expression.hpp>
#include <mapnik/util/conversions.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/text/font_feature_settings.hpp>

// boost
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#include <boost/optional.hpp>
#pragma GCC diagnostic pop

// stl
#include <string>
#include <map>
#include <typeinfo>
#include <utility>
#include <stdexcept>

namespace mapnik { namespace detail {

template <typename T>
struct do_xml_attribute_cast
{
    static inline boost::optional<T> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& /*source*/)
    {
        std::string err_msg("No conversion from std::string to");
        err_msg += std::string(typeid(T).name());
        throw std::runtime_error(err_msg);
    }
};

// specialization for mapnik::boolean_type
template <>
struct do_xml_attribute_cast<mapnik::boolean_type>
{
    static inline boost::optional<mapnik::boolean_type> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        bool result;
        if (mapnik::util::string2bool(source, result))
            return boost::optional<mapnik::boolean_type>(result);
        return boost::optional<mapnik::boolean_type>();
    }
};

// specialization for int
template <>
struct do_xml_attribute_cast<int>
{
    static inline boost::optional<int> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        int result;
        if (mapnik::util::string2int(source, result))
            return boost::optional<int>(result);
        return boost::optional<int>();
    }
};

#ifdef BIGINT
// specialization for long long
template <>
struct do_xml_attribute_cast<mapnik::value_integer>
{
    static inline boost::optional<mapnik::value_integer> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        int result;
        if (mapnik::util::string2int(source, result))
            return boost::optional<mapnik::value_integer>(result);
        return boost::optional<mapnik::value_integer>();
    }
};

#endif

// specialization for unsigned

template <>
struct do_xml_attribute_cast<unsigned>
{
    static inline boost::optional<unsigned> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        int result;
        if (mapnik::util::string2int(source, result) && result >= 0)
            return boost::optional<unsigned>(static_cast<unsigned>(result));
        return boost::optional<unsigned>();
    }
};

// specialization for float
template <>
struct do_xml_attribute_cast<float>
{
    static inline boost::optional<float> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        float result;
        if (mapnik::util::string2float(source, result))
            return boost::optional<float>(result);
        return boost::optional<float>();
    }
};

// specialization for double
template <>
struct do_xml_attribute_cast<double>
{
    static inline boost::optional<double> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        double result;
        if (mapnik::util::string2double(source, result))
            return boost::optional<double>(result);
        return boost::optional<double>();
    }
};

// specialization for mapnik::enumeration<T,int>
template <typename T, int MAX>
struct do_xml_attribute_cast<mapnik::enumeration<T,MAX> >
{
    static inline boost::optional<mapnik::enumeration<T,MAX> > xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
    {
        using result_type = typename boost::optional<mapnik::enumeration<T,MAX> >;
        try
        {
            mapnik::enumeration<T,MAX> e;
            e.from_string(source);
            return result_type(e);
        }
        catch (illegal_enum_value const& ex)
        {
            MAPNIK_LOG_ERROR(do_xml_attribute_cast) << ex.what();
            return result_type();
        }
    }
};

// specialization for mapnik::color
template <>
struct do_xml_attribute_cast<mapnik::color>
{
    static inline boost::optional<mapnik::color> xml_attribute_cast_impl(xml_tree const&, std::string const& source)
    {
        return parse_color(source);
    }
};

// specialization for std::string
template <>
struct do_xml_attribute_cast<std::string>
{
    static inline boost::optional<std::string> xml_attribute_cast_impl(xml_tree const&, std::string const& source)
    {
        return boost::optional<std::string>(source);
    }
};

// specialization for mapnik::expression_ptr
template <>
struct do_xml_attribute_cast<mapnik::expression_ptr>
{
    static inline boost::optional<mapnik::expression_ptr> xml_attribute_cast_impl(xml_tree const& tree, std::string const& source)
    {
        std::map<std::string,mapnik::expression_ptr>::const_iterator itr = tree.expr_cache_.find(source);
        if (itr != tree.expr_cache_.end())
        {
            return itr->second;
        }
        else
        {
            mapnik::expression_ptr expr = parse_expression(source);
            tree.expr_cache_.emplace(source,expr);
            return expr;
        }
    }
};

// specialization for mapnik::font_feature_settings
template <>
struct do_xml_attribute_cast<mapnik::font_feature_settings>
{
    static inline boost::optional<mapnik::font_feature_settings> xml_attribute_cast_impl(xml_tree const&, std::string const& source)
    {
        return mapnik::font_feature_settings(source);
    }
};

} // end namespace detail

template <typename T>
boost::optional<T> xml_attribute_cast(xml_tree const& tree, std::string const& source)
{
    return detail::do_xml_attribute_cast<T>::xml_attribute_cast_impl(tree, source);
}

} // end namespace mapnik

#endif // MAPNIK_XML_ATTRIBUTE_CAST_HPP
<|endoftext|>


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

// Realm+Kokkos interop support

#include "realm/kokkos_interop.h"

#include "realm/mutex.h"
#include "realm/processor.h"
#include "realm/runtime_impl.h"
#include "realm/logging.h"

#ifdef REALM_USE_CUDA
#include "realm/cuda/cuda_module.h"

#include <cuda_runtime.h>
#endif

#include <Kokkos_Core.hpp>

#include <stdlib.h>

namespace Realm {

  Logger log_kokkos("kokkos");

  namespace KokkosInterop {

    bool is_kokkos_cuda_enabled(void)
    {
#ifdef KOKKOS_ENABLE_CUDA
      return true;
#else
      return false;
#endif
    }

    bool is_kokkos_openmp_enabled(void)
    {
#ifdef KOKKOS_ENABLE_OPENMP
      return true;
#else
      return false;
#endif
    }

    class KokkosInternalTask : public InternalTask {
    public:
      KokkosInternalTask()
	: done(false), condvar(mutex) {}

      void mark_done()
      {
	AutoLock<> al(mutex);
	done = true;
	condvar.broadcast();
      }

      void wait_done()
      {
	AutoLock<> al(mutex);
	while(!done) condvar.wait();
      }

      bool done;
      Mutex mutex;
      CondVar condvar;
    };

#ifdef KOKKOS_ENABLE_OPENMP
    std::vector<ProcessorImpl *> kokkos_omp_procs;

    class KokkosOpenMPInitializer : public KokkosInternalTask {
    public:
      virtual void execute_on_processor(Processor p)
      {
	log_kokkos.info() << "doing openmp init on proc " << p;
	int thread_count = -1; // todo - get from proc
	Kokkos::OpenMP::impl_initialize(thread_count);
	mark_done();
      }
    };

    class KokkosOpenMPFinalizer : public KokkosInternalTask {
    public:
      virtual void execute_on_processor(Processor p)
      {
	log_kokkos.info() << "doing openmp finalize on proc " << p;
	Kokkos::OpenMP::impl_finalize();
	mark_done();
      }
    };
#endif

#ifdef KOKKOS_ENABLE_CUDA
    std::vector<ProcessorImpl *> kokkos_cuda_procs;

    Mutex cuda_instance_map_mutex;
    std::map<std::pair<Processor, cudaStream_t>, Kokkos::Cuda *> cuda_instance_map;

    class KokkosCudaInitializer : public KokkosInternalTask {
    public:
      virtual void execute_on_processor(Processor p)
      {
	log_kokkos.info() << "doing cuda init on proc " << p;

	ProcessorImpl *impl = get_runtime()->get_processor_impl(p);
	assert(impl->kind == Processor::TOC_PROC);
	Cuda::GPUProcessor *gpu = checked_cast<Cuda::GPUProcessor *>(impl);

	int cuda_device_id = gpu->gpu->info->index;
	int num_instances = 1; // unused in kokkos?

	Kokkos::Cuda::impl_initialize(Kokkos::Cuda::SelectDevice(cuda_device_id),
				      num_instances);
	{
	  // some init is deferred until an instance is created
	  Kokkos::Cuda dummy;
	}
	mark_done();
      }
    };

    class KokkosCudaFinalizer : public KokkosInternalTask {
    public:
      virtual void execute_on_processor(Processor p)
      {
	log_kokkos.info() << "doing cuda finalize on proc " << p;

	// delete all the cuda instances from this proc that we've cached
	for(std::map<std::pair<Processor, cudaStream_t>, Kokkos::Cuda *>::iterator it = cuda_instance_map.begin();
	    it != cuda_instance_map.end();
	    ++it)
	  if(it->first.first == p)
	    delete it->second;

	Kokkos::Cuda::impl_finalize();
	mark_done();
      }
    };
#endif

    void kokkos_initialize(const std::vector<ProcessorImpl *>& local_procs)
    {
      // use Kokkos::Impl::{pre,post}_initialize to allow us to do our own
      //  execution space initialization
      Kokkos::InitArguments kokkos_init_args;
      log_kokkos.info() << "doing general pre-initialization";
      Kokkos::Impl::pre_initialize(kokkos_init_args);

#ifdef KOKKOS_ENABLE_SERIAL
      // nothing thread-specific for serial execution space, so just call it
      //  here
      Kokkos::Serial::impl_initialize();
#endif

#ifdef KOKKOS_ENABLE_OPENMP
      // need to initialize the Kokkos openmp execution space...
#ifdef REALM_USE_OPENMP
      // ... from an openmp proc
      {
	// if we're providing openmp goodness, set environment variable to shut
	//  off some kokkos warnings that don't mean anything
	setenv("OMP_PROC_BIND", "false", 0 /*!overwrite*/);

	size_t count = 0;
	for(std::vector<ProcessorImpl *>::const_iterator it = local_procs.begin();
	    it != local_procs.end();
	    ++it)
	  if((*it)->kind == Processor::OMP_PROC) {
	    count++;
	    if(count > 1) continue; // we'll complain below
	    KokkosOpenMPInitializer ompinit;
	    (*it)->add_internal_task(&ompinit);
	    ompinit.wait_done();
	    kokkos_omp_procs.push_back(*it);
	  }
	if(count != 1) {
	  log_kokkos.fatal() << "Kokkos OpenMP support requires exactly 1 omp proc (found " << count << ") - suggest -ll:ocpu 1 -ll:onuma 0";
	  abort();
	}
      }
#else
      // ... from normal CPU procs since we don't have anything better
      {
	size_t count = 0;
	for(std::vector<ProcessorImpl *>::const_iterator it = local_procs.begin();
	    it != local_procs.end();
	    ++it)
	  if((*it)->kind == Processor::LOC_PROC) {
	    count++;
	    if(count > 1) continue; // we'll complain below
	    KokkosOpenMPInitializer ompinit;
	    (*it)->add_internal_task(&ompinit);
	    ompinit.wait_done();
	    kokkos_omp_procs.push_back(*it);
	  }
	if(count != 1) {
	  log_kokkos.fatal() << "Kokkos OpenMP support without realm OpenMP requires exactly 1 cpu proc (found " << count << ") - suggest -ll:cpu 1";
	  abort();
	}
      }
#endif
#endif

#ifdef KOKKOS_ENABLE_CUDA
      {
	size_t count = 0;
	for(std::vector<ProcessorImpl *>::const_iterator it = local_procs.begin();
	    it != local_procs.end();
	    ++it)
	  if((*it)->kind == Processor::TOC_PROC) {
	    count++;
	    if(count > 1) continue; // we'll complain below
	    KokkosCudaInitializer cudainit;
	    (*it)->add_internal_task(&cudainit);
	    cudainit.wait_done();
	    kokkos_cuda_procs.push_back(*it);
	  }
	if(count != 1) {
	  log_kokkos.fatal() << "Kokkos Cuda support requires exactly 1 gpu proc (found " << count << ") - suggest -ll:gpu 1";
	  abort();
	}
      }
#endif

      // TODO: warn if Kokkos has other execution spaces enabled that we're not
      //  willing/able to initialize?

      log_kokkos.info() << "doing general post-initialization";
      Kokkos::Impl::post_initialize(kokkos_init_args);
    }

    void kokkos_finalize(const std::vector<ProcessorImpl *>& local_procs)
    {
      // per processor finalization on the correct threads
#ifdef KOKKOS_ENABLE_OPENMP
      for(std::vector<ProcessorImpl *>::const_iterator it = kokkos_omp_procs.begin();
	  it != kokkos_omp_procs.end();
	  ++it)
	{
	  KokkosOpenMPFinalizer ompfinal;
	  (*it)->add_internal_task(&ompfinal);
	  ompfinal.wait_done();
	}
#endif

#ifdef KOKKOS_ENABLE_CUDA
      for(std::vector<ProcessorImpl *>::const_iterator it = kokkos_cuda_procs.begin();
	  it != kokkos_cuda_procs.end();
	  ++it)
	{
	  KokkosCudaFinalizer cudafinal;
	  (*it)->add_internal_task(&cudafinal);
	  cudafinal.wait_done();
	}
#endif

      log_kokkos.info() << "doing general finalization";
      Kokkos::finalize();
    }

  };

  // execution space instance conversions from processor.h
#ifdef KOKKOS_ENABLE_SERIAL
  template <>
  Processor::KokkosExecInstance::operator Kokkos::Serial() const
  {
    return Kokkos::Serial();
  }
#endif

#ifdef KOKKOS_ENABLE_OPENMP
  template <>
  Processor::KokkosExecInstance::operator Kokkos::OpenMP() const
  {
    return Kokkos::OpenMP();
  }
#endif

#ifdef KOKKOS_ENABLE_CUDA
  template <>
  Processor::KokkosExecInstance::operator Kokkos::Cuda() const
  {
#ifdef REALM_USE_CUDA
    ProcessorImpl *impl = get_runtime()->get_processor_impl(p);
    assert(impl->kind == Processor::TOC_PROC);
    Cuda::GPUProcessor *gpu = checked_cast<Cuda::GPUProcessor *>(impl);
    cudaStream_t stream = gpu->gpu->get_null_task_stream()->get_stream();
    log_kokkos.info() << "handing back stream " << stream;
    Kokkos::Cuda *inst = 0;
    {
      AutoLock<> al(KokkosInterop::cuda_instance_map_mutex);
      std::pair<Processor, cudaStream_t> key(p, stream);
      std::map<std::pair<Processor, cudaStream_t>, Kokkos::Cuda *>::iterator it = KokkosInterop::cuda_instance_map.find(key);
      if(it != KokkosInterop::cuda_instance_map.end()) {
	inst = it->second;
      } else {
	// creating a Kokkos::Cuda instance does some blocking calls, but we're
	//  not re-entrant here, so enable the scheduler lock
	Processor::enable_scheduler_lock();
	inst = new Kokkos::Cuda(stream);
	Processor::disable_scheduler_lock();
	KokkosInterop::cuda_instance_map[key] = inst;
      }
    }
    return *inst;
#else
    // we're oblivious to the application's use of CUDA
    return Kokkos::Cuda();
#endif
  }
#endif

};
<commit_msg>realm: work around symbol linkage quirks<commit_after>/* Copyright 2019 Stanford University, NVIDIA Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Realm+Kokkos interop support

#include "realm/kokkos_interop.h"

#include "realm/mutex.h"
#include "realm/processor.h"
#include "realm/runtime_impl.h"
#include "realm/logging.h"

#ifdef REALM_USE_CUDA
#include "realm/cuda/cuda_module.h"

#include <cuda_runtime.h>
#endif

// some compilers (e.g. clang++ 10) will hide symbols that you want to be
//  public if any template parameters have hidden visibility, even if they
//  come from an "external" header file...
// work around this by declaring any of the kokkos execution space types
//  that we might use below (we don't get the defines to say whether we
//  actually use them until we include Kokkos_Core.hpp, at which point it's
//  too late to try to change the visibility)
namespace Kokkos {
  class REALM_PUBLIC_API Serial;
  class REALM_PUBLIC_API OpenMP;
  class REALM_PUBLIC_API Cuda;
};

#include <Kokkos_Core.hpp>

#include <stdlib.h>

namespace Realm {

  Logger log_kokkos("kokkos");

  namespace KokkosInterop {

    bool is_kokkos_cuda_enabled(void)
    {
#ifdef KOKKOS_ENABLE_CUDA
      return true;
#else
      return false;
#endif
    }

    bool is_kokkos_openmp_enabled(void)
    {
#ifdef KOKKOS_ENABLE_OPENMP
      return true;
#else
      return false;
#endif
    }

    class KokkosInternalTask : public InternalTask {
    public:
      KokkosInternalTask()
	: done(false), condvar(mutex) {}

      void mark_done()
      {
	AutoLock<> al(mutex);
	done = true;
	condvar.broadcast();
      }

      void wait_done()
      {
	AutoLock<> al(mutex);
	while(!done) condvar.wait();
      }

      bool done;
      Mutex mutex;
      CondVar condvar;
    };

#ifdef KOKKOS_ENABLE_OPENMP
    std::vector<ProcessorImpl *> kokkos_omp_procs;

    class KokkosOpenMPInitializer : public KokkosInternalTask {
    public:
      virtual void execute_on_processor(Processor p)
      {
	log_kokkos.info() << "doing openmp init on proc " << p;
	int thread_count = -1; // todo - get from proc
	Kokkos::OpenMP::impl_initialize(thread_count);
	mark_done();
      }
    };

    class KokkosOpenMPFinalizer : public KokkosInternalTask {
    public:
      virtual void execute_on_processor(Processor p)
      {
	log_kokkos.info() << "doing openmp finalize on proc " << p;
	Kokkos::OpenMP::impl_finalize();
	mark_done();
      }
    };
#endif

#ifdef KOKKOS_ENABLE_CUDA
    std::vector<ProcessorImpl *> kokkos_cuda_procs;

    Mutex cuda_instance_map_mutex;
    std::map<std::pair<Processor, cudaStream_t>, Kokkos::Cuda *> cuda_instance_map;

    class KokkosCudaInitializer : public KokkosInternalTask {
    public:
      virtual void execute_on_processor(Processor p)
      {
	log_kokkos.info() << "doing cuda init on proc " << p;

	ProcessorImpl *impl = get_runtime()->get_processor_impl(p);
	assert(impl->kind == Processor::TOC_PROC);
	Cuda::GPUProcessor *gpu = checked_cast<Cuda::GPUProcessor *>(impl);

	int cuda_device_id = gpu->gpu->info->index;
	int num_instances = 1; // unused in kokkos?

	Kokkos::Cuda::impl_initialize(Kokkos::Cuda::SelectDevice(cuda_device_id),
				      num_instances);
	{
	  // some init is deferred until an instance is created
	  Kokkos::Cuda dummy;
	}
	mark_done();
      }
    };

    class KokkosCudaFinalizer : public KokkosInternalTask {
    public:
      virtual void execute_on_processor(Processor p)
      {
	log_kokkos.info() << "doing cuda finalize on proc " << p;

	// delete all the cuda instances from this proc that we've cached
	for(std::map<std::pair<Processor, cudaStream_t>, Kokkos::Cuda *>::iterator it = cuda_instance_map.begin();
	    it != cuda_instance_map.end();
	    ++it)
	  if(it->first.first == p)
	    delete it->second;

	Kokkos::Cuda::impl_finalize();
	mark_done();
      }
    };
#endif

    void kokkos_initialize(const std::vector<ProcessorImpl *>& local_procs)
    {
      // use Kokkos::Impl::{pre,post}_initialize to allow us to do our own
      //  execution space initialization
      Kokkos::InitArguments kokkos_init_args;
      log_kokkos.info() << "doing general pre-initialization";
      Kokkos::Impl::pre_initialize(kokkos_init_args);

#ifdef KOKKOS_ENABLE_SERIAL
      // nothing thread-specific for serial execution space, so just call it
      //  here
      Kokkos::Serial::impl_initialize();
#endif

#ifdef KOKKOS_ENABLE_OPENMP
      // need to initialize the Kokkos openmp execution space...
#ifdef REALM_USE_OPENMP
      // ... from an openmp proc
      {
	// if we're providing openmp goodness, set environment variable to shut
	//  off some kokkos warnings that don't mean anything
	setenv("OMP_PROC_BIND", "false", 0 /*!overwrite*/);

	size_t count = 0;
	for(std::vector<ProcessorImpl *>::const_iterator it = local_procs.begin();
	    it != local_procs.end();
	    ++it)
	  if((*it)->kind == Processor::OMP_PROC) {
	    count++;
	    if(count > 1) continue; // we'll complain below
	    KokkosOpenMPInitializer ompinit;
	    (*it)->add_internal_task(&ompinit);
	    ompinit.wait_done();
	    kokkos_omp_procs.push_back(*it);
	  }
	if(count != 1) {
	  log_kokkos.fatal() << "Kokkos OpenMP support requires exactly 1 omp proc (found " << count << ") - suggest -ll:ocpu 1 -ll:onuma 0";
	  abort();
	}
      }
#else
      // ... from normal CPU procs since we don't have anything better
      {
	size_t count = 0;
	for(std::vector<ProcessorImpl *>::const_iterator it = local_procs.begin();
	    it != local_procs.end();
	    ++it)
	  if((*it)->kind == Processor::LOC_PROC) {
	    count++;
	    if(count > 1) continue; // we'll complain below
	    KokkosOpenMPInitializer ompinit;
	    (*it)->add_internal_task(&ompinit);
	    ompinit.wait_done();
	    kokkos_omp_procs.push_back(*it);
	  }
	if(count != 1) {
	  log_kokkos.fatal() << "Kokkos OpenMP support without realm OpenMP requires exactly 1 cpu proc (found " << count << ") - suggest -ll:cpu 1";
	  abort();
	}
      }
#endif
#endif

#ifdef KOKKOS_ENABLE_CUDA
      {
	size_t count = 0;
	for(std::vector<ProcessorImpl *>::const_iterator it = local_procs.begin();
	    it != local_procs.end();
	    ++it)
	  if((*it)->kind == Processor::TOC_PROC) {
	    count++;
	    if(count > 1) continue; // we'll complain below
	    KokkosCudaInitializer cudainit;
	    (*it)->add_internal_task(&cudainit);
	    cudainit.wait_done();
	    kokkos_cuda_procs.push_back(*it);
	  }
	if(count != 1) {
	  log_kokkos.fatal() << "Kokkos Cuda support requires exactly 1 gpu proc (found " << count << ") - suggest -ll:gpu 1";
	  abort();
	}
      }
#endif

      // TODO: warn if Kokkos has other execution spaces enabled that we're not
      //  willing/able to initialize?

      log_kokkos.info() << "doing general post-initialization";
      Kokkos::Impl::post_initialize(kokkos_init_args);
    }

    void kokkos_finalize(const std::vector<ProcessorImpl *>& local_procs)
    {
      // per processor finalization on the correct threads
#ifdef KOKKOS_ENABLE_OPENMP
      for(std::vector<ProcessorImpl *>::const_iterator it = kokkos_omp_procs.begin();
	  it != kokkos_omp_procs.end();
	  ++it)
	{
	  KokkosOpenMPFinalizer ompfinal;
	  (*it)->add_internal_task(&ompfinal);
	  ompfinal.wait_done();
	}
#endif

#ifdef KOKKOS_ENABLE_CUDA
      for(std::vector<ProcessorImpl *>::const_iterator it = kokkos_cuda_procs.begin();
	  it != kokkos_cuda_procs.end();
	  ++it)
	{
	  KokkosCudaFinalizer cudafinal;
	  (*it)->add_internal_task(&cudafinal);
	  cudafinal.wait_done();
	}
#endif

      log_kokkos.info() << "doing general finalization";
      Kokkos::finalize();
    }

  };

  // execution space instance conversions from processor.h
#ifdef KOKKOS_ENABLE_SERIAL
  template <>
  Processor::KokkosExecInstance::operator Kokkos::Serial() const
  {
    return Kokkos::Serial();
  }
#endif

#ifdef KOKKOS_ENABLE_OPENMP
  template <>
  Processor::KokkosExecInstance::operator Kokkos::OpenMP() const
  {
    return Kokkos::OpenMP();
  }
#endif

#ifdef KOKKOS_ENABLE_CUDA
  template <>
  Processor::KokkosExecInstance::operator Kokkos::Cuda() const
  {
#ifdef REALM_USE_CUDA
    ProcessorImpl *impl = get_runtime()->get_processor_impl(p);
    assert(impl->kind == Processor::TOC_PROC);
    Cuda::GPUProcessor *gpu = checked_cast<Cuda::GPUProcessor *>(impl);
    cudaStream_t stream = gpu->gpu->get_null_task_stream()->get_stream();
    log_kokkos.info() << "handing back stream " << stream;
    Kokkos::Cuda *inst = 0;
    {
      AutoLock<> al(KokkosInterop::cuda_instance_map_mutex);
      std::pair<Processor, cudaStream_t> key(p, stream);
      std::map<std::pair<Processor, cudaStream_t>, Kokkos::Cuda *>::iterator it = KokkosInterop::cuda_instance_map.find(key);
      if(it != KokkosInterop::cuda_instance_map.end()) {
	inst = it->second;
      } else {
	// creating a Kokkos::Cuda instance does some blocking calls, but we're
	//  not re-entrant here, so enable the scheduler lock
	Processor::enable_scheduler_lock();
	inst = new Kokkos::Cuda(stream);
	Processor::disable_scheduler_lock();
	KokkosInterop::cuda_instance_map[key] = inst;
      }
    }
    return *inst;
#else
    // we're oblivious to the application's use of CUDA
    return Kokkos::Cuda();
#endif
  }
#endif

};
<|endoftext|>


<commit_before>#pragma once

#include <atomic>
#include <memory_resource>
#include <string>
#include <vector>

#include <glm/glm.hpp>

namespace nova::renderer {
    struct FullVertex {
        glm::vec3 position;          // 12 bytes
        glm::vec3 normal;            // 12 bytes
        glm::vec3 tangent;           // 12 bytes
        glm::u16vec2 main_uv;        // 4 bytes
        glm::u8vec2 secondary_uv;    // 2 bytes
        uint32_t virtual_texture_id; // 4 bytes
        glm::vec4 additional_stuff;  // 16 bytes
    };

    static_assert(sizeof(FullVertex) % 16 == 0, "full_vertex struct is not aligned to 16 bytes!");

    /*!
     * \brief All the data needed to make a single mesh
     *
     * Meshes all have the same data. Chunks need all the mesh data, and they're most of the world. Entities, GUI,
     * particles, etc will probably have FAR fewer vertices than chunks, meaning that there's not a huge savings by
     * making them use special vertex formats
     */
    struct MeshData {
        std::pmr::vector<FullVertex> vertex_data;
        std::pmr::vector<uint32_t> indices;
    };

    using MeshId = uint64_t;

    struct StaticMeshRenderableUpdateData {
        MeshId mesh;
    };

    struct StaticMeshRenderableData : StaticMeshRenderableUpdateData {
        glm::vec3 initial_position = {};
        glm::vec3 initial_rotation = {};
        glm::vec3 initial_scale = glm::vec3(1);

        bool is_static = true;
    };

    using RenderableId = uint64_t;

    struct RenderableMetadata {
        RenderableId id = 0;

        std::pmr::vector<std::string> passes;
    };

    struct RenderCommand {
        RenderableId id = 0;

        bool is_visible = true;

        glm::mat4 model_matrix = glm::mat4(1);
    };

    struct StaticMeshRenderCommand : RenderCommand {};

    StaticMeshRenderCommand make_render_command(const StaticMeshRenderableData& data, RenderableId id);
} // namespace nova::renderer
<commit_msg>[renderables] Restore used variable<commit_after>#pragma once

#include <atomic>
#include <memory_resource>
#include <string>
#include <vector>

#include <glm/glm.hpp>

namespace nova::renderer {
    struct FullVertex {
        glm::vec3 position;          // 12 bytes
        glm::vec3 normal;            // 12 bytes
        glm::vec3 tangent;           // 12 bytes
        glm::u16vec2 main_uv;        // 4 bytes
        glm::u8vec2 secondary_uv;    // 2 bytes
        uint32_t virtual_texture_id; // 4 bytes
        glm::vec4 additional_stuff;  // 16 bytes
    };

    static_assert(sizeof(FullVertex) % 16 == 0, "full_vertex struct is not aligned to 16 bytes!");

    /*!
     * \brief All the data needed to make a single mesh
     *
     * Meshes all have the same data. Chunks need all the mesh data, and they're most of the world. Entities, GUI,
     * particles, etc will probably have FAR fewer vertices than chunks, meaning that there's not a huge savings by
     * making them use special vertex formats
     */
    struct MeshData {
        std::pmr::vector<FullVertex> vertex_data;
        std::pmr::vector<uint32_t> indices;
    };

    using MeshId = uint64_t;

    struct StaticMeshRenderableUpdateData {
        MeshId mesh;
    };

    struct StaticMeshRenderableData : StaticMeshRenderableUpdateData {
        glm::vec3 initial_position = {};
        glm::vec3 initial_rotation = {};
        glm::vec3 initial_scale = glm::vec3(1);

        bool is_static = true;
    };

    using RenderableId = uint64_t;

    static std::atomic<RenderableId> next_renderable_id;

    struct RenderableMetadata {
        RenderableId id = 0;

        std::pmr::vector<std::string> passes;
    };

    struct RenderCommand {
        RenderableId id = 0;

        bool is_visible = true;

        glm::mat4 model_matrix = glm::mat4(1);
    };

    struct StaticMeshRenderCommand : RenderCommand {};

    StaticMeshRenderCommand make_render_command(const StaticMeshRenderableData& data, RenderableId id);
} // namespace nova::renderer
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS dr34 (1.14.46); FILE MERGED 2005/02/24 20:13:16 dr 1.14.46.2: RESYNC: (1.14-1.15); FILE MERGED 2005/02/24 19:01:07 dr 1.14.46.1: #i42572# chart import changes<commit_after><|endoftext|>


<commit_before><commit_msg>still no SetUpdateMode in ScCellEditSource::GetTextForwarder<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2016, Tom Honermann
//
// This file is distributed under the MIT License. See the accompanying file
// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms
// and conditions.

#ifndef TEXT_VIEW_CONCEPTS_HPP // {
#define TEXT_VIEW_CONCEPTS_HPP

#include <origin/core/traits.hpp>
#include <origin/algorithm/concepts.hpp>
#include <origin/range/range.hpp>
#include <text_view_detail/traits.hpp>

namespace std {
namespace experimental {
inline namespace text {

namespace text_detail {
template<typename T, T t1, T t2>
concept bool Same_value() {
    return t1 == t2;
}
} // text_detail namespace

/*
 * Code unit concept
 */
template<typename T>
concept bool Code_unit() {
    return origin::Integral_type<T>()
        && (origin::Unsigned_type<T>()
            || origin::Same<T, origin::Remove_cv<char>>()
            || origin::Same<T, origin::Remove_cv<wchar_t>>());
}

/*
 * Code point concept
 */
template<typename T>
concept bool Code_point() {
    return origin::Integral_type<T>()
        && (origin::Unsigned_type<T>()
            || origin::Same<T, origin::Remove_cv<char>>()
            || origin::Same<T, origin::Remove_cv<wchar_t>>());
}

/*
 * Character set concept
 */
template<typename T>
concept bool Character_set() {
    return requires () {
               typename T::code_point_type;
               { T::get_name() } noexcept -> const char *;
           }
        && Code_point<typename T::code_point_type>();
}

/*
 * Character concept
 */
template<typename T>
concept bool Character() {
    return Character_set<character_set_type_of<T>>()
        && origin::Regular<T>()
        && origin::Copy_assignable<T>()
        && requires (T t, code_point_type_of<character_set_type_of<T>> cp) {
               t.set_code_point(cp);
               { t.get_code_point() } -> code_point_type_of<character_set_type_of<T>>;
               { t.get_character_set_id() } -> character_set_id;
           };
}

/*
 * Code unit iterator concept
 */
template<typename T>
concept bool Code_unit_iterator() {
    return origin::Iterator<T>()
        && Code_unit<origin::Value_type<T>>();
}

/*
 * Text encoding state concept
 * These requirements are intended to match the char_traits<T>::state_type
 * requirements described in C++11 [char.traits.typedefs] 21.2.2p4.
 */
template<typename T>
concept bool Text_encoding_state() {
    return origin::Default_constructible<T>()
        && origin::Copy_constructible<T>()
        && origin::Copy_assignable<T>();
}

/*
 * Text encoding state transition concept
 */
template<typename T>
concept bool Text_encoding_state_transition() {
    return origin::Default_constructible<T>()
        && origin::Copy_constructible<T>()
        && origin::Copy_assignable<T>();
}

/*
 * Text encoding concept
 */
template<typename T>
concept bool Text_encoding() {
    return requires () {
               typename T::state_type;
               typename T::state_transition_type;
               typename T::code_unit_type;
               typename T::character_type;
               { T::min_code_units } noexcept -> int;
               { T::max_code_units } noexcept -> int;
           }
        && Text_encoding_state<typename T::state_type>()
        && Text_encoding_state_transition<typename T::state_transition_type>()
        && Code_unit<typename T::code_unit_type>()
        && Character<typename T::character_type>()
        && requires () {
               { T::initial_state() }
                   -> const typename T::state_type&;
           };
}

/*
 * Text encoder concept
 */
template<typename T, typename CUIT>
concept bool Text_encoder() {
    return Text_encoding<T>()
        && origin::Output_iterator<CUIT, typename T::code_unit_type>()
        && requires (
               typename T::state_type &state,
               CUIT &out,
               typename T::state_transition_type stt,
               int &encoded_code_units)
           {
               T::encode_state_transition(state, out, stt, encoded_code_units);
           }
        && requires (
               typename T::state_type &state,
               CUIT &out,
               typename T::character_type c,
               int &encoded_code_units)
           {
               T::encode(state, out, c, encoded_code_units);
           };
}

/*
 * Text decoder concept
 */
template<typename T, typename CUIT>
concept bool Text_decoder() {
    return Text_encoding<T>()
        && origin::Input_iterator<CUIT>()
        && origin::Convertible<origin::Value_type<CUIT>,
                               typename T::code_unit_type>()
        && requires (
               typename T::state_type &state,
               CUIT &in_next,
               CUIT in_end,
               typename T::character_type &c,
               int &decoded_code_units)
           {
               { T::decode(state, in_next, in_end, c, decoded_code_units) } -> bool;
           };
}

/*
 * Text forward decoder concept
 */
template<typename T, typename CUIT>
concept bool Text_forward_decoder() {
    return Text_decoder<T, CUIT>()
        && origin::Forward_iterator<CUIT>();
}

/*
 * Text bidirectional decoder concept
 */
template<typename T, typename CUIT>
concept bool Text_bidirectional_decoder() {
    return Text_forward_decoder<T, CUIT>()
        && origin::Bidirectional_iterator<CUIT>()
        && requires (
               typename T::state_type &state,
               CUIT &in_next,
               CUIT in_end,
               typename T::character_type &c,
               int &decoded_code_units)
           {
               { T::rdecode(state, in_next, in_end, c, decoded_code_units) } -> bool;
           };
}

/*
 * Text random access decoder concept
 */
template<typename T, typename CUIT>
concept bool Text_random_access_decoder() {
    return Text_bidirectional_decoder<T, CUIT>()
        && origin::Random_access_iterator<CUIT>()
        && text_detail::Same_value<int, T::min_code_units, T::max_code_units>()
        && origin::Empty_type<typename T::state_type>();
}

/*
 * Text iterator concept
 */
template<typename T>
concept bool Text_iterator() {
    return requires () {
               typename T::encoding_type;
               typename T::state_type;
           }
        && Text_encoding<typename T::encoding_type>()
        && Text_encoding_state<typename T::state_type>()
        && origin::Iterator<T>()
        && Character<origin::Value_type<T>>()
        && requires (T t, const T ct) {
               { t.state() } noexcept
                   -> typename T::encoding_type::state_type&;
               { ct.state() } noexcept
                   -> const typename T::encoding_type::state_type&;
           };
}

/*
 * Text sentinel concept
 */
template<typename T, typename I>
concept bool Text_sentinel() {
    return origin::Sentinel<T, I>()
        && Text_iterator<I>();
}

/*
 * Text view concept
 */
template<typename T>
concept bool Text_view() {
    return requires () {
               typename T::encoding_type;
               typename T::range_type;
               typename T::state_type;
               typename T::code_unit_iterator;
           }
        && Text_encoding<typename T::encoding_type>()
        && origin::Input_range<typename T::range_type>()
        && Text_encoding_state<typename T::state_type>()
        && origin::Iterator<typename T::code_unit_iterator>()
        && origin::Input_range<T>()
        && Text_iterator<origin::Iterator_type<T>>()
        && requires (T t, const T ct) {
               { t.base() } noexcept
                   -> typename T::range_type&;
               { ct.base() } noexcept
                   -> const typename T::range_type&;
               { t.initial_state() } noexcept
                   -> typename T::state_type&;
               { ct.initial_state() } noexcept
                   -> const typename T::state_type&;
           };
}

} // inline namespace text
} // namespace experimental
} // namespace std

#endif // } TEXT_VIEW_CONCEPTS_HPP
<commit_msg>Changed the definitions of a few concepts to use Copyable instead of Copy_assignable.<commit_after>// Copyright (c) 2016, Tom Honermann
//
// This file is distributed under the MIT License. See the accompanying file
// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms
// and conditions.

#ifndef TEXT_VIEW_CONCEPTS_HPP // {
#define TEXT_VIEW_CONCEPTS_HPP

#include <origin/core/traits.hpp>
#include <origin/algorithm/concepts.hpp>
#include <origin/range/range.hpp>
#include <text_view_detail/traits.hpp>

namespace std {
namespace experimental {
inline namespace text {

namespace text_detail {
template<typename T, T t1, T t2>
concept bool Same_value() {
    return t1 == t2;
}
} // text_detail namespace

/*
 * Code unit concept
 */
template<typename T>
concept bool Code_unit() {
    return origin::Integral_type<T>()
        && (origin::Unsigned_type<T>()
            || origin::Same<T, origin::Remove_cv<char>>()
            || origin::Same<T, origin::Remove_cv<wchar_t>>());
}

/*
 * Code point concept
 */
template<typename T>
concept bool Code_point() {
    return origin::Integral_type<T>()
        && (origin::Unsigned_type<T>()
            || origin::Same<T, origin::Remove_cv<char>>()
            || origin::Same<T, origin::Remove_cv<wchar_t>>());
}

/*
 * Character set concept
 */
template<typename T>
concept bool Character_set() {
    return requires () {
               typename T::code_point_type;
               { T::get_name() } noexcept -> const char *;
           }
        && Code_point<typename T::code_point_type>();
}

/*
 * Character concept
 */
template<typename T>
concept bool Character() {
    return Character_set<character_set_type_of<T>>()
        && origin::Regular<T>()
        && origin::Copyable<T>()
        && requires (T t, code_point_type_of<character_set_type_of<T>> cp) {
               t.set_code_point(cp);
               { t.get_code_point() } -> code_point_type_of<character_set_type_of<T>>;
               { t.get_character_set_id() } -> character_set_id;
           };
}

/*
 * Code unit iterator concept
 */
template<typename T>
concept bool Code_unit_iterator() {
    return origin::Iterator<T>()
        && Code_unit<origin::Value_type<T>>();
}

/*
 * Text encoding state concept
 * These requirements are intended to match the char_traits<T>::state_type
 * requirements described in C++11 [char.traits.typedefs] 21.2.2p4.
 */
template<typename T>
concept bool Text_encoding_state() {
    return origin::Default_constructible<T>()
        && origin::Copyable<T>();
}

/*
 * Text encoding state transition concept
 */
template<typename T>
concept bool Text_encoding_state_transition() {
    return origin::Default_constructible<T>()
        && origin::Copyable<T>();
}

/*
 * Text encoding concept
 */
template<typename T>
concept bool Text_encoding() {
    return requires () {
               typename T::state_type;
               typename T::state_transition_type;
               typename T::code_unit_type;
               typename T::character_type;
               { T::min_code_units } noexcept -> int;
               { T::max_code_units } noexcept -> int;
           }
        && Text_encoding_state<typename T::state_type>()
        && Text_encoding_state_transition<typename T::state_transition_type>()
        && Code_unit<typename T::code_unit_type>()
        && Character<typename T::character_type>()
        && requires () {
               { T::initial_state() }
                   -> const typename T::state_type&;
           };
}

/*
 * Text encoder concept
 */
template<typename T, typename CUIT>
concept bool Text_encoder() {
    return Text_encoding<T>()
        && origin::Output_iterator<CUIT, typename T::code_unit_type>()
        && requires (
               typename T::state_type &state,
               CUIT &out,
               typename T::state_transition_type stt,
               int &encoded_code_units)
           {
               T::encode_state_transition(state, out, stt, encoded_code_units);
           }
        && requires (
               typename T::state_type &state,
               CUIT &out,
               typename T::character_type c,
               int &encoded_code_units)
           {
               T::encode(state, out, c, encoded_code_units);
           };
}

/*
 * Text decoder concept
 */
template<typename T, typename CUIT>
concept bool Text_decoder() {
    return Text_encoding<T>()
        && origin::Input_iterator<CUIT>()
        && origin::Convertible<origin::Value_type<CUIT>,
                               typename T::code_unit_type>()
        && requires (
               typename T::state_type &state,
               CUIT &in_next,
               CUIT in_end,
               typename T::character_type &c,
               int &decoded_code_units)
           {
               { T::decode(state, in_next, in_end, c, decoded_code_units) } -> bool;
           };
}

/*
 * Text forward decoder concept
 */
template<typename T, typename CUIT>
concept bool Text_forward_decoder() {
    return Text_decoder<T, CUIT>()
        && origin::Forward_iterator<CUIT>();
}

/*
 * Text bidirectional decoder concept
 */
template<typename T, typename CUIT>
concept bool Text_bidirectional_decoder() {
    return Text_forward_decoder<T, CUIT>()
        && origin::Bidirectional_iterator<CUIT>()
        && requires (
               typename T::state_type &state,
               CUIT &in_next,
               CUIT in_end,
               typename T::character_type &c,
               int &decoded_code_units)
           {
               { T::rdecode(state, in_next, in_end, c, decoded_code_units) } -> bool;
           };
}

/*
 * Text random access decoder concept
 */
template<typename T, typename CUIT>
concept bool Text_random_access_decoder() {
    return Text_bidirectional_decoder<T, CUIT>()
        && origin::Random_access_iterator<CUIT>()
        && text_detail::Same_value<int, T::min_code_units, T::max_code_units>()
        && origin::Empty_type<typename T::state_type>();
}

/*
 * Text iterator concept
 */
template<typename T>
concept bool Text_iterator() {
    return requires () {
               typename T::encoding_type;
               typename T::state_type;
           }
        && Text_encoding<typename T::encoding_type>()
        && Text_encoding_state<typename T::state_type>()
        && origin::Iterator<T>()
        && Character<origin::Value_type<T>>()
        && requires (T t, const T ct) {
               { t.state() } noexcept
                   -> typename T::encoding_type::state_type&;
               { ct.state() } noexcept
                   -> const typename T::encoding_type::state_type&;
           };
}

/*
 * Text sentinel concept
 */
template<typename T, typename I>
concept bool Text_sentinel() {
    return origin::Sentinel<T, I>()
        && Text_iterator<I>();
}

/*
 * Text view concept
 */
template<typename T>
concept bool Text_view() {
    return requires () {
               typename T::encoding_type;
               typename T::range_type;
               typename T::state_type;
               typename T::code_unit_iterator;
           }
        && Text_encoding<typename T::encoding_type>()
        && origin::Input_range<typename T::range_type>()
        && Text_encoding_state<typename T::state_type>()
        && origin::Iterator<typename T::code_unit_iterator>()
        && origin::Input_range<T>()
        && Text_iterator<origin::Iterator_type<T>>()
        && requires (T t, const T ct) {
               { t.base() } noexcept
                   -> typename T::range_type&;
               { ct.base() } noexcept
                   -> const typename T::range_type&;
               { t.initial_state() } noexcept
                   -> typename T::state_type&;
               { ct.initial_state() } noexcept
                   -> const typename T::state_type&;
           };
}

} // inline namespace text
} // namespace experimental
} // namespace std

#endif // } TEXT_VIEW_CONCEPTS_HPP
<|endoftext|>