<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: line.cxx,v $
 * $Revision: 1.6 $
 *
 * 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_tools.hxx"

#define _LINE_CXX
#include <tools/link.hxx>
#include <tools/line.hxx>
#include <tools/debug.hxx>

#include <cstdlib>
#include <cmath>

inline long FRound( double fVal )
{
    return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
}

// --------
// - Line -
// --------

double Line::GetLength() const
{
    return hypot( maStart.X() - maEnd.X(), maStart.Y() - maEnd.Y() );
}

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

BOOL Line::Intersection( const Line& rLine, Point& rIntersection ) const
{
    double  fX, fY;
    BOOL    bRet;

    if( Intersection( rLine, fX, fY ) )
    {
        rIntersection.X() = FRound( fX );
        rIntersection.Y() = FRound( fY );
        bRet = TRUE;
    }
    else
        bRet = FALSE;

    return bRet;
}

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

BOOL Line::Intersection( const Line& rLine, double& rIntersectionX, double& rIntersectionY ) const
{
    const double    fAx = maEnd.X() - maStart.X();
    const double    fAy = maEnd.Y() - maStart.Y();
    const double    fBx = rLine.maStart.X() - rLine.maEnd.X();
    const double    fBy = rLine.maStart.Y() - rLine.maEnd.Y();
    const double    fDen = fAy * fBx - fAx * fBy;
    BOOL            bOk = FALSE;

    if( fDen != 0. )
    {
        const double    fCx = maStart.X() - rLine.maStart.X();
        const double    fCy = maStart.Y() - rLine.maStart.Y();
        const double    fA = fBy * fCx - fBx * fCy;
        const BOOL      bGreater = ( fDen > 0. );

        bOk = TRUE;

        if ( bGreater )
        {
            if ( ( fA < 0. ) || ( fA > fDen ) )
                bOk = FALSE;
        }
        else if ( ( fA > 0. ) || ( fA < fDen ) )
            bOk = FALSE;

        if ( bOk )
        {
            const double fB = fAx * fCy - fAy * fCx;

            if ( bGreater )
            {
                if ( ( fB < 0. ) || ( fB > fDen ) )
                    bOk = FALSE;
            }
            else if ( ( fB > 0. ) || ( fB < fDen ) )
                bOk = FALSE;

            if( bOk )
            {
                const double fAlpha = fA / fDen;

                rIntersectionX = ( maStart.X() + fAlpha * fAx );
                rIntersectionY = ( maStart.Y() + fAlpha * fAy );
            }
        }
    }

    return bOk;
}

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

BOOL Line::Intersection( const Rectangle& rRect, Line& rIntersection ) const
{
    const BOOL  bStartInside = rRect.IsInside( maStart );
    const BOOL  bEndInside = rRect.IsInside( maEnd );
    BOOL        bRet = TRUE;

    if( bStartInside && bEndInside )
    {
        // line completely inside rect
        rIntersection.maStart = maStart;
        rIntersection.maEnd = maEnd;
    }
    else
    {
        // calculate intersections
        const Point aTL( rRect.TopLeft() ), aTR( rRect.TopRight() );
        const Point aBR( rRect.BottomRight() ), aBL( rRect.BottomLeft() );
        Point       aIntersect1, aIntersect2;
        Point*      pCurIntersection = &aIntersect1;

        if( Intersection( Line( aTL, aTR ), *pCurIntersection ) )
            pCurIntersection = &aIntersect2;

        if( Intersection( Line( aTR, aBR ), *pCurIntersection ) )
            pCurIntersection = ( pCurIntersection == &aIntersect1 ) ? &aIntersect2 : NULL;

        if( pCurIntersection && Intersection( Line( aBR, aBL ), *pCurIntersection ) )
            pCurIntersection = ( pCurIntersection == &aIntersect1 ) ? &aIntersect2 : NULL;

        if( pCurIntersection && Intersection( Line( aBL, aTL ), *pCurIntersection ) )
            pCurIntersection = ( pCurIntersection == &aIntersect1 ) ? &aIntersect2 : NULL;

        if( !pCurIntersection )
        {
            // two intersections
            rIntersection.maStart = aIntersect1;
            rIntersection.maEnd = aIntersect2;
        }
        else if( pCurIntersection == &aIntersect2 )
        {
            // one intersection
            rIntersection.maStart = aIntersect1;

            if( ( maStart != aIntersect1 ) && bStartInside )
                rIntersection.maEnd = maStart;
            else if( ( maEnd != aIntersect1 ) && bEndInside )
                rIntersection.maEnd = maEnd;
            else
                rIntersection.maEnd = rIntersection.maStart;
        }
        else
            bRet = FALSE;
    }

    return bRet;
}

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

Point Line::NearestPoint( const Point& rPoint ) const
{
    Point aRetPt;

    if ( maStart != maEnd )
    {
        const double    fDistX = maEnd.X() - maStart.X();
        const double    fDistY = maStart.Y() - maEnd.Y();
        const double    fTau = ( ( maStart.Y() - rPoint.Y() ) * fDistY -
                                 ( maStart.X() - rPoint.X() ) * fDistX ) /
                               ( fDistX * fDistX + fDistY * fDistY );

        if( fTau < 0.0 )
            aRetPt = maStart;
        else if( fTau <= 1.0 )
        {
            aRetPt.X() = FRound( maStart.X() + fTau * fDistX );
            aRetPt.Y() = FRound( maStart.Y() - fTau * fDistY );
        }
        else
            aRetPt = maEnd;
    }
    else
        aRetPt = maStart;

    return aRetPt;
}

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

double Line::GetDistance( const double& rPtX, const double& rPtY ) const
{
    double fDist;

    if( maStart != maEnd )
    {
        const double    fDistX = maEnd.X() - maStart.X();
        const double    fDistY = maEnd.Y() - maStart.Y();
        const double    fACX = maStart.X() - rPtX;
        const double    fACY = maStart.Y() - rPtY;
        const double    fL2 = fDistX * fDistX + fDistY * fDistY;
        const double    fR = ( fACY * -fDistY - fACX * fDistX ) / fL2;
        const double    fS = ( fACY * fDistX - fACX * fDistY ) / fL2;

        if( fR < 0.0 )
        {
            fDist = hypot( maStart.X() - rPtX, maStart.Y() - rPtY );

            if( fS < 0.0 )
                fDist *= -1.0;
        }
        else if( fR <= 1.0 )
            fDist = fS * sqrt( fL2 );
        else
        {
            fDist = hypot( maEnd.X() - rPtX, maEnd.Y() - rPtY );

            if( fS < 0.0 )
                fDist *= -1.0;
        }
    }
    else
        fDist = hypot( maStart.X() - rPtX, maStart.Y() - rPtY );

    return fDist;
}

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

void Line::Enum( const Link& rEnumLink )
{
    DBG_ASSERT( rEnumLink.IsSet(), "This call doesn't make any sense with !rEnumLink.IsSet()" );

    Point   aEnum;
    long    nX;
    long    nY;

    if( maStart.X() == maEnd.X() )
    {
        const long nEndY = maEnd.Y();

        nX = maStart.X();
        nY = maStart.Y();

        if( nEndY > nY )
        {
            while( nY <= nEndY )
            {
                aEnum.X() = nX;
                aEnum.Y() = nY++;
                rEnumLink.Call( &aEnum );
            }
        }
        else
        {
            while( nY >= nEndY )
            {
                aEnum.X() = nX;
                aEnum.Y() = nY--;
                rEnumLink.Call( &aEnum );
            }
        }
    }
    else if( maStart.Y() == maEnd.Y() )
    {
        const long nEndX = maEnd.X();

        nX = maStart.X();
        nY = maStart.Y();

        if( nEndX > nX )
        {
            while( nX <= nEndX )
            {
                aEnum.X() = nX++;
                aEnum.Y() = nY;
                rEnumLink.Call( &aEnum );
            }
        }
        else
        {
            while( nX >= nEndX )
            {
                aEnum.X() = nX--;
                aEnum.Y() = nY;
                rEnumLink.Call( &aEnum );
            }
        }
    }
    else
    {
        const long  nDX = labs( maEnd.X() - maStart.X() );
        const long  nDY = labs( maEnd.Y() - maStart.Y() );
        const long  nStartX = maStart.X();
        const long  nStartY = maStart.Y();
        const long  nEndX = maEnd.X();
        const long  nEndY = maEnd.Y();
        const long  nXInc = ( nStartX < nEndX ) ? 1L : -1L;
        const long  nYInc = ( nStartY < nEndY ) ? 1L : -1L;

        if( nDX >= nDY )
        {
            const long  nDYX = ( nDY - nDX ) << 1;
            const long  nDY2 = nDY << 1;
            long        nD = nDY2 - nDX;

            for( nX = nStartX, nY = nStartY; nX != nEndX; nX += nXInc )
            {
                aEnum.X() = nX;
                aEnum.Y() = nY;
                rEnumLink.Call( &aEnum );

                if( nD < 0L )
                    nD += nDY2;
                else
                    nD += nDYX, nY += nYInc;
            }
        }
        else
        {
            const long  nDYX = ( nDX - nDY ) << 1;
            const long  nDY2 = nDX << 1;
            long        nD = nDY2 - nDY;

            for( nX = nStartX, nY = nStartY; nY != nEndY; nY += nYInc )
            {
                aEnum.X() = nX;
                aEnum.Y() = nY;
                rEnumLink.Call( &aEnum );

                if( nD < 0L )
                    nD += nDY2;
                else
                    nD += nDYX, nX += nXInc;
            }
        }

        // last point
        aEnum.X() = nEndX;
        aEnum.Y() = nEndY;
        rEnumLink.Call( &aEnum );
    }
}
<commit_msg>INTEGRATION: CWS hr51 (1.6.16); FILE MERGED 2008/06/06 14:13:38 hr 1.6.16.1: #i88947#: includes; namespaces<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: line.cxx,v $
 * $Revision: 1.7 $
 *
 * 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_tools.hxx"

#define _LINE_CXX
#include <tools/link.hxx>
#include <tools/line.hxx>
#include <tools/debug.hxx>

#include <cstdlib>
#include <cmath>    // std::sqrt
#include <math.h>   // hypot, doens't seem to live in std namespace everywhere

inline long FRound( double fVal )
{
    return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
}

// --------
// - Line -
// --------

double Line::GetLength() const
{
    return hypot( maStart.X() - maEnd.X(), maStart.Y() - maEnd.Y() );
}

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

BOOL Line::Intersection( const Line& rLine, Point& rIntersection ) const
{
    double  fX, fY;
    BOOL    bRet;

    if( Intersection( rLine, fX, fY ) )
    {
        rIntersection.X() = FRound( fX );
        rIntersection.Y() = FRound( fY );
        bRet = TRUE;
    }
    else
        bRet = FALSE;

    return bRet;
}

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

BOOL Line::Intersection( const Line& rLine, double& rIntersectionX, double& rIntersectionY ) const
{
    const double    fAx = maEnd.X() - maStart.X();
    const double    fAy = maEnd.Y() - maStart.Y();
    const double    fBx = rLine.maStart.X() - rLine.maEnd.X();
    const double    fBy = rLine.maStart.Y() - rLine.maEnd.Y();
    const double    fDen = fAy * fBx - fAx * fBy;
    BOOL            bOk = FALSE;

    if( fDen != 0. )
    {
        const double    fCx = maStart.X() - rLine.maStart.X();
        const double    fCy = maStart.Y() - rLine.maStart.Y();
        const double    fA = fBy * fCx - fBx * fCy;
        const BOOL      bGreater = ( fDen > 0. );

        bOk = TRUE;

        if ( bGreater )
        {
            if ( ( fA < 0. ) || ( fA > fDen ) )
                bOk = FALSE;
        }
        else if ( ( fA > 0. ) || ( fA < fDen ) )
            bOk = FALSE;

        if ( bOk )
        {
            const double fB = fAx * fCy - fAy * fCx;

            if ( bGreater )
            {
                if ( ( fB < 0. ) || ( fB > fDen ) )
                    bOk = FALSE;
            }
            else if ( ( fB > 0. ) || ( fB < fDen ) )
                bOk = FALSE;

            if( bOk )
            {
                const double fAlpha = fA / fDen;

                rIntersectionX = ( maStart.X() + fAlpha * fAx );
                rIntersectionY = ( maStart.Y() + fAlpha * fAy );
            }
        }
    }

    return bOk;
}

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

