<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file HitFinderTools.h
 */

#include "HitFinderTools.h"

using namespace std;

vector<JPetHit> HitFinderTools::createHits(const SignalsContainer& allSignalsInTimeWindow, const double timeDifferenceWindow){

    // This method takes signal from side A on a scintilator and compares it with signals on side B - if they are within time window then it creates hit

    vector<JPetHit> hits;

    for (auto scintillator : allSignalsInTimeWindow) {

        auto sideA = scintillator.second.first;
        auto sideB = scintillator.second.second;

        if(sideA.size() > 0 and sideB.size() > 0){

            for(auto signalA : sideA){
                for(auto signalB : sideB){

                    if(abs(signalA.getTime() - signalB.getTime()) < timeDifferenceWindow /*ps*/){

                        JPetHit hit;
                        hit.setSignalA(signalA);
                        hit.setSignalB(signalB);
                        hit.setTime( (signalA.getTime() + signalB.getTime())/2.0 );
                        hit.setScintillator(signalA.getRecoSignal().getRawSignal().getPM().getScin());
                        hit.setBarrelSlot(signalA.getRecoSignal().getRawSignal().getPM().getScin().getBarrelSlot());

                        hits.push_back(hit);
                    }
                }
            }

        }
    }
    return hits;
}
<commit_msg>Sort signals<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file HitFinderTools.h
 */

#include "HitFinderTools.h"

using namespace std;

