<commit_before>
#include <QApplication>
#include "QImageWidget.h"
#include "Raycasting.h"
#include "KinectSpecs.h"

#define DegToRad(angle_degrees) (angle_degrees * M_PI / 180.0)		// Converts degrees to radians.
#define RadToDeg(angle_radians) (angle_radians * 180.0 / M_PI)		// Converts radians to degrees.

static void multDirMatrix(const Eigen::Vector3f &src, const Eigen::Matrix4f &mat, Eigen::Vector3f &dst)
{
	float a, b, c;

	a = src[0] * mat(0, 0) + src[1] * mat(1, 0) + src[2] * mat(2, 0);
	b = src[0] * mat(0, 1) + src[1] * mat(1, 1) + src[2] * mat(2, 1);
	c = src[0] * mat(0, 2) + src[1] * mat(1, 2) + src[2] * mat(2, 2);

	dst.x() = a;
	dst.y() = b;
	dst.z() = c;
}

template <typename Type>
static Eigen::Matrix<Type, 3, 1> compute_normal(
	const Eigen::Matrix<Type, 3, 1>& p1,
	const Eigen::Matrix<Type, 3, 1>& p2,
	const Eigen::Matrix<Type, 3, 1>& p3)
{
	Eigen::Matrix<Type, 3, 1> u = p2 - p1;
	Eigen::Matrix<Type, 3, 1> v = p3 - p1;

	return v.cross(u).normalized();
}

template <typename Type>
static Eigen::Matrix<Type, 3, 1> reflect(const Eigen::Matrix<Type, 3, 1>& i, const Eigen::Matrix<Type, 3, 1>& n)
{
	return i - 2.0 * n * n.dot(i);
}

int raycast_and_render_grid(int argc, char* argv[])
{
	int vx_count = 8;
	int vx_size = 16;

	Eigen::Vector3i voxel_count(vx_count, vx_count, vx_count);
	Eigen::Vector3i voxel_size(vx_size, vx_size, vx_size);

	if (argc > 2)
	{
		vx_count = atoi(argv[1]);
		vx_size = atoi(argv[2]);

		voxel_count = Eigen::Vector3i(vx_count, vx_count, vx_count);
		voxel_size = Eigen::Vector3i(vx_size, vx_size, vx_size);
	}

	Eigen::Vector3i volume_size(voxel_count.x() * voxel_size.x(), voxel_count.y() * voxel_size.y(), voxel_count.z() * voxel_size.z());
	Eigen::Vector3f half_volume_size = volume_size.cast<float>() * 0.5f;
	const int total_voxels = voxel_count.x() * voxel_count.y() * voxel_count.z();

	std::cout << std::fixed
		<< "Voxel Count  : " << voxel_count.transpose() << std::endl
		<< "Voxel Size   : " << voxel_size.transpose() << std::endl
		<< "Volume Size  : " << volume_size.transpose() << std::endl
		<< "Total Voxels : " << total_voxels << std::endl;

	//
	// create the grid params and set a few voxels with different signals
	// in order to obtain zero crossings
	//
	std::vector<Eigen::Vector2f> tsdf(total_voxels, Eigen::Vector2f::Ones());
	//tsdf.at(13)[0] =
	//tsdf.at(22)[0] =
	//tsdf.at(18)[0] =
	//tsdf.at(26)[0] = -1.0f;
	tsdf.at(0)[0] = -1.0f;
	tsdf.at(tsdf.size() - voxel_count.x())[0] =
	tsdf.at(tsdf.size() - 1)[0] = -1.0f;

	//
	// setup camera parameters
	//
	Eigen::Affine3f camera_to_world = Eigen::Affine3f::Identity();
	float cam_z = (-vx_count - 1) * vx_size;
	camera_to_world.translate(Eigen::Vector3f(half_volume_size.x(), half_volume_size.y(), cam_z));
	Eigen::Vector3f camera_pos = camera_to_world.matrix().col(3).head<3>();
	float scale = (float)tan(DegToRad(KINECT_V1_FOVY * 0.5f));
	float aspect_ratio = KINECT_V1_ASPECT_RATIO;

	//
	// setup image parameters
	//
	unsigned short image_width = KINECT_V1_COLOR_WIDTH;
	unsigned short image_height = image_width / aspect_ratio;
	unsigned char* image_data = new unsigned char[image_width * image_height * 3]{0}; // rgb
	QImage image(image_data, image_width, image_height, QImage::Format_RGB888);
	image.fill(Qt::GlobalColor::black);

	//
	// for each pixel, trace a ray
	//
	for (int y = 0; y < image_height; ++y)
	{
		for (int x = 0; x < image_width; ++x)
		{
			// Convert from image space (in pixels) to screen space
			// Screen Space alon X axis = [-aspect ratio, aspect ratio]
			// Screen Space alon Y axis = [-1, 1]
			Eigen::Vector3f screen_coord(
				(2 * (x + 0.5f) / (float)image_width - 1) * aspect_ratio * scale,
				(1 - 2 * (y + 0.5f) / (float)image_height) * scale,
				1.0f);

			Eigen::Vector3f direction;
			multDirMatrix(screen_coord, camera_to_world.matrix(), direction);
			direction.normalize();

			std::vector<int> voxels_zero_crossing;
			if (raycast_tsdf_volume(camera_pos, direction, voxel_count, voxel_size, tsdf, voxels_zero_crossing) > 0)
			{
				if (voxels_zero_crossing.size() == 2)
				{
					image.setPixel(QPoint(x, y), qRgb(128, 128, 0));
				}
				else
				{
					image.setPixel(QPoint(x, y), qRgb(128, 0, 0));
				}
			}
		}
	}

	QApplication app(argc, argv);
	QImageWidget widget;
	widget.setImage(image);
	widget.show();

	return app.exec();
}

int raycast_and_render_two_triangles(int argc, char* argv[])
{
	Eigen::Affine3f camera_to_world = Eigen::Affine3f::Identity();
	camera_to_world.translate(Eigen::Vector3f(2, 2, 5));
	Eigen::Vector3f camera_pos = camera_to_world.matrix().col(3).head<3>();
	float scale = tan(DegToRad(60.f * 0.5f));
	float aspect_ratio = 1.7778f;
	unsigned short image_width = 710;
	unsigned short image_height = 400;
	unsigned char* image_data = new unsigned char[image_width * image_height * 3]{0}; // rgb
	QImage image(image_data, image_width, image_height, QImage::Format_RGB888);

	Eigen::Vector3f hit;
	Eigen::Vector3f v1(0.0f, -1.0f, -2.0f);
	Eigen::Vector3f v2(0.0f, 1.0f, -4.0f);
	Eigen::Vector3f v3(-1.0f, -1.0f, -3.0f);
	Eigen::Vector3f v4(0.0f, -1.0f, -2.0f);
	Eigen::Vector3f v5(0.0f, 1.0f, -4.0f);
	Eigen::Vector3f v6(1.0f, -1.0f, -3.0f);

	Eigen::Vector3f diff_color(1, 0, 0);
	Eigen::Vector3f spec_color(1, 1, 0);
	float spec_shininess = 1.0f;
	Eigen::Vector3f E(0, 0, -1);				// view direction
	Eigen::Vector3f L = Eigen::Vector3f(0.2, -1, -1).normalized();	// light direction
	Eigen::Vector3f N[2] = {
		compute_normal(v1, v2, v3),
		compute_normal(v4, v5, v6) };
	Eigen::Vector3f R[2] = {
		-reflect(L, N[0]).normalized(),
		-reflect(L, N[1]).normalized() };

	for (int y = 0; y < image_height; ++y)
	{
		for (int x = 0; x < image_width; ++x)
		{
			// Convert from image space (in pixels) to screen space
			// Screen Space alon X axis = [-aspect ratio, aspect ratio]
			// Screen Space alon Y axis = [-1, 1]
			Eigen::Vector3f screen_coord(
				(2 * (x + 0.5f) / (float)image_width - 1) * aspect_ratio * scale,
				(1 - 2 * (y + 0.5f) / (float)image_height) * scale,
				-1.0f);

			Eigen::Vector3f direction;
			multDirMatrix(screen_coord, camera_to_world.matrix(), direction);
			direction.normalize();

			bool intersec[2] = {
				triangle_intersection(camera_pos, direction, v1, v2, v3, hit),
				triangle_intersection(camera_pos, direction, v4, v5, v6, hit) };

			for (int i = 0; i < 2; ++i)
			{
				if (intersec[i])
				{
					Eigen::Vector3f diff = diff_color * std::fmax(N[i].dot(L), 0.0f);
					Eigen::Vector3f spec = spec_color * pow(std::fmax(R[i].dot(E), 0.0f), spec_shininess);
					Eigen::Vector3f color = eigen_clamp(diff + spec, 0.f, 1.f) * 255;
					image.setPixel(QPoint(x, y), qRgb(color.x(), color.y(), color.z()));
				}
			}
		}
	}

	QApplication app(argc, argv);
	QImageWidget widget;
	widget.setImage(image);
	widget.show();

	return app.exec();
}

int raycast_volume_test(int argc, char **argv)
{
	//int vx_count = 3;
	//int vx_size = 1;
	//int vx_count = 2;
	//int vx_size = 2;
	int vx_count = 3;
	int vx_size = 16;

	Eigen::Vector3i voxel_count(vx_count, vx_count, vx_count);
	Eigen::Vector3i voxel_size(vx_size, vx_size, vx_size);

	//Eigen::Vector3f ray_origin(0.5f, 0.5f, -1.0f);
	//Eigen::Vector3f ray_target(0.5f, 2.0f, 1.f);	// { 3, 6, 15, 24 }
	//Eigen::Vector3f ray_origin(2.f, 2.f, -2.0f);
	//Eigen::Vector3f ray_target(2.f, 2.f, 2.f);	// { 3, 7 }

	Eigen::Vector3f ray_origin(64.f, 64.f, -32.0f);
	Eigen::Vector3f ray_target(8.f, 8.f, 40.f);	// { 3, 7 }

	Eigen::Vector3f ray_direction = (ray_target - ray_origin).normalized();

	if (argc > 8)
	{
		vx_count = atoi(argv[1]);
		vx_size = atoi(argv[2]);

		voxel_count = Eigen::Vector3i(vx_count, vx_count, vx_count);
		voxel_size = Eigen::Vector3i(vx_size, vx_size, vx_size);

		ray_origin = Eigen::Vector3f(atof(argv[3]), atof(argv[4]), atof(argv[5]));
		ray_target = Eigen::Vector3f(atof(argv[6]), atof(argv[7]), atof(argv[8]));
		ray_direction = (ray_target - ray_origin).normalized();
	}

	std::vector<int> voxels_intersected;
	Timer t;
	t.start();
	raycast_volume<float>(ray_origin, ray_direction, voxel_count, voxel_size, voxels_intersected);
	t.print_interval("Raycasting volume       : ");

	std::cout << "Voxels Intersected: ";
	for (auto v : voxels_intersected)
		std::cout << v << ' ';
	std::cout << std::endl;

	return 0;
}

