<commit_before>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2014 ETH Zurich
** 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 the ETH Zurich 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 HOLDER 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.
**
***********************************************************************************************************************/

#include "nodes/composite/CompositeNode.h"
#include "../../commands/CompositeNodeChangeChild.h"

namespace Model {

DEFINE_TYPE_ID_DERIVED(CompositeNode, "CompositeNode", )

REGISTER_ATTRIBUTE(CompositeNode, comment, Node, false, true, true)

int CompositeNode::nextExtensionId_ = 0;

void CompositeNode::initType()
{
	Node::registerNodeType("CompositeNode",
			[](Node* parent) -> Node* { return CompositeNode::createDefaultInstance(parent);},
			[](Node *parent, PersistentStore &store, bool partialLoadHint) -> Node*
			{ return new CompositeNode(parent, store, partialLoadHint);});

	for (int i = 0; i<attributesToRegisterAtInitialization_().size(); ++i)
		attributesToRegisterAtInitialization_().at(i).first =
				registerNewAttribute(attributesToRegisterAtInitialization_().at(i).second);
}

CompositeNode* CompositeNode::createDefaultInstance( Node* parent)
{
	return new CompositeNode(parent);
}

AttributeChain& CompositeNode::topLevelMeta()
{
	return meta_;
}

CompositeNode::CompositeNode(Node *parent) :
	Super(parent), meta_(CompositeNode::getMetaData())
{
	throw ModelException("Constructing an CompositeNode class directly, without specifying meta data");
}

CompositeNode::CompositeNode(Node *parent, PersistentStore &, bool) :
	Super(parent), meta_(CompositeNode::getMetaData())
{
	throw ModelException("Constructing an CompositeNode class directly, without specifying meta data");
}

CompositeNode::CompositeNode(const CompositeNode& other)
	: Super{other}, meta_{other.meta_}, subnodes_(meta_.numLevels())
{
	Q_ASSERT(subnodes_.size() == other.subnodes_.size());

	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);
		subnodes_[level] = QVector<Node*> (currentLevel->size(), nullptr);

		for (int i = 0; i < currentLevel->size(); ++i)
			if ( auto node = other.subnodes_[level][i] )
			{
				subnodes_[level][i] = node->clone();
				node->setParent(this);
			}
	}
}

CompositeNode* CompositeNode::clone() const { return new CompositeNode(*this); }

CompositeNode::CompositeNode(Node *parent, AttributeChain& metaData) :
	Super(parent), meta_(metaData), subnodes_(meta_.numLevels())
{
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);
		subnodes_[level] = QVector<Node*> (currentLevel->size(), nullptr);

		for (int i = 0; i < currentLevel->size(); ++i)
			if ( !(*currentLevel)[i].optional() )
				subnodes_[level][i] = Node::createNewNode((*currentLevel)[i].type(), this);
	}
}

CompositeNode::CompositeNode(Node *parent, PersistentStore &store, bool, AttributeChain& metaData) :
	Super(parent), meta_(metaData), subnodes_(meta_.numLevels())
{
	QSet<QString> partial;
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		subnodes_[level] = QVector<Node*> (meta_.level(level)->size(), nullptr);

		AttributeChain* currentLevel = meta_.level(level);
		for (int i = 0; i < currentLevel->size(); ++i)
			if ( (*currentLevel)[i].partial() ) partial.insert( (*currentLevel)[i].name() );
	}

	QList<LoadedNode> children = store.loadAllSubNodes(this, partial);

	for (QList<LoadedNode>::iterator ln = children.begin(); ln != children.end(); ln++)
	{
		CompositeIndex index = meta_.indexForAttribute(ln->name);
		if ( !index.isValid() ) throw ModelException("Node has attribute "
				+ ln->name + " in persistent store, but this attribute is not registered");

		auto attribute = meta_.attribute(index);
		Q_ASSERT(ln->node->isSubtypeOf(attribute.type()));

		// Skip loading partial optional children.
		if (!store.isLoadingPartially() || !attribute.optional() || !attribute.partial())
		{
			subnodes_[index.level()][index.index()] = ln->node;
			ln->node->setParent(this);
		}
	}

	verifyHasAllMandatoryAttributes();
}

CompositeNode::~CompositeNode()
{
	for (int level = 0; level < subnodes_.size(); ++level)
		for (int i = 0; i < subnodes_[level].size(); ++i)
			if ( subnodes_[level][i] ) SAFE_DELETE( subnodes_[level][i] );
}

AttributeChain& CompositeNode::getMetaData()
{
	static AttributeChain descriptions{"CompositeNode"};
	return descriptions;
}

CompositeIndex CompositeNode::registerNewAttribute(AttributeChain& metaData, const QString &attributeName,
		const QString &attributeType, bool canBePartiallyLoaded, bool isOptional, bool isPersistent)
{
	return registerNewAttribute(metaData, Attribute(attributeName, attributeType,
												isOptional, canBePartiallyLoaded, isPersistent));
}

CompositeIndex CompositeNode::registerNewAttribute(AttributeChain& metaData, const Attribute& attribute)
{
	if ( metaData.hasAttribute(attribute.name()) )
		throw ModelException("Trying to register new attribute " + attribute.name() + " but this name already exists");

	metaData.append(attribute);

	return CompositeIndex(metaData.numLevels() - 1, metaData.size() - 1);
}

CompositeIndex CompositeNode::registerNewAttribute(const Attribute& attribute)
{
	return registerNewAttribute(getMetaData(), attribute);
}

CompositeIndex CompositeNode::addAttributeToInitialRegistrationList_ (CompositeIndex& index,
	const QString &attributeName, const QString &attributeType, bool canBePartiallyLoaded, bool isOptional,
			 bool isPersistent)
{
	attributesToRegisterAtInitialization_().append(QPair< CompositeIndex&, Attribute>(index,
			Attribute(attributeName, attributeType, isOptional, canBePartiallyLoaded, isPersistent)));
	return CompositeIndex();
}

QList<QPair< CompositeIndex&, Attribute> >& CompositeNode::attributesToRegisterAtInitialization_()
{
	static QList<QPair< CompositeIndex&, Attribute> > a;
	return a;
}

void CompositeNode::set(const CompositeIndex &attributeIndex, Node* node)
{
	Q_ASSERT( attributeIndex.isValid() );
	Q_ASSERT( attributeIndex.level() < subnodes_.size());
	Q_ASSERT( attributeIndex.index() < subnodes_[attributeIndex.level()].size());
	auto attribute = meta_.attribute(attributeIndex);
	Q_ASSERT( node || attribute.optional());
	Q_ASSERT( !node || node->isSubtypeOf(attribute.type()));
	execute(new CompositeNodeChangeChild(this, node, attributeIndex, &subnodes_));
}

Node* CompositeNode::get(const QString &attributeName) const
{
	CompositeIndex index = meta_.indexForAttribute(attributeName);
	if ( index.isValid() ) return subnodes_[index.level()][index.index()];
	return nullptr;
}

CompositeIndex CompositeNode::indexOf(Node* node) const
{
	if (node)
	{
		for (int level = 0; level < subnodes_.size(); ++level)
			for (int i = 0; i < subnodes_[level].size(); ++i)
				if (subnodes_[level][i] == node)
					return CompositeIndex(level, i);
	}

	return CompositeIndex();
}

CompositeIndex CompositeNode::indexOf(const QString& nodeName) const
{
	return meta_.indexForAttribute(nodeName);
}

QList<Node*> CompositeNode::children() const
{
	QList<Node*> result;

	for (int level = 0; level < subnodes_.size(); ++level)
		for (int i = 0; i < subnodes_[level].size(); ++i)
			if (subnodes_[level][i]) result << subnodes_[level][i];

	return result;
}

bool CompositeNode::replaceChild(Node* child, Node* replacement)
{
	if (!child || !replacement) return false;

	CompositeIndex index = indexOf(child);
	Q_ASSERT(index.isValid());
	Q_ASSERT( !replacement || replacement->isSubtypeOf(meta_.attribute(index).type()));
	execute(new CompositeNodeChangeChild(this, replacement, index, &subnodes_));
	return true;
}

bool CompositeNode::hasAttribute(const QString& attributeName)
{
	return meta_.hasAttribute(attributeName);
}

QList< QPair<QString, Node*> > CompositeNode::getAllAttributes(bool includeNullValues)
{
	QList< QPair<QString, Node*> > result;

	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);

		for (int i = 0; i < currentLevel->size(); ++i)
			if ( subnodes_[level][i] || includeNullValues )
				result.append(QPair<QString, Node*>((*currentLevel)[i].name(), subnodes_[level][i]));
	}

	return result;
}

void CompositeNode::save(PersistentStore &store) const
{
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);
		for (int i = 0; i < currentLevel->size(); ++i)
			if ( subnodes_[level][i] != nullptr && currentLevel->at(i).persistent() )
				store.saveNode(subnodes_[level][i], currentLevel->at(i).name());
	}
}

void CompositeNode::load(PersistentStore &store)
{
	if (store.currentNodeType() != typeName())
		throw ModelException("Trying to load a CompositeNode from an incompatible node type "
				+ store.currentNodeType());

	removeAllNodes();

	QSet<QString> partial;
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);
		for (int i = 0; i < currentLevel->size(); ++i)
			if ( currentLevel->at(i).partial() )
				partial.insert(currentLevel->at(i).name());
	}

	QList<LoadedNode> children = store.loadAllSubNodes(this, partial);

	for (QList<LoadedNode>::iterator ln = children.begin(); ln != children.end(); ln++)
	{
		CompositeIndex index = meta_.indexForAttribute(ln->name);
		if ( !index.isValid() )
			throw ModelException("Node has attribute "
					+ ln->name + " in persistent store, but this attribute is not registered");

		auto attribute = meta_.attribute(index);
		Q_ASSERT(ln->node->isSubtypeOf(attribute.type()));

		// Skip loading partial optional children.
		if (!store.isLoadingPartially() || !attribute.optional() || !attribute.partial())
			execute(new CompositeNodeChangeChild(this, ln->node, CompositeIndex(index.level(), index.index()), &subnodes_));
	}

	verifyHasAllMandatoryAttributes();
}

