<commit_before>// Use RAII types

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

int main()
{
	std::vector<int> vec = {1, 2, 3, 4, 5};
	std::map<std::string, int> map = {{"Foo", 10}, {"Bar", 20}};
	std::string str = "Some text";
	std::unique_ptr<int> ptr1 = std::make_unique<int>(8);
	std::shared_ptr<int> ptr2 = std::make_shared<int>(16);
}

// Avoid manual memory management to improve safety and reduce bugs
// and memory leaks.
//
// Every object created on [10-14] will internally manage some
// dynamically allocated memory (allocated with the `new` keyword).
// They are all, however, implemented such that they deallocate that
// memory when they are destroyed. This practice is known as RAII.
//
// The user of these classes does not need to perform manual memory
// management, reducing the risk of memory leaks and other bugs. In
// fact, the use of `new` and `delete` can be avoided entirely by
// using these RAII types.
//
// Likewise, it is good practice to ensure your own classes also
// implement the RAII idiom with the
// [rule of three](/common-tasks/rule-of-three.html)
// or [rule of zero](/common-tasks/rule-of-zero.html).
<commit_msg>Fix link from "use RAII" to rule of five<commit_after>// Use RAII types

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

int main()
{
	std::vector<int> vec = {1, 2, 3, 4, 5};
	std::map<std::string, int> map = {{"Foo", 10}, {"Bar", 20}};
	std::string str = "Some text";
	std::unique_ptr<int> ptr1 = std::make_unique<int>(8);
	std::shared_ptr<int> ptr2 = std::make_shared<int>(16);
}

// Avoid manual memory management to improve safety and reduce bugs
// and memory leaks.
//
// Every object created on [10-14] will internally manage some
// dynamically allocated memory (allocated with the `new` keyword).
// They are all, however, implemented such that they deallocate that
// memory when they are destroyed. This practice is known as RAII.
//
// The user of these classes does not need to perform manual memory
// management, reducing the risk of memory leaks and other bugs. In
// fact, the use of `new` and `delete` can be avoided entirely by
// using these RAII types.
//
// Likewise, it is good practice to ensure your own classes also
// implement the RAII idiom with the
// [rule of five](/common-tasks/rule-of-five.html)
// or [rule of zero](/common-tasks/rule-of-zero.html).
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Max Kellermann <max@duempel.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SYSTEM_ERROR_HXX
#define SYSTEM_ERROR_HXX

#include "util/StringUtil.hxx"

#include <inline/compiler.h>

#include <system_error>
#include <utility>

template<typename... Args>
static inline std::system_error
FormatSystemError(std::error_code code, const char *fmt, Args&&... args)
{
	char buffer[1024];
	snprintf(buffer, sizeof(buffer), fmt, std::forward<Args>(args)...);
	return std::system_error(code, buffer);
}

#ifdef WIN32

#include <windows.h>

static inline std::system_error
MakeLastError(DWORD code, const char *msg)
{
	return std::system_error(std::error_code(code, std::system_category()),
				 msg);
}

static inline std::system_error
MakeLastError(const char *msg)
{
	return MakeLastError(GetLastError(), msg);
}

template<typename... Args>
static inline std::system_error
FormatLastError(DWORD code, const char *fmt, Args&&... args)
{
	char buffer[512];
	const auto end = buffer + sizeof(buffer);
	size_t length = snprintf(buffer, sizeof(buffer) - 128,
				 fmt, std::forward<Args>(args)...);
	char *p = buffer + length;
	*p++ = ':';
	*p++ = ' ';

	FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
		       FORMAT_MESSAGE_IGNORE_INSERTS,
		       nullptr, code, 0, p, end - p, nullptr);
	return MakeLastError(code, buffer);
}

template<typename... Args>
static inline std::system_error
FormatLastError(const char *fmt, Args&&... args)
{
	return FormatLastError(GetLastError(), fmt,
			       std::forward<Args>(args)...);
}

#else

#include <errno.h>
#include <string.h>

static inline std::system_error
MakeErrno(int code, const char *msg)
{
	return std::system_error(std::error_code(code, std::system_category()),
				 msg);
}

static inline std::system_error
MakeErrno(const char *msg)
{
	return MakeErrno(errno, msg);
}

template<typename... Args>
static inline std::system_error
FormatErrno(int code, const char *fmt, Args&&... args)
{
	char buffer[512];
	snprintf(buffer, sizeof(buffer),
		 fmt, std::forward<Args>(args)...);
	return MakeErrno(code, buffer);
}

template<typename... Args>
static inline std::system_error
FormatErrno(const char *fmt, Args&&... args)
{
	return FormatErrno(errno, fmt, std::forward<Args>(args)...);
}

#endif

gcc_pure
static inline bool
IsFileNotFound(const std::system_error &e)
{
#ifdef WIN32
	return e.code().category() == std::system_category() &&
		e.code().value() == ERROR_FILE_NOT_FOUND;
#else
	return e.code().category() == std::system_category() &&
		e.code().value() == ENOENT;
#endif
}

gcc_pure
static inline bool
IsAccessDenied(const std::system_error &e)
{
#ifdef WIN32
	return e.code().category() == std::system_category() &&
		e.code().value() == ERROR_ACCESS_DENIED;
#else
	return e.code().category() == std::system_category() &&
		e.code().value() == EACCES;
#endif
}

#endif
<commit_msg>system/Error: add MakeErrno() overloads without mnessage<commit_after>/*
 * Copyright (C) 2015 Max Kellermann <max@duempel.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SYSTEM_ERROR_HXX
#define SYSTEM_ERROR_HXX

#include "util/StringUtil.hxx"

#include <inline/compiler.h>

#include <system_error>
#include <utility>

template<typename... Args>
static inline std::system_error
FormatSystemError(std::error_code code, const char *fmt, Args&&... args)
{
	char buffer[1024];
	snprintf(buffer, sizeof(buffer), fmt, std::forward<Args>(args)...);
	return std::system_error(code, buffer);
}

#ifdef WIN32

#include <windows.h>

static inline std::system_error
MakeLastError(DWORD code, const char *msg)
{
	return std::system_error(std::error_code(code, std::system_category()),
				 msg);
}

static inline std::system_error
MakeLastError(const char *msg)
{
	return MakeLastError(GetLastError(), msg);
}

template<typename... Args>
static inline std::system_error
FormatLastError(DWORD code, const char *fmt, Args&&... args)
{
	char buffer[512];
	const auto end = buffer + sizeof(buffer);
	size_t length = snprintf(buffer, sizeof(buffer) - 128,
				 fmt, std::forward<Args>(args)...);
	char *p = buffer + length;
	*p++ = ':';
	*p++ = ' ';

	FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
		       FORMAT_MESSAGE_IGNORE_INSERTS,
		       nullptr, code, 0, p, end - p, nullptr);
	return MakeLastError(code, buffer);
}

template<typename... Args>
static inline std::system_error
FormatLastError(const char *fmt, Args&&... args)
{
	return FormatLastError(GetLastError(), fmt,
			       std::forward<Args>(args)...);
}

#else

#include <errno.h>
#include <string.h>

static inline std::system_error
MakeErrno(int code, const char *msg)
{
	return std::system_error(std::error_code(code, std::system_category()),
				 msg);
}

static inline std::system_error
MakeErrno(const char *msg)
{
	return MakeErrno(errno, msg);
}

static inline std::system_error
MakeErrno(int code)
{
	return MakeErrno(code, strerror(code));
}

static inline std::system_error
MakeErrno()
{
	return MakeErrno(errno);
}

template<typename... Args>
static inline std::system_error
FormatErrno(int code, const char *fmt, Args&&... args)
{
	char buffer[512];
	snprintf(buffer, sizeof(buffer),
		 fmt, std::forward<Args>(args)...);
	return MakeErrno(code, buffer);
}

template<typename... Args>
static inline std::system_error
FormatErrno(const char *fmt, Args&&... args)
{
	return FormatErrno(errno, fmt, std::forward<Args>(args)...);
}

#endif

gcc_pure
static inline bool
IsFileNotFound(const std::system_error &e)
{
#ifdef WIN32
	return e.code().category() == std::system_category() &&
		e.code().value() == ERROR_FILE_NOT_FOUND;
#else
	return e.code().category() == std::system_category() &&
		e.code().value() == ENOENT;
#endif
}

gcc_pure
static inline bool
IsAccessDenied(const std::system_error &e)
{
#ifdef WIN32
	return e.code().category() == std::system_category() &&
		e.code().value() == ERROR_ACCESS_DENIED;
#else
	return e.code().category() == std::system_category() &&
		e.code().value() == EACCES;
#endif
}

#endif
<|endoftext|>


<commit_before>/*
* The MIT License (MIT)
*
* Copyright (c) Microsoft Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/

/**
  Test JIT code emission.
*/

#include "stdafx.h"
#include "catch.hpp"
#include "testing_util.h"
#include <Python.h>
#include <frameobject.h>
#include <pyjit.h>

class EmissionTest {
private:
    PyCodeObject *m_code;
    PyJittedCode *m_jittedcode;

public:
    EmissionTest(const char *code) {
        m_code = CompileCode(code);
        if (m_code == nullptr) {
            FAIL("failed to compile code");
        }
        m_jittedcode = JitCompile(m_code);
        if (m_jittedcode == nullptr) {
            FAIL("failed to JIT code");
        }
    }

    ~EmissionTest() {
        Py_XDECREF(m_code);
        Py_XDECREF(m_jittedcode);
    }