BOOL Line::Intersection( const Rectangle& rRect, Line& rIntersection ) const
{
    const BOOL  bStartInside = rRect.IsInside( maStart );
    const BOOL  bEndInside = rRect.IsInside( maEnd );
    BOOL        bRet = TRUE;

    if( bStartInside && bEndInside )
    {
        // line completely inside rect
        rIntersection.maStart = maStart;
        rIntersection.maEnd = maEnd;
    }
    else
    {
        // calculate intersections
        const Point aTL( rRect.TopLeft() ), aTR( rRect.TopRight() );
        const Point aBR( rRect.BottomRight() ), aBL( rRect.BottomLeft() );
        Point       aIntersect1, aIntersect2;
        Point*      pCurIntersection = &aIntersect1;

        if( Intersection( Line( aTL, aTR ), *pCurIntersection ) )
            pCurIntersection = &aIntersect2;

        if( Intersection( Line( aTR, aBR ), *pCurIntersection ) )
            pCurIntersection = ( pCurIntersection == &aIntersect1 ) ? &aIntersect2 : NULL;

        if( pCurIntersection && Intersection( Line( aBR, aBL ), *pCurIntersection ) )
            pCurIntersection = ( pCurIntersection == &aIntersect1 ) ? &aIntersect2 : NULL;

        if( pCurIntersection && Intersection( Line( aBL, aTL ), *pCurIntersection ) )
            pCurIntersection = ( pCurIntersection == &aIntersect1 ) ? &aIntersect2 : NULL;

        if( !pCurIntersection )
        {
            // two intersections
            rIntersection.maStart = aIntersect1;
            rIntersection.maEnd = aIntersect2;
        }
        else if( pCurIntersection == &aIntersect2 )
        {
            // one intersection
            rIntersection.maStart = aIntersect1;

            if( ( maStart != aIntersect1 ) && bStartInside )
                rIntersection.maEnd = maStart;
            else if( ( maEnd != aIntersect1 ) && bEndInside )
                rIntersection.maEnd = maEnd;
            else
                rIntersection.maEnd = rIntersection.maStart;
        }
        else
            bRet = FALSE;
    }

    return bRet;
}

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

Point Line::NearestPoint( const Point& rPoint ) const
{
    Point aRetPt;

    if ( maStart != maEnd )
    {
        const double    fDistX = maEnd.X() - maStart.X();
        const double    fDistY = maStart.Y() - maEnd.Y();
        const double    fTau = ( ( maStart.Y() - rPoint.Y() ) * fDistY -
                                 ( maStart.X() - rPoint.X() ) * fDistX ) /
                               ( fDistX * fDistX + fDistY * fDistY );

        if( fTau < 0.0 )
            aRetPt = maStart;
        else if( fTau <= 1.0 )
        {
            aRetPt.X() = FRound( maStart.X() + fTau * fDistX );
            aRetPt.Y() = FRound( maStart.Y() - fTau * fDistY );
        }
        else
            aRetPt = maEnd;
    }
    else
        aRetPt = maStart;

    return aRetPt;
}

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

double Line::GetDistance( const double& rPtX, const double& rPtY ) const
{
    double fDist;

    if( maStart != maEnd )
    {
        const double    fDistX = maEnd.X() - maStart.X();
        const double    fDistY = maEnd.Y() - maStart.Y();
        const double    fACX = maStart.X() - rPtX;
        const double    fACY = maStart.Y() - rPtY;
        const double    fL2 = fDistX * fDistX + fDistY * fDistY;
        const double    fR = ( fACY * -fDistY - fACX * fDistX ) / fL2;
        const double    fS = ( fACY * fDistX - fACX * fDistY ) / fL2;

        if( fR < 0.0 )
        {
            fDist = hypot( maStart.X() - rPtX, maStart.Y() - rPtY );

            if( fS < 0.0 )
                fDist *= -1.0;
        }
        else if( fR <= 1.0 )
            fDist = fS * std::sqrt( fL2 );
        else
        {
            fDist = hypot( maEnd.X() - rPtX, maEnd.Y() - rPtY );

            if( fS < 0.0 )
                fDist *= -1.0;
        }
    }
    else
        fDist = hypot( maStart.X() - rPtX, maStart.Y() - rPtY );

    return fDist;
}

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

void Line::Enum( const Link& rEnumLink )
{
    DBG_ASSERT( rEnumLink.IsSet(), "This call doesn't make any sense with !rEnumLink.IsSet()" );

    Point   aEnum;
    long    nX;
    long    nY;

    if( maStart.X() == maEnd.X() )
    {
        const long nEndY = maEnd.Y();

        nX = maStart.X();
        nY = maStart.Y();

        if( nEndY > nY )
        {
            while( nY <= nEndY )
            {
                aEnum.X() = nX;
                aEnum.Y() = nY++;
                rEnumLink.Call( &aEnum );
            }
        }
        else
        {
            while( nY >= nEndY )
            {
                aEnum.X() = nX;
                aEnum.Y() = nY--;
                rEnumLink.Call( &aEnum );
            }
        }
    }
    else if( maStart.Y() == maEnd.Y() )
    {
        const long nEndX = maEnd.X();

        nX = maStart.X();
        nY = maStart.Y();

        if( nEndX > nX )
        {
            while( nX <= nEndX )
            {
                aEnum.X() = nX++;
                aEnum.Y() = nY;
                rEnumLink.Call( &aEnum );
            }
        }
        else
        {
            while( nX >= nEndX )
            {
                aEnum.X() = nX--;
                aEnum.Y() = nY;
                rEnumLink.Call( &aEnum );
            }
        }
    }
    else
    {
        const long  nDX = labs( maEnd.X() - maStart.X() );
        const long  nDY = labs( maEnd.Y() - maStart.Y() );
        const long  nStartX = maStart.X();
        const long  nStartY = maStart.Y();
        const long  nEndX = maEnd.X();
        const long  nEndY = maEnd.Y();
        const long  nXInc = ( nStartX < nEndX ) ? 1L : -1L;
        const long  nYInc = ( nStartY < nEndY ) ? 1L : -1L;

        if( nDX >= nDY )
        {
            const long  nDYX = ( nDY - nDX ) << 1;
            const long  nDY2 = nDY << 1;
            long        nD = nDY2 - nDX;

            for( nX = nStartX, nY = nStartY; nX != nEndX; nX += nXInc )
            {
                aEnum.X() = nX;
                aEnum.Y() = nY;
                rEnumLink.Call( &aEnum );

                if( nD < 0L )
                    nD += nDY2;
                else
                    nD += nDYX, nY += nYInc;
            }
        }
        else
        {
            const long  nDYX = ( nDX - nDY ) << 1;
            const long  nDY2 = nDX << 1;
            long        nD = nDY2 - nDY;

            for( nX = nStartX, nY = nStartY; nY != nEndY; nY += nYInc )
            {
                aEnum.X() = nX;
                aEnum.Y() = nY;
                rEnumLink.Call( &aEnum );

                if( nD < 0L )
                    nD += nDY2;
                else
                    nD += nDYX, nX += nXInc;
            }
        }

        // last point
        aEnum.X() = nEndX;
        aEnum.Y() = nEndY;
        rEnumLink.Call( &aEnum );
    }
}
<|endoftext|>


<commit_before>//===--- OwnedToGuaranteedTransform.cpp -----------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "fso-owned-to-guaranteed-transform"
#include "FunctionSignatureOpts.h"
#include "swift/SIL/DebugUtils.h"
#include "llvm/Support/CommandLine.h"

using namespace swift;

static llvm::cl::opt<bool> FSODisableOwnedToGuaranteed(
    "sil-fso-disable-owned-to-guaranteed",
    llvm::cl::desc("Do not perform owned to guaranteed during FSO. Intended "
                   "only for testing purposes."));

//===----------------------------------------------------------------------===//
//                                 Utilities
//===----------------------------------------------------------------------===//

/// Return the single return value of the function.
static SILValue findReturnValue(SILFunction *F) {
  auto RBB = F->findReturnBB();
  if (RBB == F->end())
    return SILValue();
  auto Term = dyn_cast<ReturnInst>(RBB->getTerminator());
  return Term->getOperand();
}

/// Return the single apply found in this function.
static SILInstruction *findOnlyApply(SILFunction *F) {
  SILInstruction *OnlyApply = nullptr;
  for (auto &B : *F) {
    for (auto &X : B) {
      if (!isa<ApplyInst>(X) && !isa<TryApplyInst>(X))
        continue;
      assert(!OnlyApply && "There are more than 1 function calls");
      OnlyApply = &X;
    }
  }
  assert(OnlyApply && "There is no function calls");
  return OnlyApply;
}

//===----------------------------------------------------------------------===//
//                               Implementation
//===----------------------------------------------------------------------===//

bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeParameters() {
  SILFunction *F = TransformDescriptor.OriginalFunction;
  auto Args = F->begin()->getSILFunctionArguments();
  // A map from consumed SILArguments to the release associated with an
  // argument.
  //
  // TODO: The return block and throw block should really be abstracted away.
  SILArgumentConvention ArgumentConventions[] = {
      SILArgumentConvention::Direct_Owned, SILArgumentConvention::Indirect_In};
  ConsumedArgToEpilogueReleaseMatcher ArgToReturnReleaseMap(
      RCIA->get(F), F, ArgumentConventions);
  ConsumedArgToEpilogueReleaseMatcher ArgToThrowReleaseMap(
      RCIA->get(F), F, ArgumentConventions,
      ConsumedArgToEpilogueReleaseMatcher::ExitKind::Throw);

  // Did we decide we should optimize any parameter?
  bool SignatureOptimize = false;

  // Analyze the argument information.
  for (unsigned i : indices(Args)) {
    ArgumentDescriptor &A = TransformDescriptor.ArgumentDescList[i];
    if (!A.canOptimizeLiveArg()) {
      continue;
    }

    // See if we can find a ref count equivalent strong_release or release_value
    // at the end of this function if our argument is an @owned parameter.
    // See if we can find a destroy_addr at the end of this function if our
    // argument is an @in parameter.
    if (A.hasConvention(SILArgumentConvention::Direct_Owned) ||
        A.hasConvention(SILArgumentConvention::Indirect_In)) {
      auto Releases = ArgToReturnReleaseMap.getReleasesForArgument(A.Arg);
      if (!Releases.empty()) {
        // If the function has a throw block we must also find a matching
        // release in the throw block.
        auto ReleasesInThrow =
            ArgToThrowReleaseMap.getReleasesForArgument(A.Arg);
        if (!ArgToThrowReleaseMap.hasBlock() || !ReleasesInThrow.empty()) {
          assert(A.CalleeRelease.empty());
          assert(A.CalleeReleaseInThrowBlock.empty());
          llvm::copy(Releases, std::back_inserter(A.CalleeRelease));
          llvm::copy(ReleasesInThrow,
                     std::back_inserter(A.CalleeReleaseInThrowBlock));
          // We can convert this parameter to a @guaranteed.
          A.OwnedToGuaranteed = true;
          SignatureOptimize = true;
        }
      }
    }

    // Modified self argument.
    if (A.OwnedToGuaranteed && Args[i]->isSelf()) {
      TransformDescriptor.shouldModifySelfArgument = true;
    }
  }
  return SignatureOptimize;
}

bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeResults() {
  SILFunction *F = TransformDescriptor.OriginalFunction;
  auto ResultDescList = TransformDescriptor.ResultDescList;

  auto fnConv = F->getConventions();
  // For now, only do anything if there's a single direct result.
  if (fnConv.getNumDirectSILResults() != 1)
    return false;
  if (!fnConv.getIndirectSILResults().empty())
    return false;

  bool SignatureOptimize = false;
  if (ResultDescList[0].hasConvention(ResultConvention::Owned)) {
    auto RV = findReturnValue(F);
    if (!RV)
      return false;
    auto &RI = ResultDescList[0];
    // We have an @owned return value, find the epilogue retains now.
    auto Retains = EA->get(F)->computeEpilogueARCInstructions(
        EpilogueARCContext::EpilogueARCKind::Retain, RV);
    // We do not need to worry about the throw block, as the return value is
    // only going to be used in the return block/normal block of the try_apply
    // instruction.
    if (!Retains.empty()) {
      RI.CalleeRetain = Retains;
      SignatureOptimize = true;
      RI.OwnedToGuaranteed = true;
    }
  }
  return SignatureOptimize;
}

void
FunctionSignatureTransform::OwnedToGuaranteedTransformFunctionParameters() {
  // And remove all Callee releases that we found and made redundant via owned
  // to guaranteed conversion.
  for (const ArgumentDescriptor &AD : TransformDescriptor.ArgumentDescList) {
    if (!AD.OwnedToGuaranteed)
      continue;
    for (auto &X : AD.CalleeRelease) {
      X->eraseFromParent();
    }
    for (auto &X : AD.CalleeReleaseInThrowBlock) {
      X->eraseFromParent();
    }

    // Now we need to replace the FunctionArgument so that we have the correct
    // ValueOwnershipKind.
    AD.Arg->setOwnershipKind(ValueOwnershipKind::Guaranteed);
  }
}

void FunctionSignatureTransform::OwnedToGuaranteedTransformFunctionResults() {
  // And remove all callee retains that we found and made redundant via owned
  // to unowned conversion.
  for (const ResultDescriptor &RD : TransformDescriptor.ResultDescList) {
    if (!RD.OwnedToGuaranteed)
      continue;
    for (auto &X : RD.CalleeRetain) {
      if (isa<StrongRetainInst>(X) || isa<RetainValueInst>(X)) {
        X->eraseFromParent();
        continue;
      }
      // Create a release to balance it out.
      auto AI = cast<ApplyInst>(X);
      createDecrementBefore(AI, AI->getParent()->getTerminator());
    }
  }
}

void FunctionSignatureTransform::OwnedToGuaranteedFinalizeThunkFunction(
    SILBuilder &Builder, SILFunction *F) {
  // Finish the epilogue work for the argument as well as result.
  for (auto &ArgDesc : TransformDescriptor.ArgumentDescList) {
    OwnedToGuaranteedAddArgumentRelease(ArgDesc, Builder, F);
  }
  for (auto &ResDesc : TransformDescriptor.ResultDescList) {
    OwnedToGuaranteedAddResultRelease(ResDesc, Builder, F);
  }
}

static void createArgumentRelease(SILBuilder &Builder, ArgumentDescriptor &AD) {
  auto &F = Builder.getFunction();
  SILArgument *Arg = F.getArguments()[AD.Index];
  if (Arg->getType().isAddress()) {
    assert(AD.PInfo->getConvention() == ParameterConvention::Indirect_In &&
           F.getConventions().useLoweredAddresses());
    Builder.createDestroyAddr(RegularLocation::getAutoGeneratedLocation(),
                              F.getArguments()[AD.Index]);
    return;
  }
  Builder.createReleaseValue(RegularLocation::getAutoGeneratedLocation(),
                             F.getArguments()[AD.Index],
                             Builder.getDefaultAtomicity());
}

/// Set up epilogue work for the thunk arguments based in the given argument.
/// Default implementation simply passes it through.
void FunctionSignatureTransform::OwnedToGuaranteedAddArgumentRelease(
    ArgumentDescriptor &AD, SILBuilder &Builder, SILFunction *F) {
  // If we have any arguments that were consumed but are now guaranteed,
  // insert a releasing RC instruction.
  if (!AD.OwnedToGuaranteed) {
    return;
  }

  SILInstruction *Call = findOnlyApply(F);
  if (isa<ApplyInst>(Call)) {
    Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(Call)));
    createArgumentRelease(Builder, AD);
  } else {
    SILBasicBlock *NormalBB = dyn_cast<TryApplyInst>(Call)->getNormalBB();
    Builder.setInsertionPoint(&*NormalBB->begin());
    createArgumentRelease(Builder, AD);

    SILBasicBlock *ErrorBB = dyn_cast<TryApplyInst>(Call)->getErrorBB();
    Builder.setInsertionPoint(&*ErrorBB->begin());
    createArgumentRelease(Builder, AD);
  }
}

void FunctionSignatureTransform::OwnedToGuaranteedAddResultRelease(
    ResultDescriptor &RD, SILBuilder &Builder, SILFunction *F) {
  // If we have any result that were consumed but are now guaranteed,
  // insert a releasing RC instruction.
  if (!RD.OwnedToGuaranteed) {
    return;
  }

  SILInstruction *Call = findOnlyApply(F);
  if (auto AI = dyn_cast<ApplyInst>(Call)) {
    Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(AI)));
    Builder.createRetainValue(RegularLocation::getAutoGeneratedLocation(), AI,
                              Builder.getDefaultAtomicity());
  } else {
    SILBasicBlock *NormalBB = cast<TryApplyInst>(Call)->getNormalBB();
    Builder.setInsertionPoint(&*NormalBB->begin());
    Builder.createRetainValue(RegularLocation::getAutoGeneratedLocation(),
                              NormalBB->getArgument(0),
                              Builder.getDefaultAtomicity());
  }
}

bool FunctionSignatureTransform::OwnedToGuaranteedAnalyze() {
  if (FSODisableOwnedToGuaranteed)
    return false;

  bool Result = OwnedToGuaranteedAnalyzeResults();
  bool Params = OwnedToGuaranteedAnalyzeParameters();
  return Params || Result;
}

void FunctionSignatureTransform::OwnedToGuaranteedTransform() {
  OwnedToGuaranteedTransformFunctionResults();
  OwnedToGuaranteedTransformFunctionParameters();
}
<commit_msg>Make booleans const<commit_after>//===--- OwnedToGuaranteedTransform.cpp -----------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "fso-owned-to-guaranteed-transform"
#include "FunctionSignatureOpts.h"
#include "swift/SIL/DebugUtils.h"
#include "llvm/Support/CommandLine.h"

using namespace swift;

static llvm::cl::opt<bool> FSODisableOwnedToGuaranteed(
    "sil-fso-disable-owned-to-guaranteed",
    llvm::cl::desc("Do not perform owned to guaranteed during FSO. Intended "
                   "only for testing purposes."));

//===----------------------------------------------------------------------===//
//                                 Utilities
//===----------------------------------------------------------------------===//

/// Return the single return value of the function.
static SILValue findReturnValue(SILFunction *F) {
  auto RBB = F->findReturnBB();
  if (RBB == F->end())
    return SILValue();
  auto Term = dyn_cast<ReturnInst>(RBB->getTerminator());
  return Term->getOperand();
}

/// Return the single apply found in this function.
static SILInstruction *findOnlyApply(SILFunction *F) {
  SILInstruction *OnlyApply = nullptr;
  for (auto &B : *F) {
    for (auto &X : B) {
      if (!isa<ApplyInst>(X) && !isa<TryApplyInst>(X))
        continue;
      assert(!OnlyApply && "There are more than 1 function calls");
      OnlyApply = &X;
    }
  }
  assert(OnlyApply && "There is no function calls");
  return OnlyApply;
}

//===----------------------------------------------------------------------===//
//                               Implementation
//===----------------------------------------------------------------------===//

bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeParameters() {
  SILFunction *F = TransformDescriptor.OriginalFunction;
  auto Args = F->begin()->getSILFunctionArguments();
  // A map from consumed SILArguments to the release associated with an
  // argument.
  //
  // TODO: The return block and throw block should really be abstracted away.
  SILArgumentConvention ArgumentConventions[] = {
      SILArgumentConvention::Direct_Owned, SILArgumentConvention::Indirect_In};
  ConsumedArgToEpilogueReleaseMatcher ArgToReturnReleaseMap(
      RCIA->get(F), F, ArgumentConventions);
  ConsumedArgToEpilogueReleaseMatcher ArgToThrowReleaseMap(
      RCIA->get(F), F, ArgumentConventions,
      ConsumedArgToEpilogueReleaseMatcher::ExitKind::Throw);

  // Did we decide we should optimize any parameter?
  bool SignatureOptimize = false;

  // Analyze the argument information.
  for (unsigned i : indices(Args)) {
    ArgumentDescriptor &A = TransformDescriptor.ArgumentDescList[i];
    if (!A.canOptimizeLiveArg()) {
      continue;
    }

    // See if we can find a ref count equivalent strong_release or release_value
    // at the end of this function if our argument is an @owned parameter.
    // See if we can find a destroy_addr at the end of this function if our
    // argument is an @in parameter.
    if (A.hasConvention(SILArgumentConvention::Direct_Owned) ||
        A.hasConvention(SILArgumentConvention::Indirect_In)) {
      auto Releases = ArgToReturnReleaseMap.getReleasesForArgument(A.Arg);
      if (!Releases.empty()) {
        // If the function has a throw block we must also find a matching
        // release in the throw block.
        auto ReleasesInThrow =
            ArgToThrowReleaseMap.getReleasesForArgument(A.Arg);
        if (!ArgToThrowReleaseMap.hasBlock() || !ReleasesInThrow.empty()) {
          assert(A.CalleeRelease.empty());
          assert(A.CalleeReleaseInThrowBlock.empty());
          llvm::copy(Releases, std::back_inserter(A.CalleeRelease));
          llvm::copy(ReleasesInThrow,
                     std::back_inserter(A.CalleeReleaseInThrowBlock));
          // We can convert this parameter to a @guaranteed.
          A.OwnedToGuaranteed = true;
          SignatureOptimize = true;
        }
      }
    }

    // Modified self argument.
    if (A.OwnedToGuaranteed && Args[i]->isSelf()) {
      TransformDescriptor.shouldModifySelfArgument = true;
    }
  }
  return SignatureOptimize;
}

bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeResults() {
  SILFunction *F = TransformDescriptor.OriginalFunction;
  auto ResultDescList = TransformDescriptor.ResultDescList;

  auto fnConv = F->getConventions();
  // For now, only do anything if there's a single direct result.
  if (fnConv.getNumDirectSILResults() != 1)
    return false;
  if (!fnConv.getIndirectSILResults().empty())
    return false;

  bool SignatureOptimize = false;
  if (ResultDescList[0].hasConvention(ResultConvention::Owned)) {
    auto RV = findReturnValue(F);
    if (!RV)
      return false;
    auto &RI = ResultDescList[0];
    // We have an @owned return value, find the epilogue retains now.
    auto Retains = EA->get(F)->computeEpilogueARCInstructions(
        EpilogueARCContext::EpilogueARCKind::Retain, RV);
    // We do not need to worry about the throw block, as the return value is
    // only going to be used in the return block/normal block of the try_apply
    // instruction.
    if (!Retains.empty()) {
      RI.CalleeRetain = Retains;
      SignatureOptimize = true;
      RI.OwnedToGuaranteed = true;
    }
  }
  return SignatureOptimize;
}

