<commit_before>/*
 *   kmail: KDE mail client
 *   This file: Copyright (C) 2000 Espen Sand, <espen@kde.org>
 *   Contains code segments and ideas from earlier kmail dialog code
 *   by Stefan Taferner <taferner@alpin.or.at>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <qbuttongroup.h>
#include <qlayout.h>
#include <qradiobutton.h>

#include <klocale.h>

#include "kmacctseldlg.h"
#include "kmacctseldlg.moc"

KMAcctSelDlg::KMAcctSelDlg( QWidget *parent, const char *name, bool modal )
  : KDialogBase( parent, name, modal, i18n("Add Account"), Ok|Cancel, Ok )
{
  QFrame *page = makeMainWidget();
  QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );

  QButtonGroup *group = new QButtonGroup( i18n("Account Type"), page );
  connect(group, SIGNAL(clicked(int)), SLOT(buttonClicked(int)) );

  topLayout->addWidget( group, 10 );
  QVBoxLayout *vlay = new QVBoxLayout( group, spacingHint()*2, spacingHint() );
  vlay->addSpacing( fontMetrics().lineSpacing() );

  QRadioButton *radioButton1 = new QRadioButton(i18n("Local Mailbox"), group );
  vlay->addWidget( radioButton1 );
  QRadioButton *radioButton2  = new QRadioButton(i18n("Pop3"),  group );
  vlay->addWidget( radioButton2 );
  QRadioButton *radioButton3  =
    new QRadioButton(i18n("Advanced Pop3"), group );
  vlay->addWidget( radioButton3 );

  vlay->addStretch( 10 );

  radioButton2->setChecked(true); // Pop is most common ?
  buttonClicked(1);
}

void KMAcctSelDlg::buttonClicked( int id )
{
  mSelectedButton = id;
}

int KMAcctSelDlg::selected( void ) const
{
  return mSelectedButton;
}

<commit_msg>Make advanced pop the default.<commit_after>/*
 *   kmail: KDE mail client
 *   This file: Copyright (C) 2000 Espen Sand, <espen@kde.org>
 *   Contains code segments and ideas from earlier kmail dialog code
 *   by Stefan Taferner <taferner@alpin.or.at>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <qbuttongroup.h>
#include <qlayout.h>
#include <qradiobutton.h>

#include <klocale.h>

#include "kmacctseldlg.h"
#include "kmacctseldlg.moc"

KMAcctSelDlg::KMAcctSelDlg( QWidget *parent, const char *name, bool modal )
  : KDialogBase( parent, name, modal, i18n("Add Account"), Ok|Cancel, Ok )
{
  QFrame *page = makeMainWidget();
  QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );

  QButtonGroup *group = new QButtonGroup( i18n("Account Type"), page );
  connect(group, SIGNAL(clicked(int)), SLOT(buttonClicked(int)) );

  topLayout->addWidget( group, 10 );
  QVBoxLayout *vlay = new QVBoxLayout( group, spacingHint()*2, spacingHint() );
  vlay->addSpacing( fontMetrics().lineSpacing() );

  QRadioButton *radioButton1 = new QRadioButton(i18n("Local Mailbox"), group );
  vlay->addWidget( radioButton1 );
  QRadioButton *radioButton2  = new QRadioButton(i18n("Pop3"),  group );
  vlay->addWidget( radioButton2 );
  QRadioButton *radioButton3  =
    new QRadioButton(i18n("Advanced Pop3"), group );
  vlay->addWidget( radioButton3 );

  vlay->addStretch( 10 );

  radioButton3->setChecked(true); // Advanced Pop is most common ?
  buttonClicked(1);
}

void KMAcctSelDlg::buttonClicked( int id )
{
  mSelectedButton = id;
}

int KMAcctSelDlg::selected( void ) const
{
  return mSelectedButton;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: math.hxx,v $
 * $Revision: 1.8 $
 *
 * 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.
 *
 ************************************************************************/

#if !defined INCLUDED_RTL_MATH_HXX
#define INCLUDED_RTL_MATH_HXX

#include "rtl/math.h"
#include "rtl/string.hxx"
#include "rtl/ustring.hxx"
#include "rtl/ustrbuf.hxx"
#include "sal/mathconf.h"
#include "sal/types.h"

#include <math.h>

namespace rtl {

namespace math {

/** A wrapper around rtl_math_doubleToString.
 */
inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
                                   sal_Int32 nDecPlaces,
                                   sal_Char cDecSeparator,
                                   sal_Int32 const * pGroups,
                                   sal_Char cGroupSeparator,
                                   bool bEraseTrailingDecZeros = false)
{
    rtl::OString aResult;
    rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
                            cDecSeparator, pGroups, cGroupSeparator,
                            bEraseTrailingDecZeros);
    return aResult;
}

/** A wrapper around rtl_math_doubleToString, with no grouping.
 */
inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
                                   sal_Int32 nDecPlaces,
                                   sal_Char cDecSeparator,
                                   bool bEraseTrailingDecZeros = false)
{
    rtl::OString aResult;
    rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
                            cDecSeparator, 0, 0, bEraseTrailingDecZeros);
    return aResult;
}

/** A wrapper around rtl_math_doubleToUString.
 */
inline rtl::OUString doubleToUString(double fValue,
                                     rtl_math_StringFormat eFormat,
                                     sal_Int32 nDecPlaces,
                                     sal_Unicode cDecSeparator,
                                     sal_Int32 const * pGroups,
                                     sal_Unicode cGroupSeparator,
                                     bool bEraseTrailingDecZeros = false)
{
    rtl::OUString aResult;
    rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
                             cDecSeparator, pGroups, cGroupSeparator,
                             bEraseTrailingDecZeros);
    return aResult;
}

/** A wrapper around rtl_math_doubleToUString, with no grouping.
 */
inline rtl::OUString doubleToUString(double fValue,
                                     rtl_math_StringFormat eFormat,
                                     sal_Int32 nDecPlaces,
                                     sal_Unicode cDecSeparator,
                                     bool bEraseTrailingDecZeros = false)
{
    rtl::OUString aResult;
    rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
                             cDecSeparator, 0, 0, bEraseTrailingDecZeros);
    return aResult;
}

/** A wrapper around rtl_math_doubleToUString that appends to an
    rtl::OUStringBuffer.
 */
inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
                                   rtl_math_StringFormat eFormat,
                                   sal_Int32 nDecPlaces,
                                   sal_Unicode cDecSeparator,
                                   sal_Int32 const * pGroups,
                                   sal_Unicode cGroupSeparator,
                                   bool bEraseTrailingDecZeros = false)
{
    rtl_uString ** pData;
    sal_Int32 * pCapacity;
    rBuffer.accessInternals( &pData, &pCapacity );
    rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
                              eFormat, nDecPlaces, cDecSeparator, pGroups,
                              cGroupSeparator, bEraseTrailingDecZeros);
}

/** A wrapper around rtl_math_doubleToUString that appends to an
    rtl::OUStringBuffer, with no grouping.
 */
inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
                                   rtl_math_StringFormat eFormat,
                                   sal_Int32 nDecPlaces,
                                   sal_Unicode cDecSeparator,
                                   bool bEraseTrailingDecZeros = false)
{
    rtl_uString ** pData;
    sal_Int32 * pCapacity;
    rBuffer.accessInternals( &pData, &pCapacity );
    rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
                              eFormat, nDecPlaces, cDecSeparator, 0, 0,
                              bEraseTrailingDecZeros);
}

/** A wrapper around rtl_math_stringToDouble.
 */
inline double stringToDouble(rtl::OString const & rString,
                             sal_Char cDecSeparator, sal_Char cGroupSeparator,
                             rtl_math_ConversionStatus * pStatus,
                             sal_Int32 * pParsedEnd)
{
    sal_Char const * pBegin = rString.getStr();
    sal_Char const * pEnd;
    double fResult = rtl_math_stringToDouble(pBegin,
                                             pBegin + rString.getLength(),
                                             cDecSeparator, cGroupSeparator,
                                             pStatus, &pEnd);
    if (pParsedEnd != 0)
        *pParsedEnd = (sal_Int32)(pEnd - pBegin);
    return fResult;
}

/** A wrapper around rtl_math_uStringToDouble.
 */
inline double stringToDouble(rtl::OUString const & rString,
                             sal_Unicode cDecSeparator,
                             sal_Unicode cGroupSeparator,
                             rtl_math_ConversionStatus * pStatus,
                             sal_Int32 * pParsedEnd)
{
    sal_Unicode const * pBegin = rString.getStr();
    sal_Unicode const * pEnd;
    double fResult = rtl_math_uStringToDouble(pBegin,
                                              pBegin + rString.getLength(),
                                              cDecSeparator, cGroupSeparator,
                                              pStatus, &pEnd);
    if (pParsedEnd != 0)
        *pParsedEnd = (sal_Int32)(pEnd - pBegin);
    return fResult;
}

/** A wrapper around rtl_math_round.
 */
inline double round(
    double fValue, int nDecPlaces = 0,
    rtl_math_RoundingMode eMode = rtl_math_RoundingMode_Corrected)
{
    return rtl_math_round(fValue, nDecPlaces, eMode);
}

/** A wrapper around rtl_math_pow10Exp.
 */
inline double pow10Exp(double fValue, int nExp)
{
    return rtl_math_pow10Exp(fValue, nExp);
}

/** A wrapper around rtl_math_approxValue.
 */
inline double approxValue(double fValue)
{
    return rtl_math_approxValue(fValue);
}

/** A wrapper around rtl_math_expm1.
 */
inline double expm1(double fValue)
{
    return rtl_math_expm1(fValue);
}

/** A wrapper around rtl_math_log1p.
 */
inline double log1p(double fValue)
{
    return rtl_math_log1p(fValue);
}

/** A wrapper around rtl_math_atanh.
 */
inline double atanh(double fValue)
{
    return rtl_math_atanh(fValue);
}

/** A wrapper around rtl_math_erf.
 */
inline double erf(double fValue)
{
    return rtl_math_erf(fValue);
}

/** A wrapper around rtl_math_erfc.
 */
inline double erfc(double fValue)
{
    return rtl_math_erfc(fValue);
}

/** A wrapper around rtl_math_asinh.
 */
inline double asinh(double fValue)
{
    return rtl_math_asinh(fValue);
}

/** A wrapper around rtl_math_acosh.
 */
inline double acosh(double fValue)
{
    return rtl_math_acosh(fValue);
}

/** Test equality of two values with an accuracy of the magnitude of the
    given values scaled by 2^-48 (4 bits roundoff stripped).

    @ATTENTION
    approxEqual( value!=0.0, 0.0 ) _never_ yields true.
 */
inline bool approxEqual(double a, double b)
{
    if ( a == b )
        return true;
    double x = a - b;
    return (x < 0.0 ? -x : x)
        < ((a < 0.0 ? -a : a) * (1.0 / (16777216.0 * 16777216.0)));
}

/** Add two values.

    If signs differ and the absolute values are equal according to approxEqual()
    the method returns 0.0 instead of calculating the sum.

    If you wanted to sum up multiple values it would be convenient not to call
    approxAdd() for each value but instead remember the first value not equal to
    0.0, add all other values using normal + operator, and with the result and
    the remembered value call approxAdd().
 */
inline double approxAdd(double a, double b)
{
    if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))
         && approxEqual( a, -b ) )
        return 0.0;
    return a + b;
}