void CompositeNode::removeAllNodes()
{
	for (int level = 0; level < subnodes_.size(); ++level)
		for (int i = 0; i < subnodes_[level].size(); ++i)
			if ( subnodes_[level][i] )
				execute(new CompositeNodeChangeChild(this, nullptr, CompositeIndex(level, i), &subnodes_));
}

void CompositeNode::verifyHasAllMandatoryAttributes()
{
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);

		for (int i = 0; i < currentLevel->size(); ++i)
			if ( subnodes_[level][i] == nullptr && (*currentLevel)[i].optional() == false )
				throw ModelException("An CompositeNode of type '" + meta_.typeName()
						+ "' has an uninitialized mandatory attribute '"
						+ (*currentLevel)[i].name() +"'");
	}
}

void CompositeNode::remove(const CompositeIndex &attributeIndex)
{
	Q_ASSERT(attributeIndex.isValid());

	if ( meta_.attribute(attributeIndex).optional() )
		execute(new CompositeNodeChangeChild(	this, nullptr, attributeIndex, &subnodes_));
	else
		execute(new CompositeNodeChangeChild(	this, Node::createNewNode(meta_.attribute(attributeIndex).type(), nullptr),
				attributeIndex, &subnodes_));
}

void CompositeNode::remove(Node* childNode)
{
	Q_ASSERT(childNode);
	remove(indexOf(childNode));
}

void CompositeNode::remove(QString childNodeName)
{
	remove(indexOf(childNodeName));
}

Node* CompositeNode::setDefault(QString nodeName)
{
	auto attributeIndex = indexOf(nodeName);

	auto newNode = Node::createNewNode(meta_.attribute(attributeIndex).type());
	set(attributeIndex, newNode);

	return newNode;
}

}
<commit_msg>Fix clone to correctly set the cloned node's parent<commit_after>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2014 ETH Zurich
** 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 the ETH Zurich 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 HOLDER 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.
**
***********************************************************************************************************************/

#include "nodes/composite/CompositeNode.h"
#include "../../commands/CompositeNodeChangeChild.h"

namespace Model {

DEFINE_TYPE_ID_DERIVED(CompositeNode, "CompositeNode", )

REGISTER_ATTRIBUTE(CompositeNode, comment, Node, false, true, true)

int CompositeNode::nextExtensionId_ = 0;

void CompositeNode::initType()
{
	Node::registerNodeType("CompositeNode",
			[](Node* parent) -> Node* { return CompositeNode::createDefaultInstance(parent);},
			[](Node *parent, PersistentStore &store, bool partialLoadHint) -> Node*
			{ return new CompositeNode(parent, store, partialLoadHint);});

	for (int i = 0; i<attributesToRegisterAtInitialization_().size(); ++i)
		attributesToRegisterAtInitialization_().at(i).first =
				registerNewAttribute(attributesToRegisterAtInitialization_().at(i).second);
}

CompositeNode* CompositeNode::createDefaultInstance( Node* parent)
{
	return new CompositeNode(parent);
}

AttributeChain& CompositeNode::topLevelMeta()
{
	return meta_;
}

CompositeNode::CompositeNode(Node *parent) :
	Super(parent), meta_(CompositeNode::getMetaData())
{
	throw ModelException("Constructing an CompositeNode class directly, without specifying meta data");
}

CompositeNode::CompositeNode(Node *parent, PersistentStore &, bool) :
	Super(parent), meta_(CompositeNode::getMetaData())
{
	throw ModelException("Constructing an CompositeNode class directly, without specifying meta data");
}

CompositeNode::CompositeNode(const CompositeNode& other)
	: Super{other}, meta_{other.meta_}, subnodes_(meta_.numLevels())
{
	Q_ASSERT(subnodes_.size() == other.subnodes_.size());

	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);
		subnodes_[level] = QVector<Node*> (currentLevel->size(), nullptr);

		for (int i = 0; i < currentLevel->size(); ++i)
			if ( auto node = other.subnodes_[level][i] )
			{
				auto cloned = node->clone();
				subnodes_[level][i] = cloned;
				cloned->setParent(this);
			}
	}
}

CompositeNode* CompositeNode::clone() const { return new CompositeNode(*this); }

CompositeNode::CompositeNode(Node *parent, AttributeChain& metaData) :
	Super(parent), meta_(metaData), subnodes_(meta_.numLevels())
{
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);
		subnodes_[level] = QVector<Node*> (currentLevel->size(), nullptr);

		for (int i = 0; i < currentLevel->size(); ++i)
			if ( !(*currentLevel)[i].optional() )
				subnodes_[level][i] = Node::createNewNode((*currentLevel)[i].type(), this);
	}
}

CompositeNode::CompositeNode(Node *parent, PersistentStore &store, bool, AttributeChain& metaData) :
	Super(parent), meta_(metaData), subnodes_(meta_.numLevels())
{
	QSet<QString> partial;
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		subnodes_[level] = QVector<Node*> (meta_.level(level)->size(), nullptr);

		AttributeChain* currentLevel = meta_.level(level);
		for (int i = 0; i < currentLevel->size(); ++i)
			if ( (*currentLevel)[i].partial() ) partial.insert( (*currentLevel)[i].name() );
	}

	QList<LoadedNode> children = store.loadAllSubNodes(this, partial);

	for (QList<LoadedNode>::iterator ln = children.begin(); ln != children.end(); ln++)
	{
		CompositeIndex index = meta_.indexForAttribute(ln->name);
		if ( !index.isValid() ) throw ModelException("Node has attribute "
				+ ln->name + " in persistent store, but this attribute is not registered");

		auto attribute = meta_.attribute(index);
		Q_ASSERT(ln->node->isSubtypeOf(attribute.type()));

		// Skip loading partial optional children.
		if (!store.isLoadingPartially() || !attribute.optional() || !attribute.partial())
		{
			subnodes_[index.level()][index.index()] = ln->node;
			ln->node->setParent(this);
		}
	}

	verifyHasAllMandatoryAttributes();
}

CompositeNode::~CompositeNode()
{
	for (int level = 0; level < subnodes_.size(); ++level)
		for (int i = 0; i < subnodes_[level].size(); ++i)
			if ( subnodes_[level][i] ) SAFE_DELETE( subnodes_[level][i] );
}

AttributeChain& CompositeNode::getMetaData()
{
	static AttributeChain descriptions{"CompositeNode"};
	return descriptions;
}

CompositeIndex CompositeNode::registerNewAttribute(AttributeChain& metaData, const QString &attributeName,
		const QString &attributeType, bool canBePartiallyLoaded, bool isOptional, bool isPersistent)
{
	return registerNewAttribute(metaData, Attribute(attributeName, attributeType,
												isOptional, canBePartiallyLoaded, isPersistent));
}

CompositeIndex CompositeNode::registerNewAttribute(AttributeChain& metaData, const Attribute& attribute)
{
	if ( metaData.hasAttribute(attribute.name()) )
		throw ModelException("Trying to register new attribute " + attribute.name() + " but this name already exists");

	metaData.append(attribute);

	return CompositeIndex(metaData.numLevels() - 1, metaData.size() - 1);
}

CompositeIndex CompositeNode::registerNewAttribute(const Attribute& attribute)
{
	return registerNewAttribute(getMetaData(), attribute);
}

CompositeIndex CompositeNode::addAttributeToInitialRegistrationList_ (CompositeIndex& index,
	const QString &attributeName, const QString &attributeType, bool canBePartiallyLoaded, bool isOptional,
			 bool isPersistent)
{
	attributesToRegisterAtInitialization_().append(QPair< CompositeIndex&, Attribute>(index,
			Attribute(attributeName, attributeType, isOptional, canBePartiallyLoaded, isPersistent)));
	return CompositeIndex();
}

QList<QPair< CompositeIndex&, Attribute> >& CompositeNode::attributesToRegisterAtInitialization_()
{
	static QList<QPair< CompositeIndex&, Attribute> > a;
	return a;
}

void CompositeNode::set(const CompositeIndex &attributeIndex, Node* node)
{
	Q_ASSERT( attributeIndex.isValid() );
	Q_ASSERT( attributeIndex.level() < subnodes_.size());
	Q_ASSERT( attributeIndex.index() < subnodes_[attributeIndex.level()].size());
	auto attribute = meta_.attribute(attributeIndex);
	Q_ASSERT( node || attribute.optional());
	Q_ASSERT( !node || node->isSubtypeOf(attribute.type()));
	execute(new CompositeNodeChangeChild(this, node, attributeIndex, &subnodes_));
}

Node* CompositeNode::get(const QString &attributeName) const
{
	CompositeIndex index = meta_.indexForAttribute(attributeName);
	if ( index.isValid() ) return subnodes_[index.level()][index.index()];
	return nullptr;
}

CompositeIndex CompositeNode::indexOf(Node* node) const
{
	if (node)
	{
		for (int level = 0; level < subnodes_.size(); ++level)
			for (int i = 0; i < subnodes_[level].size(); ++i)
				if (subnodes_[level][i] == node)
					return CompositeIndex(level, i);
	}

	return CompositeIndex();
}

CompositeIndex CompositeNode::indexOf(const QString& nodeName) const
{
	return meta_.indexForAttribute(nodeName);
}

QList<Node*> CompositeNode::children() const
{
	QList<Node*> result;

	for (int level = 0; level < subnodes_.size(); ++level)
		for (int i = 0; i < subnodes_[level].size(); ++i)
			if (subnodes_[level][i]) result << subnodes_[level][i];

	return result;
}

