<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sqlite3.h>
#include <string>
#include <zlib.h>
#include <math.h>
#include "vector_tile.pb.h"

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

// https://github.com/mapbox/mapnik-vector-tile/blob/master/src/vector_tile_compression.hpp
inline bool is_compressed(std::string const &data) {
	return data.size() > 2 && (((uint8_t) data[0] == 0x78 && (uint8_t) data[1] == 0x9C) || ((uint8_t) data[0] == 0x1F && (uint8_t) data[1] == 0x8B));
}

// https://github.com/mapbox/mapnik-vector-tile/blob/master/src/vector_tile_compression.hpp
inline int decompress(std::string const &input, std::string &output) {
	z_stream inflate_s;
	inflate_s.zalloc = Z_NULL;
	inflate_s.zfree = Z_NULL;
	inflate_s.opaque = Z_NULL;
	inflate_s.avail_in = 0;
	inflate_s.next_in = Z_NULL;
	if (inflateInit2(&inflate_s, 32 + 15) != Z_OK) {
		fprintf(stderr, "error: %s\n", inflate_s.msg);
	}
	inflate_s.next_in = (Bytef *) input.data();
	inflate_s.avail_in = input.size();
	size_t length = 0;
	do {
		output.resize(length + 2 * input.size());
		inflate_s.avail_out = 2 * input.size();
		inflate_s.next_out = (Bytef *) (output.data() + length);
		int ret = inflate(&inflate_s, Z_FINISH);
		if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR) {
			fprintf(stderr, "error: %s\n", inflate_s.msg);
			return 0;
		}

		length += (2 * input.size() - inflate_s.avail_out);
	} while (inflate_s.avail_out == 0);
	inflateEnd(&inflate_s);
	output.resize(length);
	return 1;
}

int dezig(unsigned n) {
	return (n >> 1) ^ (-(n & 1));
}

void handle(std::string message, int z, unsigned x, unsigned y) {
	GOOGLE_PROTOBUF_VERIFY_VERSION;

	// https://github.com/mapbox/mapnik-vector-tile/blob/master/examples/c%2B%2B/tileinfo.cpp
	mapnik::vector::tile tile;

	if (is_compressed(message)) {
		std::string uncompressed;
		decompress(message, uncompressed);
		if (!tile.ParseFromString(uncompressed)) {
			fprintf(stderr, "Couldn't decompress tile %d/%u/%u\n", z, x, y);
			exit(EXIT_FAILURE);
		}
	} else if (!tile.ParseFromString(message)) {
		fprintf(stderr, "Couldn't parse tile %d/%u/%u\n", z, x, y);
		exit(EXIT_FAILURE);
	}

	for (int l = 0; l < tile.layers_size(); l++) {
		mapnik::vector::tile_layer layer = tile.layers(l);
		int extent = layer.extent();

		for (int f = 0; f < layer.features_size(); f++) {
			mapnik::vector::tile_feature feat = layer.features(f);
			int px = 0, py = 0;

			for (int g = 0; g < feat.geometry_size(); g++) {
				uint32_t geom = feat.geometry(g);
				uint32_t op = geom & 7;
				uint32_t count = geom >> 3;

				if (op == 1 || op == 2) {
					if (op == 1) {
						printf("\n");
					}

					for (unsigned k = 0; k < count; k++) {
						px += dezig(feat.geometry(g + 1));
						py += dezig(feat.geometry(g + 2));
						g += 2;

						long long scale = 1LL << (32 - z);
						long long wx = scale * x + (scale / extent) * (px + .5);
						long long wy = scale * y + (scale / extent) * (py + .5);

						double lat, lon;
						tile2latlon(wx, wy, 32, &lat, &lon);
						printf("%f,%f ", lat, lon);
					}
				}
			}
		}
	}
}

void decode(char *fname, int z, unsigned x, unsigned y) {
	sqlite3 *db;
	int oz = z;
	unsigned ox = x, oy = y;

	if (sqlite3_open(fname, &db) != SQLITE_OK) {
		fprintf(stderr, "%s: %s\n", fname, sqlite3_errmsg(db));
		exit(EXIT_FAILURE);
	}

	int handled = 0;
	while (z >= 0 && !handled) {
		const char *sql = "SELECT tile_data from tiles where zoom_level = ? and tile_column = ? and tile_row = ?;";
		sqlite3_stmt *stmt;
		if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
			fprintf(stderr, "%s: select failed: %s\n", fname, sqlite3_errmsg(db));
			exit(EXIT_FAILURE);
		}

		sqlite3_bind_int(stmt, 1, z);
		sqlite3_bind_int(stmt, 2, x);
		sqlite3_bind_int(stmt, 3, (1LL << z) - 1 - y);

		while (sqlite3_step(stmt) == SQLITE_ROW) {
			int len = sqlite3_column_bytes(stmt, 0);
			const char *s = (const char *) sqlite3_column_blob(stmt, 0);

			if (z != oz) {
				fprintf(stderr, "%s: Warning: using tile %d/%u/%u instead of %d/%u/%u\n", fname, z, x, y, oz, ox, oy);
			}

			handle(std::string(s, len), z, x, y);
			handled = 1;
		}

		sqlite3_finalize(stmt);

		z--;
		x /= 2;
		y /= 2;
	}

	if (sqlite3_close(db) != SQLITE_OK) {
		fprintf(stderr, "%s: could not close database: %s\n", fname, sqlite3_errmsg(db));
		exit(EXIT_FAILURE);
	}
}

void usage(char **argv) {
	fprintf(stderr, "Usage: %s file.mbtiles zoom x y\n", argv[0]);
	exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
	extern int optind;
	// extern char *optarg;
	int i;

	while ((i = getopt(argc, argv, "")) != -1) {
		usage(argv);
	}

	if (argc != optind + 4) {
		usage(argv);
	}

	decode(argv[optind], atoi(argv[optind + 1]), atoi(argv[optind + 2]), atoi(argv[optind + 3]));

	return 0;
}
<commit_msg>Most of the way to making decode output GeoJSON<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sqlite3.h>
#include <string>
#include <zlib.h>
#include <math.h>
#include "vector_tile.pb.h"
#include "tile.h"

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

// https://github.com/mapbox/mapnik-vector-tile/blob/master/src/vector_tile_compression.hpp
inline bool is_compressed(std::string const &data) {
	return data.size() > 2 && (((uint8_t) data[0] == 0x78 && (uint8_t) data[1] == 0x9C) || ((uint8_t) data[0] == 0x1F && (uint8_t) data[1] == 0x8B));
}

// https://github.com/mapbox/mapnik-vector-tile/blob/master/src/vector_tile_compression.hpp
inline int decompress(std::string const &input, std::string &output) {
	z_stream inflate_s;
	inflate_s.zalloc = Z_NULL;
	inflate_s.zfree = Z_NULL;
	inflate_s.opaque = Z_NULL;
	inflate_s.avail_in = 0;
	inflate_s.next_in = Z_NULL;
	if (inflateInit2(&inflate_s, 32 + 15) != Z_OK) {
		fprintf(stderr, "error: %s\n", inflate_s.msg);
	}
	inflate_s.next_in = (Bytef *) input.data();
	inflate_s.avail_in = input.size();
	size_t length = 0;
	do {
		output.resize(length + 2 * input.size());
		inflate_s.avail_out = 2 * input.size();
		inflate_s.next_out = (Bytef *) (output.data() + length);
		int ret = inflate(&inflate_s, Z_FINISH);
		if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR) {
			fprintf(stderr, "error: %s\n", inflate_s.msg);
			return 0;
		}

		length += (2 * input.size() - inflate_s.avail_out);
	} while (inflate_s.avail_out == 0);
	inflateEnd(&inflate_s);
	output.resize(length);
	return 1;
}

int dezig(unsigned n) {
	return (n >> 1) ^ (-(n & 1));
}

void printq(const char *s) {
	putchar('"');
	for (; *s; s++) {
		if (*s == '\\' || *s == '"') {
			printf("\\%c", *s);
		} else if (*s >= 0 && *s < ' ') {
			printf("\\u%04x", *s);
		} else {
			putchar(*s);
		}
	}
	putchar('"');
}

struct draw {
	int op;
	double lon;
	double lat;

	draw(int op, double lon, double lat) {
		this->op = op;
		this->lon = lon;
		this->lat = lat;
	}
};

void handle(std::string message, int z, unsigned x, unsigned y) {
	GOOGLE_PROTOBUF_VERIFY_VERSION;
	int within = 0;

	// https://github.com/mapbox/mapnik-vector-tile/blob/master/examples/c%2B%2B/tileinfo.cpp
	mapnik::vector::tile tile;

	if (is_compressed(message)) {
		std::string uncompressed;
		decompress(message, uncompressed);
		if (!tile.ParseFromString(uncompressed)) {
			fprintf(stderr, "Couldn't decompress tile %d/%u/%u\n", z, x, y);
			exit(EXIT_FAILURE);
		}
	} else if (!tile.ParseFromString(message)) {
		fprintf(stderr, "Couldn't parse tile %d/%u/%u\n", z, x, y);
		exit(EXIT_FAILURE);
	}

	printf("{ \"type\": \"FeatureCollection\", \"features\": [\n");

	for (int l = 0; l < tile.layers_size(); l++) {
		mapnik::vector::tile_layer layer = tile.layers(l);
		int extent = layer.extent();

		for (int f = 0; f < layer.features_size(); f++) {
			mapnik::vector::tile_feature feat = layer.features(f);
			int px = 0, py = 0;

			if (within) {
				printf(",\n");
			}
			within = 1;

			printf("{ \"type\": \"Feature\"");
			printf(", \"properties\": { ");

			for (unsigned t = 0; t + 1 < feat.tags_size(); t += 2) {
				if (t != 0) {
					printf(", ");
				}

				const char *key = layer.keys(feat.tags(t)).c_str();
				mapnik::vector::tile_value const &val = layer.values(feat.tags(t + 1));

				if (val.has_string_value()) {
					printq(key);
					printf(": ");
					printq(val.string_value().c_str());
				} else if (val.has_int_value()) {
					printq(key);
					printf(": %lld", (long long) val.int_value());
				} else if (val.has_double_value()) {
					printq(key);
					printf(": %g", val.double_value());
				} else if (val.has_float_value()) {
					printq(key);
					printf(": %g", val.float_value());
				} else if (val.has_sint_value()) {
					printq(key);
					printf(": %lld", (long long) val.sint_value());
				} else if (val.has_uint_value()) {
					printq(key);
					printf(": %lld", (long long) val.uint_value());
				} else if (val.has_bool_value()) {
					printq(key);
					printf(": %s", val.bool_value() ? "true" : "false");
				}
			}

			printf(" }, \"geometry\": { ");

			std::vector<draw> ops;

			for (int g = 0; g < feat.geometry_size(); g++) {
				uint32_t geom = feat.geometry(g);
				uint32_t op = geom & 7;
				uint32_t count = geom >> 3;

				if (op == VT_MOVETO || op == VT_LINETO) {
					for (unsigned k = 0; k < count; k++) {
						px += dezig(feat.geometry(g + 1));
						py += dezig(feat.geometry(g + 2));
						g += 2;

						long long scale = 1LL << (32 - z);
						long long wx = scale * x + (scale / extent) * (px + .5);
						long long wy = scale * y + (scale / extent) * (py + .5);

						double lat, lon;
						tile2latlon(wx, wy, 32, &lat, &lon);

						ops.push_back(draw(op, lon, lat));
					}
				} else {
					ops.push_back(draw(op, 0, 27));
				}
			}

			if (feat.type() == VT_POINT) {
				if (ops.size() == 1) {
					printf("\"type\": \"Point\", \"coordinates\": [ %f, %f ]", ops[0].lon, ops[0].lat);
				} else {
					printf("\"type\": \"MultiPoint\", \"coordinates\": [ ");
					for (unsigned i = 0; i < ops.size(); i++) {
						if (i != 0) {
							printf(", ");
						}
						printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
					}
					printf(" ]");
				}
			} else if (feat.type() == VT_LINE) {
				int movetos = 0;
				for (unsigned i = 0; i < ops.size(); i++) {
					if (ops[i].op == VT_MOVETO) {
						movetos++;
					}
				}

				if (movetos < 2) {
					printf("\"type\": \"LineString\", \"coordinates\": [ ");
					for (unsigned i = 0; i < ops.size(); i++) {
						if (i != 0) {
							printf(", ");
						}
						printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
					}
					printf(" ]");
				} else {
					printf("\"type\": \"MultiLineString\", \"coordinates\": [ [ ");
					int state = 0;
					for (unsigned i = 0; i < ops.size(); i++) {
						if (ops[i].op == VT_MOVETO) {
							if (state == 0) {
								printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
								state = 1;
							} else {
								printf(" ], [ ");
								printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
								state = 1;
							}
						} else {
							printf(", [ %f, %f ]", ops[i].lon, ops[i].lat);
						}
					}
					printf(" ] ]");
				}
			} else if (feat.type() == VT_POLYGON) {

			}

			printf(" } }\n");
		}
	}

	printf("] }\n");
}

