<commit_before>#include <iostream>
#include <cassert>
#include <memory>
#include <vector>

class IAnimal
{
	public:
	virtual ~IAnimal(){}
	virtual const char* makeNoise() const = 0;
};

class Tiger : public IAnimal { public: const char* makeNoise() const { return "Purr"; } };
class Bear : public IAnimal { public: const char* makeNoise() const { return "Growl"; } };
class Lion : public IAnimal { public: const char* makeNoise() const { return "Roar"; } };

class IZoo
{
	public:

 	virtual ~IZoo() {}

	virtual size_t BearCount() const = 0;
	virtual const Bear* GetBear(size_t index) const = 0;

	virtual size_t TigerCount() const = 0;
	virtual const Tiger* GetTiger(size_t index) const = 0;

	virtual size_t LionCount() const = 0;
	virtual const Lion* GetLion(size_t index) const = 0;
};

class Zoo : public IZoo
{
	public:

  Zoo()
	{
		std::generate_n(std::back_inserter(m_lions), 10, [](){return std::unique_ptr<Lion>(new Lion());});
	}

	size_t BearCount() const { return m_bears.size(); }
	const Bear* GetBear(size_t index) const { return m_bears[index].get(); }

	size_t TigerCount() const { return m_tigers.size(); }
	const Tiger* GetTiger(size_t index) const { return m_tigers[index].get(); }

	size_t LionCount() const { return m_lions.size(); }
	const Lion* GetLion(size_t index) const { return m_lions[index].get(); }

	private:
		std::vector<std::unique_ptr<Lion>> m_lions;
		std::vector<std::unique_ptr<Tiger>> m_tigers;
		std::vector<std::unique_ptr<Bear>> m_bears;
};

template <typename Object_t, typename Get_f, typename Count_f>
class IterableProxy
{
	public:

		IterableProxy(Get_f f_get, Count_f f_count) : m_f_get{f_get}, m_f_count{f_count} {}

   class iterator
	 {
		 public:
      iterator(Get_f& f_get, size_t index=0) : m_index(index), m_f_get{f_get} { }

      const Object_t* operator * () { return m_f_get(m_index); }
      iterator& operator++() { ++m_index; return *this; }
			bool operator == (const iterator& i) const { return m_index == i.m_index; }
			bool operator != (const iterator& i) const { return m_index != i.m_index; }

		private:
			size_t m_index;
	 		Get_f& m_f_get;
	 };

	 iterator begin() { return iterator(m_f_get); }

	 iterator end() { return iterator(m_f_get, m_f_count()); }

	private:
	 Get_f m_f_get;
	 Count_f m_f_count;
};

template <typename Object_t, typename Get_f, typename Count_f>
IterableProxy <Object_t, Get_f, Count_f>
make_iterable_proxy(Get_f f_get, Count_f f_count)
{
	return IterableProxy <Object_t, Get_f, Count_f>(f_get, f_count);
}

int main(int argc, char* argv[])
{
	Zoo myZoo;

	assert(myZoo.LionCount() == 10);
	assert(myZoo.GetLion(0));

	auto iterableLions = make_iterable_proxy<Lion>(
			[&myZoo](size_t index){ return myZoo.GetLion(index); },
			[&myZoo](){ return myZoo.LionCount(); });

	for ( auto myLion : iterableLions )
	{
		std::cout << myLion->makeNoise() << std::endl;
	}
}

<commit_msg>Iterable proxy compares well to raw function calls<commit_after>#include <iostream>
#include <memory>
#include <vector>

class IAnimal
{
	public:
	virtual ~IAnimal(){}
	virtual const char* makeNoise() const = 0;
};

class Tiger : public IAnimal { public: const char* makeNoise() const { return "Purr"; } };
class Bear : public IAnimal { public: const char* makeNoise() const { return "Growl"; } };
class Lion : public IAnimal { public: const char* makeNoise() const { return "Roar"; } };

class IZoo
{
	public:

 	virtual ~IZoo() {}

	virtual size_t BearCount() const = 0;
	virtual const Bear* GetBear(size_t index) const = 0;

	virtual size_t TigerCount() const = 0;
	virtual const Tiger* GetTiger(size_t index) const = 0;

	virtual size_t LionCount() const = 0;
	virtual const Lion* GetLion(size_t index) const = 0;
};

class Zoo : public IZoo
{
	public:

  Zoo()
	{
		std::generate_n(std::back_inserter(m_lions), 10, [](){return std::unique_ptr<Lion>(new Lion());});
	}

	size_t BearCount() const { return m_bears.size(); }
	const Bear* GetBear(size_t index) const { return m_bears[index].get(); }

	size_t TigerCount() const { return m_tigers.size(); }
	const Tiger* GetTiger(size_t index) const { return m_tigers[index].get(); }

	size_t LionCount() const { return m_lions.size(); }
	const Lion* GetLion(size_t index) const { return m_lions[index].get(); }

	private:
		std::vector<std::unique_ptr<Lion>> m_lions;
		std::vector<std::unique_ptr<Tiger>> m_tigers;
		std::vector<std::unique_ptr<Bear>> m_bears;
};

template <typename Object_t, typename Get_f, typename Count_f>
class IterableProxy
{
	public:

		IterableProxy(Get_f f_get, Count_f f_count) : m_f_get{f_get}, m_f_count{f_count} {}

   class iterator
	 {
		 public:
      iterator(Get_f& f_get, size_t index=0) : m_index(index), m_f_get{f_get} { }

      const Object_t* operator * () { return m_f_get(m_index); }
      iterator& operator++() { ++m_index; return *this; }
			bool operator == (const iterator& i) const { return m_index == i.m_index; }
			bool operator != (const iterator& i) const { return m_index != i.m_index; }

		private:
			size_t m_index;
	 		Get_f& m_f_get;
	 };

	 iterator begin() { return iterator(m_f_get); }

	 iterator end() { return iterator(m_f_get, m_f_count()); }

	private:
	 Get_f m_f_get;
	 Count_f m_f_count;
};

template <typename Object_t, typename Get_f, typename Count_f>
IterableProxy <Object_t, Get_f, Count_f>
make_iterable_proxy(Get_f f_get, Count_f f_count)
{
	return IterableProxy <Object_t, Get_f, Count_f>(f_get, f_count);
}

int main(int argc, char* argv[])
{
	Zoo myZoo;

	auto iterableLions = make_iterable_proxy<Lion>(
			[&myZoo](size_t index){ return myZoo.GetLion(index); },
			[&myZoo](){ return myZoo.LionCount(); });

	for ( auto myLion : iterableLions )
	{
		std::cout << myLion->makeNoise() << std::endl;
	}
}

<|endoftext|>


