<commit_before>#include "vvvclanghelper.hpp"

using namespace clang;

std::string getComment(Decl* d)
{
    ASTContext& ctx = d->getASTContext();
    const RawComment* rc = ctx.getRawCommentForDeclNoCache(d);
    if(rc)
        return rc->getBriefText(ctx);
    return "";
}

std::string decl2str(const clang::Decl* d, const clang::ASTContext& context )
{
    using namespace clang;
    const auto& sm = context.getSourceManager();
    const SourceLocation  b(d->getLocStart()),
                         _e(d->getLocEnd());
    const SourceLocation  e(Lexer::getLocForEndOfToken(_e, 0, sm,
                                                       context.getLangOpts()));
    return std::string(sm.getCharacterData(b),
                       sm.getCharacterData(e) - sm.getCharacterData(b));
}

std::string decl2str(const clang::Stmt* d, const clang::ASTContext& context )
{
    using namespace clang;
    const auto& sm = context.getSourceManager();
    const SourceLocation  b(d->getLocStart()),
                         _e(d->getLocEnd());
    const SourceLocation  e(Lexer::getLocForEndOfToken(_e, 0, sm,
                                                       context.getLangOpts()));
    return std::string(sm.getCharacterData(b),
                       sm.getCharacterData(e) - sm.getCharacterData(b));
}

bool isSystemDecl(const Decl* d)
{
    return d->getASTContext().getSourceManager().
                                            isInSystemHeader(d->getLocStart());
}

std::vector<const Decl*> getDeclarations(const ASTContext& context)
{
    std::vector<const Decl*> ret;
    const auto  tu = context.getTranslationUnitDecl();
    const auto  begin = tu->decls_begin();
    const auto  end = tu->decls_end();
    for(auto i = begin; i != end; ++i)
        ret.push_back( *i );
    return ret;
}

 std::vector<const Decl*> getNonSystemDeclarations(const ASTContext& context)
{
    const auto decls = getDeclarations( context );
    return filter( decls, [](const Decl* d)
            { return !d->getASTContext().getSourceManager()
                      .isInSystemHeader(d->getLocStart()); });
}

std::vector<const Decl*> getMainFileDeclarations(const ASTContext& context)
{
    const auto decls = getDeclarations( context );
    return filter( decls, [](const Decl* d)
            { return d->getASTContext().getSourceManager()
                     .isInMainFile(d->getLocStart()); });
}

std::vector<const FunctionDecl*>
filterFunctions(const std::vector<const Decl*>& decls)
{
    std::vector<const FunctionDecl*> ret;
    std::for_each(decls.begin(), decls.end(), [&ret](const Decl* d) {
                if( d->isFunctionOrFunctionTemplate() )
                    ret.push_back( dynamic_cast<const FunctionDecl*>(d) ); });
    return ret;
}

std::vector<const RecordDecl*>
filterStructs(const std::vector<const Decl*>& decls)
{
    std::vector<const RecordDecl*> ret;
    const auto fd  = filter(decls, [](const Decl* d)
                                   { return d->getKind() ==
                                            clang::Decl::Kind::Record; });
    for(const auto& d: fd)
        ret.push_back( dynamic_cast<const RecordDecl*>(d) );
    return ret;
}

std::vector<const FieldDecl*> getStructFields(const RecordDecl* r)
{
    std::vector<const FieldDecl*> ret;
    const auto b = r->field_begin();
    const auto e = r->field_end();
    for(auto i = b; i != e; ++i)
        ret.push_back( *i );
    return ret;
}

std::vector<const ParmVarDecl*> getFunctionParams(const FunctionDecl* d)
{
    std::vector<const ParmVarDecl*> ret;
    const auto numParams = d->param_size();
    for(unsigned int i =0; i < numParams; ++i)
        ret.push_back( d->getParamDecl( i ) );
    return ret;
}

void printFunction(const FunctionDecl* d)
{
    using namespace std;
    cout     << "function name: " << d->getNameAsString() << endl
             << "  result type: " << d->getReturnType().getAsString() << endl;
    const auto params = getFunctionParams(d);
    for(auto& p: params)
        cout << "  parameter " << p->getNameAsString() <<
                " of type " << p->getType().getAsString() << endl;

    if(d->hasBody())
        cout << decl2str(d->getBody(), d->getASTContext()) << endl << endl;
}

void printStructure( const CXXRecordDecl* d)
{
    using namespace std;
    cout << d->getNameAsString() << endl;
    const auto fs = getStructFields(d);
    for(const auto& f: fs) {
        const auto name = f->getNameAsString();
        const auto t    = f->getType().getAsString();
        cout << "field: " << name << " of type "<< t << ";" << endl; }
}

std::vector<const Stmt*> getCompoundStmtChildren(const Stmt* s)
{
    std::vector<const Stmt*> ret;
    const auto b = s->child_begin();
    const auto e = s->child_end();
    for(auto i = b; i != e; ++i)
        ret.push_back(*i);
    return ret;
}

char* getSourceFromFile(const char* filename)
{
    std::ifstream f(filename, std::ios::binary);
    f.seekg(0, f.end);
    const size_t fsize = f.tellg();
    f.seekg(0, f.beg);
    char* ret = new char[fsize+1];
    f.read(ret, fsize);
    f.close();
    ret[fsize]=0;
    return ret;
}

<commit_msg>fix segfault on template functions (skip them)<commit_after>#include "vvvclanghelper.hpp"

using namespace clang;

std::string getComment(Decl* d)
{
    ASTContext& ctx = d->getASTContext();
    const RawComment* rc = ctx.getRawCommentForDeclNoCache(d);
    if(rc)
        return rc->getBriefText(ctx);
    return "";
}

std::string decl2str(const clang::Decl* d, const clang::ASTContext& context )
{
    using namespace clang;
    const auto& sm = context.getSourceManager();
    const SourceLocation  b(d->getLocStart()),
                         _e(d->getLocEnd());
    const SourceLocation  e(Lexer::getLocForEndOfToken(_e, 0, sm,
                                                       context.getLangOpts()));
    return std::string(sm.getCharacterData(b),
                       sm.getCharacterData(e) - sm.getCharacterData(b));
}

std::string decl2str(const clang::Stmt* d, const clang::ASTContext& context )
{
    using namespace clang;
    const auto& sm = context.getSourceManager();
    const SourceLocation  b(d->getLocStart()),
                         _e(d->getLocEnd());
    const SourceLocation  e(Lexer::getLocForEndOfToken(_e, 0, sm,
                                                       context.getLangOpts()));
    return std::string(sm.getCharacterData(b),
                       sm.getCharacterData(e) - sm.getCharacterData(b));
}

bool isSystemDecl(const Decl* d)
{
    return d->getASTContext().getSourceManager().
                                            isInSystemHeader(d->getLocStart());
}

std::vector<const Decl*> getDeclarations(const ASTContext& context)
{
    std::vector<const Decl*> ret;
    const auto  tu = context.getTranslationUnitDecl();
    const auto  begin = tu->decls_begin();
    const auto  end = tu->decls_end();
    for(auto i = begin; i != end; ++i)
        ret.push_back( *i );
    return ret;
}

 std::vector<const Decl*> getNonSystemDeclarations(const ASTContext& context)
{
    const auto decls = getDeclarations( context );
    return filter( decls, [](const Decl* d)
            { return !d->getASTContext().getSourceManager()
                      .isInSystemHeader(d->getLocStart()); });
}

std::vector<const Decl*> getMainFileDeclarations(const ASTContext& context)
{
    const auto decls = getDeclarations( context );
    return filter( decls, [](const Decl* d)
            { return d->getASTContext().getSourceManager()
                     .isInMainFile(d->getLocStart()); });
}

std::vector<const FunctionDecl*>
filterFunctions(const std::vector<const Decl*>& decls)
{
    std::vector<const FunctionDecl*> ret;
    std::for_each(decls.begin(), decls.end(), [&ret](const Decl* d) {
                const Decl* tempd = d;
                if( d->isFunctionOrFunctionTemplate() && !d->isTemplateDecl()){
                    const auto funcdecl = dynamic_cast<const FunctionDecl*>(d);
                    ret.push_back(funcdecl);
                }});
    return ret;
}

std::vector<const RecordDecl*>
filterStructs(const std::vector<const Decl*>& decls)
{
    std::vector<const RecordDecl*> ret;
    const auto fd  = filter(decls, [](const Decl* d)
                                   { return d->getKind() ==
                                            clang::Decl::Kind::Record; });
    for(const auto& d: fd)
        ret.push_back( dynamic_cast<const RecordDecl*>(d) );
    return ret;
}

std::vector<const FieldDecl*> getStructFields(const RecordDecl* r)
{
    std::vector<const FieldDecl*> ret;
    const auto b = r->field_begin();
    const auto e = r->field_end();
    for(auto i = b; i != e; ++i)
        ret.push_back( *i );
    return ret;
}

std::vector<const ParmVarDecl*> getFunctionParams(const FunctionDecl* d)
{
    std::vector<const ParmVarDecl*> ret;
    const auto numParams = d->param_size();
    for(unsigned int i =0; i < numParams; ++i)
        ret.push_back( d->getParamDecl( i ) );
    return ret;
}