bool CompositeNode::replaceChild(Node* child, Node* replacement)
{
	if (!child || !replacement) return false;

	CompositeIndex index = indexOf(child);
	Q_ASSERT(index.isValid());
	Q_ASSERT( !replacement || replacement->isSubtypeOf(meta_.attribute(index).type()));
	execute(new CompositeNodeChangeChild(this, replacement, index, &subnodes_));
	return true;
}

bool CompositeNode::hasAttribute(const QString& attributeName)
{
	return meta_.hasAttribute(attributeName);
}

QList< QPair<QString, Node*> > CompositeNode::getAllAttributes(bool includeNullValues)
{
	QList< QPair<QString, Node*> > result;

	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);

		for (int i = 0; i < currentLevel->size(); ++i)
			if ( subnodes_[level][i] || includeNullValues )
				result.append(QPair<QString, Node*>((*currentLevel)[i].name(), subnodes_[level][i]));
	}

	return result;
}

void CompositeNode::save(PersistentStore &store) const
{
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);
		for (int i = 0; i < currentLevel->size(); ++i)
			if ( subnodes_[level][i] != nullptr && currentLevel->at(i).persistent() )
				store.saveNode(subnodes_[level][i], currentLevel->at(i).name());
	}
}

void CompositeNode::load(PersistentStore &store)
{
	if (store.currentNodeType() != typeName())
		throw ModelException("Trying to load a CompositeNode from an incompatible node type "
				+ store.currentNodeType());

	removeAllNodes();

	QSet<QString> partial;
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);
		for (int i = 0; i < currentLevel->size(); ++i)
			if ( currentLevel->at(i).partial() )
				partial.insert(currentLevel->at(i).name());
	}

	QList<LoadedNode> children = store.loadAllSubNodes(this, partial);

	for (QList<LoadedNode>::iterator ln = children.begin(); ln != children.end(); ln++)
	{
		CompositeIndex index = meta_.indexForAttribute(ln->name);
		if ( !index.isValid() )
			throw ModelException("Node has attribute "
					+ ln->name + " in persistent store, but this attribute is not registered");

		auto attribute = meta_.attribute(index);
		Q_ASSERT(ln->node->isSubtypeOf(attribute.type()));

		// Skip loading partial optional children.
		if (!store.isLoadingPartially() || !attribute.optional() || !attribute.partial())
			execute(new CompositeNodeChangeChild(this, ln->node, CompositeIndex(index.level(), index.index()), &subnodes_));
	}

	verifyHasAllMandatoryAttributes();
}

void CompositeNode::removeAllNodes()
{
	for (int level = 0; level < subnodes_.size(); ++level)
		for (int i = 0; i < subnodes_[level].size(); ++i)
			if ( subnodes_[level][i] )
				execute(new CompositeNodeChangeChild(this, nullptr, CompositeIndex(level, i), &subnodes_));
}

void CompositeNode::verifyHasAllMandatoryAttributes()
{
	for (int level = 0; level < meta_.numLevels(); ++level)
	{
		AttributeChain* currentLevel = meta_.level(level);

		for (int i = 0; i < currentLevel->size(); ++i)
			if ( subnodes_[level][i] == nullptr && (*currentLevel)[i].optional() == false )
				throw ModelException("An CompositeNode of type '" + meta_.typeName()
						+ "' has an uninitialized mandatory attribute '"
						+ (*currentLevel)[i].name() +"'");
	}
}

void CompositeNode::remove(const CompositeIndex &attributeIndex)
{
	Q_ASSERT(attributeIndex.isValid());

	if ( meta_.attribute(attributeIndex).optional() )
		execute(new CompositeNodeChangeChild(	this, nullptr, attributeIndex, &subnodes_));
	else
		execute(new CompositeNodeChangeChild(	this, Node::createNewNode(meta_.attribute(attributeIndex).type(), nullptr),
				attributeIndex, &subnodes_));
}

void CompositeNode::remove(Node* childNode)
{
	Q_ASSERT(childNode);
	remove(indexOf(childNode));
}

void CompositeNode::remove(QString childNodeName)
{
	remove(indexOf(childNodeName));
}

Node* CompositeNode::setDefault(QString nodeName)
{
	auto attributeIndex = indexOf(nodeName);

	auto newNode = Node::createNewNode(meta_.attribute(attributeIndex).type());
	set(attributeIndex, newNode);

	return newNode;
}

}
<|endoftext|>


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

#include "itkTBBMultiThreader.h"
#include "itkNumericTraits.h"
#include "itkProcessObject.h"
#include <iostream>
#include <atomic>
#include <thread>
#include "tbb/parallel_for.h"

namespace itk
{

TBBMultiThreader::TBBMultiThreader()
{
  m_SingleMethod = nullptr;
  m_SingleData = nullptr;

  m_NumberOfThreads = std::max(1u, GetGlobalDefaultNumberOfThreads());
}

TBBMultiThreader::~TBBMultiThreader()
{
}

void TBBMultiThreader::SetSingleMethod(ThreadFunctionType f, void *data)
{
  m_SingleMethod = f;
  m_SingleData   = data;
}

void TBBMultiThreader::SingleMethodExecute()
{
  if( !m_SingleMethod )
    {
    itkExceptionMacro(<< "No single method set!");
    }

  //we request grain size of 1 and simple_partitioner to ensure there is no chunking
  tbb::parallel_for(tbb::blocked_range<int>(0, m_NumberOfThreads, 1), [&](tbb::blocked_range<int>r)
    {
    // Make sure that TBB did not call us with a block of "threads"
    // but rather with only one "thread" to handle
    itkAssertInDebugAndIgnoreInReleaseMacro(r.begin() + 1 == r.end());

    ThreadInfoStruct ti;
    ti.ThreadID = r.begin();
    ti.UserData = m_SingleData;
    ti.NumberOfThreads = m_NumberOfThreads;
    m_SingleMethod(&ti); //TBB takes care of properly propagating exceptions
    },
      tbb::simple_partitioner());
}

void TBBMultiThreader::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

void
TBBMultiThreader
::ParallelizeArray(
  SizeValueType firstIndex,
  SizeValueType lastIndexPlus1,
  ArrayThreadingFunctorType aFunc,
  ProcessObject* filter )
{
  if (filter)
    {
    filter->UpdateProgress(0.0f);
    }

  if ( firstIndex + 1 < lastIndexPlus1 )
    {
    unsigned count = lastIndexPlus1 - firstIndex;
    std::atomic< SizeValueType > progress = 0;
    std::thread::id callingThread = std::this_thread::get_id();
    //we request grain size of 1 and simple_partitioner to ensure there is no chunking
    tbb::parallel_for(
        tbb::blocked_range<SizeValueType>(firstIndex, lastIndexPlus1, 1),
        [&](tbb::blocked_range<SizeValueType>r)
        {
        // Make sure that TBB did not call us with a block of "threads"
        // but rather with only one "thread" to handle
        itkAssertInDebugAndIgnoreInReleaseMacro(r.begin() + 1 == r.end());
        if ( filter && filter->GetAbortGenerateData() )
          {
          std::string msg;
          ProcessAborted e( __FILE__, __LINE__ );
          msg += "AbortGenerateData was called in " + std::string( filter->GetNameOfClass() )
              + " during multi-threaded part of filter execution";
          e.SetDescription(msg);
          throw e;
          }

        aFunc( r.begin() ); //invoke the function

        if ( filter )
          {
          ++progress;
          //make sure we are updating progress only from the thead which invoked us
          if ( callingThread == std::this_thread::get_id() )
            {
            filter->UpdateProgress( float( progress ) / count );
            }
          }
        },
        tbb::simple_partitioner());
    }
  else if ( firstIndex + 1 == lastIndexPlus1 )
    {
    aFunc( firstIndex );
    }
  // else nothing needs to be executed

  if (filter)
    {
    filter->UpdateProgress(1.0f);
    if (filter->GetAbortGenerateData())
      {
      std::string msg;
      ProcessAborted e(__FILE__, __LINE__);
      msg += "AbortGenerateData was called in " + std::string(filter->GetNameOfClass() )
          + " during multi-threaded part of filter execution";
      e.SetDescription(msg);
      throw e;
      }
    }
}

}

namespace
{
struct TBBImageRegionSplitter : public itk::ImageIORegion
{
  static const bool is_splittable_in_proportion = true;
  TBBImageRegionSplitter(const TBBImageRegionSplitter&) = default;
  TBBImageRegionSplitter(const itk::ImageIORegion& region)
      :itk::ImageIORegion(region) //use itk::ImageIORegion's copy constructor
  {}
  TBBImageRegionSplitter(TBBImageRegionSplitter& region, tbb::split)
      :TBBImageRegionSplitter(region, tbb::proportional_split(1, 1)) //delegate to proportional split
  {}

  TBBImageRegionSplitter(TBBImageRegionSplitter& region, tbb::proportional_split p)
  {
    *this = region; //most things will be the same
    for (int d = int(this->GetImageDimension()) - 1; d >= 0; d--) //prefer to split along highest dimension
      {
      if (this->GetSize(d) > 1) //split along this dimension
        {
        size_t myP = (this->GetSize(d) * p.right()) / (p.left() + p.right());
        if (myP == 0)
          {
          ++myP;
          }
        else if (myP == this->GetSize(d))
          {
          --myP;
          }
        this->SetSize(d, myP);
        region.SetSize(d, region.GetSize(d) - myP);
        region.SetIndex(d, myP + region.GetIndex(d));
        return;
        }
      }
    itkGenericExceptionMacro("An ImageIORegion could not be split. Region: " << region);
  }

  bool empty() const
  {
    for (unsigned d = 0; d < this->GetImageDimension(); d++)
      {
      if (this->GetSize(d) == 0)
        {
        return true;
        }
      }
    return false;
  }

  bool is_divisible() const
  {
    for (unsigned d = 0; d < this->GetImageDimension(); d++)
      {
      if (this->GetSize(d) > 1)
        {
        return true;
        }
      }
    return false;
  }

};//TBBImageRegionSplitter struct definition
}//anonymous namespace