int main(int argc, char **argv)
{
#if 0
	// Usage: ./Raycastingd.exe vx_count vx_size cam_x y z target_x y z
	// Usage: ./Raycastingd.exe 3 1 1.5 1.5 -15 1.5 1.5 -10
	raycast_volume_test(argc, argv);
#endif

#if 0
	// Usage: ./Raycastingd.exe
	Timer t;
	t.start();
	raycast_and_render_two_triangles(argc, argv);
	t.print_interval("Raycasting and render   : ");
#endif

	// Usage: ./Raycastingd.exe vx_count vx_size
	// Usage: ./Raycastingd.exe 3 1
	raycast_and_render_grid(argc, argv);

	return 0;
}
<commit_msg>New values for test cube views<commit_after>
#include <QApplication>
#include "QImageWidget.h"
#include "Raycasting.h"
#include "KinectSpecs.h"

#define DegToRad(angle_degrees) (angle_degrees * M_PI / 180.0)		// Converts degrees to radians.
#define RadToDeg(angle_radians) (angle_radians * 180.0 / M_PI)		// Converts radians to degrees.

static void multDirMatrix(const Eigen::Vector3f &src, const Eigen::Matrix4f &mat, Eigen::Vector3f &dst)
{
	float a, b, c;

	a = src[0] * mat(0, 0) + src[1] * mat(1, 0) + src[2] * mat(2, 0);
	b = src[0] * mat(0, 1) + src[1] * mat(1, 1) + src[2] * mat(2, 1);
	c = src[0] * mat(0, 2) + src[1] * mat(1, 2) + src[2] * mat(2, 2);

	dst.x() = a;
	dst.y() = b;
	dst.z() = c;
}

template <typename Type>
static Eigen::Matrix<Type, 3, 1> compute_normal(
	const Eigen::Matrix<Type, 3, 1>& p1,
	const Eigen::Matrix<Type, 3, 1>& p2,
	const Eigen::Matrix<Type, 3, 1>& p3)
{
	Eigen::Matrix<Type, 3, 1> u = p2 - p1;
	Eigen::Matrix<Type, 3, 1> v = p3 - p1;

	return v.cross(u).normalized();
}

template <typename Type>
static Eigen::Matrix<Type, 3, 1> reflect(const Eigen::Matrix<Type, 3, 1>& i, const Eigen::Matrix<Type, 3, 1>& n)
{
	return i - 2.0 * n * n.dot(i);
}

int raycast_and_render_grid(int argc, char* argv[])
{
	int vx_count = 3;
	int vx_size = 1;

	Eigen::Vector3i voxel_count(vx_count, vx_count, vx_count);
	Eigen::Vector3i voxel_size(vx_size, vx_size, vx_size);

	if (argc > 2)
	{
		vx_count = atoi(argv[1]);
		vx_size = atoi(argv[2]);

		voxel_count = Eigen::Vector3i(vx_count, vx_count, vx_count);
		voxel_size = Eigen::Vector3i(vx_size, vx_size, vx_size);
	}

	Eigen::Vector3i volume_size(voxel_count.x() * voxel_size.x(), voxel_count.y() * voxel_size.y(), voxel_count.z() * voxel_size.z());
	Eigen::Vector3f half_volume_size = volume_size.cast<float>() * 0.5f;
	const int total_voxels = voxel_count.x() * voxel_count.y() * voxel_count.z();

	std::cout << std::fixed
		<< "Voxel Count  : " << voxel_count.transpose() << std::endl
		<< "Voxel Size   : " << voxel_size.transpose() << std::endl
		<< "Volume Size  : " << volume_size.transpose() << std::endl
		<< "Total Voxels : " << total_voxels << std::endl;

	//
	// create the grid params and set a few voxels with different signals
	// in order to obtain zero crossings
	//
	std::vector<Eigen::Vector2f> tsdf(total_voxels, Eigen::Vector2f::Ones());
	//tsdf.at(13)[0] =
	//tsdf.at(22)[0] =
	//tsdf.at(18)[0] =
	//tsdf.at(26)[0] = -1.0f;
	tsdf.at(0)[0] = -1.0f;
	tsdf.at(tsdf.size() - voxel_count.x())[0] =
	tsdf.at(tsdf.size() - 1)[0] = -1.0f;

	//
	// setup camera parameters
	//
	Eigen::Affine3f camera_to_world = Eigen::Affine3f::Identity();
#if 1
	float cam_z = (-vx_count - 1) * vx_size;
	camera_to_world.translate(Eigen::Vector3f(half_volume_size.x(), half_volume_size.y(), cam_z));
#else
#if 0
	camera_to_world.rotate(Eigen::AngleAxisf(DegToRad(-25), Eigen::Vector3f::UnitX()));
	camera_to_world.translate(Eigen::Vector3f(half_volume_size.x(), half_volume_size.y(), 0));
	camera_to_world.translate(Eigen::Vector3f(0, 7, -4));
#else
	camera_to_world.rotate(Eigen::AngleAxisf(DegToRad(-20), Eigen::Vector3f::UnitY()));
	camera_to_world.translate(Eigen::Vector3f(half_volume_size.x(), half_volume_size.y(), 0));
	camera_to_world.translate(Eigen::Vector3f(-5, 0, -6));
#endif
#endif
	Eigen::Vector3f camera_pos = camera_to_world.matrix().col(3).head<3>();
	float scale = (float)tan(DegToRad(KINECT_V1_FOVY * 0.5f));
	float aspect_ratio = KINECT_V1_ASPECT_RATIO;

	//
	// setup image parameters
	//
	unsigned short image_width = KINECT_V1_COLOR_WIDTH;
	unsigned short image_height = image_width / aspect_ratio;
	unsigned char* image_data = new unsigned char[image_width * image_height * 3]{0}; // rgb
	QImage image(image_data, image_width, image_height, QImage::Format_RGB888);
	image.fill(Qt::GlobalColor::black);

	//
	// for each pixel, trace a ray
	//
	for (int y = 0; y < image_height; ++y)
	{
		for (int x = 0; x < image_width; ++x)
		{
			// Convert from image space (in pixels) to screen space
			// Screen Space alon X axis = [-aspect ratio, aspect ratio]
			// Screen Space alon Y axis = [-1, 1]
			Eigen::Vector3f screen_coord(
				(2 * (x + 0.5f) / (float)image_width - 1) * aspect_ratio * scale,
				(1 - 2 * (y + 0.5f) / (float)image_height) * scale,
				1.0f);

			Eigen::Vector3f direction;
			multDirMatrix(screen_coord, camera_to_world.matrix(), direction);
			direction.normalize();

			std::vector<int> voxels_zero_crossing;
			if (raycast_tsdf_volume(camera_pos, direction, voxel_count, voxel_size, tsdf, voxels_zero_crossing) > 0)
			{
				if (voxels_zero_crossing.size() == 2)
				{
					image.setPixel(QPoint(x, y), qRgb(128, 128, 0));
				}
				else
				{
					image.setPixel(QPoint(x, y), qRgb(128, 0, 0));
				}
			}
		}
	}

	QApplication app(argc, argv);
	QImageWidget widget;
	widget.setImage(image);
	widget.show();

	return app.exec();
}

int raycast_and_render_two_triangles(int argc, char* argv[])
{
	Eigen::Affine3f camera_to_world = Eigen::Affine3f::Identity();
	camera_to_world.translate(Eigen::Vector3f(2, 2, 5));
	Eigen::Vector3f camera_pos = camera_to_world.matrix().col(3).head<3>();
	float scale = tan(DegToRad(60.f * 0.5f));
	float aspect_ratio = 1.7778f;
	unsigned short image_width = 710;
	unsigned short image_height = 400;
	unsigned char* image_data = new unsigned char[image_width * image_height * 3]{0}; // rgb
	QImage image(image_data, image_width, image_height, QImage::Format_RGB888);

	Eigen::Vector3f hit;
	Eigen::Vector3f v1(0.0f, -1.0f, -2.0f);
	Eigen::Vector3f v2(0.0f, 1.0f, -4.0f);
	Eigen::Vector3f v3(-1.0f, -1.0f, -3.0f);
	Eigen::Vector3f v4(0.0f, -1.0f, -2.0f);
	Eigen::Vector3f v5(0.0f, 1.0f, -4.0f);
	Eigen::Vector3f v6(1.0f, -1.0f, -3.0f);

	Eigen::Vector3f diff_color(1, 0, 0);
	Eigen::Vector3f spec_color(1, 1, 0);
	float spec_shininess = 1.0f;
	Eigen::Vector3f E(0, 0, -1);				// view direction
	Eigen::Vector3f L = Eigen::Vector3f(0.2, -1, -1).normalized();	// light direction
	Eigen::Vector3f N[2] = {
		compute_normal(v1, v2, v3),
		compute_normal(v4, v5, v6) };
	Eigen::Vector3f R[2] = {
		-reflect(L, N[0]).normalized(),
		-reflect(L, N[1]).normalized() };

	for (int y = 0; y < image_height; ++y)
	{
		for (int x = 0; x < image_width; ++x)
		{
			// Convert from image space (in pixels) to screen space
			// Screen Space alon X axis = [-aspect ratio, aspect ratio]
			// Screen Space alon Y axis = [-1, 1]
			Eigen::Vector3f screen_coord(
				(2 * (x + 0.5f) / (float)image_width - 1) * aspect_ratio * scale,
				(1 - 2 * (y + 0.5f) / (float)image_height) * scale,
				-1.0f);

			Eigen::Vector3f direction;
			multDirMatrix(screen_coord, camera_to_world.matrix(), direction);
			direction.normalize();

			bool intersec[2] = {
				triangle_intersection(camera_pos, direction, v1, v2, v3, hit),
				triangle_intersection(camera_pos, direction, v4, v5, v6, hit) };

			for (int i = 0; i < 2; ++i)
			{
				if (intersec[i])
				{
					Eigen::Vector3f diff = diff_color * std::fmax(N[i].dot(L), 0.0f);
					Eigen::Vector3f spec = spec_color * pow(std::fmax(R[i].dot(E), 0.0f), spec_shininess);
					Eigen::Vector3f color = eigen_clamp(diff + spec, 0.f, 1.f) * 255;
					image.setPixel(QPoint(x, y), qRgb(color.x(), color.y(), color.z()));
				}
			}
		}
	}

	QApplication app(argc, argv);
	QImageWidget widget;
	widget.setImage(image);
	widget.show();

	return app.exec();
}

