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

#ifndef _SFXTABDLG_HXX //autogen
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _IMAGEBTN_HXX //autogen
#include <vcl/imagebtn.hxx>
#endif
#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _ACTCTRL_HXX
#include <actctrl.hxx>
#endif
#include "prcntfld.hxx"
#include "swtypes.hxx"

class SwTabCols;
class SwWrtShell;
class SwTableRep;

struct TColumn
{
    SwTwips nWidth;
    BOOL    bVisible;
};

class SwFormatTablePage : public SfxTabPage
{
    FixedLine        aOptionsFL;
    FixedText       aNameFT;
    TableNameEdit   aNameED;
    FixedText       aWidthFT;
    PercentField    aWidthMF;
    CheckBox        aRelWidthCB;

    FixedLine        aPosFL;
    RadioButton     aFullBtn;
    RadioButton     aLeftBtn;
    RadioButton     aFromLeftBtn;
    RadioButton     aRightBtn;
    RadioButton     aCenterBtn;
    RadioButton     aFreeBtn;

    FixedLine       aDistFL;
    FixedText       aLeftFT;
    PercentField    aLeftMF;
    FixedText       aRightFT;
    PercentField    aRightMF;
    FixedText       aTopFT;
    MetricField     aTopMF;
    FixedText       aBottomFT;
    MetricField     aBottomMF;

    FixedLine       aPropertiesFL;
    FixedText       aTextDirectionFT;
    ListBox         aTextDirectionLB;

    SwTableRep*     pTblData;
    SwTwips         nSaveWidth;
    SwTwips         nMinTableWidth;
    USHORT          nOldAlign;
    BOOL            bModified;
    BOOL            bFull:1;
    BOOL            bHtmlMode : 1;

    void        Init();
    void        ModifyHdl( Edit* pEdit );

    DECL_LINK( AutoClickHdl, CheckBox * );
    DECL_LINK( RelWidthClickHdl, CheckBox * );
    DECL_LINK( RightModifyHdl, MetricField * );
    DECL_LINK( UpDownLoseFocusHdl, MetricField * );

public:
    SwFormatTablePage( Window* pParent, const SfxItemSet& rSet );

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet = 0 );
};

/*-------------------------------------------------------
 TabPage Format/Tabelle/Spalten
--------------------------------------------------------- */
#define MET_FIELDS 6 //Anzahl der verwendeten MetricFields

class SwTableColumnPage : public SfxTabPage
{
    CheckBox        aModifyTableCB;
    CheckBox        aProportionalCB;
    FixedText       aSpaceFT;
    MetricField     aSpaceED;

    ImageButton     aUpBtn;
    FixedText       aFT1;
    PercentField    aMF1;
    FixedText       aFT2;
    PercentField    aMF2;
    FixedText       aFT3;
    PercentField    aMF3;
    FixedText       aFT4;
    PercentField    aMF4;
    FixedText       aFT5;
    PercentField    aMF5;
    FixedText       aFT6;
    PercentField    aMF6;
    ImageButton     aDownBtn;
    FixedLine        aColFL;

    SwTableRep*     pTblData;
    PercentField*   pFieldArr[MET_FIELDS];
    FixedText*      pTextArr[MET_FIELDS];
    SwTwips         nTableWidth;
    SwTwips         nMinWidth;
    USHORT          nNoOfCols;
    USHORT          nNoOfVisibleCols;
    //Breite merken, wenn auf autom. Ausrichtung gestellt wird
    USHORT          aValueTbl[MET_FIELDS];//primaere Zuordnung der MetricFields
    BOOL            bModified:1;
    BOOL            bModifyTbl:1;
    BOOL            bPercentMode:1;

    void        Init(BOOL bWeb);
    DECL_LINK( AutoClickHdl, CheckBox * );
    void        ModifyHdl( PercentField* pEdit );
    DECL_LINK( UpHdl, PercentField * );
    DECL_LINK( DownHdl, PercentField * );
    DECL_LINK( LoseFocusHdl, PercentField * );
    DECL_LINK( ModeHdl, CheckBox * );
    void        UpdateCols( USHORT nAktPos );
    SwTwips     GetVisibleWidth(USHORT nPos);
    void        SetVisibleWidth(USHORT nPos, SwTwips nNewWidth);
public:
    SwTableColumnPage( Window* pParent, const SfxItemSet& rSet );
    ~SwTableColumnPage();

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet = 0 );

};

/*-----------------12.12.96 11.48-------------------
        Textflu
--------------------------------------------------*/
class SwTextFlowPage : public SfxTabPage
{
    FixedLine        aFlowFL;
    CheckBox        aPgBrkCB;
    RadioButton     aPgBrkRB;
    RadioButton     aColBrkRB;
    RadioButton     aPgBrkBeforeRB;
    RadioButton     aPgBrkAfterRB;
    CheckBox        aPageCollCB;
    ListBox         aPageCollLB;
    FixedText       aPageNoFT;
    NumericField    aPageNoNF;
    CheckBox        aSplitCB;
    TriStateBox     aSplitRowCB;
    CheckBox        aKeepCB;
    CheckBox        aHeadLineCB;

    FixedLine        aVertOrientFL;
    RadioButton     aTopRB;
    RadioButton     aCenterRB;
    RadioButton     aBottomRB;

    SwWrtShell*     pShell;

    BOOL            bPageBreak;
    BOOL            bHtmlMode;

    DECL_LINK( PageBreakHdl_Impl, CheckBox* );
    DECL_LINK( ApplyCollClickHdl_Impl, CheckBox* );
    DECL_LINK( PageBreakPosHdl_Impl, RadioButton* );
    DECL_LINK( PageBreakTypeHdl_Impl, RadioButton* );
    DECL_LINK( SplitHdl_Impl, CheckBox* );
    DECL_LINK( SplitRowHdl_Impl, TriStateBox* );

    SwTextFlowPage( Window* pParent, const SfxItemSet& rSet );
    ~SwTextFlowPage();

public:
    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );

    void                SetShell(SwWrtShell* pSh);

    void                DisablePageBreak();
};

#endif
<commit_msg>INTEGRATION: CWS vertcell (1.6.34); FILE MERGED 2004/02/10 09:50:08 os 1.6.34.1: #i25068# vertical text in table cells<commit_after>/*************************************************************************
 *
 *  $RCSfile: tablepg.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: svesik $ $Date: 2004-04-21 10:01:45 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SWTABLEPG_HXX
#define _SWTABLEPG_HXX

#ifndef _SFXTABDLG_HXX //autogen
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _IMAGEBTN_HXX //autogen
#include <vcl/imagebtn.hxx>
#endif
#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _ACTCTRL_HXX
#include <actctrl.hxx>
#endif
#include "prcntfld.hxx"
#include "swtypes.hxx"

class SwTabCols;
class SwWrtShell;
class SwTableRep;

struct TColumn
{
    SwTwips nWidth;
    BOOL    bVisible;
};

class SwFormatTablePage : public SfxTabPage
{
    FixedLine        aOptionsFL;
    FixedText       aNameFT;
    TableNameEdit   aNameED;
    FixedText       aWidthFT;
    PercentField    aWidthMF;
    CheckBox        aRelWidthCB;

    FixedLine        aPosFL;
    RadioButton     aFullBtn;
    RadioButton     aLeftBtn;
    RadioButton     aFromLeftBtn;
    RadioButton     aRightBtn;
    RadioButton     aCenterBtn;
    RadioButton     aFreeBtn;

    FixedLine       aDistFL;
    FixedText       aLeftFT;
    PercentField    aLeftMF;
    FixedText       aRightFT;
    PercentField    aRightMF;
    FixedText       aTopFT;
    MetricField     aTopMF;
    FixedText       aBottomFT;
    MetricField     aBottomMF;

    FixedLine       aPropertiesFL;
    FixedText       aTextDirectionFT;
    ListBox         aTextDirectionLB;

    SwTableRep*     pTblData;
    SwTwips         nSaveWidth;
    SwTwips         nMinTableWidth;
    USHORT          nOldAlign;
    BOOL            bModified;
    BOOL            bFull:1;
    BOOL            bHtmlMode : 1;

    void        Init();
    void        ModifyHdl( Edit* pEdit );

    DECL_LINK( AutoClickHdl, CheckBox * );
    DECL_LINK( RelWidthClickHdl, CheckBox * );
    DECL_LINK( RightModifyHdl, MetricField * );
    DECL_LINK( UpDownLoseFocusHdl, MetricField * );

public:
    SwFormatTablePage( Window* pParent, const SfxItemSet& rSet );

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet = 0 );
};

/*-------------------------------------------------------
 TabPage Format/Tabelle/Spalten
--------------------------------------------------------- */
#define MET_FIELDS 6 //Anzahl der verwendeten MetricFields

class SwTableColumnPage : public SfxTabPage
{
    CheckBox        aModifyTableCB;
    CheckBox        aProportionalCB;
    FixedText       aSpaceFT;
    MetricField     aSpaceED;

    ImageButton     aUpBtn;
    FixedText       aFT1;
    PercentField    aMF1;
    FixedText       aFT2;
    PercentField    aMF2;
    FixedText       aFT3;
    PercentField    aMF3;
    FixedText       aFT4;
    PercentField    aMF4;
    FixedText       aFT5;
    PercentField    aMF5;
    FixedText       aFT6;
    PercentField    aMF6;
    ImageButton     aDownBtn;
    FixedLine        aColFL;

    SwTableRep*     pTblData;
    PercentField*   pFieldArr[MET_FIELDS];
    FixedText*      pTextArr[MET_FIELDS];
    SwTwips         nTableWidth;
    SwTwips         nMinWidth;
    USHORT          nNoOfCols;
    USHORT          nNoOfVisibleCols;
    //Breite merken, wenn auf autom. Ausrichtung gestellt wird
    USHORT          aValueTbl[MET_FIELDS];//primaere Zuordnung der MetricFields
    BOOL            bModified:1;
    BOOL            bModifyTbl:1;
    BOOL            bPercentMode:1;

    void        Init(BOOL bWeb);
    DECL_LINK( AutoClickHdl, CheckBox * );
    void        ModifyHdl( PercentField* pEdit );
    DECL_LINK( UpHdl, PercentField * );
    DECL_LINK( DownHdl, PercentField * );
    DECL_LINK( LoseFocusHdl, PercentField * );
    DECL_LINK( ModeHdl, CheckBox * );
    void        UpdateCols( USHORT nAktPos );
    SwTwips     GetVisibleWidth(USHORT nPos);
    void        SetVisibleWidth(USHORT nPos, SwTwips nNewWidth);
public:
    SwTableColumnPage( Window* pParent, const SfxItemSet& rSet );
    ~SwTableColumnPage();

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet = 0 );

};