void printFunction(const FunctionDecl* d)
{
    using namespace std;
    cout     << "function name: " << d->getNameAsString() << endl
             << "  result type: " << d->getReturnType().getAsString() << endl;
    const auto params = getFunctionParams(d);
    for(auto& p: params)
        cout << "  parameter " << p->getNameAsString() <<
                " of type " << p->getType().getAsString() << endl;

    if(d->hasBody())
        cout << decl2str(d->getBody(), d->getASTContext()) << endl << endl;
}

void printStructure( const CXXRecordDecl* d)
{
    using namespace std;
    cout << d->getNameAsString() << endl;
    const auto fs = getStructFields(d);
    for(const auto& f: fs) {
        const auto name = f->getNameAsString();
        const auto t    = f->getType().getAsString();
        cout << "field: " << name << " of type "<< t << ";" << endl; }
}

std::vector<const Stmt*> getCompoundStmtChildren(const Stmt* s)
{
    std::vector<const Stmt*> ret;
    const auto b = s->child_begin();
    const auto e = s->child_end();
    for(auto i = b; i != e; ++i)
        ret.push_back(*i);
    return ret;
}

char* getSourceFromFile(const char* filename)
{
    std::ifstream f(filename, std::ios::binary);
    f.seekg(0, f.end);
    const size_t fsize = f.tellg();
    f.seekg(0, f.beg);
    char* ret = new char[fsize+1];
    f.read(ret, fsize);
    f.close();
    ret[fsize]=0;
    return ret;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ChartController_Position.cxx,v $
 * $Revision: 1.11 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "ChartController.hxx"

#include "macros.hxx"
#include "ChartWindow.hxx"
#include "DrawViewWrapper.hxx"
#include "PositionAndSizeHelper.hxx"
#include "ChartModelHelper.hxx"
#include "UndoGuard.hxx"
#include "Strings.hrc"
#include "ObjectNameProvider.hxx"
#include <svx/ActionDescriptionProvider.hxx>

// header for define RET_OK
#include <vcl/msgbox.hxx>

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#include <svx/svxdlg.hxx>
#ifndef _SVX_DIALOGS_HRC
#include <svx/dialogs.hrc>
#endif
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>

//.............................................................................
namespace chart
{
//.............................................................................
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;

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

void lcl_getPositionAndSizeFromItemSet( const SfxItemSet& rItemSet, Rectangle& rPosAndSize )
{
    long nPosX(0);
    long nPosY(0);
    long nSizX(0);
    long nSizY(0);

    const SfxPoolItem* pPoolItem=NULL;
    //read position
    if (SFX_ITEM_SET==rItemSet.GetItemState(SID_ATTR_TRANSFORM_POS_X,TRUE,&pPoolItem))
        nPosX=((const SfxInt32Item*)pPoolItem)->GetValue();
    if (SFX_ITEM_SET==rItemSet.GetItemState(SID_ATTR_TRANSFORM_POS_Y,TRUE,&pPoolItem))
        nPosY=((const SfxInt32Item*)pPoolItem)->GetValue();
    //read size
    if (SFX_ITEM_SET==rItemSet.GetItemState(SID_ATTR_TRANSFORM_WIDTH,TRUE,&pPoolItem))
        nSizX=((const SfxUInt32Item*)pPoolItem)->GetValue();
    if (SFX_ITEM_SET==rItemSet.GetItemState(SID_ATTR_TRANSFORM_HEIGHT,TRUE,&pPoolItem))
        nSizY=((const SfxUInt32Item*)pPoolItem)->GetValue();

    rPosAndSize = Rectangle(Point(nPosX,nPosY),Size(nSizX,nSizY));
}

void SAL_CALL ChartController::executeDispatch_PositionAndSize()
{
    const ::rtl::OUString aCID( m_aSelection.getSelectedCID() );

    if( !aCID.getLength() )
        return;

    UndoGuard aUndoGuard(
        ActionDescriptionProvider::createDescription(
            ActionDescriptionProvider::POS_SIZE,
            ObjectNameProvider::getName( ObjectIdentifier::getObjectType( aCID ))),
        m_xUndoManager, m_aModel->getModel() );

    SfxAbstractTabDialog * pDlg = NULL;
    try
    {
        SfxItemSet aItemSet = m_pDrawViewWrapper->getPositionAndSizeItemSetFromMarkedObject();

        //prepare and open dialog
        SdrView* pSdrView = m_pDrawViewWrapper;
        bool bResizePossible = m_aSelection.isResizeableObjectSelected();

        ::vos::OGuard aGuard( Application::GetSolarMutex());
        SvxAbstractDialogFactory * pFact = SvxAbstractDialogFactory::Create();
        DBG_ASSERT( pFact, "No dialog factory" );
        pDlg = pFact->CreateSchTransformTabDialog(
            m_pChartWindow, &aItemSet, pSdrView, RID_SCH_TransformTabDLG_SVXPAGE_ANGLE, bResizePossible );
        DBG_ASSERT( pDlg, "Couldn't create SchTransformTabDialog" );

        if( pDlg->Execute() == RET_OK )
        {
            const SfxItemSet* pOutItemSet = pDlg->GetOutputItemSet();
            if(pOutItemSet)
            {
                Rectangle aObjectRect;
                aItemSet.Put(*pOutItemSet);//overwrite old values with new values (-> all items are set)
                lcl_getPositionAndSizeFromItemSet( aItemSet, aObjectRect );
                awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel() ) );
                Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height );

                bool bChanged = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
                            , m_aModel->getModel()
                            , awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight())
                            , awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight())
                            , m_xChartView );
                if( bChanged )
                    aUndoGuard.commitAction();
            }
        }
        delete pDlg;
    }
    catch( uno::Exception& e)
    {
        delete pDlg;
        ASSERT_EXCEPTION( e );
    }
}

//.............................................................................
} //namespace chart
//.............................................................................
<commit_msg>INTEGRATION: CWS chart25 (1.9.86); FILE MERGED 2008/04/24 12:46:31 iha 1.9.86.2: RESYNC: (1.9-1.11); FILE MERGED 2008/03/14 17:01:21 iha 1.9.86.1: #i26490# Base Point for resize does not work correct<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ChartController_Position.cxx,v $
 * $Revision: 1.12 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "ChartController.hxx"

#include "macros.hxx"
#include "ChartWindow.hxx"
#include "DrawViewWrapper.hxx"
#include "PositionAndSizeHelper.hxx"
#include "ChartModelHelper.hxx"
#include "UndoGuard.hxx"
#include "Strings.hrc"
#include "ObjectNameProvider.hxx"
#include "chartview/ExplicitValueProvider.hxx"
#include "CommonConverters.hxx"
#include <svx/ActionDescriptionProvider.hxx>

// header for define RET_OK
#include <vcl/msgbox.hxx>
#include <svx/svxids.hrc>
#include <svx/rectenum.hxx>
#include <svtools/aeitem.hxx>
#include <svx/svxdlg.hxx>
#include <svx/dialogs.hrc>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>