/** Substract two values (a-b).

    If signs are identical and the values are equal according to approxEqual()
    the method returns 0.0 instead of calculating the substraction.
 */
inline double approxSub(double a, double b)
{
    if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approxEqual( a, b ) )
        return 0.0;
    return a - b;
}

/** floor() method taking approxValue() into account.

    Use for expected integer values being calculated by double functions.
 */
inline double approxFloor(double a)
{
    return floor( approxValue( a ));
}

/** ceil() method taking approxValue() into account.

    Use for expected integer values being calculated by double functions.
 */
inline double approxCeil(double a)
{
    return ceil( approxValue( a ));
}

/** Tests whether a value is neither INF nor NAN.
 */
inline bool isFinite(double d)
{
    return SAL_MATH_FINITE(d) != 0;
}

/** If a value represents +INF or -INF.

    The sign bit may be queried with isSignBitSet().

    If isFinite(d)==false and isInf(d)==false then NAN.
 */
inline bool isInf(double d)
{
    // exponent==0x7ff fraction==0
    return (SAL_MATH_FINITE(d) == 0) &&
        (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi == 0)
        && (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
            == 0);
}

/** Test on any QNAN or SNAN.
 */
inline bool isNan(double d)
{
    // exponent==0x7ff fraction!=0
    return (SAL_MATH_FINITE(d) == 0) && (
        (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi != 0)
        || (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
            != 0) );
}

/** If the sign bit is set.
 */
inline bool isSignBitSet(double d)
{
    return reinterpret_cast< sal_math_Double * >(&d)->inf_parts.sign != 0;
}

/** Set to +INF if bNegative==false or -INF if bNegative==true.
 */
inline void setInf(double * pd, bool bNegative)
{
    union
    {
        double sd;
        sal_math_Double md;
    };
    sd = *pd;
    md.w32_parts.msw = bNegative ? 0xFFF00000 : 0x7FF00000;
    md.w32_parts.lsw = 0;
    *pd = sd;
}

/** Set a QNAN.
 */
inline void setNan(double * pd)
{
    union
    {
        double sd;
        sal_math_Double md;
    };
    sd = *pd;
    md.w32_parts.msw = 0x7FFFFFFF;
    md.w32_parts.lsw = 0xFFFFFFFF;
    *pd = sd;
}

/** If a value is a valid argument for sin(), cos(), tan().

    IEEE 754 specifies that absolute values up to 2^64 (=1.844e19) for the
    radian must be supported by trigonometric functions.  Unfortunately, at
    least on x86 architectures, the FPU doesn't generate an error pattern for
    values >2^64 but produces erroneous results instead and sets only the
    "invalid operation" (IM) flag in the status word :-(  Thus the application
    has to handle it itself.
 */
inline bool isValidArcArg(double d)
{
    return fabs(d)
        <= (static_cast< double >(static_cast< unsigned long >(0x80000000))
            * static_cast< double >(static_cast< unsigned long >(0x80000000))
            * 2);
}

/** Safe sin(), returns NAN if not valid.
 */
inline double sin(double d)
{
    if ( isValidArcArg( d ) )
        return ::sin( d );
    setNan( &d );
    return d;
}

/** Safe cos(), returns NAN if not valid.
 */
inline double cos(double d)
{
    if ( isValidArcArg( d ) )
        return ::cos( d );
    setNan( &d );
    return d;
}

/** Safe tan(), returns NAN if not valid.
 */
inline double tan(double d)
{
    if ( isValidArcArg( d ) )
        return ::tan( d );
    setNan( &d );
    return d;
}

}

}

#endif // INCLUDED_RTL_MATH_HXX
<commit_msg>sb116: #i106384# removed unncessary assignments (that caused warnings about using uninitialized variables)<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: math.hxx,v $
 * $Revision: 1.8 $
 *
 * 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.
 *
 ************************************************************************/

#if !defined INCLUDED_RTL_MATH_HXX
#define INCLUDED_RTL_MATH_HXX

#include "rtl/math.h"
#include "rtl/string.hxx"
#include "rtl/ustring.hxx"
#include "rtl/ustrbuf.hxx"
#include "sal/mathconf.h"
#include "sal/types.h"

#include <math.h>

namespace rtl {

namespace math {

/** A wrapper around rtl_math_doubleToString.
 */
inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
                                   sal_Int32 nDecPlaces,
                                   sal_Char cDecSeparator,
                                   sal_Int32 const * pGroups,
                                   sal_Char cGroupSeparator,
                                   bool bEraseTrailingDecZeros = false)
{
    rtl::OString aResult;
    rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
                            cDecSeparator, pGroups, cGroupSeparator,
                            bEraseTrailingDecZeros);
    return aResult;
}

/** A wrapper around rtl_math_doubleToString, with no grouping.
 */
inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
                                   sal_Int32 nDecPlaces,
                                   sal_Char cDecSeparator,
                                   bool bEraseTrailingDecZeros = false)
{
    rtl::OString aResult;
    rtl_math_doubleToString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
                            cDecSeparator, 0, 0, bEraseTrailingDecZeros);
    return aResult;
}

/** A wrapper around rtl_math_doubleToUString.
 */
inline rtl::OUString doubleToUString(double fValue,
                                     rtl_math_StringFormat eFormat,
                                     sal_Int32 nDecPlaces,
                                     sal_Unicode cDecSeparator,
                                     sal_Int32 const * pGroups,
                                     sal_Unicode cGroupSeparator,
                                     bool bEraseTrailingDecZeros = false)
{
    rtl::OUString aResult;
    rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
                             cDecSeparator, pGroups, cGroupSeparator,
                             bEraseTrailingDecZeros);
    return aResult;
}

/** A wrapper around rtl_math_doubleToUString, with no grouping.
 */
inline rtl::OUString doubleToUString(double fValue,
                                     rtl_math_StringFormat eFormat,
                                     sal_Int32 nDecPlaces,
                                     sal_Unicode cDecSeparator,
                                     bool bEraseTrailingDecZeros = false)
{
    rtl::OUString aResult;
    rtl_math_doubleToUString(&aResult.pData, 0, 0, fValue, eFormat, nDecPlaces,
                             cDecSeparator, 0, 0, bEraseTrailingDecZeros);
    return aResult;
}

/** A wrapper around rtl_math_doubleToUString that appends to an
    rtl::OUStringBuffer.
 */
inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
                                   rtl_math_StringFormat eFormat,
                                   sal_Int32 nDecPlaces,
                                   sal_Unicode cDecSeparator,
                                   sal_Int32 const * pGroups,
                                   sal_Unicode cGroupSeparator,
                                   bool bEraseTrailingDecZeros = false)
{
    rtl_uString ** pData;
    sal_Int32 * pCapacity;
    rBuffer.accessInternals( &pData, &pCapacity );
    rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
                              eFormat, nDecPlaces, cDecSeparator, pGroups,
                              cGroupSeparator, bEraseTrailingDecZeros);
}

/** A wrapper around rtl_math_doubleToUString that appends to an
    rtl::OUStringBuffer, with no grouping.
 */
inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
                                   rtl_math_StringFormat eFormat,
                                   sal_Int32 nDecPlaces,
                                   sal_Unicode cDecSeparator,
                                   bool bEraseTrailingDecZeros = false)
{
    rtl_uString ** pData;
    sal_Int32 * pCapacity;
    rBuffer.accessInternals( &pData, &pCapacity );
    rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
                              eFormat, nDecPlaces, cDecSeparator, 0, 0,
                              bEraseTrailingDecZeros);
}

/** A wrapper around rtl_math_stringToDouble.
 */
inline double stringToDouble(rtl::OString const & rString,
                             sal_Char cDecSeparator, sal_Char cGroupSeparator,
                             rtl_math_ConversionStatus * pStatus,
                             sal_Int32 * pParsedEnd)
{
    sal_Char const * pBegin = rString.getStr();
    sal_Char const * pEnd;
    double fResult = rtl_math_stringToDouble(pBegin,
                                             pBegin + rString.getLength(),
                                             cDecSeparator, cGroupSeparator,
                                             pStatus, &pEnd);
    if (pParsedEnd != 0)
        *pParsedEnd = (sal_Int32)(pEnd - pBegin);
    return fResult;
}

/** A wrapper around rtl_math_uStringToDouble.
 */
inline double stringToDouble(rtl::OUString const & rString,
                             sal_Unicode cDecSeparator,
                             sal_Unicode cGroupSeparator,
                             rtl_math_ConversionStatus * pStatus,
                             sal_Int32 * pParsedEnd)
{
    sal_Unicode const * pBegin = rString.getStr();
    sal_Unicode const * pEnd;
    double fResult = rtl_math_uStringToDouble(pBegin,
                                              pBegin + rString.getLength(),
                                              cDecSeparator, cGroupSeparator,
                                              pStatus, &pEnd);
    if (pParsedEnd != 0)
        *pParsedEnd = (sal_Int32)(pEnd - pBegin);
    return fResult;
}

/** A wrapper around rtl_math_round.
 */
inline double round(
    double fValue, int nDecPlaces = 0,
    rtl_math_RoundingMode eMode = rtl_math_RoundingMode_Corrected)
{
    return rtl_math_round(fValue, nDecPlaces, eMode);
}

/** A wrapper around rtl_math_pow10Exp.
 */
inline double pow10Exp(double fValue, int nExp)
{
    return rtl_math_pow10Exp(fValue, nExp);
}

/** A wrapper around rtl_math_approxValue.
 */
inline double approxValue(double fValue)
{
    return rtl_math_approxValue(fValue);
}

/** A wrapper around rtl_math_expm1.
 */
inline double expm1(double fValue)
{
    return rtl_math_expm1(fValue);
}

/** A wrapper around rtl_math_log1p.
 */
inline double log1p(double fValue)
{
    return rtl_math_log1p(fValue);
}

/** A wrapper around rtl_math_atanh.
 */
inline double atanh(double fValue)
{
    return rtl_math_atanh(fValue);
}

/** A wrapper around rtl_math_erf.
 */
inline double erf(double fValue)
{
    return rtl_math_erf(fValue);
}

/** A wrapper around rtl_math_erfc.
 */
inline double erfc(double fValue)
{
    return rtl_math_erfc(fValue);
}

/** A wrapper around rtl_math_asinh.
 */
inline double asinh(double fValue)
{
    return rtl_math_asinh(fValue);
}

/** A wrapper around rtl_math_acosh.
 */
inline double acosh(double fValue)
{
    return rtl_math_acosh(fValue);
}

/** Test equality of two values with an accuracy of the magnitude of the
    given values scaled by 2^-48 (4 bits roundoff stripped).

    @ATTENTION
    approxEqual( value!=0.0, 0.0 ) _never_ yields true.
 */
inline bool approxEqual(double a, double b)
{
    if ( a == b )
        return true;
    double x = a - b;
    return (x < 0.0 ? -x : x)
        < ((a < 0.0 ? -a : a) * (1.0 / (16777216.0 * 16777216.0)));
}

/** Add two values.

    If signs differ and the absolute values are equal according to approxEqual()
    the method returns 0.0 instead of calculating the sum.

    If you wanted to sum up multiple values it would be convenient not to call
    approxAdd() for each value but instead remember the first value not equal to
    0.0, add all other values using normal + operator, and with the result and
    the remembered value call approxAdd().
 */
inline double approxAdd(double a, double b)
{
    if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))
         && approxEqual( a, -b ) )
        return 0.0;
    return a + b;
}

