<commit_before>//
//  TimeLine.cpp
//  Natron
//
//  Created by Frédéric Devernay on 24/09/13.
//
//

#include "TimeLine.h"

#include <cassert>
#include "Engine/Project.h"
#include "Engine/Node.h"

TimeLine::TimeLine(Natron::Project* project)
: _firstFrame(0)
, _lastFrame(0)
, _currentFrame(0)
, _leftBoundary(_firstFrame)
, _rightBoundary(_lastFrame)
, _keyframes()
, _project(project)
{}

SequenceTime
TimeLine::firstFrame() const
{
    QMutexLocker l(&_lock);
    return _firstFrame;
}

SequenceTime
TimeLine::lastFrame() const
{
    QMutexLocker l(&_lock);
   return _lastFrame;
}

SequenceTime
TimeLine::currentFrame() const
{
    QMutexLocker l(&_lock);
    return _currentFrame;
}

SequenceTime
TimeLine::leftBound() const
{
    QMutexLocker l(&_lock);
    return _leftBoundary;
}

SequenceTime
TimeLine::rightBound() const
{
    QMutexLocker l(&_lock);
    return _rightBoundary;
}

void
TimeLine::setFrameRange(SequenceTime first,
                        SequenceTime last)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_firstFrame != first || _lastFrame != last) {
            _firstFrame = first;
            _lastFrame = last;
            changed = true;
        }
    }
    if (changed) {
        emit frameRangeChanged(first, last);
        setBoundaries(first,last);
    }
}

void
TimeLine::seekFrame(SequenceTime frame,
                    Natron::OutputEffectInstance* caller)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_currentFrame != frame) {
            _currentFrame = frame;
            changed = true;
        }
    }
    if (changed) {
        _project->setLastTimelineSeekCaller(caller);
        emit frameChanged(frame, (int)Natron::PLAYBACK_SEEK);
    }
}

void
TimeLine::incrementCurrentFrame(Natron::OutputEffectInstance* caller)
{
    SequenceTime frame;
    {
        QMutexLocker l(&_lock);
        ++_currentFrame;
        frame = _currentFrame;
    }
    _project->setLastTimelineSeekCaller(caller);
    emit frameChanged(frame, (int)Natron::PLAYBACK_SEEK);
}

void
TimeLine::decrementCurrentFrame(Natron::OutputEffectInstance* caller)
{
    SequenceTime frame;
    {
        QMutexLocker l(&_lock);
        --_currentFrame;
        frame = _currentFrame;
    }
    _project->setLastTimelineSeekCaller(caller);
    emit frameChanged(frame, (int)Natron::PLAYBACK_SEEK);
}

void
TimeLine::onFrameChanged(SequenceTime frame)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_currentFrame != frame) {
            _currentFrame = frame;
            changed = true;
        }
    }
    if (changed) {
        /*This function is called in response to a signal emitted by a single timeline gui, but we also
         need to sync all the other timelines potentially existing.*/
        emit frameChanged(frame, (int)Natron::USER_SEEK);
    }
}

void
TimeLine::setBoundaries(SequenceTime leftBound, SequenceTime rightBound)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_leftBoundary != leftBound || _rightBoundary != rightBound) {
            _leftBoundary = leftBound;
            _rightBoundary = rightBound;
            changed = true;
        }
    }
    emit boundariesChanged(leftBound, rightBound, Natron::PLUGIN_EDITED);

}

// the reason (last line) differs in this version
void
TimeLine::onBoundariesChanged(SequenceTime leftBound, SequenceTime rightBound)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_leftBoundary != leftBound || _rightBoundary != rightBound) {
            _leftBoundary = leftBound;
            _rightBoundary = rightBound;
            changed = true;
        }
    }
     emit boundariesChanged(leftBound, rightBound, Natron::USER_EDITED);
}

void
TimeLine::removeAllKeyframesIndicators()
{
    bool wasEmpty = _keyframes.empty();
    _keyframes.clear();
    if (!wasEmpty) {
        emit keyframeIndicatorsChanged();
    }
}

void
TimeLine::addKeyframeIndicator(SequenceTime time)
{
    _keyframes.push_back(time);
    emit keyframeIndicatorsChanged();
}

void
TimeLine::addMultipleKeyframeIndicatorsAdded(const std::list<SequenceTime>& keys,
                                             bool emitSignal)
{
    _keyframes.insert(_keyframes.begin(),keys.begin(),keys.end());
    if (!keys.empty() && emitSignal) {
        emit keyframeIndicatorsChanged();
    }
}