//.............................................................................
namespace chart
{
//.............................................................................
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;

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

void lcl_getPositionAndSizeFromItemSet( const SfxItemSet& rItemSet, Rectangle& rPosAndSize, const awt::Size aOriginalSize )
{
    long nPosX(0);
    long nPosY(0);
    long nSizX(0);
    long nSizY(0);

    RECT_POINT eRP = (RECT_POINT)RP_LT;

    const SfxPoolItem* pPoolItem=NULL;
    //read position
    if (SFX_ITEM_SET==rItemSet.GetItemState(SID_ATTR_TRANSFORM_POS_X,TRUE,&pPoolItem))
        nPosX=((const SfxInt32Item*)pPoolItem)->GetValue();
    if (SFX_ITEM_SET==rItemSet.GetItemState(SID_ATTR_TRANSFORM_POS_Y,TRUE,&pPoolItem))
        nPosY=((const SfxInt32Item*)pPoolItem)->GetValue();
    //read size
    if (SFX_ITEM_SET==rItemSet.GetItemState(SID_ATTR_TRANSFORM_WIDTH,TRUE,&pPoolItem))
        nSizX=((const SfxUInt32Item*)pPoolItem)->GetValue();
    if (SFX_ITEM_SET==rItemSet.GetItemState(SID_ATTR_TRANSFORM_HEIGHT,TRUE,&pPoolItem))
        nSizY=((const SfxUInt32Item*)pPoolItem)->GetValue();
    if (SFX_ITEM_SET==rItemSet.GetItemState(SID_ATTR_TRANSFORM_SIZE_POINT,TRUE,&pPoolItem))
        eRP=(RECT_POINT)((const SfxAllEnumItem*)pPoolItem)->GetValue();

    switch( eRP )
    {
        case RP_LT:
            break;
        case RP_MT:
            nPosX += ( aOriginalSize.Width - nSizX ) / 2;
            break;
        case RP_RT:
            nPosX += aOriginalSize.Width - nSizX;
            break;
        case RP_LM:
            nPosY += ( aOriginalSize.Height - nSizY ) / 2;
            break;
        case RP_MM:
            nPosX += ( aOriginalSize.Width  - nSizX ) / 2;
            nPosY += ( aOriginalSize.Height - nSizY ) / 2;
            break;
        case RP_RM:
            nPosX += aOriginalSize.Width - nSizX;
            nPosY += ( aOriginalSize.Height - nSizY ) / 2;
            break;
        case RP_LB:
            nPosY += aOriginalSize.Height - nSizY;
            break;
        case RP_MB:
            nPosX += ( aOriginalSize.Width - nSizX ) / 2;
            nPosY += aOriginalSize.Height - nSizY;
            break;
        case RP_RB:
            nPosX += aOriginalSize.Width - nSizX;
            nPosY += aOriginalSize.Height - nSizY;
            break;
        default:
            break;
    }

    rPosAndSize = Rectangle(Point(nPosX,nPosY),Size(nSizX,nSizY));
}

void SAL_CALL ChartController::executeDispatch_PositionAndSize()
{
    const ::rtl::OUString aCID( m_aSelection.getSelectedCID() );

    if( !aCID.getLength() )
        return;

    awt::Size aSelectedSize;
    ExplicitValueProvider* pProvider( ExplicitValueProvider::getExplicitValueProvider( m_xChartView ) );
    if( pProvider )
        aSelectedSize = ToSize( ( pProvider->getRectangleOfObject( aCID ) ) );

    UndoGuard aUndoGuard(
        ActionDescriptionProvider::createDescription(
            ActionDescriptionProvider::POS_SIZE,
            ObjectNameProvider::getName( ObjectIdentifier::getObjectType( aCID ))),
        m_xUndoManager, m_aModel->getModel() );

    SfxAbstractTabDialog * pDlg = NULL;
    try
    {
        SfxItemSet aItemSet = m_pDrawViewWrapper->getPositionAndSizeItemSetFromMarkedObject();

        //prepare and open dialog
        SdrView* pSdrView = m_pDrawViewWrapper;
        bool bResizePossible = m_aSelection.isResizeableObjectSelected();

        ::vos::OGuard aGuard( Application::GetSolarMutex());
        SvxAbstractDialogFactory * pFact = SvxAbstractDialogFactory::Create();
        DBG_ASSERT( pFact, "No dialog factory" );
        pDlg = pFact->CreateSchTransformTabDialog(
            m_pChartWindow, &aItemSet, pSdrView, RID_SCH_TransformTabDLG_SVXPAGE_ANGLE, bResizePossible );
        DBG_ASSERT( pDlg, "Couldn't create SchTransformTabDialog" );

        if( pDlg->Execute() == RET_OK )
        {
            const SfxItemSet* pOutItemSet = pDlg->GetOutputItemSet();
            if(pOutItemSet)
            {
                Rectangle aObjectRect;
                aItemSet.Put(*pOutItemSet);//overwrite old values with new values (-> all items are set)
                lcl_getPositionAndSizeFromItemSet( aItemSet, aObjectRect, aSelectedSize );
                awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel() ) );
                Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height );

                bool bChanged = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
                            , m_aModel->getModel()
                            , awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight())
                            , awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight())
                            , m_xChartView );
                if( bChanged )
                    aUndoGuard.commitAction();
            }
        }
        delete pDlg;
    }
    catch( uno::Exception& e)
    {
        delete pDlg;
        ASSERT_EXCEPTION( e );
    }
}

//.............................................................................
} //namespace chart
//.............................................................................
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: StatusBarCommandDispatch.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 18:09:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/
#ifndef CHART2_STATUSBARCOMMANDDISPATCH_HXX
#define CHART2_STATUSBARCOMMANDDISPATCH_HXX

#include "CommandDispatch.hxx"

#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_VIEW_XSELECTIONSUPPLIER_HPP_
#include <com/sun/star/view/XSelectionSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFIABLE_HPP_
#include <com/sun/star/util/XModifiable.hpp>
#endif

namespace chart
{

/** This is a CommandDispatch implementation for all commands the status bar offers

    This class reads the information needed from the XModel passed here.
 */

namespace impl
{
typedef ::cppu::ImplInheritanceHelper1<
        CommandDispatch,
        ::com::sun::star::view::XSelectionChangeListener >
    StatusBarCommandDispatch_Base;
}

class StatusBarCommandDispatch : public impl::StatusBarCommandDispatch_Base
{
public:
    explicit StatusBarCommandDispatch(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > & xContext,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::frame::XModel > & xModel,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::view::XSelectionSupplier > & xSelSupp );
    virtual ~StatusBarCommandDispatch();

    // late initialisation, especially for adding as listener
    virtual void initialize();

protected:
    // ____ XDispatch ____
    virtual void SAL_CALL dispatch(
        const ::com::sun::star::util::URL& URL,
        const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ WeakComponentImplHelperBase ____
    /// is called when this is disposed
    virtual void SAL_CALL disposing();

    // ____ XModifyListener (override from CommandDispatch) ____
    virtual void SAL_CALL modified(
        const ::com::sun::star::lang::EventObject& aEvent )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XEventListener (base of XModifyListener) ____
    virtual void SAL_CALL disposing(
        const ::com::sun::star::lang::EventObject& Source )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void fireStatusEvent(
        const ::rtl::OUString & rURL,
        const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > & xSingleListener );

    // ____ XSelectionChangeListener ____
    virtual void SAL_CALL selectionChanged(
        const ::com::sun::star::lang::EventObject& aEvent )
        throw (::com::sun::star::uno::RuntimeException);

private:
    ::com::sun::star::uno::Reference<
            ::com::sun::star::util::XModifiable > m_xModifiable;
    ::com::sun::star::uno::Reference<
            ::com::sun::star::view::XSelectionSupplier > m_xSelectionSupplier;
    bool m_bIsModified;
    ::rtl::OUString m_aSelectedCID;
};

} //  namespace chart

// CHART2_STATUSBARCOMMANDDISPATCH_HXX
#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.2.126); FILE MERGED 2008/04/01 15:04:11 thb 1.2.126.3: #i85898# Stripping all external header guards 2008/04/01 10:50:26 thb 1.2.126.2: #i85898# Stripping all external header guards 2008/03/28 16:43:51 rt 1.2.126.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: StatusBarCommandDispatch.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef CHART2_STATUSBARCOMMANDDISPATCH_HXX
#define CHART2_STATUSBARCOMMANDDISPATCH_HXX

#include "CommandDispatch.hxx"
#include <cppuhelper/implbase1.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/view/XSelectionSupplier.hpp>
#include <com/sun/star/util/XModifiable.hpp>

namespace chart
{

/** This is a CommandDispatch implementation for all commands the status bar offers

    This class reads the information needed from the XModel passed here.
 */

namespace impl
{
typedef ::cppu::ImplInheritanceHelper1<
        CommandDispatch,
        ::com::sun::star::view::XSelectionChangeListener >
    StatusBarCommandDispatch_Base;
}

class StatusBarCommandDispatch : public impl::StatusBarCommandDispatch_Base
{
public:
    explicit StatusBarCommandDispatch(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > & xContext,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::frame::XModel > & xModel,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::view::XSelectionSupplier > & xSelSupp );
    virtual ~StatusBarCommandDispatch();

