<commit_before>/*
* System RNG
* (C) 2014,2015,2017,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/system_rng.h>

#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)
  #include <botan/dyn_load.h>
  #define NOMINMAX 1
  #define _WINSOCKAPI_ // stop windows.h including winsock.h
  #include <windows.h>

#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
   #include <stdlib.h>

#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   #include <unistd.h>
   #include <errno.h>
#endif

namespace Botan {

namespace {

#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl() : m_advapi("advapi32.dll")
         {
         // This throws if the function is not found
         m_rtlgenrandom = m_advapi.resolve<RtlGenRandom_f>("SystemFunction036");
         }

      void randomize(uint8_t buf[], size_t len) override
         {
         bool success = m_rtlgenrandom(buf, len) == TRUE;
         if(!success)
            throw Exception("RtlGenRandom failed");
         }

      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "RtlGenRandom"; }
   private:
      using RtlGenRandom_f = BOOLEAN (NTAPI *)(PVOID, ULONG);

      Dynamically_Loaded_Library m_advapi;
      RtlGenRandom_f m_rtlgenrandom;
   };

#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      // No constructor or destructor needed as no userland state maintained

      void randomize(uint8_t buf[], size_t len) override
         {
         ::arc4random_buf(buf, len);
         }

      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "arc4random"; }
   };

#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)

// Read a random device

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl()
         {
         #ifndef O_NOCTTY
            #define O_NOCTTY 0
         #endif

         m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR | O_NOCTTY);

         /*
         Cannot open in read-write mode. Fall back to read-only,
         calls to add_entropy will fail, but randomize will work
         */
         if(m_fd < 0)
            m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY);

         if(m_fd < 0)
            throw Exception("System_RNG failed to open RNG device");
         }

      ~System_RNG_Impl()
         {
         ::close(m_fd);
         m_fd = -1;
         }

      void randomize(uint8_t buf[], size_t len) override;
      void add_entropy(const uint8_t in[], size_t length) override;
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return BOTAN_SYSTEM_RNG_DEVICE; }
   private:
      int m_fd;
   };

void System_RNG_Impl::randomize(uint8_t buf[], size_t len)
   {
   while(len)
      {
      ssize_t got = ::read(m_fd, buf, len);

      if(got < 0)
         {
         if(errno == EINTR)
            continue;
         throw Exception("System_RNG read failed error " + std::to_string(errno));
         }
      if(got == 0)
         throw Exception("System_RNG EOF on device"); // ?!?

      buf += got;
      len -= got;
      }
   }

void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len)
   {
   while(len)
      {
      ssize_t got = ::write(m_fd, input, len);

      if(got < 0)
         {
         if(errno == EINTR)
            continue;

         /*
         * This is seen on OS X CI, despite the fact that the man page
         * for Darwin urandom explicitly states that writing to it is
         * supported, and write(2) does not document EPERM at all.
         * But in any case EPERM seems indicative of a policy decision
         * by the OS or sysadmin that additional entropy is not wanted
         * in the system pool, so we accept that and return here,
         * since there is no corrective action possible.
	 *
	 * In Linux EBADF or EPERM is returned if m_fd is not opened for
	 * writing.
         */
         if(errno == EPERM || errno == EBADF)
            return;

         // maybe just ignore any failure here and return?
         throw Exception("System_RNG write failed error " + std::to_string(errno));
         }

      input += got;
      len -= got;
      }
   }

#endif

}

RandomNumberGenerator& system_rng()
   {
   static System_RNG_Impl g_system_rng;
   return g_system_rng;
   }

}
<commit_msg>Rename RtlGenRandom_f -> RtlGenRandom_fptr<commit_after>/*
* System RNG
* (C) 2014,2015,2017,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/system_rng.h>

#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)
  #include <botan/dyn_load.h>
  #define NOMINMAX 1
  #define _WINSOCKAPI_ // stop windows.h including winsock.h
  #include <windows.h>

#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
   #include <stdlib.h>

#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   #include <unistd.h>
   #include <errno.h>
#endif

namespace Botan {

namespace {

#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl() : m_advapi("advapi32.dll")
         {
         // This throws if the function is not found
         m_rtlgenrandom = m_advapi.resolve<RtlGenRandom_fptr>("SystemFunction036");
         }

      void randomize(uint8_t buf[], size_t len) override
         {
         bool success = m_rtlgenrandom(buf, len) == TRUE;
         if(!success)
            throw Exception("RtlGenRandom failed");
         }

      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "RtlGenRandom"; }
   private:
      using RtlGenRandom_fptr = BOOLEAN (NTAPI *)(PVOID, ULONG);

      Dynamically_Loaded_Library m_advapi;
      RtlGenRandom_fptr m_rtlgenrandom;
   };

#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      // No constructor or destructor needed as no userland state maintained

      void randomize(uint8_t buf[], size_t len) override
         {
         ::arc4random_buf(buf, len);
         }

      void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return "arc4random"; }
   };

#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)

// Read a random device

class System_RNG_Impl final : public RandomNumberGenerator
   {
   public:
      System_RNG_Impl()
         {
         #ifndef O_NOCTTY
            #define O_NOCTTY 0
         #endif

         m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR | O_NOCTTY);

         /*
         Cannot open in read-write mode. Fall back to read-only,
         calls to add_entropy will fail, but randomize will work
         */
         if(m_fd < 0)
            m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY);

         if(m_fd < 0)
            throw Exception("System_RNG failed to open RNG device");
         }

      ~System_RNG_Impl()
         {
         ::close(m_fd);
         m_fd = -1;
         }

      void randomize(uint8_t buf[], size_t len) override;
      void add_entropy(const uint8_t in[], size_t length) override;
      bool is_seeded() const override { return true; }
      void clear() override { /* not possible */ }
      std::string name() const override { return BOTAN_SYSTEM_RNG_DEVICE; }
   private:
      int m_fd;
   };

void System_RNG_Impl::randomize(uint8_t buf[], size_t len)
   {
   while(len)
      {
      ssize_t got = ::read(m_fd, buf, len);

      if(got < 0)
         {
         if(errno == EINTR)
            continue;
         throw Exception("System_RNG read failed error " + std::to_string(errno));
         }
      if(got == 0)
         throw Exception("System_RNG EOF on device"); // ?!?

      buf += got;
      len -= got;
      }
   }

void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len)
   {
   while(len)
      {
      ssize_t got = ::write(m_fd, input, len);

      if(got < 0)
         {
         if(errno == EINTR)
            continue;

         /*
         * This is seen on OS X CI, despite the fact that the man page
         * for Darwin urandom explicitly states that writing to it is
         * supported, and write(2) does not document EPERM at all.
         * But in any case EPERM seems indicative of a policy decision
         * by the OS or sysadmin that additional entropy is not wanted
         * in the system pool, so we accept that and return here,
         * since there is no corrective action possible.
	 *
	 * In Linux EBADF or EPERM is returned if m_fd is not opened for
	 * writing.
         */
         if(errno == EPERM || errno == EBADF)
            return;

         // maybe just ignore any failure here and return?
         throw Exception("System_RNG write failed error " + std::to_string(errno));
         }

      input += got;
      len -= got;
      }
   }

#endif

}

RandomNumberGenerator& system_rng()
   {
   static System_RNG_Impl g_system_rng;
   return g_system_rng;
   }

}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library 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) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Nokia Corporation
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    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, see <http://www.gnu.org/licenses/>.

*/

#include "effectwidget.h"
#include "effectwidget_p.h"

#include <QtCore/QtAlgorithms>
#include <QtCore/QList>

#include "effect.h"
#include "effectparameter.h"
#include "phonondefs_p.h"
#include <QtGui/QBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QSpinBox>
#include <QtGui/QCheckBox>
#include <QtGui/QComboBox>
#include <QtGui/QSlider>
#include <limits>

#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
static const qreal DEFAULT_MIN = std::numeric_limits<qreal>::min();
static const qreal DEFAULT_MAX = std::numeric_limits<qreal>::max();
static const int DEFAULT_MIN_INT = std::numeric_limits<int>::min();
static const int DEFAULT_MAX_INT = std::numeric_limits<int>::max();
static const int SLIDER_RANGE = 8;
static const int TICKINTERVAL = 4;

QT_BEGIN_NAMESPACE

#ifndef QT_NO_PHONON_EFFECTWIDGET