int raycast_volume_test(int argc, char **argv)
{
	//int vx_count = 3;
	//int vx_size = 1;
	//int vx_count = 2;
	//int vx_size = 2;
	int vx_count = 3;
	int vx_size = 16;

	Eigen::Vector3i voxel_count(vx_count, vx_count, vx_count);
	Eigen::Vector3i voxel_size(vx_size, vx_size, vx_size);

	//Eigen::Vector3f ray_origin(0.5f, 0.5f, -1.0f);
	//Eigen::Vector3f ray_target(0.5f, 2.0f, 1.f);	// { 3, 6, 15, 24 }
	//Eigen::Vector3f ray_origin(2.f, 2.f, -2.0f);
	//Eigen::Vector3f ray_target(2.f, 2.f, 2.f);	// { 3, 7 }

	Eigen::Vector3f ray_origin(64.f, 64.f, -32.0f);
	Eigen::Vector3f ray_target(8.f, 8.f, 40.f);	// { 3, 7 }

	Eigen::Vector3f ray_direction = (ray_target - ray_origin).normalized();

	if (argc > 8)
	{
		vx_count = atoi(argv[1]);
		vx_size = atoi(argv[2]);

		voxel_count = Eigen::Vector3i(vx_count, vx_count, vx_count);
		voxel_size = Eigen::Vector3i(vx_size, vx_size, vx_size);

		ray_origin = Eigen::Vector3f(atof(argv[3]), atof(argv[4]), atof(argv[5]));
		ray_target = Eigen::Vector3f(atof(argv[6]), atof(argv[7]), atof(argv[8]));
		ray_direction = (ray_target - ray_origin).normalized();
	}

	std::vector<int> voxels_intersected;
	Timer t;
	t.start();
	raycast_volume<float>(ray_origin, ray_direction, voxel_count, voxel_size, voxels_intersected);
	t.print_interval("Raycasting volume       : ");

	std::cout << "Voxels Intersected: ";
	for (auto v : voxels_intersected)
		std::cout << v << ' ';
	std::cout << std::endl;

	return 0;
}

int main(int argc, char **argv)
{
#if 0
	// Usage: ./Raycastingd.exe vx_count vx_size cam_x y z target_x y z
	// Usage: ./Raycastingd.exe 3 1 1.5 1.5 -15 1.5 1.5 -10
	raycast_volume_test(argc, argv);
#endif

#if 0
	// Usage: ./Raycastingd.exe
	Timer t;
	t.start();
	raycast_and_render_two_triangles(argc, argv);
	t.print_interval("Raycasting and render   : ");
#endif

	// Usage: ./Raycastingd.exe vx_count vx_size
	// Usage: ./Raycastingd.exe 3 1
	raycast_and_render_grid(argc, argv);

	return 0;
}
<|endoftext|>


<commit_before>/*
    Copyright (c) 2010-2011 Sune Vuorela <sune@vuorela.dk>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#include "qrcodebarcode.h"
#include <qrencode.h>
using namespace prison;
/**
@cond PRIVATE
*/
class QRCodeBarcode::Private {
  public:
};
/**
@endcond
*/

QRCodeBarcode::QRCodeBarcode() : AbstractBarcode(), d(0){

}

QRCodeBarcode::~QRCodeBarcode() {
  delete d;
}

QImage QRCodeBarcode::toImage(const QSizeF& size) {
  const int width = qRound(qMin(size.width(),size.height()));
  if(data().size()==0 || width==0) {
    return QImage();
  }
  const QByteArray trimmedData(data().trimmed().toUtf8());
  QRcode* code = QRcode_encodeString8bit(trimmedData.constData(), 0, QR_ECLEVEL_Q);
  if(!code) {
    return QImage();
  }
  const int margin = 2;
  /*32 bit colors, 8 bit pr byte*/
  uchar* img = new uchar[4 *sizeof(char*)*(2*margin + code->width)*(2*margin* + code->width)];
  uchar* p = img;
  const char white = 0xff;
  const char black = 0x00;
  for(int row = 0 ; row < code->width+2*margin ; row++) {
    for(int col = 0 ; col < code->width+2*margin ; col++) {
      if(row < margin || row >= (code->width+margin) || col < margin || col >= (code->width+margin)) {
        /*4 bytes for color*/
        for(int i =0 ; i<4 ; i++) {
          *p = white;
          p++;
        }
      } else {
        int  c= (row-margin)*code->width + (col-margin);
        /*it is bit 1 that is the interesting bit for us from libqrencode*/
        if(code->data[c] & 1) {
          /*4 bytes for color*/
          for(int i =0 ; i<4 ; i++) {
            *p = black;
            p++;
          }
        } else {
          /*4 bytes for color*/
          for(int i =0 ; i<4 ; i++) {
            *p = white;
            p++;
          }
        }
      }
    }
  }
  QImage tmp(img,code->width+2*margin,code->width+2*margin,QImage::Format_RGB32);
  setMinimumSize(QSizeF(tmp.width()*4,tmp.height()*4));
  QImage ret = tmp.convertToFormat(QImage::Format_Mono).scaled(qMax(tmp.width()*4,width),qMax(tmp.height()*4,width)); //4 is determined by trial and error.
  delete[] img;
  QRcode_free(code);
  return ret;
}
<commit_msg>adapt qrbarcode to be able to use colors<commit_after>/*
    Copyright (c) 2010-2011 Sune Vuorela <sune@vuorela.dk>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#include "qrcodebarcode.h"
#include <qrencode.h>
#include <QColor>

using namespace prison;
/**
@cond PRIVATE
*/
class QRCodeBarcode::Private {
  public:
};
/**
@endcond
*/

QRCodeBarcode::QRCodeBarcode() : AbstractBarcode(), d(0){

}

QRCodeBarcode::~QRCodeBarcode() {
  delete d;
}

QImage QRCodeBarcode::toImage(const QSizeF& size) {
  const int width = qRound(qMin(size.width(),size.height()));
  if(data().size()==0 || width==0) {
    return QImage();
  }
  const QByteArray trimmedData(data().trimmed().toUtf8());
  QRcode* code = QRcode_encodeString8bit(trimmedData.constData(), 0, QR_ECLEVEL_Q);
  if(!code) {
    return QImage();
  }
  const int margin = 2;
  /*32 bit colors, 8 bit pr byte*/
  uchar* img = new uchar[4 *sizeof(char*)*(2*margin + code->width)*(2*margin* + code->width)];
  uchar* p = img;
  QByteArray background;
  background[3] = qAlpha(backgroundColor().rgba());
  background[2] = qRed(backgroundColor().rgba());
  background[1] = qGreen(backgroundColor().rgba());
  background[0] = qBlue(backgroundColor().rgba());
  QByteArray foreground;
  foreground[3] = qAlpha(foregroundColor().rgba());
  foreground[2] = qRed(foregroundColor().rgba());
  foreground[1] = qGreen(foregroundColor().rgba());
  foreground[0] = qBlue(foregroundColor().rgba());
  for(int row = 0 ; row < code->width+2*margin ; row++) {
    for(int col = 0 ; col < code->width+2*margin ; col++) {
      if(row < margin || row >= (code->width+margin) || col < margin || col >= (code->width+margin)) {
        /*4 bytes for color*/
        for(int i =0 ; i<4 ; i++) {
          *p = background[i];
          p++;
        }
      } else {
        int  c= (row-margin)*code->width + (col-margin);
        /*it is bit 1 that is the interesting bit for us from libqrencode*/
        if(code->data[c] & 1) {
          /*4 bytes for color*/
          for(int i =0 ; i<4 ; i++) {
            *p = foreground[i];
            p++;
          }
        } else {
          /*4 bytes for color*/
          for(int i =0 ; i<4 ; i++) {
            *p = background[i];
            p++;
          }
        }
      }
    }
  }
  QImage tmp(img,code->width+2*margin,code->width+2*margin,QImage::Format_ARGB32);
  setMinimumSize(QSizeF(tmp.width()*4,tmp.height()*4));
  QImage ret = tmp.convertToFormat(QImage::Format_ARGB32).scaled(qMax(tmp.width()*4,width),qMax(tmp.height()*4,width)); //4 is determined by trial and error.
  delete[] img;
  QRcode_free(code);
  return ret;
}
<|endoftext|>


<commit_before>/*
 * File:   lattisigns512-20130329/fastrandombytes.c
 * Author: Gim Güneysu, Tobias Oder, Thomas Pöppelmann, Peter Schwabe
 * Public Domain
 */

#include <inttypes.h>
#include <iostream>
#include "nfl/prng/crypto_stream_salsa20.h"
#include "nfl/prng/randombytes.h"

namespace nfl {

static int init = 0;
static unsigned char key[32];
static unsigned char nonce[8] = {0};

void fastrandombytes(unsigned char *r, unsigned long long rlen) {
  unsigned long long n = 0;
  int i;
  if (!init) {
    randombytes(key, 32);
    init = 1;
  }
  nfl_crypto_stream_salsa20_amd64_xmm6(r, rlen, nonce, key);

  // Increase 64-bit counter (nonce)
  for (i = 0; i < 8; i++) n ^= ((unsigned long long)nonce[i]) << 8 * i;
  n++;
  for (i = 0; i < 8; i++) nonce[i] = (n >> 8 * i) & 0xff;
}
}<commit_msg>symbolic values<commit_after>/*
 * File:   lattisigns512-20130329/fastrandombytes.c
 * Author: Gim Güneysu, Tobias Oder, Thomas Pöppelmann, Peter Schwabe
 * Public Domain
 */

#include <inttypes.h>
#include <iostream>
#include "nfl/prng/crypto_stream_salsa20.h"
#include "nfl/prng/randombytes.h"

#define nfl_crypto_stream_salsa20_KEYBYTES 32
#define nfl_crypto_stream_salsa20_NONCEBYTES 8