<commit_before>/* * This file is part of m-keyboard *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "ut_flickrecognizer.h"
#include "flickutil.h"
#include "utils.h"

#include "flickgesture.h"
#include "flickgesturerecognizer.h"

#include <MApplication>
#include <MScene>
#include <MSceneManager>
#include <MWindow>
#include <QGraphicsSceneMouseEvent>
#include <MSceneWindow>

Q_DECLARE_METATYPE(FlickGesture::Direction);
Q_DECLARE_METATYPE(QList<QPoint>);

class FlickTarget : public MSceneWindow
{
public:
    FlickTarget(QGraphicsItem *parent = 0)
        : MSceneWindow(parent)
    {
    }

    int numberOfFlickGestures() const
    {
        int sum = 0;
        for (int i = 0; i < 4; ++i) {
            sum += flickCountArray[i];
        }
        return sum;
    }

    int numberOfFlickStarts() const
    {
        int sum = 0;
        for (int i = 0; i < 4; ++i) {
            sum += flickStartCountArray[i];
        }
        return sum;
    }

    int numberOfFlickGestures(FlickGesture::Direction direction) const
    {
        const int index = static_cast<int>(direction);
        Q_ASSERT(index < 4);
        return flickCountArray[index];
    }

    int numberOfFlickStarts(FlickGesture::Direction direction) const
    {
        const int index = static_cast<int>(direction);
        Q_ASSERT(index < 4);
        return flickStartCountArray[index];
    }

    void resetFlickCounters()
    {
        flickCountArray[0] = 0;
        flickCountArray[1] = 0;
        flickCountArray[2] = 0;
        flickCountArray[3] = 0;
        flickStartCountArray[0] = 0;
        flickStartCountArray[1] = 0;
        flickStartCountArray[2] = 0;
        flickStartCountArray[3] = 0;
    }

protected:
    virtual bool event(QEvent *event)
    {
        if (event->type() == QEvent::Gesture) {
            QGestureEvent *ge = static_cast<QGestureEvent *>(event);
            QGesture *gesture = ge->gesture(FlickGestureRecognizer::sharedGestureType());
            FlickGesture *flickGesture = static_cast<FlickGesture *>(gesture);

            handleFlickGesture(flickGesture);
            return true;
        }
        return QGraphicsWidget::event(event);
    }

    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        qDebug() << "Target Mouse Press" << event->pos() << ", " << event->screenPos();
    }
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        qDebug() << "Target Mouse Move" << event->pos() << ", " << event->screenPos();
    }
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    {
        qDebug() << "Target Mouse Release" << event->pos() << ", " << event->screenPos();
    }

    void handleFlickGesture(FlickGesture *gesture)
    {
        if (gesture->state() == Qt::GestureFinished) {
            FlickGesture::Direction dir = gesture->direction();
            if (dir != FlickGesture::NoDirection) {
                ++flickCountArray[static_cast<int>(dir)];
            }
        } else if (gesture->state() == Qt::GestureStarted) {
            FlickGesture::Direction dir = gesture->direction();
            if (dir != FlickGesture::NoDirection) {
                ++flickStartCountArray[static_cast<int>(dir)];
            }
        }
    }

    int flickCountArray[4];
    int flickStartCountArray[4];
};

void Ut_FlickRecognizer::initTestCase()
{
    qRegisterMetaType<FlickGesture::Direction>("FlickGesture::Direction");
    qRegisterMetaType< QList<QPoint> >("QList<QPoint>");

    static int argc = 3;
    static char *app_args[3] = { (char *) "ut_flickrecognizer",
                                 (char *) "-local-theme",
                                 (char *) "-software" };

    disableQtPlugins();
    app = new MApplication(argc, app_args);

    MSceneManager *sceneMgr = new MSceneManager;
    window = new MWindow(sceneMgr, 0);
    window->scene()->setSceneRect(QRect(QPoint(0, 0), sceneMgr->visibleSceneSize()));

    target = new FlickTarget;
    QSignalSpy spy(target, SIGNAL(appeared()));
    target->appear(window);
    target->setPos(0, 0);
    target->resize(864, 480);

    gestureTimeout = 300;
    gestureFinishMovementThreshold = QPoint(300, 200);
    gestureStartMovementThreshold = gestureFinishMovementThreshold * 0.5;

    if (gestureTimeout <= 0
        || gestureFinishMovementThreshold.x() > window->width()
        || gestureFinishMovementThreshold.y() > window->height()) {
        QSKIP("Flick gesture parameters prevent any flick ever being made. Skipping tests.",
              SkipAll);
    }

    FlickGestureRecognizer::registerSharedRecognizer();
    FlickGestureRecognizer::instance()->setFinishThreshold(gestureFinishMovementThreshold.x(),
                                                           gestureFinishMovementThreshold.y());
    FlickGestureRecognizer::instance()->setStartThreshold(gestureStartMovementThreshold.x(),
                                                          gestureStartMovementThreshold.y());
    FlickGestureRecognizer::instance()->setTimeout(gestureTimeout);

    Qt::GestureType gtype = FlickGestureRecognizer::sharedGestureType();
    QVERIFY(gtype & Qt::CustomGesture);
    window->viewport()->grabGesture(gtype);
    target->grabGesture(gtype);

    window->show();
    QTest::qWaitForWindowShown(window);

    // Wait for target to be ready
    while(spy.count() < 1) {
        QTest::qWait(100);
    }
    // Used to have trouble with delayed show caused by remote theme. Let's still have the check.
    QVERIFY(window->isVisible());
    QVERIFY(window->testAttribute(Qt::WA_Mapped));
}

void Ut_FlickRecognizer::cleanupTestCase()
{
    window->close();

    FlickGestureRecognizer::unregisterSharedRecognizer();

    delete window->scene();
    delete window;
    window = 0;
    delete app;
    app = 0;
}

void Ut_FlickRecognizer::init()
{
    target->resetFlickCounters();
}

void Ut_FlickRecognizer::cleanup()
{
}

void Ut_FlickRecognizer::testDirections_data()
{
    QTest::addColumn<QPoint>("start");
    QTest::addColumn<QPoint>("end");
    QTest::addColumn<FlickGesture::Direction>("direction");

    const int xlength = gestureFinishMovementThreshold.x() + 1;
    const int ylength = gestureFinishMovementThreshold.y() + 1;

    QTest::newRow("->") << QPoint(0, 0) << QPoint(xlength, 0) << FlickGesture::Right;
    QTest::newRow("<-") << QPoint(xlength, 0) << QPoint(0, 0) << FlickGesture::Left;
    QTest::newRow("v") << QPoint(0, 0) << QPoint(0, ylength) << FlickGesture::Down;
    QTest::newRow("^") << QPoint(0, ylength) << QPoint(0, 0) << FlickGesture::Up;
}

void Ut_FlickRecognizer::testDirections()
{
    QFETCH(QPoint, start);
    QFETCH(QPoint, end);
    QFETCH(FlickGesture::Direction, direction);

    doMouseSwipe(target, start, end, gestureTimeout / 2);

    QCOMPARE(target->numberOfFlickGestures(), 1);
    QCOMPARE(target->numberOfFlickGestures(direction), 1);
}

void Ut_FlickRecognizer::testTimeout_data()
{
    QTest::addColumn<int>("duration");
    QTest::addColumn<bool>("wasFlicked");

    QTest::newRow("valid") << qMax(0, (gestureTimeout - 50)) << true;
    QTest::newRow("invalid") << (gestureTimeout + 50) << false;
}

void Ut_FlickRecognizer::testTimeout()
{
    QFETCH(int, duration);
    QFETCH(bool, wasFlicked);

    const int expectedNumOfGestures = wasFlicked ? 1 : 0;

    // Constant start and end point for this test.
    const QPoint start(0, 0);
    const QPoint end(start + QPoint(gestureFinishMovementThreshold.x() + 2, 0));

    doMouseSwipe(target, start, end, duration);

    QCOMPARE(target->numberOfFlickGestures(), expectedNumOfGestures);
}

void Ut_FlickRecognizer::testMovementThreshold_data()
{
    QTest::addColumn<QPoint>("start");
    QTest::addColumn<QPoint>("end");
    QTest::addColumn<bool>("wasFlicked");

    QTest::newRow("valid horizontal") << QPoint(0, 0) << QPoint(gestureFinishMovementThreshold.x() + 10, 0) << true;
    QTest::newRow("invalid horizontal") << QPoint(0, 0) << QPoint(qMax(0, (gestureFinishMovementThreshold.x() - 10)), 0) << false;
    QTest::newRow("valid vertical") << QPoint(0, 0) << QPoint(0, gestureFinishMovementThreshold.y() + 10) << true;
    QTest::newRow("invalid vertical") << QPoint(0, 0) << QPoint(0, qMax(0, (gestureFinishMovementThreshold.y() - 10))) << false;
}

void Ut_FlickRecognizer::testMovementThreshold()
{
    QFETCH(QPoint, start);
    QFETCH(QPoint, end);
    QFETCH(bool, wasFlicked);

    const int expectedNumOfGestures = wasFlicked ? 1 : 0;

    doMouseSwipe(target, start, end, gestureTimeout / 2);

    QCOMPARE(target->numberOfFlickGestures(), expectedNumOfGestures);
}

void Ut_FlickRecognizer::testStartThreshold_data()
{
    const int xlength = gestureStartMovementThreshold.x();
    const int ylength = gestureStartMovementThreshold.y();

    if (xlength >= gestureFinishMovementThreshold.x()
        || ylength >= gestureFinishMovementThreshold.y()) {
        QSKIP("Cannot recognize separate start because gesture finishes too soon.", SkipSingle);
    }

    QTest::addColumn<QPoint>("start");
    QTest::addColumn<QPoint>("end");
    QTest::addColumn<bool>("wasStarted");

    QTest::newRow("valid horizontal")   << QPoint(0, 0) << QPoint(xlength, 0)     << true;
    QTest::newRow("invalid horizontal") << QPoint(0, 0) << QPoint(xlength - 1, 0) << false;
    QTest::newRow("valid vertical")     << QPoint(0, 0) << QPoint(0, ylength)     << true;
    QTest::newRow("invalid vertical")   << QPoint(0, 0) << QPoint(0, ylength - 1) << false;
}

void Ut_FlickRecognizer::testStartThreshold()
{
    QFETCH(QPoint, start);
    QFETCH(QPoint, end);
    QFETCH(bool, wasStarted);

    const int expectedNumOfStarts = wasStarted ? 1 : 0;

    // Since start gesture is not sent it it happens on mouse release
    // we set last move point to land on the same coordinates.
    const bool lastMoveLandsOnEnd = true;
    const int steps = 5;

    doMouseSwipe(target, start, end, gestureTimeout / 2, steps, lastMoveLandsOnEnd);

    QCOMPARE(target->numberOfFlickStarts(), expectedNumOfStarts);
    QCOMPARE(target->numberOfFlickGestures(), 0);
}

void Ut_FlickRecognizer::testInvalidZigZag_data()
{
    QTest::addColumn< QList<QPoint> >("path");
    QTest::addColumn<bool>("wasFlicked");

    const unsigned int intermediatePoints = 6;
    QList<QPoint> path = makeSwipePointPath(QPoint(0, 0),
                                            QPoint(gestureFinishMovementThreshold.x(), 0),
                                            intermediatePoints);
    const QPoint point2 = path.at(2);
    const QPoint point3 = path.at(3);

    // This one is a valid flick.
    QTest::newRow("normal flick") << path << true;

    // Switch places, we have a little zigzag.
    path[2] = point3;
    path[3] = point2;
    QTest::newRow("direction changed") << path << false;

    // Restore.
    path[2] = point2;
    path[3] = point3;

    // Switch major direction at one point.
    path[2].rx() *= -1;
    QTest::newRow("major direction changed") << path << false;
}

void Ut_FlickRecognizer::testInvalidZigZag()
{
    QFETCH(QList<QPoint>, path);
    QFETCH(bool, wasFlicked);

    doMouseSwipe(target, path, gestureTimeout / 2);

    QCOMPARE(target->numberOfFlickGestures(), (wasFlicked ? 1 : 0));
}

void Ut_FlickRecognizer::testInvalidTwoFinger_data()
{
    QTest::addColumn< QList<QPoint> >("path");
    QTest::addColumn<bool>("wasFlicked");

    // Simulate the common accidental flick-made-by-two-fingers gesture.
    QList<QPoint> path;
    path << QPoint(0, 0)
         << QPoint(1, 0)
         << QPoint(2, 0)
         << QPoint(gestureFinishMovementThreshold.x(), 0)
         << QPoint(gestureFinishMovementThreshold.x() + 1, 0)
         << QPoint(gestureFinishMovementThreshold.x() + 2, 0);

    QTest::newRow("too long jump") << path << false;

    // Make one stop in the middle.
    path[3] = QPoint(gestureFinishMovementThreshold.x() / 2, 0);
    QTest::newRow("valid flick") << path << true;
}

void Ut_FlickRecognizer::testInvalidTwoFinger()
{
    QFETCH(QList<QPoint>, path);
    QFETCH(bool, wasFlicked);

    doMouseSwipe(target, path, gestureTimeout / 2);

    QCOMPARE(target->numberOfFlickGestures(), (wasFlicked ? 1 : 0));
}

QTEST_APPLESS_MAIN(Ut_FlickRecognizer);
<commit_msg>Changes: Add timeout to Ut_FlickRecognizer::initTestCase<commit_after>/* * This file is part of m-keyboard *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "ut_flickrecognizer.h"
#include "flickutil.h"
#include "utils.h"

#include "flickgesture.h"
#include "flickgesturerecognizer.h"

#include <MApplication>
#include <MScene>
#include <MSceneManager>
#include <MWindow>
#include <QGraphicsSceneMouseEvent>
#include <MSceneWindow>

Q_DECLARE_METATYPE(FlickGesture::Direction);
Q_DECLARE_METATYPE(QList<QPoint>);

class FlickTarget : public MSceneWindow
{
public:
    FlickTarget(QGraphicsItem *parent = 0)
        : MSceneWindow(parent)
    {
    }

    int numberOfFlickGestures() const
    {
        int sum = 0;
        for (int i = 0; i < 4; ++i) {
            sum += flickCountArray[i];
        }
        return sum;
    }

    int numberOfFlickStarts() const
    {
        int sum = 0;
        for (int i = 0; i < 4; ++i) {
            sum += flickStartCountArray[i];
        }
        return sum;
    }

    int numberOfFlickGestures(FlickGesture::Direction direction) const
    {
        const int index = static_cast<int>(direction);
        Q_ASSERT(index < 4);
        return flickCountArray[index];
    }

    int numberOfFlickStarts(FlickGesture::Direction direction) const
    {
        const int index = static_cast<int>(direction);
        Q_ASSERT(index < 4);
        return flickStartCountArray[index];
    }

    void resetFlickCounters()
    {
        flickCountArray[0] = 0;
        flickCountArray[1] = 0;
        flickCountArray[2] = 0;
        flickCountArray[3] = 0;
        flickStartCountArray[0] = 0;
        flickStartCountArray[1] = 0;
        flickStartCountArray[2] = 0;
        flickStartCountArray[3] = 0;
    }

protected:
    virtual bool event(QEvent *event)
    {
        if (event->type() == QEvent::Gesture) {
            QGestureEvent *ge = static_cast<QGestureEvent *>(event);
            QGesture *gesture = ge->gesture(FlickGestureRecognizer::sharedGestureType());
            FlickGesture *flickGesture = static_cast<FlickGesture *>(gesture);

            handleFlickGesture(flickGesture);
            return true;
        }
        return QGraphicsWidget::event(event);
    }

    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        qDebug() << "Target Mouse Press" << event->pos() << ", " << event->screenPos();
    }
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        qDebug() << "Target Mouse Move" << event->pos() << ", " << event->screenPos();
    }
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    {
        qDebug() << "Target Mouse Release" << event->pos() << ", " << event->screenPos();
    }

    void handleFlickGesture(FlickGesture *gesture)
    {
        if (gesture->state() == Qt::GestureFinished) {
            FlickGesture::Direction dir = gesture->direction();
            if (dir != FlickGesture::NoDirection) {
                ++flickCountArray[static_cast<int>(dir)];
            }
        } else if (gesture->state() == Qt::GestureStarted) {
            FlickGesture::Direction dir = gesture->direction();
            if (dir != FlickGesture::NoDirection) {
                ++flickStartCountArray[static_cast<int>(dir)];
            }
        }
    }

    int flickCountArray[4];
    int flickStartCountArray[4];
};

void Ut_FlickRecognizer::initTestCase()
{
    qRegisterMetaType<FlickGesture::Direction>("FlickGesture::Direction");
    qRegisterMetaType< QList<QPoint> >("QList<QPoint>");

    static int argc = 3;
    static char *app_args[3] = { (char *) "ut_flickrecognizer",
                                 (char *) "-local-theme",
                                 (char *) "-software" };

    disableQtPlugins();
    app = new MApplication(argc, app_args);

    MSceneManager *sceneMgr = new MSceneManager;
    window = new MWindow(sceneMgr, 0);
    window->scene()->setSceneRect(QRect(QPoint(0, 0), sceneMgr->visibleSceneSize()));

    target = new FlickTarget;
    QSignalSpy spy(target, SIGNAL(appeared()));
    target->appear(window);
    target->setPos(0, 0);
    target->resize(864, 480);

    gestureTimeout = 300;
    gestureFinishMovementThreshold = QPoint(300, 200);
    gestureStartMovementThreshold = gestureFinishMovementThreshold * 0.5;

    if (gestureTimeout <= 0
        || gestureFinishMovementThreshold.x() > window->width()
        || gestureFinishMovementThreshold.y() > window->height()) {
        QSKIP("Flick gesture parameters prevent any flick ever being made. Skipping tests.",
              SkipAll);
    }

    FlickGestureRecognizer::registerSharedRecognizer();
    FlickGestureRecognizer::instance()->setFinishThreshold(gestureFinishMovementThreshold.x(),
                                                           gestureFinishMovementThreshold.y());
    FlickGestureRecognizer::instance()->setStartThreshold(gestureStartMovementThreshold.x(),
                                                          gestureStartMovementThreshold.y());
    FlickGestureRecognizer::instance()->setTimeout(gestureTimeout);

    Qt::GestureType gtype = FlickGestureRecognizer::sharedGestureType();
    QVERIFY(gtype & Qt::CustomGesture);
    window->viewport()->grabGesture(gtype);
    target->grabGesture(gtype);

    window->show();
    QTest::qWaitForWindowShown(window);

    // Wait for target to be ready
    for(int waitCount=0; spy.count() < 1; ++waitCount) {
        QTest::qWait(100);
        QVERIFY(waitCount<100);
    }
    // Used to have trouble with delayed show caused by remote theme. Let's still have the check.
    QVERIFY(window->isVisible());
    QVERIFY(window->testAttribute(Qt::WA_Mapped));
}

void Ut_FlickRecognizer::cleanupTestCase()
{
    window->close();

    FlickGestureRecognizer::unregisterSharedRecognizer();

    delete window->scene();
    delete window;
    window = 0;
    delete app;
    app = 0;
}

void Ut_FlickRecognizer::init()
{
    target->resetFlickCounters();
}

void Ut_FlickRecognizer::cleanup()
{
}

void Ut_FlickRecognizer::testDirections_data()
{
    QTest::addColumn<QPoint>("start");
    QTest::addColumn<QPoint>("end");
    QTest::addColumn<FlickGesture::Direction>("direction");

    const int xlength = gestureFinishMovementThreshold.x() + 1;
    const int ylength = gestureFinishMovementThreshold.y() + 1;

    QTest::newRow("->") << QPoint(0, 0) << QPoint(xlength, 0) << FlickGesture::Right;
    QTest::newRow("<-") << QPoint(xlength, 0) << QPoint(0, 0) << FlickGesture::Left;
    QTest::newRow("v") << QPoint(0, 0) << QPoint(0, ylength) << FlickGesture::Down;
    QTest::newRow("^") << QPoint(0, ylength) << QPoint(0, 0) << FlickGesture::Up;
}

void Ut_FlickRecognizer::testDirections()
{
    QFETCH(QPoint, start);
    QFETCH(QPoint, end);
    QFETCH(FlickGesture::Direction, direction);

    doMouseSwipe(target, start, end, gestureTimeout / 2);

    QCOMPARE(target->numberOfFlickGestures(), 1);
    QCOMPARE(target->numberOfFlickGestures(direction), 1);
}

void Ut_FlickRecognizer::testTimeout_data()
{
    QTest::addColumn<int>("duration");
    QTest::addColumn<bool>("wasFlicked");

    QTest::newRow("valid") << qMax(0, (gestureTimeout - 50)) << true;
    QTest::newRow("invalid") << (gestureTimeout + 50) << false;
}

void Ut_FlickRecognizer::testTimeout()
{
    QFETCH(int, duration);
    QFETCH(bool, wasFlicked);

    const int expectedNumOfGestures = wasFlicked ? 1 : 0;

    // Constant start and end point for this test.
    const QPoint start(0, 0);
    const QPoint end(start + QPoint(gestureFinishMovementThreshold.x() + 2, 0));

    doMouseSwipe(target, start, end, duration);

    QCOMPARE(target->numberOfFlickGestures(), expectedNumOfGestures);
}

void Ut_FlickRecognizer::testMovementThreshold_data()
{
    QTest::addColumn<QPoint>("start");
    QTest::addColumn<QPoint>("end");
    QTest::addColumn<bool>("wasFlicked");

    QTest::newRow("valid horizontal") << QPoint(0, 0) << QPoint(gestureFinishMovementThreshold.x() + 10, 0) << true;
    QTest::newRow("invalid horizontal") << QPoint(0, 0) << QPoint(qMax(0, (gestureFinishMovementThreshold.x() - 10)), 0) << false;
    QTest::newRow("valid vertical") << QPoint(0, 0) << QPoint(0, gestureFinishMovementThreshold.y() + 10) << true;
    QTest::newRow("invalid vertical") << QPoint(0, 0) << QPoint(0, qMax(0, (gestureFinishMovementThreshold.y() - 10))) << false;
}

void Ut_FlickRecognizer::testMovementThreshold()
{
    QFETCH(QPoint, start);
    QFETCH(QPoint, end);
    QFETCH(bool, wasFlicked);

    const int expectedNumOfGestures = wasFlicked ? 1 : 0;

    doMouseSwipe(target, start, end, gestureTimeout / 2);

    QCOMPARE(target->numberOfFlickGestures(), expectedNumOfGestures);
}

void Ut_FlickRecognizer::testStartThreshold_data()
{
    const int xlength = gestureStartMovementThreshold.x();
    const int ylength = gestureStartMovementThreshold.y();

    if (xlength >= gestureFinishMovementThreshold.x()
        || ylength >= gestureFinishMovementThreshold.y()) {
        QSKIP("Cannot recognize separate start because gesture finishes too soon.", SkipSingle);
    }

    QTest::addColumn<QPoint>("start");
    QTest::addColumn<QPoint>("end");
    QTest::addColumn<bool>("wasStarted");

    QTest::newRow("valid horizontal")   << QPoint(0, 0) << QPoint(xlength, 0)     << true;
    QTest::newRow("invalid horizontal") << QPoint(0, 0) << QPoint(xlength - 1, 0) << false;
    QTest::newRow("valid vertical")     << QPoint(0, 0) << QPoint(0, ylength)     << true;
    QTest::newRow("invalid vertical")   << QPoint(0, 0) << QPoint(0, ylength - 1) << false;
}

void Ut_FlickRecognizer::testStartThreshold()
{
    QFETCH(QPoint, start);
    QFETCH(QPoint, end);
    QFETCH(bool, wasStarted);

    const int expectedNumOfStarts = wasStarted ? 1 : 0;

    // Since start gesture is not sent it it happens on mouse release
    // we set last move point to land on the same coordinates.
    const bool lastMoveLandsOnEnd = true;
    const int steps = 5;

    doMouseSwipe(target, start, end, gestureTimeout / 2, steps, lastMoveLandsOnEnd);

    QCOMPARE(target->numberOfFlickStarts(), expectedNumOfStarts);
    QCOMPARE(target->numberOfFlickGestures(), 0);
}

void Ut_FlickRecognizer::testInvalidZigZag_data()
{
    QTest::addColumn< QList<QPoint> >("path");
    QTest::addColumn<bool>("wasFlicked");

    const unsigned int intermediatePoints = 6;
    QList<QPoint> path = makeSwipePointPath(QPoint(0, 0),
                                            QPoint(gestureFinishMovementThreshold.x(), 0),
                                            intermediatePoints);
    const QPoint point2 = path.at(2);
    const QPoint point3 = path.at(3);

    // This one is a valid flick.
    QTest::newRow("normal flick") << path << true;

    // Switch places, we have a little zigzag.
    path[2] = point3;
    path[3] = point2;
    QTest::newRow("direction changed") << path << false;

    // Restore.
    path[2] = point2;
    path[3] = point3;

    // Switch major direction at one point.
    path[2].rx() *= -1;
    QTest::newRow("major direction changed") << path << false;
}

void Ut_FlickRecognizer::testInvalidZigZag()
{
    QFETCH(QList<QPoint>, path);
    QFETCH(bool, wasFlicked);

    doMouseSwipe(target, path, gestureTimeout / 2);

    QCOMPARE(target->numberOfFlickGestures(), (wasFlicked ? 1 : 0));
}

void Ut_FlickRecognizer::testInvalidTwoFinger_data()
{
    QTest::addColumn< QList<QPoint> >("path");
    QTest::addColumn<bool>("wasFlicked");

    // Simulate the common accidental flick-made-by-two-fingers gesture.
    QList<QPoint> path;
    path << QPoint(0, 0)
         << QPoint(1, 0)
         << QPoint(2, 0)
         << QPoint(gestureFinishMovementThreshold.x(), 0)
         << QPoint(gestureFinishMovementThreshold.x() + 1, 0)
         << QPoint(gestureFinishMovementThreshold.x() + 2, 0);

    QTest::newRow("too long jump") << path << false;

    // Make one stop in the middle.
    path[3] = QPoint(gestureFinishMovementThreshold.x() / 2, 0);
    QTest::newRow("valid flick") << path << true;
}

void Ut_FlickRecognizer::testInvalidTwoFinger()
{
    QFETCH(QList<QPoint>, path);
    QFETCH(bool, wasFlicked);

    doMouseSwipe(target, path, gestureTimeout / 2);

    QCOMPARE(target->numberOfFlickGestures(), (wasFlicked ? 1 : 0));
}

QTEST_APPLESS_MAIN(Ut_FlickRecognizer);
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "i_partitioner.hh"
#include "core/reactor.hh"
#include "murmur3_partitioner.hh"
#include "utils/class_registrator.hh"
#include "types.hh"
#include <boost/range/adaptor/map.hpp>

namespace dht {

token
minimum_token() {
    return { token::kind::before_all_keys, {} };
}

token
maximum_token() {
    return { token::kind::after_all_keys, {} };
}

// result + overflow bit
std::pair<bytes, bool>
add_bytes(bytes_view b1, bytes_view b2, bool carry = false) {
    auto sz = std::max(b1.size(), b2.size());
    auto expand = [sz] (bytes_view b) {
        bytes ret(bytes::initialized_later(), sz);
        auto bsz = b.size();
        auto p = std::copy(b.begin(), b.end(), ret.begin());
        std::fill_n(p, sz - bsz, 0);
        return ret;
    };
    auto eb1 = expand(b1);
    auto eb2 = expand(b2);
    auto p1 = eb1.begin();
    auto p2 = eb2.begin();
    unsigned tmp = carry;
    for (size_t idx = 0; idx < sz; ++idx) {
        tmp += uint8_t(p1[sz - idx - 1]);
        tmp += uint8_t(p2[sz - idx - 1]);
        p1[sz - idx - 1] = tmp;
        tmp >>= std::numeric_limits<uint8_t>::digits;
    }
    return { std::move(eb1), bool(tmp) };
}

bytes
shift_right(bool carry, bytes b) {
    unsigned tmp = carry;
    auto sz = b.size();
    auto p = b.begin();
    for (size_t i = 0; i < sz; ++i) {
        auto lsb = p[i] & 1;
        p[i] = (tmp << std::numeric_limits<uint8_t>::digits) | uint8_t(p[i]) >> 1;
        tmp = lsb;
    }
    return b;
}

token
midpoint_unsigned_tokens(const token& t1, const token& t2) {
    // calculate the average of the two tokens.
    // before_all_keys is implicit 0, after_all_keys is implicit 1.
    bool c1 = t1._kind == token::kind::after_all_keys;
    bool c2 = t1._kind == token::kind::after_all_keys;
    if (c1 && c2) {
        // both end-of-range tokens?
        return t1;
    }
    // we can ignore beginning-of-range, since their representation is 0.0
    auto sum_carry = add_bytes(t1._data, t2._data);
    auto& sum = sum_carry.first;
    // if either was end-of-range, we added 0.0, so pretend we added 1.0 and
    // and got a carry:
    bool carry = sum_carry.second || c1 || c2;
    auto avg = shift_right(carry, std::move(sum));
    if (t1 > t2) {
        // wrap around the ring.  We really want (t1 + (t2 + 1.0)) / 2, so add 0.5.
        // example: midpoint(0.9, 0.2) == midpoint(0.9, 1.2) == 1.05 == 0.05
        //                             == (0.9 + 0.2) / 2 + 0.5 (mod 1)
        if (avg.size() > 0) {
            avg[0] ^= 0x80;
        }
    }
    return token{token::kind::key, std::move(avg)};
}

static inline unsigned char get_byte(bytes_view b, size_t off) {
    if (off < b.size()) {
        return b[off];
    } else {
        return 0;
    }
}

int i_partitioner::tri_compare(const token& t1, const token& t2) const {
    size_t sz = std::max(t1._data.size(), t2._data.size());

    for (size_t i = 0; i < sz; i++) {
        auto b1 = get_byte(t1._data, i);
        auto b2 = get_byte(t2._data, i);
        if (b1 < b2) {
            return -1;
        } else if (b1 > b2) {
            return 1;
        }
    }
    return 0;
}

int tri_compare(const token& t1, const token& t2) {
    if (t1._kind == t2._kind) {
        return global_partitioner().tri_compare(t1, t2);
    } else if (t1._kind < t2._kind) {
        return -1;
    }
    return 1;
}

bool operator==(const token& t1, const token& t2)
{
    if (t1._kind != t2._kind) {
        return false;
    } else if (t1._kind == token::kind::key) {
        return global_partitioner().is_equal(t1, t2);
    }
    return true;
}

bool operator<(const token& t1, const token& t2)
{
    if (t1._kind < t2._kind) {
        return true;
    } else if (t1._kind == token::kind::key && t2._kind == token::kind::key) {
        return global_partitioner().is_less(t1, t2);
    }
    return false;
}

std::ostream& operator<<(std::ostream& out, const token& t) {
    if (t._kind == token::kind::after_all_keys) {
        out << "maximum token";
    } else if (t._kind == token::kind::before_all_keys) {
        out << "minimum token";
    } else {
        out << global_partitioner().to_sstring(t);
    }
    return out;
}

std::ostream& operator<<(std::ostream& out, const decorated_key& dk) {
    return out << "{key: " << dk._key << ", token:" << dk._token << "}";
}

// FIXME: make it per-keyspace
std::unique_ptr<i_partitioner> default_partitioner { new murmur3_partitioner };

void set_global_partitioner(const sstring& class_name, unsigned ignore_msb)
{
    try {
        default_partitioner = create_object<i_partitioner, const unsigned&, const unsigned&>(class_name, smp::count, ignore_msb);
    } catch (std::exception& e) {
        auto supported_partitioners = ::join(", ", class_registry<i_partitioner>::classes() |
                boost::adaptors::map_keys);
        throw std::runtime_error(sprint("Partitioner %s is not supported, supported partitioners = { %s } : %s",
                class_name, supported_partitioners, e.what()));
    }
}

i_partitioner&
global_partitioner() {
    return *default_partitioner;
}

bool
decorated_key::equal(const schema& s, const decorated_key& other) const {
    if (_token == other._token) {
        return _key.legacy_equal(s, other._key);
    }
    return false;
}

int
decorated_key::tri_compare(const schema& s, const decorated_key& other) const {
    auto r = dht::tri_compare(_token, other._token);
    if (r != 0) {
        return r;
    } else {
        return _key.legacy_tri_compare(s, other._key);
    }
}

int
decorated_key::tri_compare(const schema& s, const ring_position& other) const {
    auto r = dht::tri_compare(_token, other.token());
    if (r != 0) {
        return r;
    } else if (other.has_key()) {
        return _key.legacy_tri_compare(s, *other.key());
    }
    return -other.relation_to_keys();
}

bool
decorated_key::less_compare(const schema& s, const ring_position& other) const {
    return tri_compare(s, other) < 0;
}

bool
decorated_key::less_compare(const schema& s, const decorated_key& other) const {
    return tri_compare(s, other) < 0;
}

decorated_key::less_comparator::less_comparator(schema_ptr s)
    : s(std::move(s))
{ }

bool
decorated_key::less_comparator::operator()(const decorated_key& lhs, const decorated_key& rhs) const {
    return lhs.less_compare(*s, rhs);
}

bool
decorated_key::less_comparator::operator()(const ring_position& lhs, const decorated_key& rhs) const {
    return rhs.tri_compare(*s, lhs) > 0;
}

bool
decorated_key::less_comparator::operator()(const decorated_key& lhs, const ring_position& rhs) const {
    return lhs.tri_compare(*s, rhs) < 0;
}

std::ostream& operator<<(std::ostream& out, const ring_position& pos) {
    out << "{" << pos.token();
    if (pos.has_key()) {
        out << ", " << *pos.key();
    } else {
        out << ", " << ((pos.relation_to_keys() < 0) ? "start" : "end");
    }
    return out << "}";
}

unsigned shard_of(const token& t) {
    return global_partitioner().shard_of(t);
}

stdx::optional<ring_position_range_and_shard>
ring_position_range_sharder::next(const schema& s) {
    if (_done) {
        return {};
    }
    auto shard = _range.start() ? shard_of(_range.start()->value().token()) : global_partitioner().shard_of_minimum_token();
    auto shard_boundary_token = _partitioner.token_for_next_shard(_range.start() ? _range.start()->value().token() : minimum_token());
    auto shard_boundary = ring_position::starting_at(shard_boundary_token);
    if ((!_range.end() || shard_boundary.less_compare(s, _range.end()->value()))
            && shard_boundary_token != maximum_token()) {
        // split the range at end_of_shard
        auto start = _range.start();
        auto end = range_bound<ring_position>(shard_boundary, false);
        _range = nonwrapping_range<ring_position>(
                range_bound<ring_position>(std::move(shard_boundary), true),
                std::move(_range.end()));
        return ring_position_range_and_shard{nonwrapping_range<ring_position>(std::move(start), std::move(end)), shard};
    }
    _done = true;
    return ring_position_range_and_shard{std::move(_range), shard};
}

ring_position_range_vector_sharder::ring_position_range_vector_sharder(std::vector<nonwrapping_range<ring_position>> ranges)
        : _ranges(std::move(ranges))
        , _current_range(_ranges.begin()) {
    next_range();
}

stdx::optional<ring_position_range_and_shard>
ring_position_range_vector_sharder::next(const schema& s) {
    if (!_current_sharder) {
        return stdx::nullopt;
    }
    auto ret = _current_sharder->next(s);
    while (!ret && _current_range != _ranges.end()) {
        next_range();
        ret = _current_sharder->next(s);
    }
    return ret;
}

int ring_position_comparator::operator()(const ring_position& lh, const ring_position& rh) const {
    return lh.tri_compare(s, rh);
}

int token_comparator::operator()(const token& t1, const token& t2) const {
    return tri_compare(t1, t2);
}

bool ring_position::equal(const schema& s, const ring_position& other) const {
    return tri_compare(s, other) == 0;
}

bool ring_position::less_compare(const schema& s, const ring_position& other) const {
    return tri_compare(s, other) < 0;
}

int ring_position::tri_compare(const schema& s, const ring_position& o) const {
    if (_token != o._token) {
        return _token < o._token ? -1 : 1;
    }

    if (_key && o._key) {
        return _key->legacy_tri_compare(s, *o._key);
    }

    if (!_key && !o._key) {
        return relation_to_keys() - o.relation_to_keys();
    } else if (!_key) {
        return relation_to_keys();
    } else {
        return -o.relation_to_keys();
    }
}

nonwrapping_range<ring_position>
to_partition_range(nonwrapping_range<dht::token> r) {
    using bound_opt = std::experimental::optional<nonwrapping_range<ring_position>::bound>;
    auto start = r.start()
                 ? bound_opt(dht::ring_position(r.start()->value(),
                                                r.start()->is_inclusive()
                                                ? dht::ring_position::token_bound::start
                                                : dht::ring_position::token_bound::end))
                 : bound_opt();

    auto end = r.end()
               ? bound_opt(dht::ring_position(r.end()->value(),
                                              r.end()->is_inclusive()
                                              ? dht::ring_position::token_bound::end
                                              : dht::ring_position::token_bound::start))
               : bound_opt();

    return { std::move(start), std::move(end) };
}

}
<commit_msg>dht: Make i_partitioner::tri_compare memory safe<commit_after>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "i_partitioner.hh"
#include "core/reactor.hh"
#include "murmur3_partitioner.hh"
#include "utils/class_registrator.hh"
#include "types.hh"
#include <boost/range/adaptor/map.hpp>

namespace dht {

token
minimum_token() {
    return { token::kind::before_all_keys, {} };
}

token
maximum_token() {
    return { token::kind::after_all_keys, {} };
}

// result + overflow bit
std::pair<bytes, bool>
add_bytes(bytes_view b1, bytes_view b2, bool carry = false) {
    auto sz = std::max(b1.size(), b2.size());
    auto expand = [sz] (bytes_view b) {
        bytes ret(bytes::initialized_later(), sz);
        auto bsz = b.size();
        auto p = std::copy(b.begin(), b.end(), ret.begin());
        std::fill_n(p, sz - bsz, 0);
        return ret;
    };
    auto eb1 = expand(b1);
    auto eb2 = expand(b2);
    auto p1 = eb1.begin();
    auto p2 = eb2.begin();
    unsigned tmp = carry;
    for (size_t idx = 0; idx < sz; ++idx) {
        tmp += uint8_t(p1[sz - idx - 1]);
        tmp += uint8_t(p2[sz - idx - 1]);
        p1[sz - idx - 1] = tmp;
        tmp >>= std::numeric_limits<uint8_t>::digits;
    }
    return { std::move(eb1), bool(tmp) };
}

bytes
shift_right(bool carry, bytes b) {
    unsigned tmp = carry;
    auto sz = b.size();
    auto p = b.begin();
    for (size_t i = 0; i < sz; ++i) {
        auto lsb = p[i] & 1;
        p[i] = (tmp << std::numeric_limits<uint8_t>::digits) | uint8_t(p[i]) >> 1;
        tmp = lsb;
    }
    return b;
}

token
midpoint_unsigned_tokens(const token& t1, const token& t2) {
    // calculate the average of the two tokens.
    // before_all_keys is implicit 0, after_all_keys is implicit 1.
    bool c1 = t1._kind == token::kind::after_all_keys;
    bool c2 = t1._kind == token::kind::after_all_keys;
    if (c1 && c2) {
        // both end-of-range tokens?
        return t1;
    }
    // we can ignore beginning-of-range, since their representation is 0.0
    auto sum_carry = add_bytes(t1._data, t2._data);
    auto& sum = sum_carry.first;
    // if either was end-of-range, we added 0.0, so pretend we added 1.0 and
    // and got a carry:
    bool carry = sum_carry.second || c1 || c2;
    auto avg = shift_right(carry, std::move(sum));
    if (t1 > t2) {
        // wrap around the ring.  We really want (t1 + (t2 + 1.0)) / 2, so add 0.5.
        // example: midpoint(0.9, 0.2) == midpoint(0.9, 1.2) == 1.05 == 0.05
        //                             == (0.9 + 0.2) / 2 + 0.5 (mod 1)
        if (avg.size() > 0) {
            avg[0] ^= 0x80;
        }
    }
    return token{token::kind::key, std::move(avg)};
}

static inline unsigned char get_byte(bytes_view b, size_t off) {
    if (off < b.size()) {
        return b[off];
    } else {
        return 0;
    }
}

int i_partitioner::tri_compare(const token& t1, const token& t2) const {
    size_t sz = std::min(t1._data.size(), t2._data.size());

    for (size_t i = 0; i < sz; i++) {
        auto b1 = get_byte(t1._data, i);
        auto b2 = get_byte(t2._data, i);
        if (b1 < b2) {
            return -1;
        } else if (b1 > b2) {
            return 1;
        }
    }
    return 0;
}

int tri_compare(const token& t1, const token& t2) {
    if (t1._kind == t2._kind) {
        return global_partitioner().tri_compare(t1, t2);
    } else if (t1._kind < t2._kind) {
        return -1;
    }
    return 1;
}

bool operator==(const token& t1, const token& t2)
{
    if (t1._kind != t2._kind) {
        return false;
    } else if (t1._kind == token::kind::key) {
        return global_partitioner().is_equal(t1, t2);
    }
    return true;
}

bool operator<(const token& t1, const token& t2)
{
    if (t1._kind < t2._kind) {
        return true;
    } else if (t1._kind == token::kind::key && t2._kind == token::kind::key) {
        return global_partitioner().is_less(t1, t2);
    }
    return false;
}

std::ostream& operator<<(std::ostream& out, const token& t) {
    if (t._kind == token::kind::after_all_keys) {
        out << "maximum token";
    } else if (t._kind == token::kind::before_all_keys) {
        out << "minimum token";
    } else {
        out << global_partitioner().to_sstring(t);
    }
    return out;
}

std::ostream& operator<<(std::ostream& out, const decorated_key& dk) {
    return out << "{key: " << dk._key << ", token:" << dk._token << "}";
}

// FIXME: make it per-keyspace
std::unique_ptr<i_partitioner> default_partitioner { new murmur3_partitioner };

void set_global_partitioner(const sstring& class_name, unsigned ignore_msb)
{
    try {
        default_partitioner = create_object<i_partitioner, const unsigned&, const unsigned&>(class_name, smp::count, ignore_msb);
    } catch (std::exception& e) {
        auto supported_partitioners = ::join(", ", class_registry<i_partitioner>::classes() |
                boost::adaptors::map_keys);
        throw std::runtime_error(sprint("Partitioner %s is not supported, supported partitioners = { %s } : %s",
                class_name, supported_partitioners, e.what()));
    }
}

i_partitioner&
global_partitioner() {
    return *default_partitioner;
}

bool
decorated_key::equal(const schema& s, const decorated_key& other) const {
    if (_token == other._token) {
        return _key.legacy_equal(s, other._key);
    }
    return false;
}

int
decorated_key::tri_compare(const schema& s, const decorated_key& other) const {
    auto r = dht::tri_compare(_token, other._token);
    if (r != 0) {
        return r;
    } else {
        return _key.legacy_tri_compare(s, other._key);
    }
}

int
decorated_key::tri_compare(const schema& s, const ring_position& other) const {
    auto r = dht::tri_compare(_token, other.token());
    if (r != 0) {
        return r;
    } else if (other.has_key()) {
        return _key.legacy_tri_compare(s, *other.key());
    }
    return -other.relation_to_keys();
}

bool
decorated_key::less_compare(const schema& s, const ring_position& other) const {
    return tri_compare(s, other) < 0;
}

bool
decorated_key::less_compare(const schema& s, const decorated_key& other) const {
    return tri_compare(s, other) < 0;
}

decorated_key::less_comparator::less_comparator(schema_ptr s)
    : s(std::move(s))
{ }

bool
decorated_key::less_comparator::operator()(const decorated_key& lhs, const decorated_key& rhs) const {
    return lhs.less_compare(*s, rhs);
}

bool
decorated_key::less_comparator::operator()(const ring_position& lhs, const decorated_key& rhs) const {
    return rhs.tri_compare(*s, lhs) > 0;
}

bool
decorated_key::less_comparator::operator()(const decorated_key& lhs, const ring_position& rhs) const {
    return lhs.tri_compare(*s, rhs) < 0;
}

std::ostream& operator<<(std::ostream& out, const ring_position& pos) {
    out << "{" << pos.token();
    if (pos.has_key()) {
        out << ", " << *pos.key();
    } else {
        out << ", " << ((pos.relation_to_keys() < 0) ? "start" : "end");
    }
    return out << "}";
}

unsigned shard_of(const token& t) {
    return global_partitioner().shard_of(t);
}

stdx::optional<ring_position_range_and_shard>
ring_position_range_sharder::next(const schema& s) {
    if (_done) {
        return {};
    }
    auto shard = _range.start() ? shard_of(_range.start()->value().token()) : global_partitioner().shard_of_minimum_token();
    auto shard_boundary_token = _partitioner.token_for_next_shard(_range.start() ? _range.start()->value().token() : minimum_token());
    auto shard_boundary = ring_position::starting_at(shard_boundary_token);
    if ((!_range.end() || shard_boundary.less_compare(s, _range.end()->value()))
            && shard_boundary_token != maximum_token()) {
        // split the range at end_of_shard
        auto start = _range.start();
        auto end = range_bound<ring_position>(shard_boundary, false);
        _range = nonwrapping_range<ring_position>(
                range_bound<ring_position>(std::move(shard_boundary), true),
                std::move(_range.end()));
        return ring_position_range_and_shard{nonwrapping_range<ring_position>(std::move(start), std::move(end)), shard};
    }
    _done = true;
    return ring_position_range_and_shard{std::move(_range), shard};
}

ring_position_range_vector_sharder::ring_position_range_vector_sharder(std::vector<nonwrapping_range<ring_position>> ranges)
        : _ranges(std::move(ranges))
        , _current_range(_ranges.begin()) {
    next_range();
}

stdx::optional<ring_position_range_and_shard>
ring_position_range_vector_sharder::next(const schema& s) {
    if (!_current_sharder) {
        return stdx::nullopt;
    }
    auto ret = _current_sharder->next(s);
    while (!ret && _current_range != _ranges.end()) {
        next_range();
        ret = _current_sharder->next(s);
    }
    return ret;
}

int ring_position_comparator::operator()(const ring_position& lh, const ring_position& rh) const {
    return lh.tri_compare(s, rh);
}

int token_comparator::operator()(const token& t1, const token& t2) const {
    return tri_compare(t1, t2);
}

bool ring_position::equal(const schema& s, const ring_position& other) const {
    return tri_compare(s, other) == 0;
}

bool ring_position::less_compare(const schema& s, const ring_position& other) const {
    return tri_compare(s, other) < 0;
}

int ring_position::tri_compare(const schema& s, const ring_position& o) const {
    if (_token != o._token) {
        return _token < o._token ? -1 : 1;
    }

    if (_key && o._key) {
        return _key->legacy_tri_compare(s, *o._key);
    }

    if (!_key && !o._key) {
        return relation_to_keys() - o.relation_to_keys();
    } else if (!_key) {
        return relation_to_keys();
    } else {
        return -o.relation_to_keys();
    }
}

nonwrapping_range<ring_position>
to_partition_range(nonwrapping_range<dht::token> r) {
    using bound_opt = std::experimental::optional<nonwrapping_range<ring_position>::bound>;
    auto start = r.start()
                 ? bound_opt(dht::ring_position(r.start()->value(),
                                                r.start()->is_inclusive()
                                                ? dht::ring_position::token_bound::start
                                                : dht::ring_position::token_bound::end))
                 : bound_opt();

    auto end = r.end()
               ? bound_opt(dht::ring_position(r.end()->value(),
                                              r.end()->is_inclusive()
                                              ? dht::ring_position::token_bound::end
                                              : dht::ring_position::token_bound::start))
               : bound_opt();

    return { std::move(start), std::move(end) };
}

}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Modified by Cloudius Systems
 * Copyright 2015 Cloudius Systems
 */