namespace Phonon
{

EffectWidget::EffectWidget(Effect *effect, QWidget *parent)
    : QWidget(parent),
    k_ptr(new EffectWidgetPrivate(effect))
{
    K_D(EffectWidget);
    d->q_ptr = this;
    d->autogenerateUi();
}

EffectWidget::~EffectWidget()
{
    delete k_ptr;
}

/*
EffectWidget::EffectWidget(EffectWidgetPrivate &dd, QWidget *parent)
    : QWidget(parent)
    , k_ptr(&dd)
{
    K_D(EffectWidget);
    d->q_ptr = this;
    d->autogenerateUi();
}
*/

EffectWidgetPrivate::EffectWidgetPrivate(Effect *e)
    : effect(e)
{
    //TODO: look up whether there is a specialized widget for this effect. This
    //could be a DSO or a Designer ui file found via KTrader.
    //
    //if no specialized widget is available:
}

void EffectWidgetPrivate::autogenerateUi()
{
    Q_Q(EffectWidget);
    QVBoxLayout *mainLayout = new QVBoxLayout(q);
    mainLayout->setMargin(0);
    const QList<Phonon::EffectParameter> parameters = effect->parameters();
    for (int i = 0; i < parameters.count(); ++i) {
        const EffectParameter &para = parameters.at(i);
        QVariant value = effect->parameterValue(para);
        QHBoxLayout *pLayout = new QHBoxLayout;
        mainLayout->addLayout(pLayout);

        QLabel *label = new QLabel(q);
        pLayout->addWidget(label);
        label->setText(para.name());
#ifndef QT_NO_TOOLTIP
        label->setToolTip(para.description());
#endif

        QWidget *control = 0;
        switch (para.type()) {
        case QVariant::String:
            {
                QComboBox *cb = new QComboBox(q);
                control = cb;
                if (value.type() == QVariant::Int) {
                    //value just defines the item index
                    for (int i = 0; i < para.possibleValues().count(); ++i) {
                        cb->addItem(para.possibleValues().at(i).toString());
                    }
                    cb->setCurrentIndex(value.toInt());
                    QObject::connect(cb, SIGNAL(currentIndexChanged(int)), q, SLOT(_k_setIntParameter(int)));
                } else {
                    for (int i = 0; i < para.possibleValues().count(); ++i) {
                        const QVariant &item = para.possibleValues().at(i);
                        cb->addItem(item.toString());
                        if (item == value) {
                            cb->setCurrentIndex(cb->count() - 1);
                        }
                    }
                    QObject::connect(cb, SIGNAL(currentIndexChanged(QString)), q, SLOT(_k_setStringParameter(QString)));
                }
            }
            break;
        case QVariant::Bool:
            {
                QCheckBox *cb = new QCheckBox(q);
                control = cb;
                cb->setChecked(value.toBool());
                QObject::connect(cb, SIGNAL(toggled(bool)), q, SLOT(_k_setToggleParameter(bool)));
            }
            break;
        case QVariant::Int:
            {
                QSpinBox *sb = new QSpinBox(q);
                control = sb;
                bool minValueOk = false;
                bool maxValueOk = false;
                const int minValue = para.minimumValue().toInt(&minValueOk);
                const int maxValue = para.minimumValue().toInt(&maxValueOk);

                sb->setRange(minValueOk ? minValue : DEFAULT_MIN_INT, maxValueOk ? maxValue : DEFAULT_MAX_INT);
                sb->setValue(value.toInt());
                QObject::connect(sb, SIGNAL(valueChanged(int)), q, SLOT(_k_setIntParameter(int)));
            }
            break;
        case QMetaType::Float:
        case QVariant::Double:
            {
                const qreal minValue = para.minimumValue().canConvert(QVariant::Double) ?
                    para.minimumValue().toReal() : DEFAULT_MIN;
                const qreal maxValue = para.maximumValue().canConvert(QVariant::Double) ?
                    para.maximumValue().toReal() : DEFAULT_MAX;

                if (minValue == -1. && maxValue == 1.) {
                    //Special case values between -1 and 1.0 to use a slider for improved usability
                    QSlider *slider = new QSlider(Qt::Horizontal, q);
                    control = slider;
                    slider->setRange(-SLIDER_RANGE, +SLIDER_RANGE);
                    slider->setValue(int(SLIDER_RANGE * value.toReal()));
                    slider->setTickPosition(QSlider::TicksBelow);
                    slider->setTickInterval(TICKINTERVAL);
                    QObject::connect(slider, SIGNAL(valueChanged(int)), q, SLOT(_k_setSliderParameter(int)));
                } else {
                    double step = 0.1;
                    if (qAbs(maxValue - minValue) > 50)
                        step = 1.0;
                    QDoubleSpinBox *sb = new QDoubleSpinBox(q);
                    control = sb;
                    sb->setRange(minValue, maxValue);
                    sb->setValue(value.toDouble());
                    sb->setSingleStep(step);
                    QObject::connect(sb, SIGNAL(valueChanged(double)), q,
                        SLOT(_k_setDoubleParameter(double)));
                }
            }
            break;
        default:
            break;
        }

        if (control) {
#ifndef QT_NO_TOOLTIP
        control->setToolTip(para.description());
#endif
#ifndef QT_NO_SHORTCUT
            label->setBuddy(control);
#endif
            pLayout->addWidget(control);
            parameterForObject.insert(control, para);
        }
    }
}

void EffectWidgetPrivate::_k_setToggleParameter(bool checked)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], checked);
    }
}

void EffectWidgetPrivate::_k_setIntParameter(int value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setDoubleParameter(double value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setStringParameter(const QString &value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setSliderParameter(int value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], double(value) / double(SLIDER_RANGE));
    }
}

} // namespace Phonon

#endif // QT_NO_PHONON_EFFECTWIDGET

QT_END_NAMESPACE

#include "moc_effectwidget.cpp"

// vim: sw=4 ts=4
<commit_msg>Fixed typo in Phonon::EffectWidget implementation<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library 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) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Nokia Corporation
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    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, see <http://www.gnu.org/licenses/>.

*/

#include "effectwidget.h"
#include "effectwidget_p.h"

#include <QtCore/QtAlgorithms>
#include <QtCore/QList>

#include "effect.h"
#include "effectparameter.h"
#include "phonondefs_p.h"
#include <QtGui/QBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QSpinBox>
#include <QtGui/QCheckBox>
#include <QtGui/QComboBox>
#include <QtGui/QSlider>
#include <limits>

#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
static const qreal DEFAULT_MIN = std::numeric_limits<qreal>::min();
static const qreal DEFAULT_MAX = std::numeric_limits<qreal>::max();
static const int DEFAULT_MIN_INT = std::numeric_limits<int>::min();
static const int DEFAULT_MAX_INT = std::numeric_limits<int>::max();
static const int SLIDER_RANGE = 8;
static const int TICKINTERVAL = 4;

QT_BEGIN_NAMESPACE

#ifndef QT_NO_PHONON_EFFECTWIDGET

namespace Phonon
{

EffectWidget::EffectWidget(Effect *effect, QWidget *parent)
    : QWidget(parent),
    k_ptr(new EffectWidgetPrivate(effect))
{
    K_D(EffectWidget);
    d->q_ptr = this;
    d->autogenerateUi();
}

EffectWidget::~EffectWidget()
{
    delete k_ptr;
}

/*
EffectWidget::EffectWidget(EffectWidgetPrivate &dd, QWidget *parent)
    : QWidget(parent)
    , k_ptr(&dd)
{
    K_D(EffectWidget);
    d->q_ptr = this;
    d->autogenerateUi();
}
*/

EffectWidgetPrivate::EffectWidgetPrivate(Effect *e)
    : effect(e)
{
    //TODO: look up whether there is a specialized widget for this effect. This
    //could be a DSO or a Designer ui file found via KTrader.
    //
    //if no specialized widget is available:
}

void EffectWidgetPrivate::autogenerateUi()
{
    Q_Q(EffectWidget);
    QVBoxLayout *mainLayout = new QVBoxLayout(q);
    mainLayout->setMargin(0);
    const QList<Phonon::EffectParameter> parameters = effect->parameters();
    for (int i = 0; i < parameters.count(); ++i) {
        const EffectParameter &para = parameters.at(i);
        QVariant value = effect->parameterValue(para);
        QHBoxLayout *pLayout = new QHBoxLayout;
        mainLayout->addLayout(pLayout);

        QLabel *label = new QLabel(q);
        pLayout->addWidget(label);
        label->setText(para.name());
#ifndef QT_NO_TOOLTIP
        label->setToolTip(para.description());
#endif

        QWidget *control = 0;
        switch (para.type()) {
        case QVariant::String:
            {
                QComboBox *cb = new QComboBox(q);
                control = cb;
                if (value.type() == QVariant::Int) {
                    //value just defines the item index
                    for (int i = 0; i < para.possibleValues().count(); ++i) {
                        cb->addItem(para.possibleValues().at(i).toString());
                    }
                    cb->setCurrentIndex(value.toInt());
                    QObject::connect(cb, SIGNAL(currentIndexChanged(int)), q, SLOT(_k_setIntParameter(int)));
                } else {
                    for (int i = 0; i < para.possibleValues().count(); ++i) {
                        const QVariant &item = para.possibleValues().at(i);
                        cb->addItem(item.toString());
                        if (item == value) {
                            cb->setCurrentIndex(cb->count() - 1);
                        }
                    }
                    QObject::connect(cb, SIGNAL(currentIndexChanged(QString)), q, SLOT(_k_setStringParameter(QString)));
                }
            }
            break;
        case QVariant::Bool:
            {
                QCheckBox *cb = new QCheckBox(q);
                control = cb;
                cb->setChecked(value.toBool());
                QObject::connect(cb, SIGNAL(toggled(bool)), q, SLOT(_k_setToggleParameter(bool)));
            }
            break;
        case QVariant::Int:
            {
                QSpinBox *sb = new QSpinBox(q);
                control = sb;
                bool minValueOk = false;
                bool maxValueOk = false;
                const int minValue = para.minimumValue().toInt(&minValueOk);
                const int maxValue = para.maximumValue().toInt(&maxValueOk);

                sb->setRange(minValueOk ? minValue : DEFAULT_MIN_INT, maxValueOk ? maxValue : DEFAULT_MAX_INT);
                sb->setValue(value.toInt());
                QObject::connect(sb, SIGNAL(valueChanged(int)), q, SLOT(_k_setIntParameter(int)));
            }
            break;
        case QMetaType::Float:
        case QVariant::Double:
            {
                const qreal minValue = para.minimumValue().canConvert(QVariant::Double) ?
                    para.minimumValue().toReal() : DEFAULT_MIN;
                const qreal maxValue = para.maximumValue().canConvert(QVariant::Double) ?
                    para.maximumValue().toReal() : DEFAULT_MAX;

                if (minValue == -1. && maxValue == 1.) {
                    //Special case values between -1 and 1.0 to use a slider for improved usability
                    QSlider *slider = new QSlider(Qt::Horizontal, q);
                    control = slider;
                    slider->setRange(-SLIDER_RANGE, +SLIDER_RANGE);
                    slider->setValue(int(SLIDER_RANGE * value.toReal()));
                    slider->setTickPosition(QSlider::TicksBelow);
                    slider->setTickInterval(TICKINTERVAL);
                    QObject::connect(slider, SIGNAL(valueChanged(int)), q, SLOT(_k_setSliderParameter(int)));
                } else {
                    double step = 0.1;
                    if (qAbs(maxValue - minValue) > 50)
                        step = 1.0;
                    QDoubleSpinBox *sb = new QDoubleSpinBox(q);
                    control = sb;
                    sb->setRange(minValue, maxValue);
                    sb->setValue(value.toDouble());
                    sb->setSingleStep(step);
                    QObject::connect(sb, SIGNAL(valueChanged(double)), q,
                        SLOT(_k_setDoubleParameter(double)));
                }
            }
            break;
        default:
            break;
        }

        if (control) {
#ifndef QT_NO_TOOLTIP
        control->setToolTip(para.description());
#endif
#ifndef QT_NO_SHORTCUT
            label->setBuddy(control);
#endif
            pLayout->addWidget(control);
            parameterForObject.insert(control, para);
        }
    }
}

void EffectWidgetPrivate::_k_setToggleParameter(bool checked)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], checked);
    }
}