void
TimeLine::removeKeyFrameIndicator(SequenceTime time)
{
    std::list<SequenceTime>::iterator it = std::find(_keyframes.begin(), _keyframes.end(), time);
    if (it != _keyframes.end()) {
        _keyframes.erase(it);
        emit keyframeIndicatorsChanged();
    }

}

void
TimeLine::removeMultipleKeyframeIndicator(const std::list<SequenceTime>& keys,
                                          bool emitSignal)
{
    for (std::list<SequenceTime>::const_iterator it = keys.begin(); it!=keys.end(); ++it) {
        std::list<SequenceTime>::iterator it2 = std::find(_keyframes.begin(), _keyframes.end(), *it);
        if (it2 != _keyframes.end()) {
            _keyframes.erase(it2);
        }
    }
    if (!keys.empty() && emitSignal) {
        emit keyframeIndicatorsChanged();
    }
}

void
TimeLine::addNodesKeyframesToTimeline(const std::list<Natron::Node*>& nodes)
{
    std::list<Natron::Node*>::const_iterator next = nodes.begin();
    ++next;
    for (std::list<Natron::Node*>::const_iterator it = nodes.begin(); it!=nodes.end(); ++it,++next) {
        (*it)->showKeyframesOnTimeline(next == nodes.end());
    }
}

void
TimeLine::addNodeKeyframesToTimeline(Natron::Node* node)
{
    node->showKeyframesOnTimeline(true);
}

void
TimeLine::removeNodesKeyframesFromTimeline(const std::list<Natron::Node*>& nodes)
{
    std::list<Natron::Node*>::const_iterator next = nodes.begin();
    ++next;
    for (std::list<Natron::Node*>::const_iterator it = nodes.begin(); it!=nodes.end(); ++it,++next) {
        (*it)->hideKeyframesFromTimeline(next == nodes.end());
    }

}

void
TimeLine::removeNodeKeyframesFromTimeline(Natron::Node* node)
{
    node->hideKeyframesFromTimeline(true);
}

void
TimeLine::getKeyframes(std::list<SequenceTime>* keys) const
{
    *keys = _keyframes;
}

void
TimeLine::goToPreviousKeyframe()
{
    _keyframes.sort();
    std::list<SequenceTime>::iterator lowerBound = std::lower_bound(_keyframes.begin(), _keyframes.end(), _currentFrame);
    if (lowerBound != _keyframes.begin()) {
        --lowerBound;
        seekFrame(*lowerBound,NULL);
    }
}

void
TimeLine::goToNextKeyframe()
{
    _keyframes.sort();
    std::list<SequenceTime>::iterator upperBound = std::upper_bound(_keyframes.begin(), _keyframes.end(), _currentFrame);
    if (upperBound != _keyframes.end()) {
        seekFrame(*upperBound,NULL);
    }
}
<commit_msg>TimeLine: add asserts for non-my-safe members<commit_after>//
//  TimeLine.cpp
//  Natron
//
//  Created by Frédéric Devernay on 24/09/13.
//
//

#include "TimeLine.h"

#ifndef NDEBUG
#include <QThread>
#include <QCoreApplication>
#endif

#include <cassert>
#include "Engine/Project.h"
#include "Engine/Node.h"

TimeLine::TimeLine(Natron::Project* project)
: _firstFrame(0)
, _lastFrame(0)
, _currentFrame(0)
, _leftBoundary(_firstFrame)
, _rightBoundary(_lastFrame)
, _keyframes()
, _project(project)
{}

SequenceTime
TimeLine::firstFrame() const
{
    QMutexLocker l(&_lock);
    return _firstFrame;
}

SequenceTime
TimeLine::lastFrame() const
{
    QMutexLocker l(&_lock);
   return _lastFrame;
}

SequenceTime
TimeLine::currentFrame() const
{
    QMutexLocker l(&_lock);
    return _currentFrame;
}

SequenceTime
TimeLine::leftBound() const
{
    QMutexLocker l(&_lock);
    return _leftBoundary;
}

SequenceTime
TimeLine::rightBound() const
{
    QMutexLocker l(&_lock);
    return _rightBoundary;
}