    // late initialisation, especially for adding as listener
    virtual void initialize();

protected:
    // ____ XDispatch ____
    virtual void SAL_CALL dispatch(
        const ::com::sun::star::util::URL& URL,
        const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ WeakComponentImplHelperBase ____
    /// is called when this is disposed
    virtual void SAL_CALL disposing();

    // ____ XModifyListener (override from CommandDispatch) ____
    virtual void SAL_CALL modified(
        const ::com::sun::star::lang::EventObject& aEvent )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XEventListener (base of XModifyListener) ____
    virtual void SAL_CALL disposing(
        const ::com::sun::star::lang::EventObject& Source )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void fireStatusEvent(
        const ::rtl::OUString & rURL,
        const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > & xSingleListener );

    // ____ XSelectionChangeListener ____
    virtual void SAL_CALL selectionChanged(
        const ::com::sun::star::lang::EventObject& aEvent )
        throw (::com::sun::star::uno::RuntimeException);

private:
    ::com::sun::star::uno::Reference<
            ::com::sun::star::util::XModifiable > m_xModifiable;
    ::com::sun::star::uno::Reference<
            ::com::sun::star::view::XSelectionSupplier > m_xSelectionSupplier;
    bool m_bIsModified;
    ::rtl::OUString m_aSelectedCID;
};

} //  namespace chart

// CHART2_STATUSBARCOMMANDDISPATCH_HXX
#endif
<|endoftext|>


<commit_before>/*

Copyright (c) 2003-2012, Arvid Norberg
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 author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_FILE_HPP_INCLUDED
#define TORRENT_FILE_HPP_INCLUDED

#include <memory>
#include <string>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/noncopyable.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/error_code.hpp"
#include "libtorrent/size_type.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/intrusive_ptr_base.hpp"

#ifdef TORRENT_WINDOWS
// windows part
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winioctl.h>
#include <sys/types.h>
#else
// posix part
#define _FILE_OFFSET_BITS 64

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#endif

#include <unistd.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <dirent.h> // for DIR

#undef _FILE_OFFSET_BITS

#endif

namespace libtorrent
{
	struct file_status
	{
		size_type file_size;
		time_t atime;
		time_t mtime;
		time_t ctime;
		enum {
#if defined TORRENT_WINDOWS
			fifo = 0x1000, // named pipe (fifo)
			character_special = 0x2000,  // character special
			directory = 0x4000,  // directory
			regular_file = 0x8000  // regular
#else
			fifo = 0010000, // named pipe (fifo)
			character_special = 0020000,  // character special
			directory = 0040000,  // directory
			block_special = 0060000,  // block special
			regular_file = 0100000,  // regular
			link = 0120000,  // symbolic link
			socket = 0140000  // socket
#endif
		} modes_t;
		int mode;
	};

	// flags for stat_file
	enum { dont_follow_links = 1 };
	TORRENT_EXTRA_EXPORT void stat_file(std::string f, file_status* s
		, error_code& ec, int flags = 0);
	TORRENT_EXTRA_EXPORT void rename(std::string const& f
		, std::string const& newf, error_code& ec);
	TORRENT_EXTRA_EXPORT void create_directories(std::string const& f
		, error_code& ec);
	TORRENT_EXTRA_EXPORT void create_directory(std::string const& f
		, error_code& ec);
	TORRENT_EXTRA_EXPORT void remove_all(std::string const& f
		, error_code& ec);
	TORRENT_EXTRA_EXPORT void remove(std::string const& f, error_code& ec);
	TORRENT_EXTRA_EXPORT bool exists(std::string const& f);
	TORRENT_EXTRA_EXPORT size_type file_size(std::string const& f);
	TORRENT_EXTRA_EXPORT bool is_directory(std::string const& f
		, error_code& ec);
	TORRENT_EXTRA_EXPORT void recursive_copy(std::string const& old_path
		, std::string const& new_path, error_code& ec);
	TORRENT_EXTRA_EXPORT void copy_file(std::string const& f
		, std::string const& newf, error_code& ec);

	TORRENT_EXTRA_EXPORT std::string split_path(std::string const& f);
	TORRENT_EXTRA_EXPORT char const* next_path_element(char const* p);
	TORRENT_EXTRA_EXPORT std::string extension(std::string const& f);
	TORRENT_EXTRA_EXPORT void replace_extension(std::string& f, std::string const& ext);
	TORRENT_EXTRA_EXPORT bool is_root_path(std::string const& f);
	TORRENT_EXTRA_EXPORT std::string parent_path(std::string const& f);
	TORRENT_EXTRA_EXPORT bool has_parent_path(std::string const& f);
	TORRENT_EXTRA_EXPORT std::string filename(std::string const& f);
	TORRENT_EXTRA_EXPORT std::string combine_path(std::string const& lhs
		, std::string const& rhs);
	TORRENT_EXTRA_EXPORT std::string complete(std::string const& f);
	TORRENT_EXTRA_EXPORT bool is_complete(std::string const& f);
	TORRENT_EXTRA_EXPORT std::string current_working_directory();
#if TORRENT_USE_UNC_PATHS
	TORRENT_EXTRA_EXPORT std::string canonicalize_path(std::string const& f);
#endif

	class TORRENT_EXTRA_EXPORT directory : public boost::noncopyable
	{
	public:
		directory(std::string const& path, error_code& ec);
		~directory();
		void next(error_code& ec);
		std::string file() const;
		bool done() const { return m_done; }
	private:
#ifdef TORRENT_WINDOWS
		HANDLE m_handle;
#if TORRENT_USE_WSTRING
		WIN32_FIND_DATAW m_fd;
#else
		WIN32_FIND_DATAA m_fd;
#endif
#else
		DIR* m_handle;
		// the dirent struct contains a zero-sized
		// array at the end, it will end up referring
		// to the m_name field
		struct dirent m_dirent;
		char m_name[TORRENT_MAX_PATH + 1]; // +1 to make room for null
#endif
		bool m_done;
	};

	struct TORRENT_EXTRA_EXPORT file: boost::noncopyable, intrusive_ptr_base<file>
	{
		enum
		{
			// when a file is opened with no_buffer
			// file offsets have to be aligned to
			// pos_alignment() and buffer addresses
			// to buf_alignment() and read/write sizes
			// to size_alignment()
			read_only = 0,
			write_only = 1,
			read_write = 2,
			rw_mask = read_only | write_only | read_write,
			no_buffer = 4,
			sparse = 8,
			no_atime = 16,
			random_access = 32,
			lock_file = 64,

			attribute_hidden = 0x1000,
			attribute_executable = 0x2000,
			attribute_mask = attribute_hidden | attribute_executable
		};

#ifdef TORRENT_WINDOWS
		struct iovec_t
		{
			void* iov_base;
			size_t iov_len;
		};
#else
		typedef iovec iovec_t;
#endif

		// use a typedef for the type of iovec_t::iov_base
		// since it may differ
#ifdef TORRENT_SOLARIS
		typedef char* iovec_base_t;
#else
		typedef void* iovec_base_t;
#endif

		file();
		file(std::string const& p, int m, error_code& ec);
		~file();

		bool open(std::string const& p, int m, error_code& ec);
		bool is_open() const;
		void close();
		bool set_size(size_type size, error_code& ec);

		int open_mode() const { return m_open_mode; }

		// when opened in unbuffered mode, this is the
		// required alignment of file_offsets. i.e.
		// any (file_offset & (pos_alignment()-1)) == 0
		// is a precondition to read and write operations
		int pos_alignment() const;

		// when opened in unbuffered mode, this is the
		// required alignment of buffer addresses
		int buf_alignment() const;

		// read/write buffer sizes needs to be aligned to
		// this when in unbuffered mode
		int size_alignment() const;

		size_type writev(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec);
		size_type readv(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec);
		void hint_read(size_type file_offset, int len);

		size_type get_size(error_code& ec) const;

		// return the offset of the first byte that
		// belongs to a data-region
		size_type sparse_end(size_type start) const;

		size_type phys_offset(size_type offset);

#ifdef TORRENT_WINDOWS
		HANDLE native_handle() const { return m_file_handle; }
#else
		int native_handle() const { return m_fd; }
#endif

	private:

#ifdef TORRENT_WINDOWS
		HANDLE m_file_handle;
#if TORRENT_USE_WSTRING
		std::wstring m_path;
#else
		std::string m_path;
#endif // TORRENT_USE_WSTRING
#else // TORRENT_WINDOWS
		int m_fd;
#endif // TORRENT_WINDOWS

#if defined TORRENT_WINDOWS || defined TORRENT_LINUX || defined TORRENT_DEBUG
		static void init_file();
		static int m_page_size;
#endif
		int m_open_mode;
#if defined TORRENT_WINDOWS || defined TORRENT_LINUX
		mutable int m_sector_size;
#endif
#if defined TORRENT_WINDOWS
		mutable int m_cluster_size;
#endif
	};

}

#endif // TORRENT_FILE_HPP_INCLUDED

<commit_msg>fix python binding with shared linking<commit_after>/*

Copyright (c) 2003-2012, Arvid Norberg
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 author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_FILE_HPP_INCLUDED
#define TORRENT_FILE_HPP_INCLUDED

#include <memory>
#include <string>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/noncopyable.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/error_code.hpp"
#include "libtorrent/size_type.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/intrusive_ptr_base.hpp"

#ifdef TORRENT_WINDOWS
// windows part
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winioctl.h>
#include <sys/types.h>
#else
// posix part
#define _FILE_OFFSET_BITS 64

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#endif

#include <unistd.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <dirent.h> // for DIR

#undef _FILE_OFFSET_BITS

#endif

namespace libtorrent
{
	struct file_status
	{
		size_type file_size;
		time_t atime;
		time_t mtime;
		time_t ctime;
		enum {
#if defined TORRENT_WINDOWS
			fifo = 0x1000, // named pipe (fifo)
			character_special = 0x2000,  // character special
			directory = 0x4000,  // directory
			regular_file = 0x8000  // regular
#else
			fifo = 0010000, // named pipe (fifo)
			character_special = 0020000,  // character special
			directory = 0040000,  // directory
			block_special = 0060000,  // block special
			regular_file = 0100000,  // regular
			link = 0120000,  // symbolic link
			socket = 0140000  // socket
#endif
		} modes_t;
		int mode;
	};

	// flags for stat_file
	enum { dont_follow_links = 1 };
	TORRENT_EXTRA_EXPORT void stat_file(std::string f, file_status* s
		, error_code& ec, int flags = 0);
	TORRENT_EXTRA_EXPORT void rename(std::string const& f
		, std::string const& newf, error_code& ec);
	TORRENT_EXTRA_EXPORT void create_directories(std::string const& f
		, error_code& ec);
	TORRENT_EXTRA_EXPORT void create_directory(std::string const& f
		, error_code& ec);
	TORRENT_EXTRA_EXPORT void remove_all(std::string const& f
		, error_code& ec);
	TORRENT_EXTRA_EXPORT void remove(std::string const& f, error_code& ec);
	TORRENT_EXTRA_EXPORT bool exists(std::string const& f);
	TORRENT_EXTRA_EXPORT size_type file_size(std::string const& f);
	TORRENT_EXTRA_EXPORT bool is_directory(std::string const& f
		, error_code& ec);
	TORRENT_EXTRA_EXPORT void recursive_copy(std::string const& old_path
		, std::string const& new_path, error_code& ec);
	TORRENT_EXTRA_EXPORT void copy_file(std::string const& f
		, std::string const& newf, error_code& ec);

	TORRENT_EXTRA_EXPORT std::string split_path(std::string const& f);
	TORRENT_EXTRA_EXPORT char const* next_path_element(char const* p);
	TORRENT_EXTRA_EXPORT std::string extension(std::string const& f);
	TORRENT_EXTRA_EXPORT void replace_extension(std::string& f, std::string const& ext);
	TORRENT_EXTRA_EXPORT bool is_root_path(std::string const& f);
	// used by create_torrent.hpp
	TORRENT_EXPORT std::string parent_path(std::string const& f);
	TORRENT_EXTRA_EXPORT bool has_parent_path(std::string const& f);
	// used by create_torrent.hpp
	TORRENT_EXPORT std::string filename(std::string const& f);
	TORRENT_EXTRA_EXPORT std::string combine_path(std::string const& lhs
		, std::string const& rhs);
	// used by create_torrent.hpp
	TORRENT_EXPORT std::string complete(std::string const& f);
	TORRENT_EXTRA_EXPORT bool is_complete(std::string const& f);
	TORRENT_EXTRA_EXPORT std::string current_working_directory();
#if TORRENT_USE_UNC_PATHS
	TORRENT_EXTRA_EXPORT std::string canonicalize_path(std::string const& f);
#endif

	class TORRENT_EXTRA_EXPORT directory : public boost::noncopyable
	{
	public:
		directory(std::string const& path, error_code& ec);
		~directory();
		void next(error_code& ec);
		std::string file() const;
		bool done() const { return m_done; }
	private:
#ifdef TORRENT_WINDOWS
		HANDLE m_handle;
#if TORRENT_USE_WSTRING
		WIN32_FIND_DATAW m_fd;
#else
		WIN32_FIND_DATAA m_fd;
#endif
#else
		DIR* m_handle;
		// the dirent struct contains a zero-sized
		// array at the end, it will end up referring
		// to the m_name field
		struct dirent m_dirent;
		char m_name[TORRENT_MAX_PATH + 1]; // +1 to make room for null
#endif
		bool m_done;
	};

	struct TORRENT_EXTRA_EXPORT file: boost::noncopyable, intrusive_ptr_base<file>
	{
		enum
		{
			// when a file is opened with no_buffer
			// file offsets have to be aligned to
			// pos_alignment() and buffer addresses
			// to buf_alignment() and read/write sizes
			// to size_alignment()
			read_only = 0,
			write_only = 1,
			read_write = 2,
			rw_mask = read_only | write_only | read_write,
			no_buffer = 4,
			sparse = 8,
			no_atime = 16,
			random_access = 32,
			lock_file = 64,

			attribute_hidden = 0x1000,
			attribute_executable = 0x2000,
			attribute_mask = attribute_hidden | attribute_executable
		};

#ifdef TORRENT_WINDOWS
		struct iovec_t
		{
			void* iov_base;
			size_t iov_len;
		};
#else
		typedef iovec iovec_t;
#endif

		// use a typedef for the type of iovec_t::iov_base
		// since it may differ
#ifdef TORRENT_SOLARIS
		typedef char* iovec_base_t;
#else
		typedef void* iovec_base_t;
#endif

		file();
		file(std::string const& p, int m, error_code& ec);
		~file();

		bool open(std::string const& p, int m, error_code& ec);
		bool is_open() const;
		void close();
		bool set_size(size_type size, error_code& ec);

		int open_mode() const { return m_open_mode; }

		// when opened in unbuffered mode, this is the
		// required alignment of file_offsets. i.e.
		// any (file_offset & (pos_alignment()-1)) == 0
		// is a precondition to read and write operations
		int pos_alignment() const;

		// when opened in unbuffered mode, this is the
		// required alignment of buffer addresses
		int buf_alignment() const;

		// read/write buffer sizes needs to be aligned to
		// this when in unbuffered mode
		int size_alignment() const;

		size_type writev(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec);
		size_type readv(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec);
		void hint_read(size_type file_offset, int len);

		size_type get_size(error_code& ec) const;

		// return the offset of the first byte that
		// belongs to a data-region
		size_type sparse_end(size_type start) const;

		size_type phys_offset(size_type offset);

#ifdef TORRENT_WINDOWS
		HANDLE native_handle() const { return m_file_handle; }
#else
		int native_handle() const { return m_fd; }
#endif

	private:

#ifdef TORRENT_WINDOWS
		HANDLE m_file_handle;
#if TORRENT_USE_WSTRING
		std::wstring m_path;
#else
		std::string m_path;
#endif // TORRENT_USE_WSTRING
#else // TORRENT_WINDOWS
		int m_fd;
#endif // TORRENT_WINDOWS

#if defined TORRENT_WINDOWS || defined TORRENT_LINUX || defined TORRENT_DEBUG
		static void init_file();
		static int m_page_size;
#endif
		int m_open_mode;
#if defined TORRENT_WINDOWS || defined TORRENT_LINUX
		mutable int m_sector_size;
#endif
#if defined TORRENT_WINDOWS
		mutable int m_cluster_size;
#endif
	};

}

#endif // TORRENT_FILE_HPP_INCLUDED

<|endoftext|>


<commit_before>#include "TMC2130_Basics.h"

TMC2130_Basics::TMC2130_Basics(uint8_t csPin, uint8_t axisNumber)
{
  _csPin = csPin;
  _status = 0;
  _axisNumber = axisNumber;
  //_debug = "";
}

// initialize the driver with its CS/SS pin
void TMC2130_Basics::init() {
  pinMode(_csPin, OUTPUT);
  digitalWrite(_csPin, HIGH);
  // init_SPI();
  read_STAT();
}

// initialize SPI
// void TMC2130_Basics::init_SPI() {
//   SPI.setDataMode(FB_TMC_SPI_DATA_MODE);
//   SPI.setBitOrder(FB_TMC_SPI_BIT_ORDER);
//   //SPI.setClockDivider(FB_TMC_SPI_CLOCK_DIVIDER);/**
//   SPI.setClockDivider(SPI_CLOCK_DIV4);
//   SPI.begin();
// }

// read status
uint8_t TMC2130_Basics::read_STAT()
{
  //init_SPI();
  SPI.beginTransaction(SPISettings(FB_TMC_SPI_CLOCK_DIVIDER, FB_TMC_SPI_BIT_ORDER, FB_TMC_SPI_DATA_MODE));
  digitalWrite(_csPin, LOW);

  // read address
  _status = SPI.transfer(0x00);

  // flush 4 bytes
  for (int i = 0; i < 4; i++) {
    SPI.transfer(0x00);
  }

  digitalWrite(_csPin, HIGH);
  SPI.endTransaction();

  return _status;
}

// read a register
uint8_t TMC2130_Basics::read_REG(uint8_t address, uint32_t *data)
{
  // init_SPI();
  SPI.beginTransaction(SPISettings(FB_TMC_SPI_CLOCK_DIVIDER, FB_TMC_SPI_BIT_ORDER, FB_TMC_SPI_DATA_MODE));
  digitalWrite(_csPin, LOW);

  // read address
  _status = SPI.transfer(address&~FB_TMC_WRITE);

  // flush 4 bytes
  for (int i = 0; i < 4; i++) {
    SPI.transfer(0x00);
  }

  digitalWrite(_csPin, HIGH);
  // restart transmission
  digitalWrite(_csPin, LOW);

  // read address
  _status = SPI.transfer(address&~FB_TMC_WRITE);

  // retrieve data
  *data = SPI.transfer(0x00) & 0xFF;
  *data <<= 8;
  *data |= SPI.transfer(0x00) & 0xFF;
  *data <<= 8;
  *data |= SPI.transfer(0x00) & 0xFF;
  *data <<= 8;
  *data |= SPI.transfer(0x00) & 0xFF;

  digitalWrite(_csPin, HIGH);
  SPI.endTransaction();

  return _status;
}

// write to a register
uint8_t TMC2130_Basics::write_REG(uint8_t address, uint32_t data)
{
  SPI.beginTransaction(SPISettings(FB_TMC_SPI_CLOCK_DIVIDER, FB_TMC_SPI_BIT_ORDER, FB_TMC_SPI_DATA_MODE));
  digitalWrite(_csPin, LOW);

  // write address
  _status = SPI.transfer(address | FB_TMC_WRITE);

  // write data
  SPI.transfer((data >> 24UL) & 0xFF);
  SPI.transfer((data >> 16UL) & 0xFF);
  SPI.transfer((data >> 8UL) & 0xFF);
  SPI.transfer((data >> 0UL) & 0xFF);

  digitalWrite(_csPin, HIGH);
  SPI.endTransaction();

  return _status;
}

// alter a register using a bitmask
uint8_t TMC2130_Basics::alter_REG(uint8_t address, uint32_t data, uint32_t mask)
{
  uint32_t oldData, newData;

  read_REG(address, &oldData);

  newData = (oldData&~mask) | (data&mask);

  write_REG(address, newData);

  return _status;
}

// check the stallguard status
boolean TMC2130_Basics::isStallguard()
{
  return _status & FB_TMC_SPISTATUS_STALLGUARD_MASK ? true : false;
}

// check the standstill status
boolean TMC2130_Basics::isStandstill()
{
  return _status & FB_TMC_SPISTATUS_STANDSTILL_MASK ? true : false;
}

// set single bits in the GCONF register
uint8_t TMC2130_Basics::set_GCONF(uint8_t position, uint8_t value)
{
  alter_REG(FB_TMC_REG_GCONF, uint32_t(value) << position, 0x1UL << position);

  return _status;
}

// set single bits or values in the chopconf register (constraining masks are applied if necessary)
uint8_t TMC2130_Basics::set_CHOPCONF(uint8_t position, uint8_t value)
{
  alter_REG(FB_TMC_REG_CHOPCONF, uint32_t(value) << position, FB_TMC_CHOPCONF_MASKS[position] << position);

  return _status;
}

uint8_t TMC2130_Basics::getStatus()
{
  return _status;
}

uint8_t TMC2130_Basics::getAxisNumber()
{
  return _axisNumber;
}
<commit_msg>change tmc spi clock frequency<commit_after>#include "TMC2130_Basics.h"

TMC2130_Basics::TMC2130_Basics(uint8_t csPin, uint8_t axisNumber)
{
  _csPin = csPin;
  _status = 0;
  _axisNumber = axisNumber;
  //_debug = "";
}

// initialize the driver with its CS/SS pin
void TMC2130_Basics::init() {
  pinMode(_csPin, OUTPUT);
  digitalWrite(_csPin, HIGH);
  // init_SPI();
  read_STAT();
}

// initialize SPI
// void TMC2130_Basics::init_SPI() {
//   SPI.setDataMode(FB_TMC_SPI_DATA_MODE);
//   SPI.setBitOrder(FB_TMC_SPI_BIT_ORDER);
//   //SPI.setClockDivider(FB_TMC_SPI_CLOCK_DIVIDER);/**
//   SPI.setClockDivider(SPI_CLOCK_DIV4);
//   SPI.begin();
// }

// read status
uint8_t TMC2130_Basics::read_STAT()
{
  //init_SPI();
  SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV4, FB_TMC_SPI_BIT_ORDER, FB_TMC_SPI_DATA_MODE));
  digitalWrite(_csPin, LOW);

  // read address
  _status = SPI.transfer(0x00);

  // flush 4 bytes
  for (int i = 0; i < 4; i++) {
    SPI.transfer(0x00);
  }

  digitalWrite(_csPin, HIGH);
  SPI.endTransaction();

  return _status;
}

// read a register
uint8_t TMC2130_Basics::read_REG(uint8_t address, uint32_t *data)
{
  // init_SPI();
  SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV4, FB_TMC_SPI_BIT_ORDER, FB_TMC_SPI_DATA_MODE));
  digitalWrite(_csPin, LOW);

  // read address
  _status = SPI.transfer(address&~FB_TMC_WRITE);

  // flush 4 bytes
  for (int i = 0; i < 4; i++) {
    SPI.transfer(0x00);
  }

  digitalWrite(_csPin, HIGH);
  // restart transmission
  digitalWrite(_csPin, LOW);

  // read address
  _status = SPI.transfer(address&~FB_TMC_WRITE);

  // retrieve data
  *data = SPI.transfer(0x00) & 0xFF;
  *data <<= 8;
  *data |= SPI.transfer(0x00) & 0xFF;
  *data <<= 8;
  *data |= SPI.transfer(0x00) & 0xFF;
  *data <<= 8;
  *data |= SPI.transfer(0x00) & 0xFF;

  digitalWrite(_csPin, HIGH);
  SPI.endTransaction();

  return _status;
}

// write to a register
uint8_t TMC2130_Basics::write_REG(uint8_t address, uint32_t data)
{
  SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV4, FB_TMC_SPI_BIT_ORDER, FB_TMC_SPI_DATA_MODE));
  digitalWrite(_csPin, LOW);

  // write address
  _status = SPI.transfer(address | FB_TMC_WRITE);

  // write data
  SPI.transfer((data >> 24UL) & 0xFF);
  SPI.transfer((data >> 16UL) & 0xFF);
  SPI.transfer((data >> 8UL) & 0xFF);
  SPI.transfer((data >> 0UL) & 0xFF);

  digitalWrite(_csPin, HIGH);
  SPI.endTransaction();

  return _status;
}

// alter a register using a bitmask
uint8_t TMC2130_Basics::alter_REG(uint8_t address, uint32_t data, uint32_t mask)
{
  uint32_t oldData, newData;

  read_REG(address, &oldData);

  newData = (oldData&~mask) | (data&mask);

  write_REG(address, newData);

  return _status;
}

// check the stallguard status
boolean TMC2130_Basics::isStallguard()
{
  return _status & FB_TMC_SPISTATUS_STALLGUARD_MASK ? true : false;
}

// check the standstill status
boolean TMC2130_Basics::isStandstill()
{
  return _status & FB_TMC_SPISTATUS_STANDSTILL_MASK ? true : false;
}

// set single bits in the GCONF register
uint8_t TMC2130_Basics::set_GCONF(uint8_t position, uint8_t value)
{
  alter_REG(FB_TMC_REG_GCONF, uint32_t(value) << position, 0x1UL << position);

  return _status;
}

// set single bits or values in the chopconf register (constraining masks are applied if necessary)
uint8_t TMC2130_Basics::set_CHOPCONF(uint8_t position, uint8_t value)
{
  alter_REG(FB_TMC_REG_CHOPCONF, uint32_t(value) << position, FB_TMC_CHOPCONF_MASKS[position] << position);

  return _status;
}

uint8_t TMC2130_Basics::getStatus()
{
  return _status;
}

uint8_t TMC2130_Basics::getAxisNumber()
{
  return _axisNumber;
}
<|endoftext|>


<commit_before>/****************************************************************************
 * Copyright (c) 2012-2017 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 ****************************************************************************/

#ifndef DTK_DETAILSTREECONSTRUCTION_DEF_HPP
#define DTK_DETAILSTREECONSTRUCTION_DEF_HPP

#include "DTK_ConfigDefs.hpp"
#include "DTK_KokkosHelpers.hpp"
#include <Kokkos_Atomic.hpp>
#include <Kokkos_Sort.hpp>

#include <cassert>

namespace DataTransferKit
{
namespace Details
{

template <typename DeviceType>
class AssignMortonCodesFunctor
{
  public:
    AssignMortonCodesFunctor(
        Kokkos::View<Box const *, DeviceType> bounding_boxes,
        Kokkos::View<unsigned int *, DeviceType> morton_codes,
        Box const &scene_bounding_box )
        : _bounding_boxes( bounding_boxes )
        , _morton_codes( morton_codes )
        , _scene_bounding_box( scene_bounding_box )
    {
    }