void
FunctionSignatureTransform::OwnedToGuaranteedTransformFunctionParameters() {
  // And remove all Callee releases that we found and made redundant via owned
  // to guaranteed conversion.
  for (const ArgumentDescriptor &AD : TransformDescriptor.ArgumentDescList) {
    if (!AD.OwnedToGuaranteed)
      continue;
    for (auto &X : AD.CalleeRelease) {
      X->eraseFromParent();
    }
    for (auto &X : AD.CalleeReleaseInThrowBlock) {
      X->eraseFromParent();
    }

    // Now we need to replace the FunctionArgument so that we have the correct
    // ValueOwnershipKind.
    AD.Arg->setOwnershipKind(ValueOwnershipKind::Guaranteed);
  }
}

void FunctionSignatureTransform::OwnedToGuaranteedTransformFunctionResults() {
  // And remove all callee retains that we found and made redundant via owned
  // to unowned conversion.
  for (const ResultDescriptor &RD : TransformDescriptor.ResultDescList) {
    if (!RD.OwnedToGuaranteed)
      continue;
    for (auto &X : RD.CalleeRetain) {
      if (isa<StrongRetainInst>(X) || isa<RetainValueInst>(X)) {
        X->eraseFromParent();
        continue;
      }
      // Create a release to balance it out.
      auto AI = cast<ApplyInst>(X);
      createDecrementBefore(AI, AI->getParent()->getTerminator());
    }
  }
}

void FunctionSignatureTransform::OwnedToGuaranteedFinalizeThunkFunction(
    SILBuilder &Builder, SILFunction *F) {
  // Finish the epilogue work for the argument as well as result.
  for (auto &ArgDesc : TransformDescriptor.ArgumentDescList) {
    OwnedToGuaranteedAddArgumentRelease(ArgDesc, Builder, F);
  }
  for (auto &ResDesc : TransformDescriptor.ResultDescList) {
    OwnedToGuaranteedAddResultRelease(ResDesc, Builder, F);
  }
}

static void createArgumentRelease(SILBuilder &Builder, ArgumentDescriptor &AD) {
  auto &F = Builder.getFunction();
  SILArgument *Arg = F.getArguments()[AD.Index];
  if (Arg->getType().isAddress()) {
    assert(AD.PInfo->getConvention() == ParameterConvention::Indirect_In &&
           F.getConventions().useLoweredAddresses());
    Builder.createDestroyAddr(RegularLocation::getAutoGeneratedLocation(),
                              F.getArguments()[AD.Index]);
    return;
  }
  Builder.createReleaseValue(RegularLocation::getAutoGeneratedLocation(),
                             F.getArguments()[AD.Index],
                             Builder.getDefaultAtomicity());
}

/// Set up epilogue work for the thunk arguments based in the given argument.
/// Default implementation simply passes it through.
void FunctionSignatureTransform::OwnedToGuaranteedAddArgumentRelease(
    ArgumentDescriptor &AD, SILBuilder &Builder, SILFunction *F) {
  // If we have any arguments that were consumed but are now guaranteed,
  // insert a releasing RC instruction.
  if (!AD.OwnedToGuaranteed) {
    return;
  }

  SILInstruction *Call = findOnlyApply(F);
  if (isa<ApplyInst>(Call)) {
    Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(Call)));
    createArgumentRelease(Builder, AD);
  } else {
    SILBasicBlock *NormalBB = dyn_cast<TryApplyInst>(Call)->getNormalBB();
    Builder.setInsertionPoint(&*NormalBB->begin());
    createArgumentRelease(Builder, AD);

    SILBasicBlock *ErrorBB = dyn_cast<TryApplyInst>(Call)->getErrorBB();
    Builder.setInsertionPoint(&*ErrorBB->begin());
    createArgumentRelease(Builder, AD);
  }
}

void FunctionSignatureTransform::OwnedToGuaranteedAddResultRelease(
    ResultDescriptor &RD, SILBuilder &Builder, SILFunction *F) {
  // If we have any result that were consumed but are now guaranteed,
  // insert a releasing RC instruction.
  if (!RD.OwnedToGuaranteed) {
    return;
  }

  SILInstruction *Call = findOnlyApply(F);
  if (auto AI = dyn_cast<ApplyInst>(Call)) {
    Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(AI)));
    Builder.createRetainValue(RegularLocation::getAutoGeneratedLocation(), AI,
                              Builder.getDefaultAtomicity());
  } else {
    SILBasicBlock *NormalBB = cast<TryApplyInst>(Call)->getNormalBB();
    Builder.setInsertionPoint(&*NormalBB->begin());
    Builder.createRetainValue(RegularLocation::getAutoGeneratedLocation(),
                              NormalBB->getArgument(0),
                              Builder.getDefaultAtomicity());
  }
}

bool FunctionSignatureTransform::OwnedToGuaranteedAnalyze() {
  if (FSODisableOwnedToGuaranteed)
    return false;

  const bool Result = OwnedToGuaranteedAnalyzeResults();
  const bool Params = OwnedToGuaranteedAnalyzeParameters();
  return Params || Result;
}

void FunctionSignatureTransform::OwnedToGuaranteedTransform() {
  OwnedToGuaranteedTransformFunctionResults();
  OwnedToGuaranteedTransformFunctionParameters();
}
<|endoftext|>


<commit_before>/*
* IF (RSA/RW) Operation
* (C) 1999-2007 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/if_op.h>
#include <botan/numthry.h>

namespace Botan {

/*
* Default_IF_Op Constructor
*/
Default_IF_Op::Default_IF_Op(const BigInt& e, const BigInt& n, const BigInt&,
                             const BigInt& p, const BigInt& q,
                             const BigInt& d1, const BigInt& d2,
                             const BigInt& c)
   {
   powermod_e_n = Fixed_Exponent_Power_Mod(e, n);

   if(d1 != 0 && d2 != 0 && p != 0 && q != 0)
      {
      powermod_d1_p = Fixed_Exponent_Power_Mod(d1, p);
      powermod_d2_q = Fixed_Exponent_Power_Mod(d2, q);
      reducer = Modular_Reducer(p);
      this->c = c;
      this->q = q;
      }
   }

/*
* Default IF Private Operation
*/
BigInt Default_IF_Op::private_op(const BigInt& i) const
   {
   if(q == 0)
      throw Internal_Error("Default_IF_Op::private_op: No private key");

   BigInt j1 = powermod_d1_p(i);
   BigInt j2 = powermod_d2_q(i);
   j1 = reducer.reduce(sub_mul(j1, j2, c));
   return mul_add(j1, q, j2);
   }

}
<commit_msg>In IF decryption, two large powmods are done, one mod p and one mod q. Spawn one of them off in a new thread and compute the other on the current thread. Performance on my Core2 shows a 60 to 90% improvement in overall speed in RSA private key operations. Will probably be even better once std::async is available (not currently in GCC) since it will probably use a thread pool which will amortize the thread creation/shutdown cost.<commit_after>/*
* IF (RSA/RW) Operation
* (C) 1999-2007 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/if_op.h>
#include <botan/numthry.h>
#include <future>
#include <thread>

namespace Botan {

/*
* Default_IF_Op Constructor
*/
Default_IF_Op::Default_IF_Op(const BigInt& e, const BigInt& n, const BigInt&,
                             const BigInt& p, const BigInt& q,
                             const BigInt& d1, const BigInt& d2,
                             const BigInt& c)
   {
   powermod_e_n = Fixed_Exponent_Power_Mod(e, n);

   if(d1 != 0 && d2 != 0 && p != 0 && q != 0)
      {
      powermod_d1_p = Fixed_Exponent_Power_Mod(d1, p);
      powermod_d2_q = Fixed_Exponent_Power_Mod(d2, q);
      reducer = Modular_Reducer(p);
      this->c = c;
      this->q = q;
      }
   }

/*
* Default IF Private Operation
*/
BigInt Default_IF_Op::private_op(const BigInt& i) const
   {
   if(q == 0)
      throw Internal_Error("Default_IF_Op::private_op: No private key");

   /*
   * A simple std::bind(powermod_d1_p, i) would work instead of a
   * lambda but GCC 4.5's std::result_of doesn't use decltype and gets
   * confused
   *
   * Todo: use std::async() once it is in GCC
   *    auto future_j1 = std::async(std::bind(powermod_d1_p, i));
   *    BigInt j2 = powermod_d2_q(i);
   *    BigInt j1 = future.get();
   */
   std::packaged_task<BigInt ()> task_j1([&]() { return powermod_d1_p(i); });
   auto future_j1 = task_j1.get_future();

   std::thread thr_j1(std::move(task_j1));

   BigInt j2 = powermod_d2_q(i);

   BigInt j1 = future_j1.get();

   thr_j1.join();

   j1 = reducer.reduce(sub_mul(j1, j2, c));
   return mul_add(j1, q, j2);
   }

}
<|endoftext|>


<commit_before>#include "batterywidget.h"
#include "batterytranslation.h"
#include "dcpbattery.h"
#include "dcpspaceritem.h"
#include "batterygconf.h"

#include <DuiButton>
#include <DuiLayout>
#include <DuiGridLayoutPolicy>
#include <DuiLinearLayoutPolicy>
#include <DuiLabel>
#include <DuiSlider>

BatteryWidget::BatteryWidget(QGraphicsWidget *parent)
	    :DcpWidget(parent)
{
    setReferer(DcpBattery::None);
    initWidget();
}

BatteryWidget::~BatteryWidget()
{
    delete batteryGConf;
    batteryGConf = NULL;
}