namespace nfl {

static int init = 0;
static unsigned char key[nfl_crypto_stream_salsa20_KEYBYTES];
static unsigned char nonce[nfl_crypto_stream_salsa20_NONCEBYTES] = {0};

void fastrandombytes(unsigned char *r, unsigned long long rlen) {
  unsigned long long n = 0;
  int i;
  if (!init) {
    randombytes(key, nfl_crypto_stream_salsa20_KEYBYTES);
    init = 1;
  }
  nfl_crypto_stream_salsa20_amd64_xmm6(r, rlen, nonce, key);

  // Increase 64-bit counter (nonce)
  for (i = 0; i < nfl_crypto_stream_salsa20_NONCEBYTES; i++) n ^= ((unsigned long long)nonce[i]) << 8 * i;
  n++;
  for (i = 0; i < nfl_crypto_stream_salsa20_NONCEBYTES; i++) nonce[i] = (n >> 8 * i) & 0xff;
}
}<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_PRODUCTS_BASE_HH
#define DUNE_GDT_PRODUCTS_BASE_HH

#include <dune/stuff/grid/walker.hh>

#include <dune/gdt/assembler/tmp-storage.hh>
#include <dune/gdt/assembler/local/codim0.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Products {

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template< class Traits >
class LocalizableBase
  : public LocalizableProductInterface< Traits >
  , public Stuff::Grid::Functor::Codim0< typename Traits::GridViewType >
{
  typedef LocalizableProductInterface< Traits > InterfaceType;
public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeType    RangeType;
  typedef typename Traits::SourceType   SourceType;
  typedef typename Traits::FieldType    FieldType;
private:
  typedef typename Traits::LocalOperatorType        LocalOperatorType;
  typedef TmpStorageProvider::Matrices< FieldType > TmpMatricesProviderType;

public:
  using typename InterfaceType::EntityType;

public:
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, const SourceType& src)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(src)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {}

  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(range_)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {}

  virtual ~LocalizableBase() {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeType& range() const
  {
    return range_;
  }

  const SourceType& source() const
  {
    return source_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!prepared_) {
      tmp_storage_ = std::unique_ptr< TmpMatricesProviderType >(new TmpMatricesProviderType(
        {1, local_operator().numTmpObjectsRequired()}, 1, 1));
      result_ *= 0.0;
      prepared_ = true;
    }
  } // ... prepare()

  FieldType compute_locally(const EntityType& entity)
  {
    assert(prepared_);
    assert(tmp_storage_);
    auto& tmp_storage = tmp_storage_->matrices();
    assert(tmp_storage.size() >= 2);
    assert(tmp_storage[0].size() >= 1);
    auto& local_operator_result = tmp_storage[0][0];
    auto& tmp_matrices = tmp_storage[1];
    // get the local functions
    const auto local_source_ptr = this->source().local_function(entity);
    const auto local_range_ptr = this->range().local_function(entity);
    // apply local operator
    local_operator().apply(*local_range_ptr, *local_source_ptr, local_operator_result, tmp_matrices);
    assert(local_operator_result.rows() == 1);
    assert(local_operator_result.cols() == 1);
    return local_operator_result[0][0];
  } // ... compute_locally(...)

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    result_ += compute_locally(entity);
  }

  virtual void finalize() DS_OVERRIDE
  {
    if (!finalized_) {
      result_ = grid_view_.comm().sum(result_);
      finalized_ = true;
    }
  }

  FieldType apply2()
  {
    if (!finalized_) {
      Stuff::Grid::Walker< GridViewType > grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
    }
    return result_;
  }

private:
  const GridViewType& grid_view_;
  const RangeType& range_;
  const SourceType& source_;
  std::unique_ptr< TmpMatricesProviderType > tmp_storage_;
  bool prepared_;
  bool finalized_;
  FieldType result_;
}; // class LocalizableBase

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template< class Traits >
class AssemblableBase
    : public AssemblableProductInterface< Traits >
    , public Stuff::Grid::Functor::Codim0< typename Traits::GridViewType >
{
  typedef AssemblableProductInterface< Traits > InterfaceType;
public:
  typedef typename Traits::GridViewType     GridViewType;
  typedef typename Traits::RangeSpaceType   RangeSpaceType;
  typedef typename Traits::SourceSpaceType  SourceSpaceType;
  typedef typename Traits::MatrixType       MatrixType;

  typedef typename MatrixType::ScalarType   FieldType;
private:
  typedef TmpStorageProvider::Matrices< FieldType >         TmpMatricesProviderType;
  typedef typename Traits::LocalOperatorType                LocalOperatorType;
  typedef LocalAssembler::Codim0Matrix< LocalOperatorType > LocalAssemblerType;

public:
  using typename InterfaceType::EntityType;

  using InterfaceType::pattern;

  AssemblableBase(MatrixType& mtrx,
                  const RangeSpaceType& rng_spc,
                  const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(src_spc)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {}

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {}

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(*(range_space_->grid_view()))
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!assembled_ && !prepared_) {
      local_assembler_ = std::unique_ptr< LocalAssemblerType >(new LocalAssemblerType(local_operator()));
      tmp_storage_
          = std::unique_ptr< TmpMatricesProviderType >(new TmpMatricesProviderType(local_assembler_->numTmpObjectsRequired(),
                                                                                range_space_.mapper().maxNumDofs(),
                                                                                source_space_.mapper().maxNumDofs()));
      prepared_ = true;
    }
  } // ... prepare()

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    assert(prepared_);
    assert(local_assembler_);
    assert(tmp_storage_);
    local_assembler_->assembleLocal(range_space_, source_space_,
                                    entity,
                                    matrix_,
                                    tmp_storage_->matrices(), tmp_storage_->indices());
  } // ... apply_local(...)

  void assemble()
  {
    if (!assembled_) {
      Stuff::Grid::Walker< GridViewType > grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
      assembled_ = true;
    }
  } // ... assemble()

  using InterfaceType::apply2;

private:
  MatrixType& matrix_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  const SourceSpaceType& source_space_;
  std::unique_ptr< LocalAssemblerType > local_assembler_;
  std::unique_ptr< TmpMatricesProviderType > tmp_storage_;
  bool prepared_;
  bool assembled_;
}; // class AssemblableBase

} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_HH
<commit_msg>[producsts.base] makes result variable atomic<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_PRODUCTS_BASE_HH
#define DUNE_GDT_PRODUCTS_BASE_HH

#include <dune/stuff/grid/walker.hh>

#include <dune/gdt/assembler/tmp-storage.hh>
#include <dune/gdt/assembler/local/codim0.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Products {

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template< class Traits >
class LocalizableBase
  : public LocalizableProductInterface< Traits >
  , public Stuff::Grid::Functor::Codim0< typename Traits::GridViewType >
{
  typedef LocalizableProductInterface< Traits > InterfaceType;
public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeType    RangeType;
  typedef typename Traits::SourceType   SourceType;
  typedef typename Traits::FieldType    FieldType;
private:
  typedef typename Traits::LocalOperatorType        LocalOperatorType;
  typedef TmpStorageProvider::Matrices< FieldType > TmpMatricesProviderType;

public:
  using typename InterfaceType::EntityType;

public:
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, const SourceType& src)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(src)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {}

  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(range_)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {}

  virtual ~LocalizableBase() {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeType& range() const
  {
    return range_;
  }

  const SourceType& source() const
  {
    return source_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!prepared_) {
      tmp_storage_ = std::unique_ptr< TmpMatricesProviderType >(new TmpMatricesProviderType(
        {1, local_operator().numTmpObjectsRequired()}, 1, 1));
      result_ = FieldType(0.0);
      prepared_ = true;
    }
  } // ... prepare()

  FieldType compute_locally(const EntityType& entity)
  {
    assert(prepared_);
    assert(tmp_storage_);
    auto& tmp_storage = tmp_storage_->matrices();
    assert(tmp_storage.size() >= 2);
    assert(tmp_storage[0].size() >= 1);
    auto& local_operator_result = tmp_storage[0][0];
    auto& tmp_matrices = tmp_storage[1];
    // get the local functions
    const auto local_source_ptr = this->source().local_function(entity);
    const auto local_range_ptr = this->range().local_function(entity);
    // apply local operator
    local_operator().apply(*local_range_ptr, *local_source_ptr, local_operator_result, tmp_matrices);
    assert(local_operator_result.rows() == 1);
    assert(local_operator_result.cols() == 1);
    return local_operator_result[0][0];
  } // ... compute_locally(...)

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    result_ = result_ + compute_locally(entity);
  }

  virtual void finalize() DS_OVERRIDE
  {
    if (!finalized_) {
      FieldType tmp = result_;
      result_ = grid_view_.comm().sum(tmp);
      finalized_ = true;
    }
  }

  FieldType apply2()
  {
    if (!finalized_) {
      Stuff::Grid::Walker< GridViewType > grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
    }
    return result_;
  }

private:
  const GridViewType& grid_view_;
  const RangeType& range_;
  const SourceType& source_;
  std::unique_ptr< TmpMatricesProviderType > tmp_storage_;
  bool prepared_;
  bool finalized_;
  std::atomic<FieldType> result_;
}; // class LocalizableBase

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template< class Traits >
class AssemblableBase
    : public AssemblableProductInterface< Traits >
    , public Stuff::Grid::Functor::Codim0< typename Traits::GridViewType >
{
  typedef AssemblableProductInterface< Traits > InterfaceType;
public:
  typedef typename Traits::GridViewType     GridViewType;
  typedef typename Traits::RangeSpaceType   RangeSpaceType;
  typedef typename Traits::SourceSpaceType  SourceSpaceType;
  typedef typename Traits::MatrixType       MatrixType;

  typedef typename MatrixType::ScalarType   FieldType;
private:
  typedef TmpStorageProvider::Matrices< FieldType >         TmpMatricesProviderType;
  typedef typename Traits::LocalOperatorType                LocalOperatorType;
  typedef LocalAssembler::Codim0Matrix< LocalOperatorType > LocalAssemblerType;

public:
  using typename InterfaceType::EntityType;

  using InterfaceType::pattern;

  AssemblableBase(MatrixType& mtrx,
                  const RangeSpaceType& rng_spc,
                  const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(src_spc)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {}

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {}

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(*(range_space_->grid_view()))
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!assembled_ && !prepared_) {
      local_assembler_ = std::unique_ptr< LocalAssemblerType >(new LocalAssemblerType(local_operator()));
      tmp_storage_
          = std::unique_ptr< TmpMatricesProviderType >(new TmpMatricesProviderType(local_assembler_->numTmpObjectsRequired(),
                                                                                range_space_.mapper().maxNumDofs(),
                                                                                source_space_.mapper().maxNumDofs()));
      prepared_ = true;
    }
  } // ... prepare()

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    assert(prepared_);
    assert(local_assembler_);
    assert(tmp_storage_);
    local_assembler_->assembleLocal(range_space_, source_space_,
                                    entity,
                                    matrix_,
                                    tmp_storage_->matrices(), tmp_storage_->indices());
  } // ... apply_local(...)

  void assemble()
  {
    if (!assembled_) {
      Stuff::Grid::Walker< GridViewType > grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
      assembled_ = true;
    }
  } // ... assemble()

  using InterfaceType::apply2;