void
TimeLine::setFrameRange(SequenceTime first,
                        SequenceTime last)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_firstFrame != first || _lastFrame != last) {
            _firstFrame = first;
            _lastFrame = last;
            changed = true;
        }
    }
    if (changed) {
        emit frameRangeChanged(first, last);
        setBoundaries(first,last);
    }
}

void
TimeLine::seekFrame(SequenceTime frame,
                    Natron::OutputEffectInstance* caller)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_currentFrame != frame) {
            _currentFrame = frame;
            changed = true;
        }
    }
    if (changed) {
        _project->setLastTimelineSeekCaller(caller);
        emit frameChanged(frame, (int)Natron::PLAYBACK_SEEK);
    }
}

void
TimeLine::incrementCurrentFrame(Natron::OutputEffectInstance* caller)
{
    SequenceTime frame;
    {
        QMutexLocker l(&_lock);
        ++_currentFrame;
        frame = _currentFrame;
    }
    _project->setLastTimelineSeekCaller(caller);
    emit frameChanged(frame, (int)Natron::PLAYBACK_SEEK);
}

void
TimeLine::decrementCurrentFrame(Natron::OutputEffectInstance* caller)
{
    SequenceTime frame;
    {
        QMutexLocker l(&_lock);
        --_currentFrame;
        frame = _currentFrame;
    }
    _project->setLastTimelineSeekCaller(caller);
    emit frameChanged(frame, (int)Natron::PLAYBACK_SEEK);
}

void
TimeLine::onFrameChanged(SequenceTime frame)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_currentFrame != frame) {
            _currentFrame = frame;
            changed = true;
        }
    }
    if (changed) {
        /*This function is called in response to a signal emitted by a single timeline gui, but we also
         need to sync all the other timelines potentially existing.*/
        emit frameChanged(frame, (int)Natron::USER_SEEK);
    }
}

void
TimeLine::setBoundaries(SequenceTime leftBound, SequenceTime rightBound)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_leftBoundary != leftBound || _rightBoundary != rightBound) {
            _leftBoundary = leftBound;
            _rightBoundary = rightBound;
            changed = true;
        }
    }
    emit boundariesChanged(leftBound, rightBound, Natron::PLUGIN_EDITED);

}

// the reason (last line) differs in this version
void
TimeLine::onBoundariesChanged(SequenceTime leftBound, SequenceTime rightBound)
{
    bool changed = false;
    {
        QMutexLocker l(&_lock);
        if (_leftBoundary != leftBound || _rightBoundary != rightBound) {
            _leftBoundary = leftBound;
            _rightBoundary = rightBound;
            changed = true;
        }
    }
     emit boundariesChanged(leftBound, rightBound, Natron::USER_EDITED);
}

void
TimeLine::removeAllKeyframesIndicators()
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    bool wasEmpty = _keyframes.empty();
    _keyframes.clear();
    if (!wasEmpty) {
        emit keyframeIndicatorsChanged();
    }
}

void
TimeLine::addKeyframeIndicator(SequenceTime time)
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    _keyframes.push_back(time);
    emit keyframeIndicatorsChanged();
}

void
TimeLine::addMultipleKeyframeIndicatorsAdded(const std::list<SequenceTime>& keys,
                                             bool emitSignal)
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    _keyframes.insert(_keyframes.begin(),keys.begin(),keys.end());
    if (!keys.empty() && emitSignal) {
        emit keyframeIndicatorsChanged();
    }
}

void
TimeLine::removeKeyFrameIndicator(SequenceTime time)
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    std::list<SequenceTime>::iterator it = std::find(_keyframes.begin(), _keyframes.end(), time);
    if (it != _keyframes.end()) {
        _keyframes.erase(it);
        emit keyframeIndicatorsChanged();
    }

}

void
TimeLine::removeMultipleKeyframeIndicator(const std::list<SequenceTime>& keys,
                                          bool emitSignal)
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    for (std::list<SequenceTime>::const_iterator it = keys.begin(); it!=keys.end(); ++it) {
        std::list<SequenceTime>::iterator it2 = std::find(_keyframes.begin(), _keyframes.end(), *it);
        if (it2 != _keyframes.end()) {
            _keyframes.erase(it2);
        }
    }
    if (!keys.empty() && emitSignal) {
        emit keyframeIndicatorsChanged();
    }
}