    KOKKOS_INLINE_FUNCTION
    void operator()( int const i ) const
    {
        Point xyz;
        double a, b;
        centroid( _bounding_boxes[i], xyz );
        // scale coordinates with respect to bounding box of the scene
        for ( int d = 0; d < 3; ++d )
        {
            a = _scene_bounding_box[2 * d];
            b = _scene_bounding_box[2 * d + 1];
            xyz[d] = ( a != b ? ( xyz[d] - a ) / ( b - a ) : 0 );
        }
        _morton_codes[i] = morton3D( xyz[0], xyz[1], xyz[2] );
    }

  private:
    Kokkos::View<Box const *, DeviceType> _bounding_boxes;
    Kokkos::View<unsigned int *, DeviceType> _morton_codes;
    Box const &_scene_bounding_box;
};

template <typename DeviceType>
class GenerateHierarchyFunctor
{
  public:
    GenerateHierarchyFunctor(
        Kokkos::View<unsigned int *, DeviceType> sorted_morton_codes,
        Kokkos::View<Node *, DeviceType> leaf_nodes,
        Kokkos::View<Node *, DeviceType> internal_nodes )
        : _sorted_morton_codes( sorted_morton_codes )
        , _leaf_nodes( leaf_nodes )
        , _internal_nodes( internal_nodes )
    {
    }