void decode(char *fname, int z, unsigned x, unsigned y) {
	sqlite3 *db;
	int oz = z;
	unsigned ox = x, oy = y;

	if (sqlite3_open(fname, &db) != SQLITE_OK) {
		fprintf(stderr, "%s: %s\n", fname, sqlite3_errmsg(db));
		exit(EXIT_FAILURE);
	}

	int handled = 0;
	while (z >= 0 && !handled) {
		const char *sql = "SELECT tile_data from tiles where zoom_level = ? and tile_column = ? and tile_row = ?;";
		sqlite3_stmt *stmt;
		if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
			fprintf(stderr, "%s: select failed: %s\n", fname, sqlite3_errmsg(db));
			exit(EXIT_FAILURE);
		}

		sqlite3_bind_int(stmt, 1, z);
		sqlite3_bind_int(stmt, 2, x);
		sqlite3_bind_int(stmt, 3, (1LL << z) - 1 - y);

		while (sqlite3_step(stmt) == SQLITE_ROW) {
			int len = sqlite3_column_bytes(stmt, 0);
			const char *s = (const char *) sqlite3_column_blob(stmt, 0);

			if (z != oz) {
				fprintf(stderr, "%s: Warning: using tile %d/%u/%u instead of %d/%u/%u\n", fname, z, x, y, oz, ox, oy);
			}

			handle(std::string(s, len), z, x, y);
			handled = 1;
		}

		sqlite3_finalize(stmt);

		z--;
		x /= 2;
		y /= 2;
	}

	if (sqlite3_close(db) != SQLITE_OK) {
		fprintf(stderr, "%s: could not close database: %s\n", fname, sqlite3_errmsg(db));
		exit(EXIT_FAILURE);
	}
}

void usage(char **argv) {
	fprintf(stderr, "Usage: %s file.mbtiles zoom x y\n", argv[0]);
	exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
	extern int optind;
	// extern char *optarg;
	int i;

	while ((i = getopt(argc, argv, "")) != -1) {
		usage(argv);
	}

	if (argc != optind + 4) {
		usage(argv);
	}

	decode(argv[optind], atoi(argv[optind + 1]), atoi(argv[optind + 2]), atoi(argv[optind + 3]));

	return 0;
}
<|endoftext|>


<commit_before>/* Helper similar to Python's @c str.join().
 *
 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/separated_list instead.
 *
 * Copyright (c) 2000-2021, Jeroen T. Vermeulen.
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this
 * mistake, or contact the author.
 */
#ifndef PQXX_H_SEPARATED_LIST
#define PQXX_H_SEPARATED_LIST

#include "pqxx/compiler-public.hxx"
#include "pqxx/internal/compiler-internal-pre.hxx"

#include <algorithm>
#include <numeric>

#include "pqxx/strconv.hxx"

// TODO: Simplify using std::ranges::range, once we're on C++20.
// TODO: Optimise buffer allocation using C++20 random_access_range/iterator.
namespace pqxx
{
/**
 * @defgroup utility Utility functions
 */
//@{

/// Represent sequence of values as a string, joined by a given separator.
/**
 * Use this to turn e.g. the numbers 1, 2, and 3 into a string "1, 2, 3".
 *
 * @param sep separator string (to be placed between items)
 * @param begin beginning of items sequence
 * @param end end of items sequence
 * @param access functor defining how to dereference sequence elements
 */
template<typename ITER, typename ACCESS>
[[nodiscard]] inline std::string
separated_list(std::string_view sep, ITER begin, ITER end, ACCESS access)
{
  if (end == begin)
    return std::string{};
  auto next{begin};
  ++next;
  if (next == end)
    return to_string(access(begin));

  // From here on, we've got at least 2 elements -- meaning that we need sep.
  using elt_type = strip_t<decltype(access(begin))>;
  using traits = string_traits<elt_type>;

  std::size_t budget{0};
  for (ITER cnt{begin}; cnt != end; ++cnt)
    budget += traits::size_buffer(access(cnt));
  budget +=
    static_cast<std::size_t>(std::distance(begin, end)) * std::size(sep);

  std::string result;
  result.resize(budget);

  char *here{std::data(result)};
  char *stop{here + budget};
  here = traits::into_buf(here, stop, access(begin)) - 1;
  for (++begin; begin != end; ++begin)
  {
    here += sep.copy(here, std::size(sep));
    here = traits::into_buf(here, stop, access(begin)) - 1;
  }
  result.resize(static_cast<std::size_t>(here - std::data(result)));
  return result;
}

/// Render sequence as a string, using given separator between items.
template<typename ITER>
[[nodiscard]] inline std::string
separated_list(std::string_view sep, ITER begin, ITER end)
{
  return separated_list(sep, begin, end, [](ITER i) { return *i; });
}

/// Render items in a container as a string, using given separator.
template<typename CONTAINER>
[[nodiscard]] inline auto
separated_list(std::string_view sep, CONTAINER const &c)
  /*
  Always std::string; necessary because SFINAE doesn't work with the
  contents of function bodies, so the check for iterability has to be in
  the signature.
  */
  -> typename std::enable_if<
    (not std::is_void<decltype(std::begin(c))>::value and
     not std::is_void<decltype(std::end(c))>::value),
    std::string>::type
{
  return separated_list(sep, std::begin(c), std::end(c));
}

/// Render items in a tuple as a string, using given separator.
template<
  typename TUPLE, std::size_t INDEX = 0, typename ACCESS,
  typename std::enable_if<
    (INDEX == std::tuple_size<TUPLE>::value - 1), int>::type = 0>
[[nodiscard]] inline std::string separated_list(
  std::string_view /* sep */, TUPLE const &t, ACCESS const &access)
{
  return to_string(access(&std::get<INDEX>(t)));
}

template<
  typename TUPLE, std::size_t INDEX = 0, typename ACCESS,
  typename std::enable_if<
    (INDEX < std::tuple_size<TUPLE>::value - 1), int>::type = 0>
[[nodiscard]] inline std::string
separated_list(std::string_view sep, TUPLE const &t, ACCESS const &access)
{
  std::string out{to_string(access(&std::get<INDEX>(t)))};
  out.append(sep);
  out.append(separated_list<TUPLE, INDEX + 1>(sep, t, access));
  return out;
}

template<
  typename TUPLE, std::size_t INDEX = 0,
  typename std::enable_if<
    (INDEX <= std::tuple_size<TUPLE>::value), int>::type = 0>
[[nodiscard]] inline std::string
separated_list(std::string_view sep, TUPLE const &t)
{
  // TODO: Optimise allocation.
  return separated_list(sep, t, [](TUPLE const &tup) { return *tup; });
}
//@}
} // namespace pqxx

#include "pqxx/internal/compiler-internal-post.hxx"
#endif
<commit_msg>Another tiny fix for #455.<commit_after>/* Helper similar to Python's @c str.join().
 *
 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/separated_list instead.
 *
 * Copyright (c) 2000-2021, Jeroen T. Vermeulen.
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this
 * mistake, or contact the author.
 */
#ifndef PQXX_H_SEPARATED_LIST
#define PQXX_H_SEPARATED_LIST

#include "pqxx/compiler-public.hxx"
#include "pqxx/internal/compiler-internal-pre.hxx"

#include <algorithm>
#include <numeric>

#include "pqxx/strconv.hxx"

// TODO: Simplify using std::ranges::range, once we're on C++20.
// TODO: Optimise buffer allocation using C++20 random_access_range/iterator.
namespace pqxx
{
/**
 * @defgroup utility Utility functions
 */
//@{

/// Represent sequence of values as a string, joined by a given separator.
/**
 * Use this to turn e.g. the numbers 1, 2, and 3 into a string "1, 2, 3".
 *
 * @param sep separator string (to be placed between items)
 * @param begin beginning of items sequence
 * @param end end of items sequence
 * @param access functor defining how to dereference sequence elements
 */
template<typename ITER, typename ACCESS>
[[nodiscard]] inline std::string
separated_list(std::string_view sep, ITER begin, ITER end, ACCESS access)
{
  if (end == begin)
    return std::string{};
  auto next{begin};
  ++next;
  if (next == end)
    return to_string(access(begin));

  // From here on, we've got at least 2 elements -- meaning that we need sep.
  using elt_type = strip_t<decltype(access(begin))>;
  using traits = string_traits<elt_type>;

  std::size_t budget{0};
  for (ITER cnt{begin}; cnt != end; ++cnt)
    budget += traits::size_buffer(access(cnt));
  budget +=
    static_cast<std::size_t>(std::distance(begin, end)) * std::size(sep);

  std::string result;
  result.resize(budget);

  char *const data{std::data(result)};
  char *here{data};
  char *stop{data + budget};
  here = traits::into_buf(here, stop, access(begin)) - 1;
  for (++begin; begin != end; ++begin)
  {
    here += sep.copy(here, std::size(sep));
    here = traits::into_buf(here, stop, access(begin)) - 1;
  }
  result.resize(static_cast<std::size_t>(here - data));
  return result;
}

/// Render sequence as a string, using given separator between items.
template<typename ITER>
[[nodiscard]] inline std::string
separated_list(std::string_view sep, ITER begin, ITER end)
{
  return separated_list(sep, begin, end, [](ITER i) { return *i; });
}

/// Render items in a container as a string, using given separator.
template<typename CONTAINER>
[[nodiscard]] inline auto
separated_list(std::string_view sep, CONTAINER const &c)
  /*
  Always std::string; necessary because SFINAE doesn't work with the
  contents of function bodies, so the check for iterability has to be in
  the signature.
  */
  -> typename std::enable_if<
    (not std::is_void<decltype(std::begin(c))>::value and
     not std::is_void<decltype(std::end(c))>::value),
    std::string>::type
{
  return separated_list(sep, std::begin(c), std::end(c));
}

/// Render items in a tuple as a string, using given separator.
template<
  typename TUPLE, std::size_t INDEX = 0, typename ACCESS,
  typename std::enable_if<
    (INDEX == std::tuple_size<TUPLE>::value - 1), int>::type = 0>
[[nodiscard]] inline std::string separated_list(
  std::string_view /* sep */, TUPLE const &t, ACCESS const &access)
{
  return to_string(access(&std::get<INDEX>(t)));
}

template<
  typename TUPLE, std::size_t INDEX = 0, typename ACCESS,
  typename std::enable_if<
    (INDEX < std::tuple_size<TUPLE>::value - 1), int>::type = 0>
[[nodiscard]] inline std::string
separated_list(std::string_view sep, TUPLE const &t, ACCESS const &access)
{
  std::string out{to_string(access(&std::get<INDEX>(t)))};
  out.append(sep);
  out.append(separated_list<TUPLE, INDEX + 1>(sep, t, access));
  return out;
}

template<
  typename TUPLE, std::size_t INDEX = 0,
  typename std::enable_if<
    (INDEX <= std::tuple_size<TUPLE>::value), int>::type = 0>
[[nodiscard]] inline std::string
separated_list(std::string_view sep, TUPLE const &t)
{
  // TODO: Optimise allocation.
  return separated_list(sep, t, [](TUPLE const &tup) { return *tup; });
}
//@}
} // namespace pqxx

#include "pqxx/internal/compiler-internal-post.hxx"
#endif
<|endoftext|>


<commit_before>///
/// @file   primecount-internal.hpp
/// @brief  primecount internal function definitions.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef PRIMECOUNT_INTERNAL_HPP
#define PRIMECOUNT_INTERNAL_HPP

#include <int128.hpp>
#include <aligned_vector.hpp>
#include <pmath.hpp>

#include <stdint.h>
#include <algorithm>
#include <string>
#include <vector>