void BatteryWidget::initWidget()
{
    //create gconf if
    initBatteryGConf();

    //testing purposes
    batteryGConf->setRemainingTalkTime(140);
    batteryGConf->setRemainingStandByTime(340);
    batteryGConf->setPSMThreshold(20);
    QList<int> values;
    values << 10 << 20 << 30 << 60 << 90 << 120 << 150 << 180 << 210;
    batteryGConf->setPSMThresholdValues(values);
    batteryGConf->setPSMToggle(true);

    //create talkTimeLayout
    DuiLayout *talkTimeLayout = new DuiLayout(0);
    DuiGridLayoutPolicy *talkTimeLayoutPolicy = new DuiGridLayoutPolicy(talkTimeLayout);
    //TODO add the charging icon to position 0, 0, 1, 2
    talkTimeLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::TalkTimeText), 0, 1);
    talkTimeLabel = new DuiLabel(timeInString(batteryGConf->remainingTalkTime(), DcpBattery::TalkTimeValueText));
    talkTimeLayoutPolicy->addItemAtPosition(talkTimeLabel, 1, 1);

    //create standByTimeLayout
    DuiLayout *standByTimeLayout = new DuiLayout(0);
    DuiLinearLayoutPolicy *standByTimeLayoutPolicy = new DuiLinearLayoutPolicy(standByTimeLayout, Qt::Vertical);
    standByTimeLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::StandByTimeText), 0);
    standByTimeLabel = new DuiLabel(timeInString(batteryGConf->remainingStandByTime(), DcpBattery::StandByTimeValueText));
    standByTimeLayoutPolicy->addItemAtPosition(standByTimeLabel, 1);

    //create PSMLayout
    DuiLayout *PSMLayout = new DuiLayout(0);
    DuiGridLayoutPolicy *PSMLayoutPolicy = new DuiGridLayoutPolicy(PSMLayout);
    PSMLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::PSMText), 0, 0);
    PSMLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::NBCText), 1, 0);
    PSMButton = new DuiButton();
    PSMButton->setCheckable(true);
    updateButton(PSMButton, batteryGConf->PSMToggle());
    PSMLayoutPolicy->addItemAtPosition(PSMButton, 0, 1, 2, 1);

    //create upperLayout and put talkTimeLayot, standByTimeLayout and PSMLayout into it
    DuiLayout *upperLayout = new DuiLayout(0);
    DuiGridLayoutPolicy *upperLayoutPolicy = new DuiGridLayoutPolicy(upperLayout);
    upperLayoutPolicy->addItemAtPosition(talkTimeLayout, 0, 0);
    upperLayoutPolicy->addItemAtPosition(standByTimeLayout, 0, 1);
    upperLayoutPolicy->addItemAtPosition(PSMLayout, 1, 0);

    //create disablePSMLayout
    DuiLayout *disablePSMLayout = new DuiLayout(0);
    DuiLinearLayoutPolicy *disablePSMLayoutPolicy = new DuiLinearLayoutPolicy(disablePSMLayout, Qt::Horizontal);
    disablePSMButton = new DuiButton();
    disablePSMButton->setCheckable(true);
    updateButton(disablePSMButton, batteryGConf->PSMDisabled());
    disablePSMLayoutPolicy->addItemAtPosition(disablePSMButton, 0);
    disablePSMLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::DisablePSMText), 1);

    //create lowerLayout and put disablePSMLayout into it
    DuiLayout *lowerLayout = new DuiLayout(0);
    DuiLinearLayoutPolicy *lowerLayoutPolicy = new DuiLinearLayoutPolicy(lowerLayout, Qt::Vertical);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::AutoPSMText), 0);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::AutoPSMDescText), 1);
    lowerLayoutPolicy->addItemAtPosition(disablePSMLayout, 2);

    //temp duiLabel (as long as the duiSlider doesn't support thumbLabel)
    sliderLabel = new DuiLabel(timeInString(batteryGConf->PSMThreshold(), DcpBattery::PSMThresholdValueText));
    lowerLayoutPolicy->addItemAtPosition(sliderLabel, 3);

    initSlider();
    lowerLayoutPolicy->addItemAtPosition(slider, 4);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::AutoPSMAdv1Text), 5);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(QString("- " + DcpBattery::AutoPSMAdv2Text)), 6);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(QString("- " + DcpBattery::AutoPSMAdv3Text)), 7);

    /*
    landscapePolicy->addItemAtPosition(
                    new DcpSpacerItem(this, widgetWidth, 10, QSizePolicy::Expanding,
                    QSizePolicy::Expanding), 0, Qt::AlignLeft);
    mainLayoutPolicy->addItemAtPosition(centralLayout, 1, Qt::AlignHCenter);
    mainLayoutPolicy->addItemAtPosition(
                    new DcpSpacerItem(this, widgetWidth, 10, QSizePolicy::Expanding,
                    QSizePolicy::Expanding), 2, Qt::AlignRight);
                    */
    //create mainLayout
    DuiLayout *mainLayout = new DuiLayout(this);
    DuiLinearLayoutPolicy *landscapeLayoutPolicy = new DuiLinearLayoutPolicy(mainLayout, Qt::Vertical);
    //TODO create portraitLayoutPolicy and listen the orientation change signals
    landscapeLayoutPolicy->addItemAtPosition(upperLayout, 0);
    landscapeLayoutPolicy->addItemAtPosition(lowerLayout, 1);

    this->setLayout(mainLayout);
}

void BatteryWidget::initBatteryGConf()
{
    //define the slots that catch the changing GConf key values
    QHash<BatteryGConf::GConfKey, QString> keysAndSlots;
    keysAndSlots.insert(BatteryGConf::RemainingTalkTimeKey, "RemainingTalkTimeChanged");
    keysAndSlots.insert(BatteryGConf::RemainingStandByTimeKey, "RemainingTalkStandByChanged");
    keysAndSlots.insert(BatteryGConf::BatteryLevelKey, "BatteryLevelChanged");
    keysAndSlots.insert(BatteryGConf::ChargingKey, "ChargingChanged");

    batteryGConf = new BatteryGConf(this, keysAndSlots);
}

void BatteryWidget::initSlider()
{
    slider = new DuiSlider();

    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));

    sliderValues = batteryGConf->PSMThresholdValues();
    slider->setRange(0,sliderValues.size()-1);
    slider->setValue(sliderValues.indexOf(batteryGConf->PSMThreshold()));
    slider->setThumbLabel(timeInString(batteryGConf->PSMThreshold(), DcpBattery::PSMThresholdValueText));
    slider->setThumbLabelVisible(true);
    slider->setOrientation(Qt::Horizontal);
}

void BatteryWidget::sliderValueChanged(int newValue)
{
    slider->setThumbLabel(timeInString(sliderValues.at(newValue), DcpBattery::PSMThresholdValueText));

    //temp duiLabel (as long as the duiSlider doesn't support thumbLabel)
    sliderLabel->setText(timeInString(sliderValues.at(newValue), DcpBattery::PSMThresholdValueText));
}

QString BatteryWidget::timeInString(int time, QString pattern)
{
    //removing possible extra "!! " from in front
    QString patternCut = pattern.right(pattern.length() - pattern.indexOf("%1"));
    //saving possible extra "!! " from in front
    QString prefix = pattern.left(pattern.indexOf("%1"));

    QStringList list = patternCut.split("%1", QString::SkipEmptyParts);

    if(time < 60)
        return QString("%1%2%3").arg(prefix).arg(time).arg(list.at(0).trimmed());
    else {
        QVariant minutes = time%60;
        if(minutes.toInt() == 0)
            minutes = "00";
        return QString("%1%2:%3%4").arg(prefix).arg(time/60).arg(minutes.toString()).arg(list.at(1).trimmed());
    }
}

void BatteryWidget::updateButton(DuiButton *button, bool toggle)
{
    if(toggle)
        button->setText("ON");
    else
        button->setText("OFF");
    button->setChecked(toggle);
}

void BatteryWidget::BatteryPSMToggleChanged(QString key, bool value)
{
    qDebug() << "JAKAKAKAKKA: " << key << " JAKJKAJKJJKA " << value;
}
<commit_msg>Debug removed (compilation errors)<commit_after>#include "batterywidget.h"
#include "batterytranslation.h"
#include "dcpbattery.h"
#include "dcpspaceritem.h"
#include "batterygconf.h"

#include <DuiButton>
#include <DuiLayout>
#include <DuiGridLayoutPolicy>
#include <DuiLinearLayoutPolicy>
#include <DuiLabel>
#include <DuiSlider>

BatteryWidget::BatteryWidget(QGraphicsWidget *parent)
	    :DcpWidget(parent)
{
    setReferer(DcpBattery::None);
    initWidget();
}

BatteryWidget::~BatteryWidget()
{
    delete batteryGConf;
    batteryGConf = NULL;
}

void BatteryWidget::initWidget()
{
    //create gconf if
    initBatteryGConf();

    //testing purposes
    batteryGConf->setRemainingTalkTime(140);
    batteryGConf->setRemainingStandByTime(340);
    batteryGConf->setPSMThreshold(20);
    QList<int> values;
    values << 10 << 20 << 30 << 60 << 90 << 120 << 150 << 180 << 210;
    batteryGConf->setPSMThresholdValues(values);
    batteryGConf->setPSMToggle(true);

    //create talkTimeLayout
    DuiLayout *talkTimeLayout = new DuiLayout(0);
    DuiGridLayoutPolicy *talkTimeLayoutPolicy = new DuiGridLayoutPolicy(talkTimeLayout);
    //TODO add the charging icon to position 0, 0, 1, 2
    talkTimeLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::TalkTimeText), 0, 1);
    talkTimeLabel = new DuiLabel(timeInString(batteryGConf->remainingTalkTime(), DcpBattery::TalkTimeValueText));
    talkTimeLayoutPolicy->addItemAtPosition(talkTimeLabel, 1, 1);

    //create standByTimeLayout
    DuiLayout *standByTimeLayout = new DuiLayout(0);
    DuiLinearLayoutPolicy *standByTimeLayoutPolicy = new DuiLinearLayoutPolicy(standByTimeLayout, Qt::Vertical);
    standByTimeLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::StandByTimeText), 0);
    standByTimeLabel = new DuiLabel(timeInString(batteryGConf->remainingStandByTime(), DcpBattery::StandByTimeValueText));
    standByTimeLayoutPolicy->addItemAtPosition(standByTimeLabel, 1);

    //create PSMLayout
    DuiLayout *PSMLayout = new DuiLayout(0);
    DuiGridLayoutPolicy *PSMLayoutPolicy = new DuiGridLayoutPolicy(PSMLayout);
    PSMLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::PSMText), 0, 0);
    PSMLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::NBCText), 1, 0);
    PSMButton = new DuiButton();
    PSMButton->setCheckable(true);
    updateButton(PSMButton, batteryGConf->PSMToggle());
    PSMLayoutPolicy->addItemAtPosition(PSMButton, 0, 1, 2, 1);

    //create upperLayout and put talkTimeLayot, standByTimeLayout and PSMLayout into it
    DuiLayout *upperLayout = new DuiLayout(0);
    DuiGridLayoutPolicy *upperLayoutPolicy = new DuiGridLayoutPolicy(upperLayout);
    upperLayoutPolicy->addItemAtPosition(talkTimeLayout, 0, 0);
    upperLayoutPolicy->addItemAtPosition(standByTimeLayout, 0, 1);
    upperLayoutPolicy->addItemAtPosition(PSMLayout, 1, 0);

    //create disablePSMLayout
    DuiLayout *disablePSMLayout = new DuiLayout(0);
    DuiLinearLayoutPolicy *disablePSMLayoutPolicy = new DuiLinearLayoutPolicy(disablePSMLayout, Qt::Horizontal);
    disablePSMButton = new DuiButton();
    disablePSMButton->setCheckable(true);
    updateButton(disablePSMButton, batteryGConf->PSMDisabled());
    disablePSMLayoutPolicy->addItemAtPosition(disablePSMButton, 0);
    disablePSMLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::DisablePSMText), 1);

    //create lowerLayout and put disablePSMLayout into it
    DuiLayout *lowerLayout = new DuiLayout(0);
    DuiLinearLayoutPolicy *lowerLayoutPolicy = new DuiLinearLayoutPolicy(lowerLayout, Qt::Vertical);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::AutoPSMText), 0);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::AutoPSMDescText), 1);
    lowerLayoutPolicy->addItemAtPosition(disablePSMLayout, 2);

    //temp duiLabel (as long as the duiSlider doesn't support thumbLabel)
    sliderLabel = new DuiLabel(timeInString(batteryGConf->PSMThreshold(), DcpBattery::PSMThresholdValueText));
    lowerLayoutPolicy->addItemAtPosition(sliderLabel, 3);

    initSlider();
    lowerLayoutPolicy->addItemAtPosition(slider, 4);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(DcpBattery::AutoPSMAdv1Text), 5);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(QString("- " + DcpBattery::AutoPSMAdv2Text)), 6);
    lowerLayoutPolicy->addItemAtPosition(new DuiLabel(QString("- " + DcpBattery::AutoPSMAdv3Text)), 7);

    /*
    landscapePolicy->addItemAtPosition(
                    new DcpSpacerItem(this, widgetWidth, 10, QSizePolicy::Expanding,
                    QSizePolicy::Expanding), 0, Qt::AlignLeft);
    mainLayoutPolicy->addItemAtPosition(centralLayout, 1, Qt::AlignHCenter);
    mainLayoutPolicy->addItemAtPosition(
                    new DcpSpacerItem(this, widgetWidth, 10, QSizePolicy::Expanding,
                    QSizePolicy::Expanding), 2, Qt::AlignRight);
                    */
    //create mainLayout
    DuiLayout *mainLayout = new DuiLayout(this);
    DuiLinearLayoutPolicy *landscapeLayoutPolicy = new DuiLinearLayoutPolicy(mainLayout, Qt::Vertical);
    //TODO create portraitLayoutPolicy and listen the orientation change signals
    landscapeLayoutPolicy->addItemAtPosition(upperLayout, 0);
    landscapeLayoutPolicy->addItemAtPosition(lowerLayout, 1);

    this->setLayout(mainLayout);
}