    // from "Thinking Parallel, Part III: Tree Construction on the GPU" by
    // Karras
    KOKKOS_INLINE_FUNCTION
    void operator()( int const i ) const
    {
        // Construct internal nodes.
        // Find out which range of objects the node corresponds to.
        // (This is where the magic happens!)

        auto range = TreeConstruction<DeviceType>::determineRange(
            _sorted_morton_codes, i );
        int first = range.first;
        int last = range.second;

        // Determine where to split the range.

        int split = TreeConstruction<DeviceType>::findSplit(
            _sorted_morton_codes, first, last );

        // Select childA.

        Node *childA;
        if ( split == first )
            childA = &_leaf_nodes[split];
        else
            childA = &_internal_nodes[split];

        // Select childB.

        Node *childB;
        if ( split + 1 == last )
            childB = &_leaf_nodes[split + 1];
        else
            childB = &_internal_nodes[split + 1];

        // Record parent-child relationships.

        _internal_nodes[i].children.first = childA;
        _internal_nodes[i].children.second = childB;
        childA->parent = &_internal_nodes[i];
        childB->parent = &_internal_nodes[i];
    }

  private:
    Kokkos::View<unsigned int *, DeviceType> _sorted_morton_codes;
    Kokkos::View<Node *, DeviceType> _leaf_nodes;
    Kokkos::View<Node *, DeviceType> _internal_nodes;
};

template <typename DeviceType>
class CalculateBoundingBoxesFunctor
{
  public:
    CalculateBoundingBoxesFunctor( Kokkos::View<Node *, DeviceType> leaf_nodes,
                                   Node *root,
                                   Kokkos::View<int *, DeviceType> ready_flags )
        : _leaf_nodes( leaf_nodes )
        , _root( root )
        , _ready_flags( ready_flags )
    {
    }

    KOKKOS_INLINE_FUNCTION
    void operator()( int const i ) const
    {
        Node *node = _leaf_nodes[i].parent;
        while ( node != _root )
        {
            if ( Kokkos::atomic_compare_exchange_strong(
                     &_ready_flags[node - _root], 0, 1 ) )
                break;
            for ( Node *child : {node->children.first, node->children.second} )
                expand( node->bounding_box, child->bounding_box );
            node = node->parent;
        }
        // NOTE: could stop at node != root and then just check that what we
        // computed earlier (bounding box of the scene) is indeed the union of
        // the two children.
    }