namespace primecount {

enum {
  /// Uses all CPU cores.
  MAX_THREADS = -1
};

class PhiCache;

std::string pi(const std::string& x, int threads);

int64_t pi(int64_t x, int threads);

#ifdef HAVE_INT128_T

int128_t pi(int128_t x);

int128_t pi(int128_t x, int threads);

#endif

int64_t pi_deleglise_rivat(int64_t x, int threads);

#ifdef HAVE_INT128_T

int128_t pi_deleglise_rivat(int128_t x);

int128_t pi_deleglise_rivat(int128_t x, int threads);

#endif

int64_t pi_deleglise_rivat1(int64_t x);

int64_t pi_deleglise_rivat2(int64_t x);

int64_t pi_deleglise_rivat_parallel1(int64_t x, int threads);

int64_t pi_deleglise_rivat_parallel2(int64_t x, int threads);

#ifdef HAVE_INT128_T

int128_t pi_deleglise_rivat_parallel3(int128_t x, int threads);

#endif

int64_t pi_legendre(int64_t x, int threads);

int64_t pi_lehmer(int64_t x, int threads);

int64_t pi_lehmer2(int64_t x, int threads);

int64_t pi_lmo(int64_t x, int threads);

int64_t pi_lmo1(int64_t x);

int64_t pi_lmo2(int64_t x);

int64_t pi_lmo3(int64_t x);

int64_t pi_lmo4(int64_t x);

int64_t pi_lmo5(int64_t x);

int64_t pi_lmo_parallel1(int64_t x, int threads);

int64_t pi_lmo_parallel2(int64_t x, int threads);

int64_t pi_lmo_parallel3(int64_t x, int threads);

int64_t pi_meissel(int64_t x, int threads);

int64_t pi_primesieve(int64_t x, int threads);

int64_t phi(int64_t x, int64_t a, int threads);

int64_t phi(int64_t x, int64_t a, PhiCache* phiCache);

int64_t Li(int64_t);

int64_t Li_inverse(int64_t);

#ifdef HAVE_INT128_T

int128_t Li(int128_t);

int128_t Li_inverse(int128_t);

#endif

int64_t nth_prime(int64_t n, int threads);

int64_t P2(int64_t x, int64_t y, int threads);

#ifdef HAVE_INT128_T

int128_t P2(int128_t x, int64_t y, int threads);

#endif

int64_t P2_lehmer(int64_t x, int64_t a, int threads);

int64_t P3(int64_t x, int64_t a, int threads);

void set_alpha(double alpha);

double get_alpha();

double get_alpha(maxint_t x, double a, double b, double c)

double get_alpha(maxint_t x, double a, double b, double c, double d)

double get_wtime();

int validate_threads(int threads);

int validate_threads(int threads, int64_t sieve_limit, int64_t thread_threshold = 100000);

void print_result(const std::string& str, maxint_t res, double time);

void print_seconds(double seconds);

bool print_status();

maxint_t to_maxint(const std::string& expr);

template <typename T>
T get_percent(T low, T limit)
{
  T percent = (T) (100.0 * low / std::max<T>(1, limit));
  return in_between(0, percent, 100);
}

template <typename T>
T S2_approx(T x, int64_t pi_y, T P2, T S1)
{
  T pix = Li(x);
  T S2 = pix - S1 - pi_y + 1 + P2;
  return S2;
}

} // namespace primecount

#endif
<commit_msg>Fix typo<commit_after>///
/// @file   primecount-internal.hpp
/// @brief  primecount internal function definitions.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef PRIMECOUNT_INTERNAL_HPP
#define PRIMECOUNT_INTERNAL_HPP

#include <int128.hpp>
#include <aligned_vector.hpp>
#include <pmath.hpp>

#include <stdint.h>
#include <algorithm>
#include <string>
#include <vector>

namespace primecount {

enum {
  /// Uses all CPU cores.
  MAX_THREADS = -1
};

class PhiCache;

std::string pi(const std::string& x, int threads);

int64_t pi(int64_t x, int threads);

#ifdef HAVE_INT128_T

int128_t pi(int128_t x);

int128_t pi(int128_t x, int threads);

#endif

int64_t pi_deleglise_rivat(int64_t x, int threads);

#ifdef HAVE_INT128_T

int128_t pi_deleglise_rivat(int128_t x);

int128_t pi_deleglise_rivat(int128_t x, int threads);

#endif

int64_t pi_deleglise_rivat1(int64_t x);

int64_t pi_deleglise_rivat2(int64_t x);

int64_t pi_deleglise_rivat_parallel1(int64_t x, int threads);

int64_t pi_deleglise_rivat_parallel2(int64_t x, int threads);

#ifdef HAVE_INT128_T

int128_t pi_deleglise_rivat_parallel3(int128_t x, int threads);

#endif

int64_t pi_legendre(int64_t x, int threads);

int64_t pi_lehmer(int64_t x, int threads);

int64_t pi_lehmer2(int64_t x, int threads);

int64_t pi_lmo(int64_t x, int threads);

int64_t pi_lmo1(int64_t x);

int64_t pi_lmo2(int64_t x);

int64_t pi_lmo3(int64_t x);

int64_t pi_lmo4(int64_t x);

int64_t pi_lmo5(int64_t x);

int64_t pi_lmo_parallel1(int64_t x, int threads);

int64_t pi_lmo_parallel2(int64_t x, int threads);

int64_t pi_lmo_parallel3(int64_t x, int threads);

int64_t pi_meissel(int64_t x, int threads);

int64_t pi_primesieve(int64_t x, int threads);

int64_t phi(int64_t x, int64_t a, int threads);

int64_t phi(int64_t x, int64_t a, PhiCache* phiCache);

int64_t Li(int64_t);

int64_t Li_inverse(int64_t);

#ifdef HAVE_INT128_T

int128_t Li(int128_t);

int128_t Li_inverse(int128_t);

#endif

int64_t nth_prime(int64_t n, int threads);

int64_t P2(int64_t x, int64_t y, int threads);

#ifdef HAVE_INT128_T

int128_t P2(int128_t x, int64_t y, int threads);

#endif

int64_t P2_lehmer(int64_t x, int64_t a, int threads);

int64_t P3(int64_t x, int64_t a, int threads);

void set_alpha(double alpha);

double get_alpha();

double get_alpha(maxint_t x, double a, double b, double c);

double get_alpha(maxint_t x, double a, double b, double c, double d);

double get_wtime();

int validate_threads(int threads);

int validate_threads(int threads, int64_t sieve_limit, int64_t thread_threshold = 100000);

void print_result(const std::string& str, maxint_t res, double time);

void print_seconds(double seconds);

bool print_status();

maxint_t to_maxint(const std::string& expr);

template <typename T>
T get_percent(T low, T limit)
{
  T percent = (T) (100.0 * low / std::max<T>(1, limit));
  return in_between(0, percent, 100);
}

template <typename T>
T S2_approx(T x, int64_t pi_y, T P2, T S1)
{
  T pix = Li(x);
  T S2 = pix - S1 - pi_y + 1 + P2;
  return S2;
}

} // namespace primecount

#endif
<|endoftext|>


<commit_before>///
/// @file   iterator.hpp
/// @brief  The iterator class allows to easily iterate (forward and
///         backward) over prime numbers.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef PRIMESIEVE_ITERATOR_HPP
#define PRIMESIEVE_ITERATOR_HPP

#include <vector>
#include <cstddef>

namespace primesieve {

uint64_t get_max_stop();

/// Iterate over prime numbers.
/// The @link primesieve_iterator.cpp primesieve_iterator.cpp @endlink
/// and @link previous_prime.cpp previous_prime.cpp @endlink examples
/// show how to use primesieve::iterator objects.
/// @note  primesieve::iterator objects are very convenient to use at
///        the cost of being slightly slower than the
///        callback_primes() functions.
///
class iterator
{
public:
  /// Create a new iterator object.
  /// @param start      Start iterating at this number. If start is a
  ///                   prime then first calling either next_prime()
  ///                   or previous_prime() will return start.
  /// @param stop_hint  Stop number optimization hint, gives significant
  ///                   speed up if few primes are generated. E.g. if
  ///                   you want to generate the primes below 1000 use
  ///                   stop_hint = 1000.
  /// @pre              start <= 2^64 - 2^32 * 10
  ///
  iterator(uint64_t start = 0, uint64_t stop_hint = get_max_stop());

  /// Reinitialize this iterator object to start.
  /// @param start      Start iterating at this number. If start is a
  ///                   prime then first calling either next_prime()
  ///                   or previous_prime() will return start.
  /// @param stop_hint  Stop number optimization hint, gives significant
  ///                   speed up if few primes are generated. E.g. if
  ///                   you want to generate the primes below 1000 use
  ///                   stop_hint = 1000.
  /// @pre              start <= 2^64 - 2^32 * 10
  ///
  void skipto(uint64_t start, uint64_t stop_hint = get_max_stop());

  /// Free all memory, same as skipto(0).
  void clear();

  /// Advance the iterator by one position.
  /// @return  The next prime.
  ///
  uint64_t next_prime()
  {
    if (i_++ == last_idx_)
      generate_next_primes();
    return primes_[i_];
  }

  /// Decrease the iterator by one position.
  /// @return  The previous prime.
  ///
  uint64_t previous_prime()
  {
    if (i_-- == 0)
      generate_previous_primes();
    return primes_[i_];
  }
private:
  std::size_t i_;
  std::size_t last_idx_;
  std::vector<uint64_t> primes_;
  uint64_t start_;
  uint64_t stop_;
  uint64_t stop_hint_;
  uint64_t count_;
  uint64_t get_interval_size(uint64_t);
  void generate_primes(uint64_t, uint64_t);
  void generate_next_primes();
  void generate_previous_primes();
};

} // end namespace

#endif
<commit_msg>Documentation<commit_after>///
/// @file   iterator.hpp
/// @brief  The iterator class allows to easily iterate (forward and
///         backward) over prime numbers.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef PRIMESIEVE_ITERATOR_HPP
#define PRIMESIEVE_ITERATOR_HPP

#include <vector>
#include <cstddef>

namespace primesieve {

uint64_t get_max_stop();

/// Iterate over prime numbers.
/// primesieve::iterator allows to easily iterate over primes both
/// forwards and backwards. Note that generating the first prime uses
/// O(n^0.5 log log n^0.5) operations, after that any additional
/// prime is generated in amortized O(log n) operations. The memory
/// usage is about pi(sqrt(n)) * 16 bytes. primesieve::iterator
/// objects are very convenient to use at the cost of being slightly
/// slower than the callback_primes() functions.
///
class iterator
{
public:
  /// Create a new iterator object.
  /// @param start      Start iterating at this number. If start is a
  ///                   prime then first calling either next_prime()
  ///                   or previous_prime() will return start.
  /// @param stop_hint  Stop number optimization hint, gives significant
  ///                   speed up if few primes are generated. E.g. if
  ///                   you want to generate the primes below 1000 use
  ///                   stop_hint = 1000.
  /// @pre              start <= 2^64 - 2^32 * 10
  ///
  iterator(uint64_t start = 0, uint64_t stop_hint = get_max_stop());

  /// Reinitialize this iterator object to start.
  /// @param start      Start iterating at this number. If start is a
  ///                   prime then first calling either next_prime()
  ///                   or previous_prime() will return start.
  /// @param stop_hint  Stop number optimization hint, gives significant
  ///                   speed up if few primes are generated. E.g. if
  ///                   you want to generate the primes below 1000 use
  ///                   stop_hint = 1000.
  /// @pre              start <= 2^64 - 2^32 * 10
  ///
  void skipto(uint64_t start, uint64_t stop_hint = get_max_stop());

  /// Free all memory, same as skipto(0).
  void clear();

  /// Advance the iterator by one position.
  /// @return  The next prime.
  ///
  uint64_t next_prime()
  {
    if (i_++ == last_idx_)
      generate_next_primes();
    return primes_[i_];
  }

  /// Decrease the iterator by one position.
  /// @return  The previous prime.
  ///
  uint64_t previous_prime()
  {
    if (i_-- == 0)
      generate_previous_primes();
    return primes_[i_];
  }
private:
  std::size_t i_;
  std::size_t last_idx_;
  std::vector<uint64_t> primes_;
  uint64_t start_;
  uint64_t stop_;
  uint64_t stop_hint_;
  uint64_t count_;
  uint64_t get_interval_size(uint64_t);
  void generate_primes(uint64_t, uint64_t);
  void generate_next_primes();
  void generate_previous_primes();
};

} // end namespace

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/status/language_menu_button.h"