void BatteryWidget::initBatteryGConf()
{
    //define the slots that catch the changing GConf key values
    QHash<BatteryGConf::GConfKey, QString> keysAndSlots;
    keysAndSlots.insert(BatteryGConf::RemainingTalkTimeKey, "RemainingTalkTimeChanged");
    keysAndSlots.insert(BatteryGConf::RemainingStandByTimeKey, "RemainingTalkStandByChanged");
    keysAndSlots.insert(BatteryGConf::BatteryLevelKey, "BatteryLevelChanged");
    keysAndSlots.insert(BatteryGConf::ChargingKey, "ChargingChanged");

    batteryGConf = new BatteryGConf(this, keysAndSlots);
}

void BatteryWidget::initSlider()
{
    slider = new DuiSlider();

    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));

    sliderValues = batteryGConf->PSMThresholdValues();
    slider->setRange(0,sliderValues.size()-1);
    slider->setValue(sliderValues.indexOf(batteryGConf->PSMThreshold()));
    slider->setThumbLabel(timeInString(batteryGConf->PSMThreshold(), DcpBattery::PSMThresholdValueText));
    slider->setThumbLabelVisible(true);
    slider->setOrientation(Qt::Horizontal);
}

void BatteryWidget::sliderValueChanged(int newValue)
{
    slider->setThumbLabel(timeInString(sliderValues.at(newValue), DcpBattery::PSMThresholdValueText));

    //temp duiLabel (as long as the duiSlider doesn't support thumbLabel)
    sliderLabel->setText(timeInString(sliderValues.at(newValue), DcpBattery::PSMThresholdValueText));
}

QString BatteryWidget::timeInString(int time, QString pattern)
{
    //removing possible extra "!! " from in front
    QString patternCut = pattern.right(pattern.length() - pattern.indexOf("%1"));
    //saving possible extra "!! " from in front
    QString prefix = pattern.left(pattern.indexOf("%1"));

    QStringList list = patternCut.split("%1", QString::SkipEmptyParts);

    if(time < 60)
        return QString("%1%2%3").arg(prefix).arg(time).arg(list.at(0).trimmed());
    else {
        QVariant minutes = time%60;
        if(minutes.toInt() == 0)
            minutes = "00";
        return QString("%1%2:%3%4").arg(prefix).arg(time/60).arg(minutes.toString()).arg(list.at(1).trimmed());
    }
}

void BatteryWidget::updateButton(DuiButton *button, bool toggle)
{
    if(toggle)
        button->setText("ON");
    else
        button->setText("OFF");
    button->setChecked(toggle);
}

void BatteryWidget::BatteryPSMToggleChanged(QString key, bool value)
{
}
<|endoftext|>


<commit_before>#include <bench/spbench/spbenchsolver.h>

void bench_printhelp()
{
    cout<< " \nbenchsolver : performs a benchmark of all the solvers available in Eigen \n\n";
    cout<< " MATRIX FOLDER : \n";
    cout<< " The matrices for the benchmark should be collected in a folder specified with an environment variable EIGEN_MATRIXDIR \n";
    cout<< " This folder should contain the subfolders real/ and complex/ : \n";
    cout<< " The matrices are stored using the matrix market coordinate format \n";
    cout<< " The matrix and associated right-hand side (rhs) files are named respectively \n";
    cout<< " as MatrixName.mtx and MatrixName_b.mtx. If the rhs does not exist, a random one is generated. \n";
    cout<< " If a matrix is SPD, the matrix should be named as MatrixName_SPD.mtx \n";
    cout<< " If a true solution exists, it should be named as MatrixName_x.mtx; \n"     ;
    cout<< " it will be used to compute the norm of the error relative to the computed solutions\n\n";
    cout<< " OPTIONS : \n";
    cout<< " -h or --help \n    print this help and return\n\n";
    cout<< " -d matrixdir \n    Use matrixdir as the matrix folder instead of the one specified in the environment variable EIGEN_MATRIXDIR\n\n";
    cout<< " -o outputfile.html \n    Output the statistics to a html file \n\n";
    cout<< " --eps <RelErr> Sets the relative tolerance for iterative solvers (default 1e-08)
    cout<< " --maxits <MaxIts> Sets the maximum number of iterations (default 1000)

}
int main(int argc, char ** args)
{

  bool help = ( get_options(argc, args, "-h") || get_options(argc, args, "--help") );
  if(help) {
    bench_printhelp();
    return 0;
  }

  // Get the location of the test matrices
  string matrix_dir;
  if (!get_options(argc, args, "-d", &matrix_dir))
  {
    if(getenv("EIGEN_MATRIXDIR") == NULL){
      std::cerr << "Please, specify the location of the matrices with -d mat_folder or the environment variable EIGEN_MATRIXDIR \n";
      std::cerr << " Run with --help to see the list of all the available options \n";
      return -1;
    }
    matrix_dir = getenv("EIGEN_MATRIXDIR");
  }

  std::ofstream statbuf;
  string statFile ;

  // Get the file to write the statistics
  bool statFileExists = get_options(argc, args, "-o", &statFile);
  if(statFileExists)
  {
    statbuf.open(statFile.c_str(), std::ios::out);
    if(statbuf.good()){
      statFileExists = true;
      printStatheader(statbuf);
      statbuf.close();
    }
    else
      std::cerr << "Unable to open the provided file for writting... \n";
  }

  // Get the maximum number of iterations and the tolerance
  int maxiters = 1000;
  double tol = 1e-08;
  string inval;
  if (get_options(argc, args, "--eps", &inval))
    tol = atof(inval.c_str());
  if(get_options(argc, args, "--maxits", &inval))
    maxiters = atoi(inval.c_str());

  string current_dir;
  // Test the matrices in %EIGEN_MATRIXDIR/real
  current_dir = matrix_dir + "/real";
  Browse_Matrices<double>(current_dir, statFileExists, statFile,maxiters, tol);

  // Test the matrices in %EIGEN_MATRIXDIR/complex
  current_dir = matrix_dir + "/complex";
  Browse_Matrices<std::complex<double> >(current_dir, statFileExists, statFile, maxiters, tol);

  if(statFileExists)
  {
    statbuf.open(statFile.c_str(), std::ios::app);
    statbuf << "
 \n";
    cout << "\n Output written in " << statFile << " ...\n";
    statbuf.close();
  }

  return 0;
}

<commit_msg>fix sparse benchmark help<commit_after>#include <bench/spbench/spbenchsolver.h>

