<commit_before>#pragma once

#include <ews/ews.hpp>
#include <ews/ews_test_support.hpp>
#include <gtest/gtest.h>
#ifdef EWS_USE_BOOST_LIBRARY
# include <boost/filesystem.hpp>
#endif

#include <string>
#include <vector>
#include <memory>
#include <utility>

namespace tests
{
    struct environment
    {
        static const ews::test::credentials& credentials()
        {
            static auto creds = ews::test::get_from_environment();
            return creds;
        }
    };

    // Per-test-case set-up and tear-down
    class BaseFixture : public ::testing::Test
    {
    protected:
        static void SetUpTestCase()
        {
            ews::set_up();
        }

        static void TearDownTestCase()
        {
            ews::tear_down();
        }
    };

    class FakeServiceFixture : public BaseFixture
    {
    public:
        struct http_request_mock final
        {
            struct storage
            {
                static storage& instance()
                {
                    thread_local storage inst;
                    return inst;
                }

                std::string request_string;
                std::vector<char> fake_response;
            };

            http_request_mock() = default;

            bool header_contains(const std::string& search_str) const
            {
                const auto& request_str = storage::instance().request_string;
                const auto header_end_idx = request_str.find("</soap:Header>");
                const auto search_str_idx = request_str.find(search_str);
                return     search_str_idx != std::string::npos
                        && search_str_idx < header_end_idx;
            }

            // Below same public interface as ews::internal::http_request class
            enum class method { POST };

            explicit http_request_mock(const std::string& url)
            {
                (void)url;
            }

            void set_method(method m)
            {
                (void)m;
            }

            void set_content_type(const std::string& content_type)
            {
                (void)content_type;
            }

            void set_credentials(const ews::internal::credentials& creds)
            {
                (void)creds;
            }

            template <typename... Args> void set_option(CURLoption, Args...) {}

            ews::internal::http_response send(const std::string& request)
            {
                auto& s = storage::instance();
                s.request_string = request;
                auto response_bytes = s.fake_response;
                return ews::internal::http_response(200,
                                                    std::move(response_bytes));
            }
        };

        virtual ~FakeServiceFixture() = default;

        ews::basic_service<http_request_mock>& service()
        {
            return *service_ptr_;
        }

        http_request_mock get_last_request()
        {
            return http_request_mock();
        }

        void set_next_fake_response(const char* str)
        {
            auto& storage = http_request_mock::storage::instance();
            storage.fake_response =
                std::vector<char>(str, str + std::strlen(str));
            storage.fake_response.push_back('\0');
        }

    protected:
        virtual void SetUp()
        {
            BaseFixture::SetUp();
#ifdef EWS_HAS_MAKE_UNIQUE
            service_ptr_ = std::make_unique<
                                ews::basic_service<http_request_mock>>(
                                    "https://example.com/ews/Exchange.asmx",
                                    "FAKEDOMAIN",
                                    "fakeuser",
                                    "fakepassword");
#else
            service_ptr_ = std::unique_ptr<ews::basic_service<http_request_mock>>(
                                new ews::basic_service<http_request_mock>(
                                    "https://example.com/ews/Exchange.asmx",
                                    "FAKEDOMAIN",
                                    "fakeuser",
                                    "fakepassword"));
#endif
        }

        virtual void TearDown()
        {
            service_ptr_.reset();
            BaseFixture::TearDown();
        }

    private:
        std::unique_ptr<ews::basic_service<http_request_mock>> service_ptr_;
    };

    // Set-up and tear down a service object
    class ServiceFixture : public BaseFixture
    {
    public:
        virtual ~ServiceFixture() = default;

        ews::service& service()
        {
            return *service_ptr_;
        }

    protected:
        virtual void SetUp()
        {
            BaseFixture::SetUp();
            const auto& creds = environment::credentials();
#ifdef EWS_HAS_MAKE_UNIQUE
            service_ptr_ = std::make_unique<ews::service>(creds.server_uri,
                                                          creds.domain,
                                                          creds.username,
                                                          creds.password);
#else
            service_ptr_ = std::unique_ptr<ews::service>(
                                         new ews::service(creds.server_uri,
                                                          creds.domain,
                                                          creds.username,
                                                          creds.password));
#endif
        }

        virtual void TearDown()
        {
            service_ptr_.reset();
            BaseFixture::TearDown();
        }

    private:
        std::unique_ptr<ews::service> service_ptr_;
    };

    // Create and remove a task on the server
    class TaskTest : public ServiceFixture
    {
    public:
        void SetUp()
        {
            ServiceFixture::SetUp();

            task_.set_subject("Get some milk");
            task_.set_body(ews::body("Get some milk from the store"));
            task_.set_start_date(ews::date_time("2015-06-17T19:00:00Z"));
            task_.set_due_date(ews::date_time("2015-06-17T19:30:00Z"));
            const auto item_id = service().create_item(task_);
            task_ = service().get_task(item_id);
        }

        void TearDown()
        {
            service().delete_task(
                    std::move(task_),
                    ews::delete_type::hard_delete,
                    ews::affected_task_occurrences::all_occurrences);

            ServiceFixture::TearDown();
        }

        ews::task& test_task() { return task_; }

    private:
        ews::task task_;
    };

    // Create and remove a contact on the server
    class ContactTest : public ServiceFixture
    {
    public:
        void SetUp()
        {
            ServiceFixture::SetUp();

            contact_.set_given_name("Minnie");
            contact_.set_surname("Mouse");
            const auto item_id = service().create_item(contact_);
            contact_ = service().get_contact(item_id);
        }

        void TearDown()
        {
            service().delete_contact(std::move(contact_));

            ServiceFixture::TearDown();
        }

        ews::contact& test_contact() { return contact_; }

    private:
        ews::contact contact_;
    };

    struct MessageTest : public ServiceFixture
    {
    };

    class AttachmentTest : public ServiceFixture
    {
    public:
        void SetUp()
        {
            ServiceFixture::SetUp();

            auto msg = ews::message();
            msg.set_subject("Honorable Minister of Finance - Release Funds");
            std::vector<ews::email_address> recipients{
                ews::email_address("udom.emmanuel@zenith-bank.com.ng")
            };
            msg.set_to_recipients(recipients);
            auto item_id = service().create_item(
                    msg,
                    ews::message_disposition::save_only);
            message_ = service().get_message(item_id);
        }

        void TearDown()
        {
            service().delete_message(std::move(message_));

            ServiceFixture::TearDown();
        }

        ews::message& test_message() { return message_; }

    private:
        ews::message message_;
    };

#ifdef EWS_USE_BOOST_LIBRARY
    class FileAttachmentTest : public BaseFixture
    {
    public:
        FileAttachmentTest()
            : assetsdir_(ews::test::global_data::instance().assets_dir)
        {
        }

        void SetUp()
        {
            BaseFixture::SetUp();

            olddir_ = boost::filesystem::current_path();
            workingdir_ = boost::filesystem::unique_path(
                        boost::filesystem::temp_directory_path() /
                        "%%%%-%%%%-%%%%-%%%%");
            ASSERT_TRUE(boost::filesystem::create_directory(workingdir_))
                << "Unable to create temporary working directory";
            boost::filesystem::current_path(workingdir_);
        }

        void TearDown()
        {
            EXPECT_TRUE(boost::filesystem::is_empty(workingdir_))
                << "Temporary directory not empty on TearDown";
            boost::filesystem::remove_all(workingdir_);
            boost::filesystem::current_path(olddir_);

            BaseFixture::TearDown();
        }

        const boost::filesystem::path& assets_dir() const
        {
            return assetsdir_;
        }

        const boost::filesystem::path& cwd() const
        {
            return workingdir_;
        }

    private:
        boost::filesystem::path assetsdir_;
        boost::filesystem::path olddir_;
        boost::filesystem::path workingdir_;
    };
#endif // EWS_USE_BOOST_LIBRARY
}
<commit_msg>tests: fix SIGSEGV when env variables aren't set<commit_after>#pragma once

#include <ews/ews.hpp>
#include <ews/ews_test_support.hpp>
#include <gtest/gtest.h>
#ifdef EWS_USE_BOOST_LIBRARY
# include <boost/filesystem.hpp>
#endif

#include <string>
#include <vector>
#include <memory>
#include <utility>
#include <stdexcept>

namespace tests
{
    struct environment
    {
        static const ews::test::credentials& credentials()
        {
            static auto creds = ews::test::get_from_environment();
            return creds;
        }
    };

    // Per-test-case set-up and tear-down
    class BaseFixture : public ::testing::Test
    {
    protected:
        static void SetUpTestCase()
        {
            ews::set_up();
        }

        static void TearDownTestCase()
        {
            ews::tear_down();
        }
    };

    class FakeServiceFixture : public BaseFixture
    {
    public:
        struct http_request_mock final
        {
            struct storage
            {
                static storage& instance()
                {
                    thread_local storage inst;
                    return inst;
                }

                std::string request_string;
                std::vector<char> fake_response;
            };

            http_request_mock() = default;

            bool header_contains(const std::string& search_str) const
            {
                const auto& request_str = storage::instance().request_string;
                const auto header_end_idx = request_str.find("</soap:Header>");
                const auto search_str_idx = request_str.find(search_str);
                return     search_str_idx != std::string::npos
                        && search_str_idx < header_end_idx;
            }

            // Below same public interface as ews::internal::http_request class
            enum class method { POST };

            explicit http_request_mock(const std::string& url)
            {
                (void)url;
            }

            void set_method(method m)
            {
                (void)m;
            }

            void set_content_type(const std::string& content_type)
            {
                (void)content_type;
            }

            void set_credentials(const ews::internal::credentials& creds)
            {
                (void)creds;
            }

            template <typename... Args> void set_option(CURLoption, Args...) {}

            ews::internal::http_response send(const std::string& request)
            {
                auto& s = storage::instance();
                s.request_string = request;
                auto response_bytes = s.fake_response;
                return ews::internal::http_response(200,
                                                    std::move(response_bytes));
            }
        };

        virtual ~FakeServiceFixture() = default;

        ews::basic_service<http_request_mock>& service()
        {
            return *service_ptr_;
        }

        http_request_mock get_last_request()
        {
            return http_request_mock();
        }

        void set_next_fake_response(const char* str)
        {
            auto& storage = http_request_mock::storage::instance();
            storage.fake_response =
                std::vector<char>(str, str + std::strlen(str));
            storage.fake_response.push_back('\0');
        }

    protected:
        virtual void SetUp()
        {
            BaseFixture::SetUp();
#ifdef EWS_HAS_MAKE_UNIQUE
            service_ptr_ = std::make_unique<
                                ews::basic_service<http_request_mock>>(
                                    "https://example.com/ews/Exchange.asmx",
                                    "FAKEDOMAIN",
                                    "fakeuser",
                                    "fakepassword");
#else
            service_ptr_ = std::unique_ptr<ews::basic_service<http_request_mock>>(
                                new ews::basic_service<http_request_mock>(
                                    "https://example.com/ews/Exchange.asmx",
                                    "FAKEDOMAIN",
                                    "fakeuser",
                                    "fakepassword"));
#endif
        }

        virtual void TearDown()
        {
            service_ptr_.reset();
            BaseFixture::TearDown();
        }

    private:
        std::unique_ptr<ews::basic_service<http_request_mock>> service_ptr_;
    };

    // Set-up and tear down a service object
    class ServiceFixture : public BaseFixture
    {
    public:
        virtual ~ServiceFixture() = default;

        ews::service& service()
        {
            if (!service_ptr_)
            {
                throw std::runtime_error(
                        "Cannot access service: no instance created");
            }
            return *service_ptr_;
        }

    protected:
        virtual void SetUp()
        {
            BaseFixture::SetUp();
            const auto& creds = environment::credentials();
#ifdef EWS_HAS_MAKE_UNIQUE
            service_ptr_ = std::make_unique<ews::service>(creds.server_uri,
                                                          creds.domain,
                                                          creds.username,
                                                          creds.password);
#else
            service_ptr_ = std::unique_ptr<ews::service>(
                                         new ews::service(creds.server_uri,
                                                          creds.domain,
                                                          creds.username,
                                                          creds.password));
#endif
        }

        virtual void TearDown()
        {
            service_ptr_.reset();
            BaseFixture::TearDown();
        }

    private:
        std::unique_ptr<ews::service> service_ptr_;
    };

    // Create and remove a task on the server
    class TaskTest : public ServiceFixture
    {
    public:
        void SetUp()
        {
            ServiceFixture::SetUp();

            task_.set_subject("Get some milk");
            task_.set_body(ews::body("Get some milk from the store"));
            task_.set_start_date(ews::date_time("2015-06-17T19:00:00Z"));
            task_.set_due_date(ews::date_time("2015-06-17T19:30:00Z"));
            const auto item_id = service().create_item(task_);
            task_ = service().get_task(item_id);
        }

        void TearDown()
        {
            service().delete_task(
                    std::move(task_),
                    ews::delete_type::hard_delete,
                    ews::affected_task_occurrences::all_occurrences);

            ServiceFixture::TearDown();
        }

        ews::task& test_task() { return task_; }

    private:
        ews::task task_;
    };

    // Create and remove a contact on the server
    class ContactTest : public ServiceFixture
    {
    public:
        void SetUp()
        {
            ServiceFixture::SetUp();

            contact_.set_given_name("Minnie");
            contact_.set_surname("Mouse");
            const auto item_id = service().create_item(contact_);
            contact_ = service().get_contact(item_id);
        }

