<commit_before>#include <chrono>
#include <cstdio>
#include <vector>
#include <memory>
#include <algorithm>
#include <poll.h>

#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>

#include <kms++/kms++.h>
#include <kms++util/kms++util.h>
#include "cube-egl.h"
#include "cube-gles2.h"

using namespace kms;
using namespace std;

static int s_flip_pending;
static bool s_need_exit;

static bool s_support_planes;

class GbmDevice
{
public:
	GbmDevice(Card& card)
	{
		m_dev = gbm_create_device(card.fd());
		FAIL_IF(!m_dev, "failed to create gbm device");
	}

	~GbmDevice()
	{
		gbm_device_destroy(m_dev);
	}

	GbmDevice(const GbmDevice& other) = delete;
	GbmDevice& operator=(const GbmDevice& other) = delete;

	struct gbm_device* handle() const { return m_dev; }

private:
	struct gbm_device* m_dev;
};

class GbmSurface
{
public:
	GbmSurface(GbmDevice& gdev, int width, int height)
	{
		m_surface = gbm_surface_create(gdev.handle(), width, height,
					       GBM_FORMAT_XRGB8888,
					       GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
		FAIL_IF(!m_surface, "failed to create gbm surface");
	}

	~GbmSurface()
	{
		gbm_surface_destroy(m_surface);
	}

	GbmSurface(const GbmSurface& other) = delete;
	GbmSurface& operator=(const GbmSurface& other) = delete;

	bool has_free()
	{
		return gbm_surface_has_free_buffers(m_surface);
	}

	gbm_bo* lock_front_buffer()
	{
		return gbm_surface_lock_front_buffer(m_surface);
	}

	void release_buffer(gbm_bo *bo)
	{
		gbm_surface_release_buffer(m_surface, bo);
	}

	struct gbm_surface* handle() const { return m_surface; }

private:
	struct gbm_surface* m_surface;
};

class GbmEglSurface
{
public:
	GbmEglSurface(Card& card, GbmDevice& gdev, const EglState& egl, int width, int height)
		: card(card), egl(egl), m_width(width), m_height(height),
		  bo_prev(0), bo_next(0)
	{
		gsurface = unique_ptr<GbmSurface>(new GbmSurface(gdev, width, height));
		esurface = eglCreateWindowSurface(egl.display(), egl.config(), gsurface->handle(), NULL);
		FAIL_IF(esurface == EGL_NO_SURFACE, "failed to create egl surface");
	}

	~GbmEglSurface()
	{
		if (bo_next)
			gsurface->release_buffer(bo_next);
		eglDestroySurface(egl.display(), esurface);
	}

	void make_current()
	{
		FAIL_IF(!gsurface->has_free(), "No free buffers");

		eglMakeCurrent(egl.display(), esurface, esurface, egl.context());
	}

	void swap_buffers()
	{
		eglSwapBuffers(egl.display(), esurface);
	}

	static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
	{
		auto fb = reinterpret_cast<Framebuffer*>(data);
		delete fb;
	}

	static Framebuffer* drm_fb_get_from_bo(struct gbm_bo *bo, Card& card)
	{
		auto fb = reinterpret_cast<Framebuffer*>(gbm_bo_get_user_data(bo));
		if (fb)
			return fb;

		uint32_t width = gbm_bo_get_width(bo);
		uint32_t height = gbm_bo_get_height(bo);
		uint32_t stride = gbm_bo_get_stride(bo);
		uint32_t handle = gbm_bo_get_handle(bo).u32;

		fb = new ExtFramebuffer(card, width, height, 24, 32, stride, handle);

		gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);

		return fb;
	}

	Framebuffer* lock_next()
	{
		bo_prev = bo_next;
		bo_next = gsurface->lock_front_buffer();
		FAIL_IF(!bo_next, "could not lock gbm buffer");
		return drm_fb_get_from_bo(bo_next, card);
	}

	void free_prev()
	{
		if (bo_prev) {
			gsurface->release_buffer(bo_prev);
			bo_prev = 0;
		}
	}

	uint32_t width() const { return m_width; }
	uint32_t height() const { return m_height; }

private:
	Card& card;
	const EglState& egl;

	unique_ptr<GbmSurface> gsurface;
	EGLSurface esurface;

	int m_width;
	int m_height;

	struct gbm_bo* bo_prev;
	struct gbm_bo* bo_next;
};

class OutputHandler : private PageFlipHandlerBase
{
public:
	OutputHandler(Card& card, GbmDevice& gdev, const EglState& egl, Connector* connector, Crtc* crtc, Videomode& mode, Plane* plane, float rotation_mult)
		: m_frame_num(0), m_connector(connector), m_crtc(crtc), m_plane(plane), m_mode(mode),
		  m_rotation_mult(rotation_mult)
	{
		m_surface1 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, mode.hdisplay, mode.vdisplay));
		m_scene1 = unique_ptr<GlScene>(new GlScene());
		m_scene1->set_viewport(m_surface1->width(), m_surface1->height());

		if (m_plane) {
			m_surface2 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, 400, 400));
			m_scene2 = unique_ptr<GlScene>(new GlScene());
			m_scene2->set_viewport(m_surface2->width(), m_surface2->height());
		}
	}

	OutputHandler(const OutputHandler& other) = delete;
	OutputHandler& operator=(const OutputHandler& other) = delete;

	void setup()
	{
		int ret;

		m_surface1->make_current();
		m_surface1->swap_buffers();
		Framebuffer* fb = m_surface1->lock_next();

		Framebuffer* planefb = 0;

		if (m_plane) {
			m_surface2->make_current();
			m_surface2->swap_buffers();
			planefb = m_surface2->lock_next();
		}

		ret = m_crtc->set_mode(m_connector, *fb, m_mode);
		FAIL_IF(ret, "failed to set mode");

		if (m_crtc->card().has_atomic()) {
			Plane* root_plane = 0;
			for (Plane* p : m_crtc->get_possible_planes()) {
				if (p->crtc_id() == m_crtc->id()) {
					root_plane = p;
					break;
				}
			}

			FAIL_IF(!root_plane, "No primary plane for crtc %d", m_crtc->id());

			m_root_plane = root_plane;
		}

		if (m_plane) {
			ret = m_crtc->set_plane(m_plane, *planefb,
						0, 0, planefb->width(), planefb->height(),
						0, 0, planefb->width(), planefb->height());
			FAIL_IF(ret, "failed to set plane");
		}
	}

	void start_flipping()
	{
		m_t1 = chrono::steady_clock::now();
		queue_next();
	}

private:
	void handle_page_flip(uint32_t frame, double time)
	{
		++m_frame_num;

		if (m_frame_num  % 100 == 0) {
			auto t2 = chrono::steady_clock::now();
			chrono::duration<float> fsec = t2 - m_t1;
			printf("fps: %f\n", 100.0 / fsec.count());
			m_t1 = t2;
		}

		s_flip_pending--;

		m_surface1->free_prev();
		if (m_plane)
			m_surface2->free_prev();

		if (s_need_exit)
			return;

		queue_next();
	}

	void queue_next()
	{
		m_surface1->make_current();
		m_scene1->draw(m_frame_num * m_rotation_mult);
		m_surface1->swap_buffers();
		Framebuffer* fb = m_surface1->lock_next();

		Framebuffer* planefb = 0;

		if (m_plane) {
			m_surface2->make_current();
			m_scene2->draw(m_frame_num * m_rotation_mult * 2);
			m_surface2->swap_buffers();
			planefb = m_surface2->lock_next();
		}

		if (m_crtc->card().has_atomic()) {
			int r;

			AtomicReq req(m_crtc->card());

			req.add(m_root_plane, "FB_ID", fb->id());
			if (m_plane)
				req.add(m_plane, "FB_ID", planefb->id());

			r = req.test();
			FAIL_IF(r, "atomic test failed");

			r = req.commit(this);
			FAIL_IF(r, "atomic commit failed");
		} else {
			int ret;

			ret = m_crtc->page_flip(*fb, this);
			FAIL_IF(ret, "failed to queue page flip");

			if (m_plane) {
				ret = m_crtc->set_plane(m_plane, *planefb,
							0, 0, planefb->width(), planefb->height(),
							0, 0, planefb->width(), planefb->height());
				FAIL_IF(ret, "failed to set plane");
			}
		}

		s_flip_pending++;
	}

	int m_frame_num;
	chrono::steady_clock::time_point m_t1;

	Connector* m_connector;
	Crtc* m_crtc;
	Plane* m_plane;
	Videomode m_mode;
	Plane* m_root_plane;

	unique_ptr<GbmEglSurface> m_surface1;
	unique_ptr<GbmEglSurface> m_surface2;

	unique_ptr<GlScene> m_scene1;
	unique_ptr<GlScene> m_scene2;

	float m_rotation_mult;
};

void main_gbm()
{
	Card card;

	GbmDevice gdev(card);
	EglState egl(gdev.handle());

	vector<unique_ptr<OutputHandler>> outputs;
	vector<Plane*> used_planes;

	float rot_mult = 1;

	for (auto pipe : card.get_connected_pipelines()) {
		auto connector = pipe.connector;
		auto crtc = pipe.crtc;
		auto mode = connector->get_default_mode();

		Plane* plane = 0;

		if (s_support_planes) {
			for (Plane* p : crtc->get_possible_planes()) {
				if (find(used_planes.begin(), used_planes.end(), p) != used_planes.end())
					continue;

				if (p->plane_type() != PlaneType::Overlay)
					continue;

				plane = p;
				break;
			}
		}

		if (plane)
			used_planes.push_back(plane);

		auto out = new OutputHandler(card, gdev, egl, connector, crtc, mode, plane, rot_mult);
		outputs.emplace_back(out);

		rot_mult *= 1.33;
	}

	for (auto& out : outputs)
		out->setup();

	for (auto& out : outputs)
		out->start_flipping();

	struct pollfd fds[2] = { };
	fds[0].fd = 0;
	fds[0].events =  POLLIN;
	fds[1].fd = card.fd();
	fds[1].events =  POLLIN;

	while (!s_need_exit || s_flip_pending) {
		int r = poll(fds, ARRAY_SIZE(fds), -1);
		FAIL_IF(r < 0, "poll error %d", r);

		if (fds[0].revents)
			s_need_exit = true;

		if (fds[1].revents)
			card.call_page_flip_handlers();
	}
}
<commit_msg>kmscube: use drmModeAddFB2 version of ExtFB<commit_after>#include <chrono>
#include <cstdio>
#include <vector>
#include <memory>
#include <algorithm>
#include <poll.h>

#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>

#include <kms++/kms++.h>
#include <kms++util/kms++util.h>
#include "cube-egl.h"
#include "cube-gles2.h"

using namespace kms;
using namespace std;

static int s_flip_pending;
static bool s_need_exit;

static bool s_support_planes;