#include "base/string_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
#include "chrome/browser/chromeos/cros/mock_language_library.h"
#include "chrome/browser/chromeos/frame/browser_view.h"
#include "chrome/browser/chromeos/status/browser_status_area_view.h"
#include "chrome/browser/chromeos/view_ids.h"
#include "grit/theme_resources.h"

namespace chromeos {

using ::testing::Return;
using ::testing::ReturnRef;

class LanguageMenuButtonTest : public CrosInProcessBrowserTest {
 protected:
  LanguageMenuButtonTest()
      : CrosInProcessBrowserTest(),
        korean_desc_("hangul",  // The engine id for ibus-hangul.
                     "Korean",  // The display name for the input method.
                     "us",  // The input method assumes US keyboard layout.
                     "ko"),  // The input method is for Korean language.
        persian_desc_("m17n:fa:isiri",  // The engine id for ibus-m17n
                      "isiri (m17n)",  // The display name for the input method.
                      "us",  // The input method assumes US keyboard layout.
                      "fa"),  // The input method is for Farsi/Persian language.
        invalid_desc_("invalid-id",
                      "unregistered string",
                      "us",
                      "xx")  // Unknown language code.
  {}

  virtual void SetUpInProcessBrowserTestFixture() {
    InitStatusAreaMocks();
    SetStatusAreaMocksExpectations();
  }

  LanguageMenuButton* GetLanguageMenuButton() {
    BrowserView* view = static_cast<BrowserView*>(browser()->window());
    return static_cast<BrowserStatusAreaView*>(view->
        GetViewByID(VIEW_ID_STATUS_AREA))->language_view();
  }

  InputMethodDescriptor korean_desc_;
  InputMethodDescriptor persian_desc_;
  InputMethodDescriptor invalid_desc_;
};

IN_PROC_BROWSER_TEST_F(LanguageMenuButtonTest, InitialIndicatorTest) {
  LanguageMenuButton* language = GetLanguageMenuButton();
  ASSERT_TRUE(language != NULL);

  // Since the default input method is "xkb:us::eng", "EN" should be set for the
  // indicator.
  std::wstring indicator = language->text();
  EXPECT_EQ(L"EN", indicator);
}

IN_PROC_BROWSER_TEST_F(LanguageMenuButtonTest, IndicatorAndTooltipUpdateTest) {
  EXPECT_CALL(*mock_language_library_, current_input_method())
      .Times(3)
      .WillOnce(ReturnRef(korean_desc_))
      .WillOnce(ReturnRef(persian_desc_))
      .WillOnce(ReturnRef(invalid_desc_))
      .RetiresOnSaturation();
  LanguageMenuButton* language = GetLanguageMenuButton();
  ASSERT_TRUE(language != NULL);

  language->InputMethodChanged(mock_language_library_);
  std::wstring indicator = language->text();
  EXPECT_EQ(L"KO", indicator);
  std::wstring tooltip;
  language->GetTooltipText(gfx::Point(), &tooltip);
  EXPECT_EQ(L"Korean: Korean input method", tooltip);

  language->InputMethodChanged(mock_language_library_);
  indicator = language->text();
  EXPECT_EQ(L"FA", indicator);
  language->GetTooltipText(gfx::Point(), &tooltip);
  EXPECT_EQ(L"Persian: Persian input method (ISIRI 2901 layout)", tooltip);

  language->InputMethodChanged(mock_language_library_);
  indicator = language->text();
  EXPECT_EQ(L"XX", indicator);
  language->GetTooltipText(gfx::Point(), &tooltip);
  EXPECT_EQ(L"xx: unregistered string", tooltip);
}

}  // namespace chromeos
<commit_msg>Fix test expectations for language tooltips.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/status/language_menu_button.h"

#include "base/string_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
#include "chrome/browser/chromeos/cros/mock_language_library.h"
#include "chrome/browser/chromeos/frame/browser_view.h"
#include "chrome/browser/chromeos/status/browser_status_area_view.h"
#include "chrome/browser/chromeos/view_ids.h"
#include "grit/theme_resources.h"

namespace chromeos {

using ::testing::Return;
using ::testing::ReturnRef;

class LanguageMenuButtonTest : public CrosInProcessBrowserTest {
 protected:
  LanguageMenuButtonTest()
      : CrosInProcessBrowserTest(),
        korean_desc_("hangul",  // The engine id for ibus-hangul.
                     "Korean",  // The display name for the input method.
                     "us",  // The input method assumes US keyboard layout.
                     "ko"),  // The input method is for Korean language.
        persian_desc_("m17n:fa:isiri",  // The engine id for ibus-m17n
                      "isiri (m17n)",  // The display name for the input method.
                      "us",  // The input method assumes US keyboard layout.
                      "fa"),  // The input method is for Farsi/Persian language.
        invalid_desc_("invalid-id",
                      "unregistered string",
                      "us",
                      "xx")  // Unknown language code.
  {}

  virtual void SetUpInProcessBrowserTestFixture() {
    InitStatusAreaMocks();
    SetStatusAreaMocksExpectations();
  }

  LanguageMenuButton* GetLanguageMenuButton() {
    BrowserView* view = static_cast<BrowserView*>(browser()->window());
    return static_cast<BrowserStatusAreaView*>(view->
        GetViewByID(VIEW_ID_STATUS_AREA))->language_view();
  }

  InputMethodDescriptor korean_desc_;
  InputMethodDescriptor persian_desc_;
  InputMethodDescriptor invalid_desc_;
};

IN_PROC_BROWSER_TEST_F(LanguageMenuButtonTest, InitialIndicatorTest) {
  LanguageMenuButton* language = GetLanguageMenuButton();
  ASSERT_TRUE(language != NULL);

  // Since the default input method is "xkb:us::eng", "EN" should be set for the
  // indicator.
  std::wstring indicator = language->text();
  EXPECT_EQ(L"EN", indicator);
}

IN_PROC_BROWSER_TEST_F(LanguageMenuButtonTest, IndicatorAndTooltipUpdateTest) {
  EXPECT_CALL(*mock_language_library_, current_input_method())
      .Times(3)
      .WillOnce(ReturnRef(korean_desc_))
      .WillOnce(ReturnRef(persian_desc_))
      .WillOnce(ReturnRef(invalid_desc_))
      .RetiresOnSaturation();
  LanguageMenuButton* language = GetLanguageMenuButton();
  ASSERT_TRUE(language != NULL);

  language->InputMethodChanged(mock_language_library_);
  std::wstring indicator = language->text();
  EXPECT_EQ(L"KO", indicator);
  std::wstring tooltip;
  language->GetTooltipText(gfx::Point(), &tooltip);
  EXPECT_EQ(L"Korean - Korean input method", tooltip);

  language->InputMethodChanged(mock_language_library_);
  indicator = language->text();
  EXPECT_EQ(L"FA", indicator);
  language->GetTooltipText(gfx::Point(), &tooltip);
  EXPECT_EQ(L"Persian - Persian input method (ISIRI 2901 layout)", tooltip);

  language->InputMethodChanged(mock_language_library_);
  indicator = language->text();
  EXPECT_EQ(L"XX", indicator);
  language->GetTooltipText(gfx::Point(), &tooltip);
  EXPECT_EQ(L"xx - unregistered string", tooltip);
}

}  // namespace chromeos
<|endoftext|>


<commit_before>
#include <Render/Pipelining/Pipelines/CustomRenderPass/DeferredBasicBuffering.hh>

#include <memory>

#include <Render/Textures/Texture2D.hh>
#include <Render/OpenGLTask/OpenGLState.hh>
#include <Render/GeometryManagement/Painting/Painter.hh>
#include <SpacePartitioning/Ouptut/RenderLight.hh>
#include <SpacePartitioning/Ouptut/RenderPipeline.hh>
#include <SpacePartitioning/Ouptut/RenderPainter.hh>
#include <SpacePartitioning/Ouptut/RenderCamera.hh>
#include <Render/ProgramResources/Types/Uniform/Mat4.hh>
#include <Core/ConfigurationManager.hpp>
#include <Core/Engine.hh>
#include <Configuration.hpp>
#include <Threads/RenderThread.hpp>
#include <Threads/ThreadManager.hpp>
#include <Render/DepthMapHandle.hpp>
#include <Render/DepthMap.hpp>

#define DEFERRED_SHADING_BUFFERING_VERTEX "deferred_shading/deferred_shading_get_buffer.vp"
#define DEFERRED_SHADING_BUFFERING_FRAG "deferred_shading/deferred_shading_get_buffer.fp"

namespace AGE
{
	enum Programs
	{
		PROGRAM_BUFFERING = 0,
		PROGRAM_NBR
	};

	DeferredBasicBuffering::DeferredBasicBuffering(std::shared_ptr<PaintingManager> painterManager,
												std::shared_ptr<Texture2D> diffuse,
												std::shared_ptr<Texture2D> normal,
												std::shared_ptr<Texture2D> specular,
												std::shared_ptr<Texture2D> depth) :
		FrameBufferRender(painterManager)
		, _depth(depth)
	{
		AGE_ASSERT(depth != nullptr);

		// We dont want to take the skinned or transparent meshes
		_forbidden[AGE_SKINNED] = true;
		_forbidden[AGE_SEMI_TRANSPARENT] = true;

		push_storage_output(GL_COLOR_ATTACHMENT0, diffuse);
		push_storage_output(GL_COLOR_ATTACHMENT1, normal);
		push_storage_output(GL_COLOR_ATTACHMENT2, specular);
		push_storage_output(GL_DEPTH_STENCIL_ATTACHMENT, depth);

		_programs.resize(PROGRAM_NBR);

		auto confManager = GetEngine()->getInstance<ConfigurationManager>();

		auto shaderPath = confManager->getConfiguration<std::string>("ShadersPath");

		// you have to set shader directory in configuration path
		AGE_ASSERT(shaderPath != nullptr);

		auto vertexShaderPath = shaderPath->getValue() + DEFERRED_SHADING_BUFFERING_VERTEX;
		auto fragmentShaderPath = shaderPath->getValue() + DEFERRED_SHADING_BUFFERING_FRAG;

		_programs[PROGRAM_BUFFERING] = std::make_shared<Program>(Program(std::string("program_buffering"),
		{
			std::make_shared<UnitProg>(vertexShaderPath, GL_VERTEX_SHADER),
			std::make_shared<UnitProg>(fragmentShaderPath, GL_FRAGMENT_SHADER)
		}));
	}