namespace itk
{
void TBBMultiThreader
::ParallelizeImageRegion(
    unsigned int dimension,
    const IndexValueType index[],
    const SizeValueType size[],
    ThreadingFunctorType funcP,
    ProcessObject* filter)
{
  if (filter)
    {
    filter->UpdateProgress(0.0f);
    }

  if (m_NumberOfThreads == 1) //no multi-threading wanted
    {
    funcP(index, size);
    }
  else //normal multi-threading
    {
    ImageIORegion region(dimension);
    for (unsigned d = 0; d < dimension; d++)
      {
      region.SetIndex(d, index[d]);
      region.SetSize(d, size[d]);
      }
    TBBImageRegionSplitter regionSplitter = region; //use copy constructor

    std::atomic<SizeValueType> pixelProgress = { 0 };
    SizeValueType totalCount = region.GetNumberOfPixels();
    std::thread::id callingThread = std::this_thread::get_id();

    tbb::parallel_for(regionSplitter, [&](TBBImageRegionSplitter regionToProcess)
      {
      if (filter && filter->GetAbortGenerateData())
        {
        std::string msg;
        ProcessAborted e(__FILE__, __LINE__);
        msg += "AbortGenerateData was called in " + std::string(filter->GetNameOfClass() )
            + " during multi-threaded part of filter execution";
        e.SetDescription(msg);
        throw e;
        }
      funcP(&regionToProcess.GetIndex()[0], &regionToProcess.GetSize()[0]);
      if (filter) //filter is provided, update progress
        {
        SizeValueType pixelCount = regionToProcess.GetNumberOfPixels();
        pixelProgress += pixelCount;
        //make sure we are updating progress only from the thead which invoked filter->Update();
        if (callingThread == std::this_thread::get_id())
          {
          filter->UpdateProgress(float(pixelProgress) / totalCount);
          }
        }
      }); //we implicitly use auto_partitioner for load balancing
    }

  if (filter)
    {
    filter->UpdateProgress(1.0f);
    if (filter->GetAbortGenerateData())
      {
      std::string msg;
      ProcessAborted e(__FILE__, __LINE__);
      msg += "AbortGenerateData was called in " + std::string(filter->GetNameOfClass() )
          + " during multi-threaded part of filter execution";
      e.SetDescription(msg);
      throw e;
      }
    }
}
}
<commit_msg>COMP: Address usage of deleted assignment operator<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "itkTBBMultiThreader.h"
#include "itkNumericTraits.h"
#include "itkProcessObject.h"
#include <iostream>
#include <atomic>
#include <thread>
#include "tbb/parallel_for.h"

namespace itk
{

TBBMultiThreader::TBBMultiThreader()
{
  m_SingleMethod = nullptr;
  m_SingleData = nullptr;

  m_NumberOfThreads = std::max(1u, GetGlobalDefaultNumberOfThreads());
}

TBBMultiThreader::~TBBMultiThreader()
{
}

void TBBMultiThreader::SetSingleMethod(ThreadFunctionType f, void *data)
{
  m_SingleMethod = f;
  m_SingleData   = data;
}

void TBBMultiThreader::SingleMethodExecute()
{
  if( !m_SingleMethod )
    {
    itkExceptionMacro(<< "No single method set!");
    }

  //we request grain size of 1 and simple_partitioner to ensure there is no chunking
  tbb::parallel_for(tbb::blocked_range<int>(0, m_NumberOfThreads, 1), [&](tbb::blocked_range<int>r)
    {
    // Make sure that TBB did not call us with a block of "threads"
    // but rather with only one "thread" to handle
    itkAssertInDebugAndIgnoreInReleaseMacro(r.begin() + 1 == r.end());

    ThreadInfoStruct ti;
    ti.ThreadID = r.begin();
    ti.UserData = m_SingleData;
    ti.NumberOfThreads = m_NumberOfThreads;
    m_SingleMethod(&ti); //TBB takes care of properly propagating exceptions
    },
      tbb::simple_partitioner());
}

void TBBMultiThreader::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

void
TBBMultiThreader
::ParallelizeArray(
  SizeValueType firstIndex,
  SizeValueType lastIndexPlus1,
  ArrayThreadingFunctorType aFunc,
  ProcessObject* filter )
{
  if (filter)
    {
    filter->UpdateProgress(0.0f);
    }

  if ( firstIndex + 1 < lastIndexPlus1 )
    {
    unsigned count = lastIndexPlus1 - firstIndex;
    std::atomic< SizeValueType > progress( 0 );
    std::thread::id callingThread = std::this_thread::get_id();
    //we request grain size of 1 and simple_partitioner to ensure there is no chunking
    tbb::parallel_for(
        tbb::blocked_range<SizeValueType>(firstIndex, lastIndexPlus1, 1),
        [&](tbb::blocked_range<SizeValueType>r)
        {
        // Make sure that TBB did not call us with a block of "threads"
        // but rather with only one "thread" to handle
        itkAssertInDebugAndIgnoreInReleaseMacro(r.begin() + 1 == r.end());
        if ( filter && filter->GetAbortGenerateData() )
          {
          std::string msg;
          ProcessAborted e( __FILE__, __LINE__ );
          msg += "AbortGenerateData was called in " + std::string( filter->GetNameOfClass() )
              + " during multi-threaded part of filter execution";
          e.SetDescription(msg);
          throw e;
          }

        aFunc( r.begin() ); //invoke the function

        if ( filter )
          {
          ++progress;
          //make sure we are updating progress only from the thead which invoked us
          if ( callingThread == std::this_thread::get_id() )
            {
            filter->UpdateProgress( float( progress ) / count );
            }
          }
        },
        tbb::simple_partitioner());
    }
  else if ( firstIndex + 1 == lastIndexPlus1 )
    {
    aFunc( firstIndex );
    }
  // else nothing needs to be executed

  if (filter)
    {
    filter->UpdateProgress(1.0f);
    if (filter->GetAbortGenerateData())
      {
      std::string msg;
      ProcessAborted e(__FILE__, __LINE__);
      msg += "AbortGenerateData was called in " + std::string(filter->GetNameOfClass() )
          + " during multi-threaded part of filter execution";
      e.SetDescription(msg);
      throw e;
      }
    }
}

}

namespace
{
struct TBBImageRegionSplitter : public itk::ImageIORegion
{
  static const bool is_splittable_in_proportion = true;
  TBBImageRegionSplitter(const TBBImageRegionSplitter&) = default;
  TBBImageRegionSplitter(const itk::ImageIORegion& region)
      :itk::ImageIORegion(region) //use itk::ImageIORegion's copy constructor
  {}
  TBBImageRegionSplitter(TBBImageRegionSplitter& region, tbb::split)
      :TBBImageRegionSplitter(region, tbb::proportional_split(1, 1)) //delegate to proportional split
  {}

  TBBImageRegionSplitter(TBBImageRegionSplitter& region, tbb::proportional_split p)
  {
    *this = region; //most things will be the same
    for (int d = int(this->GetImageDimension()) - 1; d >= 0; d--) //prefer to split along highest dimension
      {
      if (this->GetSize(d) > 1) //split along this dimension
        {
        size_t myP = (this->GetSize(d) * p.right()) / (p.left() + p.right());
        if (myP == 0)
          {
          ++myP;
          }
        else if (myP == this->GetSize(d))
          {
          --myP;
          }
        this->SetSize(d, myP);
        region.SetSize(d, region.GetSize(d) - myP);
        region.SetIndex(d, myP + region.GetIndex(d));
        return;
        }
      }
    itkGenericExceptionMacro("An ImageIORegion could not be split. Region: " << region);
  }

  bool empty() const
  {
    for (unsigned d = 0; d < this->GetImageDimension(); d++)
      {
      if (this->GetSize(d) == 0)
        {
        return true;
        }
      }
    return false;
  }

  bool is_divisible() const
  {
    for (unsigned d = 0; d < this->GetImageDimension(); d++)
      {
      if (this->GetSize(d) > 1)
        {
        return true;
        }
      }
    return false;
  }

};//TBBImageRegionSplitter struct definition
}//anonymous namespace

namespace itk
{
void TBBMultiThreader
::ParallelizeImageRegion(
    unsigned int dimension,
    const IndexValueType index[],
    const SizeValueType size[],
    ThreadingFunctorType funcP,
    ProcessObject* filter)
{
  if (filter)
    {
    filter->UpdateProgress(0.0f);
    }

  if (m_NumberOfThreads == 1) //no multi-threading wanted
    {
    funcP(index, size);
    }
  else //normal multi-threading
    {
    ImageIORegion region(dimension);
    for (unsigned d = 0; d < dimension; d++)
      {
      region.SetIndex(d, index[d]);
      region.SetSize(d, size[d]);
      }
    TBBImageRegionSplitter regionSplitter = region; //use copy constructor

    std::atomic<SizeValueType> pixelProgress = { 0 };
    SizeValueType totalCount = region.GetNumberOfPixels();
    std::thread::id callingThread = std::this_thread::get_id();

    tbb::parallel_for(regionSplitter, [&](TBBImageRegionSplitter regionToProcess)
      {
      if (filter && filter->GetAbortGenerateData())
        {
        std::string msg;
        ProcessAborted e(__FILE__, __LINE__);
        msg += "AbortGenerateData was called in " + std::string(filter->GetNameOfClass() )
            + " during multi-threaded part of filter execution";
        e.SetDescription(msg);
        throw e;
        }
      funcP(&regionToProcess.GetIndex()[0], &regionToProcess.GetSize()[0]);
      if (filter) //filter is provided, update progress
        {
        SizeValueType pixelCount = regionToProcess.GetNumberOfPixels();
        pixelProgress += pixelCount;
        //make sure we are updating progress only from the thead which invoked filter->Update();
        if (callingThread == std::this_thread::get_id())
          {
          filter->UpdateProgress(float(pixelProgress) / totalCount);
          }
        }
      }); //we implicitly use auto_partitioner for load balancing
    }

  if (filter)
    {
    filter->UpdateProgress(1.0f);
    if (filter->GetAbortGenerateData())
      {
      std::string msg;
      ProcessAborted e(__FILE__, __LINE__);
      msg += "AbortGenerateData was called in " + std::string(filter->GetNameOfClass() )
          + " during multi-threaded part of filter execution";
      e.SetDescription(msg);
      throw e;
      }
    }
}
}
<|endoftext|>