void EffectWidgetPrivate::_k_setIntParameter(int value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setDoubleParameter(double value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setStringParameter(const QString &value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setSliderParameter(int value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], double(value) / double(SLIDER_RANGE));
    }
}

} // namespace Phonon

#endif // QT_NO_PHONON_EFFECTWIDGET

QT_END_NAMESPACE

#include "moc_effectwidget.cpp"

// vim: sw=4 ts=4
<|endoftext|>


<commit_before><commit_msg>ConstantParameter5Genの実体を追加<commit_after><|endoftext|>


<commit_before>//////////////////////////////////
//
// Compile: g++ -std=c++14 -O3 ex5.cxx -o ex5 -lboost_timer
//
//////////////////////////////////

#include <iostream>		// std::cout
#include <fstream>		// std::ifsteam
#include <utility>		// std::pair
#include <vector>		// std::vector
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/timer/timer.hpp>

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

  if (argc != 2)
  {
    std::cerr << "No file!!!" << std::endl;
    return -1;
  }

  std::ifstream file(argv[1]); // std::ifstream::in ??
  std::string str;

  boost::timer::cpu_timer timer;

  /* start get number of vertices */
  getline(file, str);

  using namespace boost::spirit;
  using qi::int_;
  using qi::double_;
  using qi::parse;

  int n;

  auto it = str.begin();
  bool r = parse(it, str.end(),
		 int_[([&n](int i){n = i;})] >> int_);
  /* end get number of vertices */

  /* start get list of edges and weights */
  typedef std::pair<int, int> Edge;
  std::vector<Edge> Edges; // vector to store std::pair of edges.
  std::vector<int> Weights; // vector to weights as integers.

  while (getline(file,str)){ // get graph line-by-line.
    int Vert1;
    int Vert2;
    double Weight; // are all weights integer-valued ??

    auto it = str.begin(); // initialize iterator for qi::parse.

    bool r = parse(it, str.end(), // parse graph.
		 int_[([&Vert1](int i){Vert1 = i;})] >> qi::space >> int_[([&Vert2](int i){Vert2 = i;})] >> qi::space >> double_[([&Weight](double i){Weight = i;})]);

    Edge edge = std::make_pair(Vert1, Vert2); // make edge-pair out of vertices.
    Edges.push_back(edge);
    Weights.push_back(Weight);
  }
  /* end get list of edges and weights */

  typedef boost::property<boost::edge_weight_t, double> EdgeWeightProperty; // initialize type to store weights on edges.
  // adjacency_list<out-edges, vertex_set, directedness, vertex properties, edge properties>
  typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, boost::no_property, EdgeWeightProperty> Graph; // create graph.

  Graph g(Edges.begin(),Edges.end(), Weights.begin(), n); // populate graph.

  // here, the graph should be built... Find shortest path.
  typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  vertex_descriptor source = boost::vertex(1, g); // define source vertex as vertex with index == 1.
  std::vector<vertex_descriptor> parents(boost::num_vertices(g)); // initialize vectors for predecessor and distances.
  std::vector<int> distances(boost::num_vertices(g));

  // find shortest distances.
  boost::dijkstra_shortest_paths(g, source, boost::predecessor_map(&parents[0]).distance_map(&distances[0]));

  /* start find longest-shortest path */
  int maxDistance = 0;
  int maxVertex = 0;

  // create iterator over vertices.
  // vertexPair.first is the iterated element, and .second is the end-index of all vertices.
  typedef boost::graph_traits <Graph>::vertex_iterator vertex_iter;
  std::pair<vertex_iter, vertex_iter> vertexPair;

  for (vertexPair = boost::vertices(g); vertexPair.first != vertexPair.second; ++vertexPair.first) // vertexPair = boost::vertices loops over all vertices in g.
  {
    // replace maxDistance if a greater distance is found, and maxDistance must be less than "infinity" (of 32-bit signed integer).
    if ((distances[*vertexPair.first] > maxDistance) && (distances[*vertexPair.first] < 2147483647)){
      maxDistance = distances[*vertexPair.first];
      maxVertex = *vertexPair.first;
    }
    // if distance == maxDistance, check if vertex index is smaller.
    if ((distances[*vertexPair.first] == maxDistance) && (*vertexPair.first < maxVertex)){
      maxDistance = distances[*vertexPair.first];
    }
  }

  boost::timer::cpu_times times = timer.elapsed();

  // output vertex and distance of the longest-shortest path.
  std::cout << "RESULT VERTEX " << maxVertex << std::endl;
  std::cout << "RESULT DIST " << maxDistance <<  std::endl;
  /* end find longest-shortest path */

  // print CPU- and Wall-Time.
  // boost::timer::cpu_times returns tuple of wall, system and user times in nanoseconds.
  std::cout << std::endl;
  std::cout << "WALL-CLOCK " << times.wall / 1e9 << "s" << std::endl;
  std::cout << "USER TIME " << times.user / 1e9 << "s" << std::endl;

  file.close();
  return 0;
}
<commit_msg>ex7 added.<commit_after>//////////////////////////////////
//
// Compile: g++ -std=c++14 -O3 ex5.cxx -o ex5 -lboost_timer
//
//////////////////////////////////

#include <iostream>		// std::cout
#include <fstream>		// std::ifsteam
#include <utility>		// std::pair
#include <vector>		// std::vector
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/timer/timer.hpp>
#include <boost/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/bimap/support/lambda.hpp>
#include <boost/bind.hpp>

namespace bm = boost::bimaps;
using namespace boost::spirit;
using qi::int_;
using qi::double_;
using qi::parse;