/*-----------------12.12.96 11.48-------------------
        Textflu
--------------------------------------------------*/
class SwTextFlowPage : public SfxTabPage
{
    FixedLine        aFlowFL;
    CheckBox        aPgBrkCB;
    RadioButton     aPgBrkRB;
    RadioButton     aColBrkRB;
    RadioButton     aPgBrkBeforeRB;
    RadioButton     aPgBrkAfterRB;
    CheckBox        aPageCollCB;
    ListBox         aPageCollLB;
    FixedText       aPageNoFT;
    NumericField    aPageNoNF;
    CheckBox        aSplitCB;
    TriStateBox     aSplitRowCB;
    CheckBox        aKeepCB;
    CheckBox        aHeadLineCB;
    FixedText       aTextDirectionFT;
    ListBox         aTextDirectionLB;

    FixedLine       aVertOrientFL;
    FixedText       aVertOrientFT;
    ListBox         aVertOrientLB;

    SwWrtShell*     pShell;

    BOOL            bPageBreak;
    BOOL            bHtmlMode;

    DECL_LINK( PageBreakHdl_Impl, CheckBox* );
    DECL_LINK( ApplyCollClickHdl_Impl, CheckBox* );
    DECL_LINK( PageBreakPosHdl_Impl, RadioButton* );
    DECL_LINK( PageBreakTypeHdl_Impl, RadioButton* );
    DECL_LINK( SplitHdl_Impl, CheckBox* );
    DECL_LINK( SplitRowHdl_Impl, TriStateBox* );

    SwTextFlowPage( Window* pParent, const SfxItemSet& rSet );
    ~SwTextFlowPage();

public:
    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );

    void                SetShell(SwWrtShell* pSh);

    void                DisablePageBreak();
};

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: uiitems.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2007-11-12 16:33:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef _SVX_ITEMTYPE_HXX
#include <svx/itemtype.hxx>
#endif
#ifndef _UNOSETT_HXX
#include <unosett.hxx>
#endif

#include "swtypes.hxx"
#include "cmdid.h"
#include "pagedesc.hxx"
#include "uiitems.hxx"

#include "utlui.hrc"
#include "attrdesc.hrc"
#ifndef _UNOMID_H
#include <unomid.h>
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

// Breitenangaben der Fussnotenlinien, mit TabPage abstimmen
static const USHORT __FAR_DATA nFtnLines[] = {
    0,
    10,
    50,
    80,
    100,
    150
};

#define FTN_LINE_STYLE_COUNT 5

SwPageFtnInfoItem::SwPageFtnInfoItem( const USHORT nId, SwPageFtnInfo& rInfo) :
    SfxPoolItem( nId ),
    aFtnInfo(rInfo)
{
}

SwPageFtnInfoItem::SwPageFtnInfoItem( const SwPageFtnInfoItem& rItem ) :
    SfxPoolItem( rItem ),
    aFtnInfo(rItem.GetPageFtnInfo())
{
}

 SwPageFtnInfoItem::~SwPageFtnInfoItem()
{
}

SfxPoolItem*  SwPageFtnInfoItem::Clone( SfxItemPool * /*pPool*/ ) const
{
    return new SwPageFtnInfoItem( *this );
}

int  SwPageFtnInfoItem::operator==( const SfxPoolItem& rAttr ) const
{
    DBG_ASSERT( Which() == rAttr.Which(), "keine gleichen Attribute" );
    return ( aFtnInfo == ((SwPageFtnInfoItem&)rAttr).GetPageFtnInfo());
}

SfxItemPresentation  SwPageFtnInfoItem::GetPresentation
(
    SfxItemPresentation ePres,
    SfxMapUnit          eCoreUnit,
    SfxMapUnit          ePresUnit,
    String&             rText,
    const IntlWrapper*    pIntl
)   const
{
    switch ( ePres )
    {
        case SFX_ITEM_PRESENTATION_NONE:
            rText.Erase();
            return SFX_ITEM_PRESENTATION_NONE;
        case SFX_ITEM_PRESENTATION_NAMELESS:
        case SFX_ITEM_PRESENTATION_COMPLETE:
        {
            USHORT nHght = (USHORT) GetPageFtnInfo().GetHeight();
            if ( nHght )
            {
                rText = SW_RESSTR( STR_MAX_FTN_HEIGHT );
                rText += ' ';
                rText += ::GetMetricText( nHght, eCoreUnit, ePresUnit, pIntl );
                rText += ::GetSvxString( ::GetMetricId( ePresUnit ) );
            }
            return ePres;
        }
        default:; //prevent warning
    }
    return SFX_ITEM_PRESENTATION_NONE;
}
/* -----------------------------26.04.01 12:25--------------------------------

 ---------------------------------------------------------------------------*/
BOOL SwPageFtnInfoItem::QueryValue( Any& rVal, BYTE nMemberId ) const
{
    sal_Bool bRet = sal_True;
    switch(nMemberId & ~CONVERT_TWIPS)
    {
        case MID_FTN_HEIGHT        :     rVal <<= (sal_Int32)TWIP_TO_MM100(aFtnInfo.GetHeight());break;
        case MID_LINE_WEIGHT       :     rVal <<= (sal_Int16)TWIP_TO_MM100_UNSIGNED(aFtnInfo.GetLineWidth());break;
        case MID_LINE_COLOR        :     rVal <<= (sal_Int32)aFtnInfo.GetLineColor().GetColor();break;
        case MID_LINE_RELWIDTH     :
        {
            Fraction aTmp( 100, 1 );
            aTmp *= aFtnInfo.GetWidth();
            rVal <<= (sal_Int8)(long)aTmp;
        }
        break;
        case MID_LINE_ADJUST       :     rVal <<= (sal_Int16)aFtnInfo.GetAdj();break;//text::HorizontalAdjust
        case MID_LINE_TEXT_DIST    :     rVal <<= (sal_Int32)TWIP_TO_MM100(aFtnInfo.GetTopDist());break;
        case MID_LINE_FOOTNOTE_DIST:     rVal <<= (sal_Int32)TWIP_TO_MM100(aFtnInfo.GetBottomDist());break;
        default:
            bRet = sal_False;
    }
    return bRet;
}
/* -----------------------------26.04.01 12:26--------------------------------

 ---------------------------------------------------------------------------*/
BOOL SwPageFtnInfoItem::PutValue(const Any& rVal, BYTE nMemberId)
{
    sal_Int32 nSet32 = 0;
    sal_Bool bRet = sal_True;
    switch(nMemberId  & ~CONVERT_TWIPS)
    {
        case MID_LINE_COLOR        :
            rVal >>= nSet32;
            aFtnInfo.SetLineColor(nSet32);
        break;
        case MID_FTN_HEIGHT:
        case MID_LINE_TEXT_DIST    :
        case MID_LINE_FOOTNOTE_DIST:
                rVal >>= nSet32;
                if(nSet32 < 0)
                    bRet = sal_False;
                else
                {
                    nSet32 = MM100_TO_TWIP(nSet32);
                    switch(nMemberId & ~CONVERT_TWIPS)
                    {
                        case MID_FTN_HEIGHT:            aFtnInfo.SetHeight(nSet32);    break;
                        case MID_LINE_TEXT_DIST:        aFtnInfo.SetTopDist(nSet32);break;
                        case MID_LINE_FOOTNOTE_DIST:    aFtnInfo.SetBottomDist(nSet32);break;
                    }
                }
        break;
        case MID_LINE_WEIGHT       :
        {
            sal_Int16 nSet = 0;
            rVal >>= nSet;
            if(nSet >= 0)
                aFtnInfo.SetLineWidth(MM100_TO_TWIP(nSet));
            else
                bRet = sal_False;
        }
        break;
        case MID_LINE_RELWIDTH     :
        {
            sal_Int8 nSet = 0;
            rVal >>= nSet;
            if(nSet < 0)
                bRet = sal_False;
            else
                aFtnInfo.SetWidth(Fraction(nSet, 100));
        }
        break;
        case MID_LINE_ADJUST       :
        {
            sal_Int16 nSet = 0;
            rVal >>= nSet;
            if(nSet >= 0 && nSet < 3) //text::HorizontalAdjust
                aFtnInfo.SetAdj((SwFtnAdj)nSet);
            else
                bRet = sal_False;
        }
        break;
        default:
            bRet = sal_False;
    }
    return bRet;
}

SwPtrItem::SwPtrItem( const USHORT nId, void* pPtr ) :
    SfxPoolItem( nId ),
    pMisc(pPtr)
{
}

/*--------------------------------------------------------------------
    Beschreibung: Copy-Konstruktor
 --------------------------------------------------------------------*/

SwPtrItem::SwPtrItem( const SwPtrItem& rItem ) : SfxPoolItem( rItem )
{
    pMisc = rItem.pMisc;
}

/*--------------------------------------------------------------------
    Beschreibung: Clonen
 --------------------------------------------------------------------*/

SfxPoolItem* SwPtrItem::Clone( SfxItemPool * /*pPool*/ ) const
{
    return new SwPtrItem( *this );
}

/*--------------------------------------------------------------------
    Beschreibung:
 --------------------------------------------------------------------*/

int SwPtrItem::operator==( const SfxPoolItem& rAttr ) const
{
    DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
    const SwPtrItem& rItem = (SwPtrItem&)rAttr;
    return ( pMisc == rItem.pMisc );
}

/*-----------------12.11.97 12:55-------------------------------
 SwUINumRuleItem fuer die NumTabPages der FormatNumRule/Stylisten
---------------------------------------------------------------*/
SwUINumRuleItem::SwUINumRuleItem( const SwNumRule& rRul, const USHORT nId )
    : SfxPoolItem( nId ), pRule( new SwNumRule( rRul ) )
{
}

SwUINumRuleItem::SwUINumRuleItem( const SwUINumRuleItem& rItem )
    : SfxPoolItem( rItem ),
    pRule( new SwNumRule( *rItem.pRule ))
{
}

 SwUINumRuleItem::~SwUINumRuleItem()
{
    delete pRule;
}

SfxPoolItem*  SwUINumRuleItem::Clone( SfxItemPool * /*pPool*/ ) const
{
    return new SwUINumRuleItem( *this );
}

int  SwUINumRuleItem::operator==( const SfxPoolItem& rAttr ) const
{
    DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
    return *pRule == *((SwUINumRuleItem&)rAttr).pRule;
}