#pragma once

#include "core/shared_ptr.hh"
#include "types.hh"
#include "keys.hh"
#include "sstables/key.hh"
#include <memory>
#include <random>

namespace dht {

//
// Origin uses a complex class hierarchy where Token is an abstract class,
// and various subclasses use different implementations (LongToken vs.
// BigIntegerToken vs. StringToken), plus other variants to to signify the
// the beginning of the token space etc.
//
// We'll fold all of that into the token class and push all of the variations
// into its users.

class decorated_key;
class token;

class token {
public:
    enum class kind {
        before_all_keys,
        key,
        after_all_keys,
    };
    kind _kind;
    // _data can be interpreted as a big endian binary fraction
    // in the range [0.0, 1.0).
    //
    // So, [] == 0.0
    //     [0x00] == 0.0
    //     [0x80] == 0.5
    //     [0x00, 0x80] == 1/512
    //     [0xff, 0x80] == 1 - 1/512
    bytes _data;
};

token midpoint(const token& t1, const token& t2);
token minimum_token();
token maximum_token();
bool operator==(const token& t1, const token& t2);
bool operator<(const token& t1, const token& t2);
std::ostream& operator<<(std::ostream& out, const token& t);

template <typename T>
inline auto get_random_number() {
    static thread_local std::random_device rd;
    static thread_local std::default_random_engine re(rd());
    static thread_local std::uniform_int_distribution<T> dist{};
    return dist(re);
}

// Wraps partition_key with its corresponding token.
//
// Total ordering defined by comparators is compatible with Origin's ordering.
class decorated_key {
public:
    token _token;
    partition_key _key;