vector<JPetHit> HitFinderTools::createHits(const SignalsContainer& allSignalsInTimeWindow, const double timeDifferenceWindow){

    // This method takes signal from side A on a scintilator and compares it with signals on side B - if they are within time window then it creates hit

    vector<JPetHit> hits;

    for (auto scintillator : allSignalsInTimeWindow) {

        auto sideA = scintillator.second.first;
        auto sideB = scintillator.second.second;

        if(sideA.size() > 0 and sideB.size() > 0){

        std::sort(sideA.begin(), sideA.end(), [] (const JPetPhysSignal & h1, const JPetPhysSignal & h2) {return h1.getTime() < h2.getTime();});
        std::sort(sideB.begin(), sideB.end(), [] (const JPetPhysSignal & h1, const JPetPhysSignal & h2) {return h1.getTime() < h2.getTime();});
            for(auto signalA : sideA){
                for(auto signalB : sideB){

                    if(abs(signalA.getTime() - signalB.getTime()) < timeDifferenceWindow  && (signalA.getTime() - signalB.getTime()) < timeDifferenceWindow/*ps*/){

                        JPetHit hit;
                        hit.setSignalA(signalA);
                        hit.setSignalB(signalB);
                        hit.setTime( (signalA.getTime() + signalB.getTime())/2.0 );
                        hit.setScintillator(signalA.getRecoSignal().getRawSignal().getPM().getScin());
                        hit.setBarrelSlot(signalA.getRecoSignal().getRawSignal().getPM().getScin().getBarrelSlot());

                        hits.push_back(hit);
                    }
                }
            }

        }
    }
    return hits;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.2  2000/02/06 07:47:24  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1.1.1  1999/11/09 01:09:29  twl
 * Initial checkin
 *
 * Revision 1.11  1999/11/08 20:43:42  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/XMLUni.hpp>
#include <sax/AttributeList.hpp>
#include "SAXPrint.hpp"

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Constructors and Destructor
// ---------------------------------------------------------------------------
SAXPrintHandlers::SAXPrintHandlers(const bool doEscapes) :

    fDoEscapes(doEscapes)
{
}

SAXPrintHandlers::~SAXPrintHandlers()
{
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX ErrorHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::error(const SAXParseException& e)
{
    cerr << "\nError at (file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "): " << StrX(e.getMessage()) << endl;
}

void SAXPrintHandlers::fatalError(const SAXParseException& e)
{
    cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "): " << StrX(e.getMessage()) << endl;
}

void SAXPrintHandlers::warning(const SAXParseException& e)
{
    cerr << "\nWarning at (file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "): " << StrX(e.getMessage()) << endl;
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX DTDHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::unparsedEntityDecl(const     XMLCh* const name
                                          , const   XMLCh* const publicId
                                          , const   XMLCh* const systemId
                                          , const   XMLCh* const notationName)
{
    // Not used at this time
}

void SAXPrintHandlers::notationDecl(                                               const   XMLCh* const name
                                    , const XMLCh* const publicId
                                    , const XMLCh* const systemId)
{
    // Not used at this time
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX DocumentHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::characters(const     XMLCh* const    chars
                                  , const   unsigned int    length)
{
    // Transcode to UTF-8 for portable display
    StrX tmpXCode(chars, length);
	const char* tmpText = tmpXCode.localForm();

    //
    //  If we were asked to escape special chars, then do that. Else just
    //  display it as normal text.
    //
    if (fDoEscapes)
    {
        for (unsigned int index = 0; index < length; index++)
        {
            switch (tmpText[index])
            {
            case chAmpersand :
                cout << "&";
                break;

            case chOpenAngle :
                cout << "<";
                break;

            case chCloseAngle:
                cout << ">";
                break;

            case chDoubleQuote :
                cout << """;
                break;

            default:
                cout << tmpText[index];
                break;
            }
        }
    }
     else
    {
        cout << tmpText;
    }
}

void SAXPrintHandlers::endDocument()
{
}

void SAXPrintHandlers::endElement(const XMLCh* const name)
{
    cout << "</" << StrX(name) << ">";
}

void SAXPrintHandlers::ignorableWhitespace( const   XMLCh* const chars
                                            ,const  unsigned int length)
{
    cout << StrX(chars, length);
}

void SAXPrintHandlers::processingInstruction(const  XMLCh* const target
                                            , const XMLCh* const data)
{
    cout << "<?" << StrX(target);
    if (data)
        cout << " " << StrX(data);
    cout << "?>\n";
}

void SAXPrintHandlers::startDocument()
{
}

void SAXPrintHandlers::startElement(const   XMLCh* const    name
                                    ,       AttributeList&  attributes)
{
    cout << "<" << StrX(name);
    unsigned int len = attributes.getLength();

    for (unsigned int index = 0; index < len; index++)
    {
        cout << " " << StrX(attributes.getName(index)) << "=\"";
		cout << StrX(attributes.getValue(index)) << "\"";
    }
    cout << ">";
}

<commit_msg>Removed second parameter from call to StrX constructor<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.3  2000/02/11 03:05:35  abagchi
 * Removed second parameter from call to StrX constructor
 *
 * Revision 1.2  2000/02/06 07:47:24  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1.1.1  1999/11/09 01:09:29  twl
 * Initial checkin
 *
 * Revision 1.11  1999/11/08 20:43:42  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/XMLUni.hpp>
#include <sax/AttributeList.hpp>
#include "SAXPrint.hpp"

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Constructors and Destructor
// ---------------------------------------------------------------------------
SAXPrintHandlers::SAXPrintHandlers(const bool doEscapes) :

    fDoEscapes(doEscapes)
{
}

SAXPrintHandlers::~SAXPrintHandlers()
{
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX ErrorHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::error(const SAXParseException& e)
{
    cerr << "\nError at (file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "): " << StrX(e.getMessage()) << endl;
}

void SAXPrintHandlers::fatalError(const SAXParseException& e)
{
    cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "): " << StrX(e.getMessage()) << endl;
}

void SAXPrintHandlers::warning(const SAXParseException& e)
{
    cerr << "\nWarning at (file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "): " << StrX(e.getMessage()) << endl;
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX DTDHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::unparsedEntityDecl(const     XMLCh* const name
                                          , const   XMLCh* const publicId
                                          , const   XMLCh* const systemId
                                          , const   XMLCh* const notationName)
{
    // Not used at this time
}

void SAXPrintHandlers::notationDecl(                                               const   XMLCh* const name
                                    , const XMLCh* const publicId
                                    , const XMLCh* const systemId)
{
    // Not used at this time
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX DocumentHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::characters(const     XMLCh* const    chars
                                  , const   unsigned int    length)
{
    // Transcode to UTF-8 for portable display
    StrX tmpXCode(chars);
    const char* tmpText = tmpXCode.localForm();

    //
    //  If we were asked to escape special chars, then do that. Else just
    //  display it as normal text.
    //
    if (fDoEscapes)
    {
        for (unsigned int index = 0; index < length; index++)
        {
            switch (tmpText[index])
            {
            case chAmpersand :
                cout << "&";
                break;

            case chOpenAngle :
                cout << "<";
                break;

            case chCloseAngle:
                cout << ">";
                break;

            case chDoubleQuote :
                cout << """;
                break;

            default:
                cout << tmpText[index];
                break;
            }
        }
    }
     else
    {
        cout << tmpText;
    }
}

void SAXPrintHandlers::endDocument()
{
}

void SAXPrintHandlers::endElement(const XMLCh* const name)
{
    cout << "</" << StrX(name) << ">";
}

void SAXPrintHandlers::ignorableWhitespace( const   XMLCh* const chars
                                            ,const  unsigned int length)
{
    cout << StrX(chars);
}

void SAXPrintHandlers::processingInstruction(const  XMLCh* const target
                                            , const XMLCh* const data)
{
    cout << "<?" << StrX(target);
    if (data)
        cout << " " << StrX(data);
    cout << "?>\n";
}

void SAXPrintHandlers::startDocument()
{
}

void SAXPrintHandlers::startElement(const   XMLCh* const    name
                                    ,       AttributeList&  attributes)
{
    cout << "<" << StrX(name);
    unsigned int len = attributes.getLength();

    for (unsigned int index = 0; index < len; index++)
    {
        cout << " " << StrX(attributes.getName(index)) << "=\"";
		cout << StrX(attributes.getValue(index)) << "\"";
    }
    cout << ">";
}

<|endoftext|>


<commit_before>//
//  Exponent.cpp
//  Calculator
//
//  Created by Gavin Scheele on 3/27/14.
//  Copyright (c) 2014 Gavin Scheele. All rights reserved.
//

#include "Exponential.h"

Exponential::Exponential(Expression* base, Rational* exponent){
    this->type = "exponential";
    this->base = base;
    this->exponent = exponent;
    this->exde = new Integer(exponent->getDenominator());
    if (exde->getValue() != 1) {
    	//if the denominator of the exponent is not 1, make the base a root of the denominator, then setting the denominator equal to 1
    	Integer* baseAsInteger = (Integer *) base;
        base = new nthRoot(exde->getValue(), baseAsInteger->getValue(), 1);
        Integer* one = new Integer(1);
        exponent->setDenominator(one);
    }
    this->exnu = new Integer(exponent->getNumerator());
    if (canExponentiate()) {
    	exponentiate();
    }
}
Exponential::~Exponential(){

}

bool Exponential::canExponentiate() {
    if(base->type == "euler"){
        return false;

    }else if(base->type == "exponential"){
	Exponential* ex = (Exponential *) base;
	this->exponent->multiply(ex->getExponent());
	Integer* numSum = new Integer (1);
	ex->getExponent()->setNumerator(numSum);
        return false;
        // false is returned because the base itself would have already been exponentiated if it were possible

    }else if(base->type == "integer"){
        return true;

    }else if(base->type == "logarithm"){
        return false;

    }else if(base->type == "nthRoot"){
	nthRoot* nr = (nthRoot *) base;
	Rational* r = new Rational(this->exponent->getNumerator(), nr->getRoot()*this->exponent->getDenominator());
	//makes a new exponent, multiplying the denominator by the root, allowing the root to be simplified to one
	this->exponent = r;
	nr->setRoot(1);
	return false;

    }else if(base->type == "pi"){
        return false;

    }else if(base->type == "rational"){
        Rational* r = (Rational *) base;
        if (r->geteNumerator()->type == "integer" && r->geteDenominator()->type == "integer") {
          Exponential* nu = new Exponential(r->geteNumerator(), this->exponent);
          r->setNumerator(nu);
          Exponential* de = new Exponential(r->geteDenominator(), this->exponent);
          r->setDenominator(de);
        }

    }else{
        cout << "type not recognized" << endl;
    }
    return false;
}

void Exponential::exponentiate(){
	Integer* one = new Integer(1);
        Rational* oneRat = new Rational(1, 1);
	if (this->base->type == "rational") {
		Rational* ratBase = (Rational *) this->base;
		Exponential* numAsExponential = new Exponential ((ratBase->geteNumerator()), (this->exponent));  //no matching constructor for exponential
		Exponential* denAsExponential = new Exponential ((ratBase->geteDenominator()), (this->exponent));    //same error
		Rational* newRatBase = new Rational(numAsExponential, denAsExponential);
		this->base = newRatBase;
		this->exponent = oneRat;
	}
	else {

    if (this->exponent->getNumerator()==0) {

       this->exponent=oneRat;
       this->base=one;

    }
    bool toFlip = false;
    if (exnu->getValue()<0) {
	    exnu->setValue(exnu->getValue()*-1);
            toFlip = true;
            //handles negative exponents
    }
    Expression* constantBase = 0;
    if (base->type == "integer") {              //fixed the problem for integers but nothing else
        Integer *a = (Integer *)base;
        constantBase = new Integer(a->getValue());
    }

    while (exponent->getNumerator()>1)
    	{
        base->multiply(constantBase);
        exponent->setNumerator(exponent->geteNumerator()->subtract(one));
    }
    if (toFlip) {
        Integer* one = new Integer(1);
        Rational* mouse = new Rational(one, base);
    	base = mouse;
    }

	}

}

Expression* Exponential::add(Expression* a){
    if(a->type == "euler"){

    }else if(a->type == "exponential"){
	Exponential* ex = (Exponential *) a;
	if (ex->getBase()==this->base) {
		if (ex->getExponent()==this->exponent) {
			Integer* two = new Integer(2);
			this->multiply(two);
		}
	}

    }else if(a->type == "integer"){

    }else if(a->type == "logarithm"){

    }else if(a->type == "nthRoot"){

    }else if(a->type == "pi"){

    }else if(a->type == "rational"){

    }else{
        cout << "type not recognized" << endl;
    }
    return this;
}
Expression* Exponential::subtract(Expression* a){
    if(a->type == "euler"){

    }else if(a->type == "exponential"){
	Exponential* ex = (Exponential *) a;
	if (ex->getBase()==this->base) {
		if (ex->getExponent()==this->exponent) {
			Integer* zero = new Integer(0);
			this->multiply(zero);
		}
	}
    }else if(a->type == "integer"){

    }else if(a->type == "logarithm"){

    }else if(a->type == "nthRoot"){

    }else if(a->type == "pi"){

    }else if(a->type == "rational"){

    }else{
        cout << "type not recognized" << endl;
    }
    return this;
}
Expression* Exponential::multiply(Expression* a){
	if(a->type == "euler"){
    		if (this->base->type == "euler") {
    			Rational* oneRat = new Rational(1, 1);
			this->exponent->add(oneRat);

    	}

    }else if(a->type == "exponential"){
		Exponential* ex = (Exponential *) a;
	if (this->base == ex->getBase()) {
		this->exponent->add(ex->getExponent());
	}

    }else if(a->type == "integer"){

    }else if(a->type == "logarithm"){

    }else if(a->type == "nthRoot"){

    }else if(a->type == "pi"){
    	if (this->base->type == "pi") {
    			Rational* oneRat = new Rational(1, 1);
			this->exponent->add(oneRat);
    	}

    }else if(a->type == "rational"){
	Rational* r = (Rational *) a;
	Expression* numToSet = r->geteNumerator();
	numToSet->multiply(this);
	r->setNumerator(numToSet);
	return r;

    }else{
        cout << "type not recognized" << endl;
    }
    return this;
}
Expression* Exponential::divide(Expression* a){
	if(a->type == "euler"){
		if (this->base->type == "euler") {
    				Rational* oneRat = new Rational(1, 1);
				this->exponent->subtract(oneRat);
    		}

    }else if(a->type == "exponential"){
	Exponential* ex = (Exponential *) a;
	if (this->base == ex->getBase()) {
		this->exponent->subtract(ex->getExponent());
	}

    }else if(a->type == "integer"){

    }else if(a->type == "logarithm"){

    }else if(a->type == "nthRoot"){

    }else if(a->type == "pi"){
    	if (this->base->type == "pi") {
    				Rational* oneRat = new Rational(1, 1);
				this->exponent->subtract(oneRat);
    		}

    }else if(a->type == "rational"){
	Rational* r = (Rational *) a;
	Expression* denToSet = r->geteDenominator();
	denToSet->multiply(this);
	r->setDenominator(denToSet);
	return r;

    }else{
        cout << "type not recognized" << endl;
    }
    return this;
}

Rational* Exponential::getExponent() {
    return exponent;
}

Expression* Exponential::getBase() {
    return base;
}

Integer* Exponential::getExnu() {
	return exnu;
}

Integer* Exponential::getExde() {
	return exde;
}

void Exponential::setExnu(Integer* n) {
	exnu = n;
}

void Exponential::setExde(Integer* n) {
	exde = n;
}

void Exponential::setExponent(Rational* e) {
    exponent = e;
}

void Exponential::setBase(Expression* e) {
    base = e;
}

string Exponential::toString() {
    stringstream str;
    if(exponent->getNumerator() == 1 && exponent->getDenominator() == 1){
        str << *base;
    }
    else if(exponent->getDenominator() == 1){
        str << *base << "^" << *exponent->geteNumerator();
    }else{
        str << *base << "^" << *exponent;
    }
    return str.str();
}

ostream& Exponential::print(std::ostream& output) const{
    Exponential *a = (Exponential *)this;
    output << a->toString();
    return output;
}

bool Exponential::canAdd(Expression* b){     //use "this" as comparison. Solver will call someExpression.canAdd(&someOtherExpression)

    if (this->type == b->type && this->type != "logarithm") {
        if (this->type == "nthRoot") {
        }
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool Exponential::canSubtract(Expression* b){
    if (this->type == b->type) {
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool Exponential::canMultiply(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer" && b->type == "rational") return true;
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;

}
bool Exponential::canDivide(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer"){
        if( b->type == "rational") return true;
    }
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
<commit_msg>Fixed canMultiply and canDivide<commit_after>//
//  Exponent.cpp
//  Calculator
//
//  Created by Gavin Scheele on 3/27/14.
//  Copyright (c) 2014 Gavin Scheele. All rights reserved.
//

#include "Exponential.h"

Exponential::Exponential(Expression* base, Rational* exponent){
    this->type = "exponential";
    this->base = base;
    this->exponent = exponent;
    this->exde = new Integer(exponent->getDenominator());
    if (exde->getValue() != 1) {
    	//if the denominator of the exponent is not 1, make the base a root of the denominator, then setting the denominator equal to 1
    	Integer* baseAsInteger = (Integer *) base;
        base = new nthRoot(exde->getValue(), baseAsInteger->getValue(), 1);
        Integer* one = new Integer(1);
        exponent->setDenominator(one);
    }
    this->exnu = new Integer(exponent->getNumerator());
    if (canExponentiate()) {
    	exponentiate();
    }
}
Exponential::~Exponential(){

}

bool Exponential::canExponentiate() {
    if(base->type == "euler"){
        return false;

    }else if(base->type == "exponential"){
	Exponential* ex = (Exponential *) base;
	this->exponent->multiply(ex->getExponent());
	Integer* numSum = new Integer (1);
	ex->getExponent()->setNumerator(numSum);
        return false;
        // false is returned because the base itself would have already been exponentiated if it were possible

    }else if(base->type == "integer"){
        return true;

    }else if(base->type == "logarithm"){
        return false;

    }else if(base->type == "nthRoot"){
	nthRoot* nr = (nthRoot *) base;
	Rational* r = new Rational(this->exponent->getNumerator(), nr->getRoot()*this->exponent->getDenominator());
	//makes a new exponent, multiplying the denominator by the root, allowing the root to be simplified to one
	this->exponent = r;
	nr->setRoot(1);
	return false;

    }else if(base->type == "pi"){
        return false;

    }else if(base->type == "rational"){
        Rational* r = (Rational *) base;
        if (r->geteNumerator()->type == "integer" && r->geteDenominator()->type == "integer") {
          Exponential* nu = new Exponential(r->geteNumerator(), this->exponent);
          r->setNumerator(nu);
          Exponential* de = new Exponential(r->geteDenominator(), this->exponent);
          r->setDenominator(de);
        }

    }else{
        cout << "type not recognized" << endl;
    }
    return false;
}

void Exponential::exponentiate(){
	Integer* one = new Integer(1);
        Rational* oneRat = new Rational(1, 1);
	if (this->base->type == "rational") {
		Rational* ratBase = (Rational *) this->base;
		Exponential* numAsExponential = new Exponential ((ratBase->geteNumerator()), (this->exponent));  //no matching constructor for exponential
		Exponential* denAsExponential = new Exponential ((ratBase->geteDenominator()), (this->exponent));    //same error
		Rational* newRatBase = new Rational(numAsExponential, denAsExponential);
		this->base = newRatBase;
		this->exponent = oneRat;
	}
	else {

    if (this->exponent->getNumerator()==0) {

       this->exponent=oneRat;
       this->base=one;

    }
    bool toFlip = false;
    if (exnu->getValue()<0) {
	    exnu->setValue(exnu->getValue()*-1);
            toFlip = true;
            //handles negative exponents
    }
    Expression* constantBase = 0;
    if (base->type == "integer") {              //fixed the problem for integers but nothing else
        Integer *a = (Integer *)base;
        constantBase = new Integer(a->getValue());
    }

    while (exponent->getNumerator()>1)
    	{
        base->multiply(constantBase);
        exponent->setNumerator(exponent->geteNumerator()->subtract(one));
    }
    if (toFlip) {
        Integer* one = new Integer(1);
        Rational* mouse = new Rational(one, base);
    	base = mouse;
    }

	}

}

Expression* Exponential::add(Expression* a){
    if(a->type == "euler"){

    }else if(a->type == "exponential"){
	Exponential* ex = (Exponential *) a;
	if (ex->getBase()==this->base) {
		if (ex->getExponent()==this->exponent) {
			Integer* two = new Integer(2);
			this->multiply(two);
		}
	}

    }else if(a->type == "integer"){

    }else if(a->type == "logarithm"){

    }else if(a->type == "nthRoot"){

    }else if(a->type == "pi"){

    }else if(a->type == "rational"){

    }else{
        cout << "type not recognized" << endl;
    }
    return this;
}
Expression* Exponential::subtract(Expression* a){
    if(a->type == "euler"){

    }else if(a->type == "exponential"){
	Exponential* ex = (Exponential *) a;
	if (ex->getBase()==this->base) {
		if (ex->getExponent()==this->exponent) {
			Integer* zero = new Integer(0);
			this->multiply(zero);
		}
	}
    }else if(a->type == "integer"){

    }else if(a->type == "logarithm"){

    }else if(a->type == "nthRoot"){

    }else if(a->type == "pi"){

    }else if(a->type == "rational"){

    }else{
        cout << "type not recognized" << endl;
    }
    return this;
}
Expression* Exponential::multiply(Expression* a){
	if(a->type == "euler"){
    		if (this->base->type == "euler") {
    			Rational* oneRat = new Rational(1, 1);
			this->exponent->add(oneRat);

    	}

    }else if(a->type == "exponential"){
		Exponential* ex = (Exponential *) a;
	if (this->base == ex->getBase()) {
		this->exponent->add(ex->getExponent());
	}

    }else if(a->type == "integer"){

    }else if(a->type == "logarithm"){

    }else if(a->type == "nthRoot"){

    }else if(a->type == "pi"){
    	if (this->base->type == "pi") {
    			Rational* oneRat = new Rational(1, 1);
			this->exponent->add(oneRat);
    	}

    }else if(a->type == "rational"){
	Rational* r = (Rational *) a;
	Expression* numToSet = r->geteNumerator();
	numToSet->multiply(this);
	r->setNumerator(numToSet);
	return r;

    }else{
        cout << "type not recognized" << endl;
    }
    return this;
}
Expression* Exponential::divide(Expression* a){
	if(a->type == "euler"){
		if (this->base->type == "euler") {
    				Rational* oneRat = new Rational(1, 1);
				this->exponent->subtract(oneRat);
    		}

    }else if(a->type == "exponential"){
	Exponential* ex = (Exponential *) a;
	if (this->base == ex->getBase()) {
		this->exponent->subtract(ex->getExponent());
	}

    }else if(a->type == "integer"){

    }else if(a->type == "logarithm"){

    }else if(a->type == "nthRoot"){

    }else if(a->type == "pi"){
    	if (this->base->type == "pi") {
    				Rational* oneRat = new Rational(1, 1);
				this->exponent->subtract(oneRat);
    		}

    }else if(a->type == "rational"){
	Rational* r = (Rational *) a;
	Expression* denToSet = r->geteDenominator();
	denToSet->multiply(this);
	r->setDenominator(denToSet);
	return r;

    }else{
        cout << "type not recognized" << endl;
    }
    return this;
}

Rational* Exponential::getExponent() {
    return exponent;
}

Expression* Exponential::getBase() {
    return base;
}

Integer* Exponential::getExnu() {
	return exnu;
}

Integer* Exponential::getExde() {
	return exde;
}

void Exponential::setExnu(Integer* n) {
	exnu = n;
}

void Exponential::setExde(Integer* n) {
	exde = n;
}

void Exponential::setExponent(Rational* e) {
    exponent = e;
}

void Exponential::setBase(Expression* e) {
    base = e;
}

string Exponential::toString() {
    stringstream str;
    if(exponent->getNumerator() == 1 && exponent->getDenominator() == 1){
        str << *base;
    }
    else if(exponent->getDenominator() == 1){
        str << *base << "^" << *exponent->geteNumerator();
    }else{
        str << *base << "^" << *exponent;
    }
    return str.str();
}

ostream& Exponential::print(std::ostream& output) const{
    Exponential *a = (Exponential *)this;
    output << a->toString();
    return output;
}

bool Exponential::canAdd(Expression* b){     //use "this" as comparison. Solver will call someExpression.canAdd(&someOtherExpression)

    if (this->type == b->type && this->type != "logarithm") {
        if (this->type == "nthRoot") {
        }
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool Exponential::canSubtract(Expression* b){
    if (this->type == b->type) {
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool Exponential::canMultiply(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if (this->base->type == b->type) {
    	return true;
    }
    else if(this->type == "integer" && b->type == "rational") return true;
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;

}
bool Exponential::canDivide(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if (this->base->type == b->type) {
    	return true;
    }
    else if(this->type == "integer"){
        if( b->type == "rational") return true;
    }
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fprogressbar.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2003-05-21 08:02:21 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// ============================================================================

#ifndef SC_FPROGRESSBAR_HXX
#define SC_FPROGRESSBAR_HXX

#include "globstr.hrc"

#ifndef SC_FTOOLS_HXX
#include "ftools.hxx"
#endif

class SfxObjectShell;
class ScProgress;

// ============================================================================

const sal_Int32 SCF_INV_SEGMENT = -1;

// ============================================================================

/** Progress bar for complex progress representation.
    @descr  The progress bar contains one or more segments, each with customable
    size. Each segment is represented by a unique identifier. While showing the
    progress bar, several segments can be started simultaneously. The progress
    bar displays the sum of all started segments on screen.

    It is possible to create a full featured ScfProgressBar object from
    any segment. This sub progress bar works only on that parent segment, with
    the effect, that if the sub progress bar reaches 100%, the parent segment is
    filled completely.

    After adding segments, the progress bar has to be activated. In this step the
    total size of all segments is calculated. Therefore it is not possible to add
    more segments from here.

    If a sub progress bar is created from a segment, and the main progress bar
    has been started (but not the sub progress bar), it is still possible to add
    segments to the sub progress bar. It is not allowed to get the sub progress bar
    of a started segment. And it is not allowed to modify the segment containing
    a sub progress bar directly.

    Following a few code examples, how to use the progress bar.

    Example 1: Simple progress bar (see also ScfSimpleProgressBar below).

        ScfProgressBar aProgress( ... );
        sal_Int32 nSeg = aProgress.AddSegment( 50 );        // segment with 50 steps (1 step = 2%)

        aProgress.ActivateSegment( nSeg );                  // start segment nSeg
        aProgress.Progress();                               // 0->1; display: 2%
        aProgress.Progress( 9 );                            // 1->9; display: 18%

    Example 2: Progress bar with 2 segments.

        ScfProgressBar aProgress( ... );
        sal_Int32 nSeg1 = aProgress.AddSegment( 70 );       // segment with 70 steps
        sal_Int32 nSeg2 = aProgress.AddSegment( 30 );       // segment with 30 steps
                                                            // both segments: 100 steps (1 step = 1%)

        aProgress.ActivateSegment( nSeg1 );                 // start first segment
        aProgress.Progress();                               // 0->1, display: 1%
        aProgress.Progress( 3 );                            // 1->3, display: 3%
        aProgress.ActivateSegment( nSeg2 );                 // start second segment
        aProgress.Progress( 5 );                            // 0->5, display: 8% (5+3 steps)
        aProgress.ActivateSegment( nSeg1 );                 // continue with first segment
        aProgress.Progress();                               // 3->4, display: 9% (5+4 steps)

    Example 3: Progress bar with 2 segments, one contains a sub progress bar.

        ScfProgressBar aProgress( ... );
        sal_Int32 nSeg1 = aProgress.AddSegment( 75 );       // segment with 75 steps
        sal_Int32 nSeg2 = aProgress.AddSegment( 25 );       // segment with 25 steps
                                                            // both segments: 100 steps (1 step = 1%)

        aProgress.ActivateSegment( nSeg1 );                 // start first segment
        aProgress.Progress();                               // 0->1, display: 1%

        ScfProgressBar& rSubProgress = aProgress.GetSegmentProgressBar( nSeg2 );
                                                            // sub progress bar from second segment
        sal_Int32 nSubSeg = rSubProgress.AddSegment( 5 );   // 5 steps, mapped to second segment
                                                            // => 1 step = 5 steps in parent = 5%

        rSubProgress.ActivateSegment( nSubSeg );            // start the segment (auto activate parent segment)
        rSubProgress.Progress();                            // 0->1 (0->5 in parent); display: 6% (1+5)

        // not allowed (second segment active):   aProgress.Progress();
        // not allowed (first segment not empty): aProgress.GetSegmentProgressBar( nSeg1 );
 */
class ScfProgressBar : ScfNoCopy
{
private:
    /** Contains all data of a segment of the progress bar. */
    struct ScfProgressSegment
    {
        typedef ::std::auto_ptr< ScfProgressBar > ScfProgressBarPtr;

        ScfProgressBarPtr           mpProgress;     /// Pointer to sub progress bar for this segment.
        sal_uInt32                  mnSize;         /// Size of this segment.
        sal_uInt32                  mnPos;          /// Current position of this segment.

        explicit                    ScfProgressSegment( sal_uInt32 nSize );
                                    ~ScfProgressSegment();
    };

    typedef ::std::auto_ptr< ScProgress >       ScProgressPtr;
    typedef ScfDelList< ScfProgressSegment >    ScfSegmentList;

    ScfSegmentList              maSegments;         /// List of progress segments.
    String                      maText;             /// UI string for system progress.

    ScProgressPtr               mpSysProgress;      /// System progress bar.
    SfxObjectShell*             mpDocShell;         /// The document shell for the progress bar.
    ScfProgressBar*             mpParentProgress;   /// Parent progress bar, if this is a segment progress bar.
    ScfProgressSegment*         mpParentSegment;    /// Parent segment, if this is a segment progress bar.
    ScfProgressSegment*         mpCurrSegment;      /// Current segment for progress.

    sal_uInt32                  mnTotalSize;        /// Total size of all segments.
    sal_uInt32                  mnTotalPos;         /// Sum of positions of all segments.
    sal_uInt32                  mnUnitSize;         /// Size between two calls of system progress.
    sal_uInt32                  mnNextUnitPos;      /// Limit for next system progress call.
    bool                        mbInProgress;       /// true = progress bar started.

public:
    explicit                    ScfProgressBar( SfxObjectShell* pDocShell, const String& rText );
    explicit                    ScfProgressBar( SfxObjectShell* pDocShell, sal_uInt16 nResId );
    virtual                     ~ScfProgressBar();

    /** Adds a new segment to the progress bar.
        @return  the identifier of the segment. */
    sal_Int32                   AddSegment( sal_uInt32 nSize );
    /** Returns a complete progress bar for the specified segment.
        @descr  The progress bar can be used to create sub segments inside of the
        segment. Do not delete it (done by root progress bar)!
        @return  A reference to an ScfProgressBar connected to the segment. */
    ScfProgressBar&             GetSegmentProgressBar( sal_Int32 nSegment );

    /** Returns true, if any progress segment has been started. */
    inline bool                 IsStarted() const { return mbInProgress; }

    /** Starts the progress bar or activates another segment. */
    void                        ActivateSegment( sal_Int32 nSegment );
    /** Starts the progress bar (with first segment). */
    inline void                 Activate() { ActivateSegment( 0 ); }
    /** Set current segment to the specified position. */
    void                        Progress( sal_uInt32 nPos );
    /** Increase current segment by 1. */
    void                        Progress();

private:
    /** Used to create sub progress bars. */
    explicit                    ScfProgressBar(
                                    ScfProgressBar& rParProgress,
                                    ScfProgressSegment* pParSegment );

    /** Initializes all members on construction. */
    void                        Init( SfxObjectShell* pDocShell );

    /** Returns the segment specified by list index. */
    ScfProgressSegment*         GetSegment( sal_Int32 nSegment ) const;
    /** Activates progress bar and sets current segment. */
    void                        SetCurrSegment( ScfProgressSegment* pSegment );
    /** Increases mnTotalPos and calls the system progress bar. */
    void                        IncreaseProgressBar( sal_uInt32 nDelta );
};

// ============================================================================

/** A simplified progress bar with only one segment. */
class ScfSimpleProgressBar
{
private:
    ScfProgressBar              maProgress;     /// The used progress bar.

public:
    explicit                    ScfSimpleProgressBar( sal_uInt32 nSize, SfxObjectShell* pDocShell, const String& rText );
    explicit                    ScfSimpleProgressBar( sal_uInt32 nSize, SfxObjectShell* pDocShell, sal_uInt16 nResId );

    /** Set progress bar to the specified position. */
    inline void                 Progress( sal_uInt32 nPos ) { maProgress.Progress( nPos ); }
    /** Increase progress bar by 1. */
    inline void                 Progress() { maProgress.Progress(); }

private:
    /** Initializes and starts the progress bar. */
    void                        Init( sal_uInt32 nSize );
};

// ============================================================================

/** A simplified progress bar based on the stream position of an existing stream. */
class ScfStreamProgressBar
{
private:
    typedef ::std::auto_ptr< ScfSimpleProgressBar > ScfSimpleProgressBarPtr;

    ScfSimpleProgressBarPtr     mpProgress;     /// The used progress bar.
    SvStream&                   mrStrm;         /// The used stream.

public:
    explicit                    ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, const String& rText );
    explicit                    ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, sal_uInt16 nResId = STR_LOAD_DOC );

    /** Sets the progress bar to the current stream position. */
    void                        Progress();

private:
    /** Initializes and starts the progress bar. */
    void                        Init( SfxObjectShell* pDocShell, const String& rText );
};

// ============================================================================

#endif

<commit_msg>INTEGRATION: CWS dr20 (1.3.320); FILE MERGED 2004/08/11 10:43:50 dr 1.3.320.3: #i12577# #i16277# #i24129# #i31482# #i24672# #i27407# #i30411# rework of cell table export - default row/column formats and shared formulas 2004/06/17 14:58:10 dr 1.3.320.2: #i27407# handle limit of SfxProgress (ULONG_MAX/100) 2004/06/15 16:40:26 dr 1.3.320.1: #i30205# Excel filter code cleanup - rowlimit changes: SCCOL/SCROW/SCTAB usage - type correctness: USHORT vs. sal_uInt16, ULONG/size_t vs. sal_uInt32 - removed compiler warnings<commit_after>/*************************************************************************
 *
 *  $RCSfile: fprogressbar.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2004-09-08 15:43:00 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_FPROGRESSBAR_HXX
#define SC_FPROGRESSBAR_HXX

#include "globstr.hrc"

#ifndef SC_FTOOLS_HXX
#include "ftools.hxx"
#endif

class SfxObjectShell;
class ScProgress;

// ============================================================================

const sal_Int32 SCF_INV_SEGMENT = -1;

// ============================================================================

/** Progress bar for complex progress representation.

    The progress bar contains one or more segments, each with customable
    size. Each segment is represented by a unique identifier. While showing the
    progress bar, several segments can be started simultaneously. The progress
    bar displays the sum of all started segments on screen.

    It is possible to create a full featured ScfProgressBar object from
    any segment. This sub progress bar works only on that parent segment, with
    the effect, that if the sub progress bar reaches 100%, the parent segment is
    filled completely.

    After adding segments, the progress bar has to be activated. In this step the
    total size of all segments is calculated. Therefore it is not possible to add
    more segments from here.

    If a sub progress bar is created from a segment, and the main progress bar
    has been started (but not the sub progress bar), it is still possible to add
    segments to the sub progress bar. It is not allowed to get the sub progress bar
    of a started segment. And it is not allowed to modify the segment containing
    a sub progress bar directly.

    Following a few code examples, how to use the progress bar.

    Example 1: Simple progress bar (see also ScfSimpleProgressBar below).

        ScfProgressBar aProgress( ... );
        sal_Int32 nSeg = aProgress.AddSegment( 50 );        // segment with 50 steps (1 step = 2%)

        aProgress.ActivateSegment( nSeg );                  // start segment nSeg
        aProgress.Progress();                               // 0->1; display: 2%
        aProgress.Progress( 9 );                            // 1->9; display: 18%

    Example 2: Progress bar with 2 segments.

        ScfProgressBar aProgress( ... );
        sal_Int32 nSeg1 = aProgress.AddSegment( 70 );       // segment with 70 steps
        sal_Int32 nSeg2 = aProgress.AddSegment( 30 );       // segment with 30 steps
                                                            // both segments: 100 steps (1 step = 1%)

        aProgress.ActivateSegment( nSeg1 );                 // start first segment
        aProgress.Progress();                               // 0->1, display: 1%
        aProgress.Progress( 3 );                            // 1->3, display: 3%
        aProgress.ActivateSegment( nSeg2 );                 // start second segment
        aProgress.Progress( 5 );                            // 0->5, display: 8% (5+3 steps)
        aProgress.ActivateSegment( nSeg1 );                 // continue with first segment
        aProgress.Progress();                               // 3->4, display: 9% (5+4 steps)

    Example 3: Progress bar with 2 segments, one contains a sub progress bar.

        ScfProgressBar aProgress( ... );
        sal_Int32 nSeg1 = aProgress.AddSegment( 75 );       // segment with 75 steps
        sal_Int32 nSeg2 = aProgress.AddSegment( 25 );       // segment with 25 steps
                                                            // both segments: 100 steps (1 step = 1%)

        aProgress.ActivateSegment( nSeg1 );                 // start first segment
        aProgress.Progress();                               // 0->1, display: 1%

        ScfProgressBar& rSubProgress = aProgress.GetSegmentProgressBar( nSeg2 );
                                                            // sub progress bar from second segment
        sal_Int32 nSubSeg = rSubProgress.AddSegment( 5 );   // 5 steps, mapped to second segment
                                                            // => 1 step = 5 steps in parent = 5%

        rSubProgress.ActivateSegment( nSubSeg );            // start the segment (auto activate parent segment)
        rSubProgress.Progress();                            // 0->1 (0->5 in parent); display: 6% (1+5)

        // not allowed (second segment active):   aProgress.Progress();
        // not allowed (first segment not empty): aProgress.GetSegmentProgressBar( nSeg1 );
 */
class ScfProgressBar : ScfNoCopy
{
public:
    explicit            ScfProgressBar( SfxObjectShell* pDocShell, const String& rText );
    explicit            ScfProgressBar( SfxObjectShell* pDocShell, USHORT nResId );
    virtual             ~ScfProgressBar();

    /** Adds a new segment to the progress bar.
        @return  the identifier of the segment. */
    sal_Int32           AddSegment( sal_uInt32 nSize );
    /** Returns a complete progress bar for the specified segment.
        @descr  The progress bar can be used to create sub segments inside of the
        segment. Do not delete it (done by root progress bar)!
        @return  A reference to an ScfProgressBar connected to the segment. */
    ScfProgressBar&     GetSegmentProgressBar( sal_Int32 nSegment );

    /** Returns true, if any progress segment has been started. */
    inline bool         IsStarted() const { return mbInProgress; }
    /** Returns true, if the current progress segment is already full. */
    bool                IsFull() const;

    /** Starts the progress bar or activates another segment. */
    void                ActivateSegment( sal_Int32 nSegment );
    /** Starts the progress bar (with first segment). */
    inline void         Activate() { ActivateSegment( 0 ); }
    /** Set current segment to the specified position. */
    void                Progress( sal_uInt32 nPos );
    /** Increase current segment by 1. */
    void                Progress();

private:
    struct ScfProgressSegment;

    /** Used to create sub progress bars. */
    explicit            ScfProgressBar(
                            ScfProgressBar& rParProgress,
                            ScfProgressSegment* pParSegment );

    /** Initializes all members on construction. */
    void                Init( SfxObjectShell* pDocShell );

    /** Returns the segment specified by list index. */
    ScfProgressSegment* GetSegment( sal_Int32 nSegment ) const;
    /** Activates progress bar and sets current segment. */
    void                SetCurrSegment( ScfProgressSegment* pSegment );
    /** Increases mnTotalPos and calls the system progress bar. */
    void                IncreaseProgressBar( sal_uInt32 nDelta );

private:
    /** Contains all data of a segment of the progress bar. */
    struct ScfProgressSegment
    {
        typedef ::std::auto_ptr< ScfProgressBar > ScfProgressBarPtr;

        ScfProgressBarPtr   mxProgress;     /// Pointer to sub progress bar for this segment.
        sal_uInt32          mnSize;         /// Size of this segment.
        sal_uInt32          mnPos;          /// Current position of this segment.

        explicit            ScfProgressSegment( sal_uInt32 nSize );
                            ~ScfProgressSegment();
    };

    typedef ::std::auto_ptr< ScProgress >       ScProgressPtr;
    typedef ScfDelList< ScfProgressSegment >    ScfSegmentList;

    ScfSegmentList      maSegments;         /// List of progress segments.
    String              maText;             /// UI string for system progress.

    ScProgressPtr       mxSysProgress;      /// System progress bar.
    SfxObjectShell*     mpDocShell;         /// The document shell for the progress bar.
    ScfProgressBar*     mpParentProgress;   /// Parent progress bar, if this is a segment progress bar.
    ScfProgressSegment* mpParentSegment;    /// Parent segment, if this is a segment progress bar.
    ScfProgressSegment* mpCurrSegment;      /// Current segment for progress.

    sal_uInt32          mnTotalSize;        /// Total size of all segments.
    sal_uInt32          mnTotalPos;         /// Sum of positions of all segments.
    sal_uInt32          mnUnitSize;         /// Size between two calls of system progress.
    sal_uInt32          mnNextUnitPos;      /// Limit for next system progress call.
    sal_uInt32          mnSysProgressScale; /// Additionally scaling factor for system progress.
    bool                mbInProgress;       /// true = progress bar started.
};

// ============================================================================

/** A simplified progress bar with only one segment. */
class ScfSimpleProgressBar
{
public:
    explicit            ScfSimpleProgressBar( sal_uInt32 nSize, SfxObjectShell* pDocShell, const String& rText );
    explicit            ScfSimpleProgressBar( sal_uInt32 nSize, SfxObjectShell* pDocShell, USHORT nResId );

    /** Set progress bar to the specified position. */
    inline void         Progress( sal_uInt32 nPos ) { maProgress.Progress( nPos ); }
    /** Increase progress bar by 1. */
    inline void         Progress() { maProgress.Progress(); }

private:
    /** Initializes and starts the progress bar. */
    void                Init( sal_uInt32 nSize );

private:
    ScfProgressBar      maProgress;     /// The used progress bar.
};

// ============================================================================

/** A simplified progress bar based on the stream position of an existing stream. */
class ScfStreamProgressBar
{
public:
    explicit            ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, const String& rText );
    explicit            ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, USHORT nResId = STR_LOAD_DOC );

    /** Sets the progress bar to the current stream position. */
    void                Progress();

private:
    /** Initializes and starts the progress bar. */
    void                Init( SfxObjectShell* pDocShell, const String& rText );

private:
    typedef ::std::auto_ptr< ScfSimpleProgressBar > ScfSimpleProgressBarPtr;

    ScfSimpleProgressBarPtr mxProgress; /// The used progress bar.
    SvStream&           mrStrm;         /// The used stream.
};

// ============================================================================

#endif

<|endoftext|>


<commit_before>#ifndef _LIBYAML_HPP_
#define _LIBYAML_HPP_

#include <yaml.h>
#include <c4/yml/yml.hpp>

#include <stdexcept>

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

namespace c4 {
namespace yml {

namespace detail {
class Event;
} // detail

class detail::Event
{
public:
    yaml_event_t m_event;
public:
    Event() {}
    ~Event()
    {
        yaml_event_delete(&m_event);
    }
};

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

class LibyamlParser
{
public:

    yaml_parser_t m_parser;

    const char *  m_input;
    size_t        m_length;

    NodeData *    m_load_root;

private:

    cspan get_scalar_val(detail::Event const &ev) const
    {
        // the memory in data.scalar is allocated anew, so don't do this
        //auto const& scalar = e.m_event.data.scalar;
        //cspan val((const char*)scalar.value, scalar.length);
        //return val;
        // ... but the event tells us where in the string the value is
        auto const& e = ev.m_event;
        size_t len = e.end_mark.index - e.start_mark.index;
        cspan val(m_input + e.start_mark.index, len);
        return val;
    }

public:

    LibyamlParser()
    {
        memset(this, 0, sizeof(*this));
        yaml_parser_initialize(&m_parser);
    }

    ~LibyamlParser()
    {
        yaml_parser_delete(&m_parser);
        memset(&m_parser, 0, sizeof(decltype(m_parser)));
    }

    template< size_t N >
    void parse(/*Tree *s, */const char (&input)[N])
    {
        parse(/*s, */&input[0], N-1);
    }

    void parse(/*Tree *s, */const cspan sp)
    {
        parse(/*s, */sp.str, sp.len);
    }
    void parse(/*Tree *s, */const char* input, size_t length)
    {
        m_input = input;
        m_length = length;
        yaml_parser_set_input_string(&m_parser, (const unsigned char*)input, length);
        _do_parse(/*s*/);
    }

    void _do_parse(/*Tree *s*/)
    {
        bool done = false;
        //bool doc_had_scalars = false;
        //cspan prev_scalar;
        while( ! done)
        {
            detail::Event ev;
            if( ! yaml_parser_parse(&m_parser, &ev.m_event))
            {
                _handle_error();
                break;
            }

#define _c4_handle_case(_ev)                            \
case YAML_ ## _ev ## _EVENT:                            \
    printf(#_ev " val=%.*s\n",                          \
           /*(int)prev_scalar.len, prev_scalar.str,*/   \
           (int)val.len, val.str);

            cspan val = get_scalar_val(ev);
            switch(ev.m_event.type)
            {

            _c4_handle_case(MAPPING_START)
                /*if(( ! s->stack_top_is_type(DOC) || doc_had_scalars)
                   &&
                   ( ! m_load_root))
                {
                    C4_ASSERT( ! prev_scalar.empty());
                    s->begin_map(prev_scalar, s->top_last());
                    prev_scalar.clear();
                }
                */
                break;
            _c4_handle_case(MAPPING_END)
                /*if( ! s->stack_top_is_type(DOC) && ! m_load_root)
                {
                    s->end_map();
                }*/
                break;

            _c4_handle_case(SEQUENCE_START)
                //s->begin_seq(prev_scalar, s->top_last());
                break;
            _c4_handle_case(SEQUENCE_END)
                //s->end_seq();
                break;

            _c4_handle_case(SCALAR)
                /*if(s->stack_top_is_type(SEQ))
                {
                    s->add_val({}, val, s->top_last());
                    prev_scalar.clear();
                }
                else
                {
                    if( ! prev_scalar.empty())
                    {
                        s->add_val(prev_scalar, val, s->top_last());
                        prev_scalar.clear();
                    }
                    else
                    {
                        prev_scalar = val;
                    }
                }
                doc_had_scalars = true;
                */
                break;

            _c4_handle_case(DOCUMENT_START)
                /*if( ! m_load_root)
                {
                    s->begin_doc(s->top_last());
                    doc_had_scalars = false;
                }*/
                break;
            _c4_handle_case(DOCUMENT_END)
                /*if( ! m_load_root)
                {
                    s->end_doc();
                }*/
                break;

            _c4_handle_case(STREAM_START)
                //s->begin_stream();
                break;
            _c4_handle_case(STREAM_END)
                //s->end_stream();
                done = true;
                break;

            _c4_handle_case(ALIAS)
                //C4_ASSERT(false && "YAML_ALIAS_EVENT not implemented");
                break;
#undef _c4_handle_case
            default:
                break;
            };
        }
    }

    void _handle_error()
    {
        Location problem_loc, context_loc;
        if(m_parser.problem)
        {
            auto const& m = m_parser.problem_mark;
            problem_loc = Location(m_parser.problem, m.index, m.line+1, m.column+1);
        }
        if(m_parser.context)
        {
            auto const& m = m_parser.context_mark;
            context_loc = Location(m_parser.context, m.index, m.line+1, m.column+1);
        }

        switch(m_parser.error)
        {

        case YAML_MEMORY_ERROR:
            error("Memory error: Not enough memory for parsing");
            break;

        case YAML_READER_ERROR:
            if (m_parser.problem_value != -1)
            {
                char buf[32];
                int ret = snprintf(buf, sizeof(buf), "Reader error: #%X", m_parser.problem_value);
                error(buf, ret, &problem_loc);
            }
            else
            {
                error("Reader error", &problem_loc);
            }
            break;

        case YAML_SCANNER_ERROR:
            error("Scanner error", &context_loc, &problem_loc);
            break;

        case YAML_PARSER_ERROR:
            error("Parser error", &context_loc, &problem_loc);
            break;

        default:
            /* Couldn't happen. */
            error("Internal error");
            break;
        };
    }

    static void error(const char* msg, size_t length, Location *loc1 = nullptr, Location *loc2 = nullptr)
    {
        fprintf(stderr, "%.*s\n", (int)length, msg);
        if(loc1 && *loc1)
        {
            fprintf(stderr, "    : %s at %zd:%zd (offset %zd)\n", loc1->name, loc1->line, loc1->col, loc1->offset);
        }
        if(loc2 && *loc2)
        {
            fprintf(stderr, "    : %s at %zd:%zd (offset %zd)\n", loc2->name, loc1->line, loc2->col, loc2->offset);
        }
        throw std::runtime_error({msg, length});
    }
    template< size_t N >
    static void error(char const (&msg)[N], Location *loc1 = nullptr, Location *loc2 = nullptr)
    {
        error(&msg[0], N-1, loc1, loc2);
    }

};

} // namespace yml
} // namespace c4

#endif // _LIBYAML_HPP_
<commit_msg>reduce test verbosity<commit_after>#ifndef _LIBYAML_HPP_
#define _LIBYAML_HPP_

#include <yaml.h>
#include <c4/yml/yml.hpp>

#include <stdexcept>

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

namespace c4 {
namespace yml {

namespace detail {
class Event;
} // detail

class detail::Event
{
public:
    yaml_event_t m_event;
public:
    Event() {}
    ~Event()
    {
        yaml_event_delete(&m_event);
    }
};

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

class LibyamlParser
{
public:

    yaml_parser_t m_parser;

    const char *  m_input;
    size_t        m_length;

    NodeData *    m_load_root;

private:

    cspan get_scalar_val(detail::Event const &ev) const
    {
        // the memory in data.scalar is allocated anew, so don't do this
        //auto const& scalar = e.m_event.data.scalar;
        //cspan val((const char*)scalar.value, scalar.length);
        //return val;
        // ... but the event tells us where in the string the value is
        auto const& e = ev.m_event;
        size_t len = e.end_mark.index - e.start_mark.index;
        cspan val(m_input + e.start_mark.index, len);
        return val;
    }

public:

    LibyamlParser()
    {
        memset(this, 0, sizeof(*this));
        yaml_parser_initialize(&m_parser);
    }

    ~LibyamlParser()
    {
        yaml_parser_delete(&m_parser);
        memset(&m_parser, 0, sizeof(decltype(m_parser)));
    }

    template< size_t N >
    void parse(/*Tree *s, */const char (&input)[N])
    {
        parse(/*s, */&input[0], N-1);
    }

    void parse(/*Tree *s, */const cspan sp)
    {
        parse(/*s, */sp.str, sp.len);
    }
    void parse(/*Tree *s, */const char* input, size_t length)
    {
        m_input = input;
        m_length = length;
        yaml_parser_set_input_string(&m_parser, (const unsigned char*)input, length);
        _do_parse(/*s*/);
    }

    void _do_parse(/*Tree *s*/)
    {
        bool done = false;
        //bool doc_had_scalars = false;
        //cspan prev_scalar;
        while( ! done)
        {
            detail::Event ev;
            if( ! yaml_parser_parse(&m_parser, &ev.m_event))
            {
                _handle_error();
                break;
            }

#ifdef RYML_DBG
#define _c4_handle_case(_ev)                            \
case YAML_ ## _ev ## _EVENT:                            \
    printf(#_ev " val=%.*s\n",                          \
           /*(int)prev_scalar.len, prev_scalar.str,*/   \
           (int)val.len, val.str);
#else
#define _c4_handle_case(_ev)                            \
case YAML_ ## _ev ## _EVENT:                            \
    (void)val;
#endif

            cspan val = get_scalar_val(ev);
            switch(ev.m_event.type)
            {

            _c4_handle_case(MAPPING_START)
                /*if(( ! s->stack_top_is_type(DOC) || doc_had_scalars)
                   &&
                   ( ! m_load_root))
                {
                    C4_ASSERT( ! prev_scalar.empty());
                    s->begin_map(prev_scalar, s->top_last());
                    prev_scalar.clear();
                }
                */
                break;
            _c4_handle_case(MAPPING_END)
                /*if( ! s->stack_top_is_type(DOC) && ! m_load_root)
                {
                    s->end_map();
                }*/
                break;

            _c4_handle_case(SEQUENCE_START)
                //s->begin_seq(prev_scalar, s->top_last());
                break;
            _c4_handle_case(SEQUENCE_END)
                //s->end_seq();
                break;

            _c4_handle_case(SCALAR)
                /*if(s->stack_top_is_type(SEQ))
                {
                    s->add_val({}, val, s->top_last());
                    prev_scalar.clear();
                }
                else
                {
                    if( ! prev_scalar.empty())
                    {
                        s->add_val(prev_scalar, val, s->top_last());
                        prev_scalar.clear();
                    }
                    else
                    {
                        prev_scalar = val;
                    }
                }
                doc_had_scalars = true;
                */
                break;

            _c4_handle_case(DOCUMENT_START)
                /*if( ! m_load_root)
                {
                    s->begin_doc(s->top_last());
                    doc_had_scalars = false;
                }*/
                break;
            _c4_handle_case(DOCUMENT_END)
                /*if( ! m_load_root)
                {
                    s->end_doc();
                }*/
                break;

            _c4_handle_case(STREAM_START)
                //s->begin_stream();
                break;
            _c4_handle_case(STREAM_END)
                //s->end_stream();
                done = true;
                break;

            _c4_handle_case(ALIAS)
                //C4_ASSERT(false && "YAML_ALIAS_EVENT not implemented");
                break;
#undef _c4_handle_case
            default:
                break;
            };
        }
    }

    void _handle_error()
    {
        Location problem_loc, context_loc;
        if(m_parser.problem)
        {
            auto const& m = m_parser.problem_mark;
            problem_loc = Location(m_parser.problem, m.index, m.line+1, m.column+1);
        }
        if(m_parser.context)
        {
            auto const& m = m_parser.context_mark;
            context_loc = Location(m_parser.context, m.index, m.line+1, m.column+1);
        }

        switch(m_parser.error)
        {

        case YAML_MEMORY_ERROR:
            error("Memory error: Not enough memory for parsing");
            break;

        case YAML_READER_ERROR:
            if (m_parser.problem_value != -1)
            {
                char buf[32];
                int ret = snprintf(buf, sizeof(buf), "Reader error: #%X", m_parser.problem_value);
                error(buf, ret, &problem_loc);
            }
            else
            {
                error("Reader error", &problem_loc);
            }
            break;

        case YAML_SCANNER_ERROR:
            error("Scanner error", &context_loc, &problem_loc);
            break;

        case YAML_PARSER_ERROR:
            error("Parser error", &context_loc, &problem_loc);
            break;

        default:
            /* Couldn't happen. */
            error("Internal error");
            break;
        };
    }

    static void error(const char* msg, size_t length, Location *loc1 = nullptr, Location *loc2 = nullptr)
    {
        fprintf(stderr, "%.*s\n", (int)length, msg);
        if(loc1 && *loc1)
        {
            fprintf(stderr, "    : %s at %zd:%zd (offset %zd)\n", loc1->name, loc1->line, loc1->col, loc1->offset);
        }
        if(loc2 && *loc2)
        {
            fprintf(stderr, "    : %s at %zd:%zd (offset %zd)\n", loc2->name, loc1->line, loc2->col, loc2->offset);
        }
        throw std::runtime_error({msg, length});
    }
    template< size_t N >
    static void error(char const (&msg)[N], Location *loc1 = nullptr, Location *loc2 = nullptr)
    {
        error(&msg[0], N-1, loc1, loc2);
    }

};

} // namespace yml
} // namespace c4

#endif // _LIBYAML_HPP_
<|endoftext|>


<commit_before>/*
 * mf_test.cpp
 *
 *  Created on: Aug 7, 2011
 *      Author: gmueller
 */

#include "gadget/MagneticField.hpp"
#include "gadget/SmoothParticle.hpp"

#include <memory>
#include <limits>
#include <stdexcept>

class AbstractTest {
protected:
	std::vector<SmoothParticle> particles;
	std::auto_ptr<DirectMagneticField> dmf;
	std::auto_ptr<SampledMagneticField> smf;
	std::vector<std::pair<Vector3f, float> > positions;
public:

	virtual void setup() = 0;

	void run() {
		for (size_t i = 0; i < positions.size(); i++)
			testPosition(positions[i].first, positions[i].second);
	}

	void testPosition(const Vector3f &position, float expected_error =
			std::numeric_limits<float>::epsilon()) {
		Vector3f df = dmf->getField(position);
		Vector3f sf = smf->getField(position);
		float error = (df - sf).length();
		std::cout << "Direct: " << df << ", Sampled: " << sf << ", Error: "
				<< error << std::endl;
		if (error > expected_error)
			throw std::runtime_error("unexpected deviation!");
	}

	void addPosition(const Vector3f &position, float expected_error =
			std::numeric_limits<float>::epsilon()) {
		positions.push_back(std::make_pair(position, expected_error));
	}
};

class SimpleTest: public AbstractTest {
public:

	void setup() {
		particles.resize(1);
		particles[0].bfield = Vector3f(0, 1, 0);
		particles[0].position = Vector3f(120000, 120000, 120000);
		particles[0].smoothingLength = 10000;
		particles[0].mass = 1;

		SmoothParticleHelper::updateRho(particles);

		Vector3f origin(100000, 100000, 100000);
		float size(40000);

		dmf.reset(new DirectMagneticField(origin, size));
		dmf->init(100);
		dmf->load(particles);

		smf.reset(new SampledMagneticField(origin, size));
		smf->init(500);
		smf->load(particles);

		addPosition(Vector3f(120000, 120000, 120000));
		addPosition(Vector3f(120500, 120500, 120500));
		addPosition(Vector3f(120550, 120550, 120550), 0.01);
	}

};

int main() {
	SimpleTest stest;
	stest.setup();
	stest.run();
}
<commit_msg>improve mf_test, use coma radial profile<commit_after>/*
 * mf_test.cpp
 *
 *  Created on: Aug 7, 2011
 *      Author: gmueller
 */

#include "gadget/MagneticField.hpp"
#include "gadget/SmoothParticle.hpp"

#include <memory>
#include <limits>
#include <stdexcept>

class AbstractTest {
public:
	struct TestPoint {
		TestPoint() :
				position(Vector3f(0, 0, 0)), value(Vector3f(0, 0, 0)), error(
						std::numeric_limits<float>::epsilon()) {

		}
		TestPoint(Vector3f position, Vector3f value, float error =
				std::numeric_limits<float>::epsilon()) :
				position(position), value(value), error(error) {

		}
		Vector3f position;
		Vector3f value;
		float error;
	};
protected:
	std::vector<SmoothParticle> particles;
	std::auto_ptr<DirectMagneticField> dmf;
	std::auto_ptr<SampledMagneticField> smf;
	std::vector<TestPoint> testPoints;
public:

	virtual void setup() = 0;

	void runTestPoints() {
		std::cout << ">> test points: " << testPoints.size() << std::endl;
		for (size_t i = 0; i < testPoints.size(); i++)
			test(testPoints[i]);
		std::cout << ">> done" << std::endl;
	}

	void runSweep(const Vector3f &from, const Vector3f &to, float stepSize,
			float allowedError) {
		std::cout << ">> Sweep from " << from << " to " << to << ", Step: "
				<< stepSize << std::endl;
		float length = (from - to).length();
		size_t steps = length / stepSize;
		Vector3f step = (to - from) * stepSize / length;
		Vector3f position = from;
		float minError = std::numeric_limits<float>::max();
		float maxError = std::numeric_limits<float>::min();
		for (size_t i = 0; i < steps; i++) {
			position += step;
			Vector3f df = dmf->getField(position);
			Vector3f sf = smf->getField(position);
			std::cout << "   -> " << df.length() << std::endl;
			float error = (df - sf).length();
			minError = std::min(error, minError);
			maxError = std::max(error, maxError);
			if (error > allowedError)
				throw std::runtime_error("unexpected deviation!");
		}
		std::cout << "   min error: " << minError << std::endl;
		std::cout << "   max error: " << maxError << std::endl;
		std::cout << "   average total: "
				<< dmf->getStatistics().getAverageTotal() << std::endl;
		std::cout << "   average actual: "
				<< dmf->getStatistics().getAverageActual() << std::endl;
		std::cout << ">> done" << std::endl;
	}

	void test(const TestPoint &testPoint) {
		std::cout << "   TestPoint: " << testPoint.position << " -> "
				<< testPoint.value << ", +- " << testPoint.error << std::endl;

		Vector3f df = dmf->getField(testPoint.position);
		float dfError = (df - testPoint.value).length();
		std::cout << "    - Direct: " << df << ", Error: " << dfError
				<< std::endl;

		Vector3f sf = smf->getField(testPoint.position);
		float sfError = (sf - testPoint.value).length();
		std::cout << "    - Samples: " << sf << ", Error: " << sfError
				<< std::endl;

		if (dfError > testPoint.error || sfError > testPoint.error)
			throw std::runtime_error("unexpected deviation!");
	}

	void getAverageFieldOnSphere(const Vector3f &center, float radius,
			float &avgDirect, float &avgSampled) {
		avgDirect = 0;
		avgSampled = 0;
		size_t count = 0;
		float phi = 0;
		while (phi < 360) {
			float theta = -90;
			while (theta <= 90) {
				theta += 10;
				Vector3f position = center;
				try {
					position.x += radius * sin(phi) * cos(theta);
					position.y += radius * cos(phi) * cos(theta);
					position.z += radius * sin(theta);
					avgDirect += dmf->getField(position).length();
					avgSampled += smf->getField(position).length();
					count++;
				} catch (...) {

				}
			}
			phi += 10;
		}

		avgDirect /= count;
		avgSampled /= count;
	}

	void runHaloTest(const Vector3f &center, float radius) {
		std::cout << ">> Halo Test around " << center << ", R_v: " << radius
				<< std::endl;
		std::cout << "  -     direct    sampled" << std::endl;
		for (size_t i = 0; i < 51; i++) {
			float r = (radius / 50) * i;
			float avgDirect, avgSampled;
			getAverageFieldOnSphere(center, r, avgDirect, avgSampled);
			std::cout << r/radius << " " << avgDirect << " " << avgSampled
					<< std::endl;
		}
	}
};

class SimpleTest: public AbstractTest {
public:

	void setup() {
		particles.resize(1);
		particles[0].bfield = Vector3f(0, 1, 0);
		particles[0].position = Vector3f(120000, 120000, 120000);
		particles[0].smoothingLength = 10000;
		particles[0].mass = 1;

		SmoothParticleHelper::updateRho(particles);

		Vector3f origin(100000, 100000, 100000);
		float size(40000);

		dmf.reset(new DirectMagneticField(origin, size));
		dmf->init(100);
		dmf->load(particles);

		smf.reset(new SampledMagneticField(origin, size));
		smf->init(500);
		smf->load(particles);

		testPoints.push_back(
				TestPoint(Vector3f(120000, 120000, 120000), Vector3f(0, 1, 0)));
		testPoints.push_back(
				TestPoint(Vector3f(120500, 120500, 120500),
						Vector3f(0, 0.958897, 0)));
		testPoints.push_back(
				TestPoint(Vector3f(120550, 120550, 120550),
						Vector3f(0, 0.950737, 0), 0.01));
	}

};

// Coma
// 11   411121   214459 7.570E+14 6.634E+14 1885.23     119.8023  190.8159  129.1431  -361.72   566.41  -315.91  949.39
Vector3f ComaPosition(119717, 221164, 133061);

class HaloTest: public AbstractTest {
public:

	void setup() {
		SmoothParticleHelper::read("test/mhd_z-5-11-6.raw", particles);

		Vector3f origin(99000, 219000, 119000);
		float size(22000);

		dmf.reset(new DirectMagneticField(origin, size));
		dmf->init(50);
		dmf->load(particles);

		smf.reset(new SampledMagneticField(origin, size));
		smf->init(100);
		smf->load(particles);

		testPoints.push_back(
				TestPoint(ComaPosition,
						Vector3f(-1.60984e-09, -3.48952e-10, 1.00858e-09), 1));
	}

};

int main() {
	SimpleTest stest;
	stest.setup();
	stest.runTestPoints();
	stest.runSweep(Vector3f(120000, 120000, 120000),
			Vector3f(120000, 110000, 120000), 10, 0.01);

	HaloTest htest;
	htest.setup();
	htest.runTestPoints();
	htest.runSweep(ComaPosition, ComaPosition + Vector3f(-1000, 1000, 500), 10,
			0.01);
	htest.runHaloTest(ComaPosition, 2700);
}
<|endoftext|>