        void TearDown()
        {
            service().delete_contact(std::move(contact_));

            ServiceFixture::TearDown();
        }

        ews::contact& test_contact() { return contact_; }

    private:
        ews::contact contact_;
    };

    struct MessageTest : public ServiceFixture
    {
    };

    class AttachmentTest : public ServiceFixture
    {
    public:
        void SetUp()
        {
            ServiceFixture::SetUp();

            auto msg = ews::message();
            msg.set_subject("Honorable Minister of Finance - Release Funds");
            std::vector<ews::email_address> recipients{
                ews::email_address("udom.emmanuel@zenith-bank.com.ng")
            };
            msg.set_to_recipients(recipients);
            auto item_id = service().create_item(
                    msg,
                    ews::message_disposition::save_only);
            message_ = service().get_message(item_id);
        }

        void TearDown()
        {
            service().delete_message(std::move(message_));

            ServiceFixture::TearDown();
        }

        ews::message& test_message() { return message_; }

    private:
        ews::message message_;
    };

#ifdef EWS_USE_BOOST_LIBRARY
    class FileAttachmentTest : public BaseFixture
    {
    public:
        FileAttachmentTest()
            : assetsdir_(ews::test::global_data::instance().assets_dir)
        {
        }

        void SetUp()
        {
            BaseFixture::SetUp();

            olddir_ = boost::filesystem::current_path();
            workingdir_ = boost::filesystem::unique_path(
                        boost::filesystem::temp_directory_path() /
                        "%%%%-%%%%-%%%%-%%%%");
            ASSERT_TRUE(boost::filesystem::create_directory(workingdir_))
                << "Unable to create temporary working directory";
            boost::filesystem::current_path(workingdir_);
        }

        void TearDown()
        {
            EXPECT_TRUE(boost::filesystem::is_empty(workingdir_))
                << "Temporary directory not empty on TearDown";
            boost::filesystem::remove_all(workingdir_);
            boost::filesystem::current_path(olddir_);

            BaseFixture::TearDown();
        }

        const boost::filesystem::path& assets_dir() const
        {
            return assetsdir_;
        }

        const boost::filesystem::path& cwd() const
        {
            return workingdir_;
        }

    private:
        boost::filesystem::path assetsdir_;
        boost::filesystem::path olddir_;
        boost::filesystem::path workingdir_;
    };
#endif // EWS_USE_BOOST_LIBRARY
}
<|endoftext|>


<commit_before>#include <storm/platform/ogl/buffer_ogl.h>

#include <cstring>

#include <storm/platform/ogl/check_result_ogl.h>
#include <storm/platform/ogl/rendering_system_ogl.h>
#include <storm/platform/ogl/resource_type_ogl.h>

namespace storm {

BufferHandleOgl::BufferHandleOgl() {
    ::glGenBuffers( 1, &_handle );
    checkResult( "::glGenBuffers" );
    return;
}

BufferHandleOgl::~BufferHandleOgl() {
    ::glDeleteBuffers( 1, &_handle );
    return;
}

// GL_COPY_WRITE_BUFFER and GL_COPY_READ_BUFFER are not used in the rendering process
// so it's safe to overwrite these targets and to use them in the data transfer operations.

BufferOgl::BufferOgl( const Description &description, const void *data )
    : _description( description )
{
    ::glBindBuffer( GL_COPY_WRITE_BUFFER, _handle );
    checkResult( "::glBindBuffer" );

    const GLenum usage = getResourceUsage( _description.resourceType );

    ::glBufferData( GL_COPY_WRITE_BUFFER, _description.size, data, usage );
    checkResult( "::glBufferData" );

    return;
}

void BufferOgl::getData( size_t offset, size_t size, void *data ) const {
    ::glBindBuffer( GL_COPY_READ_BUFFER, _handle );
    checkResult( "::glBindBuffer" );

    ::glGetBufferSubData( GL_COPY_READ_BUFFER, offset, size, data );
    checkResult( "::glGetBufferSubData" );
    return;
}

void BufferOgl::setData( size_t offset, size_t size, const void *data ) {
    storm_assert( offset + size <= _description.size );

    ::glBindBuffer( GL_COPY_WRITE_BUFFER, _handle );
    checkResult( "::glBindBuffer" );

    void *destination = ::glMapBufferRange( GL_COPY_WRITE_BUFFER, offset, size, GL_MAP_WRITE_BIT );
    checkResult( "::glMapBufferRange" );

    ::memcpy( destination, data, size );

    ::glUnmapBuffer( GL_COPY_WRITE_BUFFER );
    checkResult( "::glUnmapBuffer" );

    // glUnmapBuffer can return 'false' indicating the data corruption.
    // Now the return value is simply ignored.
    return;
}

const Buffer::Description& BufferOgl::getDescription() const {
    return _description;
}

const BufferHandleOgl& BufferOgl::getHandle() const {
    return _handle;
}

Buffer::Pointer Buffer::create(
    const Description &description, const void *data )
{
    RenderingSystemOgl::installOpenGlContext();

    return std::make_shared<BufferOgl>( description, data );
}

}
<commit_msg>Updated BufferOgl implementation<commit_after>#include <storm/platform/ogl/buffer_ogl.h>

#include <storm/platform/ogl/check_result_ogl.h>
#include <storm/platform/ogl/rendering_system_ogl.h>
#include <storm/platform/ogl/resource_type_ogl.h>

namespace storm {

BufferHandleOgl::BufferHandleOgl() {
    ::glGenBuffers( 1, &_handle );
    checkResult( "::glGenBuffers" );
}

BufferHandleOgl::~BufferHandleOgl() {
    ::glDeleteBuffers( 1, &_handle );
}

// GL_COPY_WRITE_BUFFER and GL_COPY_READ_BUFFER are not used in the rendering
// process so it's safe to overwrite these targets and to use them in the data
// transfer operations.

BufferOgl::BufferOgl( const Description &description, const void *data ) :
    _description( description )
{
    ::glBindBuffer( GL_COPY_WRITE_BUFFER, _handle );
    checkResult( "::glBindBuffer" );

    const GLenum usage = getResourceUsage( _description.resourceType );

    ::glBufferData( GL_COPY_WRITE_BUFFER, _description.size, data, usage );
    checkResult( "::glBufferData" );
}

void BufferOgl::getData( size_t offset, size_t size, void *data ) const {
    ::glBindBuffer( GL_COPY_READ_BUFFER, _handle );
    checkResult( "::glBindBuffer" );

    ::glGetBufferSubData( GL_COPY_READ_BUFFER, offset, size, data );
    checkResult( "::glGetBufferSubData" );
}

void BufferOgl::setData( size_t offset, size_t size, const void *data ) {
    storm_assert( offset + size <= _description.size );

    ::glBindBuffer( GL_COPY_WRITE_BUFFER, _handle );
    checkResult( "::glBindBuffer" );

    ::glBufferSubData( GL_COPY_WRITE_BUFFER, offset, size, data );
    checkResult( "::glBufferSubData" );
}

const Buffer::Description& BufferOgl::getDescription() const {
    return _description;
}

const BufferHandleOgl& BufferOgl::getHandle() const {
    return _handle;
}

Buffer::Pointer Buffer::create(
    const Description &description, const void *data )
{
    RenderingSystemOgl::installOpenGlContext();

    return std::make_shared<BufferOgl>( description, data );
}

}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used 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.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsystemdisplayinfo.h"
#include "qsysteminfocommon_p.h"
#include <QDesktopWidget>

QTM_BEGIN_NAMESPACE
        Q_GLOBAL_STATIC(QSystemDisplayInfoPrivate, displayInfoPrivate)

#ifdef QT_SIMULATOR
QSystemDisplayInfoPrivate *getSystemDisplayInfoPrivate() { return displayInfoPrivate(); }
#endif

// display
/*!
    \enum QSystemDisplayInfo::DisplayOrientation
    This enum describes the orientation of the default window.

    \value Unknown                  Unknown orientation or error.
    \value Landscape                Landscape is wider than high.
    \value Portrait                 Portrait is higher than wide.
    \value InvertedLandscape        Landscape that is inverted.
    \value InvertedPortrait         Portrait that is inverted.
  */

/*!
  \enum QSystemDisplayInfo::BacklightState
  This enum describes the state of the Backlight.

  \value BacklightUnknown          Error, no, or unknown Backlight state.
  \value BacklightOff              Backlight is turned off.
  \value BacklightStateDimmed      Backlight has been dimmed.
  \value BacklightStateFull        Backlight is on full.
  */
 /*!
   \class QSystemDisplayInfo
   \ingroup systeminfo
   \inmodule QtSystemInfo

    \brief The QSystemDisplayInfo class provides access to display information from the system.
*/

/*!
   Constructs a QSystemDisplayInfo object with the given \a parent.
 */
QSystemDisplayInfo::QSystemDisplayInfo(QObject *parent)
    : QObject(parent)
{
    qRegisterMetaType<QSystemDisplayInfo::DisplayOrientation>("QSystemDisplayInfo::DisplayOrientation");
    qRegisterMetaType<QSystemDisplayInfo::BacklightState>("QSystemDisplayInfo::BacklightState");
}

/*!
  Destroys the QSystemDisplayInfo object.
 */
QSystemDisplayInfo::~QSystemDisplayInfo()
{
}

/*!
    Returns the display brightness of the screen with index \a screenNumber in %, 1 - 100 scale.

    Depending on platform, displayBrightness may not be available due to
    differing hardware, software or driver implementation. In which case this
    will return -1.

    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::displayBrightness(int screenNumber)
{
    QDesktopWidget wid;
    if(wid.screenCount() < 1 || wid.screenCount() - 1 < screenNumber) {
        return -1;
    }
    return displayInfoPrivate()->displayBrightness(screenNumber);
}

/*!
    Returns the color depth of the screen with the index \a screenNumber, in bits per pixel. Will return -1 in
    the event of an error.

    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::colorDepth(int screenNumber)
{
    QDesktopWidget wid;
    if(wid.screenCount() < 1 || wid.screenCount() - 1 < screenNumber) {
        return -1;
    }
    return displayInfoPrivate()->colorDepth(screenNumber);
}

/*!
    Returns the orientation of the \a screen.

    \sa QDesktopWidget::screenCount()
*/
QSystemDisplayInfo::DisplayOrientation QSystemDisplayInfo::getOrientation(int screen)
{
    return displayInfoPrivate()->getOrientation(screen);
}

/*!
    Returns the current contrast of the screen \a screen, from 0 to 1.

    \sa QDesktopWidget::screenCount()
*/
float QSystemDisplayInfo::contrast(int screen)
{
        return displayInfoPrivate()->contrast(screen);
}

/*!
    Returns the current dots per inch (DPI) for the width of \a screen.

    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::getDPIWidth(int screen)
{
        return displayInfoPrivate()->getDPIWidth(screen);
}

/*!
    Returns the dpi (Dot Per Inch) of the height os \a screen.

    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::getDPIHeight(int screen)
{
        return displayInfoPrivate()->getDPIHeight(screen);
}

/*!
    Returns the physical height of the \a screen in millimeters.
    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::physicalHeight(int screen)
{
        return displayInfoPrivate()->physicalHeight(screen);
}

/*!
    Returns the physical width of \a screen in millimeters.
    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::physicalWidth(int screen)
{
        return displayInfoPrivate()->physicalWidth(screen);
}

/*!
    Returns whether the QSystemDisplayInfo::BacklightState for the screen \a screen.
*/
QSystemDisplayInfo::BacklightState QSystemDisplayInfo::backlightStatus(int screen)
{
    return displayInfoPrivate()->backlightStatus(screen);
}

#include "moc_qsystemdisplayinfo.cpp"

QTM_END_NAMESPACE
<commit_msg>fix build<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used 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.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsystemdisplayinfo.h"
#include "qsysteminfocommon_p.h"
#include <QDesktopWidget>
#include <QMetaType>

QTM_BEGIN_NAMESPACE
        Q_GLOBAL_STATIC(QSystemDisplayInfoPrivate, displayInfoPrivate)

#ifdef QT_SIMULATOR
QSystemDisplayInfoPrivate *getSystemDisplayInfoPrivate() { return displayInfoPrivate(); }
#endif

// display
/*!
    \enum QSystemDisplayInfo::DisplayOrientation
    This enum describes the orientation of the default window.

    \value Unknown                  Unknown orientation or error.
    \value Landscape                Landscape is wider than high.
    \value Portrait                 Portrait is higher than wide.
    \value InvertedLandscape        Landscape that is inverted.
    \value InvertedPortrait         Portrait that is inverted.
  */

/*!
  \enum QSystemDisplayInfo::BacklightState
  This enum describes the state of the Backlight.

  \value BacklightUnknown          Error, no, or unknown Backlight state.
  \value BacklightOff              Backlight is turned off.
  \value BacklightStateDimmed      Backlight has been dimmed.
  \value BacklightStateFull        Backlight is on full.
  */
 /*!
   \class QSystemDisplayInfo
   \ingroup systeminfo
   \inmodule QtSystemInfo

    \brief The QSystemDisplayInfo class provides access to display information from the system.
*/

/*!
   Constructs a QSystemDisplayInfo object with the given \a parent.
 */