private:
  MatrixType& matrix_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  const SourceSpaceType& source_space_;
  std::unique_ptr< LocalAssemblerType > local_assembler_;
  std::unique_ptr< TmpMatricesProviderType > tmp_storage_;
  bool prepared_;
  bool assembled_;
}; // class AssemblableBase

} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_HH
<|endoftext|>


<commit_before>#include <sstream>

#include "Object.h"
#include "Natives.h"
#include "VM.h"

namespace magpie
{
  NATIVE(objectClass)
  {
    // This assumes the args list has, in order, the class object and then all
    // of the field values for that class.
    return args[0]->getClass(vm);
  }

  NATIVE(objectNew)
  {
    // This assumes the args list has, in order, the class object and then all
    // of the field values for that class.
    return DynamicObject::create(args);
  }

  NATIVE(objectToString)
  {
    // TODO(bob): Can definitely do something more efficient here!
    std::stringstream stream;
    stream << args[0];
    return new StringObject(String::create(stream.str().c_str()));
  }

  NATIVE(printString)
  {
    std::cout << args[0]->toString() << std::endl;
    return args[0];
  }

  NATIVE(numPlusNum)
  {
    double c = args[0]->toNumber() + args[1]->toNumber();
    return new NumberObject(c);
  }

  NATIVE(stringPlusString)
  {
    return new StringObject(
        String::concat(args[0]->toString(), args[1]->toString()));
  }

  NATIVE(numMinusNum)
  {
    double c = args[0]->toNumber() - args[1]->toNumber();
    return new NumberObject(c);
  }

  NATIVE(numTimesNum)
  {
    double c = args[0]->toNumber() * args[1]->toNumber();
    return new NumberObject(c);
  }

  NATIVE(numDivNum)
  {
    double c = args[0]->toNumber() / args[1]->toNumber();
    return new NumberObject(c);
  }

  NATIVE(numLessThanNum)
  {
    return vm.getBool(args[0]->toNumber() < args[1]->toNumber());
  }

  NATIVE(numLessThanEqualToNum)
  {
    return vm.getBool(args[0]->toNumber() <= args[1]->toNumber());
  }

  NATIVE(numGreaterThanNum)
  {
    return vm.getBool(args[0]->toNumber() > args[1]->toNumber());
  }

  NATIVE(numGreaterThanEqualToNum)
  {
    return vm.getBool(args[0]->toNumber() >= args[1]->toNumber());
  }

  NATIVE(stringCount)
  {
    double c = args[0]->toString()->length();
    return new NumberObject(c);
  }

  NATIVE(numToString)
  {
    double n = args[0]->toNumber();
    return new StringObject(String::format("%g", n));
  }

  NATIVE(listAdd)
  {
    ListObject* list = args[0]->toList();
    list->elements().add(args[1]);
    return args[1];
  }

  NATIVE(listCount)
  {
    ListObject* list = args[0]->toList();
    return new NumberObject(list->elements().count());
  }

  NATIVE(listIndex)
  {
    ListObject* list = args[0]->toList();
    // TODO(bob): What if the index isn't an int?
    return list->elements()[static_cast<int>(args[1]->toNumber())];
  }

  NATIVE(listIndexSet)
  {
    ListObject* list = args[0]->toList();
    // TODO(bob): What if the index isn't an int?
    list->elements()[static_cast<int>(args[1]->toNumber())] = args[2];
    return args[2];
  }

  NATIVE(listInsert)
  {
    ListObject* list = args[0]->toList();
    gc<Object> value = args[1];
    // TODO(bob): How do we want to handle non-integer indices?
    int index = static_cast<int>(args[2]->toNumber());
    list->elements().insert(value, index);
    return args[1];
  }
}

<commit_msg>Remove copy/pasted comment.<commit_after>#include <sstream>

#include "Object.h"
#include "Natives.h"
#include "VM.h"

namespace magpie
{
  NATIVE(objectClass)
  {
    return args[0]->getClass(vm);
  }

  NATIVE(objectNew)
  {
    // This assumes the args list has, in order, the class object and then all
    // of the field values for that class.
    return DynamicObject::create(args);
  }

  NATIVE(objectToString)
  {
    // TODO(bob): Can definitely do something more efficient here!
    std::stringstream stream;
    stream << args[0];
    return new StringObject(String::create(stream.str().c_str()));
  }

  NATIVE(printString)
  {
    std::cout << args[0]->toString() << std::endl;
    return args[0];
  }

  NATIVE(numPlusNum)
  {
    double c = args[0]->toNumber() + args[1]->toNumber();
    return new NumberObject(c);
  }

  NATIVE(stringPlusString)
  {
    return new StringObject(
        String::concat(args[0]->toString(), args[1]->toString()));
  }

  NATIVE(numMinusNum)
  {
    double c = args[0]->toNumber() - args[1]->toNumber();
    return new NumberObject(c);
  }

  NATIVE(numTimesNum)
  {
    double c = args[0]->toNumber() * args[1]->toNumber();
    return new NumberObject(c);
  }

  NATIVE(numDivNum)
  {
    double c = args[0]->toNumber() / args[1]->toNumber();
    return new NumberObject(c);
  }

  NATIVE(numLessThanNum)
  {
    return vm.getBool(args[0]->toNumber() < args[1]->toNumber());
  }

  NATIVE(numLessThanEqualToNum)
  {
    return vm.getBool(args[0]->toNumber() <= args[1]->toNumber());
  }

  NATIVE(numGreaterThanNum)
  {
    return vm.getBool(args[0]->toNumber() > args[1]->toNumber());
  }

  NATIVE(numGreaterThanEqualToNum)
  {
    return vm.getBool(args[0]->toNumber() >= args[1]->toNumber());
  }

  NATIVE(stringCount)
  {
    double c = args[0]->toString()->length();
    return new NumberObject(c);
  }

  NATIVE(numToString)
  {
    double n = args[0]->toNumber();
    return new StringObject(String::format("%g", n));
  }

  NATIVE(listAdd)
  {
    ListObject* list = args[0]->toList();
    list->elements().add(args[1]);
    return args[1];
  }

  NATIVE(listCount)
  {
    ListObject* list = args[0]->toList();
    return new NumberObject(list->elements().count());
  }

  NATIVE(listIndex)
  {
    ListObject* list = args[0]->toList();
    // TODO(bob): What if the index isn't an int?
    return list->elements()[static_cast<int>(args[1]->toNumber())];
  }

  NATIVE(listIndexSet)
  {
    ListObject* list = args[0]->toList();
    // TODO(bob): What if the index isn't an int?
    list->elements()[static_cast<int>(args[1]->toNumber())] = args[2];
    return args[2];
  }

  NATIVE(listInsert)
  {
    ListObject* list = args[0]->toList();
    gc<Object> value = args[1];
    // TODO(bob): How do we want to handle non-integer indices?
    int index = static_cast<int>(args[2]->toNumber());
    list->elements().insert(value, index);
    return args[1];
  }
}

<|endoftext|>


<commit_before>//===-- ubsan_type_hash.cc ------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implementation of a hash table for fast checking of inheritance
// relationships. This file is only linked into C++ compilations, and is
// permitted to use language features which require a C++ ABI library.
//
//===----------------------------------------------------------------------===//

#include "ubsan_type_hash.h"

#include "sanitizer_common/sanitizer_common.h"

// The following are intended to be binary compatible with the definitions
// given in the Itanium ABI. We make no attempt to be ODR-compatible with
// those definitions, since existing ABI implementations aren't.

namespace std {
  class type_info {
  public:
    virtual ~type_info();
  private:
    const char *__type_name;
  };
}

namespace __cxxabiv1 {

/// Type info for classes with no bases, and base class for type info for
/// classes with bases.
class __class_type_info : public std::type_info {
  virtual ~__class_type_info();
};

/// Type info for classes with simple single public inheritance.
class __si_class_type_info : public __class_type_info {
public:
  virtual ~__si_class_type_info();

  const __class_type_info *__base_type;
};

class __base_class_type_info {
public:
  const __class_type_info *__base_type;
  long __offset_flags;

  enum __offset_flags_masks {
    __virtual_mask = 0x1,
    __public_mask = 0x2,
    __offset_shift = 8
  };
};

/// Type info for classes with multiple, virtual, or non-public inheritance.
class __vmi_class_type_info : public __class_type_info {
public:
  virtual ~__vmi_class_type_info();

  unsigned int flags;
  unsigned int base_count;
  __base_class_type_info base_info[1];
};

}

namespace abi = __cxxabiv1;

// We implement a simple two-level cache for type-checking results. For each
// (vptr,type) pair, a hash is computed. This hash is assumed to be globally
// unique; if it collides, we will get false negatives, but:
//  * such a collision would have to occur on the *first* bad access,
//  * the probability of such a collision is low (and for a 64-bit target, is
//    negligible), and
//  * the vptr, and thus the hash, can be affected by ASLR, so multiple runs
//    give better coverage.
//
// The first caching layer is a small hash table with no chaining; buckets are
// reused as needed. The second caching layer is a large hash table with open
// chaining. We can freely evict from either layer since this is just a cache.
//
// FIXME: Make these hash table accesses thread-safe. The races here are benign
//        (worst-case, we could miss a bug or see a slowdown) but we should
//        avoid upsetting race detectors.

/// Find a bucket to store the given hash value in.
static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
  static const unsigned HashTableSize = 65537;
  static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize] = { 1 };

  unsigned Probe = V & 65535;
  for (int Tries = 5; Tries; --Tries) {
    if (!__ubsan_vptr_hash_set[Probe] || __ubsan_vptr_hash_set[Probe] == V)
      return &__ubsan_vptr_hash_set[Probe];
    Probe += ((V >> 16) & 65535) + 1;
    if (Probe >= HashTableSize)
      Probe -= HashTableSize;
  }
  // FIXME: Pick a random entry from the probe sequence to evict rather than
  //        just taking the first.
  return &__ubsan_vptr_hash_set[V];
}

/// A cache of recently-checked hashes. Mini hash table with "random" evictions.
__ubsan::HashValue __ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize] = { 1 };