std::pair<int,int> m1 (int& n, std::ifstream& file){
    /* start get list of edges and weights */
  typedef std::pair<int, int> Edge;
  std::vector<Edge> Edges; // vector to store std::pair of edges.
  std::vector<int> Weights; // vector to weights as integers.

  std::string str;

  while (getline(file,str)){ // get graph line-by-line.
    int Vert1;
    int Vert2;
    double Weight; // are all weights integer-valued ??

    auto it = str.begin(); // initialize iterator for qi::parse.

    bool r = parse(it, str.end(), // parse graph.
		 int_[([&Vert1](int i){Vert1 = i;})] >> qi::space >> int_[([&Vert2](int i){Vert2 = i;})] >> qi::space >> double_[([&Weight](double i){Weight = i;})]);

    Edge edge = std::make_pair(Vert1, Vert2); // make edge-pair out of vertices.
    Edges.push_back(edge);
    Weights.push_back(Weight);
  }
  /* end get list of edges and weights */

  typedef boost::property<boost::edge_weight_t, double> EdgeWeightProperty; // initialize type to store weights on edges.
  // adjacency_list<out-edges, vertex_set, directedness, vertex properties, edge properties>
  typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, boost::no_property, EdgeWeightProperty> Graph; // create graph.

  Graph g(Edges.begin(),Edges.end(), Weights.begin(), n); // populate graph.

  // here, the graph should be built... Find shortest path.
  typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  vertex_descriptor source = boost::vertex(1, g); // define source vertex as vertex with index == 1.
  std::vector<vertex_descriptor> parents(boost::num_vertices(g)); // initialize vectors for predecessor and distances.
  std::vector<int> distances(boost::num_vertices(g));

  // find shortest distances.
  boost::dijkstra_shortest_paths(g, source, boost::predecessor_map(&parents[0]).distance_map(&distances[0]));

  /* start find longest-shortest path */
  int maxDistance = 0;
  int maxVertex = 0;

  // create iterator over vertices.
  // vertexPair.first is the iterated element, and .second is the end-index of all vertices.
  typedef boost::graph_traits <Graph>::vertex_iterator vertex_iter;
  std::pair<vertex_iter, vertex_iter> vertexPair;

  for (vertexPair = boost::vertices(g); vertexPair.first != vertexPair.second; ++vertexPair.first) // vertexPair = boost::vertices loops over all vertices in g.
  {
    // replace maxDistance if a greater distance is found, and maxDistance must be less than "infinity" (of 32-bit signed integer).
    if ((distances[*vertexPair.first] > maxDistance) && (distances[*vertexPair.first] < 2147483647)){
      maxDistance = distances[*vertexPair.first];
      maxVertex = *vertexPair.first;
    }
    // if distance == maxDistance, check if vertex index is smaller.
    if ((distances[*vertexPair.first] == maxDistance) && (*vertexPair.first < maxVertex)){
      maxDistance = distances[*vertexPair.first];
    }
  }
    std::pair<int,int> Final = std::make_pair(maxVertex,maxDistance);
    return Final;
}

std::pair<int,int> m2 (int& n, std::ifstream& file){
  /* start get list of edges and weights */
  using vertex =  std::pair<int, int>;
  std::vector<std::vector<vertex>> adjList(n);

  std::cout << "pass initialize adjList." << std::endl;
  std::string str;

  while (getline(file,str)){ // get graph line-by-line.
    int Vert1;
    int Vert2;
    int Weight; // are all weights integer-valued ??

    auto it = str.begin(); // initialize iterator for qi::parse.

    parse(it, str.end(), int_[([&Vert1](int i){Vert1 = i;})] >> qi::space >> int_[([&Vert2](int i){Vert2 = i;})] >> qi::space >> double_[([&Weight](double i){Weight = i;})]);

    vertex VertexWeight1(Vert2,Weight);
    adjList[Vert1].push_back(VertexWeight1);

    vertex VertexWeight2(Vert1,Weight);
    adjList[Vert2].push_back(VertexWeight2);
  }
  /* end get list of edges and weights */

  std::cout << "pass build adjList." << std::endl;

  using bimap = bm::bimap<int, boost::bimaps::multiset_of<int,std::less<int>>>;

  bimap Unvisited;
  std::vector<vertex> finalWeights(n);

  for(int i=1; i<n; i++){
    Unvisited.left.insert(bimap::left_value_type(i,std::numeric_limits<int>::max()));
    finalWeights[i] = std::make_pair(i, std::numeric_limits<int>::max());
  }
  bimap::right_iterator itr = Unvisited.right.begin();
  Unvisited.right.replace_key(itr, 0);
  finalWeights[1].second = 0;

  std::cout << "pass initialize unvisited set." << std::endl;

  while(Unvisited.size()>0){
    auto minPair = Unvisited.right.begin();
    int minIdx = minPair->second;
    int minDist = minPair->first;

    for(int j=0; j<adjList[minIdx].size(); j++){
      int neighbour = adjList[minIdx][j].first;
      int dist = adjList[minIdx][j].second;
      int newDist = minDist + dist;
      int nPWeight = finalWeights[neighbour].second;

      if (newDist < nPWeight){
	auto toBeReplaced = Unvisited.left.find(neighbour);
	Unvisited.left.modify_data(toBeReplaced, bm::_data=newDist);
	finalWeights[neighbour].second = newDist;
	}
      }
    Unvisited.left.erase(minIdx);
    }
    std::cout << "pass distance calculation." << std::endl;

    std::sort(finalWeights.begin(), finalWeights.end(), [](auto &left, auto &right) {
      return left.second < right.second;});

    int maxDistance = 0;
    int maxVertex = 0;

    for(auto ita = finalWeights.begin(); ita != finalWeights.end(); ita++){
      if ((ita->second > maxDistance) && (ita->second < std::numeric_limits<int>::max())){
      maxDistance = ita->second;
      maxVertex = ita->first;
    }
    // if distance == maxDistance, check if vertex index is smaller.
    if ((ita->second == maxDistance) && (ita->first < maxVertex)){
      maxVertex = ita->first;
    }
    }
    vertex Final = std::make_pair(maxVertex,maxDistance);
    return Final;
}

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

  if (argc < 2)
  {
    std::cerr << "No file!!!" << std::endl;
    return -1;
  }

  std::ifstream file(argv[1]); // std::ifstream::in ??
  std::string str;

  /* start get number of edges */
  getline(file, str);

  int n;

  auto it = str.begin();
  bool r = parse(it, str.end(),
		 int_[([&n](int i){n = i;})] >> int_);
  n = n + 1;
  /* end get number of edges */

  std::pair<int,int> f;
  boost::timer::cpu_timer timer;
  for(int i = 0; i < argc; i++){
    if (std::string(argv[i]) == "-m1"){
      f = m1(n,file);

    }
    else if(std::string(argv[i]) == "-m2"){
      f = m2(n,file);

    }
   else{f=std::make_pair(0,0);}
  }
  boost::timer::cpu_times times = timer.elapsed();

  // output vertex and distance of the longest-shortest path.
  std::cout << "RESULT VERTEX " << f.first << std::endl;
  std::cout << "RESULT DIST " << f.second <<  std::endl;
  /* end find longest-shortest path */

  // print CPU- and Wall-Time.
  // boost::timer::cpu_times returns tuple of wall, system and user times in nanoseconds.
  std::cout << std::endl;
  std::cout << "WALL-CLOCK " << times.wall / 1e9 << "s" << std::endl;
  std::cout << "USER TIME " << times.user / 1e9 << "s" << std::endl;

  file.close();
  return 0;
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkTexture.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
#include "vtkTexture.h"

#include "vtkDataSetAttributes.h"
#include "vtkExecutive.h"
#include "vtkGraphicsFactory.h"
#include "vtkImageData.h"
#include "vtkLookupTable.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkTransform.h"
#include "vtkPointData.h"

vtkCxxRevisionMacro(vtkTexture, "1.63");
vtkCxxSetObjectMacro(vtkTexture, LookupTable, vtkScalarsToColors);
//----------------------------------------------------------------------------
// Needed when we don't use the vtkStandardNewMacro.
vtkInstantiatorNewMacro(vtkTexture);
//----------------------------------------------------------------------------

// Construct object and initialize.
vtkTexture::vtkTexture()
{
  this->Repeat = 1;
  this->Interpolate = 0;
  this->EdgeClamp = 0;
  this->Quality = VTK_TEXTURE_QUALITY_DEFAULT;
  this->PremultipliedAlpha = false;

  this->LookupTable = NULL;
  this->MappedScalars = NULL;
  this->MapColorScalarsThroughLookupTable = 0;
  this->Transform = NULL;

  this->SelfAdjustingTableRange = 0;

  this->SetNumberOfOutputPorts(0);

  this->BlendingMode = VTK_TEXTURE_BLENDING_MODE_NONE;

  this->RestrictPowerOf2ImageSmaller = 0;

  // By default select active point scalars.
  this->SetInputArrayToProcess(0,0,0,
    vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS,
    vtkDataSetAttributes::SCALARS);
}

//----------------------------------------------------------------------------
vtkTexture::~vtkTexture()
{
  if (this->MappedScalars)
    {
    this->MappedScalars->Delete();
    }

  if (this->LookupTable != NULL)
    {
    this->LookupTable->UnRegister(this);
    }

  if(this->Transform != NULL)
    {
    this->Transform->UnRegister(this);
    }
}

//----------------------------------------------------------------------------
// return the correct type of Texture
vtkTexture *vtkTexture::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkGraphicsFactory::CreateInstance("vtkTexture");
  return static_cast<vtkTexture *>(ret);
}

//----------------------------------------------------------------------------
vtkImageData *vtkTexture::GetInput()
{
  if (this->GetNumberOfInputConnections(0) < 1)
    {
    return 0;
    }
  return vtkImageData::SafeDownCast(this->GetExecutive()->GetInputData(0, 0));
}