class GbmDevice
{
public:
	GbmDevice(Card& card)
	{
		m_dev = gbm_create_device(card.fd());
		FAIL_IF(!m_dev, "failed to create gbm device");
	}

	~GbmDevice()
	{
		gbm_device_destroy(m_dev);
	}

	GbmDevice(const GbmDevice& other) = delete;
	GbmDevice& operator=(const GbmDevice& other) = delete;

	struct gbm_device* handle() const { return m_dev; }

private:
	struct gbm_device* m_dev;
};

class GbmSurface
{
public:
	GbmSurface(GbmDevice& gdev, int width, int height)
	{
		m_surface = gbm_surface_create(gdev.handle(), width, height,
					       GBM_FORMAT_XRGB8888,
					       GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
		FAIL_IF(!m_surface, "failed to create gbm surface");
	}

	~GbmSurface()
	{
		gbm_surface_destroy(m_surface);
	}

	GbmSurface(const GbmSurface& other) = delete;
	GbmSurface& operator=(const GbmSurface& other) = delete;

	bool has_free()
	{
		return gbm_surface_has_free_buffers(m_surface);
	}

	gbm_bo* lock_front_buffer()
	{
		return gbm_surface_lock_front_buffer(m_surface);
	}

	void release_buffer(gbm_bo *bo)
	{
		gbm_surface_release_buffer(m_surface, bo);
	}

	struct gbm_surface* handle() const { return m_surface; }

private:
	struct gbm_surface* m_surface;
};

class GbmEglSurface
{
public:
	GbmEglSurface(Card& card, GbmDevice& gdev, const EglState& egl, int width, int height)
		: card(card), egl(egl), m_width(width), m_height(height),
		  bo_prev(0), bo_next(0)
	{
		gsurface = unique_ptr<GbmSurface>(new GbmSurface(gdev, width, height));
		esurface = eglCreateWindowSurface(egl.display(), egl.config(), gsurface->handle(), NULL);
		FAIL_IF(esurface == EGL_NO_SURFACE, "failed to create egl surface");
	}

	~GbmEglSurface()
	{
		if (bo_next)
			gsurface->release_buffer(bo_next);
		eglDestroySurface(egl.display(), esurface);
	}

	void make_current()
	{
		FAIL_IF(!gsurface->has_free(), "No free buffers");

		eglMakeCurrent(egl.display(), esurface, esurface, egl.context());
	}

	void swap_buffers()
	{
		eglSwapBuffers(egl.display(), esurface);
	}

	static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
	{
		auto fb = reinterpret_cast<Framebuffer*>(data);
		delete fb;
	}

	static Framebuffer* drm_fb_get_from_bo(struct gbm_bo *bo, Card& card)
	{
		auto fb = reinterpret_cast<Framebuffer*>(gbm_bo_get_user_data(bo));
		if (fb)
			return fb;

		uint32_t width = gbm_bo_get_width(bo);
		uint32_t height = gbm_bo_get_height(bo);
		uint32_t stride = gbm_bo_get_stride(bo);
		uint32_t handle = gbm_bo_get_handle(bo).u32;
		PixelFormat format = (PixelFormat)gbm_bo_get_format(bo);

		uint32_t handles[4] { handle };
		uint32_t strides[4] { stride };
		uint32_t offsets[4] { 0 };

		fb = new ExtFramebuffer(card, width, height, format, handles, strides, offsets);

		gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);

		return fb;
	}

	Framebuffer* lock_next()
	{
		bo_prev = bo_next;
		bo_next = gsurface->lock_front_buffer();
		FAIL_IF(!bo_next, "could not lock gbm buffer");
		return drm_fb_get_from_bo(bo_next, card);
	}

	void free_prev()
	{
		if (bo_prev) {
			gsurface->release_buffer(bo_prev);
			bo_prev = 0;
		}
	}

	uint32_t width() const { return m_width; }
	uint32_t height() const { return m_height; }

private:
	Card& card;
	const EglState& egl;

	unique_ptr<GbmSurface> gsurface;
	EGLSurface esurface;

	int m_width;
	int m_height;

	struct gbm_bo* bo_prev;
	struct gbm_bo* bo_next;
};

class OutputHandler : private PageFlipHandlerBase
{
public:
	OutputHandler(Card& card, GbmDevice& gdev, const EglState& egl, Connector* connector, Crtc* crtc, Videomode& mode, Plane* plane, float rotation_mult)
		: m_frame_num(0), m_connector(connector), m_crtc(crtc), m_plane(plane), m_mode(mode),
		  m_rotation_mult(rotation_mult)
	{
		m_surface1 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, mode.hdisplay, mode.vdisplay));
		m_scene1 = unique_ptr<GlScene>(new GlScene());
		m_scene1->set_viewport(m_surface1->width(), m_surface1->height());

		if (m_plane) {
			m_surface2 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, 400, 400));
			m_scene2 = unique_ptr<GlScene>(new GlScene());
			m_scene2->set_viewport(m_surface2->width(), m_surface2->height());
		}
	}

	OutputHandler(const OutputHandler& other) = delete;
	OutputHandler& operator=(const OutputHandler& other) = delete;

	void setup()
	{
		int ret;

		m_surface1->make_current();
		m_surface1->swap_buffers();
		Framebuffer* fb = m_surface1->lock_next();

		Framebuffer* planefb = 0;

		if (m_plane) {
			m_surface2->make_current();
			m_surface2->swap_buffers();
			planefb = m_surface2->lock_next();
		}

		ret = m_crtc->set_mode(m_connector, *fb, m_mode);
		FAIL_IF(ret, "failed to set mode");

		if (m_crtc->card().has_atomic()) {
			Plane* root_plane = 0;
			for (Plane* p : m_crtc->get_possible_planes()) {
				if (p->crtc_id() == m_crtc->id()) {
					root_plane = p;
					break;
				}
			}

			FAIL_IF(!root_plane, "No primary plane for crtc %d", m_crtc->id());

			m_root_plane = root_plane;
		}

		if (m_plane) {
			ret = m_crtc->set_plane(m_plane, *planefb,
						0, 0, planefb->width(), planefb->height(),
						0, 0, planefb->width(), planefb->height());
			FAIL_IF(ret, "failed to set plane");
		}
	}

	void start_flipping()
	{
		m_t1 = chrono::steady_clock::now();
		queue_next();
	}

private:
	void handle_page_flip(uint32_t frame, double time)
	{
		++m_frame_num;

		if (m_frame_num  % 100 == 0) {
			auto t2 = chrono::steady_clock::now();
			chrono::duration<float> fsec = t2 - m_t1;
			printf("fps: %f\n", 100.0 / fsec.count());
			m_t1 = t2;
		}

		s_flip_pending--;

		m_surface1->free_prev();
		if (m_plane)
			m_surface2->free_prev();

		if (s_need_exit)
			return;

		queue_next();
	}

	void queue_next()
	{
		m_surface1->make_current();
		m_scene1->draw(m_frame_num * m_rotation_mult);
		m_surface1->swap_buffers();
		Framebuffer* fb = m_surface1->lock_next();

		Framebuffer* planefb = 0;

		if (m_plane) {
			m_surface2->make_current();
			m_scene2->draw(m_frame_num * m_rotation_mult * 2);
			m_surface2->swap_buffers();
			planefb = m_surface2->lock_next();
		}

		if (m_crtc->card().has_atomic()) {
			int r;

			AtomicReq req(m_crtc->card());

			req.add(m_root_plane, "FB_ID", fb->id());
			if (m_plane)
				req.add(m_plane, "FB_ID", planefb->id());

			r = req.test();
			FAIL_IF(r, "atomic test failed");

			r = req.commit(this);
			FAIL_IF(r, "atomic commit failed");
		} else {
			int ret;

			ret = m_crtc->page_flip(*fb, this);
			FAIL_IF(ret, "failed to queue page flip");

			if (m_plane) {
				ret = m_crtc->set_plane(m_plane, *planefb,
							0, 0, planefb->width(), planefb->height(),
							0, 0, planefb->width(), planefb->height());
				FAIL_IF(ret, "failed to set plane");
			}
		}

		s_flip_pending++;
	}

	int m_frame_num;
	chrono::steady_clock::time_point m_t1;

	Connector* m_connector;
	Crtc* m_crtc;
	Plane* m_plane;
	Videomode m_mode;
	Plane* m_root_plane;

	unique_ptr<GbmEglSurface> m_surface1;
	unique_ptr<GbmEglSurface> m_surface2;

	unique_ptr<GlScene> m_scene1;
	unique_ptr<GlScene> m_scene2;

	float m_rotation_mult;
};

void main_gbm()
{
	Card card;

	GbmDevice gdev(card);
	EglState egl(gdev.handle());

	vector<unique_ptr<OutputHandler>> outputs;
	vector<Plane*> used_planes;

	float rot_mult = 1;

	for (auto pipe : card.get_connected_pipelines()) {
		auto connector = pipe.connector;
		auto crtc = pipe.crtc;
		auto mode = connector->get_default_mode();

		Plane* plane = 0;

		if (s_support_planes) {
			for (Plane* p : crtc->get_possible_planes()) {
				if (find(used_planes.begin(), used_planes.end(), p) != used_planes.end())
					continue;

				if (p->plane_type() != PlaneType::Overlay)
					continue;

				plane = p;
				break;
			}
		}

		if (plane)
			used_planes.push_back(plane);

		auto out = new OutputHandler(card, gdev, egl, connector, crtc, mode, plane, rot_mult);
		outputs.emplace_back(out);

		rot_mult *= 1.33;
	}

	for (auto& out : outputs)
		out->setup();

	for (auto& out : outputs)
		out->start_flipping();

	struct pollfd fds[2] = { };
	fds[0].fd = 0;
	fds[0].events =  POLLIN;
	fds[1].fd = card.fd();
	fds[1].events =  POLLIN;

	while (!s_need_exit || s_flip_pending) {
		int r = poll(fds, ARRAY_SIZE(fds), -1);
		FAIL_IF(r < 0, "poll error %d", r);

		if (fds[0].revents)
			s_need_exit = true;

		if (fds[1].revents)
			card.call_page_flip_handlers();
	}
}
<|endoftext|>


<commit_before>// Qubit teleporation circuit simulator
// Source: ./examples/circuits/teleport_qubit.cpp
#include <iostream>

#include "qpp.h"