/** Substract two values (a-b).

    If signs are identical and the values are equal according to approxEqual()
    the method returns 0.0 instead of calculating the substraction.
 */
inline double approxSub(double a, double b)
{
    if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approxEqual( a, b ) )
        return 0.0;
    return a - b;
}

/** floor() method taking approxValue() into account.

    Use for expected integer values being calculated by double functions.
 */
inline double approxFloor(double a)
{
    return floor( approxValue( a ));
}

/** ceil() method taking approxValue() into account.

    Use for expected integer values being calculated by double functions.
 */
inline double approxCeil(double a)
{
    return ceil( approxValue( a ));
}

/** Tests whether a value is neither INF nor NAN.
 */
inline bool isFinite(double d)
{
    return SAL_MATH_FINITE(d) != 0;
}

/** If a value represents +INF or -INF.

    The sign bit may be queried with isSignBitSet().

    If isFinite(d)==false and isInf(d)==false then NAN.
 */
inline bool isInf(double d)
{
    // exponent==0x7ff fraction==0
    return (SAL_MATH_FINITE(d) == 0) &&
        (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi == 0)
        && (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
            == 0);
}

/** Test on any QNAN or SNAN.
 */
inline bool isNan(double d)
{
    // exponent==0x7ff fraction!=0
    return (SAL_MATH_FINITE(d) == 0) && (
        (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi != 0)
        || (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
            != 0) );
}

/** If the sign bit is set.
 */
inline bool isSignBitSet(double d)
{
    return reinterpret_cast< sal_math_Double * >(&d)->inf_parts.sign != 0;
}

/** Set to +INF if bNegative==false or -INF if bNegative==true.
 */
inline void setInf(double * pd, bool bNegative)
{
    union
    {
        double sd;
        sal_math_Double md;
    };
    md.w32_parts.msw = bNegative ? 0xFFF00000 : 0x7FF00000;
    md.w32_parts.lsw = 0;
    *pd = sd;
}

/** Set a QNAN.
 */
inline void setNan(double * pd)
{
    union
    {
        double sd;
        sal_math_Double md;
    };
    md.w32_parts.msw = 0x7FFFFFFF;
    md.w32_parts.lsw = 0xFFFFFFFF;
    *pd = sd;
}

/** If a value is a valid argument for sin(), cos(), tan().

    IEEE 754 specifies that absolute values up to 2^64 (=1.844e19) for the
    radian must be supported by trigonometric functions.  Unfortunately, at
    least on x86 architectures, the FPU doesn't generate an error pattern for
    values >2^64 but produces erroneous results instead and sets only the
    "invalid operation" (IM) flag in the status word :-(  Thus the application
    has to handle it itself.
 */
inline bool isValidArcArg(double d)
{
    return fabs(d)
        <= (static_cast< double >(static_cast< unsigned long >(0x80000000))
            * static_cast< double >(static_cast< unsigned long >(0x80000000))
            * 2);
}

/** Safe sin(), returns NAN if not valid.
 */
inline double sin(double d)
{
    if ( isValidArcArg( d ) )
        return ::sin( d );
    setNan( &d );
    return d;
}

/** Safe cos(), returns NAN if not valid.
 */
inline double cos(double d)
{
    if ( isValidArcArg( d ) )
        return ::cos( d );
    setNan( &d );
    return d;
}

/** Safe tan(), returns NAN if not valid.
 */
inline double tan(double d)
{
    if ( isValidArcArg( d ) )
        return ::tan( d );
    setNan( &d );
    return d;
}

}

}

#endif // INCLUDED_RTL_MATH_HXX
<|endoftext|>


<commit_before>#include <set>
#include <sstream>
#include <string>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>

#include <boost/thread.hpp>
#include <boost/thread/locks.hpp>

namespace asio = boost::asio;
namespace ip = asio::ip;
namespace placeholders = asio::placeholders;
namespace sys = boost::system;
namespace algorithm = boost::algorithm;

template< typename TConnection >
class Task
{
public:
    Task( TConnection * connection )
        : m_connection( connection )
    {
    }

    static typename TConnection::Action start()
    {
        return TConnection::Action::Read;
    }

    typename TConnection::Action parse(
        char const * const buffer,
        std::size_t const bytesTransferred
    )
    {
        std::istringstream iss( std::string( buffer, bytesTransferred ) );

        char command, space, cr, lf;
        iss >> command;

        if( command == 'g' )
        {
            std::string id;
            iss >> id;
            m_connection->setId( id );

            char const * const line = "Hello.";
            m_connection->response( line, strlen( line ) );
            m_connection->read();
        }
        else if( command == 'b' )
        {
            std::string message;
            iss >> message;

            m_connection->broadcast( message.c_str(), message.size() );
            m_connection->read();
        }
        else if( command == 'u' )
        {
            std::string id;
            std::string message;
            iss >> id >> message;

            m_connection->unicast( id, message.c_str(), message.size() );
            m_connection->read();
        }
        else if( command == 'd' )
        {
            m_connection->disconnect();
        }
        else
        {
            char const * const line = "unknown";
            m_connection->response( line, strlen( line ) );
            m_connection->read();
        }

        return TConnection::Action::Process;
    }

    void parseError()
    {
        std::cerr
            << "Parse error"
            << std::endl;
    }

    void process()
    {
    }

private:
    TConnection * m_connection;
};

class ConnectionManager;

class Connection
    : public boost::enable_shared_from_this< Connection >
{
public:

    typedef boost::shared_ptr< Connection > ConnectionPtr;

public:

    enum class Action
    {
        Read,
        ReadError,
        Process
    };

    Connection(
        asio::io_service & ioService,
        ConnectionManager & connectionManager
    );

    ip::tcp::socket & socket();

    void disconnect();

    void start(
        Action const action = Task< Connection >::start()
    );

public: // api

    void setId(
        std::string const & id
    );

    std::string const & getId() const ;

    void read();

    void parseError();

    void process();

    void response(
        char const * const message,
        std::size_t const size
    );

    void unicast(
        std::string const & receiverId,
        char const * const message,
        std::size_t const size
    );

    void broadcast(
        char const * const message,
        std::size_t const size
    );

    void doNothing(
        sys::error_code const & errorCode
    )
    {
        if( errorCode )
        {
            std::cerr << "Do Nothing Error: " << errorCode.message() << std::endl;

            disconnect();
        }
    }

private:

    void parse(
        sys::error_code const & errorCode,
        std::size_t const bytesTransferred
    );

    void startAgain(
        sys::error_code const & errorCode
    );

    void stop(
        sys::error_code const & errorCode
    );

private:

    ip::tcp::socket m_socket;
    asio::io_service::strand m_strand;
    ConnectionManager & m_connectionManager;

    Task< Connection > m_task;

    std::string m_id;

    enum { m_maxSize = 1024 };
    char m_buffer[ m_maxSize ];
};

Connection::Connection(
    asio::io_service & ioService,
    ConnectionManager & connectionManager
)
    : m_socket( ioService )
    , m_strand( ioService )
    , m_connectionManager( connectionManager )
    , m_task( this )
{
}

ip::tcp::socket & Connection::socket()
{
    return m_socket;
}

void Connection::setId(
    std::string const & id
)
{
    m_id = id;
}

std::string const & Connection::getId() const
{
    return m_id;
}

void Connection::start(
    Connection::Action const action
)
{
    switch( action )
    {
        case Action::Process:
        {
            process();

            break;
        }

        case Action::ReadError:
        {
            parseError();

            break;
        }

        case Action::Read:
        {
            auto const parse = boost::bind(
                & Connection::parse,
                shared_from_this(),
                placeholders::error,
                placeholders::bytes_transferred()
            );

            m_socket.async_read_some(
                asio::buffer( m_buffer, m_maxSize ),
                m_strand.wrap( parse )
            );

            break;
        }
    }
}

void Connection::read()
{
    start( Action::Read );
}

void Connection::parseError()
{
    m_task.parseError();
}

void Connection::process()
{
    m_task.process();
}

void Connection::parse(
    sys::error_code const & errorCode,
    std::size_t const bytesTransferred
)
{
    if( errorCode )
    {
        std::cerr << "Parse Error: " << errorCode.message() << std::endl;

        disconnect();
    }
    else
    {
        start( m_task.parse( m_buffer, bytesTransferred ) );
    }
}

void Connection::startAgain(
    sys::error_code const & errorCode
)
{
    if( errorCode )
    {
        std::cerr << "Start Again Error: " << errorCode.message() << std::endl;

        disconnect();
    }
    else
    {
        start();
    }
}

typedef Connection::ConnectionPtr ConnectionPtr;

class ConnectionManager
    : public boost::noncopyable
{
    typedef std::set< ConnectionPtr > ConnectionsPtr;

public:

    template< typename Function, class... Args >
    void forEach( Function&& func, Args && ...args )
    {
        boost::lock_guard< boost::mutex > lock( m_mutex );

        for( auto & connection : m_connections )
        {
            func( connection, std::forward< Args >( args )... );
        }
    }

    template< typename Predicate, typename Function, class... Args >
    void forEachIf( Predicate && predicate, Function && func, Args && ...args )
    {
        boost::lock_guard< boost::mutex > lock( m_mutex );

        for( auto & connection : m_connections )
        {
            if( predicate( connection ) )
            {
                func( connection, std::forward< Args >( args )... );
            }
        }
    }

    void add(
        ConnectionPtr & connection
    )
    {
        boost::lock_guard< boost::mutex > lock( m_mutex );

        m_connections.insert( connection );
    }

    void remove(
        ConnectionPtr const & connection
    )
    {
        boost::lock_guard< boost::mutex > lock( m_mutex );

        auto const pos = m_connections.find( connection );

        if( pos != m_connections.end() ){
            m_connections.erase( pos );
        }
    }

private:

    boost::mutex m_mutex;
    ConnectionsPtr m_connections;
};

void Connection::disconnect()
{
    char const * const message = "Goodbye.";

    response( message, strlen( message ) );
}

void Connection::response(
    char const * const message,
    std::size_t const size
)
{
    auto const continuation = boost::bind(
        & Connection::doNothing,
        shared_from_this(),
        placeholders::error
    );

    asio::async_write(
        m_socket,
        asio::buffer( message, size ),
        continuation
    );
}

void Connection::unicast(
    std::string const & receiverId,
    char const * const message,
    std::size_t const size
)
{
    auto const matchReceiver = [ this, & receiverId ]( ConnectionPtr const & connectionPtr )
    {
        return connectionPtr->getId() == receiverId;
    };

    auto sendMessage = [ this, & size, & message ]( ConnectionPtr const & connectionPtr )
    {
        auto const stop = boost::bind(
            & Connection::doNothing,
            shared_from_this(),
            placeholders::error
        );

        asio::async_write(
            connectionPtr->socket(),
            asio::buffer( message, size ),
            stop
        );
    };

    m_connectionManager.forEachIf( matchReceiver, sendMessage );
}

void Connection::broadcast(
    char const * const message,
    std::size_t const size
)
{
    auto const skipSender = [ this ]( ConnectionPtr const & connectionPtr )
    {
        return connectionPtr->socket().native_handle() != this->socket().native_handle();
    };

    auto sendMessage = [ this, & size, & message ]( ConnectionPtr const & connectionPtr )
    {
        auto const continuation = boost::bind(
            & Connection::doNothing,
            shared_from_this(),
            placeholders::error
        );

        asio::async_write(
            connectionPtr->socket(),
            asio::buffer( message, size ),
            continuation
        );
    };

    m_connectionManager.forEachIf( skipSender, sendMessage );
}