    const char* returns() {
        auto sysModule = PyImport_ImportModule("sys");
        auto globals = PyDict_New();
        auto builtins = PyThreadState_GET()->interp->builtins;
        PyDict_SetItemString(globals, "__builtins__", builtins);
        PyDict_SetItemString(globals, "sys", sysModule);

        /* XXX Why?
        PyRun_String("finalized = False\nclass RefCountCheck:\n    def __del__(self):\n        print('finalizing')\n        global finalized\n        finalized = True\n    def __add__(self, other):\n        return self", Py_file_input, globals, globals);
        if (PyErr_Occurred()) {
            PyErr_Print();
            return "";
        }*/

        // Don't DECREF as frames are recycled.
        auto frame = PyFrame_New(PyThreadState_Get(), m_code, globals, PyDict_New());

        auto res = m_jittedcode->j_evalfunc(m_jittedcode->j_evalstate, frame);
        Py_DECREF(globals);
        Py_DECREF(sysModule);
        REQUIRE(!PyErr_Occurred());
        REQUIRE(res != nullptr);

        auto repr = PyUnicode_AsUTF8(PyObject_Repr(res));
        Py_DECREF(res);
        auto tstate = PyThreadState_GET();
        REQUIRE(tstate->exc_value == nullptr);
        REQUIRE(tstate->exc_traceback == nullptr);
        if (tstate->exc_type != nullptr) {
            REQUIRE(tstate->exc_type == Py_None);
        }

        return repr;
    }

    PyObject* raises() {
        return nullptr;
    }
};

TEST_CASE("General list unpacking", "[list][BUILD_LIST_UNPACK][emission]") {
    SECTION("common case") {
        auto t = EmissionTest("def f(): return [1, *[2], 3]");
        REQUIRE(t.returns() == "[1, 2, 3]");
    }

    SECTION("unpacking a non-iterable") {
        auto t = EmissionTest("def f(): return [1, *2, 3]");
        REQUIRE(t.raises() == PyExc_TypeError);
    }
}<commit_msg>Get the failing case for BUILD_LIST_UNPACK working<commit_after>/*
* The MIT License (MIT)
*
* Copyright (c) Microsoft Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/

/**
  Test JIT code emission.
*/

#include "stdafx.h"
#include "catch.hpp"
#include "testing_util.h"
#include <Python.h>
#include <frameobject.h>
#include <pyjit.h>

class EmissionTest {
private:
    PyCodeObject *m_code;
    PyJittedCode *m_jittedcode;

    PyObject *run() {
        auto sysModule = PyImport_ImportModule("sys");
        auto globals = PyDict_New();
        auto builtins = PyThreadState_GET()->interp->builtins;
        PyDict_SetItemString(globals, "__builtins__", builtins);
        PyDict_SetItemString(globals, "sys", sysModule);

        /* XXX Why?
        PyRun_String("finalized = False\nclass RefCountCheck:\n    def __del__(self):\n        print('finalizing')\n        global finalized\n        finalized = True\n    def __add__(self, other):\n        return self", Py_file_input, globals, globals);
        if (PyErr_Occurred()) {
        PyErr_Print();
        return "";
        }*/

        // Don't DECREF as frames are recycled.
        auto frame = PyFrame_New(PyThreadState_Get(), m_code, globals, PyDict_New());

        auto res = m_jittedcode->j_evalfunc(m_jittedcode->j_evalstate, frame);
        Py_DECREF(globals);
        Py_DECREF(sysModule);

        return res;
    }

public:
    EmissionTest(const char *code) {
        m_code = CompileCode(code);
        if (m_code == nullptr) {
            FAIL("failed to compile code");
        }
        m_jittedcode = JitCompile(m_code);
        if (m_jittedcode == nullptr) {
            FAIL("failed to JIT code");
        }
    }

    ~EmissionTest() {
        Py_XDECREF(m_code);
        Py_XDECREF(m_jittedcode);
    }

    const char* returns() {
        auto res = run();
        REQUIRE(res != nullptr);
        REQUIRE(!PyErr_Occurred());

        auto repr = PyUnicode_AsUTF8(PyObject_Repr(res));
        Py_DECREF(res);
        auto tstate = PyThreadState_GET();
        REQUIRE(tstate->exc_value == nullptr);
        REQUIRE(tstate->exc_traceback == nullptr);
        if (tstate->exc_type != nullptr) {
            REQUIRE(tstate->exc_type == Py_None);
        }

        return repr;
    }

    PyObject* raises() {
        auto res = run();
        REQUIRE(res == nullptr);
        return PyErr_Occurred();
    }
};

TEST_CASE("General list unpacking", "[list][BUILD_LIST_UNPACK][emission]") {
    SECTION("common case") {
        auto t = EmissionTest("def f(): return [1, *[2], 3]");
        REQUIRE(t.returns() == "[1, 2, 3]");
    }

    SECTION("unpacking a non-iterable") {
        auto t = EmissionTest("def f(): return [1, *2, 3]");
        REQUIRE(t.raises() == PyExc_TypeError);
    }
}<|endoftext|>


<commit_before>/*************************************************************************/
/*  godot_result_callbacks.cpp                                           */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "godot_result_callbacks.h"

#include "bullet_types_converter.h"
#include "collision_object_bullet.h"
#include "rigid_body_bullet.h"

/**
	@author AndreaCatania
*/

bool GodotFilterCallback::test_collision_filters(uint32_t body0_collision_layer, uint32_t body0_collision_mask, uint32_t body1_collision_layer, uint32_t body1_collision_mask) {
	return body0_collision_layer & body1_collision_mask || body1_collision_layer & body0_collision_mask;
}

bool GodotFilterCallback::needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const {
	return GodotFilterCallback::test_collision_filters(proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask, proxy1->m_collisionFilterGroup, proxy1->m_collisionFilterMask);
}

bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_pickRay && gObj->is_ray_pickable()) {
			return true;
		} else if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
	CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(convexResult.m_hitCollisionObject->getUserPointer());

	PhysicsDirectSpaceState::ShapeResult &result = m_results[count];

	result.shape = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
	result.rid = gObj->get_self();
	result.collider_id = gObj->get_instance_id();
	result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);

	++count;
	return count < m_resultMax;
}

bool GodotKinClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (gObj == m_self_object) {
			return false;
		} else {

			// A kinematic body can't be stopped by a rigid body since the mass of kinematic body is infinite
			if (m_infinite_inertia && !btObj->isStaticOrKinematicObject())
				return false;

			if (gObj->getType() == CollisionObjectBullet::TYPE_AREA)
				return false;

			if (m_self_object->has_collision_exception(gObj))
				return false;
		}
		return true;
	} else {
		return false;
	}
}

bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
	btScalar res = btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
	m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
	return res;
}

bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {

	if (m_count >= m_resultMax)
		return cp.getDistance();

	if (cp.getDistance() <= 0) {

		PhysicsDirectSpaceState::ShapeResult &result = m_results[m_count];
		// Penetrated

		CollisionObjectBullet *colObj;
		if (m_self_object == colObj0Wrap->getCollisionObject()) {
			colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
			result.shape = cp.m_index1;
		} else {
			colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
			result.shape = cp.m_index0;
		}

		if (colObj)
			result.collider_id = colObj->get_instance_id();
		else
			result.collider_id = 0;
		result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);
		result.rid = colObj->get_self();
		++m_count;
	}

	return cp.getDistance();
}

bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

btScalar GodotContactPairContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {

	if (m_self_object == colObj0Wrap->getCollisionObject()) {
		B_TO_G(cp.m_localPointA, m_results[m_count * 2 + 0]); // Local contact
		B_TO_G(cp.m_localPointB, m_results[m_count * 2 + 1]);
	} else {
		B_TO_G(cp.m_localPointB, m_results[m_count * 2 + 0]); // Local contact
		B_TO_G(cp.m_localPointA, m_results[m_count * 2 + 1]);
	}

	++m_count;

	return m_count < m_resultMax;
}

bool GodotRestInfoContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {

	if (cp.getDistance() <= m_min_distance) {
		m_min_distance = cp.getDistance();

		CollisionObjectBullet *colObj;
		if (m_self_object == colObj0Wrap->getCollisionObject()) {
			colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
			m_result->shape = cp.m_index1;
			B_TO_G(cp.getPositionWorldOnB(), m_result->point);
			m_rest_info_bt_point = cp.getPositionWorldOnB();
			m_rest_info_collision_object = colObj1Wrap->getCollisionObject();
		} else {
			colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
			m_result->shape = cp.m_index0;
			B_TO_G(cp.m_normalWorldOnB * -1, m_result->normal);
			m_rest_info_bt_point = cp.getPositionWorldOnA();
			m_rest_info_collision_object = colObj0Wrap->getCollisionObject();
		}

		if (colObj)
			m_result->collider_id = colObj->get_instance_id();
		else
			m_result->collider_id = 0;
		m_result->rid = colObj->get_self();

		m_collided = true;
	}

	return cp.getDistance();
}

void GodotDeepPenetrationContactResultCallback::addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth) {

	if (m_penetration_distance > depth) { // Has penetration?

		bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
		m_penetration_distance = depth;
		m_other_compound_shape_index = isSwapped ? m_index0 : m_index1;
		m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld;
		m_pointWorld = isSwapped ? (pointInWorldOnB + (normalOnBInWorld * depth)) : pointInWorldOnB;
	}
}
<commit_msg>Corrected physics query max result checking<commit_after>/*************************************************************************/
/*  godot_result_callbacks.cpp                                           */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "godot_result_callbacks.h"

#include "bullet_types_converter.h"
#include "collision_object_bullet.h"
#include "rigid_body_bullet.h"

/**
	@author AndreaCatania
*/

bool GodotFilterCallback::test_collision_filters(uint32_t body0_collision_layer, uint32_t body0_collision_mask, uint32_t body1_collision_layer, uint32_t body1_collision_mask) {
	return body0_collision_layer & body1_collision_mask || body1_collision_layer & body0_collision_mask;
}

bool GodotFilterCallback::needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const {
	return GodotFilterCallback::test_collision_filters(proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask, proxy1->m_collisionFilterGroup, proxy1->m_collisionFilterMask);
}

bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_pickRay && gObj->is_ray_pickable()) {
			return true;
		} else if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	if (count >= m_resultMax)
		return false;

	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}

		return true;
	} else {
		return false;
	}
}

btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
	CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(convexResult.m_hitCollisionObject->getUserPointer());

	PhysicsDirectSpaceState::ShapeResult &result = m_results[count];

	result.shape = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
	result.rid = gObj->get_self();
	result.collider_id = gObj->get_instance_id();
	result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);

	++count;
	return 1; // not used by bullet
}

bool GodotKinClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (gObj == m_self_object) {
			return false;
		} else {

			// A kinematic body can't be stopped by a rigid body since the mass of kinematic body is infinite
			if (m_infinite_inertia && !btObj->isStaticOrKinematicObject())
				return false;

			if (gObj->getType() == CollisionObjectBullet::TYPE_AREA)
				return false;

			if (m_self_object->has_collision_exception(gObj))
				return false;
		}
		return true;
	} else {
		return false;
	}
}

bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
	btScalar res = btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
	m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
	return res;
}

bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {

	if (m_count >= m_resultMax)
		return cp.getDistance();

	if (cp.getDistance() <= 0) {

		PhysicsDirectSpaceState::ShapeResult &result = m_results[m_count];
		// Penetrated

		CollisionObjectBullet *colObj;
		if (m_self_object == colObj0Wrap->getCollisionObject()) {
			colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
			result.shape = cp.m_index1;
		} else {
			colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
			result.shape = cp.m_index0;
		}

		if (colObj)
			result.collider_id = colObj->get_instance_id();
		else
			result.collider_id = 0;
		result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);
		result.rid = colObj->get_self();
		++m_count;
	}

	return cp.getDistance();
}

bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	if (m_count >= m_resultMax)
		return false;

	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

btScalar GodotContactPairContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {

	if (m_self_object == colObj0Wrap->getCollisionObject()) {
		B_TO_G(cp.m_localPointA, m_results[m_count * 2 + 0]); // Local contact
		B_TO_G(cp.m_localPointB, m_results[m_count * 2 + 1]);
	} else {
		B_TO_G(cp.m_localPointB, m_results[m_count * 2 + 0]); // Local contact
		B_TO_G(cp.m_localPointA, m_results[m_count * 2 + 1]);
	}

	++m_count;

	return 1; // Not used by bullet
}

bool GodotRestInfoContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
	const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
	if (needs) {
		btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
		CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
		if (m_exclude->has(gObj->get_self())) {
			return false;
		}
		return true;
	} else {
		return false;
	}
}

btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {

	if (cp.getDistance() <= m_min_distance) {
		m_min_distance = cp.getDistance();

		CollisionObjectBullet *colObj;
		if (m_self_object == colObj0Wrap->getCollisionObject()) {
			colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
			m_result->shape = cp.m_index1;
			B_TO_G(cp.getPositionWorldOnB(), m_result->point);
			m_rest_info_bt_point = cp.getPositionWorldOnB();
			m_rest_info_collision_object = colObj1Wrap->getCollisionObject();
		} else {
			colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
			m_result->shape = cp.m_index0;
			B_TO_G(cp.m_normalWorldOnB * -1, m_result->normal);
			m_rest_info_bt_point = cp.getPositionWorldOnA();
			m_rest_info_collision_object = colObj0Wrap->getCollisionObject();
		}

		if (colObj)
			m_result->collider_id = colObj->get_instance_id();
		else
			m_result->collider_id = 0;
		m_result->rid = colObj->get_self();

		m_collided = true;
	}

	return 1; // Not used by bullet
}

void GodotDeepPenetrationContactResultCallback::addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth) {

	if (m_penetration_distance > depth) { // Has penetration?

		bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
		m_penetration_distance = depth;
		m_other_compound_shape_index = isSwapped ? m_index0 : m_index1;
		m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld;
		m_pointWorld = isSwapped ? (pointInWorldOnB + (normalOnBInWorld * depth)) : pointInWorldOnB;
	}
}
<|endoftext|>


<commit_before>/*
 *  This file is part of Poedit (http://poedit.net)
 *
 *  Copyright (C) 1999-2014 Vaclav Slavik
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 *
 */

#include "text_control.h"

#include <wx/clipbrd.h>
#include <wx/wupdlock.h>

#ifdef __WXOSX__
  #include <wx/cocoa/string.h>
  #import <AppKit/NSTextView.h>
  #import <Foundation/NSUndoManager.h>
#endif

#ifdef __WXMSW__
  #include <richedit.h>
  #ifndef BOE_UNICODEBIDI
    #define BOE_UNICODEBIDI 0x0080
  #endif
  #ifndef BOM_UNICODEBIDI
    #define BOM_UNICODEBIDI 0x0080
  #endif
#endif

#include "spellchecking.h"

namespace
{

#ifdef __WXOSX__

inline NSTextView *TextView(const wxTextCtrl *ctrl)
{
    NSScrollView *scroll = (NSScrollView*)ctrl->GetHandle();
    return [scroll documentView];
}

#endif // __WXOSX__

} // anonymous namespace

#ifdef __WXOSX__

// wxTextCtrl implementation on OS X uses insertText:, which is intended for
// user input and performs some user input processing, such as autocorrections.
// We need to avoid this, because Poedit's text control is filled with data
// when moving in the list control: https://github.com/vslavik/poedit/issues/81
// Solve this by using a customized control with overridden DoSetValue().

CustomizedTextCtrl::CustomizedTextCtrl(wxWindow *parent, wxWindowID winid, long style)
    : wxTextCtrl(parent, winid, "", wxDefaultPosition, wxDefaultSize, style | ALWAYS_USED_STYLE)
{
    auto text = TextView(this);

    [text setTextContainerInset:NSMakeSize(1,3)];
    [text setRichText:NO];

    [text setAutomaticQuoteSubstitutionEnabled:NO];
    [text setAutomaticDashSubstitutionEnabled:NO];

    [text setAllowsUndo:YES];
}

void CustomizedTextCtrl::DoSetValue(const wxString& value, int flags)
{
    wxEventBlocker block(this, (flags & SetValue_SendEvent) ? 0 : wxEVT_ANY);

    auto text = TextView(this);
    [text setString:wxNSStringWithWxString(value)];
    NSUndoManager *undo = [text undoManager];
    [undo removeAllActions];

    SendTextUpdatedEventIfAllowed();
}

wxString CustomizedTextCtrl::DoGetValue() const
{
    // wx's implementation is not sufficient and neither is [NSTextView string]
    // (which wx uses): they ignore formatting, which would be desirable, but
    // they also include embedded Unicode marks such as U+202A (Left-to-Right Embedding)
    // or U+202C (Pop Directional Format) that are essential for correct
    // handling of BiDi text.
    //
    // Instead, export the internal storage into plain-text, UTF-8 data and
    // load that into wxString. That shouldn't be too inefficient (wx does
    // UTF-8 roundtrip anyway) and preserves the marks; it is what TextEdit.app
    // does when saving text files.
    auto ctrl = TextView(this);
    NSTextStorage *text = [ctrl textStorage];
    NSDictionary *attrs = @{
                             NSDocumentTypeDocumentAttribute: NSPlainTextDocumentType,
                             NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)
                           };
    NSData *data = [text dataFromRange:NSMakeRange(0, [text length]) documentAttributes:attrs error:nil];
    if (data && [data length] > 0)
        return wxString::FromUTF8((const char*)[data bytes], [data length]);
    else
        return wxTextCtrl::DoGetValue();
}

#else // !__WXOSX__

CustomizedTextCtrl::CustomizedTextCtrl(wxWindow *parent, wxWindowID winid, long style)
   : wxTextCtrl(parent, winid, "", wxDefaultPosition, wxDefaultSize, style | ALWAYS_USED_STYLE)
{
    wxTextAttr padding;
    padding.SetLeftIndent(5);
    padding.SetRightIndent(5);
    SetDefaultStyle(padding);

#ifdef __WXMSW__
    Bind(wxEVT_TEXT_COPY, &CustomizedTextCtrl::OnCopy, this);
    Bind(wxEVT_TEXT_CUT, &CustomizedTextCtrl::OnCut, this);
    Bind(wxEVT_TEXT_PASTE, &CustomizedTextCtrl::OnPaste, this);
#endif
}

#endif // !__WXOSX__

#ifdef __WXMSW__
// We use wxTE_RICH2 style, which allows for pasting rich-formatted
// text into the control. We want to allow only plain text (all the
// formatting done is Poedit's syntax highlighting), so we need to
// override copy/cut/paste command.s Plus, the richedit control
// (or wx's use of it) has a bug in it that causes it to copy wrong
// data when copying from the same text control to itself after its
// content was programatically changed:
// https://sourceforge.net/tracker/index.php?func=detail&aid=1910234&group_id=27043&atid=389153

bool CustomizedTextCtrl::DoCopy()
{
    long from, to;
    GetSelection(&from, &to);
    if ( from == to )
        return false;

    const wxString sel = GetRange(from, to);

    wxClipboardLocker lock;
    wxCHECK_MSG( !!lock, false, "failed to lock clipboard" );

    wxClipboard::Get()->SetData(new wxTextDataObject(sel));
    return true;
}

void CustomizedTextCtrl::OnCopy(wxClipboardTextEvent& event)
{
    DoCopy();
}

void CustomizedTextCtrl::OnCut(wxClipboardTextEvent& event)
{
    if ( !DoCopy() )
        return;

    long from, to;
    GetSelection(&from, &to);
    Remove(from, to);
}

void CustomizedTextCtrl::OnPaste(wxClipboardTextEvent& event)
{
    wxClipboardLocker lock;
    wxCHECK_RET( !!lock, "failed to lock clipboard" );

    wxTextDataObject d;
    wxClipboard::Get()->GetData(d);

    long from, to;
    GetSelection(&from, &to);
    Replace(from, to, d.GetText());
}
#endif // __WXMSW__