QSystemDisplayInfo::QSystemDisplayInfo(QObject *parent)
    : QObject(parent)
{
    qRegisterMetaType<QSystemDisplayInfo::DisplayOrientation>("QSystemDisplayInfo::DisplayOrientation");
    qRegisterMetaType<QSystemDisplayInfo::BacklightState>("QSystemDisplayInfo::BacklightState");
}

/*!
  Destroys the QSystemDisplayInfo object.
 */
QSystemDisplayInfo::~QSystemDisplayInfo()
{
}

/*!
    Returns the display brightness of the screen with index \a screenNumber in %, 1 - 100 scale.

    Depending on platform, displayBrightness may not be available due to
    differing hardware, software or driver implementation. In which case this
    will return -1.

    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::displayBrightness(int screenNumber)
{
    QDesktopWidget wid;
    if(wid.screenCount() < 1 || wid.screenCount() - 1 < screenNumber) {
        return -1;
    }
    return displayInfoPrivate()->displayBrightness(screenNumber);
}

/*!
    Returns the color depth of the screen with the index \a screenNumber, in bits per pixel. Will return -1 in
    the event of an error.

    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::colorDepth(int screenNumber)
{
    QDesktopWidget wid;
    if(wid.screenCount() < 1 || wid.screenCount() - 1 < screenNumber) {
        return -1;
    }
    return displayInfoPrivate()->colorDepth(screenNumber);
}

/*!
    Returns the orientation of the \a screen.

    \sa QDesktopWidget::screenCount()
*/
QSystemDisplayInfo::DisplayOrientation QSystemDisplayInfo::getOrientation(int screen)
{
    return displayInfoPrivate()->getOrientation(screen);
}

/*!
    Returns the current contrast of the screen \a screen, from 0 to 1.

    \sa QDesktopWidget::screenCount()
*/
float QSystemDisplayInfo::contrast(int screen)
{
        return displayInfoPrivate()->contrast(screen);
}

/*!
    Returns the current dots per inch (DPI) for the width of \a screen.

    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::getDPIWidth(int screen)
{
        return displayInfoPrivate()->getDPIWidth(screen);
}

/*!
    Returns the dpi (Dot Per Inch) of the height os \a screen.

    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::getDPIHeight(int screen)
{
        return displayInfoPrivate()->getDPIHeight(screen);
}

/*!
    Returns the physical height of the \a screen in millimeters.
    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::physicalHeight(int screen)
{
        return displayInfoPrivate()->physicalHeight(screen);
}

/*!
    Returns the physical width of \a screen in millimeters.
    \sa QDesktopWidget::screenCount()
*/
int QSystemDisplayInfo::physicalWidth(int screen)
{
        return displayInfoPrivate()->physicalWidth(screen);
}

/*!
    Returns whether the QSystemDisplayInfo::BacklightState for the screen \a screen.
*/
QSystemDisplayInfo::BacklightState QSystemDisplayInfo::backlightStatus(int screen)
{
    return displayInfoPrivate()->backlightStatus(screen);
}

#include "moc_qsystemdisplayinfo.cpp"

QTM_END_NAMESPACE
<|endoftext|>


<commit_before>#include "fixed_len_key_index.hpp"
#include <terark/io/FileStream.hpp>
#include <terark/io/DataIO.hpp>
#include <terark/util/mmap.hpp>

namespace terark { namespace db {

FixedLenKeyIndex::FixedLenKeyIndex(const Schema& schema) : m_schema(schema) {
	m_isOrdered = true;
	m_isIndexKeyByteLex = true;
	m_mmapBase = nullptr;
	m_mmapSize = 0;
	m_fixedLen = 0;
	m_uniqKeys = 0;
}

FixedLenKeyIndex::~FixedLenKeyIndex() {
	if (m_mmapBase) {
		m_keys.risk_release_ownership();
		m_index.risk_release_ownership();
		mmap_close(m_mmapBase, m_mmapSize);
	}
}

ReadableStore* FixedLenKeyIndex::getReadableStore() {
	return this;
}

ReadableIndex* FixedLenKeyIndex::getReadableIndex() {
	return this;
}

///@{ ordered and unordered index
llong FixedLenKeyIndex::indexStorageSize() const {
	return m_index.mem_size();
}

void
FixedLenKeyIndex::searchExactAppend(fstring key, valvec<llong>* recIdvec, DbContext*)
const {
	size_t f = m_fixedLen;
	if (m_schema.m_needEncodeToLexByteComparable) {
		byte* cvtbuf = (byte*)alloca(f);
		memcpy(cvtbuf, key.data(), f);
		m_schema.byteLexEncode(cvtbuf, f);
		key.p = (char*)cvtbuf;
	}
	size_t j = searchLowerBound(key);
	size_t id;
	const  byte* keysData = m_keys.data();
	while (j < m_index.size() &&
		   memcmp(keysData + f*(id=m_index[j]), key.p, f) == 0)
	{
		recIdvec->push_back(id);
		++j;
	}
}

size_t FixedLenKeyIndex::searchLowerBound_cvt(fstring key) const {
	if (m_schema.m_needEncodeToLexByteComparable) {
		size_t fixlen = m_fixedLen;
		byte*  cvtbuf = (byte*)alloca(fixlen);
		memcpy(cvtbuf, key.data(), fixlen);
		m_schema.byteLexEncode(cvtbuf, fixlen);
		return searchLowerBound(fstring(cvtbuf, fixlen));
	}
	else {
		return searchLowerBound(key);
	}
}

size_t FixedLenKeyIndex::searchUpperBound_cvt(fstring key) const {
	if (m_schema.m_needEncodeToLexByteComparable) {
		size_t fixlen = m_fixedLen;
		byte*  cvtbuf = (byte*)alloca(fixlen);
		memcpy(cvtbuf, key.data(), fixlen);
		m_schema.byteLexEncode(cvtbuf, fixlen);
		return searchUpperBound(fstring(cvtbuf, fixlen));
	}
	else {
		return searchUpperBound(key);
	}
}

size_t FixedLenKeyIndex::searchLowerBound(fstring key) const {
	assert(key.size() == m_fixedLen);
	auto indexData = m_index.data();
	auto indexBits = m_index.uintbits();
	auto indexMask = m_index.uintmask();
	auto keysData = m_keys.data();
	size_t fixlen = m_fixedLen;
	size_t i = 0, j = m_index.size();
	while (i < j) {
		size_t mid = (i + j) / 2;
		size_t hitPos = UintVecMin0::fast_get(indexData, indexBits, indexMask, mid);
		const byte* hitKey = keysData + fixlen * hitPos;
		if (memcmp(hitKey, key.p, fixlen) < 0)
			i = mid + 1;
		else
			j = mid;
	}
	return i;
}

size_t FixedLenKeyIndex::searchUpperBound(fstring key) const {
	assert(key.size() == m_fixedLen);
	auto indexData = m_index.data();
	auto indexBits = m_index.uintbits();
	auto indexMask = m_index.uintmask();
	auto keysData = m_keys.data();
	size_t fixlen = m_fixedLen;
	size_t i = 0, j = m_index.size();
	while (i < j) {
		size_t mid = (i + j) / 2;
		size_t hitPos = UintVecMin0::fast_get(indexData, indexBits, indexMask, mid);
		const byte* hitKey = keysData + fixlen * hitPos;
		if (memcmp(hitKey, key.p, fixlen) <= 0)
			i = mid + 1;
		else
			j = mid;
	}
	return i;
}

///@}

llong FixedLenKeyIndex::dataStorageSize() const {
	return m_keys.used_mem_size() + m_index.mem_size();
}

llong FixedLenKeyIndex::dataInflateSize() const {
	return m_fixedLen * m_keys.size();
}

llong FixedLenKeyIndex::numDataRows() const {
	return m_keys.size();
}

void FixedLenKeyIndex::getValueAppend(llong id, valvec<byte>* val, DbContext*) const {
	assert(id >= 0);
	size_t idx = size_t(id);
	assert(idx < m_keys.size());
	size_t fixlen = m_fixedLen;
	const byte* dataPtr = m_keys.data() + fixlen * idx;
	size_t oldsize = val->size();
	val->append(dataPtr, fixlen);
	if (m_schema.m_needEncodeToLexByteComparable) {
		m_schema.byteLexDecode(val->data() + oldsize, fixlen);
	}
}

StoreIterator* FixedLenKeyIndex::createStoreIterForward(DbContext*) const {
	return nullptr; // not needed
}

StoreIterator* FixedLenKeyIndex::createStoreIterBackward(DbContext*) const {
	return nullptr; // not needed
}

void FixedLenKeyIndex::build(const Schema& schema, SortableStrVec& strVec) {
	size_t fixlen = schema.getFixedRowLen();
	byte*  data = strVec.m_strpool.data();
	size_t rows = strVec.m_strpool.size() / fixlen;
	assert(strVec.m_index.size() == 0);
	assert(strVec.m_strpool.size() % fixlen == 0);
	if (schema.m_needEncodeToLexByteComparable) {
		for (size_t i = 0; i < rows; ++i) {
			schema.byteLexEncode(data + i*fixlen, fixlen);
		}
	}
	valvec<uint32_t> index(rows, valvec_no_init());
	for (size_t i = 0; i < rows; ++i) index[i] = i;
	std::sort(index.begin(), index.end(),
		[data,fixlen](size_t x, size_t y) {
		const byte* xkey = data + fixlen * x;
		const byte* ykey = data + fixlen * y;
		int ret = memcmp(xkey, ykey, fixlen);
		if (ret)
			return ret < 0;
		else
			return x < y;
	});
	m_fixedLen = fixlen;
	m_uniqKeys = 0;
	for(size_t i = 0; i < m_keys.size(); ) {
		size_t j = i;
		int cmp = 0;
		do {
			const byte* xkey = data + fixlen * (j + 0);
			const byte* ykey = data + fixlen * (j + 1);
			cmp = memcmp(xkey, ykey, fixlen);
			++j;
		} while (0 == cmp);
		i = j;
		m_uniqKeys++;
	}
	m_isUnique = m_uniqKeys == rows;
	auto minIdx = m_index.build_from(index);
	(void)minIdx;
	assert(0 == minIdx);
	m_keys.clear();
	m_keys.swap(strVec.m_strpool);
}

namespace {
	struct Header {
		uint32_t rows;
		uint32_t uniqKeys;
		uint32_t fixlen;
		uint32_t padding;
	};
}

void FixedLenKeyIndex::load(PathRef path) {
	auto fpath = path + ".fixlen";
	m_mmapBase = (byte_t*)mmap_load(fpath.string(), &m_mmapSize);
	auto h = (const Header*)m_mmapBase;
	m_isUnique = h->uniqKeys == h->rows;
	m_uniqKeys = h->uniqKeys;
	m_fixedLen = h->fixlen;
	size_t rbits = terark_bsr_u32(h->rows-1) + 1;
	size_t keyMemSize = h->fixlen * h->rows;
	m_keys .risk_set_data((byte*)(h+1) , keyMemSize);
	keyMemSize = (keyMemSize + 15) & ~15;
	m_index.risk_set_data((byte*)(h+1) + keyMemSize, h->rows, rbits);
}

void FixedLenKeyIndex::save(PathRef path) const {
	auto fpath = path + ".fixlen";
	NativeDataOutput<FileStream> dio;
	dio.open(fpath.string().c_str(), "wb");
	Header h;
	h.rows     = uint32_t(m_index.size());
	h.uniqKeys = m_uniqKeys;
	h.fixlen   = m_fixedLen;
	h.padding  = 0;
	dio.ensureWrite(&h, sizeof(h));
	byte zero[16];
	memset(zero, 0, sizeof(zero));
	dio.ensureWrite(m_keys .data(), m_keys .used_mem_size());
	if (m_keys.used_mem_size() % 16 != 0) {
		dio.ensureWrite(zero, 16 - m_keys.used_mem_size() % 16);
	}
	dio.ensureWrite(m_index.data(), m_index.mem_size());
}

class FixedLenKeyIndex::MyIndexIterForward : public IndexIterator {
public:
	size_t m_keyIdx;
	const FixedLenKeyIndex* m_owner;

	MyIndexIterForward(const FixedLenKeyIndex* owner) {
		m_keyIdx = 0;
		m_owner = owner;
	}

	void reset() override {
		m_keyIdx = 0;
	}

	bool increment(llong* id, valvec<byte>* key) override {
		assert(nullptr != key);
		if (m_keyIdx < m_owner->m_index.size()) {
			*id = m_owner->m_index.get(m_keyIdx++);
			key->erase_all();
			m_owner->getValueAppend(*id, key, nullptr);
			return true;
		}
		return false;
	}

	int seekLowerBound(fstring key, llong* id, valvec<byte>* retKey) override {
		assert(nullptr != retKey);
		m_keyIdx = key.empty() ? 0 : m_owner->searchLowerBound_cvt(key);
		if (m_keyIdx < m_owner->m_index.size()) {
			*id = m_owner->m_index.get(m_keyIdx);
			retKey->erase_all();
			m_owner->getValueAppend(*id, retKey, nullptr);
			m_keyIdx++;
			return key == *retKey ? 0 : 1;
		}
		return -1;
	}