  private:
    Kokkos::View<Node *, DeviceType> _leaf_nodes;
    Node *_root;
    Kokkos::View<int *, DeviceType> _ready_flags;
};

template <typename DeviceType>
void TreeConstruction<DeviceType>::calculateBoundingBoxOfTheScene(
    Kokkos::View<Box const *, DeviceType> bounding_boxes,
    Box &scene_bounding_box )
{
    int const n = bounding_boxes.extent( 0 );
    ExpandBoxWithBoxFunctor<DeviceType> functor( bounding_boxes );
    Kokkos::parallel_reduce( "calculate_bouding_of_the_scene",
                             Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
                             functor, scene_bounding_box );
    Kokkos::fence();
}

template <typename DeviceType>
void TreeConstruction<DeviceType>::assignMortonCodes(
    Kokkos::View<Box const *, DeviceType> bounding_boxes,
    Kokkos::View<unsigned int *, DeviceType> morton_codes,
    Box const &scene_bounding_box )
{
    int const n = morton_codes.extent( 0 );
    AssignMortonCodesFunctor<DeviceType> functor( bounding_boxes, morton_codes,
                                                  scene_bounding_box );
    Kokkos::parallel_for( "assign_morton_codes",
                          Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
                          functor );
    Kokkos::fence();
}

template <typename DeviceType>
void TreeConstruction<DeviceType>::sortObjects(
    Kokkos::View<unsigned int *, DeviceType> morton_codes,
    Kokkos::View<int *, DeviceType> object_ids )
{
    using ExecutionSpace = typename DeviceType::execution_space;
    int const n = morton_codes.extent( 0 );

    typedef Kokkos::BinOp1D<Kokkos::View<unsigned int *, DeviceType>> CompType;

    Kokkos::Experimental::MinMaxScalar<unsigned int> result;
    Kokkos::Experimental::MinMax<unsigned int> reducer( result );
    parallel_reduce(
        Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
        Kokkos::Impl::min_max_functor<Kokkos::View<unsigned int *, DeviceType>>(
            morton_codes ),
        reducer );
    if ( result.min_val == result.max_val )
        return;
    Kokkos::BinSort<Kokkos::View<unsigned int *, DeviceType>, CompType>
        bin_sort( morton_codes,
                  CompType( n / 2, result.min_val, result.max_val ), true );
    bin_sort.create_permute_vector();
    bin_sort.sort( morton_codes );
    // TODO: We might be able to just use `bin_sort.get_permute_vector()`
    // instead of initializing the indices with Iota and sorting the vector
    bin_sort.sort( object_ids );
}

template <typename DeviceType>
Node *TreeConstruction<DeviceType>::generateHierarchy(
    Kokkos::View<unsigned int *, DeviceType> sorted_morton_codes,
    Kokkos::View<Node *, DeviceType> leaf_nodes,
    Kokkos::View<Node *, DeviceType> internal_nodes )
{
    GenerateHierarchyFunctor<DeviceType> functor( sorted_morton_codes,
                                                  leaf_nodes, internal_nodes );

    int const n = sorted_morton_codes.extent( 0 );
    Kokkos::parallel_for( "generate_hierarchy",
                          Kokkos::RangePolicy<ExecutionSpace>( 0, n - 1 ),
                          functor );
    Kokkos::fence();

    // Node 0 is the root.
    return &( internal_nodes.data()[0] );
}

template <typename DeviceType>
void TreeConstruction<DeviceType>::calculateBoundingBoxes(
    Kokkos::View<Node *, DeviceType> leaf_nodes,
    Kokkos::View<Node *, DeviceType> internal_nodes )
{
    int const n = leaf_nodes.extent( 0 );

    // Use int instead of bool because CAS on CUDA does not support boolean
    Kokkos::View<int *, DeviceType> ready_flags( "ready_flags", n - 1 );
    Kokkos::parallel_for( "fill_ready_flags",
                          Kokkos::RangePolicy<ExecutionSpace>( 0, n - 1 ),
                          KOKKOS_LAMBDA( int i ) { ready_flags[i] = 0; } );
    Kokkos::fence();

    Node *root = &internal_nodes[0];

    CalculateBoundingBoxesFunctor<DeviceType> calc_functor( leaf_nodes, root,
                                                            ready_flags );
    Kokkos::parallel_for( "calculate_bounding_boxes",
                          Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
                          calc_functor );
    Kokkos::fence();
}

template <typename DeviceType>
int TreeConstruction<DeviceType>::findSplit(
    Kokkos::View<unsigned int *, DeviceType> sorted_morton_codes, int first,
    int last )
{
    // Identical Morton codes => split the range in the middle.

    unsigned int first_code = sorted_morton_codes[first];
    unsigned int last_code = sorted_morton_codes[last];

    if ( first_code == last_code )
        return ( first + last ) >> 1;

    // Calculate the number of highest bits that are the same
    // for all objects, using the count-leading-zeros intrinsic.

    int common_prefix = clz( first_code ^ last_code );

    // Use binary search to find where the next bit differs.
    // Specifically, we are looking for the highest object that
    // shares more than commonPrefix bits with the first one.

    int split = first; // initial guess
    int step = last - first;

    do
    {
        step = ( step + 1 ) >> 1;     // exponential decrease
        int new_split = split + step; // proposed new position

        if ( new_split < last )
        {
            unsigned int split_code = sorted_morton_codes[new_split];
            int split_prefix = clz( first_code ^ split_code );
            if ( split_prefix > common_prefix )
                split = new_split; // accept proposal
        }
    } while ( step > 1 );

    return split;
}

template <typename DeviceType>
Kokkos::pair<int, int> TreeConstruction<DeviceType>::determineRange(
    Kokkos::View<unsigned int *, DeviceType> sorted_morton_codes, int i )
{
    // determine direction of the range (+1 or -1)
    int direction =
        KokkosHelpers::sgn( commonPrefix( sorted_morton_codes, i, i + 1 ) -
                            commonPrefix( sorted_morton_codes, i, i - 1 ) );
    assert( direction == +1 || direction == -1 );

    // compute upper bound for the length of the range
    int max_step = 2;
    int common_prefix = commonPrefix( sorted_morton_codes, i, i - direction );

    // compute upper bound for the length of the range
    while ( commonPrefix( sorted_morton_codes, i, i + direction * max_step ) >
            common_prefix )
    {
        max_step = max_step << 1;
    }

    // find the other end using binary search
    int split = 0;
    int step = max_step;
    do
    {
        step = step >> 1;
        if ( commonPrefix( sorted_morton_codes, i,
                           i + ( split + step ) * direction ) > common_prefix )
            split += step;
    } while ( step > 1 );
    int j = i + split * direction;

    return {KokkosHelpers::min( i, j ), KokkosHelpers::max( i, j )};
}
}
}

// Explicit instantiation macro
#define DTK_TREECONSTRUCTION_INSTANT( NODE )                                   \
    namespace Details                                                          \
    {                                                                          \
    template struct TreeConstruction<typename NODE::device_type>;              \
    }

#endif
<commit_msg>Get rid of redefinition of ExecutionSpace in TreeConstruction::SortObjects()<commit_after>/****************************************************************************
 * Copyright (c) 2012-2017 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 ****************************************************************************/

#ifndef DTK_DETAILSTREECONSTRUCTION_DEF_HPP
#define DTK_DETAILSTREECONSTRUCTION_DEF_HPP

#include "DTK_ConfigDefs.hpp"
#include "DTK_KokkosHelpers.hpp"
#include <Kokkos_Atomic.hpp>
#include <Kokkos_Sort.hpp>

#include <cassert>

namespace DataTransferKit
{
namespace Details
{

template <typename DeviceType>
class AssignMortonCodesFunctor
{
  public:
    AssignMortonCodesFunctor(
        Kokkos::View<Box const *, DeviceType> bounding_boxes,
        Kokkos::View<unsigned int *, DeviceType> morton_codes,
        Box const &scene_bounding_box )
        : _bounding_boxes( bounding_boxes )
        , _morton_codes( morton_codes )
        , _scene_bounding_box( scene_bounding_box )
    {
    }

    KOKKOS_INLINE_FUNCTION
    void operator()( int const i ) const
    {
        Point xyz;
        double a, b;
        centroid( _bounding_boxes[i], xyz );
        // scale coordinates with respect to bounding box of the scene
        for ( int d = 0; d < 3; ++d )
        {
            a = _scene_bounding_box[2 * d];
            b = _scene_bounding_box[2 * d + 1];
            xyz[d] = ( a != b ? ( xyz[d] - a ) / ( b - a ) : 0 );
        }
        _morton_codes[i] = morton3D( xyz[0], xyz[1], xyz[2] );
    }

  private:
    Kokkos::View<Box const *, DeviceType> _bounding_boxes;
    Kokkos::View<unsigned int *, DeviceType> _morton_codes;
    Box const &_scene_bounding_box;
};

template <typename DeviceType>
class GenerateHierarchyFunctor
{
  public:
    GenerateHierarchyFunctor(
        Kokkos::View<unsigned int *, DeviceType> sorted_morton_codes,
        Kokkos::View<Node *, DeviceType> leaf_nodes,
        Kokkos::View<Node *, DeviceType> internal_nodes )
        : _sorted_morton_codes( sorted_morton_codes )
        , _leaf_nodes( leaf_nodes )
        , _internal_nodes( internal_nodes )
    {
    }