class AnyTranslatableTextCtrl::Attributes
{
public:
#ifdef __WXOSX__
    NSDictionary *m_attrSpace, *m_attrEscape;
    typedef NSDictionary* AttrType;

    Attributes()
    {
        m_attrSpace  = @{NSBackgroundColorAttributeName: [NSColor colorWithSRGBRed:0.89 green:0.96 blue:0.68 alpha:1]};
        m_attrEscape = @{NSBackgroundColorAttributeName: [NSColor colorWithSRGBRed:1 green:0.95 blue:1 alpha:1],
                         NSForegroundColorAttributeName: [NSColor colorWithSRGBRed:0.46 green:0 blue:0.01 alpha:1]};
    }
#else // !__WXOSX__
    wxTextAttr m_attrDefault, m_attrSpace, m_attrEscape;
    typedef wxTextAttr AttrType;

    Attributes()
    {
        m_attrDefault.SetBackgroundColour(*wxWHITE);
        m_attrDefault.SetTextColour(*wxBLACK);

        m_attrSpace.SetBackgroundColour("#E4F6AE");

        m_attrEscape.SetBackgroundColour("#FFF1FF");
        m_attrEscape.SetTextColour("#760003");
    }

    const AttrType& Default() const {  return m_attrDefault; }
#endif

    const AttrType& For(SyntaxHighlighter::TextKind kind) const
    {
        switch (kind)
        {
            case SyntaxHighlighter::LeadingWhitespace:  return m_attrSpace;
            case SyntaxHighlighter::Escape:             return m_attrEscape;
        }
        return m_attrSpace; // silence bogus warning
    }
};

AnyTranslatableTextCtrl::AnyTranslatableTextCtrl(wxWindow *parent, wxWindowID winid, int style)
   : CustomizedTextCtrl(parent, winid, style),
     m_attrs(new Attributes)
{
    Bind(wxEVT_TEXT, [=](wxCommandEvent& e){
        e.Skip();
        HighlightText();
    });

#ifdef __WXMSW__
    m_isRTL = false;
#endif
}

AnyTranslatableTextCtrl::~AnyTranslatableTextCtrl()
{
}

void AnyTranslatableTextCtrl::SetLanguageRTL(bool isRTL)
{
#ifdef __WXOSX__
    NSTextView *text = TextView(this);
    [text setBaseWritingDirection:isRTL ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight];
#endif
#ifdef __WXMSW__
    m_isRTL = isRTL;

    BIDIOPTIONS bidi;
    ::ZeroMemory(&bidi, sizeof(bidi));
    bidi.cbSize = sizeof(bidi);
    bidi.wMask = BOM_UNICODEBIDI;
    bidi.wEffects = isRTL ? BOE_UNICODEBIDI : 0;
    ::SendMessage((HWND)GetHWND(), EM_SETBIDIOPTIONS, 0, (LPARAM) &bidi);

    ::SendMessage((HWND)GetHWND(), EM_SETEDITSTYLE, isRTL ? SES_BIDI : 0, SES_BIDI);

    UpdateRTLStyle();
#endif
}

#ifdef __WXMSW__
void AnyTranslatableTextCtrl::DoSetValue(const wxString& value, int flags)
{
    wxWindowUpdateLocker dis(this);
    CustomizedTextCtrl::DoSetValue(value, flags);
    UpdateRTLStyle();
}

void AnyTranslatableTextCtrl::UpdateRTLStyle()
{
    wxEventBlocker block(this, wxEVT_TEXT);

    PARAFORMAT2 pf;
    ::ZeroMemory(&pf, sizeof(pf));
    pf.cbSize = sizeof(pf);
    pf.dwMask |= PFM_RTLPARA;
    if (m_isRTL)
        pf.wEffects |= PFE_RTLPARA;

    long start, end;
    GetSelection(&start, &end);
    SetSelection(-1, -1);
    ::SendMessage((HWND) GetHWND(), EM_SETPARAFORMAT, 0, (LPARAM) &pf);
    SetSelection(start, end);
}
#endif // __WXMSW__

#ifdef __WXGTK__
void AnyTranslatableTextCtrl::DoSetValue(const wxString& value, int flags)
{
    CustomizedTextCtrl::DoSetValue(value, flags);
    HighlightText();
}
#endif

void AnyTranslatableTextCtrl::HighlightText()
{
    auto text = GetValue().ToStdWstring();

#ifdef __WXOSX__

    NSRange fullRange = NSMakeRange(0, text.length());
    NSLayoutManager *layout = [TextView(this) layoutManager];
    [layout removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:fullRange];
    [layout removeTemporaryAttribute:NSBackgroundColorAttributeName forCharacterRange:fullRange];

    m_syntax.Highlight(text, [=](int a, int b, SyntaxHighlighter::TextKind kind){
        [layout addTemporaryAttributes:m_attrs->For(kind) forCharacterRange:NSMakeRange(a, b-a)];
    });

#else // !__WXOSX__

    wxWindowUpdateLocker noupd(this);
    wxEventBlocker block(this, wxEVT_TEXT);
    SetStyle(0, text.length(), m_attrs->Default());

    m_syntax.Highlight(text, [=](int a, int b, SyntaxHighlighter::TextKind kind){
        SetStyle(a, b, m_attrs->For(kind));
    });

#endif // __WXOSX__/!__WXOSX__
}

SourceTextCtrl::SourceTextCtrl(wxWindow *parent, wxWindowID winid)
    : AnyTranslatableTextCtrl(parent, winid, wxTE_READONLY)
{
    SetLanguageRTL(false); // English is LTR
}

TranslationTextCtrl::TranslationTextCtrl(wxWindow *parent, wxWindowID winid)
    : AnyTranslatableTextCtrl(parent, winid)
{
#ifdef __WXMSW__
    PrepareTextCtrlForSpellchecker(this);
#endif
}
<commit_msg>Windows: fix undo broken by syntax higlighting.<commit_after>/*
 *  This file is part of Poedit (http://poedit.net)
 *
 *  Copyright (C) 1999-2014 Vaclav Slavik
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 *
 */

#include "text_control.h"

#include <wx/clipbrd.h>
#include <wx/wupdlock.h>

#ifdef __WXOSX__
  #include <wx/cocoa/string.h>
  #import <AppKit/NSTextView.h>
  #import <Foundation/NSUndoManager.h>
#endif

#ifdef __WXMSW__
  #include <windows.h>
  #include <richedit.h>
  #ifndef BOE_UNICODEBIDI
    #define BOE_UNICODEBIDI 0x0080
  #endif
  #ifndef BOM_UNICODEBIDI
    #define BOM_UNICODEBIDI 0x0080
  #endif

  #include <comdef.h>
  #include <tom.h>
  _COM_SMARTPTR_TYPEDEF(ITextDocument, __uuidof(ITextDocument));
#endif

#include "spellchecking.h"

namespace
{

#ifdef __WXOSX__
inline NSTextView *TextView(const wxTextCtrl *ctrl)
{
    NSScrollView *scroll = (NSScrollView*)ctrl->GetHandle();
    return [scroll documentView];
}
#endif // __WXOSX__

#ifdef __WXMSW__

inline ITextDocumentPtr TextDocument(wxTextCtrl *ctrl)
{
    IUnknown *ole_raw;
    ::SendMessage((HWND) ctrl->GetHWND(), EM_GETOLEINTERFACE, 0, (LPARAM) &ole_raw);
    IUnknownPtr ole(ole_raw, /*addRef=*/false);
    ITextDocumentPtr doc;
    if (ole)
        ole->QueryInterface<ITextDocument>(&doc);
    return doc;
}

// Temporarily supresses recording of changes for Undo/Redo functionality
// See http://stackoverflow.com/questions/4138981/temporaily-disabling-the-c-sharp-rich-edit-undo-buffer-while-performing-syntax-h
// and http://forums.codeguru.com/showthread.php?325068-Realizing-Undo-Redo-functionality-for-RichEdit-Syntax-Highlighter
class UndoSupressor
{
public:
    UndoSupressor(CustomizedTextCtrl *ctrl) : m_doc(TextDocument(ctrl))
    {
        if (m_doc)
            m_doc->Undo(tomSuspend, NULL);
    }

    ~UndoSupressor()
    {
        if (m_doc)
            m_doc->Undo(tomResume, NULL);
    }

private:
    ITextDocumentPtr m_doc;
};
#endif

} // anonymous namespace

#ifdef __WXOSX__

// wxTextCtrl implementation on OS X uses insertText:, which is intended for
// user input and performs some user input processing, such as autocorrections.
// We need to avoid this, because Poedit's text control is filled with data
// when moving in the list control: https://github.com/vslavik/poedit/issues/81
// Solve this by using a customized control with overridden DoSetValue().

CustomizedTextCtrl::CustomizedTextCtrl(wxWindow *parent, wxWindowID winid, long style)
    : wxTextCtrl(parent, winid, "", wxDefaultPosition, wxDefaultSize, style | ALWAYS_USED_STYLE)
{
    auto text = TextView(this);

    [text setTextContainerInset:NSMakeSize(1,3)];
    [text setRichText:NO];

    [text setAutomaticQuoteSubstitutionEnabled:NO];
    [text setAutomaticDashSubstitutionEnabled:NO];

    [text setAllowsUndo:YES];
}

void CustomizedTextCtrl::DoSetValue(const wxString& value, int flags)
{
    wxEventBlocker block(this, (flags & SetValue_SendEvent) ? 0 : wxEVT_ANY);

    auto text = TextView(this);
    [text setString:wxNSStringWithWxString(value)];
    NSUndoManager *undo = [text undoManager];
    [undo removeAllActions];

    SendTextUpdatedEventIfAllowed();
}