int main() {
    using namespace qpp;
    idx d = 5; // qudit dimension
    std::cout << ">> Qudit teleportation (d = " << d << ") ";
    std::cout << "quantum circuit simulation\n\n";

    // quantum circuit description with 3 qudits, 2 classical bits, (optional)
    // dimension d = 5 and (optional) name = "qudit teleportation"
    QCircuitDescription tele_qudit{3, 2, d, "qudit teleportation"};
    // set the qubit 0 to a random state
    cmat U = randU(d);
    tele_qudit.gate(U, 0);

    // set the MES between qudits 1 and 2
    tele_qudit.gate(gt.Fd(d), 1);
    tele_qudit.CTRL(gt.Xd(d), 1, 2);

    // perform the Bell measurement between qudits 0 and 1
    tele_qudit.CTRL(adjoint(gt.Xd(d)), 0, 1);
    tele_qudit.gate(adjoint(gt.Fd(d)), 0);

    // perform the measurements
    tele_qudit.measureZ(0, 0);
    tele_qudit.measureZ(1, 1);

    // apply the classical controls
    tele_qudit.cCTRL(adjoint(gt.Xd(d)), 1, 2);
    tele_qudit.cCTRL(gt.Zd(d), 0, 2);

    QCircuit qc_tele_qudit{tele_qudit};
    std::cout << ">> BEGIN CIRCUIT DESCRIPTION\n";
    std::cout << qc_tele_qudit.get_circuit_description() << '\n';
    std::cout << ">> END CIRCUIT DESCRIPTION\n\n";

    // non-verbose run, use qc_teleport_qubit.run(true) for verbose running
    qc_tele_qudit.run();

    // displays the  measurement statistics
    std::cout << ">> BEGIN AFTER RUNNING\n";
    std::cout << qc_tele_qudit << '\n';
    std::cout << ">> END AFTER RUNNING\n\n";

    // verify that the teleportation was successful
    ket psi_initial = U * mket({0}, d);
    ket psi_final = qc_tele_qudit.get_psi();
    std::cout << ">> Teleported state:\n";
    std::cout << disp(psi_final) << '\n';
    std::cout << ">> Norm difference: " << norm(psi_final - psi_initial)
              << '\n';
}
<commit_msg>Update teleport_qudit_circuit.cpp<commit_after>// Qudit teleporation circuit simulator
// Source: ./examples/circuits/teleport_qudit_circuit.cpp
#include <iostream>

#include "qpp.h"

int main() {
    using namespace qpp;
    idx d = 5; // qudit dimension
    std::cout << ">> Qudit teleportation (d = " << d << ") ";
    std::cout << "quantum circuit simulation\n\n";

    // quantum circuit description with 3 qudits, 2 classical bits, (optional)
    // dimension d = 5 and (optional) name = "qudit teleportation"
    QCircuitDescription tele_qudit{3, 2, d, "qudit teleportation"};
    // set the qubit 0 to a random state
    cmat U = randU(d);
    tele_qudit.gate(U, 0);

    // set the MES between qudits 1 and 2
    tele_qudit.gate(gt.Fd(d), 1);
    tele_qudit.CTRL(gt.Xd(d), 1, 2);

    // perform the Bell measurement between qudits 0 and 1
    tele_qudit.CTRL(adjoint(gt.Xd(d)), 0, 1);
    tele_qudit.gate(adjoint(gt.Fd(d)), 0);

    // perform the measurements
    tele_qudit.measureZ(0, 0);
    tele_qudit.measureZ(1, 1);

    // apply the classical controls
    tele_qudit.cCTRL(adjoint(gt.Xd(d)), 1, 2);
    tele_qudit.cCTRL(gt.Zd(d), 0, 2);

    QCircuit qc_tele_qudit{tele_qudit};
    std::cout << ">> BEGIN CIRCUIT DESCRIPTION\n";
    std::cout << qc_tele_qudit.get_circuit_description() << '\n';
    std::cout << ">> END CIRCUIT DESCRIPTION\n\n";

    // non-verbose run, use qc_teleport_qubit.run(true) for verbose running
    qc_tele_qudit.run();

    // displays the  measurement statistics
    std::cout << ">> BEGIN AFTER RUNNING\n";
    std::cout << qc_tele_qudit << '\n';
    std::cout << ">> END AFTER RUNNING\n\n";

    // verify that the teleportation was successful
    ket psi_initial = U * mket({0}, d);
    ket psi_final = qc_tele_qudit.get_psi();
    std::cout << ">> Teleported state:\n";
    std::cout << disp(psi_final) << '\n';
    std::cout << ">> Norm difference: " << norm(psi_final - psi_initial)
              << '\n';
}
<|endoftext|>


<commit_before>#include <libtorrent/enum_net.hpp>
#include <libtorrent/socket.hpp>
#include <libtorrent/broadcast_socket.hpp>
#include <vector>

using namespace libtorrent;

int main()
{
	io_service ios;
	asio::error_code ec;
	std::vector<ip_interface> const& net = enum_net_interfaces(ios, ec);

	for (std::vector<ip_interface>::const_iterator i = net.begin()
		, end(net.end()); i != end; ++i)
	{
		std::cout << "address: " << i->interface_address << std::endl
			<< "   mask: " << i->netmask << std::endl
			<< "   flags: ";
		if (is_multicast(i->interface_address)) std::cout << "multicast ";
		if (is_local(i->interface_address)) std::cout << "local ";
		if (is_loopback(i->interface_address)) std::cout << "loopback ";
		std::cout << std::endl;
	}

	address local = guess_local_address(ios);

	std::cout << "Local address: " << local << std::endl;
}

<commit_msg>prints out default gateway in example<commit_after>#include <libtorrent/enum_net.hpp>
#include <libtorrent/socket.hpp>
#include <libtorrent/broadcast_socket.hpp>
#include <vector>

using namespace libtorrent;

int main()
{
	io_service ios;
	asio::error_code ec;
	std::vector<ip_interface> const& net = enum_net_interfaces(ios, ec);

	for (std::vector<ip_interface>::const_iterator i = net.begin()
		, end(net.end()); i != end; ++i)
	{
		std::cout << "address: " << i->interface_address << std::endl
			<< "   mask: " << i->netmask << std::endl
			<< "   flags: ";
		if (is_multicast(i->interface_address)) std::cout << "multicast ";
		if (is_local(i->interface_address)) std::cout << "local ";
		if (is_loopback(i->interface_address)) std::cout << "loopback ";
		std::cout << std::endl;
	}

	address local = guess_local_address(ios);
	std::cout << "Local address: " << local << std::endl;

	address gateway = get_default_gateway(ios, local, ec);
	std::cout << "Default gateway: " << gateway << std::endl;
}

<|endoftext|>


<commit_before>/*
    This file is part of KOrganizer.

    Copyright (c) 1999 Preston Brown <pbrown@kde.org>
    Copyright (c) 2000,2001,2003 Cornelius Schumacher <schumacher@kde.org>
    Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <stdlib.h>
#include <iostream>

#include <kglobal.h>
#include <kcmdlineargs.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kwin.h>
#include <kurl.h>

#include <libkcal/calformat.h>
#include <libkcal/calendarresources.h>

#include "korganizer.h"
#include "koprefs.h"
#include "version.h"
#include "alarmclient.h"
#include "koglobals.h"
#include "actionmanager.h"
#include "importdialog.h"
#include "kocore.h"
#include "calendarview.h"
#include "stdcalendar.h"

#include "koapp.h"
#include <kstartupinfo.h>

using namespace std;

KOrganizerApp::KOrganizerApp() : KUniqueApplication()
{
  QString prodId = "-//K Desktop Environment//NONSGML KOrganizer %1//EN";
  CalFormat::setApplication( "KOrganizer", prodId.arg( korgVersion ) );
}

KOrganizerApp::~KOrganizerApp()
{
}

int KOrganizerApp::newInstance()
{
  kdDebug(5850) << "KOApp::newInstance()" << endl;
  static bool first = true;
  if ( isRestored() && first ) {
     first = false;
     return 0;
  }
  first = false;

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  KOGlobals::self()->alarmClient()->startDaemon();

  // If filenames was given as argument load this as calendars, one per window.
  if ( args->count() > 0 ) {
    int i;
    for( i = 0; i < args->count(); ++i ) {
      processCalendar( args->url( i ) );
    }
    if ( args->isSet( "import" ) ) {
      processCalendar( KURL() );
    }
  } else {
    processCalendar( KURL() );
  }

  if ( args->isSet( "import" ) ) {
    KOrg::MainWindow *korg = ActionManager::findInstance( KURL() );
    if ( !korg ) {
      kdError() << "Unable to find default calendar resources view." << endl;
    } else {
      KURL url = KCmdLineArgs::makeURL( args->getOption( "import" ) );
      korg->actionManager()->importCalendar( url );
    }
  }

  kdDebug(5850) << "KOApp::newInstance() done" << endl;

  return 0;
}

void KOrganizerApp::processCalendar( const KURL &url )
{
  KOrg::MainWindow *korg = ActionManager::findInstance( url );
  if ( !korg ) {
    bool hasDocument = !url.isEmpty();
    korg = new KOrganizer( "KOrganizer MainWindow" );
    korg->init( hasDocument );
    korg->topLevelWidget()->show();

    kdDebug(5850) << "KOrganizerApp::processCalendar(): '" << url.url()
                  << "'" << endl;

    if ( hasDocument )
      korg->openURL( url );
    else {
      KOrg::StdCalendar::self()->load();
      korg->view()->updateCategories();
      korg->view()->updateView();
    }
  } else {
    korg->topLevelWidget()->show();
  }

  // Handle window activation
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
  KStartupInfo::setNewStartupId( korg->topLevelWidget(), startupId() );
#endif
}

#include "koapp.moc"
<commit_msg>BUG: 91062 restore correct calendar at login<commit_after>/*
    This file is part of KOrganizer.

    Copyright (c) 1999 Preston Brown <pbrown@kde.org>
    Copyright (c) 2000,2001,2003 Cornelius Schumacher <schumacher@kde.org>
    Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <stdlib.h>
#include <iostream>

#include <kglobal.h>
#include <kcmdlineargs.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kwin.h>
#include <kurl.h>

#include <libkcal/calformat.h>
#include <libkcal/calendarresources.h>

#include "korganizer.h"
#include "koprefs.h"
#include "version.h"
#include "alarmclient.h"
#include "koglobals.h"
#include "actionmanager.h"
#include "importdialog.h"
#include "kocore.h"
#include "calendarview.h"
#include "stdcalendar.h"

#include "koapp.h"
#include <kstartupinfo.h>

using namespace std;

KOrganizerApp::KOrganizerApp() : KUniqueApplication()
{
  QString prodId = "-//K Desktop Environment//NONSGML KOrganizer %1//EN";
  CalFormat::setApplication( "KOrganizer", prodId.arg( korgVersion ) );
}

KOrganizerApp::~KOrganizerApp()
{
}

int KOrganizerApp::newInstance()
{
  kdDebug(5850) << "KOApp::newInstance()" << endl;
  static bool first = true;
  if ( isRestored() && first ) {
     KOrg::MainWindow *korg = ActionManager::findInstance( KURL() );
     if ( korg ) {
       KOrg::StdCalendar::self()->load();
       korg->view()->updateCategories();
       korg->view()->updateView();
     }
     first = false;
     return 0;
  }
  first = false;

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  KOGlobals::self()->alarmClient()->startDaemon();

  // If filenames was given as argument load this as calendars, one per window.
  if ( args->count() > 0 ) {
    int i;
    for( i = 0; i < args->count(); ++i ) {
      processCalendar( args->url( i ) );
    }
    if ( args->isSet( "import" ) ) {
      processCalendar( KURL() );
    }
  } else {
    processCalendar( KURL() );
  }

  if ( args->isSet( "import" ) ) {
    KOrg::MainWindow *korg = ActionManager::findInstance( KURL() );
    if ( !korg ) {
      kdError() << "Unable to find default calendar resources view." << endl;
    } else {
      KURL url = KCmdLineArgs::makeURL( args->getOption( "import" ) );
      korg->actionManager()->importCalendar( url );
    }
  }

  kdDebug(5850) << "KOApp::newInstance() done" << endl;

  return 0;
}

void KOrganizerApp::processCalendar( const KURL &url )
{
  KOrg::MainWindow *korg = ActionManager::findInstance( url );
  if ( !korg ) {
    bool hasDocument = !url.isEmpty();
    korg = new KOrganizer( "KOrganizer MainWindow" );
    korg->init( hasDocument );
    korg->topLevelWidget()->show();

    kdDebug(5850) << "KOrganizerApp::processCalendar(): '" << url.url()
                  << "'" << endl;

    if ( hasDocument )
      korg->openURL( url );
    else {
      KOrg::StdCalendar::self()->load();
      korg->view()->updateCategories();
      korg->view()->updateView();
    }
  } else {
    korg->topLevelWidget()->show();
  }

  // Handle window activation
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
  KStartupInfo::setNewStartupId( korg->topLevelWidget(), startupId() );
#endif
}

#include "koapp.moc"
<|endoftext|>


<commit_before>// MGenTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MGenTest.h"
#include "../MGen/GLibrary/GLib.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// The one and only application object

CWinApp theApp;

using namespace std;

CString current_dir, full_url, server, url;
DWORD service;
WORD port;
ofstream logfile;
int ci = 0;
int nRetCode = 0;

/*
string url_encode(const string &value) {
	ostringstream escaped;
	escaped.fill('0');
	escaped << hex;

	for (string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
		string::value_type c = (*i);

		// Keep alphanumeric and other accepted characters intact
		if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
			escaped << c;
			continue;
		}

		// Any other characters are percent-encoded
		escaped << uppercase;
		escaped << '%' << setw(2) << int((unsigned char)c);
		escaped << nouppercase;
	}

	return escaped.str();
}

void HTTPPost(CString server, WORD port, CString url, CString data) {
	cout << "HTTPPost to server " << server << " port " << port << " url " << url << " : " << data << "\n";
	CString strHeaders = "Content-Type: application/x-www-form-urlencoded";
	try {
		char szBuf [2550];
		DWORD dwRet;
		CInternetSession session;
		CHttpConnection* pConnection = session.GetHttpConnection(server, port);
		CHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, url);
		pFile->AddRequestHeaders(strHeaders);
		data = url_encode(data.GetBuffer()).c_str();
		cout << "HTTPPost to server " << server << " port " << port << " url " << url << " : " << data << "\n";
		pFile->SendRequestEx(data.GetLength());
		pFile->Write(data, data.GetLength());
		//BOOL result = pFile->SendRequest(strHeaders, (LPVOID)(LPCTSTR)data, data.GetLength());
		pFile->QueryInfoStatusCode(dwRet);
		cout << "HTTP return code: " << dwRet << "\n";
		if (dwRet == HTTP_STATUS_OK) {
			UINT nRead = pFile->Read(szBuf, 2550);
			if (nRead > 0) {
				cout << "HTTP result: " << szBuf << "\n";
			}
		}
	}
	catch (CInternetException *e) {
		//e->ReportError();
		TCHAR   szCause[2550];
		e->GetErrorMessage(szCause, 2550);
		cout << "Error when sending HTTP request: " << szCause << "\n";
		e->Delete();
	}
}
*/