BOOL SwUINumRuleItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/ ) const
{
    uno::Reference< container::XIndexReplace >xRules = new SwXNumberingRules(*pRule);
    rVal.setValue(&xRules, ::getCppuType((uno::Reference< container::XIndexReplace>*)0));
    return TRUE;
}
BOOL SwUINumRuleItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/ )
{
    uno::Reference< container::XIndexReplace> xRulesRef;
    if(rVal >>= xRulesRef)
    {
        uno::Reference< lang::XUnoTunnel > xTunnel(xRulesRef, uno::UNO_QUERY);
        SwXNumberingRules* pSwXRules = xTunnel.is() ? reinterpret_cast<SwXNumberingRules*>(
                    xTunnel->getSomething(SwXNumberingRules::getUnoTunnelId())) : 0;
        if(pSwXRules)
        {
            *pRule = *pSwXRules->GetNumRule();
        }
    }
    return TRUE;
}
/* -----------------17.06.98 17:43-------------------
 *
 * --------------------------------------------------*/
SwBackgroundDestinationItem::SwBackgroundDestinationItem(USHORT  _nWhich, USHORT nValue) :
    SfxUInt16Item(_nWhich, nValue)
{
}
/* -----------------17.06.98 17:44-------------------
 *
 * --------------------------------------------------*/
SfxPoolItem*     SwBackgroundDestinationItem::Clone( SfxItemPool * /*pPool*/ ) const
{
    return new SwBackgroundDestinationItem(Which(), GetValue());
}

<commit_msg>INTEGRATION: CWS swnewlistlevelattrs_DEV300 (1.12.84); FILE MERGED 2008/01/31 12:26:24 od 1.12.84.1: #i85348# refactoring: adjust includes<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: uiitems.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-05 17:29:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef _SVX_ITEMTYPE_HXX
#include <svx/itemtype.hxx>
#endif
#ifndef _UNOSETT_HXX
#include <unosett.hxx>
#endif

#include "swtypes.hxx"
#include "cmdid.h"
#include "uiitems.hxx"

#include "utlui.hrc"
#include "attrdesc.hrc"
#ifndef _UNOMID_H
#include <unomid.h>
#endif
#ifndef _NUMRULE_HXX
#include <numrule.hxx>
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

// Breitenangaben der Fussnotenlinien, mit TabPage abstimmen
static const USHORT __FAR_DATA nFtnLines[] = {
    0,
    10,
    50,
    80,
    100,
    150
};

#define FTN_LINE_STYLE_COUNT 5

SwPageFtnInfoItem::SwPageFtnInfoItem( const USHORT nId, SwPageFtnInfo& rInfo) :
    SfxPoolItem( nId ),
    aFtnInfo(rInfo)
{
}

SwPageFtnInfoItem::SwPageFtnInfoItem( const SwPageFtnInfoItem& rItem ) :
    SfxPoolItem( rItem ),
    aFtnInfo(rItem.GetPageFtnInfo())
{
}

 SwPageFtnInfoItem::~SwPageFtnInfoItem()
{
}

SfxPoolItem*  SwPageFtnInfoItem::Clone( SfxItemPool * /*pPool*/ ) const
{
    return new SwPageFtnInfoItem( *this );
}

int  SwPageFtnInfoItem::operator==( const SfxPoolItem& rAttr ) const
{
    DBG_ASSERT( Which() == rAttr.Which(), "keine gleichen Attribute" );
    return ( aFtnInfo == ((SwPageFtnInfoItem&)rAttr).GetPageFtnInfo());
}

SfxItemPresentation  SwPageFtnInfoItem::GetPresentation
(
    SfxItemPresentation ePres,
    SfxMapUnit          eCoreUnit,
    SfxMapUnit          ePresUnit,
    String&             rText,
    const IntlWrapper*    pIntl
)   const
{
    switch ( ePres )
    {
        case SFX_ITEM_PRESENTATION_NONE:
            rText.Erase();
            return SFX_ITEM_PRESENTATION_NONE;
        case SFX_ITEM_PRESENTATION_NAMELESS:
        case SFX_ITEM_PRESENTATION_COMPLETE:
        {
            USHORT nHght = (USHORT) GetPageFtnInfo().GetHeight();
            if ( nHght )
            {
                rText = SW_RESSTR( STR_MAX_FTN_HEIGHT );
                rText += ' ';
                rText += ::GetMetricText( nHght, eCoreUnit, ePresUnit, pIntl );
                rText += ::GetSvxString( ::GetMetricId( ePresUnit ) );
            }
            return ePres;
        }
        default:; //prevent warning
    }
    return SFX_ITEM_PRESENTATION_NONE;
}
/* -----------------------------26.04.01 12:25--------------------------------

 ---------------------------------------------------------------------------*/
BOOL SwPageFtnInfoItem::QueryValue( Any& rVal, BYTE nMemberId ) const
{
    sal_Bool bRet = sal_True;
    switch(nMemberId & ~CONVERT_TWIPS)
    {
        case MID_FTN_HEIGHT        :     rVal <<= (sal_Int32)TWIP_TO_MM100(aFtnInfo.GetHeight());break;
        case MID_LINE_WEIGHT       :     rVal <<= (sal_Int16)TWIP_TO_MM100_UNSIGNED(aFtnInfo.GetLineWidth());break;
        case MID_LINE_COLOR        :     rVal <<= (sal_Int32)aFtnInfo.GetLineColor().GetColor();break;
        case MID_LINE_RELWIDTH     :
        {
            Fraction aTmp( 100, 1 );
            aTmp *= aFtnInfo.GetWidth();
            rVal <<= (sal_Int8)(long)aTmp;
        }
        break;
        case MID_LINE_ADJUST       :     rVal <<= (sal_Int16)aFtnInfo.GetAdj();break;//text::HorizontalAdjust
        case MID_LINE_TEXT_DIST    :     rVal <<= (sal_Int32)TWIP_TO_MM100(aFtnInfo.GetTopDist());break;
        case MID_LINE_FOOTNOTE_DIST:     rVal <<= (sal_Int32)TWIP_TO_MM100(aFtnInfo.GetBottomDist());break;
        default:
            bRet = sal_False;
    }
    return bRet;
}
/* -----------------------------26.04.01 12:26--------------------------------

 ---------------------------------------------------------------------------*/
BOOL SwPageFtnInfoItem::PutValue(const Any& rVal, BYTE nMemberId)
{
    sal_Int32 nSet32 = 0;
    sal_Bool bRet = sal_True;
    switch(nMemberId  & ~CONVERT_TWIPS)
    {
        case MID_LINE_COLOR        :
            rVal >>= nSet32;
            aFtnInfo.SetLineColor(nSet32);
        break;
        case MID_FTN_HEIGHT:
        case MID_LINE_TEXT_DIST    :
        case MID_LINE_FOOTNOTE_DIST:
                rVal >>= nSet32;
                if(nSet32 < 0)
                    bRet = sal_False;
                else
                {
                    nSet32 = MM100_TO_TWIP(nSet32);
                    switch(nMemberId & ~CONVERT_TWIPS)
                    {
                        case MID_FTN_HEIGHT:            aFtnInfo.SetHeight(nSet32);    break;
                        case MID_LINE_TEXT_DIST:        aFtnInfo.SetTopDist(nSet32);break;
                        case MID_LINE_FOOTNOTE_DIST:    aFtnInfo.SetBottomDist(nSet32);break;
                    }
                }
        break;
        case MID_LINE_WEIGHT       :
        {
            sal_Int16 nSet = 0;
            rVal >>= nSet;
            if(nSet >= 0)
                aFtnInfo.SetLineWidth(MM100_TO_TWIP(nSet));
            else
                bRet = sal_False;
        }
        break;
        case MID_LINE_RELWIDTH     :
        {
            sal_Int8 nSet = 0;
            rVal >>= nSet;
            if(nSet < 0)
                bRet = sal_False;
            else
                aFtnInfo.SetWidth(Fraction(nSet, 100));
        }
        break;
        case MID_LINE_ADJUST       :
        {
            sal_Int16 nSet = 0;
            rVal >>= nSet;
            if(nSet >= 0 && nSet < 3) //text::HorizontalAdjust
                aFtnInfo.SetAdj((SwFtnAdj)nSet);
            else
                bRet = sal_False;
        }
        break;
        default:
            bRet = sal_False;
    }
    return bRet;
}

SwPtrItem::SwPtrItem( const USHORT nId, void* pPtr ) :
    SfxPoolItem( nId ),
    pMisc(pPtr)
{
}

/*--------------------------------------------------------------------
    Beschreibung: Copy-Konstruktor
 --------------------------------------------------------------------*/

SwPtrItem::SwPtrItem( const SwPtrItem& rItem ) : SfxPoolItem( rItem )
{
    pMisc = rItem.pMisc;
}

/*--------------------------------------------------------------------
    Beschreibung: Clonen
 --------------------------------------------------------------------*/

SfxPoolItem* SwPtrItem::Clone( SfxItemPool * /*pPool*/ ) const
{
    return new SwPtrItem( *this );
}

/*--------------------------------------------------------------------
    Beschreibung:
 --------------------------------------------------------------------*/

int SwPtrItem::operator==( const SfxPoolItem& rAttr ) const
{
    DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
    const SwPtrItem& rItem = (SwPtrItem&)rAttr;
    return ( pMisc == rItem.pMisc );
}

/*-----------------12.11.97 12:55-------------------------------
 SwUINumRuleItem fuer die NumTabPages der FormatNumRule/Stylisten
---------------------------------------------------------------*/
SwUINumRuleItem::SwUINumRuleItem( const SwNumRule& rRul, const USHORT nId )
    : SfxPoolItem( nId ), pRule( new SwNumRule( rRul ) )
{
}

SwUINumRuleItem::SwUINumRuleItem( const SwUINumRuleItem& rItem )
    : SfxPoolItem( rItem ),
    pRule( new SwNumRule( *rItem.pRule ))
{
}

 SwUINumRuleItem::~SwUINumRuleItem()
{
    delete pRule;
}

SfxPoolItem*  SwUINumRuleItem::Clone( SfxItemPool * /*pPool*/ ) const
{
    return new SwUINumRuleItem( *this );
}

int  SwUINumRuleItem::operator==( const SfxPoolItem& rAttr ) const
{
    DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
    return *pRule == *((SwUINumRuleItem&)rAttr).pRule;
}