	void DeferredBasicBuffering::renderPass(RenderPipeline const &pipeline, RenderLightList const &, CameraInfos const &infos)
	{
		SCOPE_profile_gpu_i("DeferredBasicBuffering render pass");
		SCOPE_profile_cpu_i("RenderTimer", "DeferredBasicBuffering render pass");

		{
			SCOPE_profile_gpu_i("Clear buffer");
			SCOPE_profile_cpu_i("RenderTimer", "Clear buffer");

			OpenGLState::glEnable(GL_CULL_FACE);
			OpenGLState::glCullFace(GL_BACK);
			OpenGLState::glDepthMask(GL_TRUE);
			OpenGLState::glDepthFunc(GL_LEQUAL);
			OpenGLState::glDisable(GL_BLEND);
			OpenGLState::glDisable(GL_STENCIL_TEST);
			OpenGLState::glEnable(GL_DEPTH_TEST);
			OpenGLState::glClearColor(glm::vec4(0.f, 0.0f, 0.0f, 0.0f));
			OpenGLState::glEnable(GL_STENCIL_TEST);
			OpenGLState::glClearStencil(0);
			OpenGLState::glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
			OpenGLState::glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		}
#ifdef OCCLUSION_CULLING

		{
			SCOPE_profile_gpu_i("Occluders pass");
			SCOPE_profile_cpu_i("RenderTimer", "Occluders pass");

			_programs[PROGRAM_BUFFERING]->use();
			*_programs[PROGRAM_BUFFERING]->get_resource<Mat4>("projection_matrix") = infos.projection;
			*_programs[PROGRAM_BUFFERING]->get_resource<Mat4>("view_matrix") = infos.view;

			for (auto &meshPaint : pipeline.keys)
			{
				auto painter = _painterManager->get_painter(Key<Painter>::createKey(meshPaint.first));
				for (auto &mode : meshPaint.second.drawables)
				{
					if (mode.renderMode.at(AGE_OCCLUDER) == true)
					{
						painter->draw(GL_TRIANGLES, _programs[PROGRAM_BUFFERING], mode.properties, mode.vertices);
					}
				}
			}
		}

		{
			SCOPE_profile_gpu_i("Copy occlusion depth to CPU");
			SCOPE_profile_cpu_i("RenderTimer", "Copy occlusion depth to CPU");

			auto writableBuffer = GetRenderThread()->getDepthMapManager().getWritableMap();
			auto mipmapLevel = GetRenderThread()->getDepthMapManager().getMipmapLevel();

			if (writableBuffer.isValid())
			{
				writableBuffer.setMV(infos.projection * infos.view);
				glActiveTextureARB(GL_TEXTURE0_ARB);
				_depth->bind();
				glGenerateMipmap(GL_TEXTURE_2D);
				_depth->get(static_cast<GLint>(mipmapLevel), GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, writableBuffer.getWritableBuffer());
				_depth->unbind();
			}
		}

		{
			SCOPE_profile_gpu_i("Draw objects");
			SCOPE_profile_cpu_i("RenderTimer", "Draw objects");

			for (auto &meshPaint : pipeline.keys)
			{
				auto painter = _painterManager->get_painter(Key<Painter>::createKey(meshPaint.first));
				for (auto &mode : meshPaint.second.drawables)
				{
					if (mode.renderMode.at(AGE_OCCLUDER) == false)
					{
						painter->draw(GL_TRIANGLES, _programs[PROGRAM_BUFFERING], mode.properties, mode.vertices);
					}
				}
			}
		}
#else
		{
			SCOPE_profile_gpu_i("Draw objects");
			SCOPE_profile_cpu_i("RenderTimer", "Clear buffer");

			_programs[PROGRAM_BUFFERING]->use();
			*_programs[PROGRAM_BUFFERING]->get_resource<Mat4>("projection_matrix") = infos.projection;
			*_programs[PROGRAM_BUFFERING]->get_resource<Mat4>("view_matrix") = infos.view;

			for (auto &meshPaint : pipeline.keys)
			{
				auto painter = _painterManager->get_painter(Key<Painter>::createKey(meshPaint.first));
				for (auto &mode : meshPaint.second.drawables)
				{
					if (renderModeCompatible(mode.renderMode))
					{
						painter->draw(GL_TRIANGLES, _programs[PROGRAM_BUFFERING], mode.properties, mode.vertices);
					}
				}
			}
		}
#endif
	}

}
<commit_msg>compilation fix<commit_after>
#include <Render/Pipelining/Pipelines/CustomRenderPass/DeferredBasicBuffering.hh>

#include <memory>

#include <Render/Textures/Texture2D.hh>
#include <Render/OpenGLTask/OpenGLState.hh>
#include <Render/GeometryManagement/Painting/Painter.hh>
#include <SpacePartitioning/Ouptut/RenderLight.hh>
#include <SpacePartitioning/Ouptut/RenderPipeline.hh>
#include <SpacePartitioning/Ouptut/RenderPainter.hh>
#include <SpacePartitioning/Ouptut/RenderCamera.hh>
#include <Render/ProgramResources/Types/Uniform/Mat4.hh>
#include <Core/ConfigurationManager.hpp>
#include <Core/Engine.hh>
#include <Configuration.hpp>
#include <Threads/RenderThread.hpp>
#include <Threads/ThreadManager.hpp>
#include <Render/DepthMapHandle.hpp>
#include <Render/DepthMap.hpp>

#define DEFERRED_SHADING_BUFFERING_VERTEX "deferred_shading/deferred_shading_get_buffer.vp"
#define DEFERRED_SHADING_BUFFERING_FRAG "deferred_shading/deferred_shading_get_buffer.fp"

namespace AGE
{
	enum Programs
	{
		PROGRAM_BUFFERING = 0,
		PROGRAM_NBR
	};

	DeferredBasicBuffering::DeferredBasicBuffering(std::shared_ptr<PaintingManager> painterManager,
												std::shared_ptr<Texture2D> diffuse,
												std::shared_ptr<Texture2D> normal,
												std::shared_ptr<Texture2D> specular,
												std::shared_ptr<Texture2D> depth) :
		FrameBufferRender(painterManager)
		, _depth(depth)
	{
		AGE_ASSERT(depth != nullptr);

		// We dont want to take the skinned or transparent meshes
		_forbidden[AGE_SKINNED] = true;
		_forbidden[AGE_SEMI_TRANSPARENT] = true;

		push_storage_output(GL_COLOR_ATTACHMENT0, diffuse);
		push_storage_output(GL_COLOR_ATTACHMENT1, normal);
		push_storage_output(GL_COLOR_ATTACHMENT2, specular);
		push_storage_output(GL_DEPTH_STENCIL_ATTACHMENT, depth);

		_programs.resize(PROGRAM_NBR);

		auto confManager = GetEngine()->getInstance<ConfigurationManager>();

		auto shaderPath = confManager->getConfiguration<std::string>("ShadersPath");

		// you have to set shader directory in configuration path
		AGE_ASSERT(shaderPath != nullptr);

		auto vertexShaderPath = shaderPath->getValue() + DEFERRED_SHADING_BUFFERING_VERTEX;
		auto fragmentShaderPath = shaderPath->getValue() + DEFERRED_SHADING_BUFFERING_FRAG;

		_programs[PROGRAM_BUFFERING] = std::make_shared<Program>(Program(std::string("program_buffering"),
		{
			std::make_shared<UnitProg>(vertexShaderPath, GL_VERTEX_SHADER),
			std::make_shared<UnitProg>(fragmentShaderPath, GL_FRAGMENT_SHADER)
		}));
	}

	void DeferredBasicBuffering::renderPass(RenderPipeline const &pipeline, RenderLightList const &, CameraInfos const &infos)
	{
		SCOPE_profile_gpu_i("DeferredBasicBuffering render pass");
		SCOPE_profile_cpu_i("RenderTimer", "DeferredBasicBuffering render pass");

		{
			SCOPE_profile_gpu_i("Clear buffer");
			SCOPE_profile_cpu_i("RenderTimer", "Clear buffer");

			OpenGLState::glEnable(GL_CULL_FACE);
			OpenGLState::glCullFace(GL_BACK);
			OpenGLState::glDepthMask(GL_TRUE);
			OpenGLState::glDepthFunc(GL_LEQUAL);
			OpenGLState::glDisable(GL_BLEND);
			OpenGLState::glDisable(GL_STENCIL_TEST);
			OpenGLState::glEnable(GL_DEPTH_TEST);
			OpenGLState::glClearColor(glm::vec4(0.f, 0.0f, 0.0f, 0.0f));
			OpenGLState::glEnable(GL_STENCIL_TEST);
			OpenGLState::glClearStencil(0);
			OpenGLState::glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
			OpenGLState::glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		}
#ifdef OCCLUSION_CULLING

		{
			SCOPE_profile_gpu_i("Occluders pass");
			SCOPE_profile_cpu_i("RenderTimer", "Occluders pass");

			_programs[PROGRAM_BUFFERING]->use();
			*_programs[PROGRAM_BUFFERING]->get_resource<Mat4>("projection_matrix") = infos.projection;
			*_programs[PROGRAM_BUFFERING]->get_resource<Mat4>("view_matrix") = infos.view;

			for (auto &meshPaint : pipeline.keys)
			{
				auto painter = _painterManager->get_painter(Key<Painter>::createKey(meshPaint.first));
				for (auto &mode : meshPaint.second.drawables)
				{
					if (mode.renderMode.at(AGE_OCCLUDER) == true)
					{
						painter->draw(GL_TRIANGLES, _programs[PROGRAM_BUFFERING], mode.properties, mode.vertices);
					}
				}
			}
		}

		{
			SCOPE_profile_gpu_i("Copy occlusion depth to CPU");
			SCOPE_profile_cpu_i("RenderTimer", "Copy occlusion depth to CPU");

			auto writableBuffer = GetRenderThread()->getDepthMapManager().getWritableMap();
			auto mipmapLevel = GetRenderThread()->getDepthMapManager().getMipmapLevel();

			if (writableBuffer.isValid())
			{
				writableBuffer.setMV(infos.projection * infos.view);
				glActiveTextureARB(GL_TEXTURE0_ARB);
				_depth->bind();
				glGenerateMipmap(GL_TEXTURE_2D);
				_depth->get(static_cast<GLint>(mipmapLevel), GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, writableBuffer.getWritableBuffer());
				_depth->unbind();
			}
		}

		{
			SCOPE_profile_gpu_i("Draw objects");
			SCOPE_profile_cpu_i("RenderTimer", "Draw objects");

			for (auto &meshPaint : pipeline.keys)
			{
				auto painter = _painterManager->get_painter(Key<Painter>::createKey(meshPaint.first));
				for (auto &mode : meshPaint.second.drawables)
				{
					if (mode.renderMode.at(AGE_OCCLUDER) == false)
					{
						painter->draw(GL_TRIANGLES, _programs[PROGRAM_BUFFERING], mode.properties, mode.vertices);
					}
				}
			}
		}
#else
		{
			SCOPE_profile_gpu_i("Draw objects");
			SCOPE_profile_cpu_i("RenderTimer", "Clear buffer");

			_programs[PROGRAM_BUFFERING]->use();
			*_programs[PROGRAM_BUFFERING]->get_resource<Mat4>("projection_matrix") = infos.projection;
			*_programs[PROGRAM_BUFFERING]->get_resource<Mat4>("view_matrix") = infos.view;

			for (auto &meshPaint : pipeline.keys)
			{
				auto painter = _painterManager->get_painter(Key<Painter>::createKey(meshPaint.first));
				for (auto &mode : meshPaint.second.drawables)
				{
					if (renderModeCompatible(mode.renderMode))
					{
						painter->draw(GL_TRIANGLES, _programs[PROGRAM_BUFFERING], mode.properties, mode.vertices);
					}
				}
			}
		}
#endif
	}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sdclient.cxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: ihi $ $Date: 2008-01-14 13:44: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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "Client.hxx"

#ifndef _COM_SUN_STAR_EMBED_NOVISUALAREASIZEEXCEPTION_HPP_
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#endif

#ifndef _SVDOOLE2_HXX //autogen
#include <svx/svdoole2.hxx>
#endif
#ifndef _SVDOGRAF_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SVDPAGV_HXX
#include <svx/svdpagv.hxx>
#endif

#include <toolkit/helper/vclunohelper.hxx>

#include "misc.hxx"

#ifdef STARIMAGE_AVAILABLE
#ifndef _SIMDLL_HXX
#include <sim2/simdll.hxx>
#endif
#endif

#include "strings.hrc"

#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_DRAW_VIEW_SHELL_HXX
#include "DrawViewShell.hxx"
#endif
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#include "sdresid.hxx"
#include <vcl/svapp.hxx>

using namespace com::sun::star;

namespace sd {

/*************************************************************************
|*
|* Ctor
|*
\************************************************************************/

Client::Client(SdrOle2Obj* pObj, ViewShell* pViewShell, ::Window* pWindow) :
    SfxInPlaceClient(pViewShell->GetViewShell(), pWindow, pObj->GetAspect() ),
    mpViewShell(pViewShell),
    pSdrOle2Obj(pObj),
    pSdrGrafObj(NULL),
    pOutlinerParaObj (NULL)
{
    SetObject( pObj->GetObjRef() );
    DBG_ASSERT( GetObject().is(), "No object connected!" );
}

/*************************************************************************
|*
|* Dtor
|*
\************************************************************************/

Client::~Client()
{
}

/*************************************************************************
|*
|* Wenn IP-aktiv, dann kommt diese Anforderung um Vergroesserung des
|* sichtbaren Ausschnitts des Objektes
|*
\************************************************************************/

void Client::RequestNewObjectArea( Rectangle& aObjRect )
{
    ::sd::View* pView = mpViewShell->GetView();

    sal_Bool bSizeProtect = sal_False;
    sal_Bool bPosProtect = sal_False;

    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    if (rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        SdrObject* pObj = pMark->GetMarkedSdrObj();

        // no need to check for changes, this method is called only if the area really changed
        bSizeProtect = pObj->IsResizeProtect();
        bPosProtect = pObj->IsMoveProtect();
    }

    Rectangle aOldRect = GetObjArea();
    if ( bPosProtect )
        aObjRect.SetPos( aOldRect.TopLeft() );

    if ( bSizeProtect )
        aObjRect.SetSize( aOldRect.GetSize() );

    Rectangle aWorkArea( pView->GetWorkArea() );
    if ( !aWorkArea.IsInside(aObjRect) && !bPosProtect && aObjRect != aOldRect )
    {
        // correct position
        Point aPos = aObjRect.TopLeft();
        Size  aSize = aObjRect.GetSize();
        Point aWorkAreaTL = aWorkArea.TopLeft();
        Point aWorkAreaBR = aWorkArea.BottomRight();

        aPos.X() = Max(aPos.X(), aWorkAreaTL.X());
        aPos.X() = Min(aPos.X(), aWorkAreaBR.X()-aSize.Width());
        aPos.Y() = Max(aPos.Y(), aWorkAreaTL.Y());
        aPos.Y() = Min(aPos.Y(), aWorkAreaBR.Y()-aSize.Height());

        aObjRect.SetPos(aPos);
    }
}

void Client::ObjectAreaChanged()
{
    ::sd::View* pView = mpViewShell->GetView();
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    if (rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        SdrObject* pObj = pMark->GetMarkedSdrObj();

        // no need to check for changes, this method is called only if the area really changed
        pObj->SetLogicRect( GetScaledObjArea() );
    }
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void Client::ViewChanged()
{
    if ( GetAspect() == embed::Aspects::MSOLE_ICON )
    {
        // the iconified object seems not to need such a scaling handling
        // since the replacement image and the size a completely controlled by the container
        // TODO/LATER: when the icon exchange is implemented the scaling handling might be required again here

        pSdrOle2Obj->ActionChanged(); // draw needs it to remove lines in slide preview
        return;
    }

    //TODO/LATER: should we try to avoid the recalculation of the visareasize
    //if we know that it didn't change?
    if (mpViewShell->GetActiveWindow())
    {
        ::sd::View* pView = mpViewShell->GetView();
        if (pView)
        {
            Rectangle aLogicRect( pSdrOle2Obj->GetLogicRect() );
            Size aLogicSize( aLogicRect.GetWidth(), aLogicRect.GetHeight() );

            if( pSdrOle2Obj->IsChart() )
            {
                //charts never should be stretched see #i84323# for example
                pSdrOle2Obj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aLogicSize ) );
                pSdrOle2Obj->BroadcastObjectChange();
                return;
            }

            // TODO/LEAN: maybe we can do this without requesting the VisualArea?
            // working with the visual area might need running state, so the object may switch itself to this state
            MapMode             aMap100( MAP_100TH_MM );
            Rectangle           aVisArea;
            Size aSize = pSdrOle2Obj->GetOrigObjSize( &aMap100 );

            aVisArea.SetSize( aSize );
            Size                aScaledSize( static_cast< long >( GetScaleWidth() * Fraction( aVisArea.GetWidth() ) ),
                                                static_cast< long >( GetScaleHeight() * Fraction( aVisArea.GetHeight() ) ) );

            // react to the change if the difference is bigger than one pixel
            Size aPixelDiff =
                Application::GetDefaultDevice()->LogicToPixel(
                    Size( aLogicRect.GetWidth() - aScaledSize.Width(),
                          aLogicRect.GetHeight() - aScaledSize.Height() ),
                    aMap100 );
            if( aPixelDiff.Width() || aPixelDiff.Height() )
            {
                pSdrOle2Obj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aScaledSize ) );
                pSdrOle2Obj->BroadcastObjectChange();
            }
            else
                pSdrOle2Obj->ActionChanged();
        }
    }
}