	int seekUpperBound(fstring key, llong* id, valvec<byte>* retKey) override {
		assert(nullptr != retKey);
		m_keyIdx = key.empty() ? 0 : m_owner->searchUpperBound_cvt(key);
		if (m_keyIdx < m_owner->m_index.size()) {
			*id = m_owner->m_index.get(m_keyIdx);
			retKey->erase_all();
			m_owner->getValueAppend(*id, retKey, nullptr);
			m_keyIdx++;
			return 1;
		}
		return -1;
	}
};

class FixedLenKeyIndex::MyIndexIterBackward : public IndexIterator {
public:
	size_t m_keyIdx;
	const FixedLenKeyIndex* m_owner;

	MyIndexIterBackward(const FixedLenKeyIndex* owner) {
		m_keyIdx = owner->m_index.size();
		m_owner = owner;
	}

	void reset() override {
		m_keyIdx = m_owner->m_index.size();
	}

	bool increment(llong* id, valvec<byte>* key) override {
		assert(nullptr != key);
		if (m_keyIdx > 0) {
			*id = m_owner->m_index.get(--m_keyIdx);
			key->erase_all();
			m_owner->getValueAppend(*id, key, nullptr);
			return true;
		}
		return false;
	}

	int seekLowerBound(fstring key, llong* id, valvec<byte>* retKey) override {
		assert(nullptr != retKey);
		if (key.empty()) {
			m_keyIdx = m_owner->m_index.size();
		} else {
			m_keyIdx = m_owner->searchUpperBound_cvt(key);
		}
		if (m_keyIdx > 0) {
			*id = m_owner->m_index[--m_keyIdx];
			retKey->erase_all();
			m_owner->getValueAppend(*id, retKey, nullptr);
			return key == *retKey ? 0 : 1;
		}
		return -1;
	}

	int seekUpperBound(fstring key, llong* id, valvec<byte>* retKey) override {
		assert(nullptr != retKey);
		if (key.empty()) {
			m_keyIdx = m_owner->m_index.size();
		} else {
			m_keyIdx = m_owner->searchLowerBound_cvt(key);
		}
		if (m_keyIdx > 0) {
			*id = m_owner->m_index[--m_keyIdx];
			retKey->erase_all();
			m_owner->getValueAppend(*id, retKey, nullptr);
			return 1;
		}
		return -1;
	}
};

IndexIterator* FixedLenKeyIndex::createIndexIterForward(DbContext*) const {
	return new MyIndexIterForward(this);
}
IndexIterator* FixedLenKeyIndex::createIndexIterBackward(DbContext*) const {
	return new MyIndexIterBackward(this);
}

}} // namespace terark::db
<commit_msg>fixed_len_key_index.cpp: Fixed 2 long lived minor bugs<commit_after>#include "fixed_len_key_index.hpp"
#include <terark/io/FileStream.hpp>
#include <terark/io/DataIO.hpp>
#include <terark/util/mmap.hpp>

namespace terark { namespace db {

FixedLenKeyIndex::FixedLenKeyIndex(const Schema& schema) : m_schema(schema) {
	m_isOrdered = true;
	m_isIndexKeyByteLex = true;
	m_mmapBase = nullptr;
	m_mmapSize = 0;
	m_fixedLen = 0;
	m_uniqKeys = 0;
}

FixedLenKeyIndex::~FixedLenKeyIndex() {
	if (m_mmapBase) {
		m_keys.risk_release_ownership();
		m_index.risk_release_ownership();
		mmap_close(m_mmapBase, m_mmapSize);
	}
}

ReadableStore* FixedLenKeyIndex::getReadableStore() {
	return this;
}

ReadableIndex* FixedLenKeyIndex::getReadableIndex() {
	return this;
}

///@{ ordered and unordered index
llong FixedLenKeyIndex::indexStorageSize() const {
	return m_index.mem_size();
}

void
FixedLenKeyIndex::searchExactAppend(fstring key, valvec<llong>* recIdvec, DbContext*)
const {
	size_t f = m_fixedLen;
	if (m_schema.m_needEncodeToLexByteComparable) {
		byte* cvtbuf = (byte*)alloca(f);
		memcpy(cvtbuf, key.data(), f);
		m_schema.byteLexEncode(cvtbuf, f);
		key.p = (char*)cvtbuf;
	}
	size_t j = searchLowerBound(key);
	size_t id;
	const  byte* keysData = m_keys.data();
	while (j < m_index.size() &&
		   memcmp(keysData + f*(id=m_index[j]), key.p, f) == 0)
	{
		recIdvec->push_back(id);
		++j;
	}
}

size_t FixedLenKeyIndex::searchLowerBound_cvt(fstring key) const {
	if (m_schema.m_needEncodeToLexByteComparable) {
		size_t fixlen = m_fixedLen;
		byte*  cvtbuf = (byte*)alloca(fixlen);
		memcpy(cvtbuf, key.data(), fixlen);
		m_schema.byteLexEncode(cvtbuf, fixlen);
		return searchLowerBound(fstring(cvtbuf, fixlen));
	}
	else {
		return searchLowerBound(key);
	}
}

size_t FixedLenKeyIndex::searchUpperBound_cvt(fstring key) const {
	if (m_schema.m_needEncodeToLexByteComparable) {
		size_t fixlen = m_fixedLen;
		byte*  cvtbuf = (byte*)alloca(fixlen);
		memcpy(cvtbuf, key.data(), fixlen);
		m_schema.byteLexEncode(cvtbuf, fixlen);
		return searchUpperBound(fstring(cvtbuf, fixlen));
	}
	else {
		return searchUpperBound(key);
	}
}

size_t FixedLenKeyIndex::searchLowerBound(fstring key) const {
	assert(key.size() == m_fixedLen);
	auto indexData = m_index.data();
	auto indexBits = m_index.uintbits();
	auto indexMask = m_index.uintmask();
	auto keysData = m_keys.data();
	size_t fixlen = m_fixedLen;
	size_t i = 0, j = m_index.size();
	while (i < j) {
		size_t mid = (i + j) / 2;
		size_t hitPos = UintVecMin0::fast_get(indexData, indexBits, indexMask, mid);
		const byte* hitKey = keysData + fixlen * hitPos;
		if (memcmp(hitKey, key.p, fixlen) < 0)
			i = mid + 1;
		else
			j = mid;
	}
	return i;
}

size_t FixedLenKeyIndex::searchUpperBound(fstring key) const {
	assert(key.size() == m_fixedLen);
	auto indexData = m_index.data();
	auto indexBits = m_index.uintbits();
	auto indexMask = m_index.uintmask();
	auto keysData = m_keys.data();
	size_t fixlen = m_fixedLen;
	size_t i = 0, j = m_index.size();
	while (i < j) {
		size_t mid = (i + j) / 2;
		size_t hitPos = UintVecMin0::fast_get(indexData, indexBits, indexMask, mid);
		const byte* hitKey = keysData + fixlen * hitPos;
		if (memcmp(hitKey, key.p, fixlen) <= 0)
			i = mid + 1;
		else
			j = mid;
	}
	return i;
}

///@}

llong FixedLenKeyIndex::dataStorageSize() const {
	return m_keys.used_mem_size() + m_index.mem_size();
}

llong FixedLenKeyIndex::dataInflateSize() const {
	return m_keys.size();
}

llong FixedLenKeyIndex::numDataRows() const {
	return m_index.size();
}

void FixedLenKeyIndex::getValueAppend(llong id, valvec<byte>* val, DbContext*) const {
	assert(id >= 0);
	size_t idx = size_t(id);
	assert(idx < m_index.size());
	size_t fixlen = m_fixedLen;
	const byte* dataPtr = m_keys.data() + fixlen * idx;
	size_t oldsize = val->size();
	val->append(dataPtr, fixlen);
	if (m_schema.m_needEncodeToLexByteComparable) {
		m_schema.byteLexDecode(val->data() + oldsize, fixlen);
	}
}

StoreIterator* FixedLenKeyIndex::createStoreIterForward(DbContext*) const {
	return nullptr; // not needed
}

StoreIterator* FixedLenKeyIndex::createStoreIterBackward(DbContext*) const {
	return nullptr; // not needed
}

void FixedLenKeyIndex::build(const Schema& schema, SortableStrVec& strVec) {
	size_t fixlen = schema.getFixedRowLen();
	byte*  data = strVec.m_strpool.data();
	size_t rows = strVec.m_strpool.size() / fixlen;
	assert(strVec.m_index.size() == 0);
	assert(strVec.m_strpool.size() % fixlen == 0);
	if (schema.m_needEncodeToLexByteComparable) {
		for (size_t i = 0; i < rows; ++i) {
			schema.byteLexEncode(data + i*fixlen, fixlen);
		}
	}
	valvec<uint32_t> index(rows, valvec_no_init());
	for (size_t i = 0; i < rows; ++i) index[i] = i;
	std::sort(index.begin(), index.end(),
		[data,fixlen](size_t x, size_t y) {
		const byte* xkey = data + fixlen * x;
		const byte* ykey = data + fixlen * y;
		int ret = memcmp(xkey, ykey, fixlen);
		if (ret)
			return ret < 0;
		else
			return x < y;
	});
	m_fixedLen = fixlen;
	m_uniqKeys = 0;
	for(size_t i = 0; i < rows; ) {
		size_t j = i;
		int cmp = 0;
		do {
			const byte* xkey = data + fixlen * (j + 0);
			const byte* ykey = data + fixlen * (j + 1);
			cmp = memcmp(xkey, ykey, fixlen);
			++j;
		} while (0 == cmp);
		i = j;
		m_uniqKeys++;
	}
	m_isUnique = m_uniqKeys == rows;
	auto minIdx = m_index.build_from(index);
	(void)minIdx;
	assert(0 == minIdx);
	m_keys.clear();
	m_keys.swap(strVec.m_strpool);
}

namespace {
	struct Header {
		uint32_t rows;
		uint32_t uniqKeys;
		uint32_t fixlen;
		uint32_t padding;
	};
}

void FixedLenKeyIndex::load(PathRef path) {
	auto fpath = path + ".fixlen";
	m_mmapBase = (byte_t*)mmap_load(fpath.string(), &m_mmapSize);
	auto h = (const Header*)m_mmapBase;
	m_isUnique = h->uniqKeys == h->rows;
	m_uniqKeys = h->uniqKeys;
	m_fixedLen = h->fixlen;
	size_t rbits = terark_bsr_u32(h->rows-1) + 1;
	size_t keyMemSize = h->fixlen * h->rows;
	m_keys .risk_set_data((byte*)(h+1) , keyMemSize);
	keyMemSize = (keyMemSize + 15) & ~15;
	m_index.risk_set_data((byte*)(h+1) + keyMemSize, h->rows, rbits);
}

void FixedLenKeyIndex::save(PathRef path) const {
	auto fpath = path + ".fixlen";
	NativeDataOutput<FileStream> dio;
	dio.open(fpath.string().c_str(), "wb");
	Header h;
	h.rows     = uint32_t(m_index.size());
	h.uniqKeys = m_uniqKeys;
	h.fixlen   = m_fixedLen;
	h.padding  = 0;
	dio.ensureWrite(&h, sizeof(h));
	byte zero[16];
	memset(zero, 0, sizeof(zero));
	dio.ensureWrite(m_keys .data(), m_keys .used_mem_size());
	if (m_keys.used_mem_size() % 16 != 0) {
		dio.ensureWrite(zero, 16 - m_keys.used_mem_size() % 16);
	}
	dio.ensureWrite(m_index.data(), m_index.mem_size());
}

class FixedLenKeyIndex::MyIndexIterForward : public IndexIterator {
public:
	size_t m_keyIdx;
	const FixedLenKeyIndex* m_owner;

	MyIndexIterForward(const FixedLenKeyIndex* owner) {
		m_keyIdx = 0;
		m_owner = owner;
	}

	void reset() override {
		m_keyIdx = 0;
	}

	bool increment(llong* id, valvec<byte>* key) override {
		assert(nullptr != key);
		if (m_keyIdx < m_owner->m_index.size()) {
			*id = m_owner->m_index.get(m_keyIdx++);
			key->erase_all();
			m_owner->getValueAppend(*id, key, nullptr);
			return true;
		}
		return false;
	}

	int seekLowerBound(fstring key, llong* id, valvec<byte>* retKey) override {
		assert(nullptr != retKey);
		m_keyIdx = key.empty() ? 0 : m_owner->searchLowerBound_cvt(key);
		if (m_keyIdx < m_owner->m_index.size()) {
			*id = m_owner->m_index.get(m_keyIdx);
			retKey->erase_all();
			m_owner->getValueAppend(*id, retKey, nullptr);
			m_keyIdx++;
			return key == *retKey ? 0 : 1;
		}
		return -1;
	}

	int seekUpperBound(fstring key, llong* id, valvec<byte>* retKey) override {
		assert(nullptr != retKey);
		m_keyIdx = key.empty() ? 0 : m_owner->searchUpperBound_cvt(key);
		if (m_keyIdx < m_owner->m_index.size()) {
			*id = m_owner->m_index.get(m_keyIdx);
			retKey->erase_all();
			m_owner->getValueAppend(*id, retKey, nullptr);
			m_keyIdx++;
			return 1;
		}
		return -1;
	}
};

class FixedLenKeyIndex::MyIndexIterBackward : public IndexIterator {
public:
	size_t m_keyIdx;
	const FixedLenKeyIndex* m_owner;

	MyIndexIterBackward(const FixedLenKeyIndex* owner) {
		m_keyIdx = owner->m_index.size();
		m_owner = owner;
	}