/// \brief Determine whether \p Derived has a \p Base base class subobject at
/// offset \p Offset.
static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
                                  const abi::__class_type_info *Base,
                                  sptr Offset) {
  if (Derived == Base)
    return Offset == 0;

  if (const abi::__si_class_type_info *SI =
        dynamic_cast<const abi::__si_class_type_info*>(Derived))
    return isDerivedFromAtOffset(SI->__base_type, Base, Offset);

  const abi::__vmi_class_type_info *VTI =
    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
  if (!VTI)
    // No base class subobjects.
    return false;

  // Look for a zero-offset base class which is derived from \p Base.
  for (unsigned int base = 0; base != VTI->base_count; ++base) {
    // FIXME: Curtail the recursion if this base can't possibly contain the
    //        given offset.
    sptr OffsetHere = VTI->base_info[base].__offset_flags >>
                      abi::__base_class_type_info::__offset_shift;
    if (VTI->base_info[base].__offset_flags &
          abi::__base_class_type_info::__virtual_mask)
      // For now, just punt on virtual bases and say 'yes'.
      // FIXME: OffsetHere is the offset in the vtable of the virtual base
      //        offset. Read the vbase offset out of the vtable and use it.
      return true;
    if (isDerivedFromAtOffset(VTI->base_info[base].__base_type,
                              Base, Offset - OffsetHere))
      return true;
  }

  return false;
}

namespace {

struct VtablePrefix {
  /// The offset from the vptr to the start of the most-derived object.
  /// This should never be greater than zero, and will usually be exactly
  /// zero.
  sptr Offset;
  /// The type_info object describing the most-derived class type.
  std::type_info *TypeInfo;
};
VtablePrefix *getVtablePrefix(void *Object) {
  VtablePrefix **Ptr = reinterpret_cast<VtablePrefix**>(Object);
  return *Ptr - 1;
}

}

bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
  // A crash anywhere within this function probably means the vptr is corrupted.
  // FIXME: Perform these checks more cautiously.

  // Check whether this is something we've evicted from the cache.
  HashValue *Bucket = getTypeCacheHashTableBucket(Hash);
  if (*Bucket == Hash) {
    __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
    return true;
  }

  VtablePrefix *Vtable = getVtablePrefix(Object);
  if (Vtable + 1 == 0 || Vtable->Offset > 0)
    // This can't possibly be a valid vtable.
    return false;

  // Check that this is actually a type_info object for a class type.
  abi::__class_type_info *Derived =
    dynamic_cast<abi::__class_type_info*>(Vtable->TypeInfo);
  if (!Derived)
    return false;

  abi::__class_type_info *Base = (abi::__class_type_info*)Type;
  if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset))
    return false;

  // Success. Cache this result.
  __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
  *Bucket = Hash;
  return true;
}
<commit_msg>Consistently declare 'extern "C"' variable in namespace __ubsan. No functionality change.<commit_after>//===-- ubsan_type_hash.cc ------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implementation of a hash table for fast checking of inheritance
// relationships. This file is only linked into C++ compilations, and is
// permitted to use language features which require a C++ ABI library.
//
//===----------------------------------------------------------------------===//

#include "ubsan_type_hash.h"

#include "sanitizer_common/sanitizer_common.h"

// The following are intended to be binary compatible with the definitions
// given in the Itanium ABI. We make no attempt to be ODR-compatible with
// those definitions, since existing ABI implementations aren't.

namespace std {
  class type_info {
  public:
    virtual ~type_info();
  private:
    const char *__type_name;
  };
}

namespace __cxxabiv1 {

/// Type info for classes with no bases, and base class for type info for
/// classes with bases.
class __class_type_info : public std::type_info {
  virtual ~__class_type_info();
};

/// Type info for classes with simple single public inheritance.
class __si_class_type_info : public __class_type_info {
public:
  virtual ~__si_class_type_info();

  const __class_type_info *__base_type;
};

class __base_class_type_info {
public:
  const __class_type_info *__base_type;
  long __offset_flags;

  enum __offset_flags_masks {
    __virtual_mask = 0x1,
    __public_mask = 0x2,
    __offset_shift = 8
  };
};

/// Type info for classes with multiple, virtual, or non-public inheritance.
class __vmi_class_type_info : public __class_type_info {
public:
  virtual ~__vmi_class_type_info();

  unsigned int flags;
  unsigned int base_count;
  __base_class_type_info base_info[1];
};

}

namespace abi = __cxxabiv1;

// We implement a simple two-level cache for type-checking results. For each
// (vptr,type) pair, a hash is computed. This hash is assumed to be globally
// unique; if it collides, we will get false negatives, but:
//  * such a collision would have to occur on the *first* bad access,
//  * the probability of such a collision is low (and for a 64-bit target, is
//    negligible), and
//  * the vptr, and thus the hash, can be affected by ASLR, so multiple runs
//    give better coverage.
//
// The first caching layer is a small hash table with no chaining; buckets are
// reused as needed. The second caching layer is a large hash table with open
// chaining. We can freely evict from either layer since this is just a cache.
//
// FIXME: Make these hash table accesses thread-safe. The races here are benign
//        (worst-case, we could miss a bug or see a slowdown) but we should
//        avoid upsetting race detectors.

/// Find a bucket to store the given hash value in.
static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
  static const unsigned HashTableSize = 65537;
  static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize] = { 1 };

  unsigned Probe = V & 65535;
  for (int Tries = 5; Tries; --Tries) {
    if (!__ubsan_vptr_hash_set[Probe] || __ubsan_vptr_hash_set[Probe] == V)
      return &__ubsan_vptr_hash_set[Probe];
    Probe += ((V >> 16) & 65535) + 1;
    if (Probe >= HashTableSize)
      Probe -= HashTableSize;
  }
  // FIXME: Pick a random entry from the probe sequence to evict rather than
  //        just taking the first.
  return &__ubsan_vptr_hash_set[V];
}

/// A cache of recently-checked hashes. Mini hash table with "random" evictions.
__ubsan::HashValue
__ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize] = { 1 };

/// \brief Determine whether \p Derived has a \p Base base class subobject at
/// offset \p Offset.
static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
                                  const abi::__class_type_info *Base,
                                  sptr Offset) {
  if (Derived == Base)
    return Offset == 0;

  if (const abi::__si_class_type_info *SI =
        dynamic_cast<const abi::__si_class_type_info*>(Derived))
    return isDerivedFromAtOffset(SI->__base_type, Base, Offset);

  const abi::__vmi_class_type_info *VTI =
    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
  if (!VTI)
    // No base class subobjects.
    return false;

  // Look for a zero-offset base class which is derived from \p Base.
  for (unsigned int base = 0; base != VTI->base_count; ++base) {
    // FIXME: Curtail the recursion if this base can't possibly contain the
    //        given offset.
    sptr OffsetHere = VTI->base_info[base].__offset_flags >>
                      abi::__base_class_type_info::__offset_shift;
    if (VTI->base_info[base].__offset_flags &
          abi::__base_class_type_info::__virtual_mask)
      // For now, just punt on virtual bases and say 'yes'.
      // FIXME: OffsetHere is the offset in the vtable of the virtual base
      //        offset. Read the vbase offset out of the vtable and use it.
      return true;
    if (isDerivedFromAtOffset(VTI->base_info[base].__base_type,
                              Base, Offset - OffsetHere))
      return true;
  }

  return false;
}

namespace {

struct VtablePrefix {
  /// The offset from the vptr to the start of the most-derived object.
  /// This should never be greater than zero, and will usually be exactly
  /// zero.
  sptr Offset;
  /// The type_info object describing the most-derived class type.
  std::type_info *TypeInfo;
};
VtablePrefix *getVtablePrefix(void *Object) {
  VtablePrefix **Ptr = reinterpret_cast<VtablePrefix**>(Object);
  return *Ptr - 1;
}

}

bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
  // A crash anywhere within this function probably means the vptr is corrupted.
  // FIXME: Perform these checks more cautiously.

  // Check whether this is something we've evicted from the cache.
  HashValue *Bucket = getTypeCacheHashTableBucket(Hash);
  if (*Bucket == Hash) {
    __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
    return true;
  }

  VtablePrefix *Vtable = getVtablePrefix(Object);
  if (Vtable + 1 == 0 || Vtable->Offset > 0)
    // This can't possibly be a valid vtable.
    return false;

  // Check that this is actually a type_info object for a class type.
  abi::__class_type_info *Derived =
    dynamic_cast<abi::__class_type_info*>(Vtable->TypeInfo);
  if (!Derived)
    return false;

  abi::__class_type_info *Base = (abi::__class_type_info*)Type;
  if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset))
    return false;

  // Success. Cache this result.
  __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
  *Bucket = Hash;
  return true;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: moduleuicfgsupplier.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 00:40:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef __FRAMEWORK_UICONFIGURATION_MODULEUICFGSUPPLIER_HXX_
#define __FRAMEWORK_UICONFIGURATION_MODULEUICFGSUPPLIER_HXX_

/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
               with solaris headers ...
*/
#include <vector>
#include <list>
#include <hash_map>

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
#include <threadhelp/threadhelpbase.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XINTERFACE_HXX_
#include <macros/xinterface.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XTYPEPROVIDER_HXX_
#include <macros/xtypeprovider.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XSERVICEINFO_HXX_
#include <macros/xserviceinfo.hxx>
#endif

#ifndef __FRAMEWORK_STDTYPES_H_
#include <stdtypes.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XTYPEPROVIDER_HPP_
#include <com/sun/star/lang/XTypeProvider.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

#ifndef _COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_
#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
#endif

#ifndef _COM_SUN_STAR_UI_XUICONFIGURATIONMANAGER_HPP_
#include <com/sun/star/ui/XUIConfigurationManager.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
#include <com/sun/star/frame/XModuleManager.hpp>
#endif

#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif

#ifndef _COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
#include <com/sun/star/embed/XTransactedObject.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

namespace framework
{
    class ModuleUIConfigurationManagerSupplier : public com::sun::star::lang::XTypeProvider ,
                                                 public com::sun::star::lang::XServiceInfo  ,
                                                 public com::sun::star::lang::XComponent    ,
                                                 public ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier      ,
                                                 private ThreadHelpBase                     ,   // Struct for right initalization of mutex member! Must be first of baseclasses.
                                                 public ::cppu::OWeakObject
    {
        public:
            //  XInterface, XTypeProvider, XServiceInfo
            DECLARE_XINTERFACE
            DECLARE_XTYPEPROVIDER
            DECLARE_XSERVICEINFO

            ModuleUIConfigurationManagerSupplier( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rServiceManager );
            virtual ~ModuleUIConfigurationManagerSupplier();

            // XComponent
            virtual void SAL_CALL dispose()
                throw (::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener )
                throw (::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener )
                throw (::com::sun::star::uno::RuntimeException);

            // XModuleUIConfigurationManagerSupplier
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > SAL_CALL getUIConfigurationManager( const ::rtl::OUString& ModuleIdentifier )
                throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);