BOOL SwUINumRuleItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/ ) const
{
    uno::Reference< container::XIndexReplace >xRules = new SwXNumberingRules(*pRule);
    rVal.setValue(&xRules, ::getCppuType((uno::Reference< container::XIndexReplace>*)0));
    return TRUE;
}
BOOL SwUINumRuleItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/ )
{
    uno::Reference< container::XIndexReplace> xRulesRef;
    if(rVal >>= xRulesRef)
    {
        uno::Reference< lang::XUnoTunnel > xTunnel(xRulesRef, uno::UNO_QUERY);
        SwXNumberingRules* pSwXRules = xTunnel.is() ? reinterpret_cast<SwXNumberingRules*>(
                    xTunnel->getSomething(SwXNumberingRules::getUnoTunnelId())) : 0;
        if(pSwXRules)
        {
            *pRule = *pSwXRules->GetNumRule();
        }
    }
    return TRUE;
}
/* -----------------17.06.98 17:43-------------------
 *
 * --------------------------------------------------*/
SwBackgroundDestinationItem::SwBackgroundDestinationItem(USHORT  _nWhich, USHORT nValue) :
    SfxUInt16Item(_nWhich, nValue)
{
}
/* -----------------17.06.98 17:44-------------------
 *
 * --------------------------------------------------*/
SfxPoolItem*     SwBackgroundDestinationItem::Clone( SfxItemPool * /*pPool*/ ) const
{
    return new SwBackgroundDestinationItem(Which(), GetValue());
}

<|endoftext|>


<commit_before>// Copyright 2010 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <stddef.h>
#include <vector>

#include "util/test.h"
#include "util/logging.h"
#include "re2/re2.h"
#include "re2/set.h"

namespace re2 {

TEST(Set, Unanchored) {
  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);

  CHECK_EQ(s.Add("foo", NULL), 0);
  CHECK_EQ(s.Add("(", NULL), -1);
  CHECK_EQ(s.Add("bar", NULL), 1);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("foobar", NULL), true);
  CHECK_EQ(s.Match("fooba", NULL), true);
  CHECK_EQ(s.Match("oobar", NULL), true);

  std::vector<int> v;
  CHECK_EQ(s.Match("foobar", &v), true);
  CHECK_EQ(v.size(), 2);
  CHECK_EQ(v[0], 0);
  CHECK_EQ(v[1], 1);

  CHECK_EQ(s.Match("fooba", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("oobar", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 1);
}

TEST(Set, UnanchoredFactored) {
  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);

  CHECK_EQ(s.Add("foo", NULL), 0);
  CHECK_EQ(s.Add("(", NULL), -1);
  CHECK_EQ(s.Add("foobar", NULL), 1);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("foobar", NULL), true);
  CHECK_EQ(s.Match("obarfoobaroo", NULL), true);
  CHECK_EQ(s.Match("fooba", NULL), true);
  CHECK_EQ(s.Match("oobar", NULL), false);

  std::vector<int> v;
  CHECK_EQ(s.Match("foobar", &v), true);
  CHECK_EQ(v.size(), 2);
  CHECK_EQ(v[0], 0);
  CHECK_EQ(v[1], 1);

  CHECK_EQ(s.Match("obarfoobaroo", &v), true);
  CHECK_EQ(v.size(), 2);
  CHECK_EQ(v[0], 0);
  CHECK_EQ(v[1], 1);

  CHECK_EQ(s.Match("fooba", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("oobar", &v), false);
  CHECK_EQ(v.size(), 0);
}

TEST(Set, UnanchoredDollar) {
  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);

  CHECK_EQ(s.Add("foo$", NULL), 0);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("foo", NULL), true);

  std::vector<int> v;
  CHECK_EQ(s.Match("foo", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);
}

