<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#include "genericlinuxdeviceconfigurationwizardpages.h"
#include "ui_genericlinuxdeviceconfigurationwizardsetuppage.h"

#include "linuxdeviceconfiguration.h"

namespace RemoteLinux {
namespace Internal {

class GenericLinuxDeviceConfigurationWizardSetupPagePrivate
{
public:
    Ui::GenericLinuxDeviceConfigurationWizardSetupPage ui;
};

} // namespace Internal

using namespace Utils;

GenericLinuxDeviceConfigurationWizardSetupPage::GenericLinuxDeviceConfigurationWizardSetupPage(QWidget *parent) :
    QWizardPage(parent), m_d(new Internal::GenericLinuxDeviceConfigurationWizardSetupPagePrivate)
{
    m_d->ui.setupUi(this);
    setTitle(tr("Connection Data"));
    setSubTitle(QLatin1String(" ")); // For Qt bug (background color)
    m_d->ui.privateKeyPathChooser->setExpectedKind(PathChooser::File);
    connect(m_d->ui.nameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
    connect(m_d->ui.hostNameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
    connect(m_d->ui.userNameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
    connect(m_d->ui.privateKeyPathChooser, SIGNAL(validChanged()), SIGNAL(completeChanged()));
    connect(m_d->ui.passwordButton, SIGNAL(toggled(bool)), SLOT(handleAuthTypeChanged()));
}

GenericLinuxDeviceConfigurationWizardSetupPage::~GenericLinuxDeviceConfigurationWizardSetupPage()
{
    delete m_d;
}

void GenericLinuxDeviceConfigurationWizardSetupPage::initializePage()
{
    m_d->ui.nameLineEdit->setText(QLatin1String("(New Configuration)"));
    m_d->ui.hostNameLineEdit->setText(defaultHostName());
    m_d->ui.userNameLineEdit->setText(defaultUserName());
    m_d->ui.passwordButton->setChecked(true);
    m_d->ui.passwordLineEdit->setText(defaultPassWord());
    m_d->ui.privateKeyPathChooser->setPath(LinuxDeviceConfiguration::defaultPrivateKeyFilePath());
    handleAuthTypeChanged();
}

bool GenericLinuxDeviceConfigurationWizardSetupPage::isComplete() const
{
    return !configurationName().isEmpty() && !hostName().isEmpty() && !userName().isEmpty()
            && (authenticationType() == SshConnectionParameters::AuthenticationByPassword
                || !m_d->ui.privateKeyPathChooser->isValid());
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::configurationName() const
{
    return m_d->ui.nameLineEdit->text().trimmed();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::hostName() const
{
    return m_d->ui.hostNameLineEdit->text().trimmed();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::userName() const
{
    return m_d->ui.userNameLineEdit->text().trimmed();
}

SshConnectionParameters::AuthenticationType GenericLinuxDeviceConfigurationWizardSetupPage::authenticationType() const
{
    return m_d->ui.passwordButton->isChecked()
        ? SshConnectionParameters::AuthenticationByPassword
        : SshConnectionParameters::AuthenticationByKey;
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::password() const
{
    return m_d->ui.passwordLineEdit->text();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::privateKeyFilePath() const
{
    return m_d->ui.privateKeyPathChooser->path();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::defaultHostName() const
{
    return QString();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::defaultUserName() const
{
    return QString();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::defaultPassWord() const
{
    return QString();
}

void GenericLinuxDeviceConfigurationWizardSetupPage::handleAuthTypeChanged()
{
    m_d->ui.passwordLineEdit->setEnabled(authenticationType() == SshConnectionParameters::AuthenticationByPassword);
    m_d->ui.privateKeyPathChooser->setEnabled(authenticationType() == SshConnectionParameters::AuthenticationByKey);
    emit completeChanged();
}

GenericLinuxDeviceConfigurationWizardFinalPage::GenericLinuxDeviceConfigurationWizardFinalPage(QWidget *parent)
    : QWizardPage(parent), m_infoLabel(new QLabel(this))
{
    setTitle(tr("Setup Finished"));
    setSubTitle(QLatin1String(" ")); // For Qt bug (background color)
    m_infoLabel->setWordWrap(true);
    QVBoxLayout * const layout = new QVBoxLayout(this);
    layout->addWidget(m_infoLabel);
}

void GenericLinuxDeviceConfigurationWizardFinalPage::initializePage()
{
    m_infoLabel->setText(infoText());
}

QString GenericLinuxDeviceConfigurationWizardFinalPage::infoText() const
{
    return tr("The new device configuration will now be created.\n"
        "In addition, device connectivity will be tested.");
}

} // namespace RemoteLinux
<commit_msg>RemoteLinux: Fix wizard bug.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#include "genericlinuxdeviceconfigurationwizardpages.h"
#include "ui_genericlinuxdeviceconfigurationwizardsetuppage.h"

#include "linuxdeviceconfiguration.h"

namespace RemoteLinux {
namespace Internal {

class GenericLinuxDeviceConfigurationWizardSetupPagePrivate
{
public:
    Ui::GenericLinuxDeviceConfigurationWizardSetupPage ui;
};

} // namespace Internal

using namespace Utils;

GenericLinuxDeviceConfigurationWizardSetupPage::GenericLinuxDeviceConfigurationWizardSetupPage(QWidget *parent) :
    QWizardPage(parent), m_d(new Internal::GenericLinuxDeviceConfigurationWizardSetupPagePrivate)
{
    m_d->ui.setupUi(this);
    setTitle(tr("Connection Data"));
    setSubTitle(QLatin1String(" ")); // For Qt bug (background color)
    m_d->ui.privateKeyPathChooser->setExpectedKind(PathChooser::File);
    connect(m_d->ui.nameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
    connect(m_d->ui.hostNameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
    connect(m_d->ui.userNameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
    connect(m_d->ui.privateKeyPathChooser, SIGNAL(validChanged()), SIGNAL(completeChanged()));
    connect(m_d->ui.passwordButton, SIGNAL(toggled(bool)), SLOT(handleAuthTypeChanged()));
}

GenericLinuxDeviceConfigurationWizardSetupPage::~GenericLinuxDeviceConfigurationWizardSetupPage()
{
    delete m_d;
}

void GenericLinuxDeviceConfigurationWizardSetupPage::initializePage()
{
    m_d->ui.nameLineEdit->setText(QLatin1String("(New Configuration)"));
    m_d->ui.hostNameLineEdit->setText(defaultHostName());
    m_d->ui.userNameLineEdit->setText(defaultUserName());
    m_d->ui.passwordButton->setChecked(true);
    m_d->ui.passwordLineEdit->setText(defaultPassWord());
    m_d->ui.privateKeyPathChooser->setPath(LinuxDeviceConfiguration::defaultPrivateKeyFilePath());
    handleAuthTypeChanged();
}

bool GenericLinuxDeviceConfigurationWizardSetupPage::isComplete() const
{
    return !configurationName().isEmpty() && !hostName().isEmpty() && !userName().isEmpty()
            && (authenticationType() == SshConnectionParameters::AuthenticationByPassword
                || m_d->ui.privateKeyPathChooser->isValid());
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::configurationName() const
{
    return m_d->ui.nameLineEdit->text().trimmed();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::hostName() const
{
    return m_d->ui.hostNameLineEdit->text().trimmed();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::userName() const
{
    return m_d->ui.userNameLineEdit->text().trimmed();
}

SshConnectionParameters::AuthenticationType GenericLinuxDeviceConfigurationWizardSetupPage::authenticationType() const
{
    return m_d->ui.passwordButton->isChecked()
        ? SshConnectionParameters::AuthenticationByPassword
        : SshConnectionParameters::AuthenticationByKey;
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::password() const
{
    return m_d->ui.passwordLineEdit->text();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::privateKeyFilePath() const
{
    return m_d->ui.privateKeyPathChooser->path();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::defaultHostName() const
{
    return QString();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::defaultUserName() const
{
    return QString();
}

QString GenericLinuxDeviceConfigurationWizardSetupPage::defaultPassWord() const
{
    return QString();
}

void GenericLinuxDeviceConfigurationWizardSetupPage::handleAuthTypeChanged()
{
    m_d->ui.passwordLineEdit->setEnabled(authenticationType() == SshConnectionParameters::AuthenticationByPassword);
    m_d->ui.privateKeyPathChooser->setEnabled(authenticationType() == SshConnectionParameters::AuthenticationByKey);
    emit completeChanged();
}

GenericLinuxDeviceConfigurationWizardFinalPage::GenericLinuxDeviceConfigurationWizardFinalPage(QWidget *parent)
    : QWizardPage(parent), m_infoLabel(new QLabel(this))
{
    setTitle(tr("Setup Finished"));
    setSubTitle(QLatin1String(" ")); // For Qt bug (background color)
    m_infoLabel->setWordWrap(true);
    QVBoxLayout * const layout = new QVBoxLayout(this);
    layout->addWidget(m_infoLabel);
}

void GenericLinuxDeviceConfigurationWizardFinalPage::initializePage()
{
    m_infoLabel->setText(infoText());
}

QString GenericLinuxDeviceConfigurationWizardFinalPage::infoText() const
{
    return tr("The new device configuration will now be created.\n"
        "In addition, device connectivity will be tested.");
}

} // namespace RemoteLinux
<|endoftext|>


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

bool MultiNodeEdit::_set(const StringName& p_name, const Variant& p_value){

	Node *es = EditorNode::get_singleton()->get_edited_scene();
	if (!es)
		return false;

	String name = p_name;

	if (name=="scripts/script") { // script/script set is intercepted at object level (check Variant Object::get() ) ,so use a different name
		name="script/script";
	}

	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();

	ur->create_action(TTR("MultiNode Set")+" "+String(name));
	for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {

		if (!es->has_node(E->get()))
			continue;

		Node*n=es->get_node(E->get());
		if (!n)
			continue;

		ur->add_do_property(n,name,p_value);
		ur->add_undo_property(n,name,n->get(name));

	}
	ur->add_do_method(EditorNode::get_singleton()->get_property_editor(),"refresh");
	ur->add_undo_method(EditorNode::get_singleton()->get_property_editor(),"refresh");

	ur->commit_action();
	return true;
}

bool MultiNodeEdit::_get(const StringName& p_name,Variant &r_ret) const {

	Node *es = EditorNode::get_singleton()->get_edited_scene();
	if (!es)
		return false;

	String name=p_name;
	if (name=="scripts/script") { // script/script set is intercepted at object level (check Variant Object::get() ) ,so use a different name
		name="script/script";
	}

	for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {

		if (!es->has_node(E->get()))
			continue;

		const Node*n=es->get_node(E->get());
		if (!n)
			continue;

		bool found;
		r_ret=n->get(name,&found);
		if (found)
			return true;

	}

	return false;
}

void MultiNodeEdit::_get_property_list( List<PropertyInfo> *p_list) const{

	HashMap<String,PLData> usage;

	Node *es = EditorNode::get_singleton()->get_edited_scene();
	if (!es)
		return;

	int nc=0;

	List<PLData*> datas;

	for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {

		if (!es->has_node(E->get()))
			continue;

		Node*n=es->get_node(E->get());
		if (!n)
			continue;

		List<PropertyInfo> plist;
		n->get_property_list(&plist,true);

		for(List<PropertyInfo>::Element *F=plist.front();F;F=F->next()) {

			if (F->get().name=="script/script")
				continue; //added later manually, since this is intercepted before being set (check Variant Object::get() )
			if (!usage.has(F->get().name)) {
				PLData pld;
				pld.uses=0;
				pld.info=F->get();
				usage[F->get().name]=pld;
				datas.push_back(usage.getptr(F->get().name));
			}

			usage[F->get().name].uses++;
		}

		nc++;
	}

	for (List<PLData*>::Element *E=datas.front();E;E=E->next()) {

		if (nc==E->get()->uses) {
			p_list->push_back(E->get()->info);
		}
	}

	p_list->push_back(PropertyInfo(Variant::OBJECT,"scripts/script",PROPERTY_HINT_RESOURCE_TYPE,"Script"));

}

void MultiNodeEdit::clear_nodes() {

	nodes.clear();
}

void MultiNodeEdit::add_node(const NodePath& p_node){

	nodes.push_back(p_node);
}

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

bool MultiNodeEdit::_set(const StringName& p_name, const Variant& p_value){

	Node *es = EditorNode::get_singleton()->get_edited_scene();
	if (!es)
		return false;

	String name = p_name;

	if (name=="scripts/script") { // script/script set is intercepted at object level (check Variant Object::get() ) ,so use a different name
		name="script/script";
	}

	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();

	ur->create_action(TTR("MultiNode Set")+" "+String(name));
	for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {

		if (!es->has_node(E->get()))
			continue;

		Node*n=es->get_node(E->get());
		if (!n)
			continue;

		if (p_value.get_type() == Variant::NODE_PATH) {
			Node *tonode = n->get_node(p_value);
			NodePath p_path = n->get_path_to(tonode);
			ur->add_do_property(n,name,p_path);
		} else {
			ur->add_do_property(n,name,p_value);
		}

		ur->add_undo_property(n,name,n->get(name));

	}
	ur->add_do_method(EditorNode::get_singleton()->get_property_editor(),"refresh");
	ur->add_undo_method(EditorNode::get_singleton()->get_property_editor(),"refresh");

	ur->commit_action();
	return true;
}

bool MultiNodeEdit::_get(const StringName& p_name,Variant &r_ret) const {

	Node *es = EditorNode::get_singleton()->get_edited_scene();
	if (!es)
		return false;

	String name=p_name;
	if (name=="scripts/script") { // script/script set is intercepted at object level (check Variant Object::get() ) ,so use a different name
		name="script/script";
	}

	for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {

		if (!es->has_node(E->get()))
			continue;

		const Node*n=es->get_node(E->get());
		if (!n)
			continue;

		bool found;
		r_ret=n->get(name,&found);
		if (found)
			return true;

	}

	return false;
}

void MultiNodeEdit::_get_property_list( List<PropertyInfo> *p_list) const{

	HashMap<String,PLData> usage;

	Node *es = EditorNode::get_singleton()->get_edited_scene();
	if (!es)
		return;

	int nc=0;

	List<PLData*> datas;

	for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {

		if (!es->has_node(E->get()))
			continue;

		Node*n=es->get_node(E->get());
		if (!n)
			continue;

		List<PropertyInfo> plist;
		n->get_property_list(&plist,true);

		for(List<PropertyInfo>::Element *F=plist.front();F;F=F->next()) {

			if (F->get().name=="script/script")
				continue; //added later manually, since this is intercepted before being set (check Variant Object::get() )
			if (!usage.has(F->get().name)) {
				PLData pld;
				pld.uses=0;
				pld.info=F->get();
				usage[F->get().name]=pld;
				datas.push_back(usage.getptr(F->get().name));
			}

			usage[F->get().name].uses++;
		}

		nc++;
	}

	for (List<PLData*>::Element *E=datas.front();E;E=E->next()) {

		if (nc==E->get()->uses) {
			p_list->push_back(E->get()->info);
		}
	}

	p_list->push_back(PropertyInfo(Variant::OBJECT,"scripts/script",PROPERTY_HINT_RESOURCE_TYPE,"Script"));

}

void MultiNodeEdit::clear_nodes() {

	nodes.clear();
}

void MultiNodeEdit::add_node(const NodePath& p_node){

	nodes.push_back(p_node);
}

MultiNodeEdit::MultiNodeEdit()
{
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "basetextblockselection.h"

using namespace TextEditor;

BaseTextBlockSelection::BaseTextBlockSelection()
    :firstVisualColumn(0), lastVisualColumn(0), anchor(BottomRight)
{
}

void BaseTextBlockSelection::moveAnchor(int blockNumber, int visualColumn)
{
    if (visualColumn >= 0) {
        if (anchor % 2) {
            lastVisualColumn = visualColumn;
            if (lastVisualColumn < firstVisualColumn) {
                qSwap(firstVisualColumn, lastVisualColumn);
                anchor = (Anchor) (anchor - 1);
            }
        } else {
            firstVisualColumn = visualColumn;
            if (firstVisualColumn > lastVisualColumn) {
                qSwap(firstVisualColumn, lastVisualColumn);
                anchor = (Anchor) (anchor + 1);
            }
        }
    }

    if (blockNumber >= 0 && blockNumber < firstBlock.document()->blockCount()) {
        if (anchor <= TopRight) {
            firstBlock.setPosition(firstBlock.document()->findBlockByNumber(blockNumber).position());
            if (firstBlock.blockNumber() > lastBlock.blockNumber()) {
                qSwap(firstBlock, lastBlock);
                anchor = (Anchor) (anchor + 2);
            }
        } else {
            lastBlock.setPosition(firstBlock.document()->findBlockByNumber(blockNumber).position());
            if (lastBlock.blockNumber() < firstBlock.blockNumber()) {
                qSwap(firstBlock, lastBlock);
                anchor = (Anchor) (anchor - 2);
            }
        }
    }
    firstBlock.movePosition(QTextCursor::StartOfBlock);
    lastBlock.movePosition(QTextCursor::EndOfBlock);
}

int BaseTextBlockSelection::position(const TabSettings &ts) const
{
    const QTextBlock &block = anchor <= TopRight ? lastBlock.block() : firstBlock.block();
    const int column = anchor % 2 ? firstVisualColumn : lastVisualColumn;
    return block.position() + ts.positionAtColumn(block.text(), column);
}

QTextCursor BaseTextBlockSelection::selection(const TabSettings &ts) const
{
    QTextCursor cursor = firstBlock;
    if (anchor <= TopRight) {
        cursor.setPosition(lastBlock.block().position() + ts.positionAtColumn(lastBlock.block().text(), lastVisualColumn));
        cursor.setPosition(firstBlock.block().position() + ts.positionAtColumn(firstBlock.block().text(), firstVisualColumn),
                           QTextCursor::KeepAnchor);
    } else {
        cursor.setPosition(firstBlock.block().position() + ts.positionAtColumn(firstBlock.block().text(), firstVisualColumn));
        cursor.setPosition(lastBlock.block().position() + ts.positionAtColumn(lastBlock.block().text(), lastVisualColumn),
                           QTextCursor::KeepAnchor);
    }
    return cursor;
}

void BaseTextBlockSelection::fromSelection(const TabSettings &ts, const QTextCursor &selection)
{
    firstBlock = selection;
    firstBlock.setPosition(selection.selectionStart());
    firstVisualColumn = ts.columnAt(firstBlock.block().text(), firstBlock.positionInBlock());
    lastBlock = selection;
    lastBlock.setPosition(selection.selectionEnd());
    lastVisualColumn = ts.columnAt(lastBlock.block().text(), lastBlock.positionInBlock());
    if (selection.anchor() > selection.position())
        anchor = TopLeft;
    else
        anchor = BottomRight;

    firstBlock.movePosition(QTextCursor::StartOfBlock);
    lastBlock.movePosition(QTextCursor::EndOfBlock);
}
<commit_msg>fix build<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "basetextblockselection.h"
#include <QTextBlock>
#include <QTextCursor>

using namespace TextEditor;

BaseTextBlockSelection::BaseTextBlockSelection()
    :firstVisualColumn(0), lastVisualColumn(0), anchor(BottomRight)
{
}

void BaseTextBlockSelection::moveAnchor(int blockNumber, int visualColumn)
{
    if (visualColumn >= 0) {
        if (anchor % 2) {
            lastVisualColumn = visualColumn;
            if (lastVisualColumn < firstVisualColumn) {
                qSwap(firstVisualColumn, lastVisualColumn);
                anchor = (Anchor) (anchor - 1);
            }
        } else {
            firstVisualColumn = visualColumn;
            if (firstVisualColumn > lastVisualColumn) {
                qSwap(firstVisualColumn, lastVisualColumn);
                anchor = (Anchor) (anchor + 1);
            }
        }
    }

    if (blockNumber >= 0 && blockNumber < firstBlock.document()->blockCount()) {
        if (anchor <= TopRight) {
            firstBlock.setPosition(firstBlock.document()->findBlockByNumber(blockNumber).position());
            if (firstBlock.blockNumber() > lastBlock.blockNumber()) {
                qSwap(firstBlock, lastBlock);
                anchor = (Anchor) (anchor + 2);
            }
        } else {
            lastBlock.setPosition(firstBlock.document()->findBlockByNumber(blockNumber).position());
            if (lastBlock.blockNumber() < firstBlock.blockNumber()) {
                qSwap(firstBlock, lastBlock);
                anchor = (Anchor) (anchor - 2);
            }
        }
    }
    firstBlock.movePosition(QTextCursor::StartOfBlock);
    lastBlock.movePosition(QTextCursor::EndOfBlock);
}

int BaseTextBlockSelection::position(const TabSettings &ts) const
{
    const QTextBlock &block = anchor <= TopRight ? lastBlock.block() : firstBlock.block();
    const int column = anchor % 2 ? firstVisualColumn : lastVisualColumn;
    return block.position() + ts.positionAtColumn(block.text(), column);
}

QTextCursor BaseTextBlockSelection::selection(const TabSettings &ts) const
{
    QTextCursor cursor = firstBlock;
    if (anchor <= TopRight) {
        cursor.setPosition(lastBlock.block().position() + ts.positionAtColumn(lastBlock.block().text(), lastVisualColumn));
        cursor.setPosition(firstBlock.block().position() + ts.positionAtColumn(firstBlock.block().text(), firstVisualColumn),
                           QTextCursor::KeepAnchor);
    } else {
        cursor.setPosition(firstBlock.block().position() + ts.positionAtColumn(firstBlock.block().text(), firstVisualColumn));
        cursor.setPosition(lastBlock.block().position() + ts.positionAtColumn(lastBlock.block().text(), lastVisualColumn),
                           QTextCursor::KeepAnchor);
    }
    return cursor;
}

void BaseTextBlockSelection::fromSelection(const TabSettings &ts, const QTextCursor &selection)
{
    firstBlock = selection;
    firstBlock.setPosition(selection.selectionStart());
    firstVisualColumn = ts.columnAt(firstBlock.block().text(), firstBlock.positionInBlock());
    lastBlock = selection;
    lastBlock.setPosition(selection.selectionEnd());
    lastVisualColumn = ts.columnAt(lastBlock.block().text(), lastBlock.positionInBlock());
    if (selection.anchor() > selection.position())
        anchor = TopLeft;
    else
        anchor = BottomRight;

    firstBlock.movePosition(QTextCursor::StartOfBlock);
    lastBlock.movePosition(QTextCursor::EndOfBlock);
}
<|endoftext|>


<commit_before>#include <plasp/Language.h>

#include <boost/assign.hpp>
#include <boost/bimap.hpp>

namespace plasp
{

////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Language
//
////////////////////////////////////////////////////////////////////////////////////////////////////

using LanguageNames = boost::bimap<Language::Type, std::string>;

////////////////////////////////////////////////////////////////////////////////////////////////////

const LanguageNames languageNames = boost::assign::list_of<LanguageNames::relation>
	(Language::Type::PDDL, "PDDL")
	(Language::Type::SAS, "SAS")
	(Language::Type::Unknown, "Unknown");

////////////////////////////////////////////////////////////////////////////////////////////////////

std::string Language::toString(Language::Type language)
{
	const auto match = languageNames.left.find(language);

	if (match != languageNames.left.end())
		return "Unknown";

	return match->second;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

Language::Type Language::fromString(const std::string &languageName)
{
	const auto match = languageNames.right.find(languageName);

	if (match != languageNames.right.end())
		return Language::Type::Unknown;

	return match->second;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

}
<commit_msg>Fixed wrong comparison for language detection.<commit_after>#include <plasp/Language.h>

#include <boost/assign.hpp>
#include <boost/bimap.hpp>

namespace plasp
{

////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Language
//
////////////////////////////////////////////////////////////////////////////////////////////////////

using LanguageNames = boost::bimap<Language::Type, std::string>;

////////////////////////////////////////////////////////////////////////////////////////////////////

const LanguageNames languageNames = boost::assign::list_of<LanguageNames::relation>
	(Language::Type::PDDL, "PDDL")
	(Language::Type::SAS, "SAS")
	(Language::Type::Unknown, "Unknown");

////////////////////////////////////////////////////////////////////////////////////////////////////

std::string Language::toString(Language::Type language)
{
	const auto match = languageNames.left.find(language);

	if (match == languageNames.left.end())
		return "Unknown";

	return match->second;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

Language::Type Language::fromString(const std::string &languageName)
{
	const auto match = languageNames.right.find(languageName);

	if (match == languageNames.right.end())
		return Language::Type::Unknown;

	return match->second;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

}
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////
//
//  chemical equilibrium
//
//  $Author$
//  $Revision$
//  $Date$
//
//  copyright California Institute of Technology 2002
//
/////////////////////////////////////////////////////////////

// turn off warnings under Windows
#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif

#include <cantera/Cantera.h>
#include <time.h>
#include "example_utils.h"
#include <cantera/equilibrium.h>

#include <cantera/IdealGasMix.h>

//-------------------------------------------------------------------

// utility functions for plotting

template<class G, class V>
void makeEquilDataLabels(const G& gas, V& names) {
    int nsp = gas.nSpecies();
    names.resize(nsp + 2);
    names[0]  = "Temperature (K)";
    names[1]  = "Pressure (Pa)";
    int k;
    for (k = 0; k < nsp; k++) names[2+k] = gas.speciesName(k);
}

template<class G, class A>
void plotEquilSoln(string fname, string fmt, string title, const G& gas,
    const A& soln) {
    vector<string> names;
    makeEquilDataLabels(gas, names);
    writePlotFile(fname, fmt, title, names, soln);
}
//-----------------------------------------------------------------

// Equilibrium example. This is written as a function so that one
// driver program can run multiple examples.
// The action taken depends on input parameter job:
//     job = 0:   print a one-line description of the example.
//     job = 1:   print a longer description
//     job = 2:   print description, then run the example.

int equil_example1(int job) {

    cout << "Chemical equilibrium." << endl;
    if (job > 0) {
        cout << "Equilibrium composition and pressure for a "
             << "range of temperatures at constant density." << endl;
    }
    if (job <= 1) return 0;

    // header
    writeCanteraHeader(cout);

    // create a gas mixture, and set its state

    IdealGasMix gas("silane.cti", "silane");
    int nsp = gas.nSpecies();

    int ntemps = 50;   // number of temperatures
    Array2D output(nsp+2, ntemps);

    // main loop
    doublereal temp;
    doublereal thigh = gas.maxTemp();
    doublereal tlow = 500.0;
    doublereal dt = (thigh - tlow)/(ntemps);
    doublereal pres = 0.01*OneAtm;
    clock_t t0 = clock();
    for (int i = 0; i < ntemps; i++) {
        temp = tlow + dt*i;
        if (temp > gas.maxTemp()) break;
        gas.setState_TPX(temp, pres, "SIH4:0.01, H2:0.99");

        equilibrate(gas,"TP");
        output(0,i) = temp;
        output(1,i) = gas.pressure();
        gas.getMoleFractions(&output(2,i));

    }
    clock_t t1 = clock();

    // make a Tecplot data file and an Excel spreadsheet
    string plotTitle = "equilibrium example 1: "
                       "chemical equilibrium";
    plotEquilSoln("eq1.dat", "TEC", plotTitle, gas, output);
    plotEquilSoln("eq1.csv", "XL", plotTitle, gas, output);

    // print timing data
    doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC;
    cout << " time = " << tmm << endl << endl;

    cout << "Output files:" << endl
         << "  eq1.csv    (Excel CSV file)" << endl
         << "  eq1.dat    (Tecplot data file)" << endl;

    return 0;

}
<commit_msg>Replaced silane.cti with silane.xml so that it will work for python none installation.<commit_after>/////////////////////////////////////////////////////////////
//
//  chemical equilibrium
//
//  $Author$
//  $Revision$
//  $Date$
//
//  copyright California Institute of Technology 2002
//
/////////////////////////////////////////////////////////////

// turn off warnings under Windows
#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif

#include <cantera/Cantera.h>
#include <time.h>
#include "example_utils.h"
#include <cantera/equilibrium.h>

#include <cantera/IdealGasMix.h>

//-------------------------------------------------------------------

// utility functions for plotting

template<class G, class V>
void makeEquilDataLabels(const G& gas, V& names) {
    int nsp = gas.nSpecies();
    names.resize(nsp + 2);
    names[0]  = "Temperature (K)";
    names[1]  = "Pressure (Pa)";
    int k;
    for (k = 0; k < nsp; k++) names[2+k] = gas.speciesName(k);
}

template<class G, class A>
void plotEquilSoln(string fname, string fmt, string title, const G& gas,
    const A& soln) {
    vector<string> names;
    makeEquilDataLabels(gas, names);
    writePlotFile(fname, fmt, title, names, soln);
}
//-----------------------------------------------------------------

// Equilibrium example. This is written as a function so that one
// driver program can run multiple examples.
// The action taken depends on input parameter job:
//     job = 0:   print a one-line description of the example.
//     job = 1:   print a longer description
//     job = 2:   print description, then run the example.

int equil_example1(int job) {

    cout << "Chemical equilibrium." << endl;
    if (job > 0) {
        cout << "Equilibrium composition and pressure for a "
             << "range of temperatures at constant density." << endl;
    }
    if (job <= 1) return 0;

    // header
    writeCanteraHeader(cout);

    // create a gas mixture, and set its state

    //IdealGasMix gas("silane.cti", "silane");
    IdealGasMix gas("silane.xml", "silane");
    int nsp = gas.nSpecies();

    int ntemps = 50;   // number of temperatures
    Array2D output(nsp+2, ntemps);

    // main loop
    doublereal temp;
    doublereal thigh = gas.maxTemp();
    doublereal tlow = 500.0;
    doublereal dt = (thigh - tlow)/(ntemps);
    doublereal pres = 0.01*OneAtm;
    clock_t t0 = clock();
    for (int i = 0; i < ntemps; i++) {
        temp = tlow + dt*i;
        if (temp > gas.maxTemp()) break;
        gas.setState_TPX(temp, pres, "SIH4:0.01, H2:0.99");

        equilibrate(gas,"TP");
        output(0,i) = temp;
        output(1,i) = gas.pressure();
        gas.getMoleFractions(&output(2,i));

    }
    clock_t t1 = clock();

    // make a Tecplot data file and an Excel spreadsheet
    string plotTitle = "equilibrium example 1: "
                       "chemical equilibrium";
    plotEquilSoln("eq1.dat", "TEC", plotTitle, gas, output);
    plotEquilSoln("eq1.csv", "XL", plotTitle, gas, output);

    // print timing data
    doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC;
    cout << " time = " << tmm << endl << endl;

    cout << "Output files:" << endl
         << "  eq1.csv    (Excel CSV file)" << endl
         << "  eq1.dat    (Tecplot data file)" << endl;

    return 0;

}
<|endoftext|>


<commit_before>
#if defined(DISC_UNION_TEST_MAIN)
#include <stdio.h>
#include <stdlib.h>

#include "disc_union.h"

#include "vector.h"
#include "strings.h"

struct MyClass{
	char name[16];
	int i;
	float f;

	Vector<int> it;
};

struct MyOtherClass{
	void* data;
	int g;
	float h;
	short header[6];
};

// Define a macro that takes a macro
#define DISC_LIST(mac) \
	mac(MyClass) \
	mac(MyOtherClass) \
	mac(String)

// This generates the actual struct body
DEFINE_DISCRIMINATED_UNION(MyUnion, DISC_LIST)

// We don't need to undef it, but it's a good idea
#undef DISC_LIST

void DoSomething(const MyUnion& mu) {
	ASSERT(mu.IsString());
}

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

	MyClass mc;
	mc.it.PushBack(1);
	MyClass mc2;
	mc2.it.PushBack(2);
	MyOtherClass moc;

	MyUnion un;
	ASSERT(un.type == MyUnion::UE_None);
	ASSERT(!un.IsMyClass());
	ASSERT(!un.IsMyOtherClass());
	ASSERT(!un.IsString());

	un = mc;
	ASSERT(un.type == MyUnion::UE_MyClass);
	ASSERT(un.IsMyClass());
	ASSERT(!un.IsMyOtherClass());
	ASSERT(!un.IsString());

	un = moc;
	ASSERT(un.type == MyUnion::UE_MyOtherClass);
	ASSERT(!un.IsMyClass());
	ASSERT(un.IsMyOtherClass());
	ASSERT(!un.IsString());

	un = mc;
	ASSERT(un.type == MyUnion::UE_MyClass);
	ASSERT(un.IsMyClass());
	ASSERT(!un.IsMyOtherClass());
	ASSERT(!un.IsString());

	un = mc2;
	ASSERT(un.type == MyUnion::UE_MyClass);

	un = mc;
	ASSERT(un.type == MyUnion::UE_MyClass);

	String str1 = "LALA";
	ASSERT(str1.GetRef() == 1);
	un = str1;
	ASSERT(un.type == MyUnion::UE_String);
	ASSERT(un.AsString() == str1);
	ASSERT(str1.GetRef() == 2);

	un = mc2;
	ASSERT(un.type == MyUnion::UE_MyClass);
	ASSERT(str1.GetRef() == 1);

	un = str1;

	ASSERT(str1.GetRef() == 2);

	{
		MyUnion un2 = un;
		ASSERT(un2.type == MyUnion::UE_String);
		ASSERT(str1.GetRef() == 3);
		MyUnion un3;
		un3 = un2;
		ASSERT(un3.type == MyUnion::UE_String);
		ASSERT(str1.GetRef() == 4);
	}

	ASSERT(str1.GetRef() == 2);

	{
		MyUnion un2 = str1;
		ASSERT(str1.GetRef() == 3);
		DoSomething(str1);
		ASSERT(str1.GetRef() == 3);
		ASSERT(un2.IsString());
		const MyUnion& un2_ref = un2;
		ASSERT(un2_ref.IsString());
		ASSERT(un2_ref.AsString().GetRef() == 3);
	}

	ASSERT(str1.GetRef() == 2);

	return 0;
}
#endif
<commit_msg>Add some more disc_union tests.<commit_after>
#if defined(DISC_UNION_TEST_MAIN)
#include <stdio.h>
#include <stdlib.h>

#include "disc_union.h"

#include "vector.h"
#include "strings.h"

struct MyClass{
	char name[16];
	int i;
	float f;

	Vector<int> it;
};

struct MyOtherClass{
	void* data;
	int g;
	float h;
	short header[6];
};

// Define a macro that takes a macro
#define DISC_LIST(mac) \
	mac(MyClass) \
	mac(MyOtherClass) \
	mac(String)

// This generates the actual struct body
DEFINE_DISCRIMINATED_UNION(MyUnion, DISC_LIST)

// We don't need to undef it, but it's a good idea
#undef DISC_LIST

void DoSomething(const MyUnion& mu) {
	ASSERT(mu.IsString());
}

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

	MyClass mc;
	mc.it.PushBack(1);
	MyClass mc2;
	mc2.it.PushBack(2);
	MyOtherClass moc;

	MyUnion un;
	ASSERT(un.type == MyUnion::UE_None);
	ASSERT(!un.IsMyClass());
	ASSERT(!un.IsMyOtherClass());
	ASSERT(!un.IsString());

	un = mc;
	ASSERT(un.type == MyUnion::UE_MyClass);
	ASSERT(un.IsMyClass());
	ASSERT(!un.IsMyOtherClass());
	ASSERT(!un.IsString());

	un = moc;
	ASSERT(un.type == MyUnion::UE_MyOtherClass);
	ASSERT(!un.IsMyClass());
	ASSERT(un.IsMyOtherClass());
	ASSERT(!un.IsString());

	un = mc;
	ASSERT(un.type == MyUnion::UE_MyClass);
	ASSERT(un.IsMyClass());
	ASSERT(!un.IsMyOtherClass());
	ASSERT(!un.IsString());

	un = mc2;
	ASSERT(un.type == MyUnion::UE_MyClass);

	un = mc;
	ASSERT(un.type == MyUnion::UE_MyClass);

	String str1 = "LALA";
	ASSERT(str1.GetRef() == 1);
	un = str1;
	ASSERT(un.type == MyUnion::UE_String);
	ASSERT(un.AsString() == str1);
	ASSERT(str1.GetRef() == 2);

	un = mc2;
	ASSERT(un.type == MyUnion::UE_MyClass);
	ASSERT(str1.GetRef() == 1);

	un = str1;

	ASSERT(str1.GetRef() == 2);

	{
		MyUnion un2 = un;
		ASSERT(un2.type == MyUnion::UE_String);
		ASSERT(str1.GetRef() == 3);
		MyUnion un3;
		un3 = un2;
		ASSERT(un3.type == MyUnion::UE_String);
		ASSERT(str1.GetRef() == 4);
	}

	ASSERT(str1.GetRef() == 2);

	{
		MyUnion un2 = str1;
		ASSERT(str1.GetRef() == 3);
		DoSomething(str1);
		ASSERT(str1.GetRef() == 3);
		ASSERT(un2.IsString());
		const MyUnion& un2_ref = un2;
		ASSERT(un2_ref.IsString());
		ASSERT(un2_ref.AsString().GetRef() == 3);
		un2 = MyUnion();
		ASSERT(!un2_ref.IsString());

		ASSERT(str1.GetRef() == 2);
		un2 = str1;
		ASSERT(str1.GetRef() == 3);
	}

	ASSERT(str1.GetRef() == 2);

	return 0;
}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#pragma once

#include "bytes.hh"
#include "timestamp.hh"
#include "tombstone.hh"
#include "gc_clock.hh"
#include "utils/managed_bytes.hh"
#include "net/byteorder.hh"
#include <cstdint>
#include <iostream>

template<typename T>
static inline
void set_field(managed_bytes& v, unsigned offset, T val) {
    reinterpret_cast<net::packed<T>*>(v.begin() + offset)->raw = net::hton(val);
}

template<typename T>
static inline
T get_field(const bytes_view& v, unsigned offset) {
    return net::ntoh(*reinterpret_cast<const net::packed<T>*>(v.begin() + offset));
}

class atomic_cell_or_collection;

/*
 * Represents atomic cell layout. Works on serialized form.
 *
 * Layout:
 *
 *  <live>  := <int8_t:flags><int64_t:timestamp>(<int32_t:expiry><int32_t:ttl>)?<value>
 *  <dead>  := <int8_t:    0><int64_t:timestamp><int32_t:deletion_time>
 */
class atomic_cell_type final {
private:
    static constexpr int8_t DEAD_FLAGS = 0;
    static constexpr int8_t LIVE_FLAG = 0x01;
    static constexpr int8_t EXPIRY_FLAG = 0x02; // When present, expiry field is present. Set only for live cells
    static constexpr unsigned flags_size = 1;
    static constexpr unsigned timestamp_offset = flags_size;
    static constexpr unsigned timestamp_size = 8;
    static constexpr unsigned expiry_offset = timestamp_offset + timestamp_size;
    static constexpr unsigned expiry_size = 4;
    static constexpr unsigned deletion_time_offset = timestamp_offset + timestamp_size;
    static constexpr unsigned deletion_time_size = 4;
    static constexpr unsigned ttl_offset = expiry_offset + expiry_size;
    static constexpr unsigned ttl_size = 4;
private:
    static bool is_live(const bytes_view& cell) {
        return cell[0] != DEAD_FLAGS;
    }
    static bool is_live_and_has_ttl(const bytes_view& cell) {
        return cell[0] & EXPIRY_FLAG;
    }
    static bool is_dead(const bytes_view& cell) {
        return cell[0] == DEAD_FLAGS;
    }
    // Can be called on live and dead cells
    static api::timestamp_type timestamp(const bytes_view& cell) {
        return get_field<api::timestamp_type>(cell, timestamp_offset);
    }
    // Can be called on live cells only
    static bytes_view value(bytes_view cell) {
        auto expiry_field_size = bool(cell[0] & EXPIRY_FLAG) * (expiry_size + ttl_size);
        auto value_offset = flags_size + timestamp_size + expiry_field_size;
        cell.remove_prefix(value_offset);
        return cell;
    }
    // Can be called only when is_dead() is true.
    static gc_clock::time_point deletion_time(const bytes_view& cell) {
        assert(is_dead(cell));
        return gc_clock::time_point(gc_clock::duration(
            get_field<int32_t>(cell, deletion_time_offset)));
    }
    // Can be called only when is_live_and_has_ttl() is true.
    static gc_clock::time_point expiry(const bytes_view& cell) {
        assert(is_live_and_has_ttl(cell));
        auto expiry = get_field<int32_t>(cell, expiry_offset);
        return gc_clock::time_point(gc_clock::duration(expiry));
    }
    // Can be called only when is_live_and_has_ttl() is true.
    static gc_clock::duration ttl(const bytes_view& cell) {
        assert(is_live_and_has_ttl(cell));
        return gc_clock::duration(get_field<int32_t>(cell, ttl_offset));
    }
    static managed_bytes make_dead(api::timestamp_type timestamp, gc_clock::time_point deletion_time) {
        managed_bytes b(managed_bytes::initialized_later(), flags_size + timestamp_size + deletion_time_size);
        b[0] = DEAD_FLAGS;
        set_field(b, timestamp_offset, timestamp);
        set_field(b, deletion_time_offset, deletion_time.time_since_epoch().count());
        return b;
    }
    static managed_bytes make_live(api::timestamp_type timestamp, bytes_view value) {
        auto value_offset = flags_size + timestamp_size;
        managed_bytes b(managed_bytes::initialized_later(), value_offset + value.size());
        b[0] = LIVE_FLAG;
        set_field(b, timestamp_offset, timestamp);
        std::copy_n(value.begin(), value.size(), b.begin() + value_offset);
        return b;
    }
    static managed_bytes make_live(api::timestamp_type timestamp, bytes_view value, gc_clock::time_point expiry, gc_clock::duration ttl) {
        auto value_offset = flags_size + timestamp_size + expiry_size + ttl_size;
        managed_bytes b(managed_bytes::initialized_later(), value_offset + value.size());
        b[0] = EXPIRY_FLAG | LIVE_FLAG;
        set_field(b, timestamp_offset, timestamp);
        set_field(b, expiry_offset, expiry.time_since_epoch().count());
        set_field(b, ttl_offset, ttl.count());
        std::copy_n(value.begin(), value.size(), b.begin() + value_offset);
        return b;
    }
    template<typename ByteContainer>
    friend class atomic_cell_base;
    friend class atomic_cell;
};

template<typename ByteContainer>
class atomic_cell_base {
protected:
    ByteContainer _data;
protected:
    atomic_cell_base(ByteContainer&& data) : _data(std::forward<ByteContainer>(data)) { }
    atomic_cell_base(const ByteContainer& data) : _data(data) { }
public:
    bool is_live() const {
        return atomic_cell_type::is_live(_data);
    }
    bool is_live(tombstone t) const {
        return is_live() && !is_covered_by(t);
    }
    bool is_live(tombstone t, gc_clock::time_point now) const {
        return is_live() && !is_covered_by(t) && !has_expired(now);
    }
    bool is_live_and_has_ttl() const {
        return atomic_cell_type::is_live_and_has_ttl(_data);
    }
    bool is_dead(gc_clock::time_point now) const {
        return atomic_cell_type::is_dead(_data) || has_expired(now);
    }
    bool is_covered_by(tombstone t) const {
        return timestamp() <= t.timestamp;
    }
    // Can be called on live and dead cells
    api::timestamp_type timestamp() const {
        return atomic_cell_type::timestamp(_data);
    }
    // Can be called on live cells only
    bytes_view value() const {
        return atomic_cell_type::value(_data);
    }
    // Can be called only when is_dead(gc_clock::time_point)
    gc_clock::time_point deletion_time() const {
        return !is_live() ? atomic_cell_type::deletion_time(_data) : expiry() - ttl();
    }
    // Can be called only when is_live_and_has_ttl()
    gc_clock::time_point expiry() const {
        return atomic_cell_type::expiry(_data);
    }
    // Can be called only when is_live_and_has_ttl()
    gc_clock::duration ttl() const {
        return atomic_cell_type::ttl(_data);
    }
    // Can be called on live and dead cells
    bool has_expired(gc_clock::time_point now) const {
        return is_live_and_has_ttl() && expiry() < now;
    }
    bytes_view serialize() const {
        return _data;
    }
};

class atomic_cell_view final : public atomic_cell_base<bytes_view> {
    atomic_cell_view(bytes_view data) : atomic_cell_base(data) {}
public:
    static atomic_cell_view from_bytes(bytes_view data) { return atomic_cell_view(data); }

    friend class atomic_cell;
    friend std::ostream& operator<<(std::ostream& os, const atomic_cell_view& acv);
};

class atomic_cell final : public atomic_cell_base<managed_bytes> {
    atomic_cell(managed_bytes b) : atomic_cell_base(std::move(b)) {}
public:
    atomic_cell(const atomic_cell&) = default;
    atomic_cell(atomic_cell&&) = default;
    atomic_cell& operator=(const atomic_cell&) = default;
    atomic_cell& operator=(atomic_cell&&) = default;
    static atomic_cell from_bytes(bytes b) {
        return atomic_cell(std::move(b));
    }
    atomic_cell(atomic_cell_view other) : atomic_cell_base(bytes { other._data.begin(), other._data.end() }) {}
    operator atomic_cell_view() const {
        return atomic_cell_view(_data);
    }
    static atomic_cell make_dead(api::timestamp_type timestamp, gc_clock::time_point deletion_time) {
        return atomic_cell_type::make_dead(timestamp, deletion_time);
    }
    static atomic_cell make_live(api::timestamp_type timestamp, bytes_view value) {
        return atomic_cell_type::make_live(timestamp, value);
    }
    static atomic_cell make_live(api::timestamp_type timestamp, bytes_view value,
        gc_clock::time_point expiry, gc_clock::duration ttl)
    {
        return atomic_cell_type::make_live(timestamp, value, expiry, ttl);
    }
    static atomic_cell make_live(api::timestamp_type timestamp, bytes_view value, ttl_opt ttl) {
        if (!ttl) {
            return atomic_cell_type::make_live(timestamp, value);
        } else {
            return atomic_cell_type::make_live(timestamp, value, gc_clock::now() + *ttl, *ttl);
        }
    }
    friend class atomic_cell_or_collection;
    friend std::ostream& operator<<(std::ostream& os, const atomic_cell& ac);
};

// Represents a mutation of a collection.  Actual format is determined by collection type,
// and is:
//   set:  list of atomic_cell
//   map:  list of pair<atomic_cell, bytes> (for key/value)
//   list: tbd, probably ugly
class collection_mutation {
public:
    struct view {
        bytes_view data;
        bytes_view serialize() const { return data; }
        static view from_bytes(bytes_view v) { return { v }; }
    };
    struct one {
        managed_bytes data;
        one() {}
        one(managed_bytes b) : data(std::move(b)) {}
        one(view v) : data(v.data) {}
        operator view() const { return { data }; }
    };
};

namespace db {
template<typename T>
class serializer;
}

// A variant type that can hold either an atomic_cell, or a serialized collection.
// Which type is stored is determinied by the schema.
class atomic_cell_or_collection final {
    managed_bytes _data;

    template<typename T>
    friend class db::serializer;
private:
    atomic_cell_or_collection() = default;
    atomic_cell_or_collection(managed_bytes&& data) : _data(std::move(data)) {}
public:
    atomic_cell_or_collection(atomic_cell ac) : _data(std::move(ac._data)) {}
    static atomic_cell_or_collection from_atomic_cell(atomic_cell data) { return { std::move(data._data) }; }
    atomic_cell_view as_atomic_cell() const { return atomic_cell_view::from_bytes(_data); }
    atomic_cell_or_collection(collection_mutation::one cm) : _data(std::move(cm.data)) {}
    static atomic_cell_or_collection from_collection_mutation(collection_mutation::one data) {
        return std::move(data.data);
    }
    collection_mutation::view as_collection_mutation() const {
        return collection_mutation::view{_data};
    }
    bytes_view serialize() const {
        return _data;
    }
    friend std::ostream& operator<<(std::ostream&, const atomic_cell_or_collection&);
};

class column_definition;

int compare_atomic_cell_for_merge(atomic_cell_view left, atomic_cell_view right);
void merge_column(const column_definition& def,
        atomic_cell_or_collection& old,
        const atomic_cell_or_collection& neww);
<commit_msg>db: Avoid allocation of temporary bytes object<commit_after>/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#pragma once

#include "bytes.hh"
#include "timestamp.hh"
#include "tombstone.hh"
#include "gc_clock.hh"
#include "utils/managed_bytes.hh"
#include "net/byteorder.hh"
#include <cstdint>
#include <iostream>

template<typename T>
static inline
void set_field(managed_bytes& v, unsigned offset, T val) {
    reinterpret_cast<net::packed<T>*>(v.begin() + offset)->raw = net::hton(val);
}

template<typename T>
static inline
T get_field(const bytes_view& v, unsigned offset) {
    return net::ntoh(*reinterpret_cast<const net::packed<T>*>(v.begin() + offset));
}

class atomic_cell_or_collection;

/*
 * Represents atomic cell layout. Works on serialized form.
 *
 * Layout:
 *
 *  <live>  := <int8_t:flags><int64_t:timestamp>(<int32_t:expiry><int32_t:ttl>)?<value>
 *  <dead>  := <int8_t:    0><int64_t:timestamp><int32_t:deletion_time>
 */
class atomic_cell_type final {
private:
    static constexpr int8_t DEAD_FLAGS = 0;
    static constexpr int8_t LIVE_FLAG = 0x01;
    static constexpr int8_t EXPIRY_FLAG = 0x02; // When present, expiry field is present. Set only for live cells
    static constexpr unsigned flags_size = 1;
    static constexpr unsigned timestamp_offset = flags_size;
    static constexpr unsigned timestamp_size = 8;
    static constexpr unsigned expiry_offset = timestamp_offset + timestamp_size;
    static constexpr unsigned expiry_size = 4;
    static constexpr unsigned deletion_time_offset = timestamp_offset + timestamp_size;
    static constexpr unsigned deletion_time_size = 4;
    static constexpr unsigned ttl_offset = expiry_offset + expiry_size;
    static constexpr unsigned ttl_size = 4;
private:
    static bool is_live(const bytes_view& cell) {
        return cell[0] != DEAD_FLAGS;
    }
    static bool is_live_and_has_ttl(const bytes_view& cell) {
        return cell[0] & EXPIRY_FLAG;
    }
    static bool is_dead(const bytes_view& cell) {
        return cell[0] == DEAD_FLAGS;
    }
    // Can be called on live and dead cells
    static api::timestamp_type timestamp(const bytes_view& cell) {
        return get_field<api::timestamp_type>(cell, timestamp_offset);
    }
    // Can be called on live cells only
    static bytes_view value(bytes_view cell) {
        auto expiry_field_size = bool(cell[0] & EXPIRY_FLAG) * (expiry_size + ttl_size);
        auto value_offset = flags_size + timestamp_size + expiry_field_size;
        cell.remove_prefix(value_offset);
        return cell;
    }
    // Can be called only when is_dead() is true.
    static gc_clock::time_point deletion_time(const bytes_view& cell) {
        assert(is_dead(cell));
        return gc_clock::time_point(gc_clock::duration(
            get_field<int32_t>(cell, deletion_time_offset)));
    }
    // Can be called only when is_live_and_has_ttl() is true.
    static gc_clock::time_point expiry(const bytes_view& cell) {
        assert(is_live_and_has_ttl(cell));
        auto expiry = get_field<int32_t>(cell, expiry_offset);
        return gc_clock::time_point(gc_clock::duration(expiry));
    }
    // Can be called only when is_live_and_has_ttl() is true.
    static gc_clock::duration ttl(const bytes_view& cell) {
        assert(is_live_and_has_ttl(cell));
        return gc_clock::duration(get_field<int32_t>(cell, ttl_offset));
    }
    static managed_bytes make_dead(api::timestamp_type timestamp, gc_clock::time_point deletion_time) {
        managed_bytes b(managed_bytes::initialized_later(), flags_size + timestamp_size + deletion_time_size);
        b[0] = DEAD_FLAGS;
        set_field(b, timestamp_offset, timestamp);
        set_field(b, deletion_time_offset, deletion_time.time_since_epoch().count());
        return b;
    }
    static managed_bytes make_live(api::timestamp_type timestamp, bytes_view value) {
        auto value_offset = flags_size + timestamp_size;
        managed_bytes b(managed_bytes::initialized_later(), value_offset + value.size());
        b[0] = LIVE_FLAG;
        set_field(b, timestamp_offset, timestamp);
        std::copy_n(value.begin(), value.size(), b.begin() + value_offset);
        return b;
    }
    static managed_bytes make_live(api::timestamp_type timestamp, bytes_view value, gc_clock::time_point expiry, gc_clock::duration ttl) {
        auto value_offset = flags_size + timestamp_size + expiry_size + ttl_size;
        managed_bytes b(managed_bytes::initialized_later(), value_offset + value.size());
        b[0] = EXPIRY_FLAG | LIVE_FLAG;
        set_field(b, timestamp_offset, timestamp);
        set_field(b, expiry_offset, expiry.time_since_epoch().count());
        set_field(b, ttl_offset, ttl.count());
        std::copy_n(value.begin(), value.size(), b.begin() + value_offset);
        return b;
    }
    template<typename ByteContainer>
    friend class atomic_cell_base;
    friend class atomic_cell;
};

template<typename ByteContainer>
class atomic_cell_base {
protected:
    ByteContainer _data;
protected:
    atomic_cell_base(ByteContainer&& data) : _data(std::forward<ByteContainer>(data)) { }
    atomic_cell_base(const ByteContainer& data) : _data(data) { }
public:
    bool is_live() const {
        return atomic_cell_type::is_live(_data);
    }
    bool is_live(tombstone t) const {
        return is_live() && !is_covered_by(t);
    }
    bool is_live(tombstone t, gc_clock::time_point now) const {
        return is_live() && !is_covered_by(t) && !has_expired(now);
    }
    bool is_live_and_has_ttl() const {
        return atomic_cell_type::is_live_and_has_ttl(_data);
    }
    bool is_dead(gc_clock::time_point now) const {
        return atomic_cell_type::is_dead(_data) || has_expired(now);
    }
    bool is_covered_by(tombstone t) const {
        return timestamp() <= t.timestamp;
    }
    // Can be called on live and dead cells
    api::timestamp_type timestamp() const {
        return atomic_cell_type::timestamp(_data);
    }
    // Can be called on live cells only
    bytes_view value() const {
        return atomic_cell_type::value(_data);
    }
    // Can be called only when is_dead(gc_clock::time_point)
    gc_clock::time_point deletion_time() const {
        return !is_live() ? atomic_cell_type::deletion_time(_data) : expiry() - ttl();
    }
    // Can be called only when is_live_and_has_ttl()
    gc_clock::time_point expiry() const {
        return atomic_cell_type::expiry(_data);
    }
    // Can be called only when is_live_and_has_ttl()
    gc_clock::duration ttl() const {
        return atomic_cell_type::ttl(_data);
    }
    // Can be called on live and dead cells
    bool has_expired(gc_clock::time_point now) const {
        return is_live_and_has_ttl() && expiry() < now;
    }
    bytes_view serialize() const {
        return _data;
    }
};

class atomic_cell_view final : public atomic_cell_base<bytes_view> {
    atomic_cell_view(bytes_view data) : atomic_cell_base(data) {}
public:
    static atomic_cell_view from_bytes(bytes_view data) { return atomic_cell_view(data); }

    friend class atomic_cell;
    friend std::ostream& operator<<(std::ostream& os, const atomic_cell_view& acv);
};

class atomic_cell final : public atomic_cell_base<managed_bytes> {
    atomic_cell(managed_bytes b) : atomic_cell_base(std::move(b)) {}
public:
    atomic_cell(const atomic_cell&) = default;
    atomic_cell(atomic_cell&&) = default;
    atomic_cell& operator=(const atomic_cell&) = default;
    atomic_cell& operator=(atomic_cell&&) = default;
    static atomic_cell from_bytes(managed_bytes b) {
        return atomic_cell(std::move(b));
    }
    atomic_cell(atomic_cell_view other) : atomic_cell_base(managed_bytes{other._data}) {}
    operator atomic_cell_view() const {
        return atomic_cell_view(_data);
    }
    static atomic_cell make_dead(api::timestamp_type timestamp, gc_clock::time_point deletion_time) {
        return atomic_cell_type::make_dead(timestamp, deletion_time);
    }
    static atomic_cell make_live(api::timestamp_type timestamp, bytes_view value) {
        return atomic_cell_type::make_live(timestamp, value);
    }
    static atomic_cell make_live(api::timestamp_type timestamp, bytes_view value,
        gc_clock::time_point expiry, gc_clock::duration ttl)
    {
        return atomic_cell_type::make_live(timestamp, value, expiry, ttl);
    }
    static atomic_cell make_live(api::timestamp_type timestamp, bytes_view value, ttl_opt ttl) {
        if (!ttl) {
            return atomic_cell_type::make_live(timestamp, value);
        } else {
            return atomic_cell_type::make_live(timestamp, value, gc_clock::now() + *ttl, *ttl);
        }
    }
    friend class atomic_cell_or_collection;
    friend std::ostream& operator<<(std::ostream& os, const atomic_cell& ac);
};

// Represents a mutation of a collection.  Actual format is determined by collection type,
// and is:
//   set:  list of atomic_cell
//   map:  list of pair<atomic_cell, bytes> (for key/value)
//   list: tbd, probably ugly
class collection_mutation {
public:
    struct view {
        bytes_view data;
        bytes_view serialize() const { return data; }
        static view from_bytes(bytes_view v) { return { v }; }
    };
    struct one {
        managed_bytes data;
        one() {}
        one(managed_bytes b) : data(std::move(b)) {}
        one(view v) : data(v.data) {}
        operator view() const { return { data }; }
    };
};

namespace db {
template<typename T>
class serializer;
}

// A variant type that can hold either an atomic_cell, or a serialized collection.
// Which type is stored is determinied by the schema.
class atomic_cell_or_collection final {
    managed_bytes _data;

    template<typename T>
    friend class db::serializer;
private:
    atomic_cell_or_collection() = default;
    atomic_cell_or_collection(managed_bytes&& data) : _data(std::move(data)) {}
public:
    atomic_cell_or_collection(atomic_cell ac) : _data(std::move(ac._data)) {}
    static atomic_cell_or_collection from_atomic_cell(atomic_cell data) { return { std::move(data._data) }; }
    atomic_cell_view as_atomic_cell() const { return atomic_cell_view::from_bytes(_data); }
    atomic_cell_or_collection(collection_mutation::one cm) : _data(std::move(cm.data)) {}
    static atomic_cell_or_collection from_collection_mutation(collection_mutation::one data) {
        return std::move(data.data);
    }
    collection_mutation::view as_collection_mutation() const {
        return collection_mutation::view{_data};
    }
    bytes_view serialize() const {
        return _data;
    }
    friend std::ostream& operator<<(std::ostream&, const atomic_cell_or_collection&);
};

class column_definition;

int compare_atomic_cell_for_merge(atomic_cell_view left, atomic_cell_view right);
void merge_column(const column_definition& def,
        atomic_cell_or_collection& old,
        const atomic_cell_or_collection& neww);
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#include <gtest/gtest.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/pcl_tests.h>

using namespace pcl;
using namespace pcl::test;

PointCloud<PointXYZ> cloud;
const size_t size = 10 * 480;

TEST (PointCloud, size)
{
  EXPECT_EQ(cloud.points.size (), cloud.size ());
}

TEST (PointCloud, sq_brackets_wrapper)
{
  for (uint32_t i = 0; i < size; ++i)
    EXPECT_EQ_VECTORS (cloud.points[i].getVector3fMap (),
                       cloud[i].getVector3fMap ());
}

TEST (PointCloud, at)
{
  for (uint32_t i = 0; i < size; ++i)
    EXPECT_EQ_VECTORS (cloud.points.at (i).getVector3fMap (),
                       cloud.at (i).getVector3fMap ());
}

TEST (PointCloud, front)
{
  EXPECT_EQ_VECTORS (cloud.points.front ().getVector3fMap (),
                     cloud.front ().getVector3fMap ());
}

TEST (PointCloud, back)
{
  EXPECT_EQ_VECTORS (cloud.points.back ().getVector3fMap (),
                     cloud.back ().getVector3fMap ());
}

TEST (PointCloud, constructor_with_allocation)
{
  PointCloud<PointXYZ> cloud2 (5, 80);
  EXPECT_EQ (cloud2.width, 5);
  EXPECT_EQ (cloud2.height, 80);
  EXPECT_EQ (cloud2.size (), 5*80);
}

TEST (PointCloud, iterators)
{
  EXPECT_EQ_VECTORS (cloud.begin ()->getVector3fMap (),
                     cloud.points.begin ()->getVector3fMap ());
  //EXPECT_EQ_VECTORS (cloud.end ()->getVector3fMap (),
  //                   cloud.points.end ()->getVector3fMap ());
  PointCloud<PointXYZ>::const_iterator pit = cloud.begin ();
  PointCloud<PointXYZ>::VectorType::const_iterator pit2 = cloud.points.begin ();
  for (; pit < cloud.end (); ++pit2, ++pit)
    EXPECT_EQ_VECTORS (pit->getVector3fMap (), pit2->getVector3fMap ());
}

TEST (PointCloud, insert_range)
{
  PointCloud<PointXYZ> cloud2 (10, 1);
  for (uint32_t i = 0; i < 10; ++i)
    cloud2[i] = PointXYZ (5*i+0,5*i+1,5*i+2);

  uint32_t old_size = cloud.size ();
  cloud.insert (cloud.begin (), cloud2.begin (), cloud2.end ());
  EXPECT_EQ (cloud.width, cloud.size ());
  EXPECT_EQ (cloud.height, 1);
  EXPECT_EQ (cloud.width, old_size + cloud2.size ());
  PointCloud<PointXYZ>::const_iterator pit = cloud.begin ();
  PointCloud<PointXYZ>::const_iterator pit2 = cloud2.begin ();
  for (; pit2 < cloud2.end (); ++pit2, ++pit)
    EXPECT_EQ_VECTORS (pit->getVector3fMap (), pit2->getVector3fMap ());
}

int
main (int argc, char** argv)
{
  cloud.width = 10;
  cloud.height = 480;
  for (uint32_t i = 0; i < size; ++i)
    cloud.points.push_back (PointXYZ (3*i+0,3*i+1,3*i+2));

  testing::InitGoogleTest (&argc, argv);
  return (RUN_ALL_TESTS ());
}
<commit_msg>Add a unit test for the valued constructor with allocation<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#include <gtest/gtest.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/pcl_tests.h>

using namespace pcl;
using namespace pcl::test;

PointCloud<PointXYZ> cloud;
const size_t size = 10 * 480;

TEST (PointCloud, size)
{
  EXPECT_EQ(cloud.points.size (), cloud.size ());
}

TEST (PointCloud, sq_brackets_wrapper)
{
  for (uint32_t i = 0; i < size; ++i)
    EXPECT_EQ_VECTORS (cloud.points[i].getVector3fMap (),
                       cloud[i].getVector3fMap ());
}

TEST (PointCloud, at)
{
  for (uint32_t i = 0; i < size; ++i)
    EXPECT_EQ_VECTORS (cloud.points.at (i).getVector3fMap (),
                       cloud.at (i).getVector3fMap ());
}

TEST (PointCloud, front)
{
  EXPECT_EQ_VECTORS (cloud.points.front ().getVector3fMap (),
                     cloud.front ().getVector3fMap ());
}

TEST (PointCloud, back)
{
  EXPECT_EQ_VECTORS (cloud.points.back ().getVector3fMap (),
                     cloud.back ().getVector3fMap ());
}

TEST (PointCloud, constructor_with_allocation)
{
  PointCloud<PointXYZ> cloud2 (5, 80);
  EXPECT_EQ (cloud2.width, 5);
  EXPECT_EQ (cloud2.height, 80);
  EXPECT_EQ (cloud2.size (), 5*80);
}

TEST (PointCloud, constructor_with_allocation_valued)
{
  PointXYZ nan_point (0.1, 0.2, 0.3);
  PointCloud<PointXYZ> cloud2 (5, 80, nan_point);
  EXPECT_EQ (cloud2.width, 5);
  EXPECT_EQ (cloud2.height, 80);
  EXPECT_EQ (cloud2.size (), 5*80);
  for (PointCloud<PointXYZ>::const_iterator pit = cloud2.begin ();
       pit != cloud2.end ();
       ++pit)
  {
    EXPECT_NEAR (pit->x, 0.1, 1e-3);
    EXPECT_NEAR (pit->y, 0.2, 1e-3);
    EXPECT_NEAR (pit->z, 0.3, 1e-3);
  }

}

TEST (PointCloud, iterators)
{
  EXPECT_EQ_VECTORS (cloud.begin ()->getVector3fMap (),
                     cloud.points.begin ()->getVector3fMap ());
  //EXPECT_EQ_VECTORS (cloud.end ()->getVector3fMap (),
  //                   cloud.points.end ()->getVector3fMap ());
  PointCloud<PointXYZ>::const_iterator pit = cloud.begin ();
  PointCloud<PointXYZ>::VectorType::const_iterator pit2 = cloud.points.begin ();
  for (; pit < cloud.end (); ++pit2, ++pit)
    EXPECT_EQ_VECTORS (pit->getVector3fMap (), pit2->getVector3fMap ());
}

TEST (PointCloud, insert_range)
{
  PointCloud<PointXYZ> cloud2 (10, 1);
  for (uint32_t i = 0; i < 10; ++i)
    cloud2[i] = PointXYZ (5*i+0,5*i+1,5*i+2);

  uint32_t old_size = cloud.size ();
  cloud.insert (cloud.begin (), cloud2.begin (), cloud2.end ());
  EXPECT_EQ (cloud.width, cloud.size ());
  EXPECT_EQ (cloud.height, 1);
  EXPECT_EQ (cloud.width, old_size + cloud2.size ());
  PointCloud<PointXYZ>::const_iterator pit = cloud.begin ();
  PointCloud<PointXYZ>::const_iterator pit2 = cloud2.begin ();
  for (; pit2 < cloud2.end (); ++pit2, ++pit)
    EXPECT_EQ_VECTORS (pit->getVector3fMap (), pit2->getVector3fMap ());
}

int
main (int argc, char** argv)
{
  cloud.width = 10;
  cloud.height = 480;
  for (uint32_t i = 0; i < size; ++i)
    cloud.points.push_back (PointXYZ (3*i+0,3*i+1,3*i+2));

  testing::InitGoogleTest (&argc, argv);
  return (RUN_ALL_TESTS ());
}
<|endoftext|>


<commit_before>/// @file wlog_tools.cpp
/// @brief Well Logs manipulation algorithms
/// @author uentity
/// @version 1.0
/// @date 27.02.2014
/// @copyright This source code is released under the terms of
///            the BSD License. See LICENSE for more details.

#ifndef WLOG_TOOLS_TMEEHO84
#define WLOG_TOOLS_TMEEHO84

#include "bs_kernel.h"
#include "conf.h"
#include <limits>
// DEBUG
//#include <iostream>

namespace blue_sky {

// hidden implementation
namespace {

typedef v_float::iterator vf_iterator;
typedef v_float::const_iterator cvf_iterator;
typedef v_float::reverse_iterator vf_riterator;
typedef v_float::const_reverse_iterator cvf_riterator;

// depth and share same iterator type
template< class data_iterator, class grid_iterator, class res_iterator >
void projection_impl(
	//const spv_float& wlog_data, const spv_float& wlog_dept,
	const data_iterator& p_data_begin, const data_iterator& p_data_end,
	const data_iterator& p_dept_begin, const data_iterator& p_dept_end,
	grid_iterator& p_grid, const grid_iterator& p_grid_end,
	res_iterator& p_res
) {
	// setup iterators
	//const cvf_iterator p_dept_begin = wlog_dept->begin();
	//const cvf_iterator p_dept_end = p_dept_begin + wlog_sz;

	const ulong wlog_sz = std::min< ulong >(p_data_end - p_data_begin, p_dept_end - p_dept_begin);
	//const ulong wlog_sz = std::min(wlog_data->size(), wlog_dept->size());
	if(wlog_sz == 0)
		return;

	// find starting point on well log
	data_iterator p_dept = std::lower_bound(
		p_dept_begin, p_dept_end, *p_grid
	);
	if(p_dept == p_dept_end)
		// grid is fully outside of well log depths
		return;

	data_iterator p_data = p_data_begin + (p_dept - p_dept_begin);

	// DEBUG
	//std::cout << "++wlog_mean_projection:" << std::endl;
	//std::cout << "log_dept = [" << *p_dept << ", " << *(p_dept_end - 1) << "]" << std::endl;
	//std::cout << "grid = [" << *p_grid << ", " << *(p_grid_end - 1) << "]" << std::endl;
	// position dest grid to next boundary
	++p_grid;
	const res_iterator p_res_end = p_res + (p_grid_end - p_grid - 1);

	// main cycle
	t_float win_sum = 0;
	// win_sz counts only valid numbers that fits in window
	// raw_sz counts all values in window, including NaNs
	ulong win_sz = 0, raw_sz = 0;
	while(p_grid != p_grid_end) {
		// if we reached window boundary
		if(*p_dept > *p_grid) {
			if(win_sz)
				*p_res = win_sum / win_sz;
			else if(!raw_sz && (p_dept != p_dept_begin)) {
				// assign prev log value only if we had no NaNs in window
				*p_res = *(p_data - 1);
			}

			// next step on dest grid and resulting array
			if(++p_res == p_res_end)
				break;
			++p_grid;
			win_sum = 0;
			win_sz = 0;
			raw_sz = 0;
		}
		else {
			// we're inside window
			// check for NaN
			if(!(*p_data != *p_data)) {
				win_sum += *p_data;
				++win_sz;
			}
			// count all values in raw_sz
			++raw_sz;
			// next step in well log
			++p_data; ++p_dept;
			if(p_dept == p_dept_end) {
				if(win_sz)
					*p_res = win_sum / win_sz;
				break;
			}
		}
	}
}

} // eof hidden namespace

BS_API spv_float wlog_mean_projection(
	spv_float wlog_data, spv_float wlog_dept, spv_float dest_grid
) {
	// sanity
	spv_float res = BS_KERNEL.create_object(v_float::bs_type());
	if(!wlog_data->size() || !wlog_dept->size() || dest_grid->size() < 2 || !res)
		return res;
	res->resize(dest_grid->size() - 1);
	// fill resulting array with NaN
	std::fill(res->begin(), res->end(), std::numeric_limits< double >::quiet_NaN());

	// check grid ordering
	if(dest_grid->ss(0) < dest_grid->ss(dest_grid->size() - 1)) {
		// normal ordering
		cvf_iterator p_grid = dest_grid->begin();
		const cvf_iterator p_grid_end = dest_grid->end();
		vf_iterator p_res = res->begin();

		// check depth ordering
		if(wlog_dept->ss(0) < wlog_dept->ss(wlog_dept->size() - 1)) {
			projection_impl(
				wlog_data->begin(), wlog_data->end(),
				wlog_dept->begin(), wlog_dept->end(),
				p_grid, p_grid_end, p_res
			);
		}
		else {
			projection_impl(
				wlog_data->rbegin(), wlog_data->rend(),
				wlog_dept->rbegin(), wlog_dept->rend(),
				p_grid, p_grid_end, p_res
			);
		}
	}
	else {
		// reversed grid ordering
		cvf_riterator p_grid = dest_grid->rbegin();
		const cvf_riterator p_grid_end = dest_grid->rend();
		vf_riterator p_res = res->rbegin();

		// check depth ordering
		if(wlog_dept->ss(0) < wlog_dept->ss(wlog_dept->size() - 1)) {
			projection_impl(
				wlog_data->begin(), wlog_data->end(),
				wlog_dept->begin(), wlog_dept->end(),
				p_grid, p_grid_end, p_res
			);
		}
		else {
			projection_impl(
				wlog_data->rbegin(), wlog_data->rend(),
				wlog_dept->rbegin(), wlog_dept->rend(),
				p_grid, p_grid_end, p_res
			);
		}
		//projection_impl(wlog_data, wlog_dept, p_grid, p_grid_end, p_res);
	}
	return res;
}

} /* namespace blue_sky */

#endif /* end of include guard: WLOG_TOOLS_TMEEHO84 */

<commit_msg>wlog_tools: add proper BS_API_PLUGIN decorator to wlog_mean_projection()<commit_after>/// @file wlog_tools.cpp
/// @brief Well Logs manipulation algorithms
/// @author uentity
/// @version 1.0
/// @date 27.02.2014
/// @copyright This source code is released under the terms of
///            the BSD License. See LICENSE for more details.

#ifndef WLOG_TOOLS_TMEEHO84
#define WLOG_TOOLS_TMEEHO84

#include "bs_kernel.h"
#include "conf.h"
#include <limits>
// DEBUG
//#include <iostream>

namespace blue_sky {

// hidden implementation
namespace {

typedef v_float::iterator vf_iterator;
typedef v_float::const_iterator cvf_iterator;
typedef v_float::reverse_iterator vf_riterator;
typedef v_float::const_reverse_iterator cvf_riterator;

// depth and share same iterator type
template< class data_iterator, class grid_iterator, class res_iterator >
void projection_impl(
	//const spv_float& wlog_data, const spv_float& wlog_dept,
	const data_iterator& p_data_begin, const data_iterator& p_data_end,
	const data_iterator& p_dept_begin, const data_iterator& p_dept_end,
	grid_iterator& p_grid, const grid_iterator& p_grid_end,
	res_iterator& p_res
) {
	// setup iterators
	//const cvf_iterator p_dept_begin = wlog_dept->begin();
	//const cvf_iterator p_dept_end = p_dept_begin + wlog_sz;

	const ulong wlog_sz = std::min< ulong >(p_data_end - p_data_begin, p_dept_end - p_dept_begin);
	//const ulong wlog_sz = std::min(wlog_data->size(), wlog_dept->size());
	if(wlog_sz == 0)
		return;

	// find starting point on well log
	data_iterator p_dept = std::lower_bound(
		p_dept_begin, p_dept_end, *p_grid
	);
	if(p_dept == p_dept_end)
		// grid is fully outside of well log depths
		return;

	data_iterator p_data = p_data_begin + (p_dept - p_dept_begin);

	// DEBUG
	//std::cout << "++wlog_mean_projection:" << std::endl;
	//std::cout << "log_dept = [" << *p_dept << ", " << *(p_dept_end - 1) << "]" << std::endl;
	//std::cout << "grid = [" << *p_grid << ", " << *(p_grid_end - 1) << "]" << std::endl;
	// position dest grid to next boundary
	++p_grid;
	const res_iterator p_res_end = p_res + (p_grid_end - p_grid - 1);

	// main cycle
	t_float win_sum = 0;
	// win_sz counts only valid numbers that fits in window
	// raw_sz counts all values in window, including NaNs
	ulong win_sz = 0, raw_sz = 0;
	while(p_grid != p_grid_end) {
		// if we reached window boundary
		if(*p_dept > *p_grid) {
			if(win_sz)
				*p_res = win_sum / win_sz;
			else if(!raw_sz && (p_dept != p_dept_begin)) {
				// assign prev log value only if we had no NaNs in window
				*p_res = *(p_data - 1);
			}

			// next step on dest grid and resulting array
			if(++p_res == p_res_end)
				break;
			++p_grid;
			win_sum = 0;
			win_sz = 0;
			raw_sz = 0;
		}
		else {
			// we're inside window
			// check for NaN
			if(!(*p_data != *p_data)) {
				win_sum += *p_data;
				++win_sz;
			}
			// count all values in raw_sz
			++raw_sz;
			// next step in well log
			++p_data; ++p_dept;
			if(p_dept == p_dept_end) {
				if(win_sz)
					*p_res = win_sum / win_sz;
				break;
			}
		}
	}
}

} // eof hidden namespace

BS_API_PLUGIN spv_float wlog_mean_projection(
	spv_float wlog_data, spv_float wlog_dept, spv_float dest_grid
) {
	// sanity
	spv_float res = BS_KERNEL.create_object(v_float::bs_type());
	if(!wlog_data->size() || !wlog_dept->size() || dest_grid->size() < 2 || !res)
		return res;
	res->resize(dest_grid->size() - 1);
	// fill resulting array with NaN
	std::fill(res->begin(), res->end(), std::numeric_limits< double >::quiet_NaN());

	// check grid ordering
	if(dest_grid->ss(0) < dest_grid->ss(dest_grid->size() - 1)) {
		// normal ordering
		cvf_iterator p_grid = dest_grid->begin();
		const cvf_iterator p_grid_end = dest_grid->end();
		vf_iterator p_res = res->begin();

		// check depth ordering
		if(wlog_dept->ss(0) < wlog_dept->ss(wlog_dept->size() - 1)) {
			projection_impl(
				wlog_data->begin(), wlog_data->end(),
				wlog_dept->begin(), wlog_dept->end(),
				p_grid, p_grid_end, p_res
			);
		}
		else {
			projection_impl(
				wlog_data->rbegin(), wlog_data->rend(),
				wlog_dept->rbegin(), wlog_dept->rend(),
				p_grid, p_grid_end, p_res
			);
		}
	}
	else {
		// reversed grid ordering
		cvf_riterator p_grid = dest_grid->rbegin();
		const cvf_riterator p_grid_end = dest_grid->rend();
		vf_riterator p_res = res->rbegin();

		// check depth ordering
		if(wlog_dept->ss(0) < wlog_dept->ss(wlog_dept->size() - 1)) {
			projection_impl(
				wlog_data->begin(), wlog_data->end(),
				wlog_dept->begin(), wlog_dept->end(),
				p_grid, p_grid_end, p_res
			);
		}
		else {
			projection_impl(
				wlog_data->rbegin(), wlog_data->rend(),
				wlog_dept->rbegin(), wlog_dept->rend(),
				p_grid, p_grid_end, p_res
			);
		}
		//projection_impl(wlog_data, wlog_dept, p_grid, p_grid_end, p_res);
	}
	return res;
}

} /* namespace blue_sky */

#endif /* end of include guard: WLOG_TOOLS_TMEEHO84 */

<|endoftext|>


<commit_before>#include "clay.hpp"

//
// callableOverloads
//

const vector<OverloadPtr> &callableOverloads(ObjectPtr x)
{
    switch (x->objKind) {
    case TYPE : {
        Type *y = (Type *)x.ptr();
        return y->overloads;
    }
    case RECORD : {
        Record *y = (Record *)x.ptr();
        return y->overloads;
    }
    case PROCEDURE : {
        Procedure *y = (Procedure *)x.ptr();
        if (y->overloads.empty()) {
            ExprPtr target = new ObjectExpr(y);
            OverloadPtr z = new Overload(target, y->code, y->inlined);
            z->env = y->env;
            y->overloads.push_back(z);
        }
        return y->overloads;
    }
    case OVERLOADABLE : {
        Overloadable *y = (Overloadable *)x.ptr();
        return y->overloads;
    }
    default : {
        assert(false);
        const vector<OverloadPtr> *ptr = NULL;
        return *ptr;
    }
    }
}

//
// isStaticFlags
//

typedef pair<ObjectPtr, unsigned> FlagsMapKey;

struct FlagsMapEntry {
    bool initialized;
    vector<bool> isStaticFlags;
    FlagsMapEntry()
        : initialized(false) {}
};

static map<FlagsMapKey, FlagsMapEntry> flagsMap;

static FlagsMapEntry &lookupFlagsMapEntry(ObjectPtr callable, unsigned nArgs)
{
    return flagsMap[make_pair(callable, nArgs)];
}

static void initCallable(ObjectPtr x)
{
    switch (x->objKind) {
    case TYPE : {
        Type *y = (Type *)x.ptr();
        if (!y->overloadsInitialized)
            initTypeOverloads(y);
        break;
    }
    case RECORD : {
        Record *y = (Record *)x.ptr();
        if (!y->builtinOverloadInitialized)
            initBuiltinConstructor(y);
        break;
    }
    case PROCEDURE :
    case OVERLOADABLE :
        break;
    default :
        assert(false);
    }
}

static bool isStaticArg(FormalArgPtr farg) {
    switch (farg->objKind) {
    case VALUE_ARG : return false;
    case STATIC_ARG : return true;
    default : assert(false); return false;
    }
}

static void computeIsStaticFlags(ObjectPtr x,
                                 unsigned nArgs,
                                 vector<bool> &isStaticFlags)
{
    initCallable(x);
    const vector<OverloadPtr> &overloads = callableOverloads(x);
    for (unsigned i = 0; i < overloads.size(); ++i) {
        CodePtr y = overloads[i]->code;
        const vector<FormalArgPtr> &fargs = y->formalArgs;
        if (y->hasVarArgs && (fargs.size() <= nArgs)) {
            for (unsigned j = 0; j < fargs.size(); ++j)
                isStaticFlags.push_back(isStaticArg(fargs[j]));
            for (unsigned j = fargs.size(); j < nArgs; ++j)
                isStaticFlags.push_back(false);
            return;
        }
        else if (fargs.size() == nArgs) {
            for (unsigned j = 0; j < fargs.size(); ++j)
                isStaticFlags.push_back(isStaticArg(fargs[j]));
            return;
        }
    }
    error("incorrect no. of arguments");
}

const vector<bool> &lookupIsStaticFlags(ObjectPtr callable, unsigned nArgs)
{
    FlagsMapEntry &entry = lookupFlagsMapEntry(callable, nArgs);
    if (!entry.initialized) {
        computeIsStaticFlags(callable, nArgs, entry.isStaticFlags);
        entry.initialized = true;
    }
    return entry.isStaticFlags;
}

bool computeArgsKey(const vector<bool> &isStaticFlags,
                    const vector<ExprPtr> &args,
                    EnvPtr env,
                    vector<ObjectPtr> &argsKey,
                    vector<ValueTempness> &argsTempness,
                    vector<LocationPtr> &argLocations)
{
    for (unsigned i = 0; i < args.size(); ++i) {
        if (isStaticFlags[i]) {
            ObjectPtr v = evaluateStatic(args[i], env);
            argsKey.push_back(v);
        }
        else {
            PValuePtr pv = analyzeValue(args[i], env);
            if (!pv)
                return false;
            argsKey.push_back(pv->type.ptr());
            argsTempness.push_back(pv->isTemp ? RVALUE : LVALUE);
        }
        argLocations.push_back(args[i]->location);
    }
    return true;
}

//
// invoke tables
//

static bool invokeTablesInitialized = false;

static vector< vector<InvokeSetPtr> > invokeTable;

static vector< vector<StaticInvokeEntryPtr> > staticInvokeTable;

//
// initInvokeTable
//

static void initInvokeTables() {
    assert(!invokeTablesInitialized);
    invokeTable.resize(16384);
    staticInvokeTable.resize(8192);
    invokeTablesInitialized = true;
}

//
// lookupInvokeSet
//

InvokeSetPtr lookupInvokeSet(ObjectPtr callable,
                             const vector<bool> &isStaticFlags,
                             const vector<ObjectPtr> &argsKey)
{
    if (!invokeTablesInitialized)
        initInvokeTables();
    int h = objectHash(callable) + objectVectorHash(argsKey);
    h &= (invokeTable.size() - 1);
    vector<InvokeSetPtr> &bucket = invokeTable[h];
    for (unsigned i = 0; i < bucket.size(); ++i) {
        InvokeSetPtr invokeSet = bucket[i];
        if (objectEquals(invokeSet->callable, callable) &&
            objectVectorEquals(invokeSet->argsKey, argsKey))
        {
            return invokeSet;
        }
    }
    InvokeSetPtr invokeSet = new InvokeSet(callable, isStaticFlags, argsKey);
    bucket.push_back(invokeSet);
    return invokeSet;
}

StaticInvokeEntryPtr lookupStaticInvoke(ObjectPtr callable,
                                        const vector<ObjectPtr> &args)
{
    if (!invokeTablesInitialized)
        initInvokeTables();
    int h = objectHash(callable) + objectVectorHash(args);
    h &= (staticInvokeTable.size() - 1);
    vector<StaticInvokeEntryPtr> &bucket = staticInvokeTable[h];
    for (unsigned i = 0; i < bucket.size(); ++i) {
        StaticInvokeEntryPtr entry = bucket[i];
        if (objectEquals(entry->callable, callable) &&
            objectVectorEquals(entry->args, args))
        {
            return entry;
        }
    }
    StaticInvokeEntryPtr entry = new StaticInvokeEntry(callable, args);
    bucket.push_back(entry);
    return entry;
}
<commit_msg>minor improvement to error message.<commit_after>#include "clay.hpp"

//
// callableOverloads
//

const vector<OverloadPtr> &callableOverloads(ObjectPtr x)
{
    switch (x->objKind) {
    case TYPE : {
        Type *y = (Type *)x.ptr();
        return y->overloads;
    }
    case RECORD : {
        Record *y = (Record *)x.ptr();
        return y->overloads;
    }
    case PROCEDURE : {
        Procedure *y = (Procedure *)x.ptr();
        if (y->overloads.empty()) {
            ExprPtr target = new ObjectExpr(y);
            OverloadPtr z = new Overload(target, y->code, y->inlined);
            z->env = y->env;
            y->overloads.push_back(z);
        }
        return y->overloads;
    }
    case OVERLOADABLE : {
        Overloadable *y = (Overloadable *)x.ptr();
        return y->overloads;
    }
    default : {
        assert(false);
        const vector<OverloadPtr> *ptr = NULL;
        return *ptr;
    }
    }
}

//
// isStaticFlags
//

typedef pair<ObjectPtr, unsigned> FlagsMapKey;

struct FlagsMapEntry {
    bool initialized;
    vector<bool> isStaticFlags;
    FlagsMapEntry()
        : initialized(false) {}
};

static map<FlagsMapKey, FlagsMapEntry> flagsMap;

static FlagsMapEntry &lookupFlagsMapEntry(ObjectPtr callable, unsigned nArgs)
{
    return flagsMap[make_pair(callable, nArgs)];
}

static void initCallable(ObjectPtr x)
{
    switch (x->objKind) {
    case TYPE : {
        Type *y = (Type *)x.ptr();
        if (!y->overloadsInitialized)
            initTypeOverloads(y);
        break;
    }
    case RECORD : {
        Record *y = (Record *)x.ptr();
        if (!y->builtinOverloadInitialized)
            initBuiltinConstructor(y);
        break;
    }
    case PROCEDURE :
    case OVERLOADABLE :
        break;
    default :
        assert(false);
    }
}

static bool isStaticArg(FormalArgPtr farg) {
    switch (farg->objKind) {
    case VALUE_ARG : return false;
    case STATIC_ARG : return true;
    default : assert(false); return false;
    }
}

static void computeIsStaticFlags(ObjectPtr x,
                                 unsigned nArgs,
                                 vector<bool> &isStaticFlags)
{
    initCallable(x);
    const vector<OverloadPtr> &overloads = callableOverloads(x);
    for (unsigned i = 0; i < overloads.size(); ++i) {
        CodePtr y = overloads[i]->code;
        const vector<FormalArgPtr> &fargs = y->formalArgs;
        if (y->hasVarArgs && (fargs.size() <= nArgs)) {
            for (unsigned j = 0; j < fargs.size(); ++j)
                isStaticFlags.push_back(isStaticArg(fargs[j]));
            for (unsigned j = fargs.size(); j < nArgs; ++j)
                isStaticFlags.push_back(false);
            return;
        }
        else if (fargs.size() == nArgs) {
            for (unsigned j = 0; j < fargs.size(); ++j)
                isStaticFlags.push_back(isStaticArg(fargs[j]));
            return;
        }
    }
    error("no matching operation");
}

const vector<bool> &lookupIsStaticFlags(ObjectPtr callable, unsigned nArgs)
{
    FlagsMapEntry &entry = lookupFlagsMapEntry(callable, nArgs);
    if (!entry.initialized) {
        computeIsStaticFlags(callable, nArgs, entry.isStaticFlags);
        entry.initialized = true;
    }
    return entry.isStaticFlags;
}

bool computeArgsKey(const vector<bool> &isStaticFlags,
                    const vector<ExprPtr> &args,
                    EnvPtr env,
                    vector<ObjectPtr> &argsKey,
                    vector<ValueTempness> &argsTempness,
                    vector<LocationPtr> &argLocations)
{
    for (unsigned i = 0; i < args.size(); ++i) {
        if (isStaticFlags[i]) {
            ObjectPtr v = evaluateStatic(args[i], env);
            argsKey.push_back(v);
        }
        else {
            PValuePtr pv = analyzeValue(args[i], env);
            if (!pv)
                return false;
            argsKey.push_back(pv->type.ptr());
            argsTempness.push_back(pv->isTemp ? RVALUE : LVALUE);
        }
        argLocations.push_back(args[i]->location);
    }
    return true;
}

//
// invoke tables
//

static bool invokeTablesInitialized = false;

static vector< vector<InvokeSetPtr> > invokeTable;

static vector< vector<StaticInvokeEntryPtr> > staticInvokeTable;

//
// initInvokeTable
//

static void initInvokeTables() {
    assert(!invokeTablesInitialized);
    invokeTable.resize(16384);
    staticInvokeTable.resize(8192);
    invokeTablesInitialized = true;
}

//
// lookupInvokeSet
//

InvokeSetPtr lookupInvokeSet(ObjectPtr callable,
                             const vector<bool> &isStaticFlags,
                             const vector<ObjectPtr> &argsKey)
{
    if (!invokeTablesInitialized)
        initInvokeTables();
    int h = objectHash(callable) + objectVectorHash(argsKey);
    h &= (invokeTable.size() - 1);
    vector<InvokeSetPtr> &bucket = invokeTable[h];
    for (unsigned i = 0; i < bucket.size(); ++i) {
        InvokeSetPtr invokeSet = bucket[i];
        if (objectEquals(invokeSet->callable, callable) &&
            objectVectorEquals(invokeSet->argsKey, argsKey))
        {
            return invokeSet;
        }
    }
    InvokeSetPtr invokeSet = new InvokeSet(callable, isStaticFlags, argsKey);
    bucket.push_back(invokeSet);
    return invokeSet;
}

StaticInvokeEntryPtr lookupStaticInvoke(ObjectPtr callable,
                                        const vector<ObjectPtr> &args)
{
    if (!invokeTablesInitialized)
        initInvokeTables();
    int h = objectHash(callable) + objectVectorHash(args);
    h &= (staticInvokeTable.size() - 1);
    vector<StaticInvokeEntryPtr> &bucket = staticInvokeTable[h];
    for (unsigned i = 0; i < bucket.size(); ++i) {
        StaticInvokeEntryPtr entry = bucket[i];
        if (objectEquals(entry->callable, callable) &&
            objectVectorEquals(entry->args, args))
        {
            return entry;
        }
    }
    StaticInvokeEntryPtr entry = new StaticInvokeEntry(callable, args);
    bucket.push_back(entry);
    return entry;
}
<|endoftext|>