    struct less_comparator {
        schema_ptr s;
        less_comparator(schema_ptr s);
        bool operator()(const decorated_key& k1, const decorated_key& k2) const;
    };

    bool equal(const schema& s, const decorated_key& other) const;

    bool less_compare(const schema& s, const decorated_key& other) const;

    int tri_compare(const schema& s, const decorated_key& other) const;
};

class i_partitioner {
public:
    virtual ~i_partitioner() {}
    /**
     * Transform key to object representation of the on-disk format.
     *
     * @param key the raw, client-facing key
     * @return decorated version of key
     */
    decorated_key decorate_key(const schema& s, const partition_key& key) {
        return { get_token(s, key), key };
    }

    /**
     * Transform key to object representation of the on-disk format.
     *
     * @param key the raw, client-facing key
     * @return decorated version of key
     */
    decorated_key decorate_key(const schema& s, partition_key&& key) {
        auto token = get_token(s, key);
        return { std::move(token), std::move(key) };
    }

    /**
     * Calculate a token representing the approximate "middle" of the given
     * range.
     *
     * @return The approximate midpoint between left and right.
     */
    token midpoint(const token& left, const token& right) {
        return dht::midpoint(left, right);
    }

    /**
     * @return A token smaller than all others in the range that is being partitioned.
     * Not legal to assign to a node or key.  (But legal to use in range scans.)
     */
    token get_minimum_token() {
        return dht::minimum_token();
    }