	void reset() override {
		m_keyIdx = m_owner->m_index.size();
	}

	bool increment(llong* id, valvec<byte>* key) override {
		assert(nullptr != key);
		if (m_keyIdx > 0) {
			*id = m_owner->m_index.get(--m_keyIdx);
			key->erase_all();
			m_owner->getValueAppend(*id, key, nullptr);
			return true;
		}
		return false;
	}

	int seekLowerBound(fstring key, llong* id, valvec<byte>* retKey) override {
		assert(nullptr != retKey);
		if (key.empty()) {
			m_keyIdx = m_owner->m_index.size();
		} else {
			m_keyIdx = m_owner->searchUpperBound_cvt(key);
		}
		if (m_keyIdx > 0) {
			*id = m_owner->m_index[--m_keyIdx];
			retKey->erase_all();
			m_owner->getValueAppend(*id, retKey, nullptr);
			return key == *retKey ? 0 : 1;
		}
		return -1;
	}

	int seekUpperBound(fstring key, llong* id, valvec<byte>* retKey) override {
		assert(nullptr != retKey);
		if (key.empty()) {
			m_keyIdx = m_owner->m_index.size();
		} else {
			m_keyIdx = m_owner->searchLowerBound_cvt(key);
		}
		if (m_keyIdx > 0) {
			*id = m_owner->m_index[--m_keyIdx];
			retKey->erase_all();
			m_owner->getValueAppend(*id, retKey, nullptr);
			return 1;
		}
		return -1;
	}
};

IndexIterator* FixedLenKeyIndex::createIndexIterForward(DbContext*) const {
	return new MyIndexIterForward(this);
}
IndexIterator* FixedLenKeyIndex::createIndexIterBackward(DbContext*) const {
	return new MyIndexIterBackward(this);
}

}} // namespace terark::db
<|endoftext|>


<commit_before>#include <memory>

#include "gtest/gtest.h"

#include "../../lib/operators/get_table.hpp"
#include "../../lib/storage/storage_manager.hpp"
#include "../../lib/storage/table.hpp"

TEST(operators_get_table, get_output_returns_correct_table) {
  auto t = std::make_shared<opossum::Table>(opossum::Table(2));
  opossum::StorageManager::get().add_table("aNiceTestTable", t);

  auto gt = std::make_shared<opossum::GetTable>("aNiceTestTable");
  gt->execute();

  EXPECT_EQ(gt->get_output(), t);
}

TEST(operators_get_table, get_output_throwns_on_unknown_table_name) {
  auto t = std::make_shared<opossum::Table>(opossum::Table(2));
  opossum::StorageManager::get().add_table("aNiceTestTable", t);

  auto gt = std::make_shared<opossum::GetTable>("anUglyTestTable");
  gt->execute();

  EXPECT_THROW(gt->get_output(), std::exception);
}
<commit_msg>Updated get_table_test (partial pull from origin/test, written by NT)<commit_after>#include <memory>

#include "gtest/gtest.h"

#include "../../lib/operators/get_table.hpp"
#include "../../lib/storage/storage_manager.hpp"
#include "../../lib/storage/table.hpp"

namespace opossum {
// The fixture for testing class GetTable.
class operators_get_table : public ::testing::Test {
  virtual void SetUp() {
    test_table = std::make_shared<opossum::Table>(opossum::Table(2));
    opossum::StorageManager::get().add_table("aNiceTestTable", test_table);
  }

 public:
  std::shared_ptr<opossum::Table> test_table;
};

TEST_F(operators_get_table, get_output_returns_correct_table) {
  auto gt = std::make_shared<opossum::GetTable>("aNiceTestTable");
  gt->execute();

  EXPECT_EQ(gt->get_output(), test_table);
}

TEST_F(operators_get_table, get_output_throwns_on_unknown_table_name) {
  auto gt = std::make_shared<opossum::GetTable>("anUglyTestTable");
  gt->execute();

  EXPECT_THROW(gt->get_output(), std::exception) << "Should throw unkown table name exception";
}

}  // namespace opossum
<|endoftext|>


<commit_before>#pragma once

#include "Game.hpp"

#include "GLSLProgram.hpp"

#include "Mesh.hpp"
#include "Triangle.hpp"
#include "Quad.hpp"

#include "Model.hpp"
#include "AABB.hpp"
#include "OrthoCamera.hpp"
#include "TrackingOrthoCamera.hpp"
#include "PerspectiveCamera.hpp"

class Pong : public Game {
public:

    GLSLProgram* glslProgram = nullptr;
    std::vector<Model*> modelList;
    std::vector<Model*> scoreMarkerList;

    OrthoCamera * orthoCamera = nullptr;
    TrackingOrthoCamera * trackingCamera = nullptr;
    Camera * camera = orthoCamera;

    Mesh* quad = nullptr;
    Mesh * triangle = nullptr;

    Model* ball = nullptr;
    Model* batLeft = nullptr;
    Model* batRight = nullptr;
    Model* wallLeft = nullptr;
    Model* wallRight = nullptr;

    GLfloat batSpeed = 100.0f;

    glm::ivec2 score = glm::vec2(0);
    Pong(std::string windowName = "Pong");
    ~Pong();

protected:
    const int scoreLimit = 5;
    void updateSimulation(double simLength = 0.02) override;
    void render() override;
    void handleInput() override;
    void handleBallCollision(Model * other);
    void handleBatCollision(Model * bat, Model * other);
    void incrementScore(int player);
};
<commit_msg>remove include for perspective (removed)<commit_after>#pragma once

#include "Game.hpp"

#include "GLSLProgram.hpp"

#include "Mesh.hpp"
#include "Triangle.hpp"
#include "Quad.hpp"

#include "Model.hpp"
#include "AABB.hpp"
#include "OrthoCamera.hpp"
#include "TrackingOrthoCamera.hpp"

class Pong : public Game {
public:

    GLSLProgram* glslProgram = nullptr;
    std::vector<Model*> modelList;
    std::vector<Model*> scoreMarkerList;

    OrthoCamera * orthoCamera = nullptr;
    TrackingOrthoCamera * trackingCamera = nullptr;
    Camera * camera = orthoCamera;

    Mesh* quad = nullptr;
    Mesh * triangle = nullptr;

    Model* ball = nullptr;
    Model* batLeft = nullptr;
    Model* batRight = nullptr;
    Model* wallLeft = nullptr;
    Model* wallRight = nullptr;

    GLfloat batSpeed = 100.0f;

    glm::ivec2 score = glm::vec2(0);
    Pong(std::string windowName = "Pong");
    ~Pong();

protected:
    const int scoreLimit = 5;
    void updateSimulation(double simLength = 0.02) override;
    void render() override;
    void handleInput() override;
    void handleBallCollision(Model * other);
    void handleBatCollision(Model * bat, Model * other);
    void incrementScore(int player);
};
<|endoftext|>


<commit_before>/*
 * Copyright (C) FFLAS-FFPACK
 * Written by Hongguang ZHU <zhuhongguang2014@gmail.com>
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */
//#define  __FFLASFFPACK_SEQUENTIAL

//#define ENABLE_ALL_CHECKINGS 1

//#include "fflas-ffpack/fflas-ffpack-config.h"
#include <givaro/modular-integer.h>

#include <iomanip>
#include <iostream>

#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "fflas-ffpack/utils/test-utils.h"
#include <givaro/modular.h>
#include <givaro/modular-balanced.h>

using namespace std;
using namespace FFLAS;
using namespace FFPACK;
using Givaro::Modular;
using Givaro::ModularBalanced;

template<typename Field, class Cut, class Param>
void run_solve(const Field &F, size_t m,
    typename Field::Element_ptr A, const size_t lda,
    typename Field::Element_ptr x, const int incx,
    typename Field::ConstElement_ptr b, const int incb,
    const FFLAS::ParSeqHelper::Parallel<Cut,Param>& parH)
{
    FFPACK::pSolve(F, m, A, lda, x, incx, b, incb);
}
template<typename Field>
void run_solve(const Field &F, size_t m,
    typename Field::Element_ptr A, const size_t lda,
    typename Field::Element_ptr x, const int incx,
    typename Field::ConstElement_ptr b, const int incb,
    const FFLAS::ParSeqHelper::Sequential& seqH)
{
    FFPACK::Solve(F, m, A, lda, x, incx, b, incb);
}

template<typename Field, class RandIter, class PSHelper>
bool check_solve(const Field &F, size_t m, RandIter& Rand, const PSHelper& psH){

    typename Field::Element_ptr A, A2, B, B2, x;

    size_t lda,incb,incx;
    lda=m;
    incb=1;
    incx=1;
    A  = FFLAS::fflas_new(F,m,lda);
    A2 = FFLAS::fflas_new(F,m,lda);
    B  = FFLAS::fflas_new(F,m,incb);
    B2 = FFLAS::fflas_new(F,m,incb);
    x  = FFLAS::fflas_new(F,m,incx);

    RandomMatrixWithRank (F,  m,  m, m, A, lda, Rand);

    RandomMatrix (F, m, 1, B, incb, Rand);

    FFLAS::fassign (F, m, B, incb, B2, incb);
    FFLAS::fassign (F, m, m, A, lda, A2, lda);
#ifdef DEBUG
    FFLAS::WriteMatrix(std::cout<<"b:="<<std::endl,F,m,1,B,incb)<<std::endl;
#endif

    FFLAS::Timer t; t.clear();
    double time=0.0;
    t.clear();
    t.start();
    run_solve(F, m, A, lda, x, incx, B, incb, psH);
    t.stop();
    time+=t.realtime();

    FFLAS::fgemv(F, FFLAS::FflasNoTrans, m, m, F.one, A2, lda, x, incx, F.zero, B, incb);

    bool ok = true;
    if (FFLAS::fequal (F, m, 1, B2, incb, B, incb)){

        cout << " PASSED ("<<time<<")";

    } else{
#ifdef DEBUG
        FFLAS::WriteMatrix(std::cout<<"A*x:="<<std::endl,F,m,1,B2,incb)<<std::endl;
        FFLAS::WriteMatrix(std::cout<<"b:="<<std::endl,F,m,1,B,incb)<<std::endl;
#endif
        cout << " FAILED ("<<time<<")";
        ok=false;

    }

    FFLAS::fflas_delete(A);
    FFLAS::fflas_delete(A2);
    FFLAS::fflas_delete(B);
    FFLAS::fflas_delete(B2);
    FFLAS::fflas_delete(x);
    return ok;
}

template <class Field>
bool run_with_field (Givaro::Integer q, size_t b, size_t m, size_t iters, uint64_t seed){
    bool ok = true ;
    int nbit=(int)iters;

    while (ok &&  nbit){
        //typedef typename Field::Element Element ;
        // choose Field
        Field* F= chooseField<Field>(q,b,seed);
        typename Field::RandIter G(*F,0,seed++);
        if (F==nullptr)
            return true;

        std::ostringstream oss;
        F->write(oss);
        std::cout.fill('.');
        std::cout<<"Checking ";
        std::cout.width(50);
        std::cout<<oss.str();
        std::cout<<" ... ";

            // testing a sequential run
        std::cout<<" seq: ";
        ok = ok && check_solve(*F,m,G, FFLAS::ParSeqHelper::Sequential());

            // testing a parallel run
        std::cout<<" par: ";
        FFLAS::ParSeqHelper::Parallel<FFLAS::CuttingStrategy::Recursive,FFLAS::StrategyParameter::Threads> parH;
        ok = ok && check_solve(*F,m,G, parH);

        std::cout<<std::endl;
        nbit--;
        delete F;

    }

    return ok;
}

int main(int argc, char** argv)
{
    cerr<<setprecision(10);
    Givaro::Integer q=-1;
    size_t b=0;
    size_t m=1000;

    size_t iters=4;
    bool loop=false;
    uint64_t seed = getSeed();
    Argument as[] = {
        { 'q', "-q Q", "Set the field characteristic (-1 for random).",         TYPE_INTEGER , &q },
        { 'b', "-b B", "Set the bitsize of the field characteristic.",  TYPE_INT , &b },
        { 'm', "-m M", "Set the dimension of unknown square matrix.",      TYPE_INT , &m },
        { 'i', "-i R", "Set number of repetitions.",            TYPE_INT , &iters },
        { 'l', "-loop Y/N", "run the test in an infinite loop.", TYPE_BOOL , &loop },
        { 's', "-s seed", "Set seed for the random generator", TYPE_UINT64, &seed },
        END_OF_ARGUMENTS
    };

    FFLAS::parseArguments(argc,argv,as);

    bool ok = true;

    do{
        ok = ok && run_with_field<Modular<double> >(q,b,m,iters,seed);
        ok = ok && run_with_field<ModularBalanced<double> >(q,b,m,iters,seed);
        ok = ok && run_with_field<Modular<float> >(q,b,m,iters,seed);
        ok = ok && run_with_field<ModularBalanced<float> >(q,b,m,iters,seed);
        ok = ok && run_with_field<Modular<int32_t> >(q,b,m,iters,seed);
        ok = ok && run_with_field<ModularBalanced<int32_t> >(q,b,m,iters,seed);
        ok = ok && run_with_field<Modular<int64_t> >(q,b,m,iters,seed);
        ok = ok && run_with_field<ModularBalanced<int64_t> >(q,b,m,iters,seed);
        ok = ok &&run_with_field<Givaro::Modular<Givaro::Integer> > (q,5,m/6,iters,seed);
        ok = ok &&run_with_field<Givaro::Modular<Givaro::Integer> > (q,(b?b:512),m/6,iters,seed);

    } while (loop && ok);

    return !ok ;
}
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<commit_msg>cleaned up the test-solve<commit_after>/*
 * Copyright (C) FFLAS-FFPACK
 * Written by Hongguang ZHU <zhuhongguang2014@gmail.com>
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */
//#define  __FFLASFFPACK_SEQUENTIAL