wxString CustomizedTextCtrl::DoGetValue() const
{
    // wx's implementation is not sufficient and neither is [NSTextView string]
    // (which wx uses): they ignore formatting, which would be desirable, but
    // they also include embedded Unicode marks such as U+202A (Left-to-Right Embedding)
    // or U+202C (Pop Directional Format) that are essential for correct
    // handling of BiDi text.
    //
    // Instead, export the internal storage into plain-text, UTF-8 data and
    // load that into wxString. That shouldn't be too inefficient (wx does
    // UTF-8 roundtrip anyway) and preserves the marks; it is what TextEdit.app
    // does when saving text files.
    auto ctrl = TextView(this);
    NSTextStorage *text = [ctrl textStorage];
    NSDictionary *attrs = @{
                             NSDocumentTypeDocumentAttribute: NSPlainTextDocumentType,
                             NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)
                           };
    NSData *data = [text dataFromRange:NSMakeRange(0, [text length]) documentAttributes:attrs error:nil];
    if (data && [data length] > 0)
        return wxString::FromUTF8((const char*)[data bytes], [data length]);
    else
        return wxTextCtrl::DoGetValue();
}

#else // !__WXOSX__

CustomizedTextCtrl::CustomizedTextCtrl(wxWindow *parent, wxWindowID winid, long style)
   : wxTextCtrl(parent, winid, "", wxDefaultPosition, wxDefaultSize, style | ALWAYS_USED_STYLE)
{
    wxTextAttr padding;
    padding.SetLeftIndent(5);
    padding.SetRightIndent(5);
    SetDefaultStyle(padding);

#ifdef __WXMSW__
    Bind(wxEVT_TEXT_COPY, &CustomizedTextCtrl::OnCopy, this);
    Bind(wxEVT_TEXT_CUT, &CustomizedTextCtrl::OnCut, this);
    Bind(wxEVT_TEXT_PASTE, &CustomizedTextCtrl::OnPaste, this);
#endif
}

#endif // !__WXOSX__

#ifdef __WXMSW__
// We use wxTE_RICH2 style, which allows for pasting rich-formatted
// text into the control. We want to allow only plain text (all the
// formatting done is Poedit's syntax highlighting), so we need to
// override copy/cut/paste command.s Plus, the richedit control
// (or wx's use of it) has a bug in it that causes it to copy wrong
// data when copying from the same text control to itself after its
// content was programatically changed:
// https://sourceforge.net/tracker/index.php?func=detail&aid=1910234&group_id=27043&atid=389153

bool CustomizedTextCtrl::DoCopy()
{
    long from, to;
    GetSelection(&from, &to);
    if ( from == to )
        return false;

    const wxString sel = GetRange(from, to);

    wxClipboardLocker lock;
    wxCHECK_MSG( !!lock, false, "failed to lock clipboard" );

    wxClipboard::Get()->SetData(new wxTextDataObject(sel));
    return true;
}

void CustomizedTextCtrl::OnCopy(wxClipboardTextEvent& event)
{
    DoCopy();
}

void CustomizedTextCtrl::OnCut(wxClipboardTextEvent& event)
{
    if ( !DoCopy() )
        return;

    long from, to;
    GetSelection(&from, &to);
    Remove(from, to);
}

void CustomizedTextCtrl::OnPaste(wxClipboardTextEvent& event)
{
    wxClipboardLocker lock;
    wxCHECK_RET( !!lock, "failed to lock clipboard" );

    wxTextDataObject d;
    wxClipboard::Get()->GetData(d);

    long from, to;
    GetSelection(&from, &to);
    Replace(from, to, d.GetText());
}
#endif // __WXMSW__

class AnyTranslatableTextCtrl::Attributes
{
public:
#ifdef __WXOSX__
    NSDictionary *m_attrSpace, *m_attrEscape;
    typedef NSDictionary* AttrType;

    Attributes()
    {
        m_attrSpace  = @{NSBackgroundColorAttributeName: [NSColor colorWithSRGBRed:0.89 green:0.96 blue:0.68 alpha:1]};
        m_attrEscape = @{NSBackgroundColorAttributeName: [NSColor colorWithSRGBRed:1 green:0.95 blue:1 alpha:1],
                         NSForegroundColorAttributeName: [NSColor colorWithSRGBRed:0.46 green:0 blue:0.01 alpha:1]};
    }
#else // !__WXOSX__
    wxTextAttr m_attrDefault, m_attrSpace, m_attrEscape;
    typedef wxTextAttr AttrType;

    Attributes()
    {
        m_attrDefault.SetBackgroundColour(*wxWHITE);
        m_attrDefault.SetTextColour(*wxBLACK);

        m_attrSpace.SetBackgroundColour("#E4F6AE");

        m_attrEscape.SetBackgroundColour("#FFF1FF");
        m_attrEscape.SetTextColour("#760003");
    }

    const AttrType& Default() const {  return m_attrDefault; }
#endif

    const AttrType& For(SyntaxHighlighter::TextKind kind) const
    {
        switch (kind)
        {
            case SyntaxHighlighter::LeadingWhitespace:  return m_attrSpace;
            case SyntaxHighlighter::Escape:             return m_attrEscape;
        }
        return m_attrSpace; // silence bogus warning
    }
};

AnyTranslatableTextCtrl::AnyTranslatableTextCtrl(wxWindow *parent, wxWindowID winid, int style)
   : CustomizedTextCtrl(parent, winid, style),
     m_attrs(new Attributes)
{
    Bind(wxEVT_TEXT, [=](wxCommandEvent& e){
        e.Skip();
        HighlightText();
    });

#ifdef __WXMSW__
    m_isRTL = false;
#endif
}

AnyTranslatableTextCtrl::~AnyTranslatableTextCtrl()
{
}

void AnyTranslatableTextCtrl::SetLanguageRTL(bool isRTL)
{
#ifdef __WXOSX__
    NSTextView *text = TextView(this);
    [text setBaseWritingDirection:isRTL ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight];
#endif
#ifdef __WXMSW__
    m_isRTL = isRTL;

    BIDIOPTIONS bidi;
    ::ZeroMemory(&bidi, sizeof(bidi));
    bidi.cbSize = sizeof(bidi);
    bidi.wMask = BOM_UNICODEBIDI;
    bidi.wEffects = isRTL ? BOE_UNICODEBIDI : 0;
    ::SendMessage((HWND)GetHWND(), EM_SETBIDIOPTIONS, 0, (LPARAM) &bidi);

    ::SendMessage((HWND)GetHWND(), EM_SETEDITSTYLE, isRTL ? SES_BIDI : 0, SES_BIDI);

    UpdateRTLStyle();
#endif
}

#ifdef __WXMSW__
void AnyTranslatableTextCtrl::DoSetValue(const wxString& value, int flags)
{
    wxWindowUpdateLocker dis(this);
    CustomizedTextCtrl::DoSetValue(value, flags);
    UpdateRTLStyle();
}

void AnyTranslatableTextCtrl::UpdateRTLStyle()
{
    wxEventBlocker block(this, wxEVT_TEXT);
    UndoSupressor blockUndo(this);

    PARAFORMAT2 pf;
    ::ZeroMemory(&pf, sizeof(pf));
    pf.cbSize = sizeof(pf);
    pf.dwMask |= PFM_RTLPARA;
    if (m_isRTL)
        pf.wEffects |= PFE_RTLPARA;

    long start, end;
    GetSelection(&start, &end);
    SetSelection(-1, -1);
    ::SendMessage((HWND) GetHWND(), EM_SETPARAFORMAT, 0, (LPARAM) &pf);
    SetSelection(start, end);
}
#endif // __WXMSW__

#ifdef __WXGTK__
void AnyTranslatableTextCtrl::DoSetValue(const wxString& value, int flags)
{
    CustomizedTextCtrl::DoSetValue(value, flags);
    HighlightText();
}
#endif

void AnyTranslatableTextCtrl::HighlightText()
{
    auto text = GetValue().ToStdWstring();

#ifdef __WXOSX__

    NSRange fullRange = NSMakeRange(0, text.length());
    NSLayoutManager *layout = [TextView(this) layoutManager];
    [layout removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:fullRange];
    [layout removeTemporaryAttribute:NSBackgroundColorAttributeName forCharacterRange:fullRange];

    m_syntax.Highlight(text, [=](int a, int b, SyntaxHighlighter::TextKind kind){
        [layout addTemporaryAttributes:m_attrs->For(kind) forCharacterRange:NSMakeRange(a, b-a)];
    });

#else // !__WXOSX__

    wxWindowUpdateLocker noupd(this);
    wxEventBlocker block(this, wxEVT_TEXT);
  #ifdef __WXMSW__
    UndoSupressor blockUndo(this);
  #endif

    SetStyle(0, text.length(), m_attrs->Default());

    m_syntax.Highlight(text, [=](int a, int b, SyntaxHighlighter::TextKind kind){
        SetStyle(a, b, m_attrs->For(kind));
    });

#endif // __WXOSX__/!__WXOSX__
}

SourceTextCtrl::SourceTextCtrl(wxWindow *parent, wxWindowID winid)
    : AnyTranslatableTextCtrl(parent, winid, wxTE_READONLY)
{
    SetLanguageRTL(false); // English is LTR
}

TranslationTextCtrl::TranslationTextCtrl(wxWindow *parent, wxWindowID winid)
    : AnyTranslatableTextCtrl(parent, winid)
{
#ifdef __WXMSW__
    PrepareTextCtrlForSpellchecker(this);
#endif
}
<|endoftext|>