void
TimeLine::addNodesKeyframesToTimeline(const std::list<Natron::Node*>& nodes)
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    std::list<Natron::Node*>::const_iterator next = nodes.begin();
    ++next;
    for (std::list<Natron::Node*>::const_iterator it = nodes.begin(); it!=nodes.end(); ++it,++next) {
        (*it)->showKeyframesOnTimeline(next == nodes.end());
    }
}

void
TimeLine::addNodeKeyframesToTimeline(Natron::Node* node)
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    node->showKeyframesOnTimeline(true);
}

void
TimeLine::removeNodesKeyframesFromTimeline(const std::list<Natron::Node*>& nodes)
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    std::list<Natron::Node*>::const_iterator next = nodes.begin();
    ++next;
    for (std::list<Natron::Node*>::const_iterator it = nodes.begin(); it!=nodes.end(); ++it,++next) {
        (*it)->hideKeyframesFromTimeline(next == nodes.end());
    }

}

void
TimeLine::removeNodeKeyframesFromTimeline(Natron::Node* node)
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    node->hideKeyframesFromTimeline(true);
}

void
TimeLine::getKeyframes(std::list<SequenceTime>* keys) const
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    *keys = _keyframes;
}

void
TimeLine::goToPreviousKeyframe()
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    _keyframes.sort();
    std::list<SequenceTime>::iterator lowerBound = std::lower_bound(_keyframes.begin(), _keyframes.end(), _currentFrame);
    if (lowerBound != _keyframes.begin()) {
        --lowerBound;
        seekFrame(*lowerBound,NULL);
    }
}

void
TimeLine::goToNextKeyframe()
{
    ///runs only in the main thread
    assert(QThread::currentThread() == qApp->thread());

    _keyframes.sort();
    std::list<SequenceTime>::iterator upperBound = std::upper_bound(_keyframes.begin(), _keyframes.end(), _currentFrame);
    if (upperBound != _keyframes.end()) {
        seekFrame(*upperBound,NULL);
    }
}
<|endoftext|>


<commit_before>/** @file
    @brief Implementation

    @date 2015

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2015 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Internal Includes
#include <osvr/Common/NetworkingSupport.h>
#include <osvr/Util/WideToUTF8.h>

// Library/third-party includes
// - none

// Standard includes
#include <iostream>
#include <type_traits>

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>

#endif

namespace osvr {
namespace common {

#ifdef _WIN32

    static inline std::string wsaErrorCodeToString(int err) {
        TCHAR buf[256] = {0};

        FormatMessage(
            FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
            err, 0, &(buf[0]), sizeof(buf) / sizeof(buf[0]), nullptr);
        return util::tcharToUTF8String(buf);
    }

    inline bool NetworkingSupport::m_start() {
        WSADATA wsaData;
        auto status = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (0 == status) {
            m_up = true;
            return true;
        }
        m_err = "WSAStartup failed: " + wsaErrorCodeToString(status);
        return false;
    }

    inline bool NetworkingSupport::m_stop() {
        if (SOCKET_ERROR == WSACleanup()) {
            m_err =
                "WSACleanup failed: " + wsaErrorCodeToString(WSAGetLastError());
            return false;
        }
        return true;
    }
#else
    // Don't think any other platforms need this.
    inline bool NetworkingSupport::m_start() { return true; }
    inline bool NetworkingSupport::m_stop() { return true; }
#endif

    NetworkingSupport::NetworkingSupport() : m_up(false), m_success(true) {
        m_success = m_start();
    }

    NetworkingSupport::~NetworkingSupport() {
        shutdown();
        if (!wasSuccessful()) {
            std::cerr << getError() << std::endl;
        }
    }

    void NetworkingSupport::shutdown() {
        m_success = true;
        m_err.clear();
        if (m_up) {
            m_success = m_stop();
        }
    }
} // namespace common
} // namespace osvr<commit_msg>Fixed VRPN network connections for Linux.<commit_after>/** @file
    @brief Implementation

    @date 2015

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2015 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Internal Includes
#include <osvr/Common/NetworkingSupport.h>
#include <osvr/Util/WideToUTF8.h>

// Library/third-party includes
// - none

// Standard includes
#include <iostream>
#include <type_traits>

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>

#endif

namespace osvr {
namespace common {

#ifdef _WIN32

    static inline std::string wsaErrorCodeToString(int err) {
        TCHAR buf[256] = {0};

        FormatMessage(
            FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
            err, 0, &(buf[0]), sizeof(buf) / sizeof(buf[0]), nullptr);
        return util::tcharToUTF8String(buf);
    }

    inline bool NetworkingSupport::m_start() {
        WSADATA wsaData;
        auto status = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (0 == status) {
            m_up = true;
            return true;
        }
        m_err = "WSAStartup failed: " + wsaErrorCodeToString(status);
        return false;
    }

    inline bool NetworkingSupport::m_stop() {
        if (SOCKET_ERROR == WSACleanup()) {
            m_err =
                "WSACleanup failed: " + wsaErrorCodeToString(WSAGetLastError());
            return false;
        }
        return true;
    }
#else
    // Don't think any other platforms need this.
    inline bool NetworkingSupport::m_start() { m_up = true; return true; }
    inline bool NetworkingSupport::m_stop() { return true; }
#endif

    NetworkingSupport::NetworkingSupport() : m_up(false), m_success(true) {
        m_success = m_start();
    }

    NetworkingSupport::~NetworkingSupport() {
        shutdown();
        if (!wasSuccessful()) {
            std::cerr << getError() << std::endl;
        }
    }

    void NetworkingSupport::shutdown() {
        m_success = true;
        m_err.clear();
        if (m_up) {
            m_success = m_stop();
        }
    }
} // namespace common
} // namespace osvr
<|endoftext|>


<commit_before>/*  This file is part of the Vc library.

    Copyright (C) 2010-2012 Matthias Kretz <kretz@kde.org>

    Vc 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.

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

*/