void Connection::stop(
    sys::error_code const & errorCode
)
{
    m_connectionManager.remove( shared_from_this() );
}

class Server
{
public:

    Server(
        std::string const & port
    )
        : m_acceptor( m_ioService )
        , m_signals( m_ioService )
    {
        m_signals.add( SIGINT );
        m_signals.add( SIGTERM );
        m_signals.add( SIGQUIT );

        m_signals.async_wait(
            boost::bind( & Server::disconnect, this )
        );

        ip::tcp::resolver resolver( m_ioService );
        ip::tcp::resolver::query query( "127.0.0.1", port );
        ip::tcp::endpoint endpoint = * resolver.resolve( query );

        m_acceptor.open( endpoint.protocol() );
        m_acceptor.set_option( ip::tcp::acceptor::reuse_address( true ) );
        m_acceptor.bind( endpoint );
        m_acceptor.listen();

        startAccept();
    }

    void run()
    {
        boost::thread_group threadGroup;

        auto const threadBody = boost::bind(
            & asio::io_service::run,
            & m_ioService
        );

        for( unsigned i = 0 ; i < 4 ; ++ i )
        {
            threadGroup.create_thread( threadBody );
        }

        threadGroup.join_all();
    }

private:

    void startAccept()
    {
        m_newConnection.reset( new Connection( m_ioService, m_connectionManager ) );

        m_connectionManager.add( m_newConnection );

        auto const onAccepted = boost::bind(
            & Server::onAccepted,
            this,
            placeholders::error
        );

        m_acceptor.async_accept(
            m_newConnection->socket(),
            onAccepted
        );
    }

    void onAccepted(
        sys::error_code const & errorCode
    )
    {
        if( ! errorCode )
        {
            m_newConnection->start();
        }

        startAccept();
    }

    void disconnect()
    {
        m_connectionManager.forEach(
            boost::bind( & Connection::disconnect, _1 )
        );

        m_ioService.stop();
    }

private:

    asio::io_service m_ioService;
    asio::ip::tcp::acceptor m_acceptor;
    asio::signal_set m_signals;

    ConnectionPtr m_newConnection;
    ConnectionManager m_connectionManager;
};

int main( int argc, char* argv[] )
{
    Server( argv[1] ).run();
}

<commit_msg>refactoring<commit_after>#include <set>
#include <sstream>
#include <string>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>

#include <boost/thread.hpp>
#include <boost/thread/locks.hpp>

namespace asio = boost::asio;
namespace ip = asio::ip;
namespace placeholders = asio::placeholders;
namespace sys = boost::system;
namespace algorithm = boost::algorithm;

template< typename TConnection >
class Task
{
public:
    Task( TConnection * connection )
        : m_connection( connection )
    {
    }

    static typename TConnection::Action start()
    {
        return TConnection::Action::Read;
    }

    typename TConnection::Action parse(
        char const * const buffer,
        std::size_t const bytesTransferred
    )
    {
        std::istringstream iss( std::string( buffer, bytesTransferred ) );

        char command, space, cr, lf;
        iss >> command;

        if( command == 'g' )
        {
            std::string id;
            iss >> id;
            m_connection->setId( id );

            char const * const line = "Hello.";
            m_connection->response( line, strlen( line ) );
            m_connection->read();
        }
        else if( command == 'b' )
        {
            std::string message;
            iss >> message;

            m_connection->broadcast( message.c_str(), message.size() );
            m_connection->read();
        }
        else if( command == 'u' )
        {
            std::string id;
            std::string message;
            iss >> id >> message;

            m_connection->unicast( id, message.c_str(), message.size() );
            m_connection->read();
        }
        else if( command == 'd' )
        {
            m_connection->disconnect();
        }
        else if( command == 'r' )
        {
            std::string message;
            iss >> message;

            m_connection->response( message.c_str(), message.size() );
            m_connection->read();
        }
        else
        {
            char const * const message = "unknown";
            m_connection->response( message, strlen( message ) );
            m_connection->read();
        }

        return TConnection::Action::Process;
    }

    void parseError()
    {
        std::cerr
            << "Parse error"
            << std::endl;
    }

    void process()
    {
    }

private:
    TConnection * m_connection;
};

class ConnectionManager;

class Connection
    : public boost::enable_shared_from_this< Connection >
{
public:

    typedef boost::shared_ptr< Connection > ConnectionPtr;

public:

    enum class Action
    {
        Read,
        ReadError,
        Process
    };

    Connection(
        asio::io_service & ioService,
        ConnectionManager & connectionManager
    );

    ip::tcp::socket & socket();

    void disconnect();

    void start(
        Action const action = Task< Connection >::start()
    );

public: // api

    void setId(
        std::string const & id
    );

    std::string const & getId() const ;

    void read();

    void parseError();

    void process();

    void response(
        char const * const message,
        std::size_t const size
    );

    void unicast(
        std::string const & receiverId,
        char const * const message,
        std::size_t const size
    );

    void broadcast(
        char const * const message,
        std::size_t const size
    );

    void doNothing(
        sys::error_code const & errorCode
    )
    {
        if( errorCode )
        {
            std::cerr << "Do Nothing Error: " << errorCode.message() << std::endl;

            disconnect();
        }
    }

private:

    void parse(
        sys::error_code const & errorCode,
        std::size_t const bytesTransferred
    );

    void startAgain(
        sys::error_code const & errorCode
    );

    void stop(
        sys::error_code const & errorCode
    );

private:

    ip::tcp::socket m_socket;
    asio::io_service::strand m_strand;
    ConnectionManager & m_connectionManager;

    Task< Connection > m_task;

    std::string m_id;

    enum { m_maxSize = 1024 };
    char m_buffer[ m_maxSize ];
};

Connection::Connection(
    asio::io_service & ioService,
    ConnectionManager & connectionManager
)
    : m_socket( ioService )
    , m_strand( ioService )
    , m_connectionManager( connectionManager )
    , m_task( this )
{
}

ip::tcp::socket & Connection::socket()
{
    return m_socket;
}

void Connection::setId(
    std::string const & id
)
{
    m_id = id;
}

std::string const & Connection::getId() const
{
    return m_id;
}

void Connection::start(
    Connection::Action const action
)
{
    switch( action )
    {
        case Action::Process:
        {
            process();

            break;
        }

        case Action::ReadError:
        {
            parseError();

            break;
        }

        case Action::Read:
        {
            auto const parse = boost::bind(
                & Connection::parse,
                shared_from_this(),
                placeholders::error,
                placeholders::bytes_transferred()
            );

            m_socket.async_read_some(
                asio::buffer( m_buffer, m_maxSize ),
                m_strand.wrap( parse )
            );

            break;
        }
    }
}

void Connection::read()
{
    start( Action::Read );
}

void Connection::parseError()
{
    m_task.parseError();
}

void Connection::process()
{
    m_task.process();
}

void Connection::parse(
    sys::error_code const & errorCode,
    std::size_t const bytesTransferred
)
{
    if( errorCode )
    {
        std::cerr << "Parse Error: " << errorCode.message() << std::endl;

        disconnect();
    }
    else
    {
        start( m_task.parse( m_buffer, bytesTransferred ) );
    }
}

void Connection::startAgain(
    sys::error_code const & errorCode
)
{
    if( errorCode )
    {
        std::cerr << "Start Again Error: " << errorCode.message() << std::endl;

        disconnect();
    }
    else
    {
        start();
    }
}

typedef Connection::ConnectionPtr ConnectionPtr;

class ConnectionManager
    : public boost::noncopyable
{
    typedef std::set< ConnectionPtr > ConnectionsPtr;

public:

    template< typename Function, class... Args >
    void forEach( Function&& func, Args && ...args )
    {
        boost::lock_guard< boost::mutex > lock( m_mutex );

        for( auto & connection : m_connections )
        {
            func( connection, std::forward< Args >( args )... );
        }
    }

    template< typename Predicate, typename Function, class... Args >
    void forEachIf( Predicate && predicate, Function && func, Args && ...args )
    {
        boost::lock_guard< boost::mutex > lock( m_mutex );

        for( auto & connection : m_connections )
        {
            if( predicate( connection ) )
            {
                func( connection, std::forward< Args >( args )... );
            }
        }
    }

    void add(
        ConnectionPtr & connection
    )
    {
        boost::lock_guard< boost::mutex > lock( m_mutex );

        m_connections.insert( connection );
    }

    void remove(
        ConnectionPtr const & connection
    )
    {
        boost::lock_guard< boost::mutex > lock( m_mutex );

        auto const pos = m_connections.find( connection );

        if( pos != m_connections.end() ){
            m_connections.erase( pos );
        }
    }

private:

    boost::mutex m_mutex;
    ConnectionsPtr m_connections;
};

void Connection::disconnect()
{
    char const * const message = "Goodbye.";

    response( message, strlen( message ) );
}

void Connection::response(
    char const * const message,
    std::size_t const size
)
{
    auto const continuation = boost::bind(
        & Connection::doNothing,
        shared_from_this(),
        placeholders::error
    );

    asio::async_write(
        m_socket,
        asio::buffer( message, size ),
        continuation
    );
}

void Connection::unicast(
    std::string const & receiverId,
    char const * const message,
    std::size_t const size
)
{
    auto const matchReceiver = [ this, & receiverId ]( ConnectionPtr const & connectionPtr )
    {
        return connectionPtr->getId() == receiverId;
    };

    auto sendMessage = [ this, & size, & message ]( ConnectionPtr const & connectionPtr )
    {
        auto const stop = boost::bind(
            & Connection::doNothing,
            shared_from_this(),
            placeholders::error
        );

        asio::async_write(
            connectionPtr->socket(),
            asio::buffer( message, size ),
            stop
        );
    };

    m_connectionManager.forEachIf( matchReceiver, sendMessage );
}

void Connection::broadcast(
    char const * const message,
    std::size_t const size
)
{
    auto const skipSender = [ this ]( ConnectionPtr const & connectionPtr )
    {
        return connectionPtr->socket().native_handle() != this->socket().native_handle();
    };

    auto sendMessage = [ this, & size, & message ]( ConnectionPtr const & connectionPtr )
    {
        auto const continuation = boost::bind(
            & Connection::doNothing,
            shared_from_this(),
            placeholders::error
        );

        asio::async_write(
            connectionPtr->socket(),
            asio::buffer( message, size ),
            continuation
        );
    };

    m_connectionManager.forEachIf( skipSender, sendMessage );
}

void Connection::stop(
    sys::error_code const & errorCode
)
{
    m_connectionManager.remove( shared_from_this() );
}

class Server
{
public:

    Server(
        std::string const & port
    )
        : m_acceptor( m_ioService )
        , m_signals( m_ioService )
    {
        m_signals.add( SIGINT );
        m_signals.add( SIGTERM );
        m_signals.add( SIGQUIT );

        m_signals.async_wait(
            boost::bind( & Server::disconnect, this )
        );

        ip::tcp::resolver resolver( m_ioService );
        ip::tcp::resolver::query query( "127.0.0.1", port );
        ip::tcp::endpoint endpoint = * resolver.resolve( query );

        m_acceptor.open( endpoint.protocol() );
        m_acceptor.set_option( ip::tcp::acceptor::reuse_address( true ) );
        m_acceptor.bind( endpoint );
        m_acceptor.listen();

        startAccept();
    }