void Run(CString fname, CString par, int delay) {
	SHELLEXECUTEINFO sei = { 0 };
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
	sei.hwnd = NULL;
	sei.lpVerb = NULL;
	sei.lpFile = fname;
	sei.lpParameters = par;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;
	ShellExecuteEx(&sei);
	WaitForSingleObject(sei.hProcess, delay);
}

void Log(CString st, int level = 0) {
	cout << st;
	logfile << st;
	if (ci && level > 0) {
		CString cat;
		if (level == 1) cat = "Information";
		if (level == 2) cat = "Warning";
		if (level == 3) cat = "Error";
		CString par = "AddMessage \"" + st + "\" -Category " + cat;
		Run("appveyor", par, 1000);
	}
}

CString file(CString fname) {
	CString st, st2;
	ifstream fs;
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	fs.open(fname);
	char pch[2550];
	while (fs.good()) {
		// Get line
		fs.getline(pch, 2550);
		st2 = pch;
		if (st2 != "") {
			st += "- " + st2 + "\n";
		}
	}
	fs.close();
	return st;
}

void ClearBuffer() {
	fstream fs;
	fs.open("autotest\\buffer.log", ios::out);
	fs.close();
}

void PublishTest(CString tname, int result, int tpassed) {
	CString st;
	CString st2;
	st2.Format("%s: code %d in %d ms\n", tname, result, tpassed);
	if (result) {
		nRetCode = 2;
		Log(st2, 3);
	}
	else {
		Log(st2, 1);
	}

	// Show errors
	CString errors = file("autotest/buffer.log");
	cout << errors;

	if (ci) {
		//errors.Replace("\n- ", "\\n ");
		CString cat = "Passed";
		if (result) cat = "Failed";
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d. %s\" -ErrorStackTrace \"%s\"", tname, tpassed, cat, result, errors, errors);
		Run("appveyor", st, 1000);
		st.Format("UpdateTest \"%s\" -StdErr \"%s\"", tname, errors);
		Run("appveyor", st, 1000);
	}

	/*
	// Send HTTP
	st.Format("{"
		" \"testName\": \"%s\","
		" \"testFramework\" : \"MSTest\","
		" \"fileName\" : \"MGen.exe\","
		" \"outcome\" : \"%s\","
		" \"durationMilliseconds\" : \"%d\","
		" \"ErrorMessage\" : \"%s\","
		" \"ErrorStackTrace\" : \"\","
		" \"StdOut\" : \"\","
		" \"StdErr\" : \"\""
		" }", tname, cat, tpassed, errors);
	if (ci) {
		HTTPPost(server, port, url + "api/tests", st);
	}
	*/
}

void LoadConfig() {
	milliseconds time_start, time_stop;
	CString fname = "autotest\\test.txt";
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	ifstream fs;
	fs.open(fname);
	LPDWORD ecode = new DWORD;
	CString st, st2;
	char pch[2550];
	int pos = 0;
	int passed;
	while (fs.good()) {
		fs.getline(pch, 2550);
		st = pch;
		pos = st.Find("#");
		if (pos != -1) st = st.Left(pos);
		st.Trim();
		if (st.GetLength()) {
			ClearBuffer();
			if (ci) Run("appveyor", "AddTest \"" + st + "\" -Framework MSTest -FileName MGen.exe -Outcome Running", 1000);
			Log("Starting test config: " + st + "\n");
			//::ShellExecute(GetDesktopWindow(), "open", "MGen", "-test " + st, NULL, SW_SHOWNORMAL);
			st2 = "-test " + st;
			SHELLEXECUTEINFO sei = { 0 };
			sei.cbSize = sizeof(SHELLEXECUTEINFO);
			sei.fMask = SEE_MASK_NOCLOSEPROCESS;
			sei.hwnd = NULL;
			sei.lpVerb = NULL;
			sei.lpFile = "MGen.exe";
			sei.lpParameters = st2;
			sei.lpDirectory = NULL;
			sei.nShow = SW_SHOW;
			sei.hInstApp = NULL;
			time_start = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
			ShellExecuteEx(&sei);
			if (WaitForSingleObject(sei.hProcess, 60000) == WAIT_TIMEOUT) {
				Log(st + ": Timeout waiting for process\n", 3);
				exit(1);
			}

			time_stop = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
			passed = static_cast<int>((time_stop - time_start).count());
			GetExitCodeProcess(sei.hProcess, ecode);
			PublishTest(st, *ecode, passed);
		}
	}
	delete ecode;
	fs.close();
}

int test() {
	//full_url = "http://my.test.server:882/some/path/script.php?parameters=123";
	//AfxParseURL(full_url, service, server, url, port);
	//ci = 1;
	if (getenv("APPVEYOR_PROJECT_NAME") != NULL) {
		ci = 1;
		//if (getenv("APPVEYOR_API_URL") != NULL) full_url = getenv("APPVEYOR_API_URL");
		//AfxParseURL(full_url, service, server, url, port);
	}
	logfile.open("autotest\\test.log", ios_base::app);

	TCHAR buffer[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, buffer);
	current_dir = string(buffer).c_str();
	Log("Current dir: " + current_dir + "\n");

	LoadConfig();
	logfile.close();
	// Do not pause if continuous integration
	if (!ci) {
		cout << "Press any key to continue... ";
		_getch();
	}
	return 0;
}

int main()
{
    HMODULE hModule = ::GetModuleHandle(nullptr);

    if (hModule != nullptr)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
        {
            // TODO: change error code to suit your needs
            wprintf(L"Fatal Error: MFC initialization failed\n");
            nRetCode = 1;
        }
        else
        {
					test();
				}
    }
    else
    {
        // TODO: change error code to suit your needs
        wprintf(L"Fatal Error: GetModuleHandle failed\n");
        nRetCode = 1;
    }

    return nRetCode;
}
<commit_msg>MGenTest: Send  -ErrorStackTrace in separate run<commit_after>// MGenTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MGenTest.h"
#include "../MGen/GLibrary/GLib.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// The one and only application object

CWinApp theApp;

using namespace std;

CString current_dir, full_url, server, url;
DWORD service;
WORD port;
ofstream logfile;
int ci = 0;
int nRetCode = 0;

/*
string url_encode(const string &value) {
	ostringstream escaped;
	escaped.fill('0');
	escaped << hex;

	for (string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
		string::value_type c = (*i);

		// Keep alphanumeric and other accepted characters intact
		if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
			escaped << c;
			continue;
		}

		// Any other characters are percent-encoded
		escaped << uppercase;
		escaped << '%' << setw(2) << int((unsigned char)c);
		escaped << nouppercase;
	}

	return escaped.str();
}

void HTTPPost(CString server, WORD port, CString url, CString data) {
	cout << "HTTPPost to server " << server << " port " << port << " url " << url << " : " << data << "\n";
	CString strHeaders = "Content-Type: application/x-www-form-urlencoded";
	try {
		char szBuf [2550];
		DWORD dwRet;
		CInternetSession session;
		CHttpConnection* pConnection = session.GetHttpConnection(server, port);
		CHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, url);
		pFile->AddRequestHeaders(strHeaders);
		data = url_encode(data.GetBuffer()).c_str();
		cout << "HTTPPost to server " << server << " port " << port << " url " << url << " : " << data << "\n";
		pFile->SendRequestEx(data.GetLength());
		pFile->Write(data, data.GetLength());
		//BOOL result = pFile->SendRequest(strHeaders, (LPVOID)(LPCTSTR)data, data.GetLength());
		pFile->QueryInfoStatusCode(dwRet);
		cout << "HTTP return code: " << dwRet << "\n";
		if (dwRet == HTTP_STATUS_OK) {
			UINT nRead = pFile->Read(szBuf, 2550);
			if (nRead > 0) {
				cout << "HTTP result: " << szBuf << "\n";
			}
		}
	}
	catch (CInternetException *e) {
		//e->ReportError();
		TCHAR   szCause[2550];
		e->GetErrorMessage(szCause, 2550);
		cout << "Error when sending HTTP request: " << szCause << "\n";
		e->Delete();
	}
}
*/