/*************************************************************************
|*
|* Objekt in den sichtbaren Breich scrollen
|*
\************************************************************************/

void Client::MakeVisible()
{
    if (mpViewShell->ISA(DrawViewShell))
    {
        static_cast<DrawViewShell*>(mpViewShell)->MakeVisible(
            pSdrOle2Obj->GetLogicRect(),
            *mpViewShell->GetActiveWindow());
    }
}

} // end of namespace sd

<commit_msg>INTEGRATION: CWS changefileheader (1.21.68); FILE MERGED 2008/04/01 15:34:25 thb 1.21.68.3: #i85898# Stripping all external header guards 2008/04/01 12:38:44 thb 1.21.68.2: #i85898# Stripping all external header guards 2008/03/31 13:58:00 rt 1.21.68.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: sdclient.cxx,v $
 * $Revision: 1.22 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "Client.hxx"
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#include <svx/svdoole2.hxx>
#include <svx/svdograf.hxx>
#include <svx/svdpagv.hxx>

#include <toolkit/helper/vclunohelper.hxx>

#include "misc.hxx"

#ifdef STARIMAGE_AVAILABLE
#ifndef _SIMDLL_HXX
#include <sim2/simdll.hxx>
#endif
#endif

#include "strings.hrc"
#include "ViewShell.hxx"
#include "DrawViewShell.hxx"
#include "View.hxx"
#include "Window.hxx"
#include "sdresid.hxx"
#include <vcl/svapp.hxx>

using namespace com::sun::star;

namespace sd {

/*************************************************************************
|*
|* Ctor
|*
\************************************************************************/

Client::Client(SdrOle2Obj* pObj, ViewShell* pViewShell, ::Window* pWindow) :
    SfxInPlaceClient(pViewShell->GetViewShell(), pWindow, pObj->GetAspect() ),
    mpViewShell(pViewShell),
    pSdrOle2Obj(pObj),
    pSdrGrafObj(NULL),
    pOutlinerParaObj (NULL)
{
    SetObject( pObj->GetObjRef() );
    DBG_ASSERT( GetObject().is(), "No object connected!" );
}

/*************************************************************************
|*
|* Dtor
|*
\************************************************************************/

Client::~Client()
{
}

/*************************************************************************
|*
|* Wenn IP-aktiv, dann kommt diese Anforderung um Vergroesserung des
|* sichtbaren Ausschnitts des Objektes
|*
\************************************************************************/

void Client::RequestNewObjectArea( Rectangle& aObjRect )
{
    ::sd::View* pView = mpViewShell->GetView();

    sal_Bool bSizeProtect = sal_False;
    sal_Bool bPosProtect = sal_False;

    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    if (rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        SdrObject* pObj = pMark->GetMarkedSdrObj();

        // no need to check for changes, this method is called only if the area really changed
        bSizeProtect = pObj->IsResizeProtect();
        bPosProtect = pObj->IsMoveProtect();
    }

    Rectangle aOldRect = GetObjArea();
    if ( bPosProtect )
        aObjRect.SetPos( aOldRect.TopLeft() );

    if ( bSizeProtect )
        aObjRect.SetSize( aOldRect.GetSize() );

    Rectangle aWorkArea( pView->GetWorkArea() );
    if ( !aWorkArea.IsInside(aObjRect) && !bPosProtect && aObjRect != aOldRect )
    {
        // correct position
        Point aPos = aObjRect.TopLeft();
        Size  aSize = aObjRect.GetSize();
        Point aWorkAreaTL = aWorkArea.TopLeft();
        Point aWorkAreaBR = aWorkArea.BottomRight();

        aPos.X() = Max(aPos.X(), aWorkAreaTL.X());
        aPos.X() = Min(aPos.X(), aWorkAreaBR.X()-aSize.Width());
        aPos.Y() = Max(aPos.Y(), aWorkAreaTL.Y());
        aPos.Y() = Min(aPos.Y(), aWorkAreaBR.Y()-aSize.Height());

        aObjRect.SetPos(aPos);
    }
}

void Client::ObjectAreaChanged()
{
    ::sd::View* pView = mpViewShell->GetView();
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    if (rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        SdrObject* pObj = pMark->GetMarkedSdrObj();

        // no need to check for changes, this method is called only if the area really changed
        pObj->SetLogicRect( GetScaledObjArea() );
    }
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void Client::ViewChanged()
{
    if ( GetAspect() == embed::Aspects::MSOLE_ICON )
    {
        // the iconified object seems not to need such a scaling handling
        // since the replacement image and the size a completely controlled by the container
        // TODO/LATER: when the icon exchange is implemented the scaling handling might be required again here

        pSdrOle2Obj->ActionChanged(); // draw needs it to remove lines in slide preview
        return;
    }

    //TODO/LATER: should we try to avoid the recalculation of the visareasize
    //if we know that it didn't change?
    if (mpViewShell->GetActiveWindow())
    {
        ::sd::View* pView = mpViewShell->GetView();
        if (pView)
        {
            Rectangle aLogicRect( pSdrOle2Obj->GetLogicRect() );
            Size aLogicSize( aLogicRect.GetWidth(), aLogicRect.GetHeight() );

            if( pSdrOle2Obj->IsChart() )
            {
                //charts never should be stretched see #i84323# for example
                pSdrOle2Obj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aLogicSize ) );
                pSdrOle2Obj->BroadcastObjectChange();
                return;
            }

            // TODO/LEAN: maybe we can do this without requesting the VisualArea?
            // working with the visual area might need running state, so the object may switch itself to this state
            MapMode             aMap100( MAP_100TH_MM );
            Rectangle           aVisArea;
            Size aSize = pSdrOle2Obj->GetOrigObjSize( &aMap100 );

            aVisArea.SetSize( aSize );
            Size                aScaledSize( static_cast< long >( GetScaleWidth() * Fraction( aVisArea.GetWidth() ) ),
                                                static_cast< long >( GetScaleHeight() * Fraction( aVisArea.GetHeight() ) ) );

            // react to the change if the difference is bigger than one pixel
            Size aPixelDiff =
                Application::GetDefaultDevice()->LogicToPixel(
                    Size( aLogicRect.GetWidth() - aScaledSize.Width(),
                          aLogicRect.GetHeight() - aScaledSize.Height() ),
                    aMap100 );
            if( aPixelDiff.Width() || aPixelDiff.Height() )
            {
                pSdrOle2Obj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aScaledSize ) );
                pSdrOle2Obj->BroadcastObjectChange();
            }
            else
                pSdrOle2Obj->ActionChanged();
        }
    }
}

/*************************************************************************
|*
|* Objekt in den sichtbaren Breich scrollen
|*
\************************************************************************/

void Client::MakeVisible()
{
    if (mpViewShell->ISA(DrawViewShell))
    {
        static_cast<DrawViewShell*>(mpViewShell)->MakeVisible(
            pSdrOle2Obj->GetLogicRect(),
            *mpViewShell->GetActiveWindow());
    }
}

} // end of namespace sd

<|endoftext|>


<commit_before>//
//  color.cpp
//  displaySimTest
//
//  Created by Kristoffer Andersen on 10/07/15.
//
//

#include <color.h>

using namespace mono::display;

/// MARK: Public contructors

Color::Color()
{
    value = 0x0821; // black color
}

Color::Color(const int col)
{
    value = (uint16_t) col;
}

Color::Color(const Color &color)
{
    value = color.value;
}

Color::Color(uint8_t R, uint8_t G, uint8_t B)
{
    value = ((R << 8) & 0xF800) |
            ((G << 3)  & 0x07E0) |
            ((B >> 3) & 0x1F);
}

/// MARK: Getters

uint8_t Color::Red() const
{
    return (value >> 8) & 0xF8;
}
uint8_t Color::Green() const
{
    return (value >> 3) & 0xFC;
}
uint8_t Color::Blue() const
{
    return (value << 3) & 0xF8;
}

/// MARK: Misc

uint8_t* Color::BytePointer()
{
    return (uint8_t*) &(this->value);
}

Color Color::scale(uint8_t factor) const
{
    uint16_t r = this->Red(), g = this->Green(), b = this->Blue();
    r *= factor;
    g *= factor;
    b *= factor;

    return Color(r >> 8, g >> 8, b >> 8);
}

Color Color::blendMultiply(Color other) const
{
    uint16_t r = this->Red(), g = this->Green(), b = this->Blue();
    r *= other.Red();
    g *= other.Green();
    b *= other.Blue();

    return Color(r >> 8, g >> 8, b >> 8);
}

Color Color::blendAdditive(Color other) const
{
    uint16_t r = this->Red(), g = this->Green(), b = this->Blue();
    r += other.Red();
    g += other.Green();
    b += other.Blue();

    return Color(r, g, b);
}

Color Color::invert() const
{
    uint8_t r = Red(), g = Green(), b = Blue();
    r = 255 - r;
    g = 255 - g;
    b = 255 - b;

    return Color(r,g,b);
}

Color Color::alphaBlend(uint8_t intensity, Color const &other) const
{
    if (this->value == other.value)
        return other;

    Color srcA = this->scale(intensity);
    uint8_t dstA = (255 - intensity);
    Color blend = srcA + other.scale(dstA);
    return blend;
}