    /**
     * @return a token that can be used to route a given key
     * (This is NOT a method to create a token from its string representation;
     * for that, use tokenFactory.fromString.)
     */
    virtual token get_token(const schema& s, partition_key_view key) = 0;
    virtual token get_token(const sstables::key_view& key) = 0;

    /**
     * @return a randomly generated token
     */
    virtual token get_random_token() = 0;

    // FIXME: token.tokenFactory
    //virtual token.tokenFactory gettokenFactory() = 0;

    /**
     * @return True if the implementing class preserves key order in the tokens
     * it generates.
     */
    virtual bool preserves_order() = 0;

    /**
     * Calculate the deltas between tokens in the ring in order to compare
     *  relative sizes.
     *
     * @param sortedtokens a sorted List of tokens
     * @return the mapping from 'token' to 'percentage of the ring owned by that token'.
     */
    virtual std::map<token, float> describe_ownership(const std::vector<token>& sorted_tokens) = 0;

    virtual data_type get_token_validator() = 0;

protected:
    /**
     * @return true if t1's _data array is equal t2's. _kind comparison should be done separately.
     */
    virtual bool is_equal(const token& t1, const token& t2);
    /**
     * @return true if t1's _data array is less then t2's. _kind comparison should be done separately.
     */
    virtual bool is_less(const token& t1, const token& t2);

    friend bool operator==(const token& t1, const token& t2);
    friend bool operator<(const token& t1, const token& t2);
};

std::ostream& operator<<(std::ostream& out, const token& t);

std::ostream& operator<<(std::ostream& out, const decorated_key& t);

i_partitioner& global_partitioner();

} // dht