#include "unittest.h"

using namespace Vc;

template<typename V> void reads()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;

    V a = V::Zero();
    const T zero = 0;
    for (int i = 0; i < V::Size; ++i) {
        const T x = a[i];
        COMPARE(x, zero);
    }
    a = static_cast<V>(I::IndexesFromZero());
    for (int i = 0; i < V::Size; ++i) {
        const T x = a[i];
        const T y = i;
        COMPARE(x, y);
    }
}

template<typename V, size_t Index>
inline void readsConstantIndexTest(VC_ALIGNED_PARAMETER(V) a, VC_ALIGNED_PARAMETER(V) b)
{
    typedef typename V::EntryType T;
    {
        const T x = a[Index];
        const T zero = 0;
        COMPARE(x, zero) << Index;
    }{
        const T x = b[Index];
        const T y = Index;
        COMPARE(x, y) << Index;
    }
}

template<typename V, size_t Index>
struct ReadsConstantIndex
{
    ReadsConstantIndex(VC_ALIGNED_PARAMETER(V) a, VC_ALIGNED_PARAMETER(V) b)
    {
        readsConstantIndexTest<V, Index>(a, b);
        ReadsConstantIndex<V, Index - 1>(a, b);
    }
};

template<typename V>
struct ReadsConstantIndex<V, 0>
{
    ReadsConstantIndex(VC_ALIGNED_PARAMETER(V) a, VC_ALIGNED_PARAMETER(V) b)
    {
        readsConstantIndexTest<V, 0>(a, b);
    }
};

template<typename V> void readsConstantIndex()
{
    typedef typename V::IndexType I;

    V a = V::Zero();
    V b = static_cast<V>(I::IndexesFromZero());
    ReadsConstantIndex<V, V::Size - 1>(a, b);
}

template<typename V> void writes()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;

    V a;
    for (int i = 0; i < V::Size; ++i) {
        a[i] = static_cast<T>(i);
    }
    V b = static_cast<V>(I::IndexesFromZero());
    COMPARE(a, b);

    const T one = 1;
    const T two = 2;

    if (V::Size == 1) {
        a(a == 0) += one;
        a[0] += one;
        a(a == 0) += one;
        COMPARE(a, V(2));
    } else if (V::Size == 4) {
        a(a == 1) += two;
        a[2] += one;
        a(a == 3) += one;
        b(b == 1) += one;
        b(b == 2) += one;
        b(b == 3) += one;
        COMPARE(a, b);
    } else if (V::Size == 8 || V::Size == 16) {
        a(a == 2) += two;
        a[3] += one;
        a(a == 4) += one;
        b(b == 2) += one;
        b(b == 3) += one;
        b(b == 4) += one;
        COMPARE(a, b);
    } else if (V::Size == 2) { // a = [0, 1]; b = [0, 1]
        a(a == 0) += two;      // a = [2, 1]
        a[1] += one;           // a = [2, 2]
        a(a == 2) += one;      // a = [3, 3]
        b(b == 0) += one;      // b = [1, 1]
        b(b == 1) += one;      // b = [2, 2]
        b(b == 2) += one;      // b = [3, 3]
        COMPARE(a, b);
    } else {
        FAIL() << "unsupported Vector::Size";
    }
}