    void run()
    {
        boost::thread_group threadGroup;

        auto const threadBody = boost::bind(
            & asio::io_service::run,
            & m_ioService
        );

        for( unsigned i = 0 ; i < 4 ; ++ i )
        {
            threadGroup.create_thread( threadBody );
        }

        threadGroup.join_all();
    }

private:

    void startAccept()
    {
        m_newConnection.reset( new Connection( m_ioService, m_connectionManager ) );

        auto const onAccepted = boost::bind(
            & Server::onAccepted,
            this,
            placeholders::error
        );

        m_acceptor.async_accept(
            m_newConnection->socket(),
            onAccepted
        );
    }

    void onAccepted(
        sys::error_code const & errorCode
    )
    {
        if( ! errorCode )
        {
            m_connectionManager.add( m_newConnection );

            m_newConnection->start();
        }

        startAccept();
    }

    void disconnect()
    {
        m_connectionManager.forEach(
            boost::bind( & Connection::disconnect, _1 )
        );

        m_ioService.stop();
    }

private:

    asio::io_service m_ioService;
    asio::ip::tcp::acceptor m_acceptor;
    asio::signal_set m_signals;

    ConnectionPtr m_newConnection;
    ConnectionManager m_connectionManager;
};

int main( int argc, char* argv[] )
{
    Server( argv[1] ).run();
}

<|endoftext|>


<commit_before>#include "server.h"

<commit_msg>Write (most of) server class<commit_after>#include "server.h"

class Server {
	public:
		Server(std::tr1::unordered_map<std::string, std::string> serverConfig);
		void parseCapab(std::vector<std::string> line005);
		void sendMsg(std::string message);
		bool isConnected();
	private:
		std::string receiveLine();
		std::string networkName;
		std::vector<char> statusModes, chanTypes, chanModes;
		short numModes;
		Socket connection ();
};

Server::Server(std::tr1::unordered_map<std::string, std::string> serverConfig) {
	connection.connect(serverConfig["address"], serverConfig["port"]);
	// handle the whole connection to the server soon
}

void Server::parseCapab(std::vector<std::string> line005) {
	// I'll handle this when I get there.
}

void Server::sendMsg(std::string message) {
	std::cout << networkName << ">" << message << std::endl;
	message += "\r\n";
	connection.send(message);
}

std::string Server::receiveLine() {
	return connection.receive();
}

bool Server::isConnected() {
	return connection.connected;
}<|endoftext|>


<commit_before>#include "tests-base.hpp"

#include "helpers-casemapping.hpp"
#include "helpers-strings.hpp"

TEST(SpecialCasing, LithuanianRemoveDotAbove)
{
	// Remove DOT ABOVE after "i" with upper or titlecase

	// U+0049 U+0307
	// U+0069

	EXPECT_STREQ("lt-LT", setlocale(LC_ALL, "lt-LT"));
	EXPECT_CASEMAPPING_EQ("i\xCC\x87", "i\xCC\x87", "I", "I");
	setlocale(LC_ALL, "C");
}<commit_msg>Add tests for Lithuanian special case mapping.<commit_after>#include "tests-base.hpp"

#include "helpers-casemapping.hpp"
#include "helpers-strings.hpp"

TEST(SpecialCasing, LithuanianRemoveDotAbove)
{
	EXPECT_STREQ("lt-LT", setlocale(LC_ALL, "lt-LT"));

	// Remove DOT ABOVE after "i" with upper or titlecase

	EXPECT_CASEMAPPING_EQ("i\xCC\x87", "i\xCC\x87", "I", "I"); // COMBINING DOT ABOVE

	setlocale(LC_ALL, "C");
}

TEST(SpecialCasing, LithuanianIntroduceExplicitDot)
{
	EXPECT_STREQ("lt-LT", setlocale(LC_ALL, "lt-LT"));

	// Introduce an explicit dot above when lowercasing capital I's and J's
	// whenever there are more accents above.
	// (of the accents used in Lithuanian: grave, acute, tilde above, and ogonek)

	EXPECT_CASEMAPPING_EQ("I", "i\xCC\x87", "I", "I"); // LATIN CAPITAL LETTER I
	EXPECT_CASEMAPPING_EQ("J", "j\xCC\x87", "J", "J"); // LATIN CAPITAL LETTER J
	EXPECT_CASEMAPPING_EQ("\xC4\xAE", "\xC4\xAF\xCC\x87", "\xC4\xAE", "\xC4\xAE"); // LATIN CAPITAL LETTER I WITH OGONEK
	EXPECT_CASEMAPPING_EQ("\xC3\x8C", "i\xCC\x87\xCC\x80", "\xC3\x8C", "\xC3\x8C"); // LATIN CAPITAL LETTER I WITH GRAVE
	EXPECT_CASEMAPPING_EQ("\xC3\x8D", "i\xCC\x87\xCC\x81", "\xC3\x8D", "\xC3\x8D"); // LATIN CAPITAL LETTER I WITH ACUTE
	EXPECT_CASEMAPPING_EQ("\xC4\xA8", "i\xCC\x87\xCC\x83", "\xC4\xA8", "\xC4\xA8"); // LATIN CAPITAL LETTER I WITH TILDE

	setlocale(LC_ALL, "C");
}<|endoftext|>


<commit_before><commit_msg>Fixed performance problem with line < 0.<commit_after><|endoftext|>


<commit_before><commit_msg>moved check for stopping non running loop<commit_after><|endoftext|>


<commit_before>///
/// @file  generate.cpp
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <generate.hpp>
#include <imath.hpp>

#include <stdint.h>
#include <algorithm>
#include <limits>
#include <vector>

using namespace std;

namespace primecount {

/// Generate a vector with Möbius function values.
/// This implementation is based on code by Rick Sladkey:
/// http://mathoverflow.net/a/99545
///
vector<int32_t> generate_moebius(int64_t max)
{
  vector<int32_t> mu(max + 1, 1);

  for (int32_t i = 2; i * i <= max; i++)
  {
    if (mu[i] == 1)
    {
      for (int32_t j = i; j <= max; j += i)
        mu[j] *= -i;
      for (int32_t j = i * i; j <= max; j += i * i)
        mu[j] = 0;
    }
  }

  for (int32_t i = 2; i <= max; i++)
  {
    if (mu[i] == i)
      mu[i] = 1;
    else if (mu[i] == -i)
      mu[i] = -1;
    else if (mu[i] < 0)
      mu[i] = 1;
    else if (mu[i] > 0)
      mu[i] = -1;
  }

  return mu;
}

/// Generate a vector with the least prime factors
/// of the integers <= max
///
vector<int32_t> generate_lpf(int64_t max)
{
  vector<int32_t> lpf(max + 1, 1);

  // phi(x / 1, c) contributes to the sum in the
  // Lagarias-Miller-Odlyzko prime counting algorithm,
  // thus set lpf[1] = MAX (normally lpf[1] = 1)
  if (lpf.size() > 1)
    lpf[1] = numeric_limits<int32_t>::max();

  for (int32_t i = 2; i * i <= max; i++)
    if (lpf[i] == 1)
      for (int32_t j = i * 2; j <= max; j += i)
        if (lpf[j] == 1)
          lpf[j] = i;

  for (int32_t i = 2; i <= max; i++)
    if (lpf[i] == 1)
      lpf[i] = i;

  return lpf;
}

/// Generate a vector with the prime counts <= max
/// using the sieve of Eratosthenes
///
vector<int32_t> generate_pi(int64_t max)
{
  int64_t size = max + 1;
  vector<char> sieve(size, 1);

  for (int64_t i = 2; i * i <= max; i++)
    if (sieve[i])
      for (int64_t j = i * i; j <= max; j += i)
        sieve[j] = 0;

  vector<int32_t> pi(size, 0);
  int32_t pix = 0;

  for (int64_t x = 2; x <= max; x++)
  {
    pix += sieve[x];
    pi[x] = pix;
  }

  return pi;
}

} // namespace
<commit_msg>Use https link instead of http<commit_after>///
/// @file  generate.cpp
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <generate.hpp>
#include <imath.hpp>

#include <stdint.h>
#include <algorithm>
#include <limits>
#include <vector>

using namespace std;

namespace primecount {

/// Generate a vector with Möbius function values.
/// This implementation is based on code by Rick Sladkey:
/// https://mathoverflow.net/q/99545
///
vector<int32_t> generate_moebius(int64_t max)
{
  vector<int32_t> mu(max + 1, 1);

  for (int32_t i = 2; i * i <= max; i++)
  {
    if (mu[i] == 1)
    {
      for (int32_t j = i; j <= max; j += i)
        mu[j] *= -i;
      for (int32_t j = i * i; j <= max; j += i * i)
        mu[j] = 0;
    }
  }

  for (int32_t i = 2; i <= max; i++)
  {
    if (mu[i] == i)
      mu[i] = 1;
    else if (mu[i] == -i)
      mu[i] = -1;
    else if (mu[i] < 0)
      mu[i] = 1;
    else if (mu[i] > 0)
      mu[i] = -1;
  }

  return mu;
}

/// Generate a vector with the least prime factors
/// of the integers <= max
///
vector<int32_t> generate_lpf(int64_t max)
{
  vector<int32_t> lpf(max + 1, 1);

  // phi(x / 1, c) contributes to the sum in the
  // Lagarias-Miller-Odlyzko prime counting algorithm,
  // thus set lpf[1] = MAX (normally lpf[1] = 1)
  if (lpf.size() > 1)
    lpf[1] = numeric_limits<int32_t>::max();

  for (int32_t i = 2; i * i <= max; i++)
    if (lpf[i] == 1)
      for (int32_t j = i * 2; j <= max; j += i)
        if (lpf[j] == 1)
          lpf[j] = i;

  for (int32_t i = 2; i <= max; i++)
    if (lpf[i] == 1)
      lpf[i] = i;

  return lpf;
}

/// Generate a vector with the prime counts <= max
/// using the sieve of Eratosthenes
///
vector<int32_t> generate_pi(int64_t max)
{
  int64_t size = max + 1;
  vector<char> sieve(size, 1);

  for (int64_t i = 2; i * i <= max; i++)
    if (sieve[i])
      for (int64_t j = i * i; j <= max; j += i)
        sieve[j] = 0;

  vector<int32_t> pi(size, 0);
  int32_t pix = 0;

  for (int64_t x = 2; x <= max; x++)
  {
    pix += sieve[x];
    pi[x] = pix;
  }

  return pi;
}

} // namespace
<|endoftext|>


<commit_before><commit_msg>+ added AST-output<commit_after><|endoftext|>


<commit_before>/*!
 * Copyright (c) 2015 by Contributors
 * \file concat.cc
 * \brief
 * \author Bing Xu
*/

#include "./concat-inl.h"
#if MXNET_USE_MKL2017 == 1
#include <mkl_memory.h>
#include "./mkl/mkl_memory-inl.h"
#include "./mkl/mkl_concat-inl.h"
#endif  // MXNET_USE_MKL2017