void Run(CString fname, CString par, int delay) {
	SHELLEXECUTEINFO sei = { 0 };
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
	sei.hwnd = NULL;
	sei.lpVerb = NULL;
	sei.lpFile = fname;
	sei.lpParameters = par;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;
	ShellExecuteEx(&sei);
	WaitForSingleObject(sei.hProcess, delay);
}

void Log(CString st, int level = 0) {
	cout << st;
	logfile << st;
	if (ci && level > 0) {
		CString cat;
		if (level == 1) cat = "Information";
		if (level == 2) cat = "Warning";
		if (level == 3) cat = "Error";
		CString par = "AddMessage \"" + st + "\" -Category " + cat;
		Run("appveyor", par, 1000);
	}
}

CString file(CString fname) {
	CString st, st2;
	ifstream fs;
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	fs.open(fname);
	char pch[2550];
	while (fs.good()) {
		// Get line
		fs.getline(pch, 2550);
		st2 = pch;
		if (st2 != "") {
			st += "- " + st2 + "\n";
		}
	}
	fs.close();
	return st;
}

void ClearBuffer() {
	fstream fs;
	fs.open("autotest\\buffer.log", ios::out);
	fs.close();
}

void PublishTest(CString tname, int result, int tpassed) {
	CString st;
	CString st2;
	st2.Format("%s: code %d in %d ms\n", tname, result, tpassed);
	if (result) {
		nRetCode = 2;
		Log(st2, 3);
	}
	else {
		Log(st2, 1);
	}

	// Show errors
	CString errors = file("autotest/buffer.log");
	cout << errors;

	if (ci) {
		//errors.Replace("\n- ", "\\n ");
		CString cat = "Passed";
		if (result) cat = "Failed";
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d. %s\"", tname, tpassed, cat, result, errors, errors);
		Run("appveyor", st, 1000);
		st.Format("UpdateTest \"%s\" -ErrorStackTrace \"%s\"", tname, errors);
		Run("appveyor", st, 1000);
	}

	/*
	// Send HTTP
	st.Format("{"
		" \"testName\": \"%s\","
		" \"testFramework\" : \"MSTest\","
		" \"fileName\" : \"MGen.exe\","
		" \"outcome\" : \"%s\","
		" \"durationMilliseconds\" : \"%d\","
		" \"ErrorMessage\" : \"%s\","
		" \"ErrorStackTrace\" : \"\","
		" \"StdOut\" : \"\","
		" \"StdErr\" : \"\""
		" }", tname, cat, tpassed, errors);
	if (ci) {
		HTTPPost(server, port, url + "api/tests", st);
	}
	*/
}

void LoadConfig() {
	milliseconds time_start, time_stop;
	CString fname = "autotest\\test.txt";
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	ifstream fs;
	fs.open(fname);
	LPDWORD ecode = new DWORD;
	CString st, st2;
	char pch[2550];
	int pos = 0;
	int passed;
	while (fs.good()) {
		fs.getline(pch, 2550);
		st = pch;
		pos = st.Find("#");
		if (pos != -1) st = st.Left(pos);
		st.Trim();
		if (st.GetLength()) {
			ClearBuffer();
			if (ci) Run("appveyor", "AddTest \"" + st + "\" -Framework MSTest -FileName MGen.exe -Outcome Running", 1000);
			Log("Starting test config: " + st + "\n");
			//::ShellExecute(GetDesktopWindow(), "open", "MGen", "-test " + st, NULL, SW_SHOWNORMAL);
			st2 = "-test " + st;
			SHELLEXECUTEINFO sei = { 0 };
			sei.cbSize = sizeof(SHELLEXECUTEINFO);
			sei.fMask = SEE_MASK_NOCLOSEPROCESS;
			sei.hwnd = NULL;
			sei.lpVerb = NULL;
			sei.lpFile = "MGen.exe";
			sei.lpParameters = st2;
			sei.lpDirectory = NULL;
			sei.nShow = SW_SHOW;
			sei.hInstApp = NULL;
			time_start = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
			ShellExecuteEx(&sei);
			if (WaitForSingleObject(sei.hProcess, 60000) == WAIT_TIMEOUT) {
				Log(st + ": Timeout waiting for process\n", 3);
				exit(1);
			}

			time_stop = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
			passed = static_cast<int>((time_stop - time_start).count());
			GetExitCodeProcess(sei.hProcess, ecode);
			PublishTest(st, *ecode, passed);
		}
	}
	delete ecode;
	fs.close();
}

int test() {
	//full_url = "http://my.test.server:882/some/path/script.php?parameters=123";
	//AfxParseURL(full_url, service, server, url, port);
	//ci = 1;
	if (getenv("APPVEYOR_PROJECT_NAME") != NULL) {
		ci = 1;
		//if (getenv("APPVEYOR_API_URL") != NULL) full_url = getenv("APPVEYOR_API_URL");
		//AfxParseURL(full_url, service, server, url, port);
	}
	logfile.open("autotest\\test.log", ios_base::app);

	TCHAR buffer[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, buffer);
	current_dir = string(buffer).c_str();
	Log("Current dir: " + current_dir + "\n");

	LoadConfig();
	logfile.close();
	// Do not pause if continuous integration
	if (!ci) {
		cout << "Press any key to continue... ";
		_getch();
	}
	return 0;
}

int main()
{
    HMODULE hModule = ::GetModuleHandle(nullptr);

    if (hModule != nullptr)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
        {
            // TODO: change error code to suit your needs
            wprintf(L"Fatal Error: MFC initialization failed\n");
            nRetCode = 1;
        }
        else
        {
					test();
				}
    }
    else
    {
        // TODO: change error code to suit your needs
        wprintf(L"Fatal Error: GetModuleHandle failed\n");
        nRetCode = 1;
    }

    return nRetCode;
}
<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     colormap.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>;
* @version  1.0
* @date     March, 2013
*
* @section  LICENSE
*
* Copyright (C) 2013, Christoph Dinh and Matti Hamalainen. 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 Massachusetts General Hospital 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 MASSACHUSETTS GENERAL HOSPITAL 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.
*
*
* @brief    Implementation of the ColorMap class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "colormap.h"
#include <math.h>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace DISPLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

ColorMap::ColorMap()
{
}

//*************************************************************************************************************

ColorMap::~ColorMap()
{
}

//*************************************************************************************************************

double ColorMap::linearSlope(double x, double m, double n)
{
    //f = m*x + n
    return m*x + n;
}

//*************************************************************************************************************
// Jet
int ColorMap::jetR(double x)
{
    //Describe the red fuzzy set
    if(x < 0.375)
        return 0;
    else if(x >= 0.375 && x < 0.625)
        return (int)floor(linearSlope(x, 4, -1.5)*255);
    else if(x >= 0.625 && x < 0.875)
        return (int)floor(1.0*255);
    else if(x >= 0.875)
        return (int)floor(linearSlope(x, -4, 4.5)*255);
    else
        return 0;
}

//*************************************************************************************************************

int ColorMap::jetG(double x)
{
    //Describe the green fuzzy set
    if(x < 0.125)
        return 0;
    else if(x >= 0.125 && x < 0.375)
        return (int)floor(linearSlope(x, 4, -0.5)*255);
    else if(x >= 0.375 && x < 0.625)
        return (int)floor(1.0*255);
    else if(x >= 0.625 && x < 0.875)
        return (int)floor(linearSlope(x, -4, 2.5)*255);
    else
        return 0;
}

//*************************************************************************************************************

int ColorMap::jetB(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.125)
        return (int)floor(linearSlope(x, 4, 0.5)*255);
    else if(x >= 0.125 && x < 0.375)
        return (int)floor(1.0*255);
    else if(x >= 0.375 && x < 0.625)
        return (int)floor(linearSlope(x, -4, 2.5)*255);
    else
        return 0;
}