TEST(Set, Anchored) {
  RE2::Set s(RE2::DefaultOptions, RE2::ANCHOR_BOTH);

  CHECK_EQ(s.Add("foo", NULL), 0);
  CHECK_EQ(s.Add("(", NULL), -1);
  CHECK_EQ(s.Add("bar", NULL), 1);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("foobar", NULL), false);
  CHECK_EQ(s.Match("fooba", NULL), false);
  CHECK_EQ(s.Match("oobar", NULL), false);
  CHECK_EQ(s.Match("foo", NULL), true);
  CHECK_EQ(s.Match("bar", NULL), true);

  std::vector<int> v;
  CHECK_EQ(s.Match("foobar", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("fooba", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("oobar", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("foo", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("bar", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 1);
}

TEST(Set, EmptyUnanchored) {
  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);

  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("", NULL), false);
  CHECK_EQ(s.Match("foobar", NULL), false);

  std::vector<int> v;
  CHECK_EQ(s.Match("", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("foobar", &v), false);
  CHECK_EQ(v.size(), 0);
}

TEST(Set, EmptyAnchored) {
  RE2::Set s(RE2::DefaultOptions, RE2::ANCHOR_BOTH);

  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("", NULL), false);
  CHECK_EQ(s.Match("foobar", NULL), false);

  std::vector<int> v;
  CHECK_EQ(s.Match("", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("foobar", &v), false);
  CHECK_EQ(v.size(), 0);
}

TEST(Set, Prefix) {
  RE2::Set s(RE2::DefaultOptions, RE2::ANCHOR_BOTH);

  CHECK_EQ(s.Add("/prefix/\\d*", NULL), 0);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("/prefix", NULL), false);
  CHECK_EQ(s.Match("/prefix/", NULL), true);
  CHECK_EQ(s.Match("/prefix/42", NULL), true);

  std::vector<int> v;
  CHECK_EQ(s.Match("/prefix", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("/prefix/", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("/prefix/42", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);
}

}  // namespace re2
<commit_msg>Add another RE2::Set test case.<commit_after>// Copyright 2010 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <stddef.h>
#include <vector>

#include "util/test.h"
#include "util/logging.h"
#include "re2/re2.h"
#include "re2/set.h"

namespace re2 {

TEST(Set, Unanchored) {
  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);

  CHECK_EQ(s.Add("foo", NULL), 0);
  CHECK_EQ(s.Add("(", NULL), -1);
  CHECK_EQ(s.Add("bar", NULL), 1);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("foobar", NULL), true);
  CHECK_EQ(s.Match("fooba", NULL), true);
  CHECK_EQ(s.Match("oobar", NULL), true);

  std::vector<int> v;
  CHECK_EQ(s.Match("foobar", &v), true);
  CHECK_EQ(v.size(), 2);
  CHECK_EQ(v[0], 0);
  CHECK_EQ(v[1], 1);

  CHECK_EQ(s.Match("fooba", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("oobar", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 1);
}

TEST(Set, UnanchoredFactored) {
  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);

  CHECK_EQ(s.Add("foo", NULL), 0);
  CHECK_EQ(s.Add("(", NULL), -1);
  CHECK_EQ(s.Add("foobar", NULL), 1);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("foobar", NULL), true);
  CHECK_EQ(s.Match("obarfoobaroo", NULL), true);
  CHECK_EQ(s.Match("fooba", NULL), true);
  CHECK_EQ(s.Match("oobar", NULL), false);

  std::vector<int> v;
  CHECK_EQ(s.Match("foobar", &v), true);
  CHECK_EQ(v.size(), 2);
  CHECK_EQ(v[0], 0);
  CHECK_EQ(v[1], 1);

  CHECK_EQ(s.Match("obarfoobaroo", &v), true);
  CHECK_EQ(v.size(), 2);
  CHECK_EQ(v[0], 0);
  CHECK_EQ(v[1], 1);

  CHECK_EQ(s.Match("fooba", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("oobar", &v), false);
  CHECK_EQ(v.size(), 0);
}

TEST(Set, UnanchoredDollar) {
  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);

  CHECK_EQ(s.Add("foo$", NULL), 0);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("foo", NULL), true);
  CHECK_EQ(s.Match("foobar", NULL), false);

  std::vector<int> v;
  CHECK_EQ(s.Match("foo", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("foobar", &v), false);
  CHECK_EQ(v.size(), 0);
}

TEST(Set, UnanchoredWordBoundary) {
  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);

  CHECK_EQ(s.Add("foo\\b", NULL), 0);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("foo", NULL), true);
  CHECK_EQ(s.Match("foobar", NULL), false);
  CHECK_EQ(s.Match("foo bar", NULL), true);

  std::vector<int> v;
  CHECK_EQ(s.Match("foo", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("foobar", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("foo bar", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);
}

TEST(Set, Anchored) {
  RE2::Set s(RE2::DefaultOptions, RE2::ANCHOR_BOTH);

  CHECK_EQ(s.Add("foo", NULL), 0);
  CHECK_EQ(s.Add("(", NULL), -1);
  CHECK_EQ(s.Add("bar", NULL), 1);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("foobar", NULL), false);
  CHECK_EQ(s.Match("fooba", NULL), false);
  CHECK_EQ(s.Match("oobar", NULL), false);
  CHECK_EQ(s.Match("foo", NULL), true);
  CHECK_EQ(s.Match("bar", NULL), true);

  std::vector<int> v;
  CHECK_EQ(s.Match("foobar", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("fooba", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("oobar", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("foo", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("bar", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 1);
}

TEST(Set, EmptyUnanchored) {
  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);

  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("", NULL), false);
  CHECK_EQ(s.Match("foobar", NULL), false);

  std::vector<int> v;
  CHECK_EQ(s.Match("", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("foobar", &v), false);
  CHECK_EQ(v.size(), 0);
}

TEST(Set, EmptyAnchored) {
  RE2::Set s(RE2::DefaultOptions, RE2::ANCHOR_BOTH);

  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("", NULL), false);
  CHECK_EQ(s.Match("foobar", NULL), false);

  std::vector<int> v;
  CHECK_EQ(s.Match("", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("foobar", &v), false);
  CHECK_EQ(v.size(), 0);
}

TEST(Set, Prefix) {
  RE2::Set s(RE2::DefaultOptions, RE2::ANCHOR_BOTH);

  CHECK_EQ(s.Add("/prefix/\\d*", NULL), 0);
  CHECK_EQ(s.Compile(), true);

  CHECK_EQ(s.Match("/prefix", NULL), false);
  CHECK_EQ(s.Match("/prefix/", NULL), true);
  CHECK_EQ(s.Match("/prefix/42", NULL), true);

  std::vector<int> v;
  CHECK_EQ(s.Match("/prefix", &v), false);
  CHECK_EQ(v.size(), 0);

  CHECK_EQ(s.Match("/prefix/", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);

  CHECK_EQ(s.Match("/prefix/42", &v), true);
  CHECK_EQ(v.size(), 1);
  CHECK_EQ(v[0], 0);
}

}  // namespace re2
<|endoftext|>


<commit_before>//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

//
// bench.cpp : spdlog benchmarks
//
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/spdlog.h"
#include "utils.h"
#include <atomic>
#include <cstdlib> // EXIT_FAILURE
#include <iostream>
#include <memory>
#include <string>
#include <thread>

using namespace std;
using namespace std::chrono;
using namespace spdlog;
using namespace spdlog::sinks;
using namespace utils;

void bench(int howmany, std::shared_ptr<spdlog::logger> log);
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);

int main(int argc, char *argv[])
{

    int queue_size = 1000000;
    int howmany = 1000000;
    int threads = 10;
    int file_size = 30 * 1024 * 1024;
    int rotating_files = 5;

    try
    {

        if (argc > 1)
            howmany = atoi(argv[1]);
        if (argc > 2)
            threads = atoi(argv[2]);
        if (argc > 3)
            queue_size = atoi(argv[3]);

        cout << "*******************************************************************************\n";
        cout << "Single thread, " << format(howmany) << " iterations" << endl;
        cout << "*******************************************************************************\n";

        auto basic_st = spdlog::basic_logger_mt("basic_st", "logs/basic_st.log", true);
        bench(howmany, basic_st);

        auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files);
        bench(howmany, rotating_st);

        auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log");
        bench(howmany, daily_st);

        bench(howmany, spdlog::create<null_sink_st>("null_st"));

        cout << "\n*******************************************************************************\n";
        cout << threads << " threads sharing same logger, " << format(howmany) << " iterations" << endl;
        cout << "*******************************************************************************\n";

        auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true);
        bench_mt(howmany, basic_mt, threads);

        auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files);
        bench_mt(howmany, rotating_mt, threads);

        auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log");
        bench_mt(howmany, daily_mt, threads);
        bench(howmany, spdlog::create<null_sink_st>("null_mt"));

        cout << "\n*******************************************************************************\n";
        cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " iterations " << endl;
        cout << "*******************************************************************************\n";

        for (int i = 0; i < 3; ++i)
        {
            spdlog::init_thread_pool(queue_size, 1);
            auto as = spdlog::basic_logger_mt<spdlog::async_factory>("as", "logs/basic_async.log", true);
            bench_mt(howmany, as, threads);
            spdlog::drop("as");
        }
    }
    catch (std::exception &ex)
    {
        std::cerr << "Error: " << ex.what() << std::endl;
        perror("Last error");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

void bench(int howmany, std::shared_ptr<spdlog::logger> log)
{
    using std::chrono::high_resolution_clock;
    cout << log->name() << "...\t\t" << flush;
    auto start = high_resolution_clock::now();
    for (auto i = 0; i < howmany; ++i)
    {
        log->info("Hello logger: msg number {}", i);
    }

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();
    cout << "Elapsed: " << delta_d << "\t" << format(int(howmany / delta_d)) << "/sec" << endl;
}

void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
{
    using std::chrono::high_resolution_clock;
    cout << log->name() << "...\t\t" << flush;
    vector<thread> threads;
    auto start = high_resolution_clock::now();
    for (int t = 0; t < thread_count; ++t)
    {
        threads.push_back(std::thread([&]() {
            for (int j = 0; j < howmany / thread_count; j++)
            {
                log->info("Hello logger: msg number {}", j);
            }
        }));
    }

    for (auto &t : threads)
    {
        t.join();
    };

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();
    cout << "Elapsed: " << delta_d << "\t" << format(int(howmany / delta_d)) << "/sec" << endl;
}
<commit_msg>Updated bench.cpp<commit_after>//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

//
// bench.cpp : spdlog benchmarks
//
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/spdlog.h"
#include "utils.h"
#include <atomic>
#include <cstdlib> // EXIT_FAILURE
#include <iostream>
#include <memory>
#include <string>
#include <thread>

using namespace std;
using namespace std::chrono;
using namespace spdlog;
using namespace spdlog::sinks;
using namespace utils;

void bench(int howmany, std::shared_ptr<spdlog::logger> log);
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);

int main(int argc, char *argv[])
{

    int queue_size = 1000000;
    int howmany = 1000000;
    int threads = 10;
    int file_size = 30 * 1024 * 1024;
    int rotating_files = 5;

    try
    {

        if (argc > 1)
            howmany = atoi(argv[1]);
        if (argc > 2)
            threads = atoi(argv[2]);
        if (argc > 3)
            queue_size = atoi(argv[3]);

        cout << "*******************************************************************************\n";
        cout << "Single thread, " << format(howmany) << " iterations" << endl;
        cout << "*******************************************************************************\n";

        auto basic_st = spdlog::basic_logger_mt("basic_st", "logs/basic_st.log", true);
        bench(howmany, basic_st);

        auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files);
        bench(howmany, rotating_st);

        auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log");
        bench(howmany, daily_st);

        bench(howmany, spdlog::create<null_sink_st>("null_st"));

        cout << "\n*******************************************************************************\n";
        cout << threads << " threads sharing same logger, " << format(howmany) << " iterations" << endl;
        cout << "*******************************************************************************\n";

        auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true);
        bench_mt(howmany, basic_mt, threads);

        auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files);
        bench_mt(howmany, rotating_mt, threads);

        auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log");
        bench_mt(howmany, daily_mt, threads);
        bench(howmany, spdlog::create<null_sink_st>("null_mt"));

        cout << "\n*******************************************************************************\n";
        cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " iterations " << endl;
        cout << "*******************************************************************************\n";

        for (int i = 0; i < 3; ++i)
        {
            spdlog::init_thread_pool(queue_size, 1);
            auto as = spdlog::basic_logger_mt<spdlog::async_factory>("async", "logs/basic_async.log", true);
            bench_mt(howmany, as, threads);
            spdlog::drop("async");
        }
    }
    catch (std::exception &ex)
    {
        std::cerr << "Error: " << ex.what() << std::endl;
        perror("Last error");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

void bench(int howmany, std::shared_ptr<spdlog::logger> log)
{
    using std::chrono::high_resolution_clock;
    cout << log->name() << "...\t\t" << flush;
    auto start = high_resolution_clock::now();
    for (auto i = 0; i < howmany; ++i)
    {
        log->info("Hello logger: msg number {}", i);
    }

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();
    cout << "Elapsed: " << delta_d << "\t" << format(int(howmany / delta_d)) << "/sec" << endl;
}

void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
{
    using std::chrono::high_resolution_clock;
    cout << log->name() << "...\t\t" << flush;
    vector<thread> threads;
    auto start = high_resolution_clock::now();
    for (int t = 0; t < thread_count; ++t)
    {
        threads.push_back(std::thread([&]() {
            for (int j = 0; j < howmany / thread_count; j++)
            {
                log->info("Hello logger: msg number {}", j);
            }
        }));
    }

    for (auto &t : threads)
    {
        t.join();
    };

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();
    cout << "Elapsed: " << delta_d << "\t" << format(int(howmany / delta_d)) << "/sec" << endl;
}
<|endoftext|>


<commit_before>#if !(defined MPL_CART_COMM_HPP)

#define MPL_CART_COMM_HPP

#include <mpi.h>
#include <algorithm>
#include <vector>
#include <tuple>

namespace mpl {

  struct shift_ranks {
    int source, dest;
  };

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

  class cart_communicator : public communicator {
  public:
    class sizes {
      std::vector<int> dims_, periodic_;
    public:
      typedef std::vector<int>::size_type size_type;
      sizes(std::initializer_list<std::pair<int, bool>> list) {
	for (const std::pair<int, bool> &i : list)
	  add(i.first, i.second);
      }
      void add(int dim, bool p) {
	dims_.push_back(dim);
	periodic_.push_back(p);
      }
      int dims(size_type i) const {
	return dims_[i];
      }
      bool periodic(size_type i) const {
	return periodic_[i];
      }
      friend class cart_communicator;
      friend sizes dims_create(int, sizes);
    };
    cart_communicator() : communicator() {
    }
    cart_communicator(const communicator &old_comm,
		      const sizes &par,
		      bool reorder=true) {
      MPI_Cart_create(old_comm.comm, par.dims_.size(), par.dims_.data(), par.periodic_.data(), reorder, &comm);
    }
    cart_communicator(const cart_communicator &old_comm,
		      const std::vector<int> &remain_dims) {
      MPI_Cart_sub(old_comm.comm, remain_dims.data(), &comm);
    }
    cart_communicator(cart_communicator &&other) {
      comm=other.comm;
      other.comm=MPI_COMM_SELF;
    }
    void operator=(const cart_communicator &)=delete;
    cart_communicator & operator=(cart_communicator &&other) {
      if (this!=&other) {
        int result1, result2;
        MPI_Comm_compare(comm, MPI_COMM_WORLD, &result1);
        MPI_Comm_compare(comm, MPI_COMM_SELF, &result2);
        if (result1!=MPI_IDENT and result2!=MPI_IDENT)
          MPI_Comm_free(&comm);
        comm=other.comm;
        other.comm=MPI_COMM_SELF;
      }
      return *this;
    }
    int dim() const {
      int ndims;
      MPI_Cartdim_get(comm, &ndims);
      return ndims;
    }
    using communicator::rank;
    int rank(const std::vector<int> &coords) const {
      int rank_;
      MPI_Cart_rank(comm, coords.data(), &rank_);
      return rank_;
    }
    std::vector<int> coords(int rank) const {
      std::vector<int> coords_(dim());
      MPI_Cart_coords(comm, rank, coords_.size(), coords_.data());
      return coords_;
    }
    std::vector<int> coords() const {
      int ndims(dim());
      std::vector<int> dims_(ndims), periodic_(ndims), coords_(ndims);
      MPI_Cart_get(comm, ndims, dims_.data(), periodic_.data(), coords_.data());
      return coords_;
    }
    std::vector<int> dims() const {
      int ndims(dim());
      std::vector<int> dims_(ndims), periodic_(ndims), coords_(ndims);
      MPI_Cart_get(comm, ndims, dims_.data(), periodic_.data(), coords_.data());
      return dims_;
    }
    std::vector<int> periodic() const {
      int ndims(dim());
      std::vector<int> dims_(ndims), periodic_(ndims), coords_(ndims);
      MPI_Cart_get(comm, ndims, dims_.data(), periodic_.data(), coords_.data());
      return periodic_;
    }
    shift_ranks shift(int direction, int disp) const {
      int rank_source, rank_dest;
      MPI_Cart_shift(comm, direction, disp, &rank_source, &rank_dest);
      return {rank_source, rank_dest};
    }
    // === neighbour collective ========================================
    // === neighbour allgather ===
    // === get a signle value from each neighbour and store in contiguous memory
    // --- blocking neighbour allgather ---
    template<typename T>
    void neighbour_allgather(const T &senddata, T *recvdata) const {
      MPI_Neighbor_allgather(*senddata, 1, datatype_traits<T>::get_datatype(),
			     recvdata, 1, datatype_traits<T>::get_datatype(),
			     comm);
    }
    template<typename T>
    void neighbour_allgather(const T *senddata, const layout<T> &sendl,
			     T *recvdata, const layout<T> &recvl) const {
      MPI_Neighbour_allgather(senddata, 1, datatype_traits<layout<T>>::get_datatype(sendl),
			      recvdata, 1, datatype_traits<layout<T>>::get_datatype(recvl),
			      comm);
    }
    // --- nonblocking neighbour allgather ---
    template<typename T>
    detail::irequest ineighbour_allgather(const T &senddata, T *recvdata) const {
      MPI_Request req;
      MPI_Ineighbour_allgather(&senddata, 1, datatype_traits<T>::get_datatype(),
			       recvdata, 1, datatype_traits<T>::get_datatype(),
			       comm, &req);
      return detail::irequest(req);
    }
    template<typename T>
    detail::irequest ineighbour_allgather(const T *senddata, const layout<T> &sendl,
					  T *recvdata, const layout<T> &recvl) const {
      MPI_Request req;
      MPI_Ineighbour_allgather(senddata, 1, datatype_traits<layout<T>>::get_datatype(sendl),
			       recvdata, 1, datatype_traits<layout<T>>::get_datatype(recvl),
			       comm, &req);
      return detail::irequest(req);
    }
    // === get varying amount of data from each neighbour and stores in noncontiguous memory
    // --- blocking neighbour allgather ---
    template<typename T>
    void neighbour_allgatherv(const T *senddata, const layout<T> &sendl,
			      T *recvdata, const layouts<T> &recvls, const displacements &recvdispls) const {
      int N(recvdispls.size());
      displacements senddispls(N);
      layouts<T> sendls(N, sendl);
      alltoallv(senddata, sendls, senddispls,
                recvdata, recvls, recvdispls);
    }
    // --- nonblocking neighbour allgather ---
    template<typename T>
    detail::irequest ineighbour_allgatherv(const T *senddata, const layout<T> &sendl,
					   T *recvdata, const layouts<T> &recvls, const displacements &recvdispls) const {
      int N(recvdispls.size());
      displacements senddispls(N);
      layouts<T> sendls(N, sendl);
      return ialltoallv(senddata, sendls, senddispls,
			recvdata, recvls, recvdispls);
    }
    // === neighbour all-to-all ===
    // === each rank sends a signle value to each neighbour
    // --- blocking neighbour all-to-all ---
    template<typename T>
    void neighbour_alltoall(const T *senddata, T *recvdata) const {
      MPI_Neighbour_alltoall(senddata, 1, datatype_traits<T>::get_datatype(),
			     recvdata, 1, datatype_traits<T>::get_datatype(),
			     comm);
    }
    template<typename T>
    void neighbour_alltoall(const T *senddata, const layout<T> &sendl,
			    T *recvdata, const layout<T> &recvl) const {
      MPI_Neighbour_alltoall(senddata, 1, datatype_traits<T>::get_datatype(),
			     recvdata, 1, datatype_traits<T>::get_datatype(),
			     comm);
    }
    // --- nonblocking neighbour all-to-all ---
    template<typename T>
    detail::irequest ineighbour_alltoall(const T *senddata, T *recvdata) const {
      MPI_Request req;
      MPI_Ineighbour_alltoall(senddata, 1, datatype_traits<T>::get_datatype(),
			      recvdata, 1, datatype_traits<T>::get_datatype(),
			      comm, &req);
      return detail::irequest(req);
    }
    template<typename T>
    detail::irequest ineighbour_alltoall(const T *senddata, const layout<T> &sendl,
					 T *recvdata, const layout<T> &recvl) const {
      MPI_Request req;
      MPI_Ineighbour_alltoall(senddata, 1, datatype_traits<T>::get_datatype(),
			      recvdata, 1, datatype_traits<T>::get_datatype(),
			      comm, &req);
      return detail::irequest(req);
    }
    // === each rank sends a varying number of values to each neighbor with possibly different layouts
    // --- blocking neighbour all-to-all ---
    template<typename T>
    void neighbour_alltoallv(const T *senddata, const layouts<T> &sendl, const displacements &senddispls,
			     T *recvdata, const layouts<T> &recvl, const displacements &recvdispls) const {
      std::vector<int> counts(recvl.size(), 1);
      MPI_Neighbour_alltoallw(senddata, counts.data(), senddispls(), reinterpret_cast<const MPI_Datatype *>(sendl()),
			      recvdata, counts.data(), recvdispls(), reinterpret_cast<const MPI_Datatype *>(recvl()),
			      comm);
    }
    // --- non-blocking neighbour all-to-all ---
    template<typename T>
    detail::irequest ineighbour_alltoallv(const T *senddata, const layouts<T> &sendl, const displacements &senddispls,
					  T *recvdata, const layouts<T> &recvl, const displacements &recvdispls) const {
      std::vector<int> counts(recvl.size(), 1);
      MPI_Request req;
      MPI_Ineighbour_alltoallw(senddata, counts.data(), senddispls(), reinterpret_cast<const MPI_Datatype *>(sendl()),
			       recvdata, counts.data(), recvdispls(), reinterpret_cast<const MPI_Datatype *>(recvl()),
			       comm, &req);
      return detail::irequest(req);
    }
  };

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

  inline cart_communicator::sizes dims_create(int size, cart_communicator::sizes par) {
    if (MPI_Dims_create(size, par.dims_.size(), par.dims_.data())!=MPI_SUCCESS)
      throw invalid_dim();
    return par;
  }

}

#endif
<commit_msg>replace detail::irequest by irequest<commit_after>#if !(defined MPL_CART_COMM_HPP)

#define MPL_CART_COMM_HPP

#include <mpi.h>
#include <algorithm>
#include <vector>
#include <tuple>

namespace mpl {

  struct shift_ranks {
    int source, dest;
  };

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

  class cart_communicator : public communicator {
  public:
    class sizes {
      std::vector<int> dims_, periodic_;
    public:
      typedef std::vector<int>::size_type size_type;
      sizes(std::initializer_list<std::pair<int, bool>> list) {
	for (const std::pair<int, bool> &i : list)
	  add(i.first, i.second);
      }
      void add(int dim, bool p) {
	dims_.push_back(dim);
	periodic_.push_back(p);
      }
      int dims(size_type i) const {
	return dims_[i];
      }
      bool periodic(size_type i) const {
	return periodic_[i];
      }
      friend class cart_communicator;
      friend sizes dims_create(int, sizes);
    };
    cart_communicator()=default;
    cart_communicator(const communicator &old_comm,
		      const sizes &par,
		      bool reorder=true) {
      MPI_Cart_create(old_comm.comm, par.dims_.size(), par.dims_.data(), par.periodic_.data(), reorder, &comm);
    }
    cart_communicator(const cart_communicator &old_comm,
		      const std::vector<int> &remain_dims) {
      MPI_Cart_sub(old_comm.comm, remain_dims.data(), &comm);
    }
    cart_communicator(cart_communicator &&other) noexcept {
      comm=other.comm;
      other.comm=MPI_COMM_SELF;
    }
    void operator=(const cart_communicator &)=delete;
    cart_communicator & operator=(cart_communicator &&other) {
      if (this!=&other) {
        int result1, result2;
        MPI_Comm_compare(comm, MPI_COMM_WORLD, &result1);
        MPI_Comm_compare(comm, MPI_COMM_SELF, &result2);
        if (result1!=MPI_IDENT and result2!=MPI_IDENT)
          MPI_Comm_free(&comm);
        comm=other.comm;
        other.comm=MPI_COMM_SELF;
      }
      return *this;
    }
    int dim() const {
      int ndims;
      MPI_Cartdim_get(comm, &ndims);
      return ndims;
    }
    using communicator::rank;
    int rank(const std::vector<int> &coords) const {
      int rank_;
      MPI_Cart_rank(comm, coords.data(), &rank_);
      return rank_;
    }
    std::vector<int> coords(int rank) const {
      std::vector<int> coords_(dim());
      MPI_Cart_coords(comm, rank, coords_.size(), coords_.data());
      return coords_;
    }
    std::vector<int> coords() const {
      int ndims(dim());
      std::vector<int> dims_(ndims), periodic_(ndims), coords_(ndims);
      MPI_Cart_get(comm, ndims, dims_.data(), periodic_.data(), coords_.data());
      return coords_;
    }
    std::vector<int> dims() const {
      int ndims(dim());
      std::vector<int> dims_(ndims), periodic_(ndims), coords_(ndims);
      MPI_Cart_get(comm, ndims, dims_.data(), periodic_.data(), coords_.data());
      return dims_;
    }
    std::vector<int> periodic() const {
      int ndims(dim());
      std::vector<int> dims_(ndims), periodic_(ndims), coords_(ndims);
      MPI_Cart_get(comm, ndims, dims_.data(), periodic_.data(), coords_.data());
      return periodic_;
    }
    shift_ranks shift(int direction, int disp) const {
      int rank_source, rank_dest;
      MPI_Cart_shift(comm, direction, disp, &rank_source, &rank_dest);
      return {rank_source, rank_dest};
    }
    // === neighbour collective ========================================
    // === neighbour allgather ===
    // === get a signle value from each neighbour and store in contiguous memory
    // --- blocking neighbour allgather ---
    template<typename T>
    void neighbour_allgather(const T &senddata, T *recvdata) const {
      MPI_Neighbor_allgather(*senddata, 1, datatype_traits<T>::get_datatype(),
			     recvdata, 1, datatype_traits<T>::get_datatype(),
			     comm);
    }
    template<typename T>
    void neighbour_allgather(const T *senddata, const layout<T> &sendl,
			     T *recvdata, const layout<T> &recvl) const {
      MPI_Neighbour_allgather(senddata, 1, datatype_traits<layout<T>>::get_datatype(sendl),
			      recvdata, 1, datatype_traits<layout<T>>::get_datatype(recvl),
			      comm);
    }
    // --- nonblocking neighbour allgather ---
    template<typename T>
    irequest ineighbour_allgather(const T &senddata, T *recvdata) const {
      MPI_Request req;
      MPI_Ineighbour_allgather(&senddata, 1, datatype_traits<T>::get_datatype(),
			       recvdata, 1, datatype_traits<T>::get_datatype(),
			       comm, &req);
      return irequest(req);
    }
    template<typename T>
    irequest ineighbour_allgather(const T *senddata, const layout<T> &sendl,
					  T *recvdata, const layout<T> &recvl) const {
      MPI_Request req;
      MPI_Ineighbour_allgather(senddata, 1, datatype_traits<layout<T>>::get_datatype(sendl),
			       recvdata, 1, datatype_traits<layout<T>>::get_datatype(recvl),
			       comm, &req);
      return irequest(req);
    }
    // === get varying amount of data from each neighbour and stores in noncontiguous memory
    // --- blocking neighbour allgather ---
    template<typename T>
    void neighbour_allgatherv(const T *senddata, const layout<T> &sendl,
			      T *recvdata, const layouts<T> &recvls, const displacements &recvdispls) const {
      int N(recvdispls.size());
      displacements senddispls(N);
      layouts<T> sendls(N, sendl);
      alltoallv(senddata, sendls, senddispls,
                recvdata, recvls, recvdispls);
    }
    // --- nonblocking neighbour allgather ---
    template<typename T>
    irequest ineighbour_allgatherv(const T *senddata, const layout<T> &sendl,
                                   T *recvdata, const layouts<T> &recvls, const displacements &recvdispls) const {
      int N(recvdispls.size());
      displacements senddispls(N);
      layouts<T> sendls(N, sendl);
      return ialltoallv(senddata, sendls, senddispls,
			recvdata, recvls, recvdispls);
    }
    // === neighbour all-to-all ===
    // === each rank sends a signle value to each neighbour
    // --- blocking neighbour all-to-all ---
    template<typename T>
    void neighbour_alltoall(const T *senddata, T *recvdata) const {
      MPI_Neighbour_alltoall(senddata, 1, datatype_traits<T>::get_datatype(),
			     recvdata, 1, datatype_traits<T>::get_datatype(),
			     comm);
    }
    template<typename T>
    void neighbour_alltoall(const T *senddata, const layout<T> &sendl,
			    T *recvdata, const layout<T> &recvl) const {
      MPI_Neighbour_alltoall(senddata, 1, datatype_traits<T>::get_datatype(),
			     recvdata, 1, datatype_traits<T>::get_datatype(),
			     comm);
    }
    // --- nonblocking neighbour all-to-all ---
    template<typename T>
    irequest ineighbour_alltoall(const T *senddata, T *recvdata) const {
      MPI_Request req;
      MPI_Ineighbour_alltoall(senddata, 1, datatype_traits<T>::get_datatype(),
			      recvdata, 1, datatype_traits<T>::get_datatype(),
			      comm, &req);
      return irequest(req);
    }
    template<typename T>
    irequest ineighbour_alltoall(const T *senddata, const layout<T> &sendl,
					 T *recvdata, const layout<T> &recvl) const {
      MPI_Request req;
      MPI_Ineighbour_alltoall(senddata, 1, datatype_traits<T>::get_datatype(),
			      recvdata, 1, datatype_traits<T>::get_datatype(),
			      comm, &req);
      return irequest(req);
    }
    // === each rank sends a varying number of values to each neighbor with possibly different layouts
    // --- blocking neighbour all-to-all ---
    template<typename T>
    void neighbour_alltoallv(const T *senddata, const layouts<T> &sendl, const displacements &senddispls,
			     T *recvdata, const layouts<T> &recvl, const displacements &recvdispls) const {
      std::vector<int> counts(recvl.size(), 1);
      MPI_Neighbour_alltoallw(senddata, counts.data(), senddispls(), reinterpret_cast<const MPI_Datatype *>(sendl()),
			      recvdata, counts.data(), recvdispls(), reinterpret_cast<const MPI_Datatype *>(recvl()),
			      comm);
    }
    // --- non-blocking neighbour all-to-all ---
    template<typename T>
    irequest ineighbour_alltoallv(const T *senddata, const layouts<T> &sendl, const displacements &senddispls,
					  T *recvdata, const layouts<T> &recvl, const displacements &recvdispls) const {
      std::vector<int> counts(recvl.size(), 1);
      MPI_Request req;
      MPI_Ineighbour_alltoallw(senddata, counts.data(), senddispls(), reinterpret_cast<const MPI_Datatype *>(sendl()),
			       recvdata, counts.data(), recvdispls(), reinterpret_cast<const MPI_Datatype *>(recvl()),
			       comm, &req);
      return irequest(req);
    }
  };

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

  inline cart_communicator::sizes dims_create(int size, cart_communicator::sizes par) {
    if (MPI_Dims_create(size, par.dims_.size(), par.dims_.data())!=MPI_SUCCESS)
      throw invalid_dim();
    return par;
  }

}

#endif
<|endoftext|>


<commit_before>#define CATCH_CONFIG_MAIN
#include "catch.hpp"

#include <algorithm>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <string>

#include "notch.hpp"

using namespace std;

/// FullyConnectedLayer_Test breaks encapsulation of FullyConnectedLayer to
/// explore its inner state.
class FullyConnectedLayer_Test : public FullyConnectedLayer {
public:
    FullyConnectedLayer_Test(size_t in, size_t out, const ActivationFunction &af)
        : FullyConnectedLayer(in, out, af) {}

    Array &getWeights() { return weights; }
    Array &getBias() { return bias; }
    Array &getInducedLocalField() { return inducedLocalField; }
    Array &getActivationGrad() { return activationGrad; }
    Array &getLocalGrad() { return localGrad; }
    shared_ptr<ALearningPolicy> getPolicy() { return policy->copy(); }

    shared_ptr<Array> getLastInputs() { return lastInputs; }
    shared_ptr<Array> getLastOutputs() { return lastOutputs; }
    shared_ptr<BackpropResult> getThisBPR() { return thisBPR; };
    shared_ptr<BackpropResult> getNextBPR() { return nextBPR; };
    bool getBuffersReadyFlag() { return buffersAreReady; };

};

#define CHECK_ARRAY_IS_INITIALIZED(name, arr_expr, expected_size) do { \
    Array &(name) = arr_expr; \
    auto is_zero = [](float x) { return x == Approx(0.0); }; \
    CHECK( (name).size() == (expected_size) ); \
    CHECK( all_of(begin(name), end(name), is_zero) ); \
} while(0)

TEST_CASE( "FullyConnectedLayer construction", "[core]" ) {
    size_t n_in = 3;
    size_t n_out = 2;
    FullyConnectedLayer_Test fc(n_in, n_out, linearActivation);

    // initialization on construction:
    CHECK_ARRAY_IS_INITIALIZED(weights, fc.getWeights(), n_in*n_out);
    CHECK_ARRAY_IS_INITIALIZED(bias, fc.getBias(), n_out);
    CHECK_ARRAY_IS_INITIALIZED(inducedLocalField, fc.getInducedLocalField(), n_out);
    CHECK_ARRAY_IS_INITIALIZED(activationGrad, fc.getActivationGrad(), n_out);
    CHECK_ARRAY_IS_INITIALIZED(localGrad, fc.getLocalGrad(), n_out);
    CHECK_FALSE(fc.getLastInputs());
    CHECK_FALSE(fc.getLastOutputs());
    CHECK_FALSE(fc.getThisBPR());
    CHECK_FALSE(fc.getNextBPR());
    CHECK_FALSE(fc.getBuffersReadyFlag());
}

TEST_CASE( "FullyConnectedLayer shared buffers initialization", "[core]" ) {
    size_t n_in = 3;
    size_t n_out = 7;
    size_t n_out_next = 4;
    auto rng = newRNG();
    FullyConnectedLayer_Test fc(n_in, n_out, linearActivation);
    FullyConnectedLayer_Test fc2(n_out, n_out_next, linearActivation);
    CHECK_FALSE(fc.getBuffersReadyFlag()); // not until connectTo()

    fc.connectTo(fc2);
    CHECK(fc.getBuffersReadyFlag()); // now ready
    CHECK(fc.getNextBPR() == fc2.getThisBPR()); // buffers are shared
    CHECK(fc.getLastOutputs() == fc2.getLastInputs());

    // check dimensions of the dynamically allocated arrays
    CHECK_ARRAY_IS_INITIALIZED(lastInputs, *fc.getLastInputs(), n_in);
    CHECK_ARRAY_IS_INITIALIZED(lastOutputs, *fc.getLastOutputs(), n_out);

    // check that dimensions of this layer's BackpropResult
    // match layer's dimensions
    shared_ptr<BackpropResult> bpr = fc.getThisBPR();
    CHECK_ARRAY_IS_INITIALIZED(bpr_propagatedErrors,
         bpr->propagatedErrors, n_in);
    CHECK_ARRAY_IS_INITIALIZED(bpr_weightsSensitivity,
         bpr->weightSensitivity, n_in * n_out);
    CHECK_ARRAY_IS_INITIALIZED(bpr_biasSensitivity,
         bpr->biasSensitivity, n_out);

    // check that dimensions of the next layer's BackpropResult
    // match layer's dimensions
    shared_ptr<BackpropResult> next_bpr = fc.getNextBPR();
    CHECK_ARRAY_IS_INITIALIZED(next_bpr_propagatedErrors,
         next_bpr->propagatedErrors, n_out);
    CHECK_ARRAY_IS_INITIALIZED(next_bpr_weightsSensitivity,
         next_bpr->weightSensitivity, n_out * n_out_next);
    CHECK_ARRAY_IS_INITIALIZED(next_bpr_biasSensitivity,
         next_bpr->biasSensitivity, n_out_next);

    fc.init(rng, normalXavier);
    CHECK(fc.getNextBPR() == fc2.getThisBPR()); // buffers are still shared
    CHECK(fc.getLastOutputs() == fc2.getLastInputs());
}

TEST_CASE( "FullyConnectedLayer from weights matrix (&&)", "[core]" ) {
    /// three in, two out
    FullyConnectedLayer fc({1, 10, 100, 0.1, 0.01, 0.001}, // weights, row-major
                           {2.5, 5.0}, // bias
                           defaultTanh);
    auto out = *fc.output({1,1,1});
    CHECK(out.size() == 2u);
    CHECK(out[0] == Approx(tanh(111 + 2.5)));
    CHECK(out[1] == Approx(tanh(0.111 + 5.0)));
}

TEST_CASE( "FullyConnectedLayer from weights matrix (const&)", "[core]" ) {
    /// three in, two out
    const Array w = {1, 10, 100, 0.1, 0.01, 0.001}; // weights, row-major
    const Array bias = {2.5, 5.0}; // bias
    FullyConnectedLayer fc(w, bias, linearActivation);
    auto out = *fc.output({1,1,1});
    CHECK(out.size() == 2);
    CHECK(out[0] == Approx(111 + 2.5));
    CHECK(out[1] == Approx(0.111 + 5.0));
}

TEST_CASE( "FullyConnectedLayer init(weights, bias)", "[core]" ) {
    FullyConnectedLayer fc(2, 1, linearActivation);
    auto out_before = *fc.output({1,1});
    CHECK(out_before.size() == 1);
    CHECK(out_before[0] == Approx(0));
    // init using r-value references
    fc.init({10, 100}, {2});
    auto out1 = *fc.output({1,1});
    CHECK(out1.size() == 1);
    CHECK(out1[0] == Approx(112));
    // init using const references
    const Array ws = {0.1, 0.01};
    const Array b = {0};
    fc.init(ws, b);
    auto out2 = *fc.output({1, 2});
    CHECK(out2.size() == 1);
    CHECK(out2[0] == Approx(0.1*1 + 0.01*2));
}

TEST_CASE( "FixedRate (delta rule) policy", "[core][train]") {
    float eta = 0.5;
    FixedRate policy(eta);
    // weight updates
    Array dEdw { 10, 20, 40 };
    Array weights { 100, 200, 400 };
    Array oldWeights = weights;
    policy.correctWeights(dEdw, weights);
    for (size_t i = 0; i < weights.size(); ++i) {
        CHECK(weights[i] == oldWeights[i] - eta*dEdw[i]);
    }
    // bias updates
    Array dBdw { -20, -10 };
    Array bias { 100, 200 };
    Array oldBias = bias;
    policy.correctBias(dBdw, bias);
    for (size_t i = 0; i < bias.size(); ++i) {
        CHECK(bias[i] == oldBias[i] - eta*dBdw[i]);
    }
}

#include "test_notch_io.hpp"
<commit_msg>test case for gemv<commit_after>#define CATCH_CONFIG_MAIN
#include "catch.hpp"

#include <algorithm>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <string>

#include "notch.hpp"

using namespace std;

/// FullyConnectedLayer_Test breaks encapsulation of FullyConnectedLayer to
/// explore its inner state.
class FullyConnectedLayer_Test : public FullyConnectedLayer {
public:
    FullyConnectedLayer_Test(size_t in, size_t out, const ActivationFunction &af)
        : FullyConnectedLayer(in, out, af) {}

    Array &getWeights() { return weights; }
    Array &getBias() { return bias; }
    Array &getInducedLocalField() { return inducedLocalField; }
    Array &getActivationGrad() { return activationGrad; }
    Array &getLocalGrad() { return localGrad; }
    shared_ptr<ALearningPolicy> getPolicy() { return policy->copy(); }

    shared_ptr<Array> getLastInputs() { return lastInputs; }
    shared_ptr<Array> getLastOutputs() { return lastOutputs; }
    shared_ptr<BackpropResult> getThisBPR() { return thisBPR; };
    shared_ptr<BackpropResult> getNextBPR() { return nextBPR; };
    bool getBuffersReadyFlag() { return buffersAreReady; };

};

#define CHECK_ARRAY_IS_INITIALIZED(name, arr_expr, expected_size) do { \
    Array &(name) = arr_expr; \
    auto is_zero = [](float x) { return x == Approx(0.0); }; \
    CHECK( (name).size() == (expected_size) ); \
    CHECK( all_of(begin(name), end(name), is_zero) ); \
} while(0)

TEST_CASE( "FullyConnectedLayer construction", "[core]" ) {
    size_t n_in = 3;
    size_t n_out = 2;
    FullyConnectedLayer_Test fc(n_in, n_out, linearActivation);

    // initialization on construction:
    CHECK_ARRAY_IS_INITIALIZED(weights, fc.getWeights(), n_in*n_out);
    CHECK_ARRAY_IS_INITIALIZED(bias, fc.getBias(), n_out);
    CHECK_ARRAY_IS_INITIALIZED(inducedLocalField, fc.getInducedLocalField(), n_out);
    CHECK_ARRAY_IS_INITIALIZED(activationGrad, fc.getActivationGrad(), n_out);
    CHECK_ARRAY_IS_INITIALIZED(localGrad, fc.getLocalGrad(), n_out);
    CHECK_FALSE(fc.getLastInputs());
    CHECK_FALSE(fc.getLastOutputs());
    CHECK_FALSE(fc.getThisBPR());
    CHECK_FALSE(fc.getNextBPR());
    CHECK_FALSE(fc.getBuffersReadyFlag());
}

TEST_CASE( "FullyConnectedLayer shared buffers initialization", "[core]" ) {
    size_t n_in = 3;
    size_t n_out = 7;
    size_t n_out_next = 4;
    auto rng = newRNG();
    FullyConnectedLayer_Test fc(n_in, n_out, linearActivation);
    FullyConnectedLayer_Test fc2(n_out, n_out_next, linearActivation);
    CHECK_FALSE(fc.getBuffersReadyFlag()); // not until connectTo()

    fc.connectTo(fc2);
    CHECK(fc.getBuffersReadyFlag()); // now ready
    CHECK(fc.getNextBPR() == fc2.getThisBPR()); // buffers are shared
    CHECK(fc.getLastOutputs() == fc2.getLastInputs());

    // check dimensions of the dynamically allocated arrays
    CHECK_ARRAY_IS_INITIALIZED(lastInputs, *fc.getLastInputs(), n_in);
    CHECK_ARRAY_IS_INITIALIZED(lastOutputs, *fc.getLastOutputs(), n_out);

    // check that dimensions of this layer's BackpropResult
    // match layer's dimensions
    shared_ptr<BackpropResult> bpr = fc.getThisBPR();
    CHECK_ARRAY_IS_INITIALIZED(bpr_propagatedErrors,
         bpr->propagatedErrors, n_in);
    CHECK_ARRAY_IS_INITIALIZED(bpr_weightsSensitivity,
         bpr->weightSensitivity, n_in * n_out);
    CHECK_ARRAY_IS_INITIALIZED(bpr_biasSensitivity,
         bpr->biasSensitivity, n_out);

    // check that dimensions of the next layer's BackpropResult
    // match layer's dimensions
    shared_ptr<BackpropResult> next_bpr = fc.getNextBPR();
    CHECK_ARRAY_IS_INITIALIZED(next_bpr_propagatedErrors,
         next_bpr->propagatedErrors, n_out);
    CHECK_ARRAY_IS_INITIALIZED(next_bpr_weightsSensitivity,
         next_bpr->weightSensitivity, n_out * n_out_next);
    CHECK_ARRAY_IS_INITIALIZED(next_bpr_biasSensitivity,
         next_bpr->biasSensitivity, n_out_next);

    fc.init(rng, normalXavier);
    CHECK(fc.getNextBPR() == fc2.getThisBPR()); // buffers are still shared
    CHECK(fc.getLastOutputs() == fc2.getLastInputs());
}

TEST_CASE( "FullyConnectedLayer from weights matrix (&&)", "[core]" ) {
    /// three in, two out
    FullyConnectedLayer fc({1, 10, 100, 0.1, 0.01, 0.001}, // weights, row-major
                           {2.5, 5.0}, // bias
                           defaultTanh);
    auto out = *fc.output({1,1,1});
    CHECK(out.size() == 2u);
    CHECK(out[0] == Approx(tanh(111 + 2.5)));
    CHECK(out[1] == Approx(tanh(0.111 + 5.0)));
}

TEST_CASE( "FullyConnectedLayer from weights matrix (const&)", "[core]" ) {
    /// three in, two out
    const Array w = {1, 10, 100, 0.1, 0.01, 0.001}; // weights, row-major
    const Array bias = {2.5, 5.0}; // bias
    FullyConnectedLayer fc(w, bias, linearActivation);
    auto out = *fc.output({1,1,1});
    CHECK(out.size() == 2);
    CHECK(out[0] == Approx(111 + 2.5));
    CHECK(out[1] == Approx(0.111 + 5.0));
}

TEST_CASE( "FullyConnectedLayer init(weights, bias)", "[core]" ) {
    FullyConnectedLayer fc(2, 1, linearActivation);
    auto out_before = *fc.output({1,1});
    CHECK(out_before.size() == 1);
    CHECK(out_before[0] == Approx(0));
    // init using r-value references
    fc.init({10, 100}, {2});
    auto out1 = *fc.output({1,1});
    CHECK(out1.size() == 1);
    CHECK(out1[0] == Approx(112));
    // init using const references
    const Array ws = {0.1, 0.01};
    const Array b = {0};
    fc.init(ws, b);
    auto out2 = *fc.output({1, 2});
    CHECK(out2.size() == 1);
    CHECK(out2[0] == Approx(0.1*1 + 0.01*2));
}

TEST_CASE( "gemv: matrix-vector product b = M*x + b", "[core][math]") {
    float M[6] = {1, 2, 3, 4, 5, 6}; // row-major 3x2
    float x[3] = {100, 10, 1};
    float b[3] = {1, 2, -1}; // with an extra element at the end
    CHECK_THROWS(gemv(begin(M), end(M), begin(x), end(x), begin(b), end(b)));
    gemv(begin(M), end(M), begin(x), end(x), begin(b), begin(b)+2);
    CHECK(b[0] == Approx(100*1 + 10*2 + 1*3 + 1));
    CHECK(b[1] == Approx(100*4 + 10*5 + 1*6 + 2));
    CHECK(b[2] == -1); // unchanged
}

TEST_CASE( "FixedRate (delta rule) policy", "[core][train]") {
    float eta = 0.5;
    FixedRate policy(eta);
    // weight updates
    Array dEdw { 10, 20, 40 };
    Array weights { 100, 200, 400 };
    Array oldWeights = weights;
    policy.correctWeights(dEdw, weights);
    for (size_t i = 0; i < weights.size(); ++i) {
        CHECK(weights[i] == oldWeights[i] - eta*dEdw[i]);
    }
    // bias updates
    Array dBdw { -20, -10 };
    Array bias { 100, 200 };
    Array oldBias = bias;
    policy.correctBias(dBdw, bias);
    for (size_t i = 0; i < bias.size(); ++i) {
        CHECK(bias[i] == oldBias[i] - eta*dBdw[i]);
    }
}

#include "test_notch_io.hpp"
<|endoftext|>