<commit_before>/* This file is part of qtsparkle.
   Copyright (c) 2010 David Sansome <me@davidsansome.com>

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

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

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

#include "appcast.h"
#include "common.h"
#include "followredirects.h"
#include "updatedialog.h"
#include "ui_updatedialog.h"

#include <QDesktopServices>
#include <QSettings>
#include <QtDebug>

namespace qtsparkle {

struct UpdateDialog::Private {
  Private()
    : network_(NULL)
  {
  }

  QScopedPointer<Ui_UpdateDialog> ui_;

  QNetworkAccessManager* network_;
  QString version_;
  AppCastPtr appcast_;

  static const int kIconSize;
};

const int UpdateDialog::Private::kIconSize = 64;

UpdateDialog::UpdateDialog(QWidget *parent)
  : QDialog(parent),
    d(new Private)
{
  d->ui_.reset(new Ui_UpdateDialog);
  d->ui_->setupUi(this);

  d->ui_->release_notes_label->setText(
      "" + d->ui_->release_notes_label->text() + "");
  d->ui_->icon->hide();

  connect(d->ui_->install, SIGNAL(clicked()), SLOT(Install()));
  connect(d->ui_->skip, SIGNAL(clicked()), SLOT(Skip()));
  connect(d->ui_->later, SIGNAL(clicked()), SLOT(close()));
}

UpdateDialog::~UpdateDialog() {
}

void UpdateDialog::SetNetworkAccessManager(QNetworkAccessManager* network) {
  d->network_ = network;
}

void UpdateDialog::SetIcon(const QIcon& icon) {
  if (icon.isNull()) {
    d->ui_->icon->hide();
  } else {
    d->ui_->icon->setPixmap(icon.pixmap(Private::kIconSize));
    d->ui_->icon->show();
  }
}

void UpdateDialog::SetVersion(const QString& version) {
  d->version_ = version;
}

void UpdateDialog::ShowUpdate(AppCastPtr appcast) {
  d->appcast_ = appcast;

  d->ui_->title->setText("
" +
      tr("A new version of %1 is available").arg(qApp->applicationName()) + "
");
  d->ui_->summary->setText(
      tr("%1 %2 is now available - you have %3.  Would you like to download it now?")
      .arg(qApp->applicationName(), appcast->version(), d->version_));

  show();

  if (!appcast->description().isEmpty())
    d->ui_->release_notes->setHtml(appcast->description());
  else
  {
  if (!d->network_)
    d->network_ = new QNetworkAccessManager(this);

  FollowRedirects* reply = new FollowRedirects(
      d->network_->get(QNetworkRequest(appcast->release_notes_url())));
  connect(reply, SIGNAL(Finished()), SLOT(ReleaseNotesReady()));
  }
}

void UpdateDialog::ReleaseNotesReady() {
  FollowRedirects* reply = qobject_cast<FollowRedirects*>(sender());
  if (!reply)
    return;
  reply->deleteLater();

  if (reply->reply()->header(QNetworkRequest::ContentTypeHeader).toString()
      .contains("text/html")) {
    d->ui_->release_notes->setHtml(reply->reply()->readAll());
  } else {
    d->ui_->release_notes->setPlainText(reply->reply()->readAll());
  }
}

void UpdateDialog::Install() {
  if (!d->appcast_)
    return;

  QDesktopServices::openUrl(d->appcast_->download_url());
  close();
}

void UpdateDialog::Skip() {
  if (!d->appcast_)
    return;

  QSettings s;
  s.beginGroup(kSettingsGroup);
  s.setValue("skipped_version", d->appcast_->version());
  close();
}

} // namespace qtsparkle
<commit_msg>Fix indentation<commit_after>/* This file is part of qtsparkle.
   Copyright (c) 2010 David Sansome <me@davidsansome.com>

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

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

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

#include "appcast.h"
#include "common.h"
#include "followredirects.h"
#include "updatedialog.h"
#include "ui_updatedialog.h"

#include <QDesktopServices>
#include <QSettings>
#include <QtDebug>

namespace qtsparkle {

struct UpdateDialog::Private {
  Private()
    : network_(NULL)
  {
  }

  QScopedPointer<Ui_UpdateDialog> ui_;

  QNetworkAccessManager* network_;
  QString version_;
  AppCastPtr appcast_;

  static const int kIconSize;
};

const int UpdateDialog::Private::kIconSize = 64;

UpdateDialog::UpdateDialog(QWidget *parent)
  : QDialog(parent),
    d(new Private)
{
  d->ui_.reset(new Ui_UpdateDialog);
  d->ui_->setupUi(this);

  d->ui_->release_notes_label->setText(
      "" + d->ui_->release_notes_label->text() + "");
  d->ui_->icon->hide();

  connect(d->ui_->install, SIGNAL(clicked()), SLOT(Install()));
  connect(d->ui_->skip, SIGNAL(clicked()), SLOT(Skip()));
  connect(d->ui_->later, SIGNAL(clicked()), SLOT(close()));
}

UpdateDialog::~UpdateDialog() {
}

void UpdateDialog::SetNetworkAccessManager(QNetworkAccessManager* network) {
  d->network_ = network;
}

void UpdateDialog::SetIcon(const QIcon& icon) {
  if (icon.isNull()) {
    d->ui_->icon->hide();
  } else {
    d->ui_->icon->setPixmap(icon.pixmap(Private::kIconSize));
    d->ui_->icon->show();
  }
}

void UpdateDialog::SetVersion(const QString& version) {
  d->version_ = version;
}

void UpdateDialog::ShowUpdate(AppCastPtr appcast) {
  d->appcast_ = appcast;

  d->ui_->title->setText("
" +
      tr("A new version of %1 is available").arg(qApp->applicationName()) + "
");
  d->ui_->summary->setText(
      tr("%1 %2 is now available - you have %3.  Would you like to download it now?")
      .arg(qApp->applicationName(), appcast->version(), d->version_));

  show();

  if (!appcast->description().isEmpty()) {
    d->ui_->release_notes->setHtml(appcast->description());
  } else {
    if (!d->network_)
      d->network_ = new QNetworkAccessManager(this);

    FollowRedirects* reply = new FollowRedirects(
        d->network_->get(QNetworkRequest(appcast->release_notes_url())));
    connect(reply, SIGNAL(Finished()), SLOT(ReleaseNotesReady()));
  }
}

void UpdateDialog::ReleaseNotesReady() {
  FollowRedirects* reply = qobject_cast<FollowRedirects*>(sender());
  if (!reply)
    return;
  reply->deleteLater();

  if (reply->reply()->header(QNetworkRequest::ContentTypeHeader).toString()
      .contains("text/html")) {
    d->ui_->release_notes->setHtml(reply->reply()->readAll());
  } else {
    d->ui_->release_notes->setPlainText(reply->reply()->readAll());
  }
}

void UpdateDialog::Install() {
  if (!d->appcast_)
    return;

  QDesktopServices::openUrl(d->appcast_->download_url());
  close();
}

void UpdateDialog::Skip() {
  if (!d->appcast_)
    return;

  QSettings s;
  s.beginGroup(kSettingsGroup);
  s.setValue("skipped_version", d->appcast_->version());
  close();
}

} // namespace qtsparkle
<|endoftext|>


<commit_before>// Measures how precise the AIG encodings are compared with the propagators.

#include "../cpp_interface/cpp_interface.h"
#include "Relations.h"
#include "../sat/MinisatCore.h"
#include "../sat/core/Solver.h"
#include "../to-sat/AIG/ToSATAIG.h"
#include "Functions.h"
#include "../printer/printers.h"
#include "StopWatch.h"

using namespace BEEV;

int bits = 64;
int iterations = 100000;
ostream& out = cout;
STPMgr *mgr = new STPMgr;

void
print(MinisatCore<Minisat::Solver> * ss, ASTNode i0, ToSAT::ASTNodeToSATVar& m)
{
  const int bits = std::max(1U, i0.GetValueWidth());
  out << "<";
  for (int i = bits - 1; i >= 0; i--)
    {
      if (ss->value(m.find(i0)->second[i]) == ss->true_literal())
        {
          out << "1";
        }
      else if (ss->value(m.find(i0)->second[i]) == ss->false_literal())
        {
          out << "0";
        }
      else
        out << "-";
    }
  out << ">";
}

void
addToClauseCount(MinisatCore<Minisat::Solver> * ss, ASTNode i0, ToSAT::ASTNodeToSATVar& m, int & count)
{
  const int bits = std::max(1U, i0.GetValueWidth());
  for (int i = bits - 1; i >= 0; i--)
    {
      SATSolver::lbool r = ss->value(m.find(i0)->second[i]);

      if (r == ss->true_literal() || r == ss->false_literal())
        count++;
    }
}

void
go(Kind k, Result
(*t_fn)(vector<FixedBits*>&, FixedBits&), int prob)
{
  const bool term = is_Term_kind(k);

  ASTNode i0 = mgr->CreateSymbol("i0", 0, bits);
  ASTNode i1 = mgr->CreateSymbol("i1", 0, bits);

  ASTNode r, p, eq;

  if (term)
    {
      p = mgr->CreateTerm(k, bits, i0, i1);
      r = mgr->CreateSymbol("r", 0, bits);
      eq = mgr->CreateNode(EQ, p, r);
    }
  else
    {
      p = mgr->CreateNode(k, i0, i1);
      r = mgr->CreateSymbol("r", 0, 0);
      eq = mgr->CreateNode(IFF, p, r);
    }

  Relations relations(iterations, bits, k, mgr, prob);

  int initial = 0;
  int transfer = 0;
  int clause = 0;

  MinisatCore<Minisat::Solver>* ss = new MinisatCore<Minisat::Solver>(mgr->soft_timeout_expired);
  ToSATAIG a(mgr, GlobalSTP->arrayTransformer);
  a.CallSAT(*ss, eq, false);
  ToSAT::ASTNodeToSATVar m = a.SATVar_to_SymbolIndexMap();

  Stopwatch2 bb;
  Stopwatch2 prop;

  list<Relations::Relation>::iterator it = relations.relations.begin();
  while (it != relations.relations.end())
    {
      Relations::Relation rel = *it;

      SATSolver::vec_literals assumptions;

      for (int i = 0; i < bits; i++)
        {
          if (rel.a[i] == '1')
            {
              assumptions.push(SATSolver::mkLit(m.find(i0)->second[i], false));
            }
          else if (rel.a[i] == '0')
            {
              assumptions.push(SATSolver::mkLit(m.find(i0)->second[i], true));
            }

          if (rel.b[i] == '1')
            {
              assumptions.push(SATSolver::mkLit(m.find(i1)->second[i], false));
            }
          else if (rel.b[i] == '0')
            {
              assumptions.push(SATSolver::mkLit(m.find(i1)->second[i], true));
            }
        }
      for (int i = 0; i < rel.output.getWidth(); i++)
        {
          if (rel.output[i] == '1')
            {
              assumptions.push(SATSolver::mkLit(m.find(r)->second[i], false));
            }
          else if (rel.output[i] == '0')
            {
              assumptions.push(SATSolver::mkLit(m.find(r)->second[i], true));
            }
        }

      //Initial.
      //cerr << rel.a << _kind_names[k] << rel.b << rel.output << endl;

      const int initialCount = rel.a.countFixed() + rel.b.countFixed() + rel.output.countFixed();
      initial += initialCount;

      // simplify does propagate.
      bb.start();
      bool ok = ss->unitPropagate(assumptions);
      bb.stop();
      assert(ok);

      // After unit propagation.
      int clauseCount = 0;
      addToClauseCount(ss, i0, a.SATVar_to_SymbolIndexMap(), clauseCount);
      addToClauseCount(ss, i1, a.SATVar_to_SymbolIndexMap(), clauseCount);
      addToClauseCount(ss, r, a.SATVar_to_SymbolIndexMap(), clauseCount);
      clause += clauseCount;

      // After unit propagation.
      /*
       print(ss, i0, a.SATVar_to_SymbolIndexMap());
       cerr <<  _kind_names[k];
       print(ss, i1, a.SATVar_to_SymbolIndexMap());
       print(ss, r, a.SATVar_to_SymbolIndexMap());
       cerr << "\n";
       */

      // After transfer functions.
      vector<FixedBits*> ch;
      ch.push_back(&rel.a);
      ch.push_back(&rel.b);
      prop.start();
      Result rr = t_fn(ch, rel.output);
      prop.stop();

      assert(rr != CONFLICT);
      //cerr << rel.a << _kind_names[k] << rel.b << rel.output << endl;
      int transferCount = rel.a.countFixed() + rel.b.countFixed() + rel.output.countFixed();
      transfer += transferCount;

      //cerr << initialCount << endl;
      // cerr << clauseCount << endl;
      assert(initialCount <= clauseCount);
      assert(initialCount <= transferCount);

      //delete ss;
      it++;
    }

  int percent = 100 * ((float)(clause - initial)) / ((float)(transfer - initial));
  if (transfer - initial == 0)
    percent = 100;

  cerr.setf(ios::fixed);
  cerr << "&" << setprecision(2) << (float(bb.elapsed) / CLOCKS_PER_SEC) << "s";

  cerr.setf(ios::fixed);
  cerr << "&" << setprecision(2) << (float(prop.elapsed) / CLOCKS_PER_SEC) << "s";

  cerr << "&" << (clause-initial) << "&" << (transfer-initial) << "&" << percent << "\\%\\\\%prob:" << prob << endl;
}