<commit_before><commit_msg>Remove unused function<commit_after><|endoftext|>


<commit_before>//----------------------------  non_primitive_1.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2002 by the deal.II authors and Anna Schneebeli
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  non_primitive_1.cc  ---------------------------

// check some things about Nedelec elements, basically also that the
// DoFRenumbering::component_wise function also works for
// non_primitive elements, for which it did not work previously since
// there is no component to associate a non-primitive shape function
// with
//
// this program is similar to anna_1, except that it tests the
// component_wise function with a different order of components than
// the default is.
//
// this program is a modified version of one by Anna Schneebeli,
// University of Basel

#include <base/logstream.h>
#include <grid/tria.h>
#include <dofs/dof_handler.h>
#include <grid/grid_generator.h>
#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_accessor.h>
#include <dofs/dof_tools.h>
#include <fe/fe_system.h>
#include <fe/fe_q.h>
#include <fe/fe_nedelec.h>
#include <fe/fe_base.h>
#include <numerics/dof_renumbering.h>
#include <iostream>
#include <fstream>

template <int dim>
class SystemTest
{
  public:
    SystemTest ();
    void run ();

  private:
    void make_grid_and_dofs ();
    void shape_to_components ();
    void check_numbering ();

    Triangulation<dim>     triangulation;
    FESystem<dim>          fe;
    DoFHandler<dim>        dof_handler;

};

template <int dim>
SystemTest<dim>::SystemTest () :
                fe (FE_Nedelec<dim>(1), 2,
                    FE_Q<dim>(1), 1),
		dof_handler (triangulation)
{};

template <int dim>
void SystemTest<dim>::make_grid_and_dofs ()
{

  GridGenerator::hyper_cube (triangulation, -1, 1);
  triangulation.refine_global (0);
  deallog << "Number of active cells: " << triangulation.n_active_cells()
          << std::endl;
  deallog << "Total number of cells: " << triangulation.n_cells()
          << std::endl;

  dof_handler.distribute_dofs (fe);
  deallog << "Number of degrees of freedom: " << dof_handler.n_dofs()
          << std::endl;

};

template <int dim>
void SystemTest<dim>::shape_to_components ()
{
                                   // testing, if the shape function
                                   // with index i is of type Nedelec:
                                   // (i.e. the first component of the FESystem)
                                   // 1 for yes, 0 for no.

  for(unsigned int i = 0; i<fe.dofs_per_cell; i++)
    deallog <<"  shapefunction "<< i << " is Nedelec:  "
            << (fe.is_primitive(i) ? "false" : "true") << std::endl;
};

template <int dim>
void SystemTest<dim>::check_numbering ()
{
  DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
                                      endc = dof_handler.end();
  std::vector<unsigned int>	local_dof_indices(fe.dofs_per_cell);

  for (; cell!=endc; ++cell)
    {
      cell->get_dof_indices (local_dof_indices);
      for (unsigned int i=0; i<fe.dofs_per_cell; i++)
        deallog <<"  DoF "<< local_dof_indices[i] << " belongs to base element "
                << fe.system_to_base_index(i).first.first
                << ", instance " << fe.system_to_base_index(i).first.second
                << std::endl;
      deallog<< std::endl;
    };

                                   //Now: Componentwise reodering of the dofs

  deallog << "  Now we renumber the DoFs anti-component-wise:" << std::endl;
  deallog << "  *********************************************" << std::endl;
  std::vector<unsigned int> comp(fe.n_components());
  for (unsigned int i=0; i<comp.size(); ++i)
    comp[i] = comp.size()-i-1;
  DoFRenumbering::component_wise (dof_handler, comp);

  cell = dof_handler.begin_active();
  endc = dof_handler.end();

  for (; cell!=endc; ++cell)
    {
      cell->get_dof_indices (local_dof_indices);
      for(unsigned int i=0; i<fe.dofs_per_cell; i++)
        deallog <<"  DoF "<< local_dof_indices[i] << " belongs to base "
                << fe.system_to_base_index(i).first.first
                << ", instance " << fe.system_to_base_index(i).first.second
                << std::endl;
      deallog << std::endl;
    };

};

template <int dim>
void SystemTest<dim>::run ()
{
  make_grid_and_dofs ();
  shape_to_components ();
  check_numbering();
};