//#define ENABLE_ALL_CHECKINGS 1

//#include "fflas-ffpack/fflas-ffpack-config.h"
#include <givaro/modular-integer.h>

#include <iomanip>
#include <iostream>

#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "fflas-ffpack/utils/test-utils.h"
#include <givaro/modular.h>
#include <givaro/modular-balanced.h>

using namespace std;
using namespace FFLAS;
using namespace FFPACK;
using Givaro::Modular;
using Givaro::ModularBalanced;

template<typename Field, class Cut, class Param>
void run_solve(const Field &F, size_t m,
    typename Field::Element_ptr A, const size_t lda,
    typename Field::Element_ptr x, const int incx,
    typename Field::ConstElement_ptr b, const int incb,
    const FFLAS::ParSeqHelper::Parallel<Cut,Param>& parH)
{
    FFPACK::pSolve(F, m, A, lda, x, incx, b, incb);
}
template<typename Field>
void run_solve(const Field &F, size_t m,
    typename Field::Element_ptr A, const size_t lda,
    typename Field::Element_ptr x, const int incx,
    typename Field::ConstElement_ptr b, const int incb,
    const FFLAS::ParSeqHelper::Sequential& seqH)
{
    FFPACK::Solve(F, m, A, lda, x, incx, b, incb);
}

template<typename Field, class RandIter, class PSHelper>
bool check_solve(const Field &F, size_t m, RandIter& Rand, const PSHelper& psH){

    typename Field::Element_ptr A, A2, B, B2, x;

    size_t lda,incb,incx;
    lda=m;
    incb=1;
    incx=1;
    A  = FFLAS::fflas_new(F,m,lda);
    A2 = FFLAS::fflas_new(F,m,lda);
    B  = FFLAS::fflas_new(F,m,incb);
    B2 = FFLAS::fflas_new(F,m,incb);
    x  = FFLAS::fflas_new(F,m,incx);

    RandomMatrixWithRank (F,  m,  m, m, A, lda, Rand);

    RandomMatrix (F, m, 1, B, incb, Rand);

    FFLAS::fassign (F, m, B, incb, B2, incb);
    FFLAS::fassign (F, m, m, A, lda, A2, lda);
#ifdef DEBUG
    FFLAS::WriteMatrix(std::cout<<"b:="<<std::endl,F,m,1,B,incb)<<std::endl;
#endif

    FFLAS::Timer t; t.clear();
    double time=0.0;
    t.clear();
    t.start();
    run_solve(F, m, A, lda, x, incx, B, incb, psH);
    t.stop();
    time+=t.realtime();

    FFLAS::fgemv(F, FFLAS::FflasNoTrans, m, m, F.one, A2, lda, x, incx, F.zero, B, incb);

    bool ok = true;
    if (FFLAS::fequal (F, m, 1, B2, incb, B, incb)){

        cout << " PASSED ("<<time<<")";

    } else{
#ifdef DEBUG
        FFLAS::WriteMatrix(std::cout<<"A*x:="<<std::endl,F,m,1,B2,incb)<<std::endl;
        FFLAS::WriteMatrix(std::cout<<"b:="<<std::endl,F,m,1,B,incb)<<std::endl;
#endif
        cout << " FAILED ("<<time<<")";
        ok=false;

    }

    FFLAS::fflas_delete(A);
    FFLAS::fflas_delete(A2);
    FFLAS::fflas_delete(B);
    FFLAS::fflas_delete(B2);
    FFLAS::fflas_delete(x);
    return ok;
}

template <class Field>
bool run_with_field (Givaro::Integer q, size_t b, size_t m, size_t iters, uint64_t seed){
    bool ok = true ;
    int nbit=(int)iters;

    while (ok &&  nbit){
        //typedef typename Field::Element Element ;
        // choose Field
        Field* F= chooseField<Field>(q,b,seed);
        typename Field::RandIter G(*F,0,seed++);
        if (F==nullptr)
            return true;

        std::ostringstream oss;
        F->write(oss);
        std::cout.fill('.');
        std::cout<<"Checking ";
        std::cout.width(50);
        std::cout<<oss.str();
        std::cout<<" ... ";

            // testing a sequential run
        std::cout<<" seq: ";
        ok = ok && check_solve(*F,m,G, FFLAS::ParSeqHelper::Sequential());

            // testing a parallel run
        std::cout<<" par: ";
        ok = ok && check_solve(*F,m,G,
        FFLAS::ParSeqHelper::Parallel<FFLAS::CuttingStrategy::Recursive,FFLAS::StrategyParameter::Threads>());

        std::cout<<std::endl;
        nbit--;
        delete F;

    }

    return ok;
}

int main(int argc, char** argv)
{
    cerr<<setprecision(10);
    Givaro::Integer q=-1;
    size_t b=0;
    size_t m=1000;

    size_t iters=4;
    bool loop=false;
    uint64_t seed = getSeed();
    Argument as[] = {
        { 'q', "-q Q", "Set the field characteristic (-1 for random).",         TYPE_INTEGER , &q },
        { 'b', "-b B", "Set the bitsize of the field characteristic.",  TYPE_INT , &b },
        { 'm', "-m M", "Set the dimension of unknown square matrix.",      TYPE_INT , &m },
        { 'i', "-i R", "Set number of repetitions.",            TYPE_INT , &iters },
        { 'l', "-loop Y/N", "run the test in an infinite loop.", TYPE_BOOL , &loop },
        { 's', "-s seed", "Set seed for the random generator", TYPE_UINT64, &seed },
        END_OF_ARGUMENTS
    };

    FFLAS::parseArguments(argc,argv,as);

    bool ok = true;

    do{
        ok = ok && run_with_field<Modular<double> >(q,b,m,iters,seed);
        ok = ok && run_with_field<ModularBalanced<double> >(q,b,m,iters,seed);
        ok = ok && run_with_field<Modular<float> >(q,b,m,iters,seed);
        ok = ok && run_with_field<ModularBalanced<float> >(q,b,m,iters,seed);
        ok = ok && run_with_field<Modular<int32_t> >(q,b,m,iters,seed);
        ok = ok && run_with_field<ModularBalanced<int32_t> >(q,b,m,iters,seed);
        ok = ok && run_with_field<Modular<int64_t> >(q,b,m,iters,seed);
        ok = ok && run_with_field<ModularBalanced<int64_t> >(q,b,m,iters,seed);
        ok = ok &&run_with_field<Givaro::Modular<Givaro::Integer> > (q,5,m/6,iters,seed);
        ok = ok &&run_with_field<Givaro::Modular<Givaro::Integer> > (q,(b?b:512),m/6,iters,seed);

    } while (loop && ok);

    return !ok ;
}
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<|endoftext|>


<commit_before>#include <iostream>

#include "GoBoard.h"
#include "Point.h"
#include "Seki.h"
#include "Semeai.h"

using namespace std;

//////////////////
//  セキの判定  //
//////////////////
void
CheckSeki( const game_info_t *game, bool seki[] )
{
  int i, j, k, pos, id;
  const char *board = game->board;
  const int *string_id = game->string_id;
  const string_t *string = game->string;
  bool seki_candidate[BOARD_MAX] = {false};
  int lib1, lib2;
  int lib1_id[4], lib2_id[4], lib1_ids, lib2_ids;
  int neighbor1_lib, neighbor2_lib;
  int neighbor4[4];
  bool already_checked;

  // 双方が自己アタリになっている座標を抽出
  for (i = 0; i < pure_board_max; i++) {
    pos = onboard_pos[i];
    if (IsSelfAtari(game, S_BLACK, pos) &&
	IsSelfAtari(game, S_WHITE, pos)) {
      seki_candidate[pos] = true;
    }
  }

  for (i = 0; i < MAX_STRING; i++) {
    // 連が存在しない,
    // または連の呼吸点数が2個でなければ次を調べる
    if (!string[i].flag || string[i].libs != 2) continue;

    // 連の大きさが6以上ならシミュレーションで
    // 自己アタリを打たないので次を調べる
    if (string[i].size >= 6) continue;

    lib1 = string[i].lib[0];
    lib2 = string[i].lib[lib1];
    // 連の持つ呼吸点がともにセキの候補
    if (seki_candidate[lib1] &&
	seki_candidate[lib2]) {
      // 呼吸点1の周囲の連のIDを取り出す
      GetNeighbor4(neighbor4, lib1);
      lib1_ids = 0;
      for (j = 0; j < 4; j++) {
	if (board[neighbor4[j]] == S_BLACK ||
	    board[neighbor4[j]] == S_WHITE) {
	  id = string_id[neighbor4[j]];
	  if (id != i) {
	    already_checked = false;
	    for (k = 0; k < lib1_ids; k++) {
	      if (lib1_id[k] == id) {
		already_checked = true;
		break;
	      }
	    }
	    if (!already_checked) {
	      lib1_id[lib1_ids++] = id;
	    }
	  }
	}
      }
      // 呼吸点2の周囲の連のIDを取り出す
      GetNeighbor4(neighbor4, lib2);
      lib2_ids = 0;
      for (j = 0; j < 4; j++) {
	if (board[neighbor4[j]] == S_BLACK ||
	    board[neighbor4[j]] == S_WHITE) {
	  id = string_id[neighbor4[j]];
	  if (id != i) {
	    already_checked = false;
	    for (k = 0; k < lib2_ids; k++) {
	      if (lib2_id[k] == id) {
		already_checked = true;
		break;
	      }
	    }
	    if (!already_checked) {
	      lib2_id[lib2_ids++] = id;
	    }
	  }
	}
      }

      if (lib1_ids == 1 && lib2_ids == 1) {
	neighbor1_lib = string[lib1_id[0]].lib[0];
	if (neighbor1_lib == lib1 ||
	    neighbor1_lib == lib2) {
	  neighbor1_lib = string[lib1_id[0]].lib[neighbor1_lib];
	}
	neighbor2_lib = string[lib2_id[0]].lib[0];
	if (neighbor2_lib == lib1 ||
	    neighbor2_lib == lib2) {
	  neighbor2_lib = string[lib2_id[0]].lib[neighbor2_lib];
	}
	if (neighbor1_lib == neighbor2_lib) {
	  if (eye_condition[Pat3(game->pat, neighbor1_lib)] != E_NOT_EYE) {
	    seki[lib1] = seki[lib2] = true;
	    seki[neighbor1_lib] = true;
	  }
	} else if (eye_condition[Pat3(game->pat, neighbor1_lib)] == E_COMPLETE_HALF_EYE &&
		   eye_condition[Pat3(game->pat, neighbor2_lib)] == E_COMPLETE_HALF_EYE) {
	  int tmp_id1 = 0, tmp_id2 = 0;
	  GetNeighbor4(neighbor4, neighbor1_lib);
	  for (j = 0; j < 4; j++) {
	    if (board[neighbor4[j]] == S_BLACK ||
		board[neighbor4[j]] == S_WHITE) {
	      id = string_id[neighbor4[j]];
	      if (id != lib1_id[0] &&
		  id != lib2_id[0] &&
		  id != tmp_id1) {
		tmp_id1 = id;
	      }
	    }
	  }
	  GetNeighbor4(neighbor4, neighbor2_lib);
	  for (j = 0; j < 4; j++) {
	    if (board[neighbor4[j]] == S_BLACK ||
		board[neighbor4[j]] == S_WHITE) {
	      id = string_id[neighbor4[j]];
	      if (id != lib1_id[0] &&
		  id != lib2_id[0] &&
		  id != tmp_id2) {
		tmp_id2 = id;
	      }
	    }
	  }
	  if (tmp_id1 == tmp_id2) {
	    seki[lib1] = seki[lib2] = true;
	    seki[neighbor1_lib] = seki[neighbor2_lib] = true;
	  }
	}
      }
    }
  }
}
<commit_msg>Refactoring<commit_after>#include <iostream>

#include "GoBoard.h"
#include "Point.h"
#include "Seki.h"
#include "Semeai.h"

using namespace std;