    // from "Thinking Parallel, Part III: Tree Construction on the GPU" by
    // Karras
    KOKKOS_INLINE_FUNCTION
    void operator()( int const i ) const
    {
        // Construct internal nodes.
        // Find out which range of objects the node corresponds to.
        // (This is where the magic happens!)

        auto range = TreeConstruction<DeviceType>::determineRange(
            _sorted_morton_codes, i );
        int first = range.first;
        int last = range.second;

        // Determine where to split the range.

        int split = TreeConstruction<DeviceType>::findSplit(
            _sorted_morton_codes, first, last );

        // Select childA.

        Node *childA;
        if ( split == first )
            childA = &_leaf_nodes[split];
        else
            childA = &_internal_nodes[split];

        // Select childB.

        Node *childB;
        if ( split + 1 == last )
            childB = &_leaf_nodes[split + 1];
        else
            childB = &_internal_nodes[split + 1];

        // Record parent-child relationships.

        _internal_nodes[i].children.first = childA;
        _internal_nodes[i].children.second = childB;
        childA->parent = &_internal_nodes[i];
        childB->parent = &_internal_nodes[i];
    }

  private:
    Kokkos::View<unsigned int *, DeviceType> _sorted_morton_codes;
    Kokkos::View<Node *, DeviceType> _leaf_nodes;
    Kokkos::View<Node *, DeviceType> _internal_nodes;
};

template <typename DeviceType>
class CalculateBoundingBoxesFunctor
{
  public:
    CalculateBoundingBoxesFunctor( Kokkos::View<Node *, DeviceType> leaf_nodes,
                                   Node *root,
                                   Kokkos::View<int *, DeviceType> ready_flags )
        : _leaf_nodes( leaf_nodes )
        , _root( root )
        , _ready_flags( ready_flags )
    {
    }

    KOKKOS_INLINE_FUNCTION
    void operator()( int const i ) const
    {
        Node *node = _leaf_nodes[i].parent;
        while ( node != _root )
        {
            if ( Kokkos::atomic_compare_exchange_strong(
                     &_ready_flags[node - _root], 0, 1 ) )
                break;
            for ( Node *child : {node->children.first, node->children.second} )
                expand( node->bounding_box, child->bounding_box );
            node = node->parent;
        }
        // NOTE: could stop at node != root and then just check that what we
        // computed earlier (bounding box of the scene) is indeed the union of
        // the two children.
    }

  private:
    Kokkos::View<Node *, DeviceType> _leaf_nodes;
    Node *_root;
    Kokkos::View<int *, DeviceType> _ready_flags;
};

template <typename DeviceType>
void TreeConstruction<DeviceType>::calculateBoundingBoxOfTheScene(
    Kokkos::View<Box const *, DeviceType> bounding_boxes,
    Box &scene_bounding_box )
{
    int const n = bounding_boxes.extent( 0 );
    ExpandBoxWithBoxFunctor<DeviceType> functor( bounding_boxes );
    Kokkos::parallel_reduce( "calculate_bouding_of_the_scene",
                             Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
                             functor, scene_bounding_box );
    Kokkos::fence();
}

template <typename DeviceType>
void TreeConstruction<DeviceType>::assignMortonCodes(
    Kokkos::View<Box const *, DeviceType> bounding_boxes,
    Kokkos::View<unsigned int *, DeviceType> morton_codes,
    Box const &scene_bounding_box )
{
    int const n = morton_codes.extent( 0 );
    AssignMortonCodesFunctor<DeviceType> functor( bounding_boxes, morton_codes,
                                                  scene_bounding_box );
    Kokkos::parallel_for( "assign_morton_codes",
                          Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
                          functor );
    Kokkos::fence();
}

template <typename DeviceType>
void TreeConstruction<DeviceType>::sortObjects(
    Kokkos::View<unsigned int *, DeviceType> morton_codes,
    Kokkos::View<int *, DeviceType> object_ids )
{
    int const n = morton_codes.extent( 0 );

    typedef Kokkos::BinOp1D<Kokkos::View<unsigned int *, DeviceType>> CompType;

    Kokkos::Experimental::MinMaxScalar<unsigned int> result;
    Kokkos::Experimental::MinMax<unsigned int> reducer( result );
    parallel_reduce(
        Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
        Kokkos::Impl::min_max_functor<Kokkos::View<unsigned int *, DeviceType>>(
            morton_codes ),
        reducer );
    if ( result.min_val == result.max_val )
        return;
    Kokkos::BinSort<Kokkos::View<unsigned int *, DeviceType>, CompType>
        bin_sort( morton_codes,
                  CompType( n / 2, result.min_val, result.max_val ), true );
    bin_sort.create_permute_vector();
    bin_sort.sort( morton_codes );
    // TODO: We might be able to just use `bin_sort.get_permute_vector()`
    // instead of initializing the indices with Iota and sorting the vector
    bin_sort.sort( object_ids );
}

template <typename DeviceType>
Node *TreeConstruction<DeviceType>::generateHierarchy(
    Kokkos::View<unsigned int *, DeviceType> sorted_morton_codes,
    Kokkos::View<Node *, DeviceType> leaf_nodes,
    Kokkos::View<Node *, DeviceType> internal_nodes )
{
    GenerateHierarchyFunctor<DeviceType> functor( sorted_morton_codes,
                                                  leaf_nodes, internal_nodes );

    int const n = sorted_morton_codes.extent( 0 );
    Kokkos::parallel_for( "generate_hierarchy",
                          Kokkos::RangePolicy<ExecutionSpace>( 0, n - 1 ),
                          functor );
    Kokkos::fence();

    // Node 0 is the root.
    return &( internal_nodes.data()[0] );
}

template <typename DeviceType>
void TreeConstruction<DeviceType>::calculateBoundingBoxes(
    Kokkos::View<Node *, DeviceType> leaf_nodes,
    Kokkos::View<Node *, DeviceType> internal_nodes )
{
    int const n = leaf_nodes.extent( 0 );

    // Use int instead of bool because CAS on CUDA does not support boolean
    Kokkos::View<int *, DeviceType> ready_flags( "ready_flags", n - 1 );
    Kokkos::parallel_for( "fill_ready_flags",
                          Kokkos::RangePolicy<ExecutionSpace>( 0, n - 1 ),
                          KOKKOS_LAMBDA( int i ) { ready_flags[i] = 0; } );
    Kokkos::fence();

    Node *root = &internal_nodes[0];

    CalculateBoundingBoxesFunctor<DeviceType> calc_functor( leaf_nodes, root,
                                                            ready_flags );
    Kokkos::parallel_for( "calculate_bounding_boxes",
                          Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
                          calc_functor );
    Kokkos::fence();
}

template <typename DeviceType>
int TreeConstruction<DeviceType>::findSplit(
    Kokkos::View<unsigned int *, DeviceType> sorted_morton_codes, int first,
    int last )
{
    // Identical Morton codes => split the range in the middle.

    unsigned int first_code = sorted_morton_codes[first];
    unsigned int last_code = sorted_morton_codes[last];

    if ( first_code == last_code )
        return ( first + last ) >> 1;

    // Calculate the number of highest bits that are the same
    // for all objects, using the count-leading-zeros intrinsic.

    int common_prefix = clz( first_code ^ last_code );

    // Use binary search to find where the next bit differs.
    // Specifically, we are looking for the highest object that
    // shares more than commonPrefix bits with the first one.

    int split = first; // initial guess
    int step = last - first;

    do
    {
        step = ( step + 1 ) >> 1;     // exponential decrease
        int new_split = split + step; // proposed new position

        if ( new_split < last )
        {
            unsigned int split_code = sorted_morton_codes[new_split];
            int split_prefix = clz( first_code ^ split_code );
            if ( split_prefix > common_prefix )
                split = new_split; // accept proposal
        }
    } while ( step > 1 );

    return split;
}

template <typename DeviceType>
Kokkos::pair<int, int> TreeConstruction<DeviceType>::determineRange(
    Kokkos::View<unsigned int *, DeviceType> sorted_morton_codes, int i )
{
    // determine direction of the range (+1 or -1)
    int direction =
        KokkosHelpers::sgn( commonPrefix( sorted_morton_codes, i, i + 1 ) -
                            commonPrefix( sorted_morton_codes, i, i - 1 ) );
    assert( direction == +1 || direction == -1 );

    // compute upper bound for the length of the range
    int max_step = 2;
    int common_prefix = commonPrefix( sorted_morton_codes, i, i - direction );

    // compute upper bound for the length of the range
    while ( commonPrefix( sorted_morton_codes, i, i + direction * max_step ) >
            common_prefix )
    {
        max_step = max_step << 1;
    }

    // find the other end using binary search
    int split = 0;
    int step = max_step;
    do
    {
        step = step >> 1;
        if ( commonPrefix( sorted_morton_codes, i,
                           i + ( split + step ) * direction ) > common_prefix )
            split += step;
    } while ( step > 1 );
    int j = i + split * direction;

    return {KokkosHelpers::min( i, j ), KokkosHelpers::max( i, j )};
}
}
}

// Explicit instantiation macro
#define DTK_TREECONSTRUCTION_INSTANT( NODE )                                   \
    namespace Details                                                          \
    {                                                                          \
    template struct TreeConstruction<typename NODE::device_type>;              \
    }

#endif
<|endoftext|>