int main ()
{
  std::ofstream logfile("anna_2.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  SystemTest<2>().run();
  SystemTest<3>().run();
  return 0;
};
<commit_msg>Fix name of program.<commit_after>//----------------------------  anna_2.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2002 by the deal.II authors and Anna Schneebeli
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  anna_2.cc  ---------------------------

// check some things about Nedelec elements, basically also that the
// DoFRenumbering::component_wise function also works for
// non_primitive elements, for which it did not work previously since
// there is no component to associate a non-primitive shape function
// with
//
// this program is similar to anna_1, except that it tests the
// component_wise function with a different order of components than
// the default is.
//
// this program is a modified version of one by Anna Schneebeli,
// University of Basel

#include <base/logstream.h>
#include <grid/tria.h>
#include <dofs/dof_handler.h>
#include <grid/grid_generator.h>
#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_accessor.h>
#include <dofs/dof_tools.h>
#include <fe/fe_system.h>
#include <fe/fe_q.h>
#include <fe/fe_nedelec.h>
#include <fe/fe_base.h>
#include <numerics/dof_renumbering.h>
#include <iostream>
#include <fstream>

template <int dim>
class SystemTest
{
  public:
    SystemTest ();
    void run ();

  private:
    void make_grid_and_dofs ();
    void shape_to_components ();
    void check_numbering ();

    Triangulation<dim>     triangulation;
    FESystem<dim>          fe;
    DoFHandler<dim>        dof_handler;

};

template <int dim>
SystemTest<dim>::SystemTest () :
                fe (FE_Nedelec<dim>(1), 2,
                    FE_Q<dim>(1), 1),
		dof_handler (triangulation)
{};

template <int dim>
void SystemTest<dim>::make_grid_and_dofs ()
{

  GridGenerator::hyper_cube (triangulation, -1, 1);
  triangulation.refine_global (0);
  deallog << "Number of active cells: " << triangulation.n_active_cells()
          << std::endl;
  deallog << "Total number of cells: " << triangulation.n_cells()
          << std::endl;

  dof_handler.distribute_dofs (fe);
  deallog << "Number of degrees of freedom: " << dof_handler.n_dofs()
          << std::endl;

};

template <int dim>
void SystemTest<dim>::shape_to_components ()
{
                                   // testing, if the shape function
                                   // with index i is of type Nedelec:
                                   // (i.e. the first component of the FESystem)
                                   // 1 for yes, 0 for no.

  for(unsigned int i = 0; i<fe.dofs_per_cell; i++)
    deallog <<"  shapefunction "<< i << " is Nedelec:  "
            << (fe.is_primitive(i) ? "false" : "true") << std::endl;
};

template <int dim>
void SystemTest<dim>::check_numbering ()
{
  DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
                                      endc = dof_handler.end();
  std::vector<unsigned int>	local_dof_indices(fe.dofs_per_cell);

  for (; cell!=endc; ++cell)
    {
      cell->get_dof_indices (local_dof_indices);
      for (unsigned int i=0; i<fe.dofs_per_cell; i++)
        deallog <<"  DoF "<< local_dof_indices[i] << " belongs to base element "
                << fe.system_to_base_index(i).first.first
                << ", instance " << fe.system_to_base_index(i).first.second
                << std::endl;
      deallog<< std::endl;
    };

                                   //Now: Componentwise reodering of the dofs

  deallog << "  Now we renumber the DoFs anti-component-wise:" << std::endl;
  deallog << "  *********************************************" << std::endl;
  std::vector<unsigned int> comp(fe.n_components());
  for (unsigned int i=0; i<comp.size(); ++i)
    comp[i] = comp.size()-i-1;
  DoFRenumbering::component_wise (dof_handler, comp);

  cell = dof_handler.begin_active();
  endc = dof_handler.end();

  for (; cell!=endc; ++cell)
    {
      cell->get_dof_indices (local_dof_indices);
      for(unsigned int i=0; i<fe.dofs_per_cell; i++)
        deallog <<"  DoF "<< local_dof_indices[i] << " belongs to base "
                << fe.system_to_base_index(i).first.first
                << ", instance " << fe.system_to_base_index(i).first.second
                << std::endl;
      deallog << std::endl;
    };

};

template <int dim>
void SystemTest<dim>::run ()
{
  make_grid_and_dofs ();
  shape_to_components ();
  check_numbering();
};

int main ()
{
  std::ofstream logfile("anna_2.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  SystemTest<2>().run();
  SystemTest<3>().run();
  return 0;
};
<|endoftext|>


<commit_before>#include "../Carlos/architecture/DllExports.h"
#include "class.MyServerSocket.hpp"
#include "split.h"
#include "../Carlos/architecture/modules/fake/class.FakeModulAndroid.hpp"
#include <windows.h>
#include <iostream>
#include <process.h>
#include <iostream>

using namespace Architecture;
using namespace std;

/**
* Modul ktory riadi TCP server a napoji tento server.
* Tento modul je potom napojeny na halvnu apliakciu cez DLL subor.
*/
class TCPServer : public FakeModulAndroid, MessageHandler {
private:
	ServerSocket* server;

public:
	// Nas modul ma zatial nacitavat fake GPS suranice zo suboru
	TCPServer() : FakeModulAndroid("data/video/2013-10-20-12-25-52.txt") {
		server = NULL;
	}

	// Nas modul sa spusta
	virtual void init() {
		FakeModulAndroid::init();
		cout << "Native TCP server starting\n";
		server = new MyServerSocket(this, "10.0.0.107", "1234");
		server->start();
	}

	// Zachytavam spravy od clienta
	void HandleMessage(char* input) {
		string inputText = input;
		cout << "Reading\n" + inputText + "\n";
		size_t pos = inputText.find(":");
		if(pos == -1) {
			cout << "Sprava nieje spravne formatovana.\n";
			return;
		}
		string key = inputText.substr(pos);
		string value = inputText.substr(pos, inputText.length());

		// Citaj prikaz
		if (key.compare("Command") != 0) {
			//sendRandomNumberResponse();
			updateCommand(value); // TODO: tu ostava :
			return;
		}

		// Citaj GPS
		if (key.compare("gps") != 0) {
			vector<string> v;
			split(value, v);
			GPS gps;
			gps.latitude = stod(v.at(0));
			gps.longitude = stod(v.at(1));
			setGPS(gps);
			return;
		}

		cout << "Unkown command from tcp!\n";
	}

	// Posielam clientovy odpoved
	/*void sendRandomNumberResponse() {
	char buffer[512];
	buffer[0] = 0;
	sprintf_s(buffer, "Command:5\n");
	getListener()->sendTEXT2Client(buffer);
	}*/

	// Nas modul ma byt vypusteny zo systemu
	~TCPServer() {
		if(server != NULL) {
			delete server;
		}
	}

	// Ma byt moodu lspusteny v samostatnom vlakne ?
	virtual bool isThreaded() { return true; }
};

// Ked nas modul ma byt vytvoreny cez riadiaci modul
IMPEXP void* callFactory() {
	return static_cast< void* > (new TCPServer());
}

// Ked chceme modul spustit ako normalnu aplikaciu
int main() {
	TCPServer* a = new TCPServer();
	a->init();
	delete a;
}

// Ked nas modul je nacitany cez riadiaci modul
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) {
	printf("Dll nacitane\n");
	return 1;
}<commit_msg>upravena ip<commit_after>#include "../Carlos/architecture/DllExports.h"
#include "class.MyServerSocket.hpp"
#include "split.h"
#include "../Carlos/architecture/modules/fake/class.FakeModulAndroid.hpp"
#include <windows.h>
#include <iostream>
#include <process.h>
#include <iostream>

using namespace Architecture;
using namespace std;

/**
* Modul ktory riadi TCP server a napoji tento server.
* Tento modul je potom napojeny na halvnu apliakciu cez DLL subor.
*/
class TCPServer : public FakeModulAndroid, MessageHandler {
private:
	ServerSocket* server;

public:
	// Nas modul ma zatial nacitavat fake GPS suranice zo suboru
	TCPServer() : FakeModulAndroid("data/video/2013-10-20-12-25-52.txt") {
		server = NULL;
	}

	// Nas modul sa spusta
	virtual void init() {
		FakeModulAndroid::init();
		cout << "Native TCP server starting\n";
		server = new MyServerSocket(this, "192.168.247.1", "1234");
		server->start();
	}

	// Zachytavam spravy od clienta
	void HandleMessage(char* input) {
		string inputText = input;
		cout << "Reading\n" + inputText + "\n";
		size_t pos = inputText.find(":");
		if(pos == -1) {
			cout << "Sprava nieje spravne formatovana.\n";
			return;
		}
		string key = inputText.substr(0, pos);
		string value = inputText.substr(pos+1, inputText.length());

		// Citaj prikaz
		if (key.compare("Command") != 0) {
			//sendRandomNumberResponse();
			updateCommand(value); // TODO: tu ostava :
			return;
		}

		// Citaj GPS

		if (key.compare("gps") != 0) {
			vector<string> v;
			split(value, v);
			GPS gps;
			gps.latitude = stod(v.at(0));
			gps.longitude = stod(v.at(1));
			setGPS(gps);
			return;
		}

		cout << "Unkown command from tcp!\n";
	}

	// Posielam clientovy odpoved
	/*void sendRandomNumberResponse() {
	char buffer[512];
	buffer[0] = 0;
	sprintf_s(buffer, "Command:5\n");
	getListener()->sendTEXT2Client(buffer);
	}*/

	// Nas modul ma byt vypusteny zo systemu
	~TCPServer() {
		if(server != NULL) {
			delete server;
		}
	}

	// Ma byt moodu lspusteny v samostatnom vlakne ?
	virtual bool isThreaded() { return true; }
};

// Ked nas modul ma byt vytvoreny cez riadiaci modul
IMPEXP void* callFactory() {
	return static_cast< void* > (new TCPServer());
}

// Ked chceme modul spustit ako normalnu aplikaciu
int main() {
	TCPServer* a = new TCPServer();
	a->init();
	delete a;
}

// Ked nas modul je nacitany cez riadiaci modul
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) {
	printf("Dll nacitane\n");
	return 1;
}<|endoftext|>


<commit_before>//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
//
// This is the llc code generator.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));

enum ArchName { noarch, x86, Sparc };

static cl::opt<ArchName>
Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix,
     cl::values(clEnumVal(x86, "  IA-32 (Pentium and above)"),
                clEnumValN(Sparc, "sparc", "  SPARC V9"),
		0),
     cl::init(noarch));

// GetFileNameRoot - Helper function to get the basename of a filename...
static inline std::string
GetFileNameRoot(const std::string &InputFilename)
{
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");

  // Load the module to be compiled...
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
  if (M.get() == 0) {
    std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
    return 1;
  }
  Module &mod = *M.get();

  // Allocate target machine.  First, check whether the user has
  // explicitly specified an architecture to compile for.
  TargetMachine* (*TargetMachineAllocator)(const Module&) = 0;
  switch (Arch) {
  case x86:
    TargetMachineAllocator = allocateX86TargetMachine;
    break;
  case Sparc:
    TargetMachineAllocator = allocateSparcTargetMachine;
    break;
  default:
    // Decide what the default target machine should be, by looking at
    // the module. This heuristic (ILP32, LE -> IA32; LP64, BE ->
    // SPARCV9) is kind of gross, but it will work until we have more
    // sophisticated target information to work from.
    if (mod.getEndianness()  == Module::LittleEndian &&
        mod.getPointerSize() == Module::Pointer32) {
      TargetMachineAllocator = allocateX86TargetMachine;
    } else if (mod.getEndianness()  == Module::BigEndian &&
               mod.getPointerSize() == Module::Pointer64) {
      TargetMachineAllocator = allocateSparcTargetMachine;
    } else {
      // If the module is target independent, favor a target which matches the
      // current build system.
#if defined(i386) || defined(__i386__) || defined(__x86__)
      TargetMachineAllocator = allocateX86TargetMachine;
#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9)
      TargetMachineAllocator = allocateSparcTargetMachine;
#else
      std::cerr << argv[0] << ": module does not specify a target to use.  "
                << "You must use the -march option.\n";
      return 1;
#endif
    }
    break;
  }
  std::auto_ptr<TargetMachine> target(TargetMachineAllocator(mod));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();
  const TargetData &TD = Target.getTargetData();

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;

  Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
                            TD.getPointerAlignment(), TD.getDoubleAlignment()));

  // Figure out where we are going to send the output...
  std::ostream *Out = 0;
  if (OutputFilename != "") {
    if (OutputFilename != "-") {
      // Specified an output filename?
      if (!Force && std::ifstream(OutputFilename.c_str())) {
	// If force is not specified, make sure not to overwrite a file!
	std::cerr << argv[0] << ": error opening '" << OutputFilename
		  << "': file exists!\n"
		  << "Use -f command line argument to force output\n";
	return 1;
      }
      Out = new std::ofstream(OutputFilename.c_str());

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    } else {
      Out = &std::cout;
    }
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = &std::cout;
    } else {
      OutputFilename = GetFileNameRoot(InputFilename);
      OutputFilename += ".s";

      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists!\n"
                  << "Use -f command line argument to force output\n";
        return 1;
      }

      Out = new std::ofstream(OutputFilename.c_str());
      if (!Out->good()) {
        std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
        delete Out;
        return 1;
      }

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    }
  }

  // Ask the target to add backend passes as necessary
  if (Target.addPassesToEmitAssembly(Passes, *Out)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' does not support static compilation!\n";
    if (Out != &std::cout) delete Out;
    // And the Out file is empty and useless, so remove it now.
    std::remove(OutputFilename.c_str());
    return 1;
  } else {
    // Run our queue of passes all at once now, efficiently.
    Passes.run(*M.get());
  }

  // Delete the ostream if it's not a stdout stream
  if (Out != &std::cout) delete Out;

  return 0;
}
<commit_msg>Added code to avoid checking for .bc when the filename is too short.<commit_after>//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
//
// This is the llc code generator.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));

enum ArchName { noarch, x86, Sparc };

static cl::opt<ArchName>
Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix,
     cl::values(clEnumVal(x86, "  IA-32 (Pentium and above)"),
                clEnumValN(Sparc, "sparc", "  SPARC V9"),
		0),
     cl::init(noarch));