//----------------------------------------------------------------------------
void vtkTexture::SetTransform(vtkTransform *transform)
{
  if (transform == this->Transform)
    {
    return;
    }

  if (this->Transform)
    {
    this->Transform->Delete();
    this->Transform = NULL;
    }

  if (transform)
    {
    this->Transform = transform;
    this->Transform->Register(this);
    }
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkTexture::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Interpolate: " << (this->Interpolate ? "On\n" : "Off\n");
  os << indent << "Repeat:      " << (this->Repeat ? "On\n" : "Off\n");
  os << indent << "EdgeClamp:   " << (this->EdgeClamp ? "On\n" : "Off\n");
  os << indent << "Quality:     ";
  switch (this->Quality)
    {
    case VTK_TEXTURE_QUALITY_DEFAULT:
      os << "Default\n";
      break;
    case VTK_TEXTURE_QUALITY_16BIT:
      os << "16Bit\n";
      break;
    case VTK_TEXTURE_QUALITY_32BIT:
      os << "32Bit\n";
      break;
    }
  os << indent << "MapColorScalarsThroughLookupTable: " <<
    (this->MapColorScalarsThroughLookupTable  ? "On\n" : "Off\n");
  os << indent << "PremultipliedAlpha: " << (this->PremultipliedAlpha ? "On\n" : "Off\n");

  if ( this->GetInput() )
    {
    os << indent << "Input: (" << static_cast<void *>(this->GetInput()) << ")\n";
    }
  else
    {
    os << indent << "Input: (none)\n";
    }
  if ( this->LookupTable )
    {
    os << indent << "LookupTable:\n";
    this->LookupTable->PrintSelf (os, indent.GetNextIndent ());
    }
  else
    {
    os << indent << "LookupTable: (none)\n";
    }

  if ( this->MappedScalars )
    {
    os << indent << "Mapped Scalars: " << this->MappedScalars << "\n";
    }
  else
    {
    os << indent << "Mapped Scalars: (none)\n";
    }

  if ( this->Transform )
    {
    os << indent << "Transform: " << this->Transform << "\n";
    }
  else
    {
    os << indent << "Transform: (none)\n";
    }
  os << indent << "MultiTexture Blending Mode:     ";
  switch (this->BlendingMode)
    {
    case VTK_TEXTURE_BLENDING_MODE_NONE:
      os << "None\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_REPLACE:
      os << "Replace\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_MODULATE:
      os << "Modulate\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_ADD:
      os << "Add\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_ADD_SIGNED:
      os << "Add Signed\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_INTERPOLATE:
      os << "Interpolate\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_SUBTRACT:
      os << "Subtract\n";
      break;
    }
  os << indent << "RestrictPowerOf2ImageSmaller:   " << (this->RestrictPowerOf2ImageSmaller ? "On\n" : "Off\n");
}

//----------------------------------------------------------------------------
unsigned char *vtkTexture::MapScalarsToColors (vtkDataArray *scalars)
{
  // if there is no lookup table, create one
  if (this->LookupTable == NULL)
    {
    this->LookupTable = vtkLookupTable::New();
    this->LookupTable->Register(this);
    this->LookupTable->Delete();
    this->LookupTable->Build ();
    this->SelfAdjustingTableRange = 1;
    }
  else
    {
    this->SelfAdjustingTableRange = 0;
    }
  // Delete old colors
  if (this->MappedScalars)
    {
    this->MappedScalars->Delete();
    this->MappedScalars = 0;
    }

  // if the texture created its own lookup table, set the Table Range
  // to the range of the scalar data.
  if (this->SelfAdjustingTableRange)
    {
    this->LookupTable->SetRange(scalars->GetRange(0));
    }

  // map the scalars to colors
  this->MappedScalars = this->LookupTable->MapScalars(scalars,
    this->MapColorScalarsThroughLookupTable?
    VTK_COLOR_MODE_MAP_SCALARS : VTK_COLOR_MODE_DEFAULT, -1);

  return this->MappedScalars? reinterpret_cast<unsigned char*>(
    this->MappedScalars->GetVoidPointer(0)): NULL;
}

//----------------------------------------------------------------------------
void vtkTexture::Render(vtkRenderer *ren)
{
  vtkImageData *input = this->GetInput();

  if (input) //load texture map
    {
    // We do not want more than requested.
    input->RequestExactExtentOn();

    // Updating the whole extent may not be necessary.
    input->UpdateInformation();
    input->SetUpdateExtentToWholeExtent();
    input->Update();
    this->Load(ren);
    }
}

//----------------------------------------------------------------------------
int vtkTexture::IsTranslucent()
{
  if(this->GetMTime() <= this->TranslucentComputationTime)
    return this->TranslucentCachedResult;

  if(this->GetInput())
    {
    this->GetInput()->UpdateInformation();
    this->GetInput()->SetUpdateExtent(
        this->GetInput()->GetWholeExtent());
    this->GetInput()->PropagateUpdateExtent();
    this->GetInput()->TriggerAsynchronousUpdate();
    this->GetInput()->UpdateData();
    }

  if(this->GetInput()->GetPointData()->GetScalars() == NULL ||
      this->GetInput()->GetPointData()->GetScalars()
              ->GetNumberOfComponents()%2)
    {
    this->TranslucentCachedResult = 0;
    }
  else
    {
    vtkDataArray* scal = this->GetInput()->GetPointData()->GetScalars();
    // the alpha component is the last one
    int alphaid = scal->GetNumberOfComponents() - 1;
    bool hasTransparentPixel = false;
    bool hasOpaquePixel = false;
    bool hasTranslucentPixel = false;
    for(vtkIdType i = 0; i < scal->GetNumberOfTuples(); i++)
      {
      double alpha = scal->GetTuple(i)[alphaid];
      if(alpha <= 0)
        {
        hasTransparentPixel = true;
        }
      else if((scal->GetDataType() == VTK_FLOAT || scal->GetDataType() == VTK_DOUBLE && alpha >= 1.0) || alpha == scal->GetDataTypeMax())
        {
        hasOpaquePixel = true;
        }
      else
        {
        hasTranslucentPixel = true;
        }
      // stop the computation if there are translucent pixels
      if(hasTranslucentPixel || (this->Interpolate && hasTransparentPixel && hasOpaquePixel))
        break;
      }
    if(hasTranslucentPixel || (this->Interpolate && hasTransparentPixel && hasOpaquePixel))
      {
      this->TranslucentCachedResult = 1;
      }
    else
      {
      this->TranslucentCachedResult = 0;
      }
    }

  this->TranslucentComputationTime.Modified();
  return this->TranslucentCachedResult;
}

<commit_msg>BUG: fix missing parentheses leading to wrong if statement when computing the IsTranslucent method, and add more robust test to determine if it can use the cached result.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkTexture.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
#include "vtkTexture.h"

#include "vtkDataSetAttributes.h"
#include "vtkExecutive.h"
#include "vtkGraphicsFactory.h"
#include "vtkImageData.h"
#include "vtkLookupTable.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkTransform.h"
#include "vtkPointData.h"

vtkCxxRevisionMacro(vtkTexture, "1.64");
vtkCxxSetObjectMacro(vtkTexture, LookupTable, vtkScalarsToColors);
//----------------------------------------------------------------------------
// Needed when we don't use the vtkStandardNewMacro.
vtkInstantiatorNewMacro(vtkTexture);
//----------------------------------------------------------------------------

// Construct object and initialize.
vtkTexture::vtkTexture()
{
  this->Repeat = 1;
  this->Interpolate = 0;
  this->EdgeClamp = 0;
  this->Quality = VTK_TEXTURE_QUALITY_DEFAULT;
  this->PremultipliedAlpha = false;

  this->LookupTable = NULL;
  this->MappedScalars = NULL;
  this->MapColorScalarsThroughLookupTable = 0;
  this->Transform = NULL;

  this->SelfAdjustingTableRange = 0;

  this->SetNumberOfOutputPorts(0);

  this->BlendingMode = VTK_TEXTURE_BLENDING_MODE_NONE;

  this->RestrictPowerOf2ImageSmaller = 0;

  // By default select active point scalars.
  this->SetInputArrayToProcess(0,0,0,
    vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS,
    vtkDataSetAttributes::SCALARS);
}

//----------------------------------------------------------------------------
vtkTexture::~vtkTexture()
{
  if (this->MappedScalars)
    {
    this->MappedScalars->Delete();
    }

  if (this->LookupTable != NULL)
    {
    this->LookupTable->UnRegister(this);
    }

  if(this->Transform != NULL)
    {
    this->Transform->UnRegister(this);
    }
}

//----------------------------------------------------------------------------
// return the correct type of Texture
vtkTexture *vtkTexture::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkGraphicsFactory::CreateInstance("vtkTexture");
  return static_cast<vtkTexture *>(ret);
}

//----------------------------------------------------------------------------
vtkImageData *vtkTexture::GetInput()
{
  if (this->GetNumberOfInputConnections(0) < 1)
    {
    return 0;
    }
  return vtkImageData::SafeDownCast(this->GetExecutive()->GetInputData(0, 0));
}