void
work(int p)
{
  out << "\\begin{table}[t]" << endl;
  out << "\\begin{center}" << endl;
  out << "\\begin{tabular}{|l| r|r|r|r|r|r|r| }" << endl;
  out << "\\hline" << endl;
  out << "\\multicolumn{1}{|c|}{Operation} &" << endl;
  out << "\\multicolumn{5}{c|}{" << p << "\\%} \\\\" << endl;
  out << "& UP time & prop. time &  UP bits & prop. bits &  \\% \\\\" << endl;
  out << "\\hline" << endl;

  Functions f;
  std::list<Functions::Function>::iterator it = f.l.begin();
  while (it != f.l.end())
    {
      Functions::Function& f = *it;
      out << f.name << endl;
      go(f.k, f.fn, p);
      it++;
    }

  out << "\\hline" << endl;
  out << "\\end{tabular}" << endl;
  out << "\\caption{Comparison of unit propagation and bit-blasting at "<<  p <<  "\\%. ";
  out << iterations << " iterations at " << bits << " bits. \label{tbl:p"<< p << "}}}" << endl;
  out << "\\end{center}" << endl;
  out << "\\end{table}" << endl;
  }

int
main()
{
  mgr = new STPMgr;
  Cpp_interface interface(*mgr);
  mgr->UserFlags.division_by_zero_returns_one_flag=true;

  out << "\\begin{subtables}" << endl;
  work(1);
  work(5);
  work(50);
  work(95);
  out << "\\end{subtables}" << endl;

  out << "% Iterations:" << iterations << " bit-width:" << bits << endl;

}

<commit_msg>Change to code for experiments.<commit_after>// Measures how precise the AIG encodings are compared with the propagators.

#include "../cpp_interface/cpp_interface.h"
#include "Relations.h"
#include "../sat/MinisatCore.h"
#include "../sat/core/Solver.h"
#include "../to-sat/AIG/ToSATAIG.h"
#include "Functions.h"
#include "../printer/printers.h"
#include "StopWatch.h"

using namespace BEEV;

int bits = 64;
int iterations = 100000;
ostream& out = cout;
STPMgr *mgr = new STPMgr;

void
print(MinisatCore<Minisat::Solver> * ss, ASTNode i0, ToSAT::ASTNodeToSATVar& m)
{
  const int bits = std::max(1U, i0.GetValueWidth());
  out << "<";
  for (int i = bits - 1; i >= 0; i--)
    {
      if (ss->value(m.find(i0)->second[i]) == ss->true_literal())
        {
          out << "1";
        }
      else if (ss->value(m.find(i0)->second[i]) == ss->false_literal())
        {
          out << "0";
        }
      else
        out << "-";
    }
  out << ">";
}

void
addToClauseCount(MinisatCore<Minisat::Solver> * ss, ASTNode i0, ToSAT::ASTNodeToSATVar& m, int & count)
{
  const int bits = std::max(1U, i0.GetValueWidth());
  for (int i = bits - 1; i >= 0; i--)
    {
      SATSolver::lbool r = ss->value(m.find(i0)->second[i]);

      if (r == ss->true_literal() || r == ss->false_literal())
        count++;
    }
}

void
go(Kind k, Result
(*t_fn)(vector<FixedBits*>&, FixedBits&), int prob)
{
  const bool term = is_Term_kind(k);

  ASTNode i0 = mgr->CreateSymbol("i0", 0, bits);
  ASTNode i1 = mgr->CreateSymbol("i1", 0, bits);

  ASTNode r, p, eq;

  if (term)
    {
      p = mgr->CreateTerm(k, bits, i0, i1);
      r = mgr->CreateSymbol("r", 0, bits);
      eq = mgr->CreateNode(EQ, p, r);
    }
  else
    {
      p = mgr->CreateNode(k, i0, i1);
      r = mgr->CreateSymbol("r", 0, 0);
      eq = mgr->CreateNode(IFF, p, r);
    }

  Relations relations(iterations, bits, k, mgr, prob);

  int initial = 0;
  int transfer = 0;
  int clause = 0;

  MinisatCore<Minisat::Solver>* ss = new MinisatCore<Minisat::Solver>(mgr->soft_timeout_expired);
  ToSATAIG aig(mgr, GlobalSTP->arrayTransformer);
  aig.CallSAT(*ss, eq, false);
  ToSAT::ASTNodeToSATVar m = aig.SATVar_to_SymbolIndexMap();

  Stopwatch2 bb;
  Stopwatch2 prop;

  list<Relations::Relation>::iterator it = relations.relations.begin();
  while (it != relations.relations.end())
    {
      //Relations::Relation rel =
      FixedBits& a = it->a;
      FixedBits& b = it->b;
      FixedBits& output = it->output;

      SATSolver::vec_literals assumptions;

      for (int i = 0; i < bits; i++)
        {
          if (a[i] == '1')
            {
              assumptions.push(SATSolver::mkLit(m.find(i0)->second[i], false));
            }
          else if (a[i] == '0')
            {
              assumptions.push(SATSolver::mkLit(m.find(i0)->second[i], true));
            }

          if (b[i] == '1')
            {
              assumptions.push(SATSolver::mkLit(m.find(i1)->second[i], false));
            }
          else if (b[i] == '0')
            {
              assumptions.push(SATSolver::mkLit(m.find(i1)->second[i], true));
            }
        }
      for (int i = 0; i < output.getWidth(); i++)
        {
          if (output[i] == '1')
            {
              assumptions.push(SATSolver::mkLit(m.find(r)->second[i], false));
            }
          else if (output[i] == '0')
            {
              assumptions.push(SATSolver::mkLit(m.find(r)->second[i], true));
            }
        }

      //Initial.
      //cerr << rel.a << _kind_names[k] << rel.b << rel.output << endl;

      const int initialCount = a.countFixed() + b.countFixed() + output.countFixed();
      initial += initialCount;

      // simplify does propagate.
      bb.start();
      bool ok = ss->unitPropagate(assumptions);
      bb.stop();
      assert(ok);

      // After unit propagation.
      int clauseCount = 0;
      addToClauseCount(ss, i0, aig.SATVar_to_SymbolIndexMap(), clauseCount);
      addToClauseCount(ss, i1, aig.SATVar_to_SymbolIndexMap(), clauseCount);
      addToClauseCount(ss, r, aig.SATVar_to_SymbolIndexMap(), clauseCount);
      clause += clauseCount;

      // After unit propagation.
      /*
       print(ss, i0, a.SATVar_to_SymbolIndexMap());
       cerr <<  _kind_names[k];
       print(ss, i1, a.SATVar_to_SymbolIndexMap());
       print(ss, r, a.SATVar_to_SymbolIndexMap());
       cerr << "\n";
       */

      // After transfer functions.
      vector<FixedBits*> ch;
      ch.push_back(&a);
      ch.push_back(&b);
      prop.start();
      Result rr = t_fn(ch, output);
      prop.stop();

      assert(rr != CONFLICT);
      //cerr << rel.a << _kind_names[k] << rel.b << rel.output << endl;
      int transferCount = a.countFixed() + b.countFixed() + output.countFixed();
      transfer += transferCount;

      //cerr << initialCount << endl;
      // cerr << clauseCount << endl;
      assert(initialCount <= clauseCount);
      assert(initialCount <= transferCount);

      //delete ss;
      it++;
    }

  int percent = 100 * ((float)(clause - initial)) / ((float)(transfer - initial));
  if (transfer - initial == 0)
    percent = 100;

  cerr.setf(ios::fixed);
  cerr << "&" << setprecision(2) << (float(bb.elapsed) / CLOCKS_PER_SEC) << "s";

  cerr.setf(ios::fixed);
  cerr << "&" << setprecision(2) << (float(prop.elapsed) / CLOCKS_PER_SEC) << "s";

  cerr << "&" << (clause-initial) << "&" << (transfer-initial) << "&" << percent << "\\%\\\\%prob:" << prob << endl;
}