// GetFileNameRoot - Helper function to get the basename of a filename...
static inline std::string
GetFileNameRoot(const std::string &InputFilename)
{
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if ((Len > 2) &&
      IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");

  // Load the module to be compiled...
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
  if (M.get() == 0) {
    std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
    return 1;
  }
  Module &mod = *M.get();

  // Allocate target machine.  First, check whether the user has
  // explicitly specified an architecture to compile for.
  TargetMachine* (*TargetMachineAllocator)(const Module&) = 0;
  switch (Arch) {
  case x86:
    TargetMachineAllocator = allocateX86TargetMachine;
    break;
  case Sparc:
    TargetMachineAllocator = allocateSparcTargetMachine;
    break;
  default:
    // Decide what the default target machine should be, by looking at
    // the module. This heuristic (ILP32, LE -> IA32; LP64, BE ->
    // SPARCV9) is kind of gross, but it will work until we have more
    // sophisticated target information to work from.
    if (mod.getEndianness()  == Module::LittleEndian &&
        mod.getPointerSize() == Module::Pointer32) {
      TargetMachineAllocator = allocateX86TargetMachine;
    } else if (mod.getEndianness()  == Module::BigEndian &&
               mod.getPointerSize() == Module::Pointer64) {
      TargetMachineAllocator = allocateSparcTargetMachine;
    } else {
      // If the module is target independent, favor a target which matches the
      // current build system.
#if defined(i386) || defined(__i386__) || defined(__x86__)
      TargetMachineAllocator = allocateX86TargetMachine;
#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9)
      TargetMachineAllocator = allocateSparcTargetMachine;
#else
      std::cerr << argv[0] << ": module does not specify a target to use.  "
                << "You must use the -march option.\n";
      return 1;
#endif
    }
    break;
  }
  std::auto_ptr<TargetMachine> target(TargetMachineAllocator(mod));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();
  const TargetData &TD = Target.getTargetData();

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;

  Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
                            TD.getPointerAlignment(), TD.getDoubleAlignment()));

  // Figure out where we are going to send the output...
  std::ostream *Out = 0;
  if (OutputFilename != "") {
    if (OutputFilename != "-") {
      // Specified an output filename?
      if (!Force && std::ifstream(OutputFilename.c_str())) {
	// If force is not specified, make sure not to overwrite a file!
	std::cerr << argv[0] << ": error opening '" << OutputFilename
		  << "': file exists!\n"
		  << "Use -f command line argument to force output\n";
	return 1;
      }
      Out = new std::ofstream(OutputFilename.c_str());

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    } else {
      Out = &std::cout;
    }
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = &std::cout;
    } else {
      OutputFilename = GetFileNameRoot(InputFilename);
      OutputFilename += ".s";

      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists!\n"
                  << "Use -f command line argument to force output\n";
        return 1;
      }

      Out = new std::ofstream(OutputFilename.c_str());
      if (!Out->good()) {
        std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
        delete Out;
        return 1;
      }

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    }
  }

  // Ask the target to add backend passes as necessary
  if (Target.addPassesToEmitAssembly(Passes, *Out)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' does not support static compilation!\n";
    if (Out != &std::cout) delete Out;
    // And the Out file is empty and useless, so remove it now.
    std::remove(OutputFilename.c_str());
    return 1;
  } else {
    // Run our queue of passes all at once now, efficiently.
    Passes.run(*M.get());
  }

  // Delete the ostream if it's not a stdout stream
  if (Out != &std::cout) delete Out;

  return 0;
}
<|endoftext|>


<commit_before>//===-- llc.cpp - Implement the LLVM Compiler -----------------------------===//
//
// This is the llc compiler driver.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/Sparc.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Instrumentation/TraceValues.h"
#include "llvm/Transforms/ChangeAllocations.h"
#include "llvm/Transforms/HoistPHIConstants.h"
#include "llvm/Transforms/Scalar/DecomposeMultiDimRefs.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Transforms/ConstantMerge.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/PassManager.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>
using std::string;

static cl::String InputFilename ("", "Input filename", cl::NoFlags, "-");
static cl::String OutputFilename("o", "Output filename", cl::NoFlags, "");
static cl::Flag   Force         ("f", "Overwrite output files");
static cl::Flag   DumpAsm       ("d", "Print bytecode before native code generation", cl::Hidden);

enum TraceLevel {
  TraceOff, TraceFunctions, TraceBasicBlocks
};

static cl::Enum<enum TraceLevel> TraceValues("trace", cl::NoFlags,
  "Trace values through functions or basic blocks",
  clEnumValN(TraceOff        , "off",        "Disable trace code"),
  clEnumValN(TraceFunctions  , "function",   "Trace each function"),
  clEnumValN(TraceBasicBlocks, "basicblock", "Trace each basic block"), 0);

// GetFileNameRoot - Helper function to get the basename of a filename...
static inline string GetFileNameRoot(const string &InputFilename) {
  string IFN = InputFilename;
  string outputFilename;
  int Len = IFN.length();
  if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

//===---------------------------------------------------------------------===//
// Function main()
//
// Entry point for the llc compiler.
//===---------------------------------------------------------------------===//

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");

  // Allocate a target... in the future this will be controllable on the
  // command line.
  std::auto_ptr<TargetMachine> target(allocateSparcTargetMachine());
  assert(target.get() && "Could not allocate target machine!");

  TargetMachine &Target = *target.get();

  // Load the module to be compiled...
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
  if (M.get() == 0) {
    cerr << "bytecode didn't read correctly.\n";
    return 1;
  }

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;

  // Hoist constants out of PHI nodes into predecessor BB's
  Passes.add(createHoistPHIConstantsPass());

  if (TraceValues != TraceOff) {   // If tracing enabled...
    // Insert trace code in all functions in the module
    if (TraceValues == TraceBasicBlocks)
      Passes.add(createTraceValuesPassForBasicBlocks());
    else if (TraceValues == TraceFunctions)
      Passes.add(createTraceValuesPassForFunction());
    else
      assert(0 && "Bad value for TraceValues!");

    // Eliminate duplication in constant pool
    Passes.add(createDynamicConstantMergePass());
  }

  // Decompose multi-dimensional refs into a sequence of 1D refs
  Passes.add(createDecomposeMultiDimRefsPass());

  // Write out the module with tracing code just before code generation
  if (TraceValues != TraceOff) {   // If tracing enabled...
    assert(InputFilename != "-" &&
           "files on stdin not supported with tracing");
    string traceFileName = GetFileNameRoot(InputFilename) + ".trace.bc";

    if (!Force && std::ifstream(OutputFilename.c_str())) {
      // If force is not specified, make sure not to overwrite a file!
      cerr << "Error opening '" << OutputFilename << "': File exists!\n"
           << "Use -f command line argument to force output\n";
      return 1;
    }

    std::ostream *os = new std::ofstream(traceFileName.c_str());
    if (!os->good()) {
      cerr << "Error opening " << traceFileName
           << "! SKIPPING OUTPUT OF TRACE CODE\n";
      delete os;
      return 1;
    }

    Passes.add(new WriteBytecodePass(os, true));
  }

  // Replace malloc and free instructions with library calls.
  // Do this after tracing until lli implements these lib calls.
  // For now, it will emulate malloc and free internally.
  Passes.add(createLowerAllocationsPass(Target.DataLayout));

  // If LLVM dumping after transformations is requested, add it to the pipeline
  if (DumpAsm)
    Passes.add(new PrintFunctionPass("Code after xformations: \n", &cerr));

  // Figure out where we are going to send the output...
  std::ostream *Out = 0;
  if (OutputFilename != "") {   // Specified an output filename?
    if (!Force && std::ifstream(OutputFilename.c_str())) {
      // If force is not specified, make sure not to overwrite a file!
      cerr << "Error opening '" << OutputFilename << "': File exists!\n"
           << "Use -f command line argument to force output\n";
      return 1;
    }
    Out = new std::ofstream(OutputFilename.c_str());

    // Make sure that the Out file gets unlink'd from the disk if we get a
    // SIGINT
    RemoveFileOnSignal(OutputFilename);
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = &std::cout;
    } else {
      string OutputFilename = GetFileNameRoot(InputFilename);
      OutputFilename += ".s";

      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        cerr << "Error opening '" << OutputFilename << "': File exists!\n"
             << "Use -f command line argument to force output\n";
        return 1;
      }

      Out = new std::ofstream(OutputFilename.c_str());
      if (!Out->good()) {
        cerr << "Error opening " << OutputFilename << "!\n";
        delete Out;
        return 1;
      }
      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    }
  }

  Target.addPassesToEmitAssembly(Passes, *Out);

  // Run our queue of passes all at once now, efficiently.
  Passes.run(M.get());

  if (Out != &std::cout) delete Out;

  return 0;
}
<commit_msg>Remove unneccesary pass.<commit_after>//===-- llc.cpp - Implement the LLVM Compiler -----------------------------===//
//
// This is the llc compiler driver.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/Sparc.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Instrumentation/TraceValues.h"
#include "llvm/Transforms/ChangeAllocations.h"
#include "llvm/Transforms/Scalar/DecomposeMultiDimRefs.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Transforms/ConstantMerge.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/PassManager.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>
using std::string;

static cl::String InputFilename ("", "Input filename", cl::NoFlags, "-");
static cl::String OutputFilename("o", "Output filename", cl::NoFlags, "");
static cl::Flag   Force         ("f", "Overwrite output files");
static cl::Flag   DumpAsm       ("d", "Print bytecode before native code generation", cl::Hidden);

enum TraceLevel {
  TraceOff, TraceFunctions, TraceBasicBlocks
};

static cl::Enum<enum TraceLevel> TraceValues("trace", cl::NoFlags,
  "Trace values through functions or basic blocks",
  clEnumValN(TraceOff        , "off",        "Disable trace code"),
  clEnumValN(TraceFunctions  , "function",   "Trace each function"),
  clEnumValN(TraceBasicBlocks, "basicblock", "Trace each basic block"), 0);