namespace std {
template<>
struct hash<dht::token> {
    size_t operator()(const dht::token& t) const {
        return (t._kind == dht::token::kind::key) ? std::hash<bytes>()(t._data) : 0;
    }
};
}
<commit_msg>token: Add constructor token(kind, bytes)<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Modified by Cloudius Systems
 * Copyright 2015 Cloudius Systems
 */

#pragma once

#include "core/shared_ptr.hh"
#include "types.hh"
#include "keys.hh"
#include "sstables/key.hh"
#include <memory>
#include <random>

namespace dht {

//
// Origin uses a complex class hierarchy where Token is an abstract class,
// and various subclasses use different implementations (LongToken vs.
// BigIntegerToken vs. StringToken), plus other variants to to signify the
// the beginning of the token space etc.
//
// We'll fold all of that into the token class and push all of the variations
// into its users.

class decorated_key;
class token;

class token {
public:
    enum class kind {
        before_all_keys,
        key,
        after_all_keys,
    };
    kind _kind;
    // _data can be interpreted as a big endian binary fraction
    // in the range [0.0, 1.0).
    //
    // So, [] == 0.0
    //     [0x00] == 0.0
    //     [0x80] == 0.5
    //     [0x00, 0x80] == 1/512
    //     [0xff, 0x80] == 1 - 1/512
    bytes _data;
    token(kind k, bytes d) : _kind(k), _data(d) {
    }
};

token midpoint(const token& t1, const token& t2);
token minimum_token();
token maximum_token();
bool operator==(const token& t1, const token& t2);
bool operator<(const token& t1, const token& t2);
std::ostream& operator<<(std::ostream& out, const token& t);

template <typename T>
inline auto get_random_number() {
    static thread_local std::random_device rd;
    static thread_local std::default_random_engine re(rd());
    static thread_local std::uniform_int_distribution<T> dist{};
    return dist(re);
}

// Wraps partition_key with its corresponding token.
//
// Total ordering defined by comparators is compatible with Origin's ordering.
class decorated_key {
public:
    token _token;
    partition_key _key;

    struct less_comparator {
        schema_ptr s;
        less_comparator(schema_ptr s);
        bool operator()(const decorated_key& k1, const decorated_key& k2) const;
    };

    bool equal(const schema& s, const decorated_key& other) const;

    bool less_compare(const schema& s, const decorated_key& other) const;

    int tri_compare(const schema& s, const decorated_key& other) const;
};

class i_partitioner {
public:
    virtual ~i_partitioner() {}
    /**
     * Transform key to object representation of the on-disk format.
     *
     * @param key the raw, client-facing key
     * @return decorated version of key
     */
    decorated_key decorate_key(const schema& s, const partition_key& key) {
        return { get_token(s, key), key };
    }

    /**
     * Transform key to object representation of the on-disk format.
     *
     * @param key the raw, client-facing key
     * @return decorated version of key
     */
    decorated_key decorate_key(const schema& s, partition_key&& key) {
        auto token = get_token(s, key);
        return { std::move(token), std::move(key) };
    }

    /**
     * Calculate a token representing the approximate "middle" of the given
     * range.
     *
     * @return The approximate midpoint between left and right.
     */
    token midpoint(const token& left, const token& right) {
        return dht::midpoint(left, right);
    }

    /**
     * @return A token smaller than all others in the range that is being partitioned.
     * Not legal to assign to a node or key.  (But legal to use in range scans.)
     */
    token get_minimum_token() {
        return dht::minimum_token();
    }

    /**
     * @return a token that can be used to route a given key
     * (This is NOT a method to create a token from its string representation;
     * for that, use tokenFactory.fromString.)
     */
    virtual token get_token(const schema& s, partition_key_view key) = 0;
    virtual token get_token(const sstables::key_view& key) = 0;

    /**
     * @return a randomly generated token
     */
    virtual token get_random_token() = 0;

    // FIXME: token.tokenFactory
    //virtual token.tokenFactory gettokenFactory() = 0;

    /**
     * @return True if the implementing class preserves key order in the tokens
     * it generates.
     */
    virtual bool preserves_order() = 0;

    /**
     * Calculate the deltas between tokens in the ring in order to compare
     *  relative sizes.
     *
     * @param sortedtokens a sorted List of tokens
     * @return the mapping from 'token' to 'percentage of the ring owned by that token'.
     */
    virtual std::map<token, float> describe_ownership(const std::vector<token>& sorted_tokens) = 0;

    virtual data_type get_token_validator() = 0;

protected:
    /**
     * @return true if t1's _data array is equal t2's. _kind comparison should be done separately.
     */
    virtual bool is_equal(const token& t1, const token& t2);
    /**
     * @return true if t1's _data array is less then t2's. _kind comparison should be done separately.
     */
    virtual bool is_less(const token& t1, const token& t2);

    friend bool operator==(const token& t1, const token& t2);
    friend bool operator<(const token& t1, const token& t2);
};

std::ostream& operator<<(std::ostream& out, const token& t);

std::ostream& operator<<(std::ostream& out, const decorated_key& t);

i_partitioner& global_partitioner();

} // dht

namespace std {
template<>
struct hash<dht::token> {
    size_t operator()(const dht::token& t) const {
        return (t._kind == dht::token::kind::key) ? std::hash<bytes>()(t._data) : 0;
    }
};
}
<|endoftext|>


<commit_before>// $Id: surface.C,v 1.5 2000/05/15 19:19:50 oliver Exp $

#include <BALL/MATHS/surface.h>

using namespace std;

namespace BALL
{

	Surface::Surface()
		:	valid_(false)
	{
	}

	Surface::Surface(const Surface& /* surface */)
	{
		// BAUSTELLE
	}

	Surface::~Surface()
	{
	}

	Size Surface::getNumberOfVertices() const
	{
		return vertices_.size();
	}

	Size Surface::getNumberOfTriangles() const
	{
		return triangles_.size();
	}

	void Surface::smoothNormals()
	{
		if (valid_ == false)
		{
			return;
		}

		Size i;
		// clear all normals
		for (i = 0; i < normals_.size(); i++)
		{
			normals_[i].set(0.0);
		}

		// iterate over all triangles, calculate their normals
		// and add them to the vertices` normals
		for (i = 0; i < triangles_.size(); i++)
		{
			Vector3 v1 = vertices_[triangles_[i].v1];
			Vector3 v2 = vertices_[triangles_[i].v2];
			Vector3 v3 = vertices_[triangles_[i].v3];
			Vector3 normal = (v2 - v1) % (v3 - v1);
			normal.normalize();
			normals_[triangles_[i].v1] += normal;
			normals_[triangles_[i].v2] += normal;
			normals_[triangles_[i].v3] += normal;
		}

		// iterate over all normals and normalize them
		for (i = 0; i < normals_.size(); ++i)
		{
			normals_[i].normalize();
		}
	}

	void Surface::readMSMSFile(const String& vert_filename, const String& face_filename)
	{
		// delete old contents
		normals_.clear();
		vertices_.clear();
		triangles_.clear();

		ifstream file(vert_filename.c_str());
		if (!file)
		{
			throw Exception::FileNotFound(__FILE__, __LINE__, vert_filename);
		}

		// there are two formats: one with three lines of
		// header and one without
		String line;
		while ((line.countFields() != 9) && file)
		{
			line.getline(file);
		}

		String s[6];
		while (file && (line.countFields() == 9))
		{
			// read the vertex coordinates and the normal vector
			line.split(s, 6);
			vertices_.push_back(Vector3(s[0].toFloat(), s[1].toFloat(), s[2].toFloat()));
			normals_.push_back(Vector3(s[3].toFloat(), s[4].toFloat(), s[5].toFloat()));

			// read the next line
			line.getline(file);
		}
		file.close();
		// workaround for trouble in File
		file.clear();

		// now read the faces file:
		file.open(face_filename.c_str());
		if (!file)
		{
			throw Exception::FileNotFound(__FILE__, __LINE__, face_filename);
		}

		// there are two formats: one with three lines of
		// header and one without
		while ((line.countFields() != 5) && file)
		{
			line.getline(file);
		}

		Triangle t;
		Size number_of_vertices = vertices_.size();
		while (file && (line.countFields() == 5))
		{
			// read the vertex indices
			line.split(s, 5);
			t.v1 = (Index)s[0].toInt() - 1;
			t.v2 = (Index)s[1].toInt() - 1;
			t.v3 = (Index)s[2].toInt() - 1;

			// if all three vertex indices are valid, insert the triangle
			if ((t.v1 < (Index)number_of_vertices) && (t.v1 >= 0)
					&& (t.v1 < (Index)number_of_vertices) && (t.v1 >= 0)
					&& (t.v1 < (Index)number_of_vertices) && (t.v1 >= 0))
			{
				triangles_.push_back(t);
			}

			// read the next line
			line.getline(file);
		}
		file.close();
	}

	float Surface::getVolume() const
	{
		// BAUSTELLE
		return 0;
	}

	float Surface::getArea() const
	{
		float area = 0;
		// add the areas of all triangles
		for (Size i = 0; i < triangles_.size(); i++)
		{
			//Vector3 v1 = vertices_[triangles_[i].v1];
			//Vector3 v2 = vertices_[triangles_[i].v2];
			//Vector3 v3 = vertices_[triangles_[i].v3];

			// projection of v3 onto v1-v2
			//Vector3	v4 =
			// BAUSTELLE
		}

		return area;
	}

	Surface::Triangle Surface::triangle(Size index) const
	{
		return triangles_[index];
	}

	Vector3 Surface::vertex(Size index) const
	{
		return vertices_[index];
	}

	Vector3 Surface::normal(Size index) const
	{
		return normals_[index];
	}

} // namespace BALL
<commit_msg>changed: attributes are now public, some methods removed<commit_after>// $Id: surface.C,v 1.6 2000/06/02 07:12:41 oliver Exp $

#include <BALL/MATHS/surface.h>

using namespace std;

namespace BALL
{

	Surface::Surface()
		:	valid_(false)
	{
	}

	Surface::Surface(const Surface& surface)
		:	vertex(surface.vertex),
			normal(surface.normal),
			triangle(surface.triangle),
			valid_(surface.valid_)
	{
	}

	Surface::~Surface()
	{
		valid_ = false;
	}

	void Surface::clear()
	{
		valid_ = true;
		vertex.clear();
		normal.clear();
		triangle.clear();
	}

	void Surface::destroy()
	{
		clear();
	}

	void Surface::readMSMSFile
		(const String& vert_filename, const String& face_filename)
	{
		// delete old contents
		normal.clear();
		vertex.clear();
		triangle.clear();

		ifstream file(vert_filename.c_str());
		if (!file)
		{
			throw Exception::FileNotFound(__FILE__, __LINE__, vert_filename);
		}

		// there are two formats: one with three lines of
		// header and one without
		String line;
		while ((line.countFields() != 9) && file)
		{
			line.getline(file);
		}

		String s[6];
		while (file && (line.countFields() == 9))
		{
			// read the vertex coordinates and the normal vector
			line.split(s, 6);
			vertex.push_back(Vector3(s[0].toFloat(), s[1].toFloat(), s[2].toFloat()));
			normal.push_back(Vector3(s[3].toFloat(), s[4].toFloat(), s[5].toFloat()));

			// read the next line
			line.getline(file);
		}
		file.close();
		// workaround for trouble in File
		file.clear();

		// now read the faces file:
		file.open(face_filename.c_str());
		if (!file)
		{
			throw Exception::FileNotFound(__FILE__, __LINE__, face_filename);
		}

		// there are two formats: one with three lines of
		// header and one without
		while ((line.countFields() != 5) && file)
		{
			line.getline(file);
		}

		Triangle t;
		Size number_of_vertices = vertex.size();
		while (file && (line.countFields() == 5))
		{
			// read the vertex indices
			line.split(s, 5);
			t.v1 = (Index)s[0].toInt() - 1;
			t.v2 = (Index)s[1].toInt() - 1;
			t.v3 = (Index)s[2].toInt() - 1;

			// if all three vertex indices are valid, insert the triangle
			if ((t.v1 < (Index)number_of_vertices) && (t.v1 >= 0)
					&& (t.v1 < (Index)number_of_vertices) && (t.v1 >= 0)
					&& (t.v1 < (Index)number_of_vertices) && (t.v1 >= 0))
			{
				triangle.push_back(t);
			}

			// read the next line
			line.getline(file);
		}
		file.close();
	}