namespace mxnet {
namespace op {
template<>
Operator* CreateOp<cpu>(ConcatParam param, int dtype) {
  Operator *op = NULL;
#if MXNET_USE_MKL2017 == 1
  if ((1 == param.dim) &&
    (param.num_args < (dnnResourceMultipleDst - dnnResourceMultipleSrc))) {
    switch (dtype) {
      case mshadow::kFloat32:
      return new MKLConcatOp<cpu, float>(param);
    case mshadow::kFloat64:
      return new MKLConcatOp<cpu, double>(param);
    default:
      break;
    }
  }
  if (enableMKLWarnGenerated())
    LOG(INFO) << MKLConcatOp<cpu, float>::getName() << " Skip MKL optimization";
#endif
  MSHADOW_TYPE_SWITCH(dtype, DType, {
    op = new ConcatOp<cpu, DType>(param);
  });
  return op;
}

Operator* ConcatProp::CreateOperatorEx(Context ctx, std::vector<TShape> *in_shape,
                                       std::vector<int> *in_type) const {
  DO_BIND_DISPATCH(CreateOp, param_, in_type->at(0));
}

DMLC_REGISTER_PARAMETER(ConcatParam);

MXNET_REGISTER_OP_PROPERTY(Concat, ConcatProp)
.describe(R"code(Concate a list of array along a given axis.

The dimension sizes of the input arrays on the given axis should be the same.

For example::

  x = [[1,1],[1,1]]
  y = [[2,2],[2,2]]
  z = [[3,3],[3,3],[3,3]]

  Concat(x,y,z,dim=0) = [[ 1.,  1.],
                         [ 1.,  1.],
                         [ 2.,  2.],
                         [ 2.,  2.],
                         [ 3.,  3.],
                         [ 3.,  3.],
                         [ 3.,  3.]]

  Concat(x,y,z,dim=1) = [[ 1.,  1.,  2.,  2.],
                         [ 1.,  1.,  2.,  2.]]

)code" ADD_FILELINE)
.add_argument("data", "NDArray-or-Symbol[]", "List of tensors to concatenate")
.add_arguments(ConcatParam::__FIELDS__())
.set_key_var_num_args("num_args");

NNVM_REGISTER_OP(Concat).add_alias("concat");

}  // namespace op
}  // namespace mxnet
<commit_msg>Fix concat.cc documentation (#5882)<commit_after>/*!
 * Copyright (c) 2015 by Contributors
 * \file concat.cc
 * \brief
 * \author Bing Xu
*/

#include "./concat-inl.h"
#if MXNET_USE_MKL2017 == 1
#include <mkl_memory.h>
#include "./mkl/mkl_memory-inl.h"
#include "./mkl/mkl_concat-inl.h"
#endif  // MXNET_USE_MKL2017

namespace mxnet {
namespace op {
template<>
Operator* CreateOp<cpu>(ConcatParam param, int dtype) {
  Operator *op = NULL;
#if MXNET_USE_MKL2017 == 1
  if ((1 == param.dim) &&
    (param.num_args < (dnnResourceMultipleDst - dnnResourceMultipleSrc))) {
    switch (dtype) {
      case mshadow::kFloat32:
      return new MKLConcatOp<cpu, float>(param);
    case mshadow::kFloat64:
      return new MKLConcatOp<cpu, double>(param);
    default:
      break;
    }
  }
  if (enableMKLWarnGenerated())
    LOG(INFO) << MKLConcatOp<cpu, float>::getName() << " Skip MKL optimization";
#endif
  MSHADOW_TYPE_SWITCH(dtype, DType, {
    op = new ConcatOp<cpu, DType>(param);
  });
  return op;
}

Operator* ConcatProp::CreateOperatorEx(Context ctx, std::vector<TShape> *in_shape,
                                       std::vector<int> *in_type) const {
  DO_BIND_DISPATCH(CreateOp, param_, in_type->at(0));
}

DMLC_REGISTER_PARAMETER(ConcatParam);

MXNET_REGISTER_OP_PROPERTY(Concat, ConcatProp)
.describe(R"code(Concate a list of array along a given axis.

The dimension sizes of the input arrays on the given axis should be the same.

For example::

  x = [[1,1],[1,1]]
  y = [[2,2],[2,2]]
  z = [[3,3],[3,3],[3,3]]

  Concat(x,y,z,dim=0) = [[ 1.,  1.],
                         [ 1.,  1.],
                         [ 2.,  2.],
                         [ 2.,  2.],
                         [ 3.,  3.],
                         [ 3.,  3.],
                         [ 3.,  3.]]

  Concat(x,y,dim=1) = [[ 1.,  1.,  2.,  2.],
                         [ 1.,  1.,  2.,  2.]]

)code" ADD_FILELINE)
.add_argument("data", "NDArray-or-Symbol[]", "List of tensors to concatenate")
.add_arguments(ConcatParam::__FIELDS__())
.set_key_var_num_args("num_args");

NNVM_REGISTER_OP(Concat).add_alias("concat");

}  // namespace op
}  // namespace mxnet
<|endoftext|>


<commit_before>#include "optimal_solver.h"
#include "indexing.h"
#include "corner_permutation.h"
#include "corner_orientation.h"
#include "corner.h"
#include "edge_orientation.h"
#include "edge_permutation.h"
#include <iostream>
#include <ctime>
#include <sstream>
#include <iomanip>

double diffclock(clock_t clock1, clock_t clock2)
{
    double diffticks = abs(clock1 - clock2);
    double diffms = (diffticks) / (CLOCKS_PER_SEC / 1000);
    return diffms;
}

OptimalSolver::OptimalSolver()
{
    CornerPermutation cp;
    cp.buildTransitionTable();
    cp_transition = cp.getTransitionTable();

    CornerOrientation co;
    co.buildTransitionTable();
    co_transition = co.getTransitionTable();

    Corner corner(cp_transition, co_transition);
    corner.buildPruneTable();
    c_prune = corner.getPruneTable();

    EdgeOrientation eo;
    eo.buildTransitionTable();
    eo.buildPruneTable();
    eo_transition = eo.getTransitionTable();
    eo_prune = eo.getPruneTable();

    EdgePermutation ep;
    ep.buildTransitionTable();
    ep.buildPruneTable();
    //ep.buildPruneTable2();
    ep_transition = ep.getTransitionTable();
    ep1_prune = ep.getPruneTable();
    //ep2_prune = ep.getPruneTable2();

    // IDA* for e_prune
    edges_combined_max = 8;
    e_prune = unordered_map<long long, char>(73596790*2);

    prune_count = 0;
    e_prune.clear();
    char depth = 0;
    long long max = 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1;
    cout << endl << "Edge Prune Table:" << endl;
    while (prune_count < max && depth < edges_combined_max)
    {
        prune_treeSearch(0, 366288, depth, depth, -1);
        cout << "Depth " << (int)depth << ": " << prune_count << endl;
        depth++;
    }

    long long sum_c_prune = 0;
    for (long long i = 0; i < c_prune.size(); i++)
        sum_c_prune += c_prune[i];
    cout << "average prune depth corners: " << (sum_c_prune / (double)c_prune.size()) << endl;

    long long sum_e1_prune = 0;
    for (long long i = 0; i < ep1_prune.size(); i++)
        sum_e1_prune += ep1_prune[i];
    cout << "average prune depth corners: " << (sum_e1_prune / (double)ep1_prune.size()) << endl;

    moveNames[0] = string("U");
    moveNames[1] = string("D");
    moveNames[2] = string("R");
    moveNames[3] = string("L");
    moveNames[4] = string("F");
    moveNames[5] = string("B");
    moveCntNames[0] = string(" ");
    moveCntNames[1] = string("2");
    moveCntNames[2] = string("'");
};

char OptimalSolver::solve(string scramble)
{
    vector<int> cp_vec{ 0, 1, 2, 3, 4, 5, 6, 7 };
    vector<int> co_vec{ 0, 0, 0, 0, 0, 0, 0, 0 };
    vector<int> eo_vec{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    vector<int> ep1_vec{ 0, 1, 2, 3, 4, 5 };
    vector<int> ep2_vec{ 6, 7, 8, 9, 10, 11, 12 };

    apply_scramble(scramble, cp_vec, co_vec, eo_vec, ep1_vec, ep2_vec);

    cout << "Solve the scramble \"" << scramble << "\": " << endl;
    char depth = IDA(cp_vec, co_vec, eo_vec, ep1_vec, ep2_vec);
    cout << endl;
    return depth;
}

char OptimalSolver::IDA(vector<int> cornerPermutation, vector<int> cornerOrientation, vector<int> edgeOrientation, vector<int> edgePermutation1, vector<int> edgePermutation2)
{
    int cornerPerm = Indexing::permutation_to_index(cornerPermutation);
    int cornerOrient = Indexing::orientation_to_index_dependent(cornerOrientation, 3);
    int edgeOrient = Indexing::orientation_to_index_dependent(edgeOrientation, 2);
    EdgePermutation ep;
    int edgePerm1 = ep.array_to_index(edgePermutation1);
    int edgePerm2 = ep.array_to_index(edgePermutation2);

    solution = "";
    nodeCnt = 0;
    clock_t start = clock();

    cout << "Start solving" << endl;
    char depth;
    for (depth = 0; depth <= 20; depth++)
    {
        cout << "Depth " << setfill(' ') << setw(2) << (int)depth << ": " << flush;
        if (treeSearch(cornerPerm, cornerOrient, edgeOrient, edgePerm1, edgePerm2, depth, -1))
        {
            cout << "solution, " << setfill(' ') << setw(10) << nodeCnt << " nodes visited" << endl;
            cout << solution.c_str() << endl;
            break;
        }
        else
        {
            cout << "nothing,  " << setfill(' ') << setw(10) << nodeCnt << " nodes visited" << endl;
        }
    }
    cout << "total: " << nodeCnt << " nodes visited" << endl;
    clock_t end = clock();
    double seconds = diffclock(start, end) / 1000.0;
    cout << "Time: " << seconds << " seconds(" << (int)(nodeCnt / seconds) << " nodes / second)" << endl;

    return depth;
}

bool OptimalSolver::treeSearch(int cornerPermutation, int cornerOrientation, int edgeOrientation, int edgePermutation1, int edgePermutation2, char depth, int lastMove)
{
    nodeCnt++;
    if (depth == 0)
    {
        return (cornerPermutation == 0 && cornerOrientation == 0 && edgeOrientation == 0 && edgePermutation1 == 0 && edgePermutation2 == 366288);
    }
    else
    {
        long long p = edgePermutation1 * 665280L + edgePermutation2;
        char ep_prune_value = edges_combined_max;
        if (e_prune.count(p) == 1)
            ep_prune_value = e_prune[p];

        if (c_prune[cornerPermutation * 2187 + cornerOrientation] <= depth && eo_prune[edgeOrientation] <= depth && ep_prune_value <= depth)
        {
            for (int move = 0; move < 6; move++)
            {
                if (move == lastMove)
                    continue;
                if ((lastMove & 1) == 1 && move == lastMove - 1)
                    continue;

                for (int j = 0; j < 3; j++)
                {
                    cornerPermutation = cp_transition[cornerPermutation][move];
                    cornerOrientation = co_transition[cornerOrientation][move];
                    edgeOrientation = eo_transition[edgeOrientation][move];
                    edgePermutation1 = ep_transition[edgePermutation1][move];
                    edgePermutation2 = ep_transition[edgePermutation2][move];

                    if (treeSearch(cornerPermutation, cornerOrientation, edgeOrientation, edgePermutation1, edgePermutation2, depth - 1, move))
                    {
                        solution = moveNames[move] + moveCntNames[j] + string(" ") + solution;
                        return true;
                    }
                }
                cornerPermutation = cp_transition[cornerPermutation][move];
                cornerOrientation = co_transition[cornerOrientation][move];
                edgeOrientation = eo_transition[edgeOrientation][move];
                edgePermutation1 = ep_transition[edgePermutation1][move];
                edgePermutation2 = ep_transition[edgePermutation2][move];
            }
        }

        return false;
    }
}

void OptimalSolver::prune_treeSearch(long long ep1, long long ep2, char depth_left, char depth, int lastMove)
{
    long long p = ep1 * 665280 + ep2;

    if (depth_left == 0)
    {
        if (e_prune.count(p) == 0)
        {
            e_prune[p] = depth;
            prune_count++;
        }
    }
    else
    {
        if (e_prune[p] == depth - depth_left)
        {
            for (int move = 0; move < 6; move++)
            {
                if (move == lastMove)
                    continue;
                if ((lastMove & 1) == 1 && move == lastMove - 1)
                    continue;

                for (int j = 0; j < 3; j++)
                {
                    ep1 = ep_transition[ep1][move];
                    ep2 = ep_transition[ep2][move];
                    prune_treeSearch(ep1, ep2, depth_left - 1, depth, move);
                }
                ep1 = ep_transition[ep1][move];
                ep2 = ep_transition[ep2][move];
            }
        }
    }
}

void OptimalSolver::apply_scramble(string scramble, vector<int> &cp_vec, vector<int> &co_vec, vector<int> &eo_vec, vector<int> &ep1_vec, vector<int> &ep2_vec)
{
    CornerPermutation cp;
    CornerOrientation co;
    EdgeOrientation eo;
    EdgePermutation ep;

    stringstream ss(scramble);
    string turn;

    while (ss >> turn)
    {
        int move;
        switch (turn[0])
        {
            case 'U':
                move = 0;
                break;
            case 'D':
                move = 1;
                break;
            case 'R':
                move = 2;
                break;
            case 'L':
                move = 3;
                break;
            case 'F':
                move = 4;
                break;
            case 'B':
                move = 5;
                break;
            default:
                move = 0;
        }

        int count = 1;
        if (turn.size() == 2)
        {
            switch (turn[1])
            {
                case '2':
                    count = 2;
                    break;
                case '\'':
                    count = 3;
                    break;
                default:
                    count = 1;
            }
        }

        for (int i = 0; i < count; i++)
        {
            cp.apply_move(cp_vec, move);
            co.apply_move(co_vec, move);
            eo.apply_move(eo_vec, move);
            ep.apply_move(ep1_vec, move);
            ep.apply_move(ep2_vec, move);
        }
    }
}<commit_msg>Print the current stage while generating tables<commit_after>#include "optimal_solver.h"
#include "indexing.h"
#include "corner_permutation.h"
#include "corner_orientation.h"
#include "corner.h"
#include "edge_orientation.h"
#include "edge_permutation.h"
#include <iostream>
#include <ctime>
#include <sstream>
#include <iomanip>

double diffclock(clock_t clock1, clock_t clock2)
{
    double diffticks = abs(clock1 - clock2);
    double diffms = (diffticks) / (CLOCKS_PER_SEC / 1000);
    return diffms;
}

OptimalSolver::OptimalSolver()
{
    cout << "Generate Corner Permutation Transition Table" << endl;
    CornerPermutation cp;
    cp.buildTransitionTable();
    cp_transition = cp.getTransitionTable();

    cout << "Generate Corner Orientation Transition Table" << endl;
    CornerOrientation co;
    co.buildTransitionTable();
    co_transition = co.getTransitionTable();

    cout << "Generate Corner Prune Table" << endl;
    Corner corner(cp_transition, co_transition);
    corner.buildPruneTable();
    c_prune = corner.getPruneTable();

    cout << "Generate Edge Orientation Transition Table" << endl;
    EdgeOrientation eo;
    eo.buildTransitionTable();
    cout << "Generate Edge Orientation Prune Table" << endl;
    eo.buildPruneTable();
    eo_transition = eo.getTransitionTable();
    eo_prune = eo.getPruneTable();

    cout << "Generate Edge Permutation Transition Table" << endl;
    EdgePermutation ep;
    ep.buildTransitionTable();
    cout << "Generate Edge Permutation Prune Table 1" << endl;
    ep.buildPruneTable();
    //ep.buildPruneTable2();
    ep_transition = ep.getTransitionTable();
    ep1_prune = ep.getPruneTable();
    //ep2_prune = ep.getPruneTable2();

    // IDA* for e_prune
    edges_combined_max = 8;
    e_prune = unordered_map<long long, char>(73596790*2);

    prune_count = 0;
    e_prune.clear();
    char depth = 0;
    long long max = 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1;
    cout << "Generate Edge Permutation Prune Table 2:" << endl;
    while (prune_count < max && depth < edges_combined_max)
    {
        prune_treeSearch(0, 366288, depth, depth, -1);
        cout << "Depth " << (int)depth << ": " << prune_count << endl;
        depth++;
    }

    long long sum_c_prune = 0;
    for (long long i = 0; i < c_prune.size(); i++)
        sum_c_prune += c_prune[i];
    cout << "average prune depth corners: " << (sum_c_prune / (double)c_prune.size()) << endl;

    long long sum_e1_prune = 0;
    for (long long i = 0; i < ep1_prune.size(); i++)
        sum_e1_prune += ep1_prune[i];
    cout << "average prune depth corners: " << (sum_e1_prune / (double)ep1_prune.size()) << endl;

    moveNames[0] = string("U");
    moveNames[1] = string("D");
    moveNames[2] = string("R");
    moveNames[3] = string("L");
    moveNames[4] = string("F");
    moveNames[5] = string("B");
    moveCntNames[0] = string(" ");
    moveCntNames[1] = string("2");
    moveCntNames[2] = string("'");
};

char OptimalSolver::solve(string scramble)
{
    vector<int> cp_vec{ 0, 1, 2, 3, 4, 5, 6, 7 };
    vector<int> co_vec{ 0, 0, 0, 0, 0, 0, 0, 0 };
    vector<int> eo_vec{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    vector<int> ep1_vec{ 0, 1, 2, 3, 4, 5 };
    vector<int> ep2_vec{ 6, 7, 8, 9, 10, 11, 12 };

    apply_scramble(scramble, cp_vec, co_vec, eo_vec, ep1_vec, ep2_vec);

    cout << "Solve the scramble \"" << scramble << "\": " << endl;
    char depth = IDA(cp_vec, co_vec, eo_vec, ep1_vec, ep2_vec);
    cout << endl;
    return depth;
}

char OptimalSolver::IDA(vector<int> cornerPermutation, vector<int> cornerOrientation, vector<int> edgeOrientation, vector<int> edgePermutation1, vector<int> edgePermutation2)
{
    int cornerPerm = Indexing::permutation_to_index(cornerPermutation);
    int cornerOrient = Indexing::orientation_to_index_dependent(cornerOrientation, 3);
    int edgeOrient = Indexing::orientation_to_index_dependent(edgeOrientation, 2);
    EdgePermutation ep;
    int edgePerm1 = ep.array_to_index(edgePermutation1);
    int edgePerm2 = ep.array_to_index(edgePermutation2);

    solution = "";
    nodeCnt = 0;
    clock_t start = clock();

    cout << "Start solving" << endl;
    char depth;
    for (depth = 0; depth <= 20; depth++)
    {
        cout << "Depth " << setfill(' ') << setw(2) << (int)depth << ": " << flush;
        if (treeSearch(cornerPerm, cornerOrient, edgeOrient, edgePerm1, edgePerm2, depth, -1))
        {
            cout << "solution, " << setfill(' ') << setw(10) << nodeCnt << " nodes visited" << endl;
            cout << solution.c_str() << endl;
            break;
        }
        else
        {
            cout << "nothing,  " << setfill(' ') << setw(10) << nodeCnt << " nodes visited" << endl;
        }
    }
    cout << "total: " << nodeCnt << " nodes visited" << endl;
    clock_t end = clock();
    double seconds = diffclock(start, end) / 1000.0;
    cout << "Time: " << seconds << " seconds(" << (int)(nodeCnt / seconds) << " nodes / second)" << endl;

    return depth;
}

bool OptimalSolver::treeSearch(int cornerPermutation, int cornerOrientation, int edgeOrientation, int edgePermutation1, int edgePermutation2, char depth, int lastMove)
{
    nodeCnt++;
    if (depth == 0)
    {
        return (cornerPermutation == 0 && cornerOrientation == 0 && edgeOrientation == 0 && edgePermutation1 == 0 && edgePermutation2 == 366288);
    }
    else
    {
        long long p = edgePermutation1 * 665280L + edgePermutation2;
        char ep_prune_value = edges_combined_max;
        if (e_prune.count(p) == 1)
            ep_prune_value = e_prune[p];

        if (c_prune[cornerPermutation * 2187 + cornerOrientation] <= depth && eo_prune[edgeOrientation] <= depth && ep_prune_value <= depth)
        {
            for (int move = 0; move < 6; move++)
            {
                if (move == lastMove)
                    continue;
                if ((lastMove & 1) == 1 && move == lastMove - 1)
                    continue;

                for (int j = 0; j < 3; j++)
                {
                    cornerPermutation = cp_transition[cornerPermutation][move];
                    cornerOrientation = co_transition[cornerOrientation][move];
                    edgeOrientation = eo_transition[edgeOrientation][move];
                    edgePermutation1 = ep_transition[edgePermutation1][move];
                    edgePermutation2 = ep_transition[edgePermutation2][move];

                    if (treeSearch(cornerPermutation, cornerOrientation, edgeOrientation, edgePermutation1, edgePermutation2, depth - 1, move))
                    {
                        solution = moveNames[move] + moveCntNames[j] + string(" ") + solution;
                        return true;
                    }
                }
                cornerPermutation = cp_transition[cornerPermutation][move];
                cornerOrientation = co_transition[cornerOrientation][move];
                edgeOrientation = eo_transition[edgeOrientation][move];
                edgePermutation1 = ep_transition[edgePermutation1][move];
                edgePermutation2 = ep_transition[edgePermutation2][move];
            }
        }

        return false;
    }
}

void OptimalSolver::prune_treeSearch(long long ep1, long long ep2, char depth_left, char depth, int lastMove)
{
    long long p = ep1 * 665280 + ep2;

    if (depth_left == 0)
    {
        if (e_prune.count(p) == 0)
        {
            e_prune[p] = depth;
            prune_count++;
        }
    }
    else
    {
        if (e_prune[p] == depth - depth_left)
        {
            for (int move = 0; move < 6; move++)
            {
                if (move == lastMove)
                    continue;
                if ((lastMove & 1) == 1 && move == lastMove - 1)
                    continue;

                for (int j = 0; j < 3; j++)
                {
                    ep1 = ep_transition[ep1][move];
                    ep2 = ep_transition[ep2][move];
                    prune_treeSearch(ep1, ep2, depth_left - 1, depth, move);
                }
                ep1 = ep_transition[ep1][move];
                ep2 = ep_transition[ep2][move];
            }
        }
    }
}

void OptimalSolver::apply_scramble(string scramble, vector<int> &cp_vec, vector<int> &co_vec, vector<int> &eo_vec, vector<int> &ep1_vec, vector<int> &ep2_vec)
{
    CornerPermutation cp;
    CornerOrientation co;
    EdgeOrientation eo;
    EdgePermutation ep;

    stringstream ss(scramble);
    string turn;

    while (ss >> turn)
    {
        int move;
        switch (turn[0])
        {
            case 'U':
                move = 0;
                break;
            case 'D':
                move = 1;
                break;
            case 'R':
                move = 2;
                break;
            case 'L':
                move = 3;
                break;
            case 'F':
                move = 4;
                break;
            case 'B':
                move = 5;
                break;
            default:
                move = 0;
        }

        int count = 1;
        if (turn.size() == 2)
        {
            switch (turn[1])
            {
                case '2':
                    count = 2;
                    break;
                case '\'':
                    count = 3;
                    break;
                default:
                    count = 1;
            }
        }

        for (int i = 0; i < count; i++)
        {
            cp.apply_move(cp_vec, move);
            co.apply_move(co_vec, move);
            eo.apply_move(eo_vec, move);
            ep.apply_move(ep1_vec, move);
            ep.apply_move(ep2_vec, move);
        }
    }
}<|endoftext|>


<commit_before>/*
 * paged_grid.cpp
 *
 *  Created on: 06.05.2010
 *      Author: gmueller
 */

#include "arguments.hpp"

#include "gadget/Grid.hpp"
#include "gadget/Index3.hpp"
#include "gadget/SmoothParticle.hpp"
#include "gadget/GadgetFile.hpp"
#include "gadget/Vector3.hpp"

#include <ctime>
#include <limits>
#include <algorithm>
#include <omp.h>
#include <sstream>
#include <fstream>

int sph(Arguments &arguments) {

	int size = arguments.getInt("-size", 240000);
	std::cout << "Size:           " << size << " kpc" << std::endl;

	float h = arguments.getFloat("-h", 0.7);
	std::cout << "h:              " << h << std::endl;

	size_t fileSizeKpc = arguments.getInt("-fileSize", 20000);
	std::cout << "FileSize:       " << fileSizeKpc << " kpc ";

	size_t marginKpc = arguments.getInt("-margin", 500);
	std::cout << "Margin:       " << marginKpc << " kpc ";

	std::string prefix = arguments.getString("-prefix", "sph");

	bool verbose = arguments.hasFlag("-v");

	size_t bins = size / fileSizeKpc;
	Grid< std::vector<SmoothParticle> > grid(bins, size);

	std::vector < std::string > files;
	arguments.getVector("-f", files);
	for (size_t iArg = 0; iArg < files.size(); iArg++) {
		std::cout << "Open " << files[iArg] << " (" << (iArg + 1) << "/"
				<< files.size() << ")" << std::endl;

		GadgetFile file;
		file.open(files[iArg]);
		if (file.good() == false) {
			std::cerr << "Failed to open file " << files[iArg] << std::endl;
			return 1;
		}

		file.readHeader();
		int pn = file.getHeader().particleNumberList[0];
		std::cout << "  Number of SmoothParticles: " << pn << std::endl;

		std::cout << "  Read POS block" << std::endl;
		std::vector<float> pos;
		if (file.readFloatBlock("POS ", pos) == false) {
			std::cerr << "Failed to read POS block" << std::endl;
			return 1;
		}

		std::cout << "  Read BFLD block" << std::endl;
		std::vector<float> bfld;
		if (file.readFloatBlock("BFLD", bfld) == false) {
			std::cerr << "Failed to read BFLD block" << std::endl;
			return 1;
		}

		std::cout << "  Read HSML block" << std::endl;
		std::vector<float> hsml;
		if (file.readFloatBlock("HSML", hsml) == false) {
			std::cerr << "Failed to read HSML block" << std::endl;
			return 1;
		}

		for (int iP = 0; iP < pn; iP++) {
			SmoothParticle particle;
			particle.smoothingLength = hsml[iP] / h;
			particle.position.x = (pos[iP * 3] - size / 2) / h + size / 2;
			particle.position.y = (pos[iP * 3 + 1] - size / 2) / h + size / 2;
			particle.position.z = (pos[iP * 3 + 2] - size / 2) / h + size / 2;

			float norm = 1.0 / M_PI / pow(particle.smoothingLength, 3);
			particle.bfield.x = bfld[iP * 3] * norm;
			particle.bfield.y = bfld[iP * 3 + 1] * norm;
			particle.bfield.z = bfld[iP * 3 + 2] * norm;

			Vector3f l = particle.position - Vector3f(
					particle.smoothingLength * 2 + marginKpc);
			l.clamp(0.0, size);

			Vector3f u = particle.position + Vector3f(
					particle.smoothingLength * 2 + marginKpc);
			u.clamp(0.0, size);

			Index3 lower, upper;
			lower.x = (uint32_t) std::floor(l.x / fileSizeKpc);
			lower.y = (uint32_t) std::floor(l.y / fileSizeKpc);
			lower.z = (uint32_t) std::floor(l.z / fileSizeKpc);

			upper.x = (uint32_t) std::ceil(u.x / fileSizeKpc);
			upper.y = (uint32_t) std::ceil(u.y / fileSizeKpc);
			upper.z = (uint32_t) std::ceil(u.z / fileSizeKpc);

			if (verbose && (iP % 100000 ==0)) {
				std::cout << "Pos:" << particle.position << std::endl;
				std::cout << "SL:" << particle.smoothingLength << std::endl;
				std::cout << "Lower:" << lower << std::endl;
				std::cout << "Upper:" << upper << std::endl;
			}

			for (size_t x = lower.x; x < upper.x; x++)
				for (size_t y = lower.y; y < upper.y; y++)
					for (size_t z = lower.z; z < upper.z; z++)
						grid.get(x, y, z).push_back(particle);
		}
	}

	std::cout << "Write output" << std::endl;

	for (size_t x = 0; x < bins; x++) {
		if (verbose) {
			std::cout << "x = " << x << std::endl;
		}

		for (size_t y = 0; y < bins; y++)
			for (size_t z = 0; z < bins; z++) {
				std::stringstream sstr;
				sstr << prefix << "-" << x << "-" << y << "-" << z << ".raw";
				std::ofstream out(sstr.str().c_str(),std::ofstream::binary);
				uint32_t s = grid.get(x, y, z).size();
				if (verbose)
					std::cout << s << std::endl;
				out.write((const char *)&s, sizeof(uint32_t));
				out.write((const char *)&grid.get(x, y, z)[0], sizeof(SmoothParticle) * s);
			}

	}

	return 0;
}
<commit_msg>remove bfield normalization<commit_after>/*
 * paged_grid.cpp
 *
 *  Created on: 06.05.2010
 *      Author: gmueller
 */

#include "arguments.hpp"

#include "gadget/Grid.hpp"
#include "gadget/Index3.hpp"
#include "gadget/SmoothParticle.hpp"
#include "gadget/GadgetFile.hpp"
#include "gadget/Vector3.hpp"

#include <ctime>
#include <limits>
#include <algorithm>
#include <omp.h>
#include <sstream>
#include <fstream>

int sph(Arguments &arguments) {

	int size = arguments.getInt("-size", 240000);
	std::cout << "Size:           " << size << " kpc" << std::endl;

	float h = arguments.getFloat("-h", 0.7);
	std::cout << "h:              " << h << std::endl;

	size_t fileSizeKpc = arguments.getInt("-fileSize", 20000);
	std::cout << "FileSize:       " << fileSizeKpc << " kpc ";

	size_t marginKpc = arguments.getInt("-margin", 500);
	std::cout << "Margin:       " << marginKpc << " kpc ";

	std::string prefix = arguments.getString("-prefix", "sph");

	bool verbose = arguments.hasFlag("-v");

	size_t bins = size / fileSizeKpc;
	Grid< std::vector<SmoothParticle> > grid(bins, size);

	std::vector < std::string > files;
	arguments.getVector("-f", files);
	for (size_t iArg = 0; iArg < files.size(); iArg++) {
		std::cout << "Open " << files[iArg] << " (" << (iArg + 1) << "/"
				<< files.size() << ")" << std::endl;

		GadgetFile file;
		file.open(files[iArg]);
		if (file.good() == false) {
			std::cerr << "Failed to open file " << files[iArg] << std::endl;
			return 1;
		}

		file.readHeader();
		int pn = file.getHeader().particleNumberList[0];
		std::cout << "  Number of SmoothParticles: " << pn << std::endl;

		std::cout << "  Read POS block" << std::endl;
		std::vector<float> pos;
		if (file.readFloatBlock("POS ", pos) == false) {
			std::cerr << "Failed to read POS block" << std::endl;
			return 1;
		}

		std::cout << "  Read BFLD block" << std::endl;
		std::vector<float> bfld;
		if (file.readFloatBlock("BFLD", bfld) == false) {
			std::cerr << "Failed to read BFLD block" << std::endl;
			return 1;
		}

		std::cout << "  Read HSML block" << std::endl;
		std::vector<float> hsml;
		if (file.readFloatBlock("HSML", hsml) == false) {
			std::cerr << "Failed to read HSML block" << std::endl;
			return 1;
		}

		for (int iP = 0; iP < pn; iP++) {
			SmoothParticle particle;
			particle.smoothingLength = hsml[iP] / h;
			particle.position.x = (pos[iP * 3] - size / 2) / h + size / 2;
			particle.position.y = (pos[iP * 3 + 1] - size / 2) / h + size / 2;
			particle.position.z = (pos[iP * 3 + 2] - size / 2) / h + size / 2;

			particle.bfield.x = bfld[iP * 3];
			particle.bfield.y = bfld[iP * 3 + 1];
			particle.bfield.z = bfld[iP * 3 + 2];

			Vector3f l = particle.position - Vector3f(
					particle.smoothingLength * 2 + marginKpc);
			l.clamp(0.0, size);

			Vector3f u = particle.position + Vector3f(
					particle.smoothingLength * 2 + marginKpc);
			u.clamp(0.0, size);

			Index3 lower, upper;
			lower.x = (uint32_t) std::floor(l.x / fileSizeKpc);
			lower.y = (uint32_t) std::floor(l.y / fileSizeKpc);
			lower.z = (uint32_t) std::floor(l.z / fileSizeKpc);

			upper.x = (uint32_t) std::ceil(u.x / fileSizeKpc);
			upper.y = (uint32_t) std::ceil(u.y / fileSizeKpc);
			upper.z = (uint32_t) std::ceil(u.z / fileSizeKpc);

			if (verbose && (iP % 100000 ==0)) {
				std::cout << "Pos:" << particle.position << std::endl;
				std::cout << "SL:" << particle.smoothingLength << std::endl;
				std::cout << "Lower:" << lower << std::endl;
				std::cout << "Upper:" << upper << std::endl;
			}

			for (size_t x = lower.x; x < upper.x; x++)
				for (size_t y = lower.y; y < upper.y; y++)
					for (size_t z = lower.z; z < upper.z; z++)
						grid.get(x, y, z).push_back(particle);
		}
	}

	std::cout << "Write output" << std::endl;

	for (size_t x = 0; x < bins; x++) {
		if (verbose) {
			std::cout << "x = " << x << std::endl;
		}

		for (size_t y = 0; y < bins; y++)
			for (size_t z = 0; z < bins; z++) {
				std::stringstream sstr;
				sstr << prefix << "-" << x << "-" << y << "-" << z << ".raw";
				std::ofstream out(sstr.str().c_str(),std::ofstream::binary);
				uint32_t s = grid.get(x, y, z).size();
				if (verbose)
					std::cout << s << std::endl;
				out.write((const char *)&s, sizeof(uint32_t));
				out.write((const char *)&grid.get(x, y, z)[0], sizeof(SmoothParticle) * s);
			}

	}

	return 0;
}
<|endoftext|>