/// MARK: Operator overloads

uint16_t Color::operator=(Color col)
{
    value = col.value;
    return value;
}

bool Color::operator!=(const Color &col)
{
    return col.value != this->value;
}

bool Color::operator==(const Color &col)
{
    return this->value == col.value;
}

Color Color::operator*(const mono::display::Color &col)
{
    return blendMultiply(col);
}

Color Color::operator+(const mono::display::Color &col)
{
    return blendAdditive(col);
}
<commit_msg>Added better scaling for colors<commit_after>//
//  color.cpp
//  displaySimTest
//
//  Created by Kristoffer Andersen on 10/07/15.
//
//

#include <color.h>

using namespace mono::display;

/// MARK: Public contructors

Color::Color()
{
    value = 0x0821; // black color
}

Color::Color(const int col)
{
    value = (uint16_t) col;
}

Color::Color(const Color &color)
{
    value = color.value;
}

Color::Color(uint8_t R, uint8_t G, uint8_t B)
{
    value = ((R << 8) & 0xF800) |
            ((G << 3)  & 0x07E0) |
            ((B >> 3) & 0x1F);
}

/// MARK: Getters

uint8_t Color::Red() const
{
    return (value >> 8) & 0xF8;
}
uint8_t Color::Green() const
{
    return (value >> 3) & 0xFC;
}
uint8_t Color::Blue() const
{
    return (value << 3) & 0xF8;
}

/// MARK: Misc

uint8_t* Color::BytePointer()
{
    return (uint8_t*) &(this->value);
}

Color Color::scale(uint8_t factor) const
{
    if (factor == 0xFF)
        return *this;
    else if (factor == 0)
        return Color(0);

    uint16_t r = this->Red(), g = this->Green(), b = this->Blue();
    r *= factor;
    g *= factor;
    b *= factor;

    return Color(r >> 8, g >> 8, b >> 8);
}

Color Color::blendMultiply(Color other) const
{
    uint16_t r = this->Red(), g = this->Green(), b = this->Blue();
    r *= other.Red();
    g *= other.Green();
    b *= other.Blue();

    return Color(r >> 8, g >> 8, b >> 8);
}

Color Color::blendAdditive(Color other) const
{
    uint16_t r = this->Red(), g = this->Green(), b = this->Blue();
    r += other.Red();
    g += other.Green();
    b += other.Blue();

    return Color(r, g, b);
}

Color Color::invert() const
{
    uint8_t r = Red(), g = Green(), b = Blue();
    r = 255 - r;
    g = 255 - g;
    b = 255 - b;

    return Color(r,g,b);
}

Color Color::alphaBlend(uint8_t intensity, Color const &other) const
{
    if (this->value == other.value)
        return other;

    Color srcA = this->scale(intensity);
    uint8_t dstA = (255 - intensity);
    Color blend = srcA + other.scale(dstA);
    return blend;
}

/// MARK: Operator overloads

uint16_t Color::operator=(Color col)
{
    value = col.value;
    return value;
}

bool Color::operator!=(const Color &col)
{
    return col.value != this->value;
}

bool Color::operator==(const Color &col)
{
    return this->value == col.value;
}

Color Color::operator*(const mono::display::Color &col)
{
    return blendMultiply(col);
}

Color Color::operator+(const mono::display::Color &col)
{
    return blendAdditive(col);
}
<|endoftext|>


<commit_before>#include "Arith256.h"
#include "Runtime.h"
#include "Type.h"

#include <llvm/IR/Function.h>

namespace dev
{
namespace eth
{
namespace jit
{

Arith256::Arith256(llvm::IRBuilder<>& _builder) :
	CompilerHelper(_builder)
{
	using namespace llvm;

	m_result = m_builder.CreateAlloca(Type::Word, nullptr, "arith.result");
	m_arg1 = m_builder.CreateAlloca(Type::Word, nullptr, "arith.arg1");
	m_arg2 = m_builder.CreateAlloca(Type::Word, nullptr, "arith.arg2");
	m_arg3 = m_builder.CreateAlloca(Type::Word, nullptr, "arith.arg3");

	using Linkage = GlobalValue::LinkageTypes;

	llvm::Type* arg2Types[] = {Type::WordPtr, Type::WordPtr, Type::WordPtr};
	llvm::Type* arg3Types[] = {Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr};

	m_mul = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_mul", getModule());
	m_div = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_div", getModule());
	m_mod = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_mod", getModule());
	m_sdiv = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_sdiv", getModule());
	m_smod = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_smod", getModule());
	m_exp = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_exp", getModule());
	m_addmod = Function::Create(FunctionType::get(Type::Void, arg3Types, false), Linkage::ExternalLinkage, "arith_addmod", getModule());
	m_mulmod = Function::Create(FunctionType::get(Type::Void, arg3Types, false), Linkage::ExternalLinkage, "arith_mulmod", getModule());
}

Arith256::~Arith256()
{}

llvm::Value* Arith256::binaryOp(llvm::Function* _op, llvm::Value* _arg1, llvm::Value* _arg2)
{
	m_builder.CreateStore(_arg1, m_arg1);
	m_builder.CreateStore(_arg2, m_arg2);
	m_builder.CreateCall3(_op, m_arg1, m_arg2, m_result);
	return m_builder.CreateLoad(m_result);
}

llvm::Value* Arith256::ternaryOp(llvm::Function* _op, llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3)
{
	m_builder.CreateStore(_arg1, m_arg1);
	m_builder.CreateStore(_arg2, m_arg2);
	m_builder.CreateStore(_arg3, m_arg3);
	m_builder.CreateCall4(_op, m_arg1, m_arg2, m_arg3, m_result);
	return m_builder.CreateLoad(m_result);
}

llvm::Value* Arith256::mul(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_mul, _arg1, _arg2);
}

llvm::Value* Arith256::div(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_div, _arg1, _arg2);
}

llvm::Value* Arith256::mod(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_mod, _arg1, _arg2);
}

llvm::Value* Arith256::sdiv(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_sdiv, _arg1, _arg2);
}

llvm::Value* Arith256::smod(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_smod, _arg1, _arg2);
}

llvm::Value* Arith256::exp(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_exp, _arg1, _arg2);
}

llvm::Value* Arith256::addmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3)
{
	return ternaryOp(m_addmod, _arg1, _arg2, _arg3);
}

llvm::Value* Arith256::mulmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3)
{
	return ternaryOp(m_mulmod, _arg1, _arg2, _arg3);
}

namespace
{
	using s256 = boost::multiprecision::int256_t;

	inline s256 u2s(u256 _u)
	{
		static const bigint c_end = (bigint)1 << 256;
		static const u256 c_send = (u256)1 << 255;
		if (_u < c_send)
			return (s256)_u;
		else
			return (s256)-(c_end - _u);
	}

	inline u256 s2u(s256 _u)
	{
		static const bigint c_end = (bigint)1 << 256;
		if (_u >= 0)
			return (u256)_u;
		else
			return (u256)(c_end + _u);
	}
}

}
}
}

extern "C"
{

	using namespace dev::eth::jit;

	EXPORT void arith_mul(i256* _arg1, i256* _arg2, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		*o_result = eth2llvm(arg1 * arg2);
	}

	EXPORT void arith_div(i256* _arg1, i256* _arg2, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		*o_result = eth2llvm(arg2 == 0 ? arg2 : arg1 / arg2);
	}

	EXPORT void arith_mod(i256* _arg1, i256* _arg2, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		*o_result = eth2llvm(arg2 == 0 ? arg2 : arg1 % arg2);
	}

	EXPORT void arith_sdiv(i256* _arg1, i256* _arg2, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		*o_result = eth2llvm(arg2 == 0 ? arg2 : s2u(u2s(arg1) / u2s(arg2)));
	}

	EXPORT void arith_smod(i256* _arg1, i256* _arg2, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		*o_result = eth2llvm(arg2 == 0 ? arg2 : s2u(u2s(arg1) % u2s(arg2)));
	}

	EXPORT void arith_exp(i256* _arg1, i256* _arg2, i256* o_result)
	{
		bigint left = llvm2eth(*_arg1);
		bigint right = llvm2eth(*_arg2);
		auto ret = static_cast<u256>(boost::multiprecision::powm(left, right, bigint(2) << 256));
		*o_result = eth2llvm(ret);
	}

	EXPORT void arith_mulmod(i256* _arg1, i256* _arg2, i256* _arg3, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		auto arg3 = llvm2eth(*_arg3);
		if (arg3 != 0)
			*o_result = eth2llvm(u256((bigint(arg1) * bigint(arg2)) % arg3));
		else
			*o_result = {};
	}

	EXPORT void arith_addmod(i256* _arg1, i256* _arg2, i256* _arg3, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		auto arg3 = llvm2eth(*_arg3);
		if (arg3 != 0)
			*o_result = eth2llvm(u256((bigint(arg1) + bigint(arg2)) % arg3));
		else
			*o_result = {};
	}

}

<commit_msg>Internal mul256 implementation<commit_after>#include "Arith256.h"
#include "Runtime.h"
#include "Type.h"

#include <llvm/IR/Function.h>

namespace dev
{
namespace eth
{
namespace jit
{

Arith256::Arith256(llvm::IRBuilder<>& _builder) :
	CompilerHelper(_builder)
{
	using namespace llvm;

	m_result = m_builder.CreateAlloca(Type::Word, nullptr, "arith.result");
	m_arg1 = m_builder.CreateAlloca(Type::Word, nullptr, "arith.arg1");
	m_arg2 = m_builder.CreateAlloca(Type::Word, nullptr, "arith.arg2");
	m_arg3 = m_builder.CreateAlloca(Type::Word, nullptr, "arith.arg3");

	using Linkage = GlobalValue::LinkageTypes;

	llvm::Type* arg2Types[] = {Type::WordPtr, Type::WordPtr, Type::WordPtr};
	llvm::Type* arg3Types[] = {Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr};

	m_mul = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_mul", getModule());
	m_div = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_div", getModule());
	m_mod = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_mod", getModule());
	m_sdiv = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_sdiv", getModule());
	m_smod = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_smod", getModule());
	m_exp = Function::Create(FunctionType::get(Type::Void, arg2Types, false), Linkage::ExternalLinkage, "arith_exp", getModule());
	m_addmod = Function::Create(FunctionType::get(Type::Void, arg3Types, false), Linkage::ExternalLinkage, "arith_addmod", getModule());
	m_mulmod = Function::Create(FunctionType::get(Type::Void, arg3Types, false), Linkage::ExternalLinkage, "arith_mulmod", getModule());
}

Arith256::~Arith256()
{}

llvm::Value* Arith256::binaryOp(llvm::Function* _op, llvm::Value* _arg1, llvm::Value* _arg2)
{
	m_builder.CreateStore(_arg1, m_arg1);
	m_builder.CreateStore(_arg2, m_arg2);
	m_builder.CreateCall3(_op, m_arg1, m_arg2, m_result);
	return m_builder.CreateLoad(m_result);
}

llvm::Value* Arith256::ternaryOp(llvm::Function* _op, llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3)
{
	m_builder.CreateStore(_arg1, m_arg1);
	m_builder.CreateStore(_arg2, m_arg2);
	m_builder.CreateStore(_arg3, m_arg3);
	m_builder.CreateCall4(_op, m_arg1, m_arg2, m_arg3, m_result);
	return m_builder.CreateLoad(m_result);
}

llvm::Value* Arith256::mul(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_mul, _arg1, _arg2);
}

llvm::Value* Arith256::div(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_div, _arg1, _arg2);
}

llvm::Value* Arith256::mod(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_mod, _arg1, _arg2);
}

llvm::Value* Arith256::sdiv(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_sdiv, _arg1, _arg2);
}

llvm::Value* Arith256::smod(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_smod, _arg1, _arg2);
}

llvm::Value* Arith256::exp(llvm::Value* _arg1, llvm::Value* _arg2)
{
	return binaryOp(m_exp, _arg1, _arg2);
}

llvm::Value* Arith256::addmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3)
{
	return ternaryOp(m_addmod, _arg1, _arg2, _arg3);
}

llvm::Value* Arith256::mulmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3)
{
	return ternaryOp(m_mulmod, _arg1, _arg2, _arg3);
}

namespace
{
	using s256 = boost::multiprecision::int256_t;