void bench_printhelp()
{
    cout<< " \nbenchsolver : performs a benchmark of all the solvers available in Eigen \n\n";
    cout<< " MATRIX FOLDER : \n";
    cout<< " The matrices for the benchmark should be collected in a folder specified with an environment variable EIGEN_MATRIXDIR \n";
    cout<< " This folder should contain the subfolders real/ and complex/ : \n";
    cout<< " The matrices are stored using the matrix market coordinate format \n";
    cout<< " The matrix and associated right-hand side (rhs) files are named respectively \n";
    cout<< " as MatrixName.mtx and MatrixName_b.mtx. If the rhs does not exist, a random one is generated. \n";
    cout<< " If a matrix is SPD, the matrix should be named as MatrixName_SPD.mtx \n";
    cout<< " If a true solution exists, it should be named as MatrixName_x.mtx; \n"     ;
    cout<< " it will be used to compute the norm of the error relative to the computed solutions\n\n";
    cout<< " OPTIONS : \n";
    cout<< " -h or --help \n    print this help and return\n\n";
    cout<< " -d matrixdir \n    Use matrixdir as the matrix folder instead of the one specified in the environment variable EIGEN_MATRIXDIR\n\n";
    cout<< " -o outputfile.html \n    Output the statistics to a html file \n\n";
    cout<< " --eps <RelErr> Sets the relative tolerance for iterative solvers (default 1e-08) \n\n";
    cout<< " --maxits <MaxIts> Sets the maximum number of iterations (default 1000) \n\n";

}
int main(int argc, char ** args)
{

  bool help = ( get_options(argc, args, "-h") || get_options(argc, args, "--help") );
  if(help) {
    bench_printhelp();
    return 0;
  }

  // Get the location of the test matrices
  string matrix_dir;
  if (!get_options(argc, args, "-d", &matrix_dir))
  {
    if(getenv("EIGEN_MATRIXDIR") == NULL){
      std::cerr << "Please, specify the location of the matrices with -d mat_folder or the environment variable EIGEN_MATRIXDIR \n";
      std::cerr << " Run with --help to see the list of all the available options \n";
      return -1;
    }
    matrix_dir = getenv("EIGEN_MATRIXDIR");
  }

  std::ofstream statbuf;
  string statFile ;

  // Get the file to write the statistics
  bool statFileExists = get_options(argc, args, "-o", &statFile);
  if(statFileExists)
  {
    statbuf.open(statFile.c_str(), std::ios::out);
    if(statbuf.good()){
      statFileExists = true;
      printStatheader(statbuf);
      statbuf.close();
    }
    else
      std::cerr << "Unable to open the provided file for writting... \n";
  }

  // Get the maximum number of iterations and the tolerance
  int maxiters = 1000;
  double tol = 1e-08;
  string inval;
  if (get_options(argc, args, "--eps", &inval))
    tol = atof(inval.c_str());
  if(get_options(argc, args, "--maxits", &inval))
    maxiters = atoi(inval.c_str());

  string current_dir;
  // Test the matrices in %EIGEN_MATRIXDIR/real
  current_dir = matrix_dir + "/real";
  Browse_Matrices<double>(current_dir, statFileExists, statFile,maxiters, tol);

  // Test the matrices in %EIGEN_MATRIXDIR/complex
  current_dir = matrix_dir + "/complex";
  Browse_Matrices<std::complex<double> >(current_dir, statFileExists, statFile, maxiters, tol);

  if(statFileExists)
  {
    statbuf.open(statFile.c_str(), std::ios::app);
    statbuf << "
 \n";
    cout << "\n Output written in " << statFile << " ...\n";
    statbuf.close();
  }

  return 0;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <cmath>

#include "timer.h"
#include "matrix.h"

#if defined(AMATRIX_COMPARE_WITH_EIGEN)
#include "Eigen/Dense"
#endif

#if defined(AMATRIX_COMPARE_WITH_UBLAS)
#include <boost/numeric/ublas/matrix.hpp>
#endif

template <typename TMatrixType, std::size_t NumberOfRows,
    std::size_t NumberOfColumns>
class ComparisonColumn {
   protected:
    static constexpr std::size_t mRepeat =
        static_cast<std::size_t>(1e8 / (NumberOfRows * NumberOfColumns));
    TMatrixType mA;
    TMatrixType mB;
    TMatrixType mResult;
    std::string mColumnName;

    void initialize(TMatrixType& TheMatrix) {
        for (std::size_t i = 0; i < NumberOfRows; i++)
            for (std::size_t j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = j + 1.00;
    }

    void initializeInverse(TMatrixType& TheMatrix) {
        for (std::size_t i = 0; i < NumberOfRows; i++)
            for (std::size_t j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = 1.00 / (i + 1);
    }

   public:
    ComparisonColumn() = delete;

    ComparisonColumn(std::string ColumnName) : mColumnName(ColumnName) {
        initialize(mA);
        initialize(mB);
        initialize(mResult);
    }
    std::string const& GetColumnName() { return mColumnName; }
    TMatrixType& GetResult() { return mResult; }

    template <typename TMatrixType2>
    bool CheckResult(TMatrixType2 const& Reference) {
        constexpr double tolerance = 1e-12;
        for (std::size_t i = 0; i < NumberOfRows; i++)
            for (std::size_t j = 0; j < NumberOfColumns; j++)
                if (std::abs(mResult(i, j) != Reference(i, j)) > tolerance){
                    std::cout << mResult(i, j) << " != " << Reference(i, j) ;
                    return false;
                }

        return true;
    }

    void MeasureSumTime() {
        initialize(mA);
        initialize(mB);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < mRepeat; i_repeat++) {
            mResult.noalias() = mA + mB;
            mB.noalias() = mResult;
        }
        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

    void MeasureMultTime() {
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < mRepeat; i_repeat++) {
            mResult.noalias() = D * mA;
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
   void MeasureABAMultTime() {
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < mRepeat; i_repeat++) {
            mResult.noalias() = mA * TMatrixType(D * mA);
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

    void MeasureATransposeBAMultTime() {
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < mRepeat; i_repeat++) {
            mResult.noalias() = mA.transpose() * TMatrixType(D * mA);
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
};

template <typename TMatrixType, std::size_t NumberOfRows,
    std::size_t NumberOfColumns>
class UblasComparisonColumn
    : public ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns> {
   public:
    using BaseType =
        ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>;

    UblasComparisonColumn(std::string ColumnName)
        : ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>(
              ColumnName) {}

    void MeasureSumTime() {
        BaseType::initialize(BaseType::mA);
        BaseType::initialize(BaseType::mB);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < BaseType::mRepeat;
             i_repeat++) {
            boost::numeric::ublas::noalias(BaseType::mResult) =
                BaseType::mA + BaseType::mB;
            boost::numeric::ublas::noalias(BaseType::mB) = BaseType::mResult;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
    void MeasureMultTime() {
        using namespace boost::numeric::ublas;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < BaseType::mRepeat;
             i_repeat++) {
            noalias(BaseType::mResult) = prod(D, BaseType::mA);
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
    void MeasureABAMultTime() {
        using namespace boost::numeric::ublas;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < BaseType::mRepeat;
             i_repeat++) {
            noalias(BaseType::mResult) =
                prod(BaseType::mA, TMatrixType(prod(D, BaseType::mA)));
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
   void MeasureATransposeBAMultTime() {
        using namespace boost::numeric::ublas;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < BaseType::mRepeat;
             i_repeat++) {
            noalias(BaseType::mResult) =
                prod(trans(BaseType::mA), TMatrixType(prod(D, BaseType::mA)));
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
};

template <typename TMatrixType, std::size_t NumberOfRows,
    std::size_t NumberOfColumns>
class EmptyComparisonColumn
    : public ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns> {
   public:
    EmptyComparisonColumn(std::string ColumnName)
        : ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>("") {}
    void MeasureSumTime() { std::cout << "\t\t"; }
    void MeasureMultTime() { std::cout << "\t\t"; }
    void MeasureABAMultTime() { std::cout << "\t\t"; }
    void MeasureATransposeBAMultTime() { std::cout << "\t\t"; }

    template <typename TMatrixType2>
    bool CheckResult(TMatrixType2 const& Reference) {
        return true;
    }
};

template <std::size_t NumberOfRows, std::size_t NumberOfColumns>
class BenchmarkMatrix {
    ComparisonColumn<AMatrix::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mAMatrixColumn;
#if defined(AMATRIX_COMPARE_WITH_EIGEN)
    ComparisonColumn<Eigen::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mEigenColumn;
#else
    EmptyComparisonColumn<
        AMatrix::Matrix<double, NumberOfRows, NumberOfColumns>, NumberOfRows,
        NumberOfColumns>
        mEigenColumn;
#endif
#if defined(AMATRIX_COMPARE_WITH_UBLAS)
    UblasComparisonColumn<boost::numeric::ublas::bounded_matrix<double,
                              NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mUblasColumn;
#else
    EmptyComparisonColumn<
        AMatrix::Matrix<double, NumberOfRows, NumberOfColumns>, NumberOfRows,
        NumberOfColumns>
        mUblasColumn;
#endif
   public:
    BenchmarkMatrix()
        : mAMatrixColumn("AMatrix"),
          mEigenColumn("Eigen"),
          mUblasColumn("Ublas") {
        std::cout << "Benchmark[" << NumberOfRows << "," << NumberOfColumns
                  << "]";
        std::cout << "\t\t" << mAMatrixColumn.GetColumnName();
        std::cout << "\t\t" << mEigenColumn.GetColumnName();
        std::cout << "\t\t" << mUblasColumn.GetColumnName();
        std::cout << std::endl;
    }

    ~BenchmarkMatrix() = default;
    void Run() {
        std::cout << "C = A + B";
        mAMatrixColumn.MeasureSumTime();
        mEigenColumn.MeasureSumTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureSumTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A * B";
        mAMatrixColumn.MeasureMultTime();
        mEigenColumn.MeasureMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A * B * A";
        mAMatrixColumn.MeasureABAMultTime();
        mEigenColumn.MeasureABAMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureABAMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A^T * B * A";
        mAMatrixColumn.MeasureATransposeBAMultTime();
        mEigenColumn.MeasureATransposeBAMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureATransposeBAMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        // std::cout << "AMatrix : " << mAMatrixColumn.GetResult() << std::endl;
        // std::cout << "Eigen   : " << mEigenColumn.GetResult() << std::endl;

        std::cout << std::endl;
    }
};

int main() {
    BenchmarkMatrix<3, 3> benchmark_3_3;
    benchmark_3_3.Run();

    BenchmarkMatrix<4, 4> benchmark_4_4;
    benchmark_4_4.Run();

    BenchmarkMatrix<6, 6> benchmark_6_6;
    benchmark_6_6.Run();

    BenchmarkMatrix<12, 12> benchmark_12_12;
    benchmark_12_12.Run();

    BenchmarkMatrix<16, 16> benchmark_16_16;
    benchmark_16_16.Run();

    return 0;
}
<commit_msg>adding the macro to disable boost part in benchmarking<commit_after>#include <iostream>
#include <cmath>

#include "timer.h"
#include "matrix.h"

#if defined(AMATRIX_COMPARE_WITH_EIGEN)
#include "Eigen/Dense"
#endif

#if defined(AMATRIX_COMPARE_WITH_UBLAS)
#include <boost/numeric/ublas/matrix.hpp>
#endif

template <typename TMatrixType, std::size_t NumberOfRows,
    std::size_t NumberOfColumns>
class ComparisonColumn {
   protected:
    static constexpr std::size_t mRepeat =
        static_cast<std::size_t>(1e8 / (NumberOfRows * NumberOfColumns));
    TMatrixType mA;
    TMatrixType mB;
    TMatrixType mResult;
    std::string mColumnName;

    void initialize(TMatrixType& TheMatrix) {
        for (std::size_t i = 0; i < NumberOfRows; i++)
            for (std::size_t j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = j + 1.00;
    }

    void initializeInverse(TMatrixType& TheMatrix) {
        for (std::size_t i = 0; i < NumberOfRows; i++)
            for (std::size_t j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = 1.00 / (i + 1);
    }

   public:
    ComparisonColumn() = delete;

    ComparisonColumn(std::string ColumnName) : mColumnName(ColumnName) {
        initialize(mA);
        initialize(mB);
        initialize(mResult);
    }
    std::string const& GetColumnName() { return mColumnName; }
    TMatrixType& GetResult() { return mResult; }

    template <typename TMatrixType2>
    bool CheckResult(TMatrixType2 const& Reference) {
        constexpr double tolerance = 1e-12;
        for (std::size_t i = 0; i < NumberOfRows; i++)
            for (std::size_t j = 0; j < NumberOfColumns; j++)
                if (std::abs(mResult(i, j) != Reference(i, j)) > tolerance){
                    std::cout << mResult(i, j) << " != " << Reference(i, j) ;
                    return false;
                }

        return true;
    }

    void MeasureSumTime() {
        initialize(mA);
        initialize(mB);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < mRepeat; i_repeat++) {
            mResult.noalias() = mA + mB;
            mB.noalias() = mResult;
        }
        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

    void MeasureMultTime() {
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < mRepeat; i_repeat++) {
            mResult.noalias() = D * mA;
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
   void MeasureABAMultTime() {
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < mRepeat; i_repeat++) {
            mResult.noalias() = mA * TMatrixType(D * mA);
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

    void MeasureATransposeBAMultTime() {
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < mRepeat; i_repeat++) {
            mResult.noalias() = mA.transpose() * TMatrixType(D * mA);
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
};

#if defined(AMATRIX_COMPARE_WITH_UBLAS)
template <typename TMatrixType, std::size_t NumberOfRows,
    std::size_t NumberOfColumns>

    class UblasComparisonColumn
    : public ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns> {
   public:
    using BaseType =
        ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>;

    UblasComparisonColumn(std::string ColumnName)
        : ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>(
              ColumnName) {}

    void MeasureSumTime() {
        BaseType::initialize(BaseType::mA);
        BaseType::initialize(BaseType::mB);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < BaseType::mRepeat;
             i_repeat++) {
            boost::numeric::ublas::noalias(BaseType::mResult) =
                BaseType::mA + BaseType::mB;
            boost::numeric::ublas::noalias(BaseType::mB) = BaseType::mResult;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
    void MeasureMultTime() {
        using namespace boost::numeric::ublas;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < BaseType::mRepeat;
             i_repeat++) {
            noalias(BaseType::mResult) = prod(D, BaseType::mA);
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
    void MeasureABAMultTime() {
        using namespace boost::numeric::ublas;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < BaseType::mRepeat;
             i_repeat++) {
            noalias(BaseType::mResult) =
                prod(BaseType::mA, TMatrixType(prod(D, BaseType::mA)));
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
   void MeasureATransposeBAMultTime() {
        using namespace boost::numeric::ublas;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (std::size_t i_repeat = 0; i_repeat < BaseType::mRepeat;
             i_repeat++) {
            noalias(BaseType::mResult) =
                prod(trans(BaseType::mA), TMatrixType(prod(D, BaseType::mA)));
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
};
#endif

template <typename TMatrixType, std::size_t NumberOfRows,
    std::size_t NumberOfColumns>
class EmptyComparisonColumn
    : public ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns> {
   public:
    EmptyComparisonColumn(std::string ColumnName)
        : ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>("") {}
    void MeasureSumTime() { std::cout << "\t\t"; }
    void MeasureMultTime() { std::cout << "\t\t"; }
    void MeasureABAMultTime() { std::cout << "\t\t"; }
    void MeasureATransposeBAMultTime() { std::cout << "\t\t"; }

    template <typename TMatrixType2>
    bool CheckResult(TMatrixType2 const& Reference) {
        return true;
    }
};

template <std::size_t NumberOfRows, std::size_t NumberOfColumns>
class BenchmarkMatrix {
    ComparisonColumn<AMatrix::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mAMatrixColumn;
#if defined(AMATRIX_COMPARE_WITH_EIGEN)
    ComparisonColumn<Eigen::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mEigenColumn;
#else
    EmptyComparisonColumn<
        AMatrix::Matrix<double, NumberOfRows, NumberOfColumns>, NumberOfRows,
        NumberOfColumns>
        mEigenColumn;
#endif
#if defined(AMATRIX_COMPARE_WITH_UBLAS)
    UblasComparisonColumn<boost::numeric::ublas::bounded_matrix<double,
                              NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mUblasColumn;
#else
    EmptyComparisonColumn<
        AMatrix::Matrix<double, NumberOfRows, NumberOfColumns>, NumberOfRows,
        NumberOfColumns>
        mUblasColumn;
#endif
   public:
    BenchmarkMatrix()
        : mAMatrixColumn("AMatrix"),
          mEigenColumn("Eigen"),
          mUblasColumn("Ublas") {
        std::cout << "Benchmark[" << NumberOfRows << "," << NumberOfColumns
                  << "]";
        std::cout << "\t\t" << mAMatrixColumn.GetColumnName();
        std::cout << "\t\t" << mEigenColumn.GetColumnName();
        std::cout << "\t\t" << mUblasColumn.GetColumnName();
        std::cout << std::endl;
    }

    ~BenchmarkMatrix() = default;
    void Run() {
        std::cout << "C = A + B";
        mAMatrixColumn.MeasureSumTime();
        mEigenColumn.MeasureSumTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureSumTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A * B";
        mAMatrixColumn.MeasureMultTime();
        mEigenColumn.MeasureMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A * B * A";
        mAMatrixColumn.MeasureABAMultTime();
        mEigenColumn.MeasureABAMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureABAMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A^T * B * A";
        mAMatrixColumn.MeasureATransposeBAMultTime();
        mEigenColumn.MeasureATransposeBAMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureATransposeBAMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        // std::cout << "AMatrix : " << mAMatrixColumn.GetResult() << std::endl;
        // std::cout << "Eigen   : " << mEigenColumn.GetResult() << std::endl;

        std::cout << std::endl;
    }
};

int main() {
    BenchmarkMatrix<3, 3> benchmark_3_3;
    benchmark_3_3.Run();

    BenchmarkMatrix<4, 4> benchmark_4_4;
    benchmark_4_4.Run();

    BenchmarkMatrix<6, 6> benchmark_6_6;
    benchmark_6_6.Run();

    BenchmarkMatrix<12, 12> benchmark_12_12;
    benchmark_12_12.Run();

    BenchmarkMatrix<16, 16> benchmark_16_16;
    benchmark_16_16.Run();

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016, Andrej Kislovskij
 *
 * This is PUBLIC DOMAIN software so use at your own risk as it comes
 * with no warranties. This code is yours to share, use and modify without
 * any restrictions or obligations.
 *
 * For more information see conwrap/LICENSE or refer refer to http://unlicense.org
 *
 * Author: gimesketvirtadieni at gmail dot com (Andrej Kislovskij)
 */

#include <asio.hpp>
#include <chrono>
#include <conwrap/ProcessorAsio.hpp>
#include <conwrap/ProcessorQueue.hpp>
#include <functional>
#include <iostream>

struct Dummy
{
	// TODO: this is a temporary fix before reflection is implemented
	void setProcessor(conwrap::Processor<Dummy>*) {}
};

class Server
{
	public:
		Server(short p) : port(p) {}

		void close()
		{
			// closing acceptor
			acceptorPtr->close();

			// closing socket
			if (socketPtr->is_open())
			{
				try {
					socketPtr->shutdown(asio::socket_base::shutdown_both);
				} catch (...) {}
				try {
					socketPtr->close();
				} catch (...) {}
			}
		}

		void ping()
		{
			if (socketPtr->is_open())
			{
				socketPtr->send(asio::buffer("ping\n\r"));
			}
		}

		void setProcessor(conwrap::ProcessorAsio<Server>* p)
		{
			processorPtr = p;

			// creating an acceptor
			acceptorPtr = std::make_unique<asio::ip::tcp::acceptor>(
				*processorPtr->getDispatcher(),
				asio::ip::tcp::endpoint(
					asio::ip::tcp::v4(),
					port
				)
			);

			// creating a socket
			socketPtr = std::make_unique<asio::ip::tcp::socket>(
				*processorPtr->getDispatcher()
			);

			acceptorPtr->async_accept(
				*socketPtr,
				[=](const std::error_code error)
				{
					// this wrapping is needed to pass handler from asio thread to the processor thread
					processorPtr->wrapHandler([=]
					{
						// start receiving data
						onData(error, 0);
					})();
				}
			);
		}

		// TODO: this is a temporary fix before reflection is implemented
		void setProcessor(conwrap::ProcessorQueue<Server>*) {}

	protected:
		void onData(const std::error_code error, const std::size_t receivedSize)
		{
			if (!error)
			{
				// if there is data to send back to the client
				if (receivedSize > 0)
				{
					socketPtr->send(asio::buffer(buffer, receivedSize));
				}

				// keep receiving
				socketPtr->async_read_some(
					asio::buffer(buffer, BUFFER_SIZE),
					[=](const std::error_code error, const std::size_t receivedSize)
					{
						// this wrapping is needed to pass handler from asio thread to the processor thread
						processorPtr->wrapHandler([=]
						{
							onData(error, receivedSize);
						})();
					}
				);
			}
		}

	private:
		conwrap::ProcessorAsio<Server>*          processorPtr;
		short                                    port;
		std::unique_ptr<asio::ip::tcp::acceptor> acceptorPtr;
		std::unique_ptr<asio::ip::tcp::socket>   socketPtr;
		enum {
			BUFFER_SIZE = 1024
		};
		char                                     buffer[BUFFER_SIZE];
};

int main(int argc, char *argv[])
{
	{
		conwrap::ProcessorQueue<Dummy> processorQueue;

		processorQueue.process([]
		{
			std::cout << "Hello from queue task\n\r";
		});
	}
	std::cout << "Back to main\n\r";

	{
		conwrap::ProcessorAsio<Dummy> processorAsio;

		processorAsio.process([]
		{
			std::cout << "Hello from asio task\n\r";
		});
		processorAsio.flush();
		std::cout << "Back to main\n\r";
	}

	{
		conwrap::ProcessorAsio<Server> processorAsio(1234);
		std::cout << "Echo server is listening on 1234 port (press ^C to terminate)\n\r";

		// now server runs on a separate thread; any other logic can be done here
		for (int i = 0; i < 3; i++)
		{
			// submitting a task in a regular way
			processorAsio.process([]() -> int
			{
				std::cout << "Hello from asio task\n\r";

				// this is just to demonstrate that now asio can be used with tasks that return value
				return 1234;
			});

			for (int j = 0; j < 3; j++)
			{
				// submitting a task directly via asio io_service
				processorAsio.getDispatcher()->post(

					// a task submitted directly via asio io_service must be wrapped as following
					processorAsio.wrapHandler([&]
					{
						processorAsio.getResource()->ping();
					})
				);

				// sleeping
				std::this_thread::sleep_for(std::chrono::seconds{5});
			}

			// after this flush all tasks including asio handlers are executed
			processorAsio.flush();
			std::cout << "All tasks were flushed\n\r";
		}

		// without this close processor's destructor would wait forever for async receive handler
		// sync socket operations are thread safe since asio 1.4.0 so posting to asio thread is optional
		processorAsio.getDispatcher()->post([&]
		{
			 processorAsio.getResource()->close();
		});

		// this flush is required as handler posted to asio captured processorAsio reference
		processorAsio.flush();
	}

	return 0;
}
<commit_msg>Minor changes<commit_after>/*
 * Copyright 2016, Andrej Kislovskij
 *
 * This is PUBLIC DOMAIN software so use at your own risk as it comes
 * with no warranties. This code is yours to share, use and modify without
 * any restrictions or obligations.
 *
 * For more information see conwrap/LICENSE or refer refer to http://unlicense.org
 *
 * Author: gimesketvirtadieni at gmail dot com (Andrej Kislovskij)
 */

#include <asio.hpp>
#include <chrono>
#include <conwrap/ProcessorAsio.hpp>
#include <conwrap/ProcessorQueue.hpp>
#include <functional>
#include <iostream>

struct Dummy
{
	// TODO: this is a temporary fix before reflection is implemented
	void setProcessor(conwrap::Processor<Dummy>*) {}
};

class Server
{
	public:
		Server(short p) : port(p) {}

		void close()
		{
			// closing acceptor
			acceptorPtr->close();

			// closing socket
			if (socketPtr->is_open())
			{
				try {
					socketPtr->shutdown(asio::socket_base::shutdown_both);
				} catch (...) {}
				try {
					socketPtr->close();
				} catch (...) {}
			}
		}

		void ping()
		{
			if (socketPtr->is_open())
			{
				socketPtr->send(asio::buffer("ping\n\r"));
			}
		}

		void setProcessor(conwrap::ProcessorAsio<Server>* p)
		{
			processorPtr = p;

			// creating an acceptor
			acceptorPtr = std::make_unique<asio::ip::tcp::acceptor>(
				*processorPtr->getDispatcher(),
				asio::ip::tcp::endpoint(
					asio::ip::tcp::v4(),
					port
				)
			);

			// creating a socket
			socketPtr = std::make_unique<asio::ip::tcp::socket>(
				*processorPtr->getDispatcher()
			);

			acceptorPtr->async_accept(
				*socketPtr,
				[=](const std::error_code error)
				{
					// wrapping is needed to pass handler from asio's thread to the processor's thread
					processorPtr->wrapHandler([=]
					{
						// start receiving data
						onData(error, 0);
					})();
				}
			);
		}

		// TODO: this is a temporary fix before reflection is implemented
		void setProcessor(conwrap::ProcessorQueue<Server>*) {}

	protected:
		void onData(const std::error_code error, const std::size_t receivedSize)
		{
			if (!error)
			{
				// if there is data to send back to the client
				if (receivedSize > 0)
				{
					socketPtr->send(asio::buffer(buffer, receivedSize));
				}

				// keep receiving
				socketPtr->async_read_some(
					asio::buffer(buffer, BUFFER_SIZE),
					[=](const std::error_code error, const std::size_t receivedSize)
					{
						// wrapping is needed to pass handler from asio's thread to the processor's thread
						processorPtr->wrapHandler([=]
						{
							onData(error, receivedSize);
						})();
					}
				);
			}
		}

	private:
		conwrap::ProcessorAsio<Server>*          processorPtr;
		short                                    port;
		std::unique_ptr<asio::ip::tcp::acceptor> acceptorPtr;
		std::unique_ptr<asio::ip::tcp::socket>   socketPtr;
		enum {
			BUFFER_SIZE = 1024
		};
		char                                     buffer[BUFFER_SIZE];
};

int main(int argc, char *argv[])
{
	{
		conwrap::ProcessorQueue<Dummy> processorQueue;

		processorQueue.process([]
		{
			std::cout << "Hello from queue task\n\r";
		});
	}
	std::cout << "Back to main\n\r";

	{
		conwrap::ProcessorAsio<Dummy> processorAsio;

		processorAsio.process([]
		{
			std::cout << "Hello from asio task\n\r";
		});
		processorAsio.flush();
		std::cout << "Back to main\n\r";
	}

	{
		conwrap::ProcessorAsio<Server> processorAsio(1234);
		std::cout << "Echo server is listening on 1234 port (press ^C to terminate)\n\r";

		// now server runs on a separate thread; any other logic can be done here
		for (int i = 0; i < 3; i++)
		{
			// submitting a task in a regular way
			processorAsio.process([]() -> int
			{
				std::cout << "Hello from asio task\n\r";

				// this is just to demonstrate that now asio can be used with tasks that return value
				return 1234;
			});

			for (int j = 0; j < 3; j++)
			{
				// submitting a task directly via asio io_service
				processorAsio.getDispatcher()->post(

					// a task submitted directly via asio io_service must be wrapped as following
					processorAsio.wrapHandler([&]
					{
						processorAsio.getResource()->ping();
					})
				);

				// sleeping
				std::this_thread::sleep_for(std::chrono::seconds{5});
			}

			// after this flush all tasks including asio handlers are executed
			processorAsio.flush();
			std::cout << "All tasks were flushed\n\r";
		}

		// without this close processor's destructor would wait forever for async receive handler
		// sync socket operations are thread safe since asio 1.4.0 so posting to asio thread is optional
		processorAsio.getDispatcher()->post([&]
		{
			 processorAsio.getResource()->close();
		});

		// this flush is required as handler posted to asio captured processorAsio reference
		processorAsio.flush();
	}

	return 0;
}
<|endoftext|>