// GetFileNameRoot - Helper function to get the basename of a filename...
static inline string GetFileNameRoot(const string &InputFilename) {
  string IFN = InputFilename;
  string outputFilename;
  int Len = IFN.length();
  if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

//===---------------------------------------------------------------------===//
// Function main()
//
// Entry point for the llc compiler.
//===---------------------------------------------------------------------===//

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");

  // Allocate a target... in the future this will be controllable on the
  // command line.
  std::auto_ptr<TargetMachine> target(allocateSparcTargetMachine());
  assert(target.get() && "Could not allocate target machine!");

  TargetMachine &Target = *target.get();

  // Load the module to be compiled...
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
  if (M.get() == 0) {
    cerr << "bytecode didn't read correctly.\n";
    return 1;
  }

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;

  if (TraceValues != TraceOff) {   // If tracing enabled...
    // Insert trace code in all functions in the module
    if (TraceValues == TraceBasicBlocks)
      Passes.add(createTraceValuesPassForBasicBlocks());
    else if (TraceValues == TraceFunctions)
      Passes.add(createTraceValuesPassForFunction());
    else
      assert(0 && "Bad value for TraceValues!");

    // Eliminate duplication in constant pool
    Passes.add(createDynamicConstantMergePass());
  }

  // Decompose multi-dimensional refs into a sequence of 1D refs
  Passes.add(createDecomposeMultiDimRefsPass());

  // Write out the module with tracing code just before code generation
  if (TraceValues != TraceOff) {   // If tracing enabled...
    assert(InputFilename != "-" &&
           "files on stdin not supported with tracing");
    string traceFileName = GetFileNameRoot(InputFilename) + ".trace.bc";

    if (!Force && std::ifstream(OutputFilename.c_str())) {
      // If force is not specified, make sure not to overwrite a file!
      cerr << "Error opening '" << OutputFilename << "': File exists!\n"
           << "Use -f command line argument to force output\n";
      return 1;
    }

    std::ostream *os = new std::ofstream(traceFileName.c_str());
    if (!os->good()) {
      cerr << "Error opening " << traceFileName
           << "! SKIPPING OUTPUT OF TRACE CODE\n";
      delete os;
      return 1;
    }

    Passes.add(new WriteBytecodePass(os, true));
  }

  // Replace malloc and free instructions with library calls.
  // Do this after tracing until lli implements these lib calls.
  // For now, it will emulate malloc and free internally.
  Passes.add(createLowerAllocationsPass(Target.DataLayout));

  // If LLVM dumping after transformations is requested, add it to the pipeline
  if (DumpAsm)
    Passes.add(new PrintFunctionPass("Code after xformations: \n", &cerr));

  // Figure out where we are going to send the output...
  std::ostream *Out = 0;
  if (OutputFilename != "") {   // Specified an output filename?
    if (!Force && std::ifstream(OutputFilename.c_str())) {
      // If force is not specified, make sure not to overwrite a file!
      cerr << "Error opening '" << OutputFilename << "': File exists!\n"
           << "Use -f command line argument to force output\n";
      return 1;
    }
    Out = new std::ofstream(OutputFilename.c_str());

    // Make sure that the Out file gets unlink'd from the disk if we get a
    // SIGINT
    RemoveFileOnSignal(OutputFilename);
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = &std::cout;
    } else {
      string OutputFilename = GetFileNameRoot(InputFilename);
      OutputFilename += ".s";

      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        cerr << "Error opening '" << OutputFilename << "': File exists!\n"
             << "Use -f command line argument to force output\n";
        return 1;
      }

      Out = new std::ofstream(OutputFilename.c_str());
      if (!Out->good()) {
        cerr << "Error opening " << OutputFilename << "!\n";
        delete Out;
        return 1;
      }
      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    }
  }

  Target.addPassesToEmitAssembly(Passes, *Out);

  // Run our queue of passes all at once now, efficiently.
  Passes.run(M.get());

  if (Out != &std::cout) delete Out;

  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015-2016 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
// "Materials"), to deal in the Materials without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Materials, and to
// permit persons to whom the Materials are 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 Materials.
//
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
//    https://www.khronos.org/registry/
//
// THE MATERIALS ARE 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
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <vector>

#include "spirv-tools/libspirv.h"

void print_usage(char* argv0) {
  printf(
      R"(%s - Validate a SPIR-V binary file.

USAGE: %s [options] [<filename>]

The SPIR-V binary is read from <filename>. If no file is specified,
or if the filename is "-", then the binary is read from standard input.

Options:
  -all       Perform all validation (default OFF)
  -basic     Perform basic validation (default OFF)
  -id        Perform id validation (default OFF)
  -layout    Perform layout validation (default OFF)
  -rules     Perform rules validation (default OFF)
)",
      argv0, argv0);
}

int main(int argc, char** argv) {
  const char* inFile = nullptr;
  uint32_t options = 0;

  for (int argi = 1; argi < argc; ++argi) {
    const char* cur_arg = argv[argi];
    if ('-' == cur_arg[0]) {
      if (!strcmp("all", cur_arg + 1)) {
        options |= SPV_VALIDATE_ALL;
      } else if (!strcmp("basic", cur_arg + 1)) {
        options |= SPV_VALIDATE_BASIC_BIT;
      } else if (!strcmp("id", cur_arg + 1)) {
        options |= SPV_VALIDATE_ID_BIT;
      } else if (!strcmp("layout", cur_arg + 1)) {
        options |= SPV_VALIDATE_LAYOUT_BIT;
      } else if (!strcmp("rules", cur_arg + 1)) {
        options |= SPV_VALIDATE_RULES_BIT;
      } else if (0 == cur_arg[1]) {
        // Setting a filename of "-" to indicate stdin.
        if (!inFile) {
          inFile = cur_arg;
        } else {
          fprintf(stderr, "error: More than one input file specified\n");
          return 1;
        }

      } else {
        print_usage(argv[0]);
        return 1;
      }
    } else {
      if (!inFile) {
        inFile = cur_arg;
      } else {
        fprintf(stderr, "error: More than one input file specified\n");
        return 1;
      }
    }
  }

  std::vector<uint32_t> contents;
  const bool use_file = inFile && strcmp("-", inFile);
  if (FILE* fp = (use_file ? fopen(inFile, "rb") : stdin)) {
    uint32_t buf[1024];
    while (size_t len = fread(buf, sizeof(uint32_t),
                              sizeof(buf) / sizeof(uint32_t), fp)) {
      contents.insert(contents.end(), buf, buf + len);
    }
    if (use_file) fclose(fp);
  } else {
    fprintf(stderr, "error: file does not exist '%s'\n", inFile);
    return 1;
  }

  spv_const_binary_t binary = {contents.data(), contents.size()};

  spv_diagnostic diagnostic = nullptr;
  spv_context context = spvContextCreate();
  spv_result_t error = spvValidate(context, &binary, options, &diagnostic);
  spvContextDestroy(context);
  if (error) {
    spvDiagnosticPrint(diagnostic);
    spvDiagnosticDestroy(diagnostic);
    return error;
  }

  return 0;
}
<commit_msg>spirv-val help says it's a work in progress.<commit_after>// Copyright (c) 2015-2016 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
// "Materials"), to deal in the Materials without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Materials, and to
// permit persons to whom the Materials are 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 Materials.
//
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
//    https://www.khronos.org/registry/
//
// THE MATERIALS ARE 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
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <vector>

#include "spirv-tools/libspirv.h"

void print_usage(char* argv0) {
  printf(
      R"(%s - Validate a SPIR-V binary file.

USAGE: %s [options] [<filename>]

The SPIR-V binary is read from <filename>. If no file is specified,
or if the filename is "-", then the binary is read from standard input.

NOTE: The validator is a work in progress.

Options:
  -all       Perform all validation (default OFF)
  -basic     Perform basic validation (default OFF)
  -id        Perform id validation (default OFF)
  -layout    Perform layout validation (default OFF)
  -rules     Perform rules validation (default OFF)
)",
      argv0, argv0);
}

int main(int argc, char** argv) {
  const char* inFile = nullptr;
  uint32_t options = 0;

  for (int argi = 1; argi < argc; ++argi) {
    const char* cur_arg = argv[argi];
    if ('-' == cur_arg[0]) {
      if (!strcmp("all", cur_arg + 1)) {
        options |= SPV_VALIDATE_ALL;
      } else if (!strcmp("basic", cur_arg + 1)) {
        options |= SPV_VALIDATE_BASIC_BIT;
      } else if (!strcmp("id", cur_arg + 1)) {
        options |= SPV_VALIDATE_ID_BIT;
      } else if (!strcmp("layout", cur_arg + 1)) {
        options |= SPV_VALIDATE_LAYOUT_BIT;
      } else if (!strcmp("rules", cur_arg + 1)) {
        options |= SPV_VALIDATE_RULES_BIT;
      } else if (0 == cur_arg[1]) {
        // Setting a filename of "-" to indicate stdin.
        if (!inFile) {
          inFile = cur_arg;
        } else {
          fprintf(stderr, "error: More than one input file specified\n");
          return 1;
        }

      } else {
        print_usage(argv[0]);
        return 1;
      }
    } else {
      if (!inFile) {
        inFile = cur_arg;
      } else {
        fprintf(stderr, "error: More than one input file specified\n");
        return 1;
      }
    }
  }

  std::vector<uint32_t> contents;
  const bool use_file = inFile && strcmp("-", inFile);
  if (FILE* fp = (use_file ? fopen(inFile, "rb") : stdin)) {
    uint32_t buf[1024];
    while (size_t len = fread(buf, sizeof(uint32_t),
                              sizeof(buf) / sizeof(uint32_t), fp)) {
      contents.insert(contents.end(), buf, buf + len);
    }
    if (use_file) fclose(fp);
  } else {
    fprintf(stderr, "error: file does not exist '%s'\n", inFile);
    return 1;
  }

  spv_const_binary_t binary = {contents.data(), contents.size()};

  spv_diagnostic diagnostic = nullptr;
  spv_context context = spvContextCreate();
  spv_result_t error = spvValidate(context, &binary, options, &diagnostic);
  spvContextDestroy(context);
  if (error) {
    spvDiagnosticPrint(diagnostic);
    spvDiagnosticDestroy(diagnostic);
    return error;
  }

  return 0;
}
<|endoftext|>