	float Surface::getArea() const
	{
		float area = 0;
		// add the areas of all triangles
		for (Size i = 0; i < triangle.size(); i++)
		{
			//Vector3 v1 = vertex[triangle[i].v1];
			//Vector3 v2 = vertex[triangle[i].v2];
			//Vector3 v3 = vertex[triangle[i].v3];

			// projection of v3 onto v1-v2
			//Vector3	v4 =
			// BAUSTELLE
		}

		return area;
	}

} // namespace BALL
<|endoftext|>


<commit_before>#pragma once
#include "stdafx.h"

#define SafeDelete(x) {if((x) != nullptr) { delete (x); } x = nullptr; }
#define SafeDeleteArray(x) {if((x) != nullptr) { delete[] (x); } x = nullptr; }

namespace MUtil
{
	namespace Gen
	{
		static std::string ReadWholeFile(const std::string& path)
		{
			std::ifstream in(path);
			return std::string(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>());
		}

		static std::wstring StrToWStr(const std::string& str)
		{
			using convert_typeX = std::codecvt_utf8<wchar_t>;
			std::wstring_convert<convert_typeX, wchar_t> converterX;

			return converterX.from_bytes(str);
		}

		static std::string WStrToStr(const std::wstring& wstr)
		{
			using convert_typeX = std::codecvt_utf8<wchar_t>;
			std::wstring_convert<convert_typeX, wchar_t> converterX;

			return converterX.to_bytes(wstr);
		}
	}

	namespace CL
	{
		static unsigned int INVALID_OBJECT = 0xFFFFFFFF;
		static const wcahr_t* INVALID_NAME = L"[INVALID]";

		static const char* MapErrorToString(cl_int error)
		{
			static const char* errorString[] = {
				"CL_SUCCESS",
				"CL_DEVICE_NOT_FOUND",
				"CL_DEVICE_NOT_AVAILABLE",
				"CL_COMPILER_NOT_AVAILABLE",
				"CL_MEM_OBJECT_ALLOCATION_FAILURE",
				"CL_OUT_OF_RESOURCES",
				"CL_OUT_OF_HOST_MEMORY",
				"CL_PROFILING_INFO_NOT_AVAILABLE",
				"CL_MEM_COPY_OVERLAP",
				"CL_IMAGE_FORMAT_MISMATCH",
				"CL_IMAGE_FORMAT_NOT_SUPPORTED",
				"CL_BUILD_PROGRAM_FAILURE",
				"CL_MAP_FAILURE",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"CL_INVALID_VALUE",
				"CL_INVALID_DEVICE_TYPE",
				"CL_INVALID_PLATFORM",
				"CL_INVALID_DEVICE",
				"CL_INVALID_CONTEXT",
				"CL_INVALID_QUEUE_PROPERTIES",
				"CL_INVALID_COMMAND_QUEUE",
				"CL_INVALID_HOST_PTR",
				"CL_INVALID_MEM_OBJECT - EX: WRONG R/W RIGHTS? WRONG STORAGE CLASS? WRONG ARG INDEX?",
				"CL_INVALID_IMAGE_FORMAT_DESCRIPTOR",
				"CL_INVALID_IMAGE_SIZE",
				"CL_INVALID_SAMPLER",
				"CL_INVALID_BINARY",
				"CL_INVALID_BUILD_OPTIONS",
				"CL_INVALID_PROGRAM",
				"CL_INVALID_PROGRAM_EXECUTABLE",
				"CL_INVALID_KERNEL_NAME",
				"CL_INVALID_KERNEL_DEFINITION",
				"CL_INVALID_KERNEL",
				"CL_INVALID_ARG_INDEX",
				"CL_INVALID_ARG_VALUE",
				"CL_INVALID_ARG_SIZE",
				"CL_INVALID_KERNEL_ARGS",
				"CL_INVALID_WORK_DIMENSION",
				"CL_INVALID_WORK_GROUP_SIZE",
				"CL_INVALID_WORK_ITEM_SIZE",
				"CL_INVALID_GLOBAL_OFFSET",
				"CL_INVALID_EVENT_WAIT_LIST",
				"CL_INVALID_EVENT",
				"CL_INVALID_OPERATION",
				"CL_INVALID_GL_OBJECT",
				"CL_INVALID_BUFFER_SIZE",
				"CL_INVALID_MIP_LEVEL",
				"CL_INVALID_GLOBAL_WORK_SIZE",
			};

			const int errorCount = sizeof(errorString) / sizeof(errorString[0]);

			const int index = -error;

			return (index >= 0 && index < errorCount) ? errorString[index] : "";
		}

		static bool ResultCheck(const cl_int val)
		{
			if (val != CL_SUCCESS)
			{
				std::string s;
				s.append("\OpenCL Error -> ");
				s.append(MapErrorToString(val));
				s.append("\n\n");
				std::wcout << s.c_str();
				return true;
			}
			return false;
		}

		static size_t RoundUpToWGSize(int value, int wgSize)
		{
			int remaining = value % wgSize;
			return value + (remaining == 0 ? 0 : (wgSize - remaining));
		}

		class CLImage2D
		{
		private:
			cl_mem mMemObject; // OpenCL image memory object
			std::wstring mName; // Readable name of the image object
			cl_image_format mFormat; // OpenCL image format
			cl_image_desc mDescr; // OpenCL image descriptor

		public:
			// Initializes the object with invalid values
			CLImage2D()
				: mMemObject(INVALID_OBJECT),
					mName(INVALID_NAME)
			{
			}

			// Creates the OpenCL image object and initializes internal variables. Throws and exception if failed.
			void Initialize(cl_context clContext, const std::wstring& name, size_t w, size_t h, size_t rowPitch, cl_channel_order channelOrder, cl_channel_type channelType)
			{
				mName = name;
				mFormat.image_channel_order = channelOrder;
				mFormat.image_channel_data_type = channelType;
				// Fill descriptor here

				// Create object here

			}

			// Returns true if teh object is alread created and returns false if it is not initialized yet.
			bool IsValid() const
			{
				return mMemObject == INVALID_OBJECT ? false : true;
			}

			// Returns the internal cl_mem object
			cl_mem getMemObject() const
			{
				return mMemObject;
			}

			// Returns the name of the image object
			std::wstring getName() const
			{
				return mName;
			}

			// Returns the format of the image
			cl_image_format getFormat() const
			{
				return mFormat;
			}

			// Returns the description of the image
			cl_image_desc getDescription() const
			{
				return mDescr;
			}
		}
	}
}
<commit_msg>Update MCL_Utility.hpp<commit_after>#pragma once
#include "stdafx.h"

#define SafeDelete(x) {if((x) != nullptr) { delete (x); } x = nullptr; }
#define SafeDeleteArray(x) {if((x) != nullptr) { delete[] (x); } x = nullptr; }
#define SafeReleaseClMemObject(x) {if((x) != MUtil::CL::INVALID_OBJECT) { clReleaseMemObject(x); x =  MUtil::CL::INVALID_OBJECT; } }

typedef sf::Image SFImage;
typedef sf::Texture SFTexture;

namespace MUtil
{
	namespace Gen
	{
		static std::string ReadWholeFile(const std::string& path)
		{
			std::ifstream in(path);
			return std::string(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>());
		}

		static std::wstring StrToWStr(const std::string& str)
		{
			using convert_typeX = std::codecvt_utf8<wchar_t>;
			std::wstring_convert<convert_typeX, wchar_t> converterX;

			return converterX.from_bytes(str);
		}

		static std::string WStrToStr(const std::wstring& wstr)
		{
			using convert_typeX = std::codecvt_utf8<wchar_t>;
			std::wstring_convert<convert_typeX, wchar_t> converterX;

			return converterX.to_bytes(wstr);
		}
	}

	namespace CL
	{
		static unsigned int INVALID_OBJECT = 0xFFFFFFFF;
		static const wcahr_t* INVALID_NAME = L"[INVALID]";

		static const char* MapErrorToString(cl_int error)
		{
			static const char* errorString[] = {
				"CL_SUCCESS",
				"CL_DEVICE_NOT_FOUND",
				"CL_DEVICE_NOT_AVAILABLE",
				"CL_COMPILER_NOT_AVAILABLE",
				"CL_MEM_OBJECT_ALLOCATION_FAILURE",
				"CL_OUT_OF_RESOURCES",
				"CL_OUT_OF_HOST_MEMORY",
				"CL_PROFILING_INFO_NOT_AVAILABLE",
				"CL_MEM_COPY_OVERLAP",
				"CL_IMAGE_FORMAT_MISMATCH",
				"CL_IMAGE_FORMAT_NOT_SUPPORTED",
				"CL_BUILD_PROGRAM_FAILURE",
				"CL_MAP_FAILURE",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"",
				"CL_INVALID_VALUE",
				"CL_INVALID_DEVICE_TYPE",
				"CL_INVALID_PLATFORM",
				"CL_INVALID_DEVICE",
				"CL_INVALID_CONTEXT",
				"CL_INVALID_QUEUE_PROPERTIES",
				"CL_INVALID_COMMAND_QUEUE",
				"CL_INVALID_HOST_PTR",
				"CL_INVALID_MEM_OBJECT - EX: WRONG R/W RIGHTS? WRONG STORAGE CLASS? WRONG ARG INDEX?",
				"CL_INVALID_IMAGE_FORMAT_DESCRIPTOR",
				"CL_INVALID_IMAGE_SIZE",
				"CL_INVALID_SAMPLER",
				"CL_INVALID_BINARY",
				"CL_INVALID_BUILD_OPTIONS",
				"CL_INVALID_PROGRAM",
				"CL_INVALID_PROGRAM_EXECUTABLE",
				"CL_INVALID_KERNEL_NAME",
				"CL_INVALID_KERNEL_DEFINITION",
				"CL_INVALID_KERNEL",
				"CL_INVALID_ARG_INDEX",
				"CL_INVALID_ARG_VALUE",
				"CL_INVALID_ARG_SIZE",
				"CL_INVALID_KERNEL_ARGS",
				"CL_INVALID_WORK_DIMENSION",
				"CL_INVALID_WORK_GROUP_SIZE",
				"CL_INVALID_WORK_ITEM_SIZE",
				"CL_INVALID_GLOBAL_OFFSET",
				"CL_INVALID_EVENT_WAIT_LIST",
				"CL_INVALID_EVENT",
				"CL_INVALID_OPERATION",
				"CL_INVALID_GL_OBJECT",
				"CL_INVALID_BUFFER_SIZE",
				"CL_INVALID_MIP_LEVEL",
				"CL_INVALID_GLOBAL_WORK_SIZE",
			};

			const int errorCount = sizeof(errorString) / sizeof(errorString[0]);

			const int index = -error;

			return (index >= 0 && index < errorCount) ? errorString[index] : "";
		}

		static bool ResultCheck(const cl_int val)
		{
			if (val != CL_SUCCESS)
			{
				std::string s;
				s.append("\OpenCL Error -> ");
				s.append(MapErrorToString(val));
				s.append("\n\n");
				std::wcout << s.c_str();
				return true;
			}
			return false;
		}

		static size_t RoundUpToWGSize(int value, int wgSize)
		{
			int remaining = value % wgSize;
			return value + (remaining == 0 ? 0 : (wgSize - remaining));
		}

		class CLImage2D //RAII, non-copyable
		{
		private:
			cl_mem mMemObject; // OpenCL image memory object
			std::wstring mName; // Readable name of the image object
			cl_image_format mFormat; // OpenCL image format
			cl_image_desc mDescr; // OpenCL image descriptor