int main(int argc, char **argv)
{
    initTest(argc, argv);

    testAllTypes(reads);
    testAllTypes(writes);
    testAllTypes(readsConstantIndex);
    //testAllTypes(writesConstantIndex);

    return 0;
}
<commit_msg>document the expected value<commit_after>/*  This file is part of the Vc library.

    Copyright (C) 2010-2012 Matthias Kretz <kretz@kde.org>

    Vc 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.

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

*/

#include "unittest.h"

using namespace Vc;

template<typename V> void reads()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;

    V a = V::Zero();
    const T zero = 0;
    for (int i = 0; i < V::Size; ++i) {
        const T x = a[i];
        COMPARE(x, zero);
    }
    a = static_cast<V>(I::IndexesFromZero());
    for (int i = 0; i < V::Size; ++i) {
        const T x = a[i];
        const T y = i;
        COMPARE(x, y);
    }
}

template<typename V, size_t Index>
inline void readsConstantIndexTest(VC_ALIGNED_PARAMETER(V) a, VC_ALIGNED_PARAMETER(V) b)
{
    typedef typename V::EntryType T;
    {
        const T x = a[Index];
        const T zero = 0;
        COMPARE(x, zero) << Index;
    }{
        const T x = b[Index];
        const T y = Index;
        COMPARE(x, y) << Index;
    }
}

template<typename V, size_t Index>
struct ReadsConstantIndex
{
    ReadsConstantIndex(VC_ALIGNED_PARAMETER(V) a, VC_ALIGNED_PARAMETER(V) b)
    {
        readsConstantIndexTest<V, Index>(a, b);
        ReadsConstantIndex<V, Index - 1>(a, b);
    }
};

template<typename V>
struct ReadsConstantIndex<V, 0>
{
    ReadsConstantIndex(VC_ALIGNED_PARAMETER(V) a, VC_ALIGNED_PARAMETER(V) b)
    {
        readsConstantIndexTest<V, 0>(a, b);
    }
};

template<typename V> void readsConstantIndex()
{
    typedef typename V::IndexType I;

    V a = V::Zero();
    V b = static_cast<V>(I::IndexesFromZero());
    ReadsConstantIndex<V, V::Size - 1>(a, b);
}

template<typename V> void writes()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;

    V a;
    for (int i = 0; i < V::Size; ++i) {
        a[i] = static_cast<T>(i);
    }
    V b = static_cast<V>(I::IndexesFromZero());
    COMPARE(a, b);

    const T one = 1;
    const T two = 2;

    if (V::Size == 1) {
        a(a == 0) += one;
        a[0] += one;
        a(a == 0) += one;
        COMPARE(a, V(2));
    } else if (V::Size == 4) {
        a(a == 1) += two;
        a[2] += one;
        a(a == 3) += one;
        b(b == 1) += one;
        b(b == 2) += one;
        b(b == 3) += one;
        COMPARE(a, b);
    } else if (V::Size == 8 || V::Size == 16) {
        a(a == 2) += two;
        a[3] += one;
        a(a == 4) += one;
        b(b == 2) += one;
        b(b == 3) += one;
        b(b == 4) += one;
        // expected: [0, 1, 5, 5, 5, 5, 6, 7]
        COMPARE(a, b);
    } else if (V::Size == 2) { // a = [0, 1]; b = [0, 1]
        a(a == 0) += two;      // a = [2, 1]
        a[1] += one;           // a = [2, 2]
        a(a == 2) += one;      // a = [3, 3]
        b(b == 0) += one;      // b = [1, 1]
        b(b == 1) += one;      // b = [2, 2]
        b(b == 2) += one;      // b = [3, 3]
        COMPARE(a, b);
    } else {
        FAIL() << "unsupported Vector::Size";
    }
}

int main(int argc, char **argv)
{
    initTest(argc, argv);

    testAllTypes(reads);
    testAllTypes(writes);
    testAllTypes(readsConstantIndex);
    //testAllTypes(writesConstantIndex);

    return 0;
}
<|endoftext|>