	inline s256 u2s(u256 _u)
	{
		static const bigint c_end = (bigint)1 << 256;
		static const u256 c_send = (u256)1 << 255;
		if (_u < c_send)
			return (s256)_u;
		else
			return (s256)-(c_end - _u);
	}

	inline u256 s2u(s256 _u)
	{
		static const bigint c_end = (bigint)1 << 256;
		if (_u >= 0)
			return (u256)_u;
		else
			return (u256)(c_end + _u);
	}

	using uint128 = __uint128_t;

//	uint128 add(uint128 a, uint128 b) { return a + b; }
//	uint128 mul(uint128 a, uint128 b) { return a * b; }
//
//	uint128 mulq(uint64_t x, uint64_t y)
//	{
//		return (uint128)x * (uint128)y;
//	}
//
//	uint128 addc(uint64_t x, uint64_t y)
//	{
//		return (uint128)x * (uint128)y;
//	}

	struct uint256
	{
		uint64_t lo;
		uint64_t mid;
		uint128 hi;
	};

//	uint256 add(uint256 x, uint256 y)
//	{
//		auto lo = (uint128) x.lo + y.lo;
//		auto mid = (uint128) x.mid + y.mid + (lo >> 64);
//		return {lo, mid, x.hi + y.hi + (mid >> 64)};
//	}

	uint256 mul(uint256 x, uint256 y)
	{
		auto t1 = (uint128) x.lo * y.lo;
		auto t2 = (uint128) x.lo * y.mid;
		auto t3 = x.lo * y.hi;
		auto t4 = (uint128) x.mid * y.lo;
		auto t5 = (uint128) x.mid * y.mid;
		auto t6 = x.mid * y.hi;
		auto t7 = x.hi * y.lo;
		auto t8 = x.hi * y.mid;

		auto lo = (uint64_t) t1;
		auto m1 = (t1 >> 64) + (uint64_t) t2;
		auto m2 = (uint64_t) m1;
		auto mid = (uint128) m2 + (uint64_t) t4;
		auto hi = (t2 >> 64) + t3 + (t4 >> 64) + t5 + (t6 << 64) + t7
			 + (t8 << 64) + (m1 >> 64) + (mid >> 64);

		return {lo, (uint64_t)mid, hi};
	}
}

}
}
}

extern "C"
{

	using namespace dev::eth::jit;

	EXPORT void arith_mul(uint256* _arg1, uint256* _arg2, uint256* o_result)
	{
		*o_result = mul(*_arg1, *_arg2);
	}

	EXPORT void arith_div(i256* _arg1, i256* _arg2, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		*o_result = eth2llvm(arg2 == 0 ? arg2 : arg1 / arg2);
	}

	EXPORT void arith_mod(i256* _arg1, i256* _arg2, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		*o_result = eth2llvm(arg2 == 0 ? arg2 : arg1 % arg2);
	}

	EXPORT void arith_sdiv(i256* _arg1, i256* _arg2, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		*o_result = eth2llvm(arg2 == 0 ? arg2 : s2u(u2s(arg1) / u2s(arg2)));
	}

	EXPORT void arith_smod(i256* _arg1, i256* _arg2, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		*o_result = eth2llvm(arg2 == 0 ? arg2 : s2u(u2s(arg1) % u2s(arg2)));
	}

	EXPORT void arith_exp(i256* _arg1, i256* _arg2, i256* o_result)
	{
		bigint left = llvm2eth(*_arg1);
		bigint right = llvm2eth(*_arg2);
		auto ret = static_cast<u256>(boost::multiprecision::powm(left, right, bigint(2) << 256));
		*o_result = eth2llvm(ret);
	}

	EXPORT void arith_mulmod(i256* _arg1, i256* _arg2, i256* _arg3, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		auto arg3 = llvm2eth(*_arg3);
		if (arg3 != 0)
			*o_result = eth2llvm(u256((bigint(arg1) * bigint(arg2)) % arg3));
		else
			*o_result = {};
	}

	EXPORT void arith_addmod(i256* _arg1, i256* _arg2, i256* _arg3, i256* o_result)
	{
		auto arg1 = llvm2eth(*_arg1);
		auto arg2 = llvm2eth(*_arg2);
		auto arg3 = llvm2eth(*_arg3);
		if (arg3 != 0)
			*o_result = eth2llvm(u256((bigint(arg1) + bigint(arg2)) % arg3));
		else
			*o_result = {};
	}

}

<|endoftext|>


<commit_before>#include <iostream>
#include "brainfuck.h"
void usage()
{
  std::cout << "./interpreter" << std::endl;
  std::cout << "./interpreter <program.txt> <input.txt>" << std::endl;
}

int main(int argc, char* argv){
  if(argc == 1)
    {
      Brainfuck bf;
      bf.run();
    }
  else
    {
      usage();
    }
  return 0;
}
<commit_msg>Fixed the command line arguments + usage<commit_after>#include <iostream>
#include "brainfuck.h"
void usage()
{
  std::cout << "./interpreter" << std::endl;
  std::cout << "./interpreter <program.txt> <input.txt>" << std::endl;
}

int main(int argc, char* argv[]){
  if(argc == 1)
    {
      Brainfuck bf;
      bf.run();
    }
  else
    {
      usage();
    }
  return 0;
}
<|endoftext|>


<commit_before>#ifndef EITHER_HH
#define EITHER_HH

#include <functional>
#include <new>
#include <type_traits>
#include <utility>

template<typename Left, typename Right,
         typename = typename std::enable_if<std::is_nothrow_move_constructible<Left>::value &&
                                            std::is_nothrow_move_constructible<Right>::value
                                           >::type
        >
class either {
  void destroy() {
    if (is_left) {
      left.~Left();
    } else {
      right.~Right();
    }
  }

  union {
    Left left;
    Right right;
  };

  bool is_left;

public:
  either(const Left &other) : left(other), is_left(true) {}
  either(const Right &other) : right(other), is_left(false) {}
  either(Left &&other) : left(std::move(other)), is_left(true) {}
  either(Right &&other) : right(std::move(other)), is_left(false) {}

  either(const either &other) : is_left(other.is_left) {
    if (is_left) {
      new(&left) Left(other.left);
    } else {
      new(&right) Right(other.right);
    }
  }

  either(either &&other) noexcept : is_left(other.is_left) {
    if (is_left) {
      new(&left) Left(std::move(other.left));
    } else {
      new(&right) Right(std::move(other.right));
    }
  }

  either &operator=(either other) {
    destroy();
    is_left = other.is_left;
    if (is_left) {
      new(&left) Left(std::move(other.left));
    } else {
      new(&right) Right(std::move(other.right));
    }
    return *this;
  }

  ~either() {
    destroy();
  }

  template<typename LeftF, typename RightF>
  auto match(LeftF leftf, RightF rightf) -> decltype(leftf(left)) {
    if (is_left) {
      return leftf(left);
    } else {
      return rightf(right);
    }
  }

  template<typename LeftF, typename RightF>
  auto match(LeftF leftf, RightF rightf) const -> decltype(leftf(left)) {
    if (is_left) {
      return leftf(left);
    } else {
      return rightf(right);
    }
  }

  template<typename ...Args>
  void emplace_left(Args &&...args) {
    destroy();
    new(&left) Left(std::forward<Args>(args)...);
  }

  template<typename ...Args>
  void emplace_right(Args &&...args) {
    destroy();
    new(&right) Right(std::forward<Args>(args)...);
  }

  bool operator==(const either &other) const {
    return is_left == other.is_left &&
           is_left ? left == other.left : right == other.right;
  }

  bool operator!=(const either &other) const {
    return is_left != other.is_left ||
           is_left ? left != other.left : right != other.right;
  }

  friend struct std::hash<either<Left, Right>>;
};

namespace std {
  template<typename Left, typename Right>
  struct hash<either<Left, Right>> {
    hash() : hash_left(), hash_right() {}

    size_t operator()(const either<Left, Right> &e) const {
      return e.is_left ? ~hash_left(e.left) : hash_right(e.right);
    }

  private:
    const hash<Left> hash_left;
    const hash<Right> hash_right;
  };
}

#endif
<commit_msg>either.hh: clean up match methods<commit_after>#ifndef EITHER_HH
#define EITHER_HH

#include <functional>
#include <new>
#include <type_traits>
#include <utility>

template<typename Left, typename Right,
         typename = typename std::enable_if<std::is_nothrow_move_constructible<Left>::value &&
                                            std::is_nothrow_move_constructible<Right>::value
                                           >::type
        >
class either {
  void destroy() {
    if (is_left) {
      left.~Left();
    } else {
      right.~Right();
    }
  }

  union {
    Left left;
    Right right;
  };

  bool is_left;

public:
  either(const Left &other) : left(other), is_left(true) {}
  either(const Right &other) : right(other), is_left(false) {}
  either(Left &&other) : left(std::move(other)), is_left(true) {}
  either(Right &&other) : right(std::move(other)), is_left(false) {}

  either(const either &other) : is_left(other.is_left) {
    if (is_left) {
      new(&left) Left(other.left);
    } else {
      new(&right) Right(other.right);
    }
  }

  either(either &&other) noexcept : is_left(other.is_left) {
    if (is_left) {
      new(&left) Left(std::move(other.left));
    } else {
      new(&right) Right(std::move(other.right));
    }
  }

  either &operator=(either other) {
    destroy();
    is_left = other.is_left;
    if (is_left) {
      new(&left) Left(std::move(other.left));
    } else {
      new(&right) Right(std::move(other.right));
    }
    return *this;
  }

  ~either() {
    destroy();
  }

  template<typename LeftF, typename RightF>
  auto match(LeftF leftf, RightF rightf) -> decltype(leftf(left)) {
    return is_left ? leftf(left) : rightf(right);
  }

  template<typename LeftF, typename RightF>
  auto match(LeftF leftf, RightF rightf) const -> decltype(leftf(left)) {
    return is_left ? leftf(left) : rightf(right);
  }

  template<typename ...Args>
  void emplace_left(Args &&...args) {
    destroy();
    new(&left) Left(std::forward<Args>(args)...);
  }

  template<typename ...Args>
  void emplace_right(Args &&...args) {
    destroy();
    new(&right) Right(std::forward<Args>(args)...);
  }

  bool operator==(const either &other) const {
    return is_left == other.is_left &&
           is_left ? left == other.left : right == other.right;
  }

  bool operator!=(const either &other) const {
    return is_left != other.is_left ||
           is_left ? left != other.left : right != other.right;
  }

  friend struct std::hash<either<Left, Right>>;
};

namespace std {
  template<typename Left, typename Right>
  struct hash<either<Left, Right>> {
    hash() : hash_left(), hash_right() {}

    size_t operator()(const either<Left, Right> &e) const {
      return e.is_left ? ~hash_left(e.left) : hash_right(e.right);
    }

  private:
    const hash<Left> hash_left;
    const hash<Right> hash_right;
  };
}

#endif
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 "IntegerTest.h"

using namespace std;
using namespace decaf;
using namespace decaf::lang;

void IntegerTest::test(void)
{
    int x = Integer::parseInt("12");
    int y = Integer::parseInt("12.1");
    int z = Integer::parseInt("42 24");

    CPPUNIT_ASSERT( x == 12 );
    CPPUNIT_ASSERT( y == 12 );
    CPPUNIT_ASSERT( z == 42 );

    std::string x1 = Integer::toString( x );
    std::string y1 = Integer::toString( y );
    std::string z1 = Integer::toString( z );

    CPPUNIT_ASSERT( x1 == "12" );
    CPPUNIT_ASSERT( y1 == "12" );
    CPPUNIT_ASSERT( z1 == "42" );

}
<commit_msg>http://issues.apache.org/activemq/browse/AMQCPP-103<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 "IntegerTest.h"

using namespace std;
using namespace decaf;
using namespace decaf::lang;

void IntegerTest::test(void)
{
    int x = Integer::parseInt("12");
    int y = Integer::parseInt("FF", 16);
    int z = Integer::parseInt("42");

    CPPUNIT_ASSERT( x == 12 );
    CPPUNIT_ASSERT( y == 255 );
    CPPUNIT_ASSERT( z == 42 );

    std::string x1 = Integer::toString( x );
    std::string y1 = Integer::toString( y );
    std::string z1 = Integer::toString( z );

    CPPUNIT_ASSERT( x1 == "12" );
    CPPUNIT_ASSERT( y1 == "255" );
    CPPUNIT_ASSERT( z1 == "42" );

}
<|endoftext|>