//////////////////
//  セキの判定  //
//////////////////
void
CheckSeki( const game_info_t *game, bool seki[] )
{
  const char *board = game->board;
  const int *string_id = game->string_id;
  const string_t *string = game->string;
  int id, lib1, lib2;
  int lib1_id[4], lib2_id[4], lib1_ids, lib2_ids;
  int neighbor1_lib, neighbor2_lib;
  int neighbor4[4];
  bool seki_candidate[BOARD_MAX] = {false};
  bool already_checked;

  // 双方が自己アタリになっている座標を抽出
  for (int i = 0; i < pure_board_max; i++) {
    const int pos = onboard_pos[i];
    if (IsSelfAtari(game, S_BLACK, pos) &&
	IsSelfAtari(game, S_WHITE, pos)) {
      seki_candidate[pos] = true;
    }
  }

  for (int i = 0; i < MAX_STRING; i++) {
    // 連が存在しない,
    // または連の呼吸点数が2個でなければ次を調べる
    if (!string[i].flag || string[i].libs != 2) continue;

    // 連の大きさが6以上ならシミュレーションで
    // 自己アタリを打たないので次を調べる
    if (string[i].size >= 6) continue;

    lib1 = string[i].lib[0];
    lib2 = string[i].lib[lib1];
    // 連の持つ呼吸点がともにセキの候補
    if (seki_candidate[lib1] &&
	seki_candidate[lib2]) {
      // 呼吸点1の周囲の連のIDを取り出す
      GetNeighbor4(neighbor4, lib1);
      lib1_ids = 0;
      for (int j = 0; j < 4; j++) {
	if (board[neighbor4[j]] == S_BLACK ||
	    board[neighbor4[j]] == S_WHITE) {
	  id = string_id[neighbor4[j]];
	  if (id != i) {
	    already_checked = false;
	    for (int k = 0; k < lib1_ids; k++) {
	      if (lib1_id[k] == id) {
		already_checked = true;
		break;
	      }
	    }
	    if (!already_checked) {
	      lib1_id[lib1_ids++] = id;
	    }
	  }
	}
      }
      // 呼吸点2の周囲の連のIDを取り出す
      GetNeighbor4(neighbor4, lib2);
      lib2_ids = 0;
      for (int j = 0; j < 4; j++) {
	if (board[neighbor4[j]] == S_BLACK ||
	    board[neighbor4[j]] == S_WHITE) {
	  id = string_id[neighbor4[j]];
	  if (id != i) {
	    already_checked = false;
	    for (int k = 0; k < lib2_ids; k++) {
	      if (lib2_id[k] == id) {
		already_checked = true;
		break;
	      }
	    }
	    if (!already_checked) {
	      lib2_id[lib2_ids++] = id;
	    }
	  }
	}
      }

      if (lib1_ids == 1 && lib2_ids == 1) {
	neighbor1_lib = string[lib1_id[0]].lib[0];
	if (neighbor1_lib == lib1 ||
	    neighbor1_lib == lib2) {
	  neighbor1_lib = string[lib1_id[0]].lib[neighbor1_lib];
	}
	neighbor2_lib = string[lib2_id[0]].lib[0];
	if (neighbor2_lib == lib1 ||
	    neighbor2_lib == lib2) {
	  neighbor2_lib = string[lib2_id[0]].lib[neighbor2_lib];
	}
	if (neighbor1_lib == neighbor2_lib) {
	  if (eye_condition[Pat3(game->pat, neighbor1_lib)] != E_NOT_EYE) {
	    seki[lib1] = seki[lib2] = true;
	    seki[neighbor1_lib] = true;
	  }
	} else if (eye_condition[Pat3(game->pat, neighbor1_lib)] == E_COMPLETE_HALF_EYE &&
		   eye_condition[Pat3(game->pat, neighbor2_lib)] == E_COMPLETE_HALF_EYE) {
	  int tmp_id1 = 0, tmp_id2 = 0;
	  GetNeighbor4(neighbor4, neighbor1_lib);
	  for (int j = 0; j < 4; j++) {
	    if (board[neighbor4[j]] == S_BLACK ||
		board[neighbor4[j]] == S_WHITE) {
	      id = string_id[neighbor4[j]];
	      if (id != lib1_id[0] &&
		  id != lib2_id[0] &&
		  id != tmp_id1) {
		tmp_id1 = id;
	      }
	    }
	  }
	  GetNeighbor4(neighbor4, neighbor2_lib);
	  for (int j = 0; j < 4; j++) {
	    if (board[neighbor4[j]] == S_BLACK ||
		board[neighbor4[j]] == S_WHITE) {
	      id = string_id[neighbor4[j]];
	      if (id != lib1_id[0] &&
		  id != lib2_id[0] &&
		  id != tmp_id2) {
		tmp_id2 = id;
	      }
	    }
	  }
	  if (tmp_id1 == tmp_id2) {
	    seki[lib1] = seki[lib2] = true;
	    seki[neighbor1_lib] = seki[neighbor2_lib] = true;
	  }
	}
      }
    }
  }
}
<|endoftext|>


<commit_before>#include "Tree.hpp"
#include <cstdio>

AABB::AABB() : sub(0), radius(-1) { }

AABB::AABB(Vec3Df& pos, float radius) : sub(0), pos(pos), radius(radius) {
}

AABB::~AABB() {
	// can safeley delete the null pointer
	delete[] sub;
}

int AABB::follow(const Vec3Df& v) {
	int axis = 0;
	for (int a = 0; a < 3; a++) {
		if (v.p[a] > pos.p[a] + radius)
			axis |= 1 << a;
	}

	return axis;
}

void AABB::split() {
	// if already subdivided, return
	if (sub)
		return;

	// make leaves
	sub = new AABB*[8];
	for (int x = 0; x < 2; x++){
		for (int y = 0; y < 2; y++){
			for (int z = 0; z < 2; z++){
				Vec3Df subpos(pos + Vec3Df(x * radius, y * radius, z * radius));
				float subradius = radius * 0.5f;

				sub[z * 4 + y * 2 + x] = new AABB(subpos, subradius);
			}
		}
	}
}

bool AABB::collidePlane(int axis, const Vec3Df& orig, const Vec3Df& dir) {
	// check axis plane
	float v1 = pos.p[axis];

	// flip
	bool flip = (dir.p[axis] < 0);
	//if (dir.p[axis] > 0 && orig.p[axis] > v1) flip = !flip;
	//if (dir.p[axis] < 0 && orig.p[axis] < v1 + 2 * radius) flip = !flip;
	if (flip) v1 += 2 * radius;

	// factor
	float a = (v1 - orig.p[axis]) / dir.p[axis];

	// behind the plane
	if (a < 0)
		return false;

	// other axis
	int axis2 = (axis + 1) % 3;
	int axis3 = (axis + 2) % 3;

	// other axis values
	float v2 = a * dir.p[axis2] + orig.p[axis2];
	float v3 = a * dir.p[axis3] + orig.p[axis3];

	// check 2D aabb
	if (pos.p[axis2] < v2 && v2 < pos.p[axis2] + 2 * radius)
	if (pos.p[axis3] < v3 && v3 < pos.p[axis3] + 2 * radius)
		return true;
	return false;
}

bool AABB::hit(const Vec3Df& orig, const Vec3Df& dir) {
	for (int i = 0; i < 3; i++)
		if (collidePlane(i, orig, dir))
			return true;
	return false;
}

inline float intersect(const Vec3Df& orig, const Vec3Df& dir, const Triangle* const triangle) {
	const Vertex* vertices = triangle->vertices;
	const Vec3Df& v0 = vertices[0].position;
	const Vec3Df& v1 = vertices[1].position;
	const Vec3Df& v2 = vertices[2].position;

	Vec3Df e1 = v1;
	e1 -= v0;
	Vec3Df e2 = v2;
	e2 -= v0;

	const Vec3Df P = cross(dir, e2);
	const float det = dot(e1, P);

	if (det < 0.000000001 && det > -0.000000001)
		return 0;

	float inv_det = 1.0f;
	inv_det /= det;

	Vec3Df T = orig;
	T -= vertices[0].position;

	float u = dot(T, P);
	u *= inv_det;
	if (u < 0.0f || u > 1.0f)
		return 0;

	const Vec3Df Q = cross(T, e1);

	float v = dot(dir, Q);
	v *= inv_det;
	if (v < 0.0f || u + v > 1.0f)
		return 0;

	float t = dot(e2, Q);
	t *= inv_det;

	return t;
}

float AABB::collide(const Vec3Df& orig, const Vec3Df& dir, Triangle** out) {
	// check hit with this cube
	if (!hit(orig, dir)) {
		*out = 0;
		return 1e10f;
	}

	// current closest triangle
	float shortest = 1e10f;
	Triangle* res = 0;

	// check with leaves
	for (unsigned int i = 0; i < leaves.size(); i++) {
		const float dist = intersect(orig, dir, leaves[i]);
		if (dist && dist < shortest) {
			shortest = dist;
			res = leaves[i];
		}
	}

	// check with subnodes
	// TODO: skip irrelevant subnodes
	if (sub) {
		for (int i = 0; i < 8; i++) {
			Triangle* res2;
			float dist = sub[i]->collide(orig, dir, &res2);
			if (dist < shortest) {
				res = res2;
				shortest = dist;
			}
		}
	}

	// hit
	*out = res;
	return shortest;
}

void Tree::calcSize(Mesh& mesh) {
	Vec3Df p1; // min
	Vec3Df p2; // max

	for (unsigned int i = 0; i < mesh.triangles.size(); i++) { // triangle
		for (int v = 0; v < 3; v++) { // vertex
			for (int d = 0; d < 3; d++) { // dimension
				const float dim = mesh.triangles[i].vertices[v].position.p[d];
				if (dim < p1.p[d])
					p1.p[d] = dim;
				if (dim > p2.p[d])
					p2.p[d] = dim;
			}
		}
	}
	printf("min: (%.1f,%.1f,%.1f)\n", p1.p[0], p1.p[1], p1.p[2]);
	printf("max: (%.1f,%.1f,%.1f)\n", p2.p[0], p2.p[1], p2.p[2]);

	Vec3Df dim = p2 - p1;
	float sdim = dim.p[0];
	sdim = fmax(sdim, dim.p[1]);
	sdim = fmax(sdim, dim.p[2]);

	root = new AABB(p1, sdim * 0.5f);
}

void Tree::build(Mesh& mesh) {
	printf("Building tree!\n");
	calcSize(mesh);

	for (unsigned int i = 0; i < mesh.triangles.size(); i++)
		add(mesh.triangles[i]);
}

void Tree::add(Triangle& tr) {
	AABB* current = root;
	int a0, a1, a2;

	int depth = 0;
	while (depth < MAX_DEPTH) {
		a0 = current->follow(tr.vertices[0].position);
		a1 = current->follow(tr.vertices[1].position);
		a2 = current->follow(tr.vertices[2].position);

		if (a0 != a1 || a1 != a2)
			break;

		current->split();
		current = current->sub[a0];
		depth++;
	}

	current->leaves.push_back(&tr);
}

float Tree::collide(const Vec3Df& orig, const Vec3Df& dir, Triangle** out) {
	return root->collide(orig, dir, out);
}
<commit_msg>removed print stuff<commit_after>#include "Tree.hpp"
#include <cstdio>

AABB::AABB() : sub(0), radius(-1) { }

AABB::AABB(Vec3Df& pos, float radius) : sub(0), pos(pos), radius(radius) {
}

AABB::~AABB() {
	// can safeley delete the null pointer
	delete[] sub;
}

int AABB::follow(const Vec3Df& v) {
	int axis = 0;
	for (int a = 0; a < 3; a++) {
		if (v.p[a] > pos.p[a] + radius)
			axis |= 1 << a;
	}

	return axis;
}

void AABB::split() {
	// if already subdivided, return
	if (sub)
		return;

	// make leaves
	sub = new AABB*[8];
	for (int x = 0; x < 2; x++){
		for (int y = 0; y < 2; y++){
			for (int z = 0; z < 2; z++){
				Vec3Df subpos(pos + Vec3Df(x * radius, y * radius, z * radius));
				float subradius = radius * 0.5f;

				sub[z * 4 + y * 2 + x] = new AABB(subpos, subradius);
			}
		}
	}
}

bool AABB::collidePlane(int axis, const Vec3Df& orig, const Vec3Df& dir) {
	// check axis plane
	float v1 = pos.p[axis];

	// flip
	bool flip = (dir.p[axis] < 0);
	//if (dir.p[axis] > 0 && orig.p[axis] > v1) flip = !flip;
	//if (dir.p[axis] < 0 && orig.p[axis] < v1 + 2 * radius) flip = !flip;
	if (flip) v1 += 2 * radius;

	// factor
	float a = (v1 - orig.p[axis]) / dir.p[axis];

	// behind the plane
	if (a < 0)
		return false;

	// other axis
	int axis2 = (axis + 1) % 3;
	int axis3 = (axis + 2) % 3;

	// other axis values
	float v2 = a * dir.p[axis2] + orig.p[axis2];
	float v3 = a * dir.p[axis3] + orig.p[axis3];

	// check 2D aabb
	if (pos.p[axis2] < v2 && v2 < pos.p[axis2] + 2 * radius)
	if (pos.p[axis3] < v3 && v3 < pos.p[axis3] + 2 * radius)
		return true;
	return false;
}

bool AABB::hit(const Vec3Df& orig, const Vec3Df& dir) {
	for (int i = 0; i < 3; i++)
		if (collidePlane(i, orig, dir))
			return true;
	return false;
}

inline float intersect(const Vec3Df& orig, const Vec3Df& dir, const Triangle* const triangle) {
	const Vertex* vertices = triangle->vertices;
	const Vec3Df& v0 = vertices[0].position;
	const Vec3Df& v1 = vertices[1].position;
	const Vec3Df& v2 = vertices[2].position;

	Vec3Df e1 = v1;
	e1 -= v0;
	Vec3Df e2 = v2;
	e2 -= v0;

	const Vec3Df P = cross(dir, e2);
	const float det = dot(e1, P);

	if (det < 0.000000001 && det > -0.000000001)
		return 0;

	float inv_det = 1.0f;
	inv_det /= det;

	Vec3Df T = orig;
	T -= vertices[0].position;

	float u = dot(T, P);
	u *= inv_det;
	if (u < 0.0f || u > 1.0f)
		return 0;

	const Vec3Df Q = cross(T, e1);

	float v = dot(dir, Q);
	v *= inv_det;
	if (v < 0.0f || u + v > 1.0f)
		return 0;

	float t = dot(e2, Q);
	t *= inv_det;

	return t;
}