//----------------------------------------------------------------------------
void vtkTexture::SetTransform(vtkTransform *transform)
{
  if (transform == this->Transform)
    {
    return;
    }

  if (this->Transform)
    {
    this->Transform->Delete();
    this->Transform = NULL;
    }

  if (transform)
    {
    this->Transform = transform;
    this->Transform->Register(this);
    }
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkTexture::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Interpolate: " << (this->Interpolate ? "On\n" : "Off\n");
  os << indent << "Repeat:      " << (this->Repeat ? "On\n" : "Off\n");
  os << indent << "EdgeClamp:   " << (this->EdgeClamp ? "On\n" : "Off\n");
  os << indent << "Quality:     ";
  switch (this->Quality)
    {
    case VTK_TEXTURE_QUALITY_DEFAULT:
      os << "Default\n";
      break;
    case VTK_TEXTURE_QUALITY_16BIT:
      os << "16Bit\n";
      break;
    case VTK_TEXTURE_QUALITY_32BIT:
      os << "32Bit\n";
      break;
    }
  os << indent << "MapColorScalarsThroughLookupTable: " <<
    (this->MapColorScalarsThroughLookupTable  ? "On\n" : "Off\n");
  os << indent << "PremultipliedAlpha: " << (this->PremultipliedAlpha ? "On\n" : "Off\n");

  if ( this->GetInput() )
    {
    os << indent << "Input: (" << static_cast<void *>(this->GetInput()) << ")\n";
    }
  else
    {
    os << indent << "Input: (none)\n";
    }
  if ( this->LookupTable )
    {
    os << indent << "LookupTable:\n";
    this->LookupTable->PrintSelf (os, indent.GetNextIndent ());
    }
  else
    {
    os << indent << "LookupTable: (none)\n";
    }

  if ( this->MappedScalars )
    {
    os << indent << "Mapped Scalars: " << this->MappedScalars << "\n";
    }
  else
    {
    os << indent << "Mapped Scalars: (none)\n";
    }

  if ( this->Transform )
    {
    os << indent << "Transform: " << this->Transform << "\n";
    }
  else
    {
    os << indent << "Transform: (none)\n";
    }
  os << indent << "MultiTexture Blending Mode:     ";
  switch (this->BlendingMode)
    {
    case VTK_TEXTURE_BLENDING_MODE_NONE:
      os << "None\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_REPLACE:
      os << "Replace\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_MODULATE:
      os << "Modulate\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_ADD:
      os << "Add\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_ADD_SIGNED:
      os << "Add Signed\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_INTERPOLATE:
      os << "Interpolate\n";
      break;
    case VTK_TEXTURE_BLENDING_MODE_SUBTRACT:
      os << "Subtract\n";
      break;
    }
  os << indent << "RestrictPowerOf2ImageSmaller:   " << (this->RestrictPowerOf2ImageSmaller ? "On\n" : "Off\n");
}

//----------------------------------------------------------------------------
unsigned char *vtkTexture::MapScalarsToColors (vtkDataArray *scalars)
{
  // if there is no lookup table, create one
  if (this->LookupTable == NULL)
    {
    this->LookupTable = vtkLookupTable::New();
    this->LookupTable->Register(this);
    this->LookupTable->Delete();
    this->LookupTable->Build ();
    this->SelfAdjustingTableRange = 1;
    }
  else
    {
    this->SelfAdjustingTableRange = 0;
    }
  // Delete old colors
  if (this->MappedScalars)
    {
    this->MappedScalars->Delete();
    this->MappedScalars = 0;
    }

  // if the texture created its own lookup table, set the Table Range
  // to the range of the scalar data.
  if (this->SelfAdjustingTableRange)
    {
    this->LookupTable->SetRange(scalars->GetRange(0));
    }

  // map the scalars to colors
  this->MappedScalars = this->LookupTable->MapScalars(scalars,
    this->MapColorScalarsThroughLookupTable?
    VTK_COLOR_MODE_MAP_SCALARS : VTK_COLOR_MODE_DEFAULT, -1);

  return this->MappedScalars? reinterpret_cast<unsigned char*>(
    this->MappedScalars->GetVoidPointer(0)): NULL;
}

//----------------------------------------------------------------------------
void vtkTexture::Render(vtkRenderer *ren)
{
  vtkImageData *input = this->GetInput();

  if (input) //load texture map
    {
    // We do not want more than requested.
    input->RequestExactExtentOn();

    // Updating the whole extent may not be necessary.
    input->UpdateInformation();
    input->SetUpdateExtentToWholeExtent();
    input->Update();
    this->Load(ren);
    }
}

//----------------------------------------------------------------------------
int vtkTexture::IsTranslucent()
{
  if(this->GetMTime() <= this->TranslucentComputationTime
      && (this->GetInput() == NULL ||
          (this->GetInput()->GetMTime() <= this->TranslucentComputationTime)))
    return this->TranslucentCachedResult;

  if(this->GetInput())
    {
    this->GetInput()->UpdateInformation();
    this->GetInput()->SetUpdateExtent(
        this->GetInput()->GetWholeExtent());
    this->GetInput()->PropagateUpdateExtent();
    this->GetInput()->TriggerAsynchronousUpdate();
    this->GetInput()->UpdateData();
    }

  if(this->GetInput()->GetPointData()->GetScalars() == NULL ||
      this->GetInput()->GetPointData()->GetScalars()
              ->GetNumberOfComponents()%2)
    {
    this->TranslucentCachedResult = 0;
    }
  else
    {
    vtkDataArray* scal = this->GetInput()->GetPointData()->GetScalars();
    // the alpha component is the last one
    int alphaid = scal->GetNumberOfComponents() - 1;
    bool hasTransparentPixel = false;
    bool hasOpaquePixel = false;
    bool hasTranslucentPixel = false;
    for(vtkIdType i = 0; i < scal->GetNumberOfTuples(); i++)
      {
      double alpha = scal->GetTuple(i)[alphaid];
      if(alpha <= 0)
        {
        hasTransparentPixel = true;
        }
      else if(((scal->GetDataType() == VTK_FLOAT || scal->GetDataType() == VTK_DOUBLE) && alpha >= 1.0) || alpha == scal->GetDataTypeMax())
        {
        hasOpaquePixel = true;
        }
      else
        {
        hasTranslucentPixel = true;
        }
      // stop the computation if there are translucent pixels
      if(hasTranslucentPixel || (this->Interpolate && hasTransparentPixel && hasOpaquePixel))
        break;
      }
    if(hasTranslucentPixel || (this->Interpolate && hasTransparentPixel && hasOpaquePixel))
      {
      this->TranslucentCachedResult = 1;
      }
    else
      {
      this->TranslucentCachedResult = 0;
      }
    }

  this->TranslucentComputationTime.Modified();
  return this->TranslucentCachedResult;
}

<|endoftext|>


<commit_before>#include <nanogui/layout.h>
#include "common.hpp"
#include "directpopup.hpp"
#include "clickablelabel.hpp"
#include "glshadersource.hpp"
#include "glshaderobject.hpp"
#include "graphnodelink.hpp"
#include "connector.hpp"
#include "graphnode.hpp"
#include "genericgraphnode.hpp"
#include "outputgraphnode.hpp"
#include "sink.hpp"
#include "qce.hpp"
#include "graph.hpp"

NAMESPACE_BEGIN(QCE);

Graph::Graph(Widget *parent, Qce *qce, const std::string &title) :
    Window(parent, title),
    mQce(qce),
    mPopup(nullptr),
    mActiveConnector(nullptr),
    mActiveNode(nullptr)
{
    mPopup = new DirectPopup(this, this);
    mPopup->setId("addPopup");
    mPopup->setSize(Eigen::Vector2i(10, 10));
    mPopup->setLayout(new nanogui::GroupLayout());
    mPopup->setVisible(false);

    mOutputNode = new OutputGraphNode(this, this, "Output");
}

void Graph::addNodeType(GLShaderSource *shaderSource)
{
    spdlog::get("qde")->debug(
        "Adding nodeType for selection: {}",
        shaderSource->name()
    );
    nanogui::ref<ClickableLabel> addNodeButton = new ClickableLabel(
        mPopup,
        fmt::format("Add {} node", shaderSource->name())
    );
    addNodeButton->setCallback([this, shaderSource](const Eigen::Vector2i &p) {
        addNodeButtonEvent(p, shaderSource);
    });
}

void Graph::calculateOutput()
{
    std::string nodeOuptut = mOutputNode->calculateOutput();

    if (!nodeOuptut.empty()) {
        std::string output = fmt::format(
            "result = {}", mOutputNode->calculateOutput()
        );
        spdlog::get("qde")->debug("Graph {}: Calculated and set output {}", id(), output);
        mQce->setShaderOutput(output);
    }
}

void Graph::nodeSelectedEvent(GraphNode *node)
{
    spdlog::get("qde")->debug("Graph: Node '{}' was selected", node->id());

    if (mActiveNode != nullptr) {
        mActiveNode->shaderObject()->hideForm();
    }

    auto shaderObject = node->shaderObject();
    if (shaderObject != nullptr) {
        if (shaderObject->hasProperties()) {
            spdlog::get("qde")->debug("Graph: Rendering properties of node '{}'", node->id());
            shaderObject->showForm();
            mActiveNode = node;
        }
    }
}