        private:
            typedef ::std::hash_map< rtl::OUString, com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager >, OUStringHashCode, ::std::equal_to< rtl::OUString > > ModuleToModuleCfgMgr;

//TODO_AS            void impl_initStorages();

            // private methods
            ModuleToModuleCfgMgr                                                                m_aModuleToModuleUICfgMgrMap;
            bool                                                                                m_bDisposed;
// TODO_AS            bool                                                                                m_bInit;
            rtl::OUString                                                                       m_aDefaultConfigURL;
            rtl::OUString                                                                       m_aUserConfigURL;
            com::sun::star::uno::Reference< com::sun::star::embed::XStorage >                   m_xDefaultCfgRootStorage;
            com::sun::star::uno::Reference< com::sun::star::embed::XStorage >                   m_xUserCfgRootStorage;
            com::sun::star::uno::Reference< com::sun::star::embed::XTransactedObject >          m_xUserRootCommit;
            com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager >   m_xModuleMgr;
            com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >        m_xServiceManager;
            ::cppu::OMultiTypeInterfaceContainerHelper                                          m_aListenerContainer;   /// container for ALL Listener
   };
}

#endif // __FRAMEWORK_UICONFIGURATION_MODULEUICFGSUPPLIER_HXX_
<commit_msg>INTEGRATION: CWS warnings01 (1.5.32); FILE MERGED 2005/10/28 14:48:19 cd 1.5.32.1: #i55991# Warning free code changes for gcc<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: moduleuicfgsupplier.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 11:03:08 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef __FRAMEWORK_UICONFIGURATION_MODULEUICFGSUPPLIER_HXX_
#define __FRAMEWORK_UICONFIGURATION_MODULEUICFGSUPPLIER_HXX_

/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
               with solaris headers ...
*/
#include <vector>
#include <list>
#include <hash_map>

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
#include <threadhelp/threadhelpbase.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XINTERFACE_HXX_
#include <macros/xinterface.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XTYPEPROVIDER_HXX_
#include <macros/xtypeprovider.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XSERVICEINFO_HXX_
#include <macros/xserviceinfo.hxx>
#endif

#ifndef __FRAMEWORK_STDTYPES_H_
#include <stdtypes.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XTYPEPROVIDER_HPP_
#include <com/sun/star/lang/XTypeProvider.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

#ifndef _COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_
#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
#endif

#ifndef _COM_SUN_STAR_UI_XUICONFIGURATIONMANAGER_HPP_
#include <com/sun/star/ui/XUIConfigurationManager.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
#include <com/sun/star/frame/XModuleManager.hpp>
#endif

#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif

#ifndef _COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
#include <com/sun/star/embed/XTransactedObject.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

namespace framework
{
    class ModuleUIConfigurationManagerSupplier : public com::sun::star::lang::XTypeProvider ,
                                                 public com::sun::star::lang::XServiceInfo  ,
                                                 public com::sun::star::lang::XComponent    ,
                                                 public ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier      ,
                                                 private ThreadHelpBase                     ,   // Struct for right initalization of mutex member! Must be first of baseclasses.
                                                 public ::cppu::OWeakObject
    {
        public:
            //  XInterface, XTypeProvider, XServiceInfo
            FWK_DECLARE_XINTERFACE
            FWK_DECLARE_XTYPEPROVIDER
            DECLARE_XSERVICEINFO

            ModuleUIConfigurationManagerSupplier( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rServiceManager );
            virtual ~ModuleUIConfigurationManagerSupplier();

            // XComponent
            virtual void SAL_CALL dispose()
                throw (::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener )
                throw (::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener )
                throw (::com::sun::star::uno::RuntimeException);

            // XModuleUIConfigurationManagerSupplier
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > SAL_CALL getUIConfigurationManager( const ::rtl::OUString& ModuleIdentifier )
                throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);

        private:
            typedef ::std::hash_map< rtl::OUString, com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager >, OUStringHashCode, ::std::equal_to< rtl::OUString > > ModuleToModuleCfgMgr;

//TODO_AS            void impl_initStorages();

            // private methods
            ModuleToModuleCfgMgr                                                                m_aModuleToModuleUICfgMgrMap;
            bool                                                                                m_bDisposed;
// TODO_AS            bool                                                                                m_bInit;
            rtl::OUString                                                                       m_aDefaultConfigURL;
            rtl::OUString                                                                       m_aUserConfigURL;
            com::sun::star::uno::Reference< com::sun::star::embed::XStorage >                   m_xDefaultCfgRootStorage;
            com::sun::star::uno::Reference< com::sun::star::embed::XStorage >                   m_xUserCfgRootStorage;
            com::sun::star::uno::Reference< com::sun::star::embed::XTransactedObject >          m_xUserRootCommit;
            com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager >   m_xModuleMgr;
            com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >        m_xServiceManager;
            ::cppu::OMultiTypeInterfaceContainerHelper                                          m_aListenerContainer;   /// container for ALL Listener
   };
}

#endif // __FRAMEWORK_UICONFIGURATION_MODULEUICFGSUPPLIER_HXX_
<|endoftext|>