		public:
         CLImage2D(const CLImage2D&) = delete;
         CLImage2D& operator=(const CLImage2D&) = delete;

         // Destructor
         ~CLImage2D()
         {
           SafeReleaseClMemObject(mMemObject)
         }

			// Creates the OpenCL image object and initializes internal variables. Throws and exception if failed.
			void CLImage2D(cl_context clContext, const std::wstring& name, size_t w, size_t h, size_t rowPitch, cl_channel_order channelOrder, cl_channel_type channelType)
			{
				mName = name;
				mFormat.image_channel_order = channelOrder;
				mFormat.image_channel_data_type = channelType;
				// Fill descriptor here

				// Create object here

			}

			// Returns true if the object is alread created and returns false if it is not initialized yet.
			bool IsValid() const
			{
				return mMemObject == INVALID_OBJECT ? false : true;
			}

			// Returns the internal cl_mem object
			cl_mem getMemObject() const
			{
				return mMemObject;
			}

			// Returns the name of the image object
			std::wstring getName() const
			{
				return mName;
			}

			// Returns the format of the image
			cl_image_format getFormat() const
			{
				return mFormat;
			}

			// Returns the description of the image
			cl_image_desc getDescription() const
			{
				return mDescr;
			}
		}
	}
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013-2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include "tlib/system.hpp"

int main(int argc, char* argv[]);

extern "C" {

void _start(int argc, char* argv[]) __attribute__((section(".start")));

void _start(int argc, char* argv[]){
    // Call the global constructors, if any
    _init();

    // Execute the main function
    auto code = main(argc, argv);

    // Call the global destructors, if any
    __cxa_finalize();

    // Kill the process with the correct exit code
    exit(code);
}

#define ATEXIT_MAX_FUNCS 32

struct atexit_func_entry_t {
    void (*destructor_func)(void *);
    void *obj_ptr;
    void *dso_handle;
};

atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS];
int __atexit_func_count = 0;

int __cxa_atexit(void (*f)(void *), void *objptr, void *dso){
    if (__atexit_func_count >= ATEXIT_MAX_FUNCS) {
        return -1;
    }

    __atexit_funcs[__atexit_func_count].destructor_func = f;
    __atexit_funcs[__atexit_func_count].obj_ptr = objptr;
    __atexit_funcs[__atexit_func_count].dso_handle = dso;
    __atexit_func_count++;

    return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/
}

void __cxa_finalize(void *f){
    int i = __atexit_func_count;
    if (!f){
        while (i--){
            if (__atexit_funcs[i].destructor_func){
                (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
            }
        }
        return;
    }

    for ( ; i >= 0; --i){
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
        if (__atexit_funcs[i].destructor_func == f){
            (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
            __atexit_funcs[i].destructor_func = 0;
        }
#pragma GCC diagnostic pop
    }
}

} // end of extern C
<commit_msg>Continue runtime support<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013-2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include "tlib/system.hpp"

int main(int argc, char* argv[]);

extern "C" {

void __cxa_finalize(void* f);

void _start(int argc, char* argv[]) __attribute__((section(".start")));

void _start(int argc, char* argv[]){
    // Call the global constructors, if any
    _init();

    // Execute the main function
    auto code = main(argc, argv);

    // Call the global destructors, if any
    __cxa_finalize(nullptr);

    // Kill the process with the correct exit code
    exit(code);
}

#define ATEXIT_MAX_FUNCS 32

struct atexit_func_entry_t {
    void (*destructor_func)(void *);
    void *obj_ptr;
    void *dso_handle;
};

atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS];
int __atexit_func_count = 0;

int __cxa_atexit(void (*f)(void *), void *objptr, void *dso){
    if (__atexit_func_count >= ATEXIT_MAX_FUNCS) {
        return -1;
    }

    __atexit_funcs[__atexit_func_count].destructor_func = f;
    __atexit_funcs[__atexit_func_count].obj_ptr = objptr;
    __atexit_funcs[__atexit_func_count].dso_handle = dso;
    __atexit_func_count++;

    return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/
}

void __cxa_finalize(void* f){
    int i = __atexit_func_count;
    if (!f){
        while (i--){
            if (__atexit_funcs[i].destructor_func){
                (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
            }
        }
        return;
    }

    for ( ; i >= 0; --i){
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
        if (__atexit_funcs[i].destructor_func == f){
            (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
            __atexit_funcs[i].destructor_func = 0;
        }
#pragma GCC diagnostic pop
    }
}

} // end of extern C
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision: 17495 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "QmitkImageNavigatorView.h"

#include "mitkNodePredicateDataType.h"

#include "QmitkDataStorageComboBox.h"
#include "QmitkStdMultiWidget.h"

#include "mitkDataStorageEditorInput.h"

// berry Includes
#include <berryPlatform.h>
#include <berryIWorkbenchPage.h>
#include <berryConstants.h>

#include <QMessageBox>

const std::string QmitkImageNavigatorView::VIEW_ID = "org.mitk.views.imagenavigator";

QmitkImageNavigatorView::QmitkImageNavigatorView()
: m_MultiWidget(NULL)
{
}

QmitkImageNavigatorView::~QmitkImageNavigatorView()
{
  //delete m_TransversalStepper;
  //delete m_SagittalStepper;
  //delete m_FrontalStepper;
  //delete m_TimeStepper;
}

void QmitkImageNavigatorView::CreateQtPartControl(QWidget *parent)
{

  // create GUI widgets
  m_Controls.setupUi(parent);
  m_MultiWidget = this->GetActiveStdMultiWidget();

  m_TransversalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorTransversal, m_MultiWidget->mitkWidget1->GetSliceNavigationController()->GetSlice(), "sliceNavigatorTransversalFromSimpleExample");
  m_SagittalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorSagittal, m_MultiWidget->mitkWidget2->GetSliceNavigationController()->GetSlice(), "sliceNavigatorSagittalFromSimpleExample");
  m_FrontalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorFrontal, m_MultiWidget->mitkWidget3->GetSliceNavigationController()->GetSlice(), "sliceNavigatorFrontalFromSimpleExample");
  m_TimeStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorTime, m_MultiWidget->GetTimeNavigationController()->GetTime(), "sliceNavigatorTimeFromSimpleExample");
}

void QmitkImageNavigatorView::SetFocus ()
{

}

QmitkStdMultiWidget* QmitkImageNavigatorView::GetActiveStdMultiWidget()
{
  QmitkStdMultiWidget* activeStdMultiWidget = 0;
  berry::IEditorPart::Pointer editor =
    this->GetSite()->GetPage()->GetActiveEditor();

  if (editor.Cast<QmitkStdMultiWidgetEditor>().IsNotNull())
  {
    activeStdMultiWidget = editor.Cast<QmitkStdMultiWidgetEditor>()->GetStdMultiWidget();
  }
  else
  {
    mitk::DataStorageEditorInput::Pointer editorInput;
    editorInput = new mitk::DataStorageEditorInput();
    berry::IEditorPart::Pointer editor = this->GetSite()->GetPage()->OpenEditor(editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID);
    activeStdMultiWidget = editor.Cast<QmitkStdMultiWidgetEditor>()->GetStdMultiWidget();
  }

  return activeStdMultiWidget;
}

int QmitkImageNavigatorView::GetSizeFlags(bool width)
{
  if(!width)
  {
    return berry::Constants::MIN | berry::Constants::MAX | berry::Constants::FILL;
  }
  else
  {
    return 0;
  }
}

int QmitkImageNavigatorView::ComputePreferredSize(bool width, int availableParallel, int availablePerpendicular, int preferredResult)
{
  if(width==false)
  {
    return 160;
  }
  else
  {
    return preferredResult;
  }
}

<commit_msg>FIX (#3400): don't focus the multiwidget when opening it (this messes with the restored active part on startup)<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision: 17495 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "QmitkImageNavigatorView.h"

#include "mitkNodePredicateDataType.h"

#include "QmitkDataStorageComboBox.h"
#include "QmitkStdMultiWidget.h"

#include "mitkDataStorageEditorInput.h"

// berry Includes
#include <berryPlatform.h>
#include <berryIWorkbenchPage.h>
#include <berryConstants.h>

#include <QMessageBox>

const std::string QmitkImageNavigatorView::VIEW_ID = "org.mitk.views.imagenavigator";

QmitkImageNavigatorView::QmitkImageNavigatorView()
: m_MultiWidget(NULL)
{
}

QmitkImageNavigatorView::~QmitkImageNavigatorView()
{
  //delete m_TransversalStepper;
  //delete m_SagittalStepper;
  //delete m_FrontalStepper;
  //delete m_TimeStepper;
}

void QmitkImageNavigatorView::CreateQtPartControl(QWidget *parent)
{

  // create GUI widgets
  m_Controls.setupUi(parent);
  m_MultiWidget = this->GetActiveStdMultiWidget();

  m_TransversalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorTransversal, m_MultiWidget->mitkWidget1->GetSliceNavigationController()->GetSlice(), "sliceNavigatorTransversalFromSimpleExample");
  m_SagittalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorSagittal, m_MultiWidget->mitkWidget2->GetSliceNavigationController()->GetSlice(), "sliceNavigatorSagittalFromSimpleExample");
  m_FrontalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorFrontal, m_MultiWidget->mitkWidget3->GetSliceNavigationController()->GetSlice(), "sliceNavigatorFrontalFromSimpleExample");
  m_TimeStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorTime, m_MultiWidget->GetTimeNavigationController()->GetTime(), "sliceNavigatorTimeFromSimpleExample");
}

void QmitkImageNavigatorView::SetFocus ()
{

}

QmitkStdMultiWidget* QmitkImageNavigatorView::GetActiveStdMultiWidget()
{
  QmitkStdMultiWidget* activeStdMultiWidget = 0;
  berry::IEditorPart::Pointer editor =
    this->GetSite()->GetPage()->GetActiveEditor();

  if (editor.Cast<QmitkStdMultiWidgetEditor>().IsNotNull())
  {
    activeStdMultiWidget = editor.Cast<QmitkStdMultiWidgetEditor>()->GetStdMultiWidget();
  }
  else
  {
    mitk::DataStorageEditorInput::Pointer editorInput;
    editorInput = new mitk::DataStorageEditorInput();
    berry::IEditorPart::Pointer editor = this->GetSite()->GetPage()->OpenEditor(editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID, false);
    activeStdMultiWidget = editor.Cast<QmitkStdMultiWidgetEditor>()->GetStdMultiWidget();
  }

  return activeStdMultiWidget;
}

int QmitkImageNavigatorView::GetSizeFlags(bool width)
{
  if(!width)
  {
    return berry::Constants::MIN | berry::Constants::MAX | berry::Constants::FILL;
  }
  else
  {
    return 0;
  }
}

int QmitkImageNavigatorView::ComputePreferredSize(bool width, int availableParallel, int availablePerpendicular, int preferredResult)
{
  if(width==false)
  {
    return 160;
  }
  else
  {
    return preferredResult;
  }
}

<|endoftext|>


<commit_before>#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;

typedef vector<int> vi;

vi divisores(int n) {
    vi d;
    int r = sqrt(n);

    for(int i = 1; i <= r; i++) {
        if(n % i == 0) {
            d.push_back(i);

            if(i != r)
                d.push_back(n / i);
        }
    }
    return d;
}

int main() {
    vi divi = divisores(52132);
    for(int i=0; i<divi.size(); i++)
        printf("%d ", divi[i]);
    printf("\n");
}
<commit_msg>update divisors.cpp<commit_after>#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;

typedef vector<int> vi;

vi divisores(int n) {
    vi d;
    int r = ceil(sqrt(n));

    for(int i = 1; i < r; i++) {
        if(n % i == 0) {
            d.push_back(i);

            if(i != r)
                d.push_back(n / i);
        }
    }
    return d;
}

int main() {
    vi divi = divisores(52132);
    for(int i=0; i<divi.size(); i++)
        printf("%d ", divi[i]);
    printf("\n");
}
<|endoftext|>