void
work(int p)
{
  out << "\\begin{table}[t]" << endl;
  out << "\\begin{center}" << endl;
  out << "\\begin{tabular}{|l| r|r|r|r|r|r|r| }" << endl;
  out << "\\hline" << endl;
  out << "\\multicolumn{1}{|c|}{Operation} &" << endl;
  out << "\\multicolumn{5}{c|}{" << p << "\\%} \\\\" << endl;
  out << "& UP time & prop. time &  UP bits & prop. bits &  \\% \\\\" << endl;
  out << "\\hline" << endl;

  Functions f;
  std::list<Functions::Function>::iterator it = f.l.begin();
  while (it != f.l.end())
    {
      Functions::Function& f = *it;
      out << f.name << endl;
      go(f.k, f.fn, p);
      it++;
    }

  out << "\\hline" << endl;
  out << "\\end{tabular}" << endl;
  out << "\\caption{Comparison of unit propagation and bit-blasting at "<<  p <<  "\\%. ";
  out << iterations << " iterations at " << bits << " bits. \label{tbl:p"<< p << "}}}" << endl;
  out << "\\end{center}" << endl;
  out << "\\end{table}" << endl;
  }

int
main()
{
  mgr = new STPMgr;
  Cpp_interface interface(*mgr);
  mgr->UserFlags.division_by_zero_returns_one_flag=true;

  out << "\\begin{subtables}" << endl;
  work(1);
  work(5);
  work(50);
  work(95);
  out << "\\end{subtables}" << endl;

  out << "% Iterations:" << iterations << " bit-width:" << bits << endl;

}

<|endoftext|>


<commit_before>#ifndef _AQUARIUS_STL_EXT_HPP_
#define _AQUARIUS_STL_EXT_HPP_

#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>

#include <algorithm>
#include <array>
#include <deque>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <ostream>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <utility>
#include <regex>
#include <stdexcept>

#include "algorithm.hpp"
#include "complex.hpp"
#include "cosort.hpp"
#include "global_ptr.hpp"
#include "iostream.hpp"
#include "ptr_list.hpp"
#include "ptr_vector.hpp"
#include "string.hpp"
#include "type_traits.hpp"
#include "vector.hpp"
#include "zip.hpp"

#define INSTANTIATE_SPECIALIZATIONS(name) \
template class name<double>;

#define INSTANTIATE_SPECIALIZATIONS_2(name,extra1) \
template class name<double,extra1>;

#define INSTANTIATE_SPECIALIZATIONS_3(name,extra1,extra2) \
template class name<double,extra1,extra2>;

#define CONCAT(...) __VA_ARGS__

#define STRINGIZE(...) #__VA_ARGS__

#ifdef DEBUG

#define DPRINTF(...) \
do \
{ \
    printf("%s(%d): ", __FILE__, __LINE__); \
    printf(__VA_ARGS__); \
} while (0)

#define DPRINTFC(...) \
do \
{ \
    printf(__VA_ARGS__); \
} while (0)

#else

#define DPRINTF(...)

#define DPRINTFC(...)

#endif

namespace aquarius
{
    using std::string;
    using std::tuple;
    using std::map;
    using std::list;
    using std::set;
    using std::array;
    using std::vector;
    using std::deque;
    using std::pair;
    using std::make_pair;
    using std::make_tuple;
    using std::get;
    using std::tuple_element;

    using std::complex;
    using std::real;
    using std::imag;
    using std::conj;
    using std::numeric_limits;

    using std::min;
    using std::max;
    using std::abs;
    using std::copy;
    using std::copy_n;
    using std::fill;
    using std::fill_n;
    using std::sort;
    using std::swap;
    using std::remove;
    using std::rotate;

    using std::unique_ptr;
    using std::shared_ptr;
    using std::make_shared;

    using std::runtime_error;
    using std::logic_error;

    using std::move;
    using std::forward;

    using std::iterator;
    using std::iterator_traits;
    using std::reverse_iterator;
    using std::forward_iterator_tag;
    using std::bidirectional_iterator_tag;
    using std::random_access_iterator_tag;

    using std::unary_function;
    using std::binary_function;

    using std::ostream;
    using std::istream;
    using std::stringstream;
    using std::ostringstream;
    using std::istringstream;
    using std::fstream;
    using std::ofstream;
    using std::ifstream;
    using std::cout;
    using std::cin;
    using std::cerr;
    using std::endl;
    using std::setprecision;
    using std::scientific;
    //using std::defaultfloat; //no GCC support until GCC5 :(
    //using std::hexfloat;
    using std::fixed;
    using std::skipws;
    using std::showpos;
    using std::showbase;
    using std::noshowbase;
    using std::noshowpos;
    using std::showpoint;
    using std::noshowpoint;
    using std::dec;
    using std::oct;
    using std::hex;
    using std::setfill;
    using std::setw;
    using std::streamsize;
    using std::streambuf;

    using std::toupper;
    using std::tolower;

    using std::exception;
    using std::logic_error;
    using std::runtime_error;
    using std::out_of_range;

    using std::regex_search;
    using std::regex_match;
    using std::smatch;
    using std::cmatch;
    using std::regex;

    using std::uniform_int_distribution;
    using std::uniform_real_distribution;
    using std::default_random_engine;
    using std::mt19937;

    using namespace stl_ext;
    using stl_ext::sort;
}

#endif
<commit_msg>Use stl_ext implementations of real/imag/conj.<commit_after>#ifndef _AQUARIUS_STL_EXT_HPP_
#define _AQUARIUS_STL_EXT_HPP_

#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>

#include <algorithm>
#include <array>
#include <deque>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <ostream>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <utility>
#include <regex>
#include <stdexcept>

#include "algorithm.hpp"
#include "complex.hpp"
#include "cosort.hpp"
#include "global_ptr.hpp"
#include "iostream.hpp"
#include "ptr_list.hpp"
#include "ptr_vector.hpp"
#include "string.hpp"
#include "type_traits.hpp"
#include "vector.hpp"
#include "zip.hpp"

#define INSTANTIATE_SPECIALIZATIONS(name) \
template class name<double>;

#define INSTANTIATE_SPECIALIZATIONS_2(name,extra1) \
template class name<double,extra1>;

#define INSTANTIATE_SPECIALIZATIONS_3(name,extra1,extra2) \
template class name<double,extra1,extra2>;

#define CONCAT(...) __VA_ARGS__

#define STRINGIZE(...) #__VA_ARGS__

#ifdef DEBUG

#define DPRINTF(...) \
do \
{ \
    printf("%s(%d): ", __FILE__, __LINE__); \
    printf(__VA_ARGS__); \
} while (0)

#define DPRINTFC(...) \
do \
{ \
    printf(__VA_ARGS__); \
} while (0)

#else

#define DPRINTF(...)

#define DPRINTFC(...)

#endif

namespace aquarius
{
    using std::string;
    using std::tuple;
    using std::map;
    using std::list;
    using std::set;
    using std::array;
    using std::vector;
    using std::deque;
    using std::pair;
    using std::make_pair;
    using std::make_tuple;
    using std::get;
    using std::tuple_element;
    using std::numeric_limits;

    using std::min;
    using std::max;
    using std::abs;
    using std::copy;
    using std::copy_n;
    using std::fill;
    using std::fill_n;
    using std::sort;
    using std::swap;
    using std::remove;
    using std::rotate;

    using std::unique_ptr;
    using std::shared_ptr;
    using std::make_shared;

    using std::runtime_error;
    using std::logic_error;

    using std::move;
    using std::forward;

    using std::iterator;
    using std::iterator_traits;
    using std::reverse_iterator;
    using std::forward_iterator_tag;
    using std::bidirectional_iterator_tag;
    using std::random_access_iterator_tag;

    using std::unary_function;
    using std::binary_function;

    using std::ostream;
    using std::istream;
    using std::stringstream;
    using std::ostringstream;
    using std::istringstream;
    using std::fstream;
    using std::ofstream;
    using std::ifstream;
    using std::cout;
    using std::cin;
    using std::cerr;
    using std::endl;
    using std::setprecision;
    using std::scientific;
    //using std::defaultfloat; //no GCC support until GCC5 :(
    //using std::hexfloat;
    using std::fixed;
    using std::skipws;
    using std::showpos;
    using std::showbase;
    using std::noshowbase;
    using std::noshowpos;
    using std::showpoint;
    using std::noshowpoint;
    using std::dec;
    using std::oct;
    using std::hex;
    using std::setfill;
    using std::setw;
    using std::streamsize;
    using std::streambuf;

    using std::toupper;
    using std::tolower;

    using std::exception;
    using std::logic_error;
    using std::runtime_error;
    using std::out_of_range;

    using std::regex_search;
    using std::regex_match;
    using std::smatch;
    using std::cmatch;
    using std::regex;

    using std::uniform_int_distribution;
    using std::uniform_real_distribution;
    using std::default_random_engine;
    using std::mt19937;

    using namespace stl_ext;
    using stl_ext::sort;
}

#endif
<|endoftext|>