void Graph::nodeConnectedEvent(Connector *source, Connector *target)
{
    spdlog::get("qde")->debug("Graph: Source {} was connected to target {}", source->id(), target->id());

    auto shaderParameter = target->shaderParameter();

    // Set input to source shader object only if we actually have a shader set
    if (shaderParameter != nullptr) {
        target->shaderParameter()->setInput(source->parent()->shaderObject());
    }

    // Add shader source only if we actually have a shader set
    if (source->parent()->shaderObject() != nullptr) {
        mQce->addShaderToOutput(source->parent()->shaderObject());
    }
}

bool Graph::mouseButtonEvent(const Eigen::Vector2i &p, int button, bool down, int modifiers)
{
    if (Window::mouseButtonEvent(p, button, down, modifiers)) {
        return true;
    }

    if (button == GLFW_MOUSE_BUTTON_2 && mEnabled && down) {
        int offsetX = p.x() - absolutePosition().x();
        int offsetY = p.y() - absolutePosition().y();
        Eigen::Vector2i position(offsetX, offsetY);
        mPopup->setAnchorPos(position);
        mPopup->setVisible(!mPopup->visible());

        return true;
    }

    return false;
}

void Graph::performLayout(NVGcontext *ctx)
{
    spdlog::get("qde")->debug("Performing layout on graph at ({}, {})", mPos.x(), mPos.y());
    Window::performLayout(ctx);
}

void Graph::addNodeButtonEvent(const Eigen::Vector2i &p, GLShaderSource *shaderSource)
{
    spdlog::get("qde")->debug("Graph: Add shader node button was pressed at ({}, {})", p.x(), p.y());

    nanogui::ref<GLShaderObject> shaderObject = new GLShaderObject(shaderSource, mQce);

    nanogui::ref<GenericGraphNode> node = new GenericGraphNode(this, this, shaderObject->name());
    node->setPosition(p);
    node->setEnabled(true);
    node->setVisible(true);
    node->setShaderObject(shaderObject);

    // Add parameters: Properties and/or inputs
    int index = 0;
    for (GLShaderObjectParameter param : shaderSource->parameters()) {
        GLShaderParameter *shaderParameter = shaderObject->addParameter(param);

        if (shaderParameter->parameterType() == ParameterType::INPUT) {
            nanogui::ref<Sink> input = new Sink(node, this, shaderParameter->name());
            input->setShaderParameter(shaderParameter);
            input->setIndex(index);
            index++;
        }
    }

    mQce->performLayout();

    spdlog::get("qde")->debug("Graph: Set shader node position to ({}, {})", p.x(), p.y());
    mPopup->setVisible(false);
    shaderSource->incTimesUsed();
}

void Graph::addNodeButtonEvent(const Eigen::Vector2i &p, GraphNode *graphNode)
{
    spdlog::get("qde")->debug("Graph: Add graph node button was pressed at ({}, {})", p.x(), p.y());

    // TODO: Implement this
    graphNode->setPosition(p);
    graphNode->setEnabled(true);
    graphNode->setVisible(true);

    mQce->performLayout();

    spdlog::get("qde")->debug("Graph: Set graph node position to ({}, {})", p.x(), p.y());
    mPopup->setVisible(false);
}

NAMESPACE_END(QCE);
<commit_msg>Add mergegraphnode (statically) to output menu<commit_after>#include <nanogui/layout.h>
#include "common.hpp"
#include "directpopup.hpp"
#include "clickablelabel.hpp"
#include "glshadersource.hpp"
#include "glshaderobject.hpp"
#include "graphnodelink.hpp"
#include "connector.hpp"
#include "graphnode.hpp"
#include "genericgraphnode.hpp"
#include "mergegraphnode.hpp"
#include "outputgraphnode.hpp"
#include "sink.hpp"
#include "qce.hpp"
#include "graph.hpp"

NAMESPACE_BEGIN(QCE);

Graph::Graph(Widget *parent, Qce *qce, const std::string &title) :
    Window(parent, title),
    mQce(qce),
    mPopup(nullptr),
    mActiveConnector(nullptr),
    mActiveNode(nullptr)
{
    mPopup = new DirectPopup(this, this);
    mPopup->setId("addPopup");
    mPopup->setSize(Eigen::Vector2i(10, 10));
    mPopup->setLayout(new nanogui::GroupLayout());
    mPopup->setVisible(false);

    nanogui::ref<ClickableLabel> addNodeButton = new ClickableLabel(
        mPopup,
        fmt::format("Add merge node")
    );
    addNodeButton->setCallback([this](const Eigen::Vector2i &p) {
        addNodeButtonEvent(p, new MergeGraphNode(this, this));
    });

    mOutputNode = new OutputGraphNode(this, this, "Output");
}

void Graph::addNodeType(GLShaderSource *shaderSource)
{
    spdlog::get("qde")->debug(
        "Adding nodeType for selection: {}",
        shaderSource->name()
    );
    nanogui::ref<ClickableLabel> addNodeButton = new ClickableLabel(
        mPopup,
        fmt::format("Add {} node", shaderSource->name())
    );
    addNodeButton->setCallback([this, shaderSource](const Eigen::Vector2i &p) {
        addNodeButtonEvent(p, shaderSource);
    });
}

void Graph::calculateOutput()
{
    std::string nodeOuptut = mOutputNode->calculateOutput();

    if (!nodeOuptut.empty()) {
        std::string output = fmt::format(
            "result = {}", mOutputNode->calculateOutput()
        );
        spdlog::get("qde")->debug("Graph {}: Calculated and set output {}", id(), output);
        mQce->setShaderOutput(output);
    }
}

void Graph::nodeSelectedEvent(GraphNode *node)
{
    spdlog::get("qde")->debug("Graph: Node '{}' was selected", node->id());

    if (mActiveNode != nullptr) {
        mActiveNode->shaderObject()->hideForm();
    }

    auto shaderObject = node->shaderObject();
    if (shaderObject != nullptr) {
        if (shaderObject->hasProperties()) {
            spdlog::get("qde")->debug("Graph: Rendering properties of node '{}'", node->id());
            shaderObject->showForm();
            mActiveNode = node;
        }
    }
}

void Graph::nodeConnectedEvent(Connector *source, Connector *target)
{
    spdlog::get("qde")->debug("Graph: Source {} was connected to target {}", source->id(), target->id());

    auto shaderParameter = target->shaderParameter();

    // Set input to source shader object only if we actually have a shader set
    if (shaderParameter != nullptr) {
        target->shaderParameter()->setInput(source->parent()->shaderObject());
    }

    // Add shader source only if we actually have a shader set
    if (source->parent()->shaderObject() != nullptr) {
        mQce->addShaderToOutput(source->parent()->shaderObject());
    }
}

bool Graph::mouseButtonEvent(const Eigen::Vector2i &p, int button, bool down, int modifiers)
{
    if (Window::mouseButtonEvent(p, button, down, modifiers)) {
        return true;
    }

    if (button == GLFW_MOUSE_BUTTON_2 && mEnabled && down) {
        int offsetX = p.x() - absolutePosition().x();
        int offsetY = p.y() - absolutePosition().y();
        Eigen::Vector2i position(offsetX, offsetY);
        mPopup->setAnchorPos(position);
        mPopup->setVisible(!mPopup->visible());

        return true;
    }

    return false;
}

void Graph::performLayout(NVGcontext *ctx)
{
    spdlog::get("qde")->debug("Performing layout on graph at ({}, {})", mPos.x(), mPos.y());
    Window::performLayout(ctx);
}

void Graph::addNodeButtonEvent(const Eigen::Vector2i &p, GLShaderSource *shaderSource)
{
    spdlog::get("qde")->debug("Graph: Add shader node button was pressed at ({}, {})", p.x(), p.y());

    nanogui::ref<GLShaderObject> shaderObject = new GLShaderObject(shaderSource, mQce);

    nanogui::ref<GenericGraphNode> node = new GenericGraphNode(this, this, shaderObject->name());
    node->setPosition(p);
    node->setEnabled(true);
    node->setVisible(true);
    node->setShaderObject(shaderObject);

    // Add parameters: Properties and/or inputs
    int index = 0;
    for (GLShaderObjectParameter param : shaderSource->parameters()) {
        GLShaderParameter *shaderParameter = shaderObject->addParameter(param);

        if (shaderParameter->parameterType() == ParameterType::INPUT) {
            nanogui::ref<Sink> input = new Sink(node, this, shaderParameter->name());
            input->setShaderParameter(shaderParameter);
            input->setIndex(index);
            index++;
        }
    }

    mQce->performLayout();

    spdlog::get("qde")->debug("Graph: Set shader node position to ({}, {})", p.x(), p.y());
    mPopup->setVisible(false);
    shaderSource->incTimesUsed();
}