<commit_before>/* Copyright 2015 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

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

#include "tensorflow/core/common_runtime/constant_folding.h"

#include "tensorflow/core/common_runtime/device_factory.h"
#include "tensorflow/core/common_runtime/device_mgr.h"
#include "tensorflow/core/framework/node_def_util.h"
#include "tensorflow/core/framework/tensor_testutil.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/graph/node_builder.h"
#include "tensorflow/core/graph/testlib.h"
#include "tensorflow/core/lib/core/status_test_util.h"
#include "tensorflow/core/lib/core/threadpool.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/public/session_options.h"
#include "tensorflow/core/public/tensor.h"
#include "tensorflow/core/public/tensor_shape.h"

namespace tensorflow {
namespace {

class ConstantFoldingTest : public ::testing::Test {
 protected:
  ConstantFoldingTest() { Reset(); }
  void Reset() { g_.reset(new Graph(OpRegistry::Global())); }

  template <typename T>
  Node* Constant(gtl::ArraySlice<T> values, TensorShape shape) {
    return test::graph::Constant(g_.get(), test::AsTensor(values, shape));
  }

  template <typename T>
  void ExpectNodeClose(const Node* n, gtl::ArraySlice<T> values,
                       TensorShape shape) {
    EXPECT_TRUE(n->IsConstant());
    const TensorProto* tensor_proto;
    TF_EXPECT_OK(GetNodeAttr(n->def(), "value", &tensor_proto));
    DataType dtype;
    TF_EXPECT_OK(GetNodeAttr(n->def(), "dtype", &dtype));
    Tensor t(dtype);
    EXPECT_TRUE(t.FromProto(*tensor_proto));
    test::ExpectClose(t, test::AsTensor(values, shape));
  }

  template <typename T>
  void ExpectNodeEqual(const Node* n, gtl::ArraySlice<T> values,
                       TensorShape shape) {
    EXPECT_TRUE(n->IsConstant());
    const TensorProto* tensor_proto;
    EXPECT_OK(GetNodeAttr(n->def(), "value", &tensor_proto));
    DataType dtype;
    EXPECT_OK(GetNodeAttr(n->def(), "dtype", &dtype));
    Tensor t(dtype);
    EXPECT_TRUE(t.FromProto(*tensor_proto));
    test::ExpectTensorEqual<T>(t, test::AsTensor(values, shape));
  }

// Construct the following graph
//    s1  s2
//    |    |
//    m1   m2
//    / \ / \
//   a   b   c
#define SIMPLE_GRAPH                                                  \
  Reset();                                                            \
  Graph* g = g_.get();                                                \
  Node* a = Constant<float>({1.0, 0.0, 0.0, 1.0}, {2, 2});            \
  Node* b = Constant<float>({1.0, 2.0, 3.0, 4.0}, {2, 2});            \
  Node* c = Constant<float>({0.0, 1.0, 1.0, 0.0}, {2, 2});            \
  g->AddControlEdge(g->source_node(), a);                             \
  g->AddControlEdge(g->source_node(), b);                             \
  g->AddControlEdge(g->source_node(), c);                             \
  Node* m1 = test::graph::Matmul(g, a, b, false, false);              \
  Node* s1 = test::graph::Send(g, m1, "m1", "sender", 0, "receiver"); \
  Node* m2 = test::graph::Matmul(g, b, c, false, false);              \
  Node* s2 = test::graph::Send(g, m2, "m2", "sender", 0, "receiver"); \
  g->AddControlEdge(s1, g->sink_node());                              \
  g->AddControlEdge(s2, g->sink_node());

  std::unique_ptr<Graph> g_;
};

TEST_F(ConstantFoldingTest, Basic) {
  SIMPLE_GRAPH;
  EXPECT_TRUE(DoConstantFolding(ConstantFoldingOptions{}, g));

  // Nodes s1 and s2 now should now have a constant input
  EXPECT_EQ(1, s1->num_inputs());
  ExpectNodeClose<float>(*(s1->in_nodes().begin()), {1.0, 2.0, 3.0, 4.0},
                         {2, 2});
  EXPECT_EQ(1, s2->num_inputs());
  ExpectNodeClose<float>(*(s2->in_nodes().begin()), {2.0, 1.0, 4.0, 3.0},
                         {2, 2});
}

TEST_F(ConstantFoldingTest, ConsiderFunction) {
  SIMPLE_GRAPH;
  ConstantFoldingOptions opts;
  // Do not allow constant folding of m2
  opts.consider = [m2](const Node* n) { return m2 != n; };
  EXPECT_TRUE(DoConstantFolding(opts, g));

  // Node s1 now should now have a constant input
  EXPECT_EQ(1, s1->num_inputs());
  ExpectNodeClose<float>(*(s1->in_nodes().begin()), {1.0, 2.0, 3.0, 4.0},
                         {2, 2});
  // s2's input should still be m2
  EXPECT_EQ(1, s2->num_inputs());
  EXPECT_EQ(*(s2->in_nodes().begin()), m2);
}
#undef SIMPLE_GRAPH

TEST_F(ConstantFoldingTest, TwoOutputs) {
  Reset();
  Graph* g = g_.get();
  Node* s0 = Constant<int>({1}, {1});
  Node* s1 = Constant<int>({2, 2}, {2});
  g->AddControlEdge(g->source_node(), s0);
  g->AddControlEdge(g->source_node(), s1);
  Node* b = test::graph::BroadcastGradientArgs(g, s0, s1);
  Node* b0 = test::graph::Send(g, test::graph::Identity(g, b, 0),
                               strings::StrCat(b->name(), "0"), "sender", 0,
                               "receiver");
  Node* b1 = test::graph::Send(g, test::graph::Identity(g, b, 1),
                               strings::StrCat(b->name(), "1"), "sender", 0,
                               "receiver");
  g->AddControlEdge(b0, g->sink_node());
  g->AddControlEdge(b1, g->sink_node());

  EXPECT_TRUE(DoConstantFolding(ConstantFoldingOptions{}, g));
  EXPECT_EQ(1, b0->num_inputs());
  ExpectNodeEqual<int>(*(b0->in_nodes().begin()), {0, 1}, {2});
  EXPECT_EQ(1, b1->num_inputs());
  ExpectNodeEqual<int>(*(b1->in_nodes().begin()), {}, {0});
}

TEST_F(ConstantFoldingTest, TwoOutputsFoldOneOutput) {
  Reset();
  Graph* g = g_.get();
  Node* s0 = Constant<int>({1}, {1});
  Node* s1 = Constant<int>({2, 2}, {2});
  g->AddControlEdge(g->source_node(), s0);
  g->AddControlEdge(g->source_node(), s1);
  Node* b = test::graph::BroadcastGradientArgs(g, s0, s1);
  Node* b0 = test::graph::Send(g, test::graph::Identity(g, b, 0),
                               strings::StrCat(b->name(), "0"), "sender", 0,
                               "receiver");
  Node* b1_ident = test::graph::Identity(g, b, 1);
  Node* b1 = test::graph::Send(g, b1_ident, strings::StrCat(b->name(), "1"),
                               "sender", 0, "receiver");
  g->AddControlEdge(b0, g->sink_node());
  g->AddControlEdge(b1, g->sink_node());

  ConstantFoldingOptions opts;
  opts.consider = [b1_ident](const Node* n) { return b1_ident != n; };
  EXPECT_TRUE(DoConstantFolding(opts, g));
  // 0th output of b should have been folded.
  EXPECT_EQ(1, b0->num_inputs());
  ExpectNodeEqual<int>(*(b0->in_nodes().begin()), {0, 1}, {2});
  // 1st output of b should still be b1_ident. However, b1_ident's input must
  // have been replaced with a constant.
  EXPECT_EQ(1, b1->num_inputs());
  EXPECT_EQ(*(b1->in_nodes().begin()), b1_ident);

  EXPECT_EQ(1, b1_ident->num_inputs());
  ExpectNodeEqual<int>(*(b1_ident->in_nodes().begin()), {}, {0});
}

}  // namespace
}  // namespace tensorflow
<commit_msg>Global search & replace to move to the new location for tensorflow/core/ files and build targets. Change: 113248293<commit_after>/* Copyright 2015 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

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

#include "tensorflow/core/common_runtime/constant_folding.h"

#include "tensorflow/core/common_runtime/device_factory.h"
#include "tensorflow/core/common_runtime/device_mgr.h"
#include "tensorflow/core/framework/node_def_util.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/tensor_testutil.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/graph/node_builder.h"
#include "tensorflow/core/graph/testlib.h"
#include "tensorflow/core/lib/core/status_test_util.h"
#include "tensorflow/core/lib/core/threadpool.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/public/session_options.h"

namespace tensorflow {
namespace {

class ConstantFoldingTest : public ::testing::Test {
 protected:
  ConstantFoldingTest() { Reset(); }
  void Reset() { g_.reset(new Graph(OpRegistry::Global())); }

  template <typename T>
  Node* Constant(gtl::ArraySlice<T> values, TensorShape shape) {
    return test::graph::Constant(g_.get(), test::AsTensor(values, shape));
  }

  template <typename T>
  void ExpectNodeClose(const Node* n, gtl::ArraySlice<T> values,
                       TensorShape shape) {
    EXPECT_TRUE(n->IsConstant());
    const TensorProto* tensor_proto;
    TF_EXPECT_OK(GetNodeAttr(n->def(), "value", &tensor_proto));
    DataType dtype;
    TF_EXPECT_OK(GetNodeAttr(n->def(), "dtype", &dtype));
    Tensor t(dtype);
    EXPECT_TRUE(t.FromProto(*tensor_proto));
    test::ExpectClose(t, test::AsTensor(values, shape));
  }

  template <typename T>
  void ExpectNodeEqual(const Node* n, gtl::ArraySlice<T> values,
                       TensorShape shape) {
    EXPECT_TRUE(n->IsConstant());
    const TensorProto* tensor_proto;
    EXPECT_OK(GetNodeAttr(n->def(), "value", &tensor_proto));
    DataType dtype;
    EXPECT_OK(GetNodeAttr(n->def(), "dtype", &dtype));
    Tensor t(dtype);
    EXPECT_TRUE(t.FromProto(*tensor_proto));
    test::ExpectTensorEqual<T>(t, test::AsTensor(values, shape));
  }

// Construct the following graph
//    s1  s2
//    |    |
//    m1   m2
//    / \ / \
//   a   b   c
#define SIMPLE_GRAPH                                                  \
  Reset();                                                            \
  Graph* g = g_.get();                                                \
  Node* a = Constant<float>({1.0, 0.0, 0.0, 1.0}, {2, 2});            \
  Node* b = Constant<float>({1.0, 2.0, 3.0, 4.0}, {2, 2});            \
  Node* c = Constant<float>({0.0, 1.0, 1.0, 0.0}, {2, 2});            \
  g->AddControlEdge(g->source_node(), a);                             \
  g->AddControlEdge(g->source_node(), b);                             \
  g->AddControlEdge(g->source_node(), c);                             \
  Node* m1 = test::graph::Matmul(g, a, b, false, false);              \
  Node* s1 = test::graph::Send(g, m1, "m1", "sender", 0, "receiver"); \
  Node* m2 = test::graph::Matmul(g, b, c, false, false);              \
  Node* s2 = test::graph::Send(g, m2, "m2", "sender", 0, "receiver"); \
  g->AddControlEdge(s1, g->sink_node());                              \
  g->AddControlEdge(s2, g->sink_node());

  std::unique_ptr<Graph> g_;
};

TEST_F(ConstantFoldingTest, Basic) {
  SIMPLE_GRAPH;
  EXPECT_TRUE(DoConstantFolding(ConstantFoldingOptions{}, g));

  // Nodes s1 and s2 now should now have a constant input
  EXPECT_EQ(1, s1->num_inputs());
  ExpectNodeClose<float>(*(s1->in_nodes().begin()), {1.0, 2.0, 3.0, 4.0},
                         {2, 2});
  EXPECT_EQ(1, s2->num_inputs());
  ExpectNodeClose<float>(*(s2->in_nodes().begin()), {2.0, 1.0, 4.0, 3.0},
                         {2, 2});
}

TEST_F(ConstantFoldingTest, ConsiderFunction) {
  SIMPLE_GRAPH;
  ConstantFoldingOptions opts;
  // Do not allow constant folding of m2
  opts.consider = [m2](const Node* n) { return m2 != n; };
  EXPECT_TRUE(DoConstantFolding(opts, g));

  // Node s1 now should now have a constant input
  EXPECT_EQ(1, s1->num_inputs());
  ExpectNodeClose<float>(*(s1->in_nodes().begin()), {1.0, 2.0, 3.0, 4.0},
                         {2, 2});
  // s2's input should still be m2
  EXPECT_EQ(1, s2->num_inputs());
  EXPECT_EQ(*(s2->in_nodes().begin()), m2);
}
#undef SIMPLE_GRAPH

TEST_F(ConstantFoldingTest, TwoOutputs) {
  Reset();
  Graph* g = g_.get();
  Node* s0 = Constant<int>({1}, {1});
  Node* s1 = Constant<int>({2, 2}, {2});
  g->AddControlEdge(g->source_node(), s0);
  g->AddControlEdge(g->source_node(), s1);
  Node* b = test::graph::BroadcastGradientArgs(g, s0, s1);
  Node* b0 = test::graph::Send(g, test::graph::Identity(g, b, 0),
                               strings::StrCat(b->name(), "0"), "sender", 0,
                               "receiver");
  Node* b1 = test::graph::Send(g, test::graph::Identity(g, b, 1),
                               strings::StrCat(b->name(), "1"), "sender", 0,
                               "receiver");
  g->AddControlEdge(b0, g->sink_node());
  g->AddControlEdge(b1, g->sink_node());

  EXPECT_TRUE(DoConstantFolding(ConstantFoldingOptions{}, g));
  EXPECT_EQ(1, b0->num_inputs());
  ExpectNodeEqual<int>(*(b0->in_nodes().begin()), {0, 1}, {2});
  EXPECT_EQ(1, b1->num_inputs());
  ExpectNodeEqual<int>(*(b1->in_nodes().begin()), {}, {0});
}

TEST_F(ConstantFoldingTest, TwoOutputsFoldOneOutput) {
  Reset();
  Graph* g = g_.get();
  Node* s0 = Constant<int>({1}, {1});
  Node* s1 = Constant<int>({2, 2}, {2});
  g->AddControlEdge(g->source_node(), s0);
  g->AddControlEdge(g->source_node(), s1);
  Node* b = test::graph::BroadcastGradientArgs(g, s0, s1);
  Node* b0 = test::graph::Send(g, test::graph::Identity(g, b, 0),
                               strings::StrCat(b->name(), "0"), "sender", 0,
                               "receiver");
  Node* b1_ident = test::graph::Identity(g, b, 1);
  Node* b1 = test::graph::Send(g, b1_ident, strings::StrCat(b->name(), "1"),
                               "sender", 0, "receiver");
  g->AddControlEdge(b0, g->sink_node());
  g->AddControlEdge(b1, g->sink_node());

  ConstantFoldingOptions opts;
  opts.consider = [b1_ident](const Node* n) { return b1_ident != n; };
  EXPECT_TRUE(DoConstantFolding(opts, g));
  // 0th output of b should have been folded.
  EXPECT_EQ(1, b0->num_inputs());
  ExpectNodeEqual<int>(*(b0->in_nodes().begin()), {0, 1}, {2});
  // 1st output of b should still be b1_ident. However, b1_ident's input must
  // have been replaced with a constant.
  EXPECT_EQ(1, b1->num_inputs());
  EXPECT_EQ(*(b1->in_nodes().begin()), b1_ident);

  EXPECT_EQ(1, b1_ident->num_inputs());
  ExpectNodeEqual<int>(*(b1_ident->in_nodes().begin()), {}, {0});
}

}  // namespace
}  // namespace tensorflow
<|endoftext|>