float AABB::collide(const Vec3Df& orig, const Vec3Df& dir, Triangle** out) {
	// check hit with this cube
	if (!hit(orig, dir)) {
		*out = 0;
		return 1e10f;
	}

	// current closest triangle
	float shortest = 1e10f;
	Triangle* res = 0;

	// check with leaves
	for (unsigned int i = 0; i < leaves.size(); i++) {
		const float dist = intersect(orig, dir, leaves[i]);
		if (dist && dist < shortest) {
			shortest = dist;
			res = leaves[i];
		}
	}

	// check with subnodes
	// TODO: skip irrelevant subnodes
	if (sub) {
		for (int i = 0; i < 8; i++) {
			Triangle* res2;
			float dist = sub[i]->collide(orig, dir, &res2);
			if (dist < shortest) {
				res = res2;
				shortest = dist;
			}
		}
	}

	// hit
	*out = res;
	return shortest;
}

void Tree::calcSize(Mesh& mesh) {
	Vec3Df p1; // min
	Vec3Df p2; // max

	for (unsigned int i = 0; i < mesh.triangles.size(); i++) { // triangle
		for (int v = 0; v < 3; v++) { // vertex
			for (int d = 0; d < 3; d++) { // dimension
				const float dim = mesh.triangles[i].vertices[v].position.p[d];
				if (dim < p1.p[d])
					p1.p[d] = dim;
				if (dim > p2.p[d])
					p2.p[d] = dim;
			}
		}
	}
//	printf("min: (%.1f,%.1f,%.1f)\n", p1.p[0], p1.p[1], p1.p[2]);
//	printf("max: (%.1f,%.1f,%.1f)\n", p2.p[0], p2.p[1], p2.p[2]);

	Vec3Df dim = p2 - p1;
	float sdim = dim.p[0];
	sdim = fmax(sdim, dim.p[1]);
	sdim = fmax(sdim, dim.p[2]);

	root = new AABB(p1, sdim * 0.5f);
}

void Tree::build(Mesh& mesh) {
//	printf("Building tree!\n");
	calcSize(mesh);

	for (unsigned int i = 0; i < mesh.triangles.size(); i++)
		add(mesh.triangles[i]);
}

void Tree::add(Triangle& tr) {
	AABB* current = root;
	int a0, a1, a2;

	int depth = 0;
	while (depth < MAX_DEPTH) {
		a0 = current->follow(tr.vertices[0].position);
		a1 = current->follow(tr.vertices[1].position);
		a2 = current->follow(tr.vertices[2].position);

		if (a0 != a1 || a1 != a2)
			break;

		current->split();
		current = current->sub[a0];
		depth++;
	}

	current->leaves.push_back(&tr);
}

float Tree::collide(const Vec3Df& orig, const Vec3Df& dir, Triangle** out) {
	return root->collide(orig, dir, out);
}
<|endoftext|>


<commit_before>#include "Tree.hpp"
#include <cstdio>

AABB::AABB() : sub(0), radius(-1) { }

AABB::AABB(Vec3Df& pos, float radius) : sub(0), pos(pos), radius(radius) {
}

AABB::~AABB() {
	// can safeley delete the null pointer
	delete[] sub;
}

int AABB::follow(Vec3Df& v) {
	int axis = 0;
	for (int a = 0; a < 3; a++) {
		if (v.p[a] > pos.p[a] + radius)
			axis |= 1 << a;
	}

	return axis;
}

void AABB::split() {
	// if already subdivided, return
	if (sub)
		return;

	// make leaves
	sub = new AABB*[8];
	for (int x = 0; x < 2; x++)
	for (int y = 0; y < 2; y++)
	for (int z = 0; z < 2; z++) {
		Vec3Df subpos(pos + Vec3Df(x * radius, y * radius, z * radius));
		float subradius = radius * 0.5f;

		sub[z * 4 + y * 2 + x] = new AABB(subpos, subradius);
	}
}

bool AABB::collidePlane(int axis, Ray& ray) {
	// check axis plane
	float v1 = pos.p[axis];
	if (ray.dir.p[axis] > 0)
		v1 += 2 * radius;

	// factor
	float a = (v1 - ray.orig.p[axis]) / ray.dir.p[axis];

	// other axis
	int axis2 = (axis + 1) % 3;
	int axis3 = (axis + 2) % 3;

	// other axis values
	float v2 = a * ray.dir.p[axis2] + ray.orig.p[axis2];
	float v3 = a * ray.dir.p[axis3] + ray.orig.p[axis3];

	// check 2D aabb
	if (pos.p[axis2] < v2 && v2 < pos.p[axis2] + 2 * radius)
		if (pos.p[axis3] < v3 && v3 < pos.p[axis3] + 2 * radius)
			return true;
	return false;
}

float AABB::collide(Ray& ray, Triangle** out) {
	// check hit with this cube
	bool hit = false;
	for (int i = 0; i < 3; i++) {
		if (collidePlane(i, ray)) {
			hit = true;
			break;
		}
	}

	// return when no hit
	if (!hit)
		return 0;

	// current closest triangle
	float shortest = 1e10f;
	Triangle* res = 0;

	// check with leaves
	for (int i = 0; i < leaves.size(); i++) {
		float dist = ray.intersect(leaves[i]);
		if (dist < shortest) {
			shortest = dist;
			res = leaves[i];
		}
	}

	// check with subnodes
	// TODO: skip irrelevant subnodes
	for (int i = 0; i < 8; i++) {
		Triangle* res2;
		float dist = sub[i]->collide(ray, &res2);
		if (dist < shortest) {
			res = res2;
			shortest = dist;
		}
	}

	// hit
	*out = res;
	return shortest;

	//printf("(%f, %f)\n", y, z);

	return 0;
}

void Tree::calcSize(Mesh& mesh) {
	Vec3Df p1; // min
	Vec3Df p2; // max

	for (unsigned int i = 0; i < mesh.triangles.size(); i++) { // triangle
		for (int v = 0; v < 3; v++) { // vertex
			for (int d = 0; d < 3; d++) { // dimension
				const float dim = mesh.triangles[i].vertices[v].p.p[d];
				if (dim < p1.p[d])
					p1.p[d] = dim;
				if (dim > p2.p[d])
					p2.p[d] = dim;
			}
		}
	}
	printf("min: (%.1f,%.1f,%.1f)\n", p1.p[0], p1.p[1], p1.p[2]);
	printf("max: (%.1f,%.1f,%.1f)\n", p2.p[0], p2.p[1], p2.p[2]);

	Vec3Df dim = p2 - p1;
	float sdim = dim.p[0];
	sdim = max(sdim, dim.p[1]);
	sdim = max(sdim, dim.p[2]);

	root = new AABB(p1, sdim * 0.5f);
}

void Tree::build(Mesh& mesh) {
	printf("Building tree!\n");
	calcSize(mesh);

	for (unsigned int i = 0; i < mesh.triangles.size(); i++)
		add(mesh.triangles[i]);

	//Ray ray = Ray(Vec3Df(0, 0, 0), Vec3Df(-2, -5, 0), Vec3Df(-1, 0, 0));
	//Triangle* tr = root->collide(ray);
}

void Tree::add(Triangle& tr) {
	AABB* current = root;
	int a0, a1, a2;

	int depth = 0;
	while (depth < MAX_DEPTH) {
		a0 = current->follow(tr.vertices[0].p);
		a1 = current->follow(tr.vertices[1].p);
		a2 = current->follow(tr.vertices[2].p);

		//printf("follow: %d, %d, %d\n", a0, a1, a2);

		if (a0 != a1 || a1 != a2)
			break;

		current->split();
		current = current->sub[a0];
		depth++;
	}

	//printf("Depth: %d\n\n", depth);

	current->leaves.push_back(&tr);
}

float Tree::collide(Ray& ray, Triangle** out) {
	return root->collide(ray, out);
}<commit_msg>fixed (unsigned) int comparison<commit_after>#include "Tree.hpp"
#include <cstdio>

AABB::AABB() : sub(0), radius(-1) { }

AABB::AABB(Vec3Df& pos, float radius) : sub(0), pos(pos), radius(radius) {
}

AABB::~AABB() {
	// can safeley delete the null pointer
	delete[] sub;
}

int AABB::follow(Vec3Df& v) {
	int axis = 0;
	for (int a = 0; a < 3; a++) {
		if (v.p[a] > pos.p[a] + radius)
			axis |= 1 << a;
	}

	return axis;
}

void AABB::split() {
	// if already subdivided, return
	if (sub)
		return;

	// make leaves
	sub = new AABB*[8];
	for (int x = 0; x < 2; x++)
	for (int y = 0; y < 2; y++)
	for (int z = 0; z < 2; z++) {
		Vec3Df subpos(pos + Vec3Df(x * radius, y * radius, z * radius));
		float subradius = radius * 0.5f;

		sub[z * 4 + y * 2 + x] = new AABB(subpos, subradius);
	}
}

bool AABB::collidePlane(int axis, Ray& ray) {
	// check axis plane
	float v1 = pos.p[axis];
	if (ray.dir.p[axis] > 0)
		v1 += 2 * radius;

	// factor
	float a = (v1 - ray.orig.p[axis]) / ray.dir.p[axis];

	// other axis
	int axis2 = (axis + 1) % 3;
	int axis3 = (axis + 2) % 3;

	// other axis values
	float v2 = a * ray.dir.p[axis2] + ray.orig.p[axis2];
	float v3 = a * ray.dir.p[axis3] + ray.orig.p[axis3];

	// check 2D aabb
	if (pos.p[axis2] < v2 && v2 < pos.p[axis2] + 2 * radius)
		if (pos.p[axis3] < v3 && v3 < pos.p[axis3] + 2 * radius)
			return true;
	return false;
}

float AABB::collide(Ray& ray, Triangle** out) {
	// check hit with this cube
	bool hit = false;
	for (int i = 0; i < 3; i++) {
		if (collidePlane(i, ray)) {
			hit = true;
			break;
		}
	}

	// return when no hit
	if (!hit)
		return 0;

	// current closest triangle
	float shortest = 1e10f;
	Triangle* res = 0;

	// check with leaves
	for (unsigned int i = 0; i < leaves.size(); i++) {
		float dist = ray.intersect(leaves[i]);
		if (dist < shortest) {
			shortest = dist;
			res = leaves[i];
		}
	}

	// check with subnodes
	// TODO: skip irrelevant subnodes
	for (int i = 0; i < 8; i++) {
		Triangle* res2;
		float dist = sub[i]->collide(ray, &res2);
		if (dist < shortest) {
			res = res2;
			shortest = dist;
		}
	}

	// hit
	*out = res;
	return shortest;

	//printf("(%f, %f)\n", y, z);

	return 0;
}

void Tree::calcSize(Mesh& mesh) {
	Vec3Df p1; // min
	Vec3Df p2; // max

	for (unsigned int i = 0; i < mesh.triangles.size(); i++) { // triangle
		for (int v = 0; v < 3; v++) { // vertex
			for (int d = 0; d < 3; d++) { // dimension
				const float dim = mesh.triangles[i].vertices[v].p.p[d];
				if (dim < p1.p[d])
					p1.p[d] = dim;
				if (dim > p2.p[d])
					p2.p[d] = dim;
			}
		}
	}
	printf("min: (%.1f,%.1f,%.1f)\n", p1.p[0], p1.p[1], p1.p[2]);
	printf("max: (%.1f,%.1f,%.1f)\n", p2.p[0], p2.p[1], p2.p[2]);

	Vec3Df dim = p2 - p1;
	float sdim = dim.p[0];
	sdim = max(sdim, dim.p[1]);
	sdim = max(sdim, dim.p[2]);

	root = new AABB(p1, sdim * 0.5f);
}

void Tree::build(Mesh& mesh) {
	printf("Building tree!\n");
	calcSize(mesh);

	for (unsigned int i = 0; i < mesh.triangles.size(); i++)
		add(mesh.triangles[i]);

	//Ray ray = Ray(Vec3Df(0, 0, 0), Vec3Df(-2, -5, 0), Vec3Df(-1, 0, 0));
	//Triangle* tr = root->collide(ray);
}

void Tree::add(Triangle& tr) {
	AABB* current = root;
	int a0, a1, a2;

	int depth = 0;
	while (depth < MAX_DEPTH) {
		a0 = current->follow(tr.vertices[0].p);
		a1 = current->follow(tr.vertices[1].p);
		a2 = current->follow(tr.vertices[2].p);

		//printf("follow: %d, %d, %d\n", a0, a1, a2);

		if (a0 != a1 || a1 != a2)
			break;

		current->split();
		current = current->sub[a0];
		depth++;
	}

	//printf("Depth: %d\n\n", depth);

	current->leaves.push_back(&tr);
}

float Tree::collide(Ray& ray, Triangle** out) {
	return root->collide(ray, out);
}
<|endoftext|>