void Graph::addNodeButtonEvent(const Eigen::Vector2i &p, GraphNode *graphNode)
{
    spdlog::get("qde")->debug("Graph: Add graph node button was pressed at ({}, {})", p.x(), p.y());

    // TODO: Implement this
    graphNode->setPosition(p);
    graphNode->setEnabled(true);
    graphNode->setVisible(true);

    mQce->performLayout();

    spdlog::get("qde")->debug("Graph: Set graph node position to ({}, {})", p.x(), p.y());
    mPopup->setVisible(false);
}

NAMESPACE_END(QCE);
<|endoftext|>


<commit_before><commit_msg>Bug Fix: The target collected and detected counts were not cleared.<commit_after><|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

template<typename MatrixType> void basicStuff(const MatrixType& m)
{
  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;

  int rows = m.rows();
  int cols = m.cols();

  // this test relies a lot on Random.h, and there's not much more that we can do
  // to test it, hence I consider that we will have tested Random.h
  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols),
             mzero = MatrixType::Zero(rows, cols),
             identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
                              ::Identity(rows, rows),
             square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>::Random(rows, rows);
  VectorType v1 = VectorType::Random(rows),
             v2 = VectorType::Random(rows),
             vzero = VectorType::Zero(rows);

  Scalar x = ei_random<Scalar>();

  int r = ei_random<int>(0, rows-1),
      c = ei_random<int>(0, cols-1);

  m1.coeffRef(r,c) = x;
  VERIFY_IS_APPROX(x, m1.coeff(r,c));
  m1(r,c) = x;
  VERIFY_IS_APPROX(x, m1(r,c));
  v1.coeffRef(r) = x;
  VERIFY_IS_APPROX(x, v1.coeff(r));
  v1(r) = x;
  VERIFY_IS_APPROX(x, v1(r));
  v1[r] = x;
  VERIFY_IS_APPROX(x, v1[r]);

  VERIFY_IS_APPROX(               v1,    v1);
  VERIFY_IS_NOT_APPROX(           v1,    2*v1);
  VERIFY_IS_MUCH_SMALLER_THAN(    vzero, v1);
  if(NumTraits<Scalar>::HasFloatingPoint)
    VERIFY_IS_MUCH_SMALLER_THAN(  vzero, v1.norm());
  VERIFY_IS_NOT_MUCH_SMALLER_THAN(v1,    v1);
  VERIFY_IS_APPROX(               vzero, v1-v1);
  VERIFY_IS_APPROX(               m1,    m1);
  VERIFY_IS_NOT_APPROX(           m1,    2*m1);
  VERIFY_IS_MUCH_SMALLER_THAN(    mzero, m1);
  VERIFY_IS_NOT_MUCH_SMALLER_THAN(m1,    m1);
  VERIFY_IS_APPROX(               mzero, m1-m1);

  // always test operator() on each read-only expression class,
  // in order to check const-qualifiers.
  // indeed, if an expression class (here Zero) is meant to be read-only,
  // hence has no _write() method, the corresponding MatrixBase method (here zero())
  // should return a const-qualified object so that it is the const-qualified
  // operator() that gets called, which in turn calls _read().
  VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows,cols)(r,c), static_cast<Scalar>(1));

  // now test copying a row-vector into a (column-)vector and conversely.
  square.col(r) = square.row(r).eval();
  Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows);
  Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows);
  rv = square.row(r);
  cv = square.col(r);
  VERIFY_IS_APPROX(rv, cv.transpose());

  if(cols!=1 && rows!=1 && MatrixType::SizeAtCompileTime!=Dynamic)
  {
    VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1)));
  }

  VERIFY_IS_APPROX(m3 = m1,m1);
  MatrixType m4;
  VERIFY_IS_APPROX(m4 = m1,m1);

  // test swap
  m3 = m1;
  m1.swap(m2);
  VERIFY_IS_APPROX(m3, m2);
  if(rows*cols>=3)
  {
    VERIFY_IS_NOT_APPROX(m3, m1);
  }
}

void casting()
{
  Matrix4f m = Matrix4f::Random(), m2;
  Matrix4d n = m.cast<double>();
  VERIFY(m.isApprox(n.cast<float>()));
  m2 = m.cast<float>(); // check the specialization when NewType == Type
  VERIFY(m.isApprox(m2));
}

void test_basicstuff()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST( basicStuff(Matrix<float, 1, 1>()) );
    CALL_SUBTEST( basicStuff(Matrix4d()) );
    CALL_SUBTEST( basicStuff(MatrixXcf(3, 3)) );
    CALL_SUBTEST( basicStuff(MatrixXi(8, 12)) );
    CALL_SUBTEST( basicStuff(MatrixXcd(20, 20)) );
    CALL_SUBTEST( basicStuff(Matrix<float, 100, 100>()) );
    CALL_SUBTEST( basicStuff(Matrix<long double,Dynamic,Dynamic>(10,10)) );
  }
}
<commit_msg>gni, forgot to call the new subtest<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

template<typename MatrixType> void basicStuff(const MatrixType& m)
{
  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;

  int rows = m.rows();
  int cols = m.cols();

  // this test relies a lot on Random.h, and there's not much more that we can do
  // to test it, hence I consider that we will have tested Random.h
  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols),
             mzero = MatrixType::Zero(rows, cols),
             identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
                              ::Identity(rows, rows),
             square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>::Random(rows, rows);
  VectorType v1 = VectorType::Random(rows),
             v2 = VectorType::Random(rows),
             vzero = VectorType::Zero(rows);

  Scalar x = ei_random<Scalar>();

  int r = ei_random<int>(0, rows-1),
      c = ei_random<int>(0, cols-1);

  m1.coeffRef(r,c) = x;
  VERIFY_IS_APPROX(x, m1.coeff(r,c));
  m1(r,c) = x;
  VERIFY_IS_APPROX(x, m1(r,c));
  v1.coeffRef(r) = x;
  VERIFY_IS_APPROX(x, v1.coeff(r));
  v1(r) = x;
  VERIFY_IS_APPROX(x, v1(r));
  v1[r] = x;
  VERIFY_IS_APPROX(x, v1[r]);

  VERIFY_IS_APPROX(               v1,    v1);
  VERIFY_IS_NOT_APPROX(           v1,    2*v1);
  VERIFY_IS_MUCH_SMALLER_THAN(    vzero, v1);
  if(NumTraits<Scalar>::HasFloatingPoint)
    VERIFY_IS_MUCH_SMALLER_THAN(  vzero, v1.norm());
  VERIFY_IS_NOT_MUCH_SMALLER_THAN(v1,    v1);
  VERIFY_IS_APPROX(               vzero, v1-v1);
  VERIFY_IS_APPROX(               m1,    m1);
  VERIFY_IS_NOT_APPROX(           m1,    2*m1);
  VERIFY_IS_MUCH_SMALLER_THAN(    mzero, m1);
  VERIFY_IS_NOT_MUCH_SMALLER_THAN(m1,    m1);
  VERIFY_IS_APPROX(               mzero, m1-m1);

  // always test operator() on each read-only expression class,
  // in order to check const-qualifiers.
  // indeed, if an expression class (here Zero) is meant to be read-only,
  // hence has no _write() method, the corresponding MatrixBase method (here zero())
  // should return a const-qualified object so that it is the const-qualified
  // operator() that gets called, which in turn calls _read().
  VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows,cols)(r,c), static_cast<Scalar>(1));

  // now test copying a row-vector into a (column-)vector and conversely.
  square.col(r) = square.row(r).eval();
  Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows);
  Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows);
  rv = square.row(r);
  cv = square.col(r);
  VERIFY_IS_APPROX(rv, cv.transpose());

  if(cols!=1 && rows!=1 && MatrixType::SizeAtCompileTime!=Dynamic)
  {
    VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1)));
  }

  VERIFY_IS_APPROX(m3 = m1,m1);
  MatrixType m4;
  VERIFY_IS_APPROX(m4 = m1,m1);

  // test swap
  m3 = m1;
  m1.swap(m2);
  VERIFY_IS_APPROX(m3, m2);
  if(rows*cols>=3)
  {
    VERIFY_IS_NOT_APPROX(m3, m1);
  }
}

void casting()
{
  Matrix4f m = Matrix4f::Random(), m2;
  Matrix4d n = m.cast<double>();
  VERIFY(m.isApprox(n.cast<float>()));
  m2 = m.cast<float>(); // check the specialization when NewType == Type
  VERIFY(m.isApprox(m2));
}

void test_basicstuff()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST( basicStuff(Matrix<float, 1, 1>()) );
    CALL_SUBTEST( basicStuff(Matrix4d()) );
    CALL_SUBTEST( basicStuff(MatrixXcf(3, 3)) );
    CALL_SUBTEST( basicStuff(MatrixXi(8, 12)) );
    CALL_SUBTEST( basicStuff(MatrixXcd(20, 20)) );
    CALL_SUBTEST( basicStuff(Matrix<float, 100, 100>()) );
    CALL_SUBTEST( basicStuff(Matrix<long double,Dynamic,Dynamic>(10,10)) );
  }

  CALL_SUBTEST(casting());
}
<|endoftext|>