//*************************************************************************************************************
// Hot
int ColorMap::hotR(double x)
{
    //Describe the red fuzzy set
    if(x < 0.375)
        return (int)floor(linearSlope(x, 2.5621, 0.0392)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotG(double x)
{
    //Describe the green fuzzy set
    if(x < 0.375)
        return 0;
    else if(x >= 0.375 && x < 0.75)
        return (int)floor(linearSlope(x, 2.6667, -1.0)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotB(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.75)
        return 0;
    else
        return (int)floor(linearSlope(x,4,-3)*255);
}

//*************************************************************************************************************
// Hot negative skewed
int ColorMap::hotRNeg1(double x)
{
    //Describe the red fuzzy set
    if(x < 0.2188)
        return 0;
    else if(x < 0.5781)
        return (int)floor(linearSlope(x, 2.7832, -0.6090)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotGNeg1(double x)
{
    //Describe the green fuzzy set
    if(x < 0.5781)
        return 0;
    else if(x >= 0.5781 && x < 0.8125)
        return (int)floor(linearSlope(x, 4.2662, -2.4663)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotBNeg1(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.8125)
        return 0;
    else
        return (int)floor(linearSlope(x,5.3333,-4.3333)*255);
}

//*************************************************************************************************************

int ColorMap::hotRNeg2(double x)
{
    //Describe the red fuzzy set
    if(x < 0.5625)
        return 0;
    else if(x < 0.8438)
        return (int)floor(linearSlope(x, 2.7832, -0.6090)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotGNeg2(double x)
{
    //Describe the green fuzzy set
    if(x < 0.8438)
        return 0;
    else if(x >= 0.8438 && x < 0.9531)
        return (int)floor(linearSlope(x, 4.2662, -2.4663)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotBNeg2(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.9531)
        return 0;
    else
        return (int)floor(linearSlope(x,5.3333,-4.3333)*255);
}

//*************************************************************************************************************
// Bone
int ColorMap::boneR(double x)
{
    //Describe the red fuzzy set
    if(x < 0.375)
        return (int)floor(linearSlope(x, 0.8471, 0)*255);
    else if(x >= 0.375 && x < 0.75)
        return (int)floor(linearSlope(x, 0.8889, -0.0157)*255);
    else
        return (int)floor(linearSlope(x, 1.396, -0.396)*255);
}

//*************************************************************************************************************

int ColorMap::boneG(double x)
{
    //Describe the green fuzzy set
    if(x < 0.375)
        return (int)floor(linearSlope(x, 0.8471, 0)*255);
    else if(x >= 0.375 && x < 0.75)
        return (int)floor(linearSlope(x, 1.2237, -0.1413)*255);
    else
        return (int)floor(linearSlope(x, 0.894, 0.106)*255);
}

//*************************************************************************************************************

int ColorMap::boneB(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.375)
        return (int)floor(linearSlope(x, 1.1712, 0.0039)*255);
    else if(x >= 0.375 && x < 0.75)
        return (int)floor(linearSlope(x, 0.8889, 0.1098)*255);
    else
        return (int)floor(linearSlope(x, 0.8941, 0.1059)*255);
}

//*************************************************************************************************************
// RedBlue
int ColorMap::rbR(double x)
{
    //Describe the red fuzzy set
    if(x < 0)
        return (int)floor(linearSlope(x, 1, 1)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::rbG(double x)
{
    //Describe the green fuzzy set
    if(x < 0)
        return (int)floor(linearSlope(x, 1, 1)*255);
    else
        return (int)floor(linearSlope(x, -1, 1)*255);
}

//*************************************************************************************************************

int ColorMap::rbB(double x)
{
    //Describe the blue fuzzy set
    if(x < 0)
        return (int)floor(1.0*255);
    else
        return (int)floor(linearSlope(x, -1, 1)*255);
}
<commit_msg>negative skewed colormap<commit_after>//=============================================================================================================
/**
* @file     colormap.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>;
* @version  1.0
* @date     March, 2013
*
* @section  LICENSE
*
* Copyright (C) 2013, Christoph Dinh and Matti Hamalainen. 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 Massachusetts General Hospital 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 MASSACHUSETTS GENERAL HOSPITAL 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.
*
*
* @brief    Implementation of the ColorMap class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "colormap.h"
#include <math.h>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace DISPLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

ColorMap::ColorMap()
{
}

//*************************************************************************************************************

ColorMap::~ColorMap()
{
}

//*************************************************************************************************************

double ColorMap::linearSlope(double x, double m, double n)
{
    //f = m*x + n
    return m*x + n;
}

//*************************************************************************************************************
// Jet
int ColorMap::jetR(double x)
{
    //Describe the red fuzzy set
    if(x < 0.375)
        return 0;
    else if(x >= 0.375 && x < 0.625)
        return (int)floor(linearSlope(x, 4, -1.5)*255);
    else if(x >= 0.625 && x < 0.875)
        return (int)floor(1.0*255);
    else if(x >= 0.875)
        return (int)floor(linearSlope(x, -4, 4.5)*255);
    else
        return 0;
}

//*************************************************************************************************************

int ColorMap::jetG(double x)
{
    //Describe the green fuzzy set
    if(x < 0.125)
        return 0;
    else if(x >= 0.125 && x < 0.375)
        return (int)floor(linearSlope(x, 4, -0.5)*255);
    else if(x >= 0.375 && x < 0.625)
        return (int)floor(1.0*255);
    else if(x >= 0.625 && x < 0.875)
        return (int)floor(linearSlope(x, -4, 2.5)*255);
    else
        return 0;
}

//*************************************************************************************************************

int ColorMap::jetB(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.125)
        return (int)floor(linearSlope(x, 4, 0.5)*255);
    else if(x >= 0.125 && x < 0.375)
        return (int)floor(1.0*255);
    else if(x >= 0.375 && x < 0.625)
        return (int)floor(linearSlope(x, -4, 2.5)*255);
    else
        return 0;
}

//*************************************************************************************************************
// Hot
int ColorMap::hotR(double x)
{
    //Describe the red fuzzy set
    if(x < 0.375)
        return (int)floor(linearSlope(x, 2.5621, 0.0392)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotG(double x)
{
    //Describe the green fuzzy set
    if(x < 0.375)
        return 0;
    else if(x >= 0.375 && x < 0.75)
        return (int)floor(linearSlope(x, 2.6667, -1.0)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotB(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.75)
        return 0;
    else
        return (int)floor(linearSlope(x,4,-3)*255);
}

//*************************************************************************************************************
// Hot negative skewed
int ColorMap::hotRNeg1(double x)
{
    //Describe the red fuzzy set
    if(x < 0.2188)
        return 0;
    else if(x < 0.5781)
        return (int)floor(linearSlope(x, 2.7832, -0.6090)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotGNeg1(double x)
{
    //Describe the green fuzzy set
    if(x < 0.5781)
        return 0;
    else if(x >= 0.5781 && x < 0.8125)
        return (int)floor(linearSlope(x, 4.2662, -2.4663)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotBNeg1(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.8125)
        return 0;
    else
        return (int)floor(linearSlope(x,5.3333,-4.3333)*255);
}

//*************************************************************************************************************

int ColorMap::hotRNeg2(double x)
{
    //Describe the red fuzzy set
    if(x < 0.5625)
        return 0;
    else if(x < 0.8438)
        return (int)floor(linearSlope(x, 3.5549, -1.9996)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotGNeg2(double x)
{
    //Describe the green fuzzy set
    if(x < 0.8438)
        return 0;
    else if(x >= 0.8438 && x < 0.9531)
        return (int)floor(linearSlope(x, 9.1491, -7.72)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::hotBNeg2(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.9531)
        return 0;
    else
        return (int)floor(linearSlope(x,21.3220,-20.3220)*255);
}

//*************************************************************************************************************
// Bone
int ColorMap::boneR(double x)
{
    //Describe the red fuzzy set
    if(x < 0.375)
        return (int)floor(linearSlope(x, 0.8471, 0)*255);
    else if(x >= 0.375 && x < 0.75)
        return (int)floor(linearSlope(x, 0.8889, -0.0157)*255);
    else
        return (int)floor(linearSlope(x, 1.396, -0.396)*255);
}

//*************************************************************************************************************

int ColorMap::boneG(double x)
{
    //Describe the green fuzzy set
    if(x < 0.375)
        return (int)floor(linearSlope(x, 0.8471, 0)*255);
    else if(x >= 0.375 && x < 0.75)
        return (int)floor(linearSlope(x, 1.2237, -0.1413)*255);
    else
        return (int)floor(linearSlope(x, 0.894, 0.106)*255);
}

//*************************************************************************************************************

int ColorMap::boneB(double x)
{
    //Describe the blue fuzzy set
    if(x < 0.375)
        return (int)floor(linearSlope(x, 1.1712, 0.0039)*255);
    else if(x >= 0.375 && x < 0.75)
        return (int)floor(linearSlope(x, 0.8889, 0.1098)*255);
    else
        return (int)floor(linearSlope(x, 0.8941, 0.1059)*255);
}

//*************************************************************************************************************
// RedBlue
int ColorMap::rbR(double x)
{
    //Describe the red fuzzy set
    if(x < 0)
        return (int)floor(linearSlope(x, 1, 1)*255);
    else
        return (int)floor(1.0*255);
}

//*************************************************************************************************************

int ColorMap::rbG(double x)
{
    //Describe the green fuzzy set
    if(x < 0)
        return (int)floor(linearSlope(x, 1, 1)*255);
    else
        return (int)floor(linearSlope(x, -1, 1)*255);
}

//*************************************************************************************************************

int ColorMap::rbB(double x)
{
    //Describe the blue fuzzy set
    if(x < 0)
        return (int)floor(1.0*255);
    else
        return (int)floor(linearSlope(x, -1, 1)*255);
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <variant>

#include <op/utest/unit_test.h>
#include <op/utest/unit_test_is.h>

#include <op/vtm/EventSourcingSegmentManager.h>
#include <op/vtm/StringMemoryManager.h>

#include <op/trie/PlainValueManager.h>
#include <op/trie/Trie.h>

#include "TrieTestUtils.h"

using namespace OP::trie;
using namespace OP::utest;
static const char* test_file_name = "trie.test";

namespace OP::trie::store_converter
{
    template <class ... Tx>
    inline std::ostream& operator << (std::ostream& os, const PersistedVariant<Tx...>& val)
    {
        os << "{ persisted-variant }";
        return os;
    }

    template <class ...Tx>
    inline bool operator == (const PersistedVariant<Tx...>& left, const PersistedVariant<Tx...>& right)
    {
        if (left._selector == right._selector)
            return memcmp(left._data, right._data, buffer_size_c) == 0;
        return false;
    }
//---------------------
    using namespace OP::vtm;

//---------------------
}//ns

template <class T, class TTopology>
auto oft(TTopology&topology, T&& t)
{
    using store_converter_t = OP::trie::store_converter::Storage<std::decay_t<T>>;
    typename store_converter_t::storage_type_t result;
    store_converter_t::serialize(topology, t, result);
    return result;
}

template <class T, class V, class TTopology>
auto tfo(TTopology& topology, const V & stor)
{
    return OP::trie::store_converter::Storage<T>::deserialize(topology, stor);
}

namespace
{
    struct TestStruct
    {
        TestStruct(double a,
            float x1 = 1, float x2 = 2, float x3 = 3,
            float x4 = 4, float x5 = 5, float x6 = 6,
            float x7 = 7, float x8 = 8, float x9 = 9,
            float x10 = 10, float x11 = 11)
            : v1(a), vector1{ x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11 }
        {}
        double v1;
        float vector1[11];
    };

    inline std::ostream& operator << (std::ostream& os, const TestStruct& val)
    {
        os << "{" << val.v1 << "...}";
        return os;
    }
    inline bool operator == (const TestStruct& left, const TestStruct& right)
    {
        return left.v1 == right.v1;
    }

    template <class  ... Tx>
    inline std::ostream& operator << (std::ostream& os, const std::variant<Tx...>& val)
    {
        os << "{var(" << val.index()<<")";
        size_t n = 0;
        std::visit([&](const auto& v) {
                using arg_t = std::decay_t<decltype(v)>;

                if constexpr (OP::has_operators::ostream_out_v<arg_t>)
                {
                    os << v;
                }
                else
                {
                    os << "[unprintable:" << typeid(arg_t).name() << "]";
                }
            }, val);
        os << "}";
        return os;
    }

    void testDefault(OP::utest::TestRuntime& tresult)
    {
        using namespace OP::flur;
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using test_payload_t = TestStruct;

        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<test_payload_t>
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        std::map<atom_string_t, test_payload_t> test_values;

        using p_t = std::pair<atom_string_t, test_payload_t>;

        const p_t ini_data[] = {
            p_t("ab.c"_astr, {1.}),
            p_t("abc"_astr, {11.}),
            p_t("abc.1"_astr, {13.}),
            p_t("abc.2"_astr, {15.}),
            p_t("abc.3"_astr, {17.}),
            p_t("abc.333"_astr, {19.}), //not a child since only 'abc.3' in the result
            p_t("abc.444"_astr, {21.}), // a child
            p_t("abcdef"_astr, {113.}),
        };

        for (const p_t& s : ini_data)
        {
            trie->insert(s.first, s.second);
            test_values.emplace(s);
        }
        compare_containers(tresult, *trie, test_values);

    }

    void testVariant(OP::utest::TestRuntime& tresult)
    {
        using namespace OP::flur;
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using test_variant_t = std::variant<
            std::monostate,
            short, double, TestStruct,
            std::string
        >;
        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<test_variant_t>
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        std::map<atom_string_t, test_variant_t> test_values;

        using p_t = std::pair<atom_string_t, test_variant_t>;

        const p_t ini_data[] = {
            p_t("ab.c"_astr, test_variant_t{1.}),
            p_t("abc"_astr, test_variant_t(TestStruct{11.})),
            p_t("xyz.1"_astr, test_variant_t{short(13)}),
            p_t("abc.1"_astr, test_variant_t{std::string("xyz")}),
            p_t("empty"_astr, test_variant_t{})
        };

        for (const p_t& s : ini_data)
        {
            trie->insert(s.first, s.second);
            test_values.emplace(s);
        }

        auto debug_prn = [&]() {
            for (const auto& p : trie->range())
            {
                tresult.debug() << (const char*)p.key().c_str() << "=" << p.value() << "\n";
            }
        };
        debug_prn();
        compare_containers(tresult, *trie, test_values);
        //test update with change type
        auto ab_range = trie->prefixed_range("ab"_astr);
        OP::vtm::TransactionGuard op_g(
            trie->segment_manager().begin_transaction(), true);
        for (auto& iter : ab_range)
        {
            test_variant_t empt{};
            trie->update(iter, empt);
            test_values[iter.key()] = empt;
        }
        op_g.commit();
        compare_containers(tresult, *trie, test_values);
        debug_prn();

        OP::vtm::TransactionGuard op_g2(
            trie->segment_manager().begin_transaction(), true);
        for (auto& iter : ab_range)
        {
            std::string rstr;
            test_variant_t new_var{tools::RandomGenerator ::instance().next_alpha_num(rstr, 32)};
            trie->update(iter, new_var);
            test_values[iter.key()] = new_var;
        }
        op_g2.commit();
        compare_containers(tresult, *trie, test_values);
        debug_prn();
    }

    template <class ...Tx>
    std::ostream& operator << (std::ostream& os, const std::tuple<Tx...>& t)
    {
        std::apply([&](const auto& ... args) {
            size_t n = 0;
            os << "{";
            ((os << (n++ == 0 ? "" : ", ") << args ), ...);
            os << "}";
            }, t);
        return os;
    }

    void testTuple(OP::utest::TestRuntime& tresult)
    {
        using namespace OP::flur;
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using var_t = std::variant<std::monostate, short, double, TestStruct>;
        using test_tuple_t =
            std::tuple<std::uint64_t, var_t, std::string>;

        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<test_tuple_t>
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        std::map<atom_string_t, test_tuple_t> test_values;
        auto make_key = [](int x) {
            std::ostringstream os;
            os << std::hex << std::setw(8) << std::setfill('0')
                << x;
            return os.str();
        };
        for (int i = -11; i < 11; ++i)
        {
            auto str = make_key(i);
            auto val = test_tuple_t(i, var_t(57.75 / i), str);
            auto [iter, ok] = trie->insert(str, val);
            tresult.assert_true(ok);
            test_values.emplace(iter.key(), std::move(val));
        }
        compare_containers(tresult, *trie, test_values);
        for (int i = -5; i < 5; ++i)
        {
            auto str = make_key(i);
            auto pos = trie->find(str);
            auto v = *pos;
            std::get<var_t>(v) = (double)i;
            trie->update(pos, v);
            test_values[pos.key()] = std::move(v);
        }
        compare_containers(tresult, *trie, test_values);
    }

    void testStr(OP::utest::TestRuntime& tresult)
    {
        using namespace OP::flur;
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<std::string>
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        std::map<atom_string_t, std::string> test_values;
        constexpr size_t N = 1025;
        for (auto i = 0; i < N; ++i)
        {
            std::string rstr;
            tools::RandomGenerator::instance().next_alpha_num(rstr, 0xFF, 1);
            trie->insert(rstr, rstr);
            test_values.emplace(atom_string_t(reinterpret_cast<const atom_t*>(rstr.c_str())), rstr);
        }
        compare_containers(tresult, *trie, test_values);

    }

    void testErase(OP::utest::TestRuntime& tresult)
    {
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using test_variant_t = std::variant<
            std::monostate,
            short, double, TestStruct,
            std::string
        >;
        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<test_variant_t>
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        constexpr size_t N = 1025;
        for (auto i = 0; i < N; ++i)
        {
            std::string rstr;
            test_variant_t new_var{ tools::RandomGenerator::instance().next_alpha_num(rstr, 0xFF) };
            trie->insert(rstr, new_var);
            //if (!rstr.empty() && rstr[0] == '4')
            //    tresult.debug() << rstr << "\n";
        }
        //tresult.debug() << "4='" << *trie->find("4"_astr) << "'\n";
        for (std::uint16_t a = 0; a < 256; ++a)
        {
            atom_string_t k(1, (atom_t)a);
            trie->prefixed_key_erase_all(k);
        }
        tresult.assert_that<equals>(1, trie->nodes_count());
    }

    static auto& module_suite = OP::utest::default_test_suite("trie-values")
        .declare("default", testDefault)
        .declare("variant", testVariant)
        .declare("tuple", testTuple)
        .declare("str", testStr)
        .declare("erase", testErase)
        ;
}<commit_msg>Introduce generic approach to serialize values<commit_after>#include <algorithm>
#include <variant>

#include <op/utest/unit_test.h>
#include <op/utest/unit_test_is.h>

#include <op/vtm/EventSourcingSegmentManager.h>
#include <op/vtm/StringMemoryManager.h>

#include <op/trie/PlainValueManager.h>
#include <op/trie/Trie.h>

#include "TrieTestUtils.h"

using namespace OP::trie;
using namespace OP::utest;
static const char* test_file_name = "trie.test";

namespace OP::trie::store_converter
{
    template <class ... Tx>
    inline std::ostream& operator << (std::ostream& os, const PersistedVariant<Tx...>& val)
    {
        os << "{ persisted-variant }";
        return os;
    }

    template <class ...Tx>
    inline bool operator == (const PersistedVariant<Tx...>& left, const PersistedVariant<Tx...>& right)
    {
        if (left._selector == right._selector)
            return memcmp(left._data, right._data, buffer_size_c) == 0;
        return false;
    }
//---------------------
    using namespace OP::vtm;

//---------------------
}//ns

template <class T, class TTopology>
auto oft(TTopology&topology, T&& t)
{
    using store_converter_t = OP::trie::store_converter::Storage<std::decay_t<T>>;
    typename store_converter_t::storage_type_t result;
    store_converter_t::serialize(topology, t, result);
    return result;
}

template <class T, class V, class TTopology>
auto tfo(TTopology& topology, const V & stor)
{
    return OP::trie::store_converter::Storage<T>::deserialize(topology, stor);
}

namespace
{
    struct TestStruct
    {
        TestStruct(double a,
            float x1 = 1, float x2 = 2, float x3 = 3,
            float x4 = 4, float x5 = 5, float x6 = 6,
            float x7 = 7, float x8 = 8, float x9 = 9,
            float x10 = 10, float x11 = 11)
            : v1(a), vector1{ x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11 }
        {}
        double v1;
        float vector1[11];
    };

    inline std::ostream& operator << (std::ostream& os, const TestStruct& val)
    {
        os << "{" << val.v1 << "...}";
        return os;
    }
    inline bool operator == (const TestStruct& left, const TestStruct& right)
    {
        return left.v1 == right.v1;
    }

    template <class  ... Tx>
    inline std::ostream& operator << (std::ostream& os, const std::variant<Tx...>& val)
    {
        os << "{var(" << val.index()<<")";
        size_t n = 0;
        std::visit([&](const auto& v) {
                using arg_t = std::decay_t<decltype(v)>;

                if constexpr (OP::has_operators::ostream_out_v<arg_t>)
                {
                    os << v;
                }
                else
                {
                    os << "[unprintable:" << typeid(arg_t).name() << "]";
                }
            }, val);
        os << "}";
        return os;
    }

    void testDefault(OP::utest::TestRuntime& tresult)
    {
        using namespace OP::flur;
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using test_payload_t = TestStruct;

        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<test_payload_t>
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        std::map<atom_string_t, test_payload_t> test_values;

        using p_t = std::pair<atom_string_t, test_payload_t>;

        const p_t ini_data[] = {
            p_t("ab.c"_astr, {1.}),
            p_t("abc"_astr, {11.}),
            p_t("abc.1"_astr, {13.}),
            p_t("abc.2"_astr, {15.}),
            p_t("abc.3"_astr, {17.}),
            p_t("abc.333"_astr, {19.}), //not a child since only 'abc.3' in the result
            p_t("abc.444"_astr, {21.}), // a child
            p_t("abcdef"_astr, {113.}),
        };

        for (const p_t& s : ini_data)
        {
            trie->insert(s.first, s.second);
            test_values.emplace(s);
        }
        compare_containers(tresult, *trie, test_values);

    }

    void testVariant(OP::utest::TestRuntime& tresult)
    {
        using namespace OP::flur;
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using test_variant_t = std::variant<
            std::monostate,
            short, double, TestStruct,
            std::string
        >;
        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<test_variant_t>
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        std::map<atom_string_t, test_variant_t> test_values;

        using p_t = std::pair<atom_string_t, test_variant_t>;

        const p_t ini_data[] = {
            p_t("ab.c"_astr, test_variant_t{1.}),
            p_t("abc"_astr, test_variant_t(TestStruct{11.})),
            p_t("xyz.1"_astr, test_variant_t{short(13)}),
            p_t("abc.1"_astr, test_variant_t{std::string("xyz")}),
            p_t("empty"_astr, test_variant_t{})
        };

        for (const p_t& s : ini_data)
        {
            trie->insert(s.first, s.second);
            test_values.emplace(s);
        }

        auto debug_prn = [&]() {
            for (const auto& p : trie->range())
            {
                tresult.debug() << (const char*)p.key().c_str() << "=" << p.value() << "\n";
            }
        };
        debug_prn();
        compare_containers(tresult, *trie, test_values);
        //test update with change type
        auto ab_range = trie->prefixed_range("ab"_astr);
        OP::vtm::TransactionGuard op_g(
            trie->segment_manager().begin_transaction(), true);
        for (auto& iter : ab_range)
        {
            test_variant_t empt{};
            trie->update(iter, empt);
            test_values[iter.key()] = empt;
        }
        op_g.commit();
        compare_containers(tresult, *trie, test_values);
        debug_prn();

        OP::vtm::TransactionGuard op_g2(
            trie->segment_manager().begin_transaction(), true);
        for (auto& iter : ab_range)
        {
            std::string rstr;
            test_variant_t new_var{tools::RandomGenerator ::instance().next_alpha_num(rstr, 32)};
            trie->update(iter, new_var);
            test_values[iter.key()] = new_var;
        }
        op_g2.commit();
        compare_containers(tresult, *trie, test_values);
        debug_prn();
    }

    template <class ...Tx>
    std::ostream& operator << (std::ostream& os, const std::tuple<Tx...>& t)
    {
        std::apply([&](const auto& ... args) {
            size_t n = 0;
            os << "{";
            ((os << (n++ == 0 ? "" : ", ") << args ), ...);
            os << "}";
            }, t);
        return os;
    }

    void testTuple(OP::utest::TestRuntime& tresult)
    {
        using namespace OP::flur;
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using var_t = std::variant<std::monostate, short, double, TestStruct>;
        using test_tuple_t =
            std::tuple<std::uint64_t, var_t, std::string>;

        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<test_tuple_t>
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        std::map<atom_string_t, test_tuple_t> test_values;
        auto make_key = [](int x) {
            std::ostringstream os;
            os << std::hex << std::setw(8) << std::setfill('0')
                << x;
            return os.str();
        };
        for (int i = -11; i < 11; ++i)
        {
            auto str = make_key(i);
            auto val = test_tuple_t(i, var_t(57.75 / i), str);
            auto [iter, ok] = trie->insert(str, val);
            tresult.assert_true(ok);
            test_values.emplace(iter.key(), std::move(val));
        }
        compare_containers(tresult, *trie, test_values);
        for (int i = -5; i < 5; ++i)
        {
            auto str = make_key(i);
            auto pos = trie->find(str);
            auto v = *pos;
            std::get<var_t>(v) = (double)i;
            trie->update(pos, v);
            test_values[pos.key()] = std::move(v);
        }
        compare_containers(tresult, *trie, test_values);
    }

    void testStr(OP::utest::TestRuntime& tresult)
    {
        using namespace OP::flur;
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<std::string>
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        std::map<atom_string_t, std::string> test_values;
        constexpr size_t N = 1025;
        for (auto i = 0; i < N; ++i)
        {
            std::string rstr;
            tools::RandomGenerator::instance().next_alpha_num(rstr, 0xFF, 1);
            trie->insert(rstr, rstr);
            test_values.emplace(atom_string_t(reinterpret_cast<const atom_t*>(rstr.c_str())), rstr);
        }
        compare_containers(tresult, *trie, test_values);

    }

    void testStrCompact(OP::utest::TestRuntime& tresult)
    {
        using namespace OP::flur;
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>("trie2.test",
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<std::string, 16>, 1ull << 9
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        std::map<atom_string_t, std::string> test_values;
        constexpr size_t N = 1025;
        for (auto i = 0; i < N; ++i)
        {
            std::string rstr;
            tools::RandomGenerator::instance().next_alpha_num(rstr, 0xFF, 1);
            trie->insert(rstr, rstr);
            test_values.emplace(atom_string_t(reinterpret_cast<const atom_t*>(rstr.c_str())), rstr);
        }
        compare_containers(tresult, *trie, test_values);

    }

    void testErase(OP::utest::TestRuntime& tresult)
    {
        auto tmngr = OP::trie::SegmentManager::create_new<EventSourcingSegmentManager>(test_file_name,
            OP::trie::SegmentOptions()
            .segment_size(0x110000));

        using test_variant_t = std::variant<
            std::monostate,
            short, double, TestStruct,
            std::string
        >;
        using trie_t = Trie<
            EventSourcingSegmentManager, PlainValueManager<test_variant_t, 16>,
            1ull << 10
        >;
        std::shared_ptr<trie_t> trie = trie_t::create_new(tmngr);

        constexpr size_t N = 1025;
        for (auto i = 0; i < N; ++i)
        {
            std::string rstr;
            test_variant_t new_var{ tools::RandomGenerator::instance().next_alpha_num(rstr, 0xFF) };
            trie->insert(rstr, new_var);
            //if (!rstr.empty() && rstr[0] == '4')
            //    tresult.debug() << rstr << "\n";
        }
        //tresult.debug() << "4='" << *trie->find("4"_astr) << "'\n";
        for (std::uint16_t a = 0; a < 256; ++a)
        {
            atom_string_t k(1, (atom_t)a);
            trie->prefixed_key_erase_all(k);
        }
        tresult.assert_that<equals>(1, trie->nodes_count());
    }

    static auto& module_suite = OP::utest::default_test_suite("trie-values")
        .declare("default", testDefault)
        .declare("variant", testVariant)
        .declare("tuple", testTuple)
        .declare("str", testStr)
        .declare("str-compact", testStrCompact)
        .declare("erase", testErase)
        ;
}<|endoftext|>


<commit_before>#ifndef SEQUENCE_SPACE_HPP_
#define SEQUENCE_SPACE_HPP_

#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/dynamic_bitset.hpp>

#include "allele_space.hpp"

class SequenceSpace {
public:
    typedef boost::dynamic_bitset< unsigned long >  sequence_type;
    typedef std::shared_ptr< sequence_type >        sequence_ptr;

    SequenceSpace( boost::property_tree::ptree & config );

    sequence_ptr create();

    sequence_ptr clone( sequence_ptr s );

    size_t size();
    void prune();

    virtual ~SequenceSpace();
protected:
    AlleleSpace m_alleles;

    std::vector< sequence_ptr > m_seq_map;
};

#endif  // SEQUENCE_SPACE_HPP_
<commit_msg>Formatting<commit_after>#ifndef SEQUENCE_SPACE_HPP_
#define SEQUENCE_SPACE_HPP_

#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/dynamic_bitset.hpp>

#include "allele_space.hpp"

class SequenceSpace {
public:
    typedef boost::dynamic_bitset< unsigned long >  sequence_type;
    typedef std::shared_ptr< sequence_type >        sequence_ptr;

    SequenceSpace( boost::property_tree::ptree & config );

    sequence_ptr create();

    sequence_ptr clone( sequence_ptr s );

    size_t size();
    void prune();

    virtual ~SequenceSpace();
protected:
    AlleleSpace m_alleles;

    std::vector< sequence_ptr > m_seq_map;
};

#endif  // SEQUENCE_SPACE_HPP_
<|endoftext|>


<commit_before>// Copyright (c) 2020 Manfred Moitzi
// License: MIT License
// Fast cubic bezier curve library for ezdxf
// All required checks are done in the Cython code!

#include "_cpp_cubic_bezier.hpp"

CppCubicBezier::CppCubicBezier():
    p0(CppVec3()), p1(CppVec3()), p2(CppVec3()), p3(CppVec3()) {
}

CppCubicBezier::CppCubicBezier(CppVec3 v0, CppVec3 v1, CppVec3 v2, CppVec3 v3):
    p0(v0), p1(v1), p2(v2), p3(v3) {
}

void CppCubicBezier::bernstein_poly_d0(double t, double *weights) {
    // Required domain check for t has to be done by the caller!
    // 0 <= t <= 1
    double t2 = t * t;
    double _1_minus_t = 1.0 - t;
    double _1_minus_t_square = _1_minus_t * _1_minus_t;
    weights[0] = _1_minus_t_square * _1_minus_t;
    weights[1] = 3.0 * _1_minus_t_square * t;
    weights[2] = 3.0 * _1_minus_t * t2;
    weights[3] = t2 * t;
}

void CppCubicBezier::bernstein_poly_d1(double t, double *weights) {
    // Required domain check for t has to be done by the caller!
    // 0 <= t <= 1
    double t2 = t * t;
    weights[0] = -3.0 * (1.0 - t) * (1.0 - t);
    weights[1] = 3.0 * (1.0 - 4.0 * t + 3.0 * t2);
    weights[2] = 3.0 * t * (2.0 - 3.0 * t);
    weights[3] = 3.0 * t2;
}

CppVec3 CppCubicBezier::point(double t) {
    // Required domain check for t has to be done by the caller!
    // 0 <= t <= 1
    double weights[4];
    bernstein_poly_d0(t, weights);
    CppVec3 res = p0 * weights[0] + p1 * weights[1] + p2 * weights[2] + p3 * weights[3];
    return res;
}

CppVec3 CppCubicBezier::tangent(double t) {
    // Required domain check for t has to be done by the caller!
    // 0 <= t <= 1
    double weights[4];
    bernstein_poly_d1(t, weights);
    CppVec3 res = p0 * weights[0] + p1 * weights[1] + p2 * weights[2] + p3 * weights[3];
    return res;
}
<commit_msg>remove temp var<commit_after>// Copyright (c) 2020 Manfred Moitzi
// License: MIT License
// Fast cubic bezier curve library for ezdxf
// All required checks are done in the Cython code!

#include "_cpp_cubic_bezier.hpp"

CppCubicBezier::CppCubicBezier():
    p0(CppVec3()), p1(CppVec3()), p2(CppVec3()), p3(CppVec3()) {
}

CppCubicBezier::CppCubicBezier(CppVec3 v0, CppVec3 v1, CppVec3 v2, CppVec3 v3):
    p0(v0), p1(v1), p2(v2), p3(v3) {
}

void CppCubicBezier::bernstein_poly_d0(double t, double *weights) {
    // Required domain check for t has to be done by the caller!
    // 0 <= t <= 1
    double t2 = t * t;
    double _1_minus_t = 1.0 - t;
    double _1_minus_t_square = _1_minus_t * _1_minus_t;
    weights[0] = _1_minus_t_square * _1_minus_t;
    weights[1] = 3.0 * _1_minus_t_square * t;
    weights[2] = 3.0 * _1_minus_t * t2;
    weights[3] = t2 * t;
}

void CppCubicBezier::bernstein_poly_d1(double t, double *weights) {
    // Required domain check for t has to be done by the caller!
    // 0 <= t <= 1
    double t2 = t * t;
    weights[0] = -3.0 * (1.0 - t) * (1.0 - t);
    weights[1] = 3.0 * (1.0 - 4.0 * t + 3.0 * t2);
    weights[2] = 3.0 * t * (2.0 - 3.0 * t);
    weights[3] = 3.0 * t2;
}

CppVec3 CppCubicBezier::point(double t) {
    // Required domain check for t has to be done by the caller!
    // 0 <= t <= 1
    double weights[4];
    bernstein_poly_d0(t, weights);
    return p0 * weights[0] + p1 * weights[1] + p2 * weights[2] + p3 * weights[3];
}

CppVec3 CppCubicBezier::tangent(double t) {
    // Required domain check for t has to be done by the caller!
    // 0 <= t <= 1
    double weights[4];
    bernstein_poly_d1(t, weights);
    return p0 * weights[0] + p1 * weights[1] + p2 * weights[2] + p3 * weights[3];
}
<|endoftext|>