<commit_before>/*************************************************************************
 *
 *  $RCSfile: commanddefinition.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: fs $ $Date: 2003-07-10 13:02:09 $
 *
 *  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 _DBA_COREDATAACESS_COMMANDDEFINITION_HXX_
#define _DBA_COREDATAACESS_COMMANDDEFINITION_HXX_

#ifndef _DBA_CORE_COMMANDBASE_HXX_
#include "commandbase.hxx"
#endif
#ifndef _DBA_CORE_CONTAINERELEMENT_HXX_
#include "containerelement.hxx"
#endif
#ifndef _COMPHELPER_PROPERTYCONTAINER_HXX_
#include <comphelper/propertycontainer.hxx>
#endif
#ifndef _DBA_CORE_CONFIGURATIONFLUSHABLE_HXX_
#include "configurationflushable.hxx"
#endif
#ifndef _DBA_REGHELPER_HXX_
#include "dba_reghelper.hxx"
#endif
#ifndef _DBASHARED_APITOOLS_HXX_
#include "apitools.hxx"
#endif

#ifndef _COM_SUN_STAR_SDBCX_XRENAME_HPP_
#include <com/sun/star/sdbcx/XRename.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif
#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
#include <comphelper/proparrhlp.hxx>
#endif
#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
#include <comphelper/broadcasthelper.hxx>
#endif

//........................................................................
namespace dbaccess
{
//........................................................................

//=========================================================================
//= OCommandDefinition - a database "document" which describes a query
//=========================================================================

typedef ::cppu::WeakImplHelper3 <   ::com::sun::star::lang::XUnoTunnel
                                ,   ::com::sun::star::lang::XServiceInfo
                                ,   ::com::sun::star::sdbcx::XRename
                                >   OCommandDefinition_Base;

class OCommandDefinition    :public OCommandDefinition_Base
                            ,public OCommandBase
                            ,public OContainerElement
                            ,public comphelper::OMutexAndBroadcastHelper
                            ,public ::comphelper::OPropertyContainer
                            ,public OConfigurationFlushable
                            ,public ::comphelper::OPropertyArrayUsageHelper< OCommandDefinition >
{
protected:
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >               m_xContainer;

protected:
    ~OCommandDefinition();

private:
    OCommandDefinition();

public:
    // helper class for controlling access privileges
    class AccessControl
    {
        friend class OCommandContainer;
    private:
        AccessControl() { }
    };

    // --------------------------------------------------------------------
    // some kind of default ctor, accessible for selected classes only
    OCommandDefinition(AccessControl&);

    OCommandDefinition(
            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContainer,
            const ::rtl::OUString& _rElementName,
            const ::utl::OConfigurationTreeRoot& _rConfigRoot
        );

// com::sun::star::lang::XTypeProvider
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);

// ::com::sun::star::uno::XInterface
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL acquire(  ) throw() { OCommandDefinition_Base::acquire(); }
    virtual void SAL_CALL release(  ) throw() { OCommandDefinition_Base::release(); }

// ::com::sun::star::lang::XServiceInfo
    DECLARE_SERVICE_INFO();

// ::com::sun::star::lang::XServiceInfo - static methods
    static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void) throw( ::com::sun::star::uno::RuntimeException );
    static ::rtl::OUString getImplementationName_Static(void) throw( ::com::sun::star::uno::RuntimeException );
    static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
        Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&);

    // XRename
    virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::lang::XUnoTunnel
    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::beans::XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);

// OPropertySetHelper
    virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

// OContainerElement
    virtual void        inserted(
        const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContainer,
        const ::rtl::OUString& _rElementName,
        const ::utl::OConfigurationTreeRoot& _rConfigRoot);

    virtual void        removed();

    virtual sal_Bool    isContainerElement() const { return m_aConfigurationNode.isValid(); }

protected:
// OPropertyArrayUsageHelper
    virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;

// OConfigurationFlushable
    void flush_NoBroadcast_NoCommit(  ) throw(::com::sun::star::uno::RuntimeException);

// initialize the members from the current configuration node
    void initializeFromConfiguration();

private:
    // helper
    void registerProperties();
};

//........................................................................
}   // namespace dbaccess
//........................................................................

#endif // _DBA_COREDATAACESS_COMMANDDEFINITION_HXX_

<commit_msg>INTEGRATION: CWS insight01 (1.13.22); FILE MERGED 2004/02/20 11:32:32 oj 1.13.22.5: #i25414# extend the datadescriptor for database location and connection resource 2004/02/12 16:15:24 oj 1.13.22.4: #111075# fix refcount problem 2003/12/17 09:46:42 oj 1.13.22.3: #111075# ongoing work 2003/11/17 09:39:08 oj 1.13.22.2: #111075# ongoning work 2003/10/24 06:27:24 oj 1.13.22.1: #i21643# import filter changes<commit_after>/*************************************************************************
 *
 *  $RCSfile: commanddefinition.hxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: hr $ $Date: 2004-08-02 15:07:37 $
 *
 *  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 _DBA_COREDATAACESS_COMMANDDEFINITION_HXX_
#define _DBA_COREDATAACESS_COMMANDDEFINITION_HXX_

#ifndef _DBA_CORE_COMMANDBASE_HXX_
#include "commandbase.hxx"
#endif
#ifndef _COMPHELPER_PROPERTYCONTAINER_HXX_
#include <comphelper/propertycontainer.hxx>
#endif
#ifndef _DBA_REGHELPER_HXX_
#include "dba_reghelper.hxx"
#endif
#ifndef _DBASHARED_APITOOLS_HXX_
#include "apitools.hxx"
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XRENAME_HPP_
#include <com/sun/star/sdbcx/XRename.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
#include <comphelper/proparrhlp.hxx>
#endif
#ifndef _DBA_CORE_DATASETTINGS_HXX_
#include "datasettings.hxx"
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef DBA_CONTENTHELPER_HXX
#include "ContentHelper.hxx"
#endif
#ifndef DBA_COREDATAACESS_COMPONENTDEFINITION_HXX
#include "ComponentDefinition.hxx"
#endif

//........................................................................
namespace dbaccess
{
//........................................................................

//=========================================================================
//= OCommandDefinition - a database "document" which describes a query
//=========================================================================
    class OCommandDefinition_Impl : public OComponentDefinition_Impl
                                  ,public OCommandBase
    {
    public:
    };
typedef ::cppu::ImplHelper1 <   ::com::sun::star::sdbcx::XRename
                                >   OCommandDefinition_Base;
class OCommandDefinition;
typedef ::comphelper::OPropertyArrayUsageHelper< OCommandDefinition >
                        OCommandDefinition_PROP;

class OCommandDefinition    :public OComponentDefinition
                            ,public OCommandDefinition_Base
                            ,public OCommandDefinition_PROP
{
protected:
    virtual ~OCommandDefinition();

    OCommandDefinition(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
        ,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >&   _xParentContainer
        ,const TContentPtr& _pImpl
        );
public:

    OCommandDefinition(
             const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContainer
            ,const ::rtl::OUString& _rElementName
            ,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
            ,const TContentPtr& _pImpl
        );

// com::sun::star::lang::XTypeProvider
    DECLARE_TYPEPROVIDER( );

// ::com::sun::star::uno::XInterface
    DECLARE_XINTERFACE( )

// ::com::sun::star::lang::XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::lang::XServiceInfo - static methods
    static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void) throw( ::com::sun::star::uno::RuntimeException );
    static ::rtl::OUString getImplementationName_Static(void) throw( ::com::sun::star::uno::RuntimeException );
    static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
        Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&);

    // XRename
    virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);

    // OPropertySetHelper
    DECLARE_PROPERTYCONTAINER_DEFAULTS( );
private:
    // helper
    void registerProperties();
};

//........................................................................
}   // namespace dbaccess
//........................................................................

#endif // _DBA_COREDATAACESS_COMMANDDEFINITION_HXX_

<|endoftext|>


<commit_before>#include <QVector3D>
#include "coverage.h"
#include "featurecoverage.h"
#include "feature.h"
#include "geometryhelper.h"
#include "drawers/attributevisualproperties.h"
#include "drawers/drawerattributesetterfactory.h"
#include "simplelinesetter.h"

using namespace Ilwis;
using namespace Geodrawer;

REGISTER_DRAWER_ATTRIBUTE_SETTER(SimpleLineSetter)

SimpleLineSetter::SimpleLineSetter(const IOOptions &options) : BaseSpatialAttributeSetter(options)
{

}

SimpleLineSetter::~SimpleLineSetter()
{

}

DrawerAttributeSetter *SimpleLineSetter::create(const IOOptions &options)
{
    return new SimpleLineSetter(options);

}

FeatureDrawing SimpleLineSetter::setSpatialAttributes(const Ilwis::SPFeatureI &feature,
                                               QVector<QVector3D> &vertices,
                                               QVector<QVector3D> &) const
{
    const UPGeometry& geometry = feature->geometry();
    FeatureDrawing drawing(itLINE);
    int n = geometry->getNumGeometries();
    for(int  geom = 0; geom < n; ++geom ){
        const geos::geom::Geometry *subgeom = geometry->getGeometryN(geom);
        if (!subgeom)
            continue;
        auto *coords = subgeom->getCoordinates();
        quint32 oldend = vertices.size();
        drawing._indices.push_back(VertexIndex(oldend, coords->size(), GL_LINE_STRIP, feature->featureid()));
        vertices.resize(oldend + coords->size());

        Coordinate crd;
        for(int i = 0; i < coords->size(); ++i){
            coords->getAt(i, crd);
            if ( coordinateConversionNeeded()){
                crd = _targetSystem->coord2coord(_sourceSystem, crd);
            }
            vertices[oldend + i] = QVector3D(crd.x, crd.y, crd.z);
        }
        delete coords;
    }
    return drawing;
}

void SimpleLineSetter::setColorAttributes(const VisualAttribute &attr, const QVariant &value, const QColor &defaultColor, const FeatureDrawing& drawing, std::vector<VertexColor> &colors) const
{
    for(int j =0; j < drawing._indices.size(); ++j){
        if ( value.isValid() && value.toInt() != iUNDEF) {
            const auto& indices = drawing[j];
            for(int i =indices._start; i < indices._start + indices._count; ++i){
                QColor clr = attr.value2color(value);
                colors.push_back(VertexColor(clr.redF(), clr.greenF(), clr.blueF(), 1.0));
            }
        }
    }
}

<commit_msg>possibility to overrule the representation color<commit_after>#include <QVector3D>
#include "coverage.h"
#include "featurecoverage.h"
#include "feature.h"
#include "geometryhelper.h"
#include "drawers/attributevisualproperties.h"
#include "drawers/drawerattributesetterfactory.h"
#include "simplelinesetter.h"

using namespace Ilwis;
using namespace Geodrawer;

REGISTER_DRAWER_ATTRIBUTE_SETTER(SimpleLineSetter)

SimpleLineSetter::SimpleLineSetter(const IOOptions &options) : BaseSpatialAttributeSetter(options)
{

}

SimpleLineSetter::~SimpleLineSetter()
{

}

DrawerAttributeSetter *SimpleLineSetter::create(const IOOptions &options)
{
    return new SimpleLineSetter(options);

}

FeatureDrawing SimpleLineSetter::setSpatialAttributes(const Ilwis::SPFeatureI &feature,
                                               QVector<QVector3D> &vertices,
                                               QVector<QVector3D> &) const
{
    const UPGeometry& geometry = feature->geometry();
    FeatureDrawing drawing(itLINE);
    int n = geometry->getNumGeometries();
    for(int  geom = 0; geom < n; ++geom ){
        const geos::geom::Geometry *subgeom = geometry->getGeometryN(geom);
        if (!subgeom)
            continue;
        auto *coords = subgeom->getCoordinates();
        quint32 oldend = vertices.size();
        drawing._indices.push_back(VertexIndex(oldend, coords->size(), GL_LINE_STRIP, feature->featureid()));
        vertices.resize(oldend + coords->size());

        Coordinate crd;
        for(int i = 0; i < coords->size(); ++i){
            coords->getAt(i, crd);
            if ( coordinateConversionNeeded()){
                crd = _targetSystem->coord2coord(_sourceSystem, crd);
            }
            vertices[oldend + i] = QVector3D(crd.x, crd.y, crd.z);
        }
        delete coords;
    }
    return drawing;
}

void SimpleLineSetter::setColorAttributes(const VisualAttribute &attr, const QVariant &value, const QColor &defaultColor, const FeatureDrawing& drawing, std::vector<VertexColor> &colors) const
{
    for(int j =0; j < drawing._indices.size(); ++j){
        if ( value.isValid() && value.toInt() != iUNDEF) {
            const auto& indices = drawing[j];
            for(int i =indices._start; i < indices._start + indices._count; ++i){
                QColor clr = attr.value2color(value);
                if ( defaultColor.isValid()){
                   colors.push_back(VertexColor(defaultColor.redF(), defaultColor.greenF(), defaultColor.blueF(), 1.0));
                }else
                    colors.push_back(VertexColor(clr.redF(), clr.greenF(), clr.blueF(), 1.0));
            }
        }
    }
}

<|endoftext|>


<commit_before>/*
  HardwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

  Modified 23 November 2006 by David A. Mellis
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "Arduino.h"
#include "wiring_private.h"

#include "HardwareSerial.h"

// Define constants and variables for buffering incoming serial data.  We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail
// is the index of the location from which to read.
#define RX_BUFFER_SIZE 128

struct ring_buffer
{
  unsigned char buffer[RX_BUFFER_SIZE];
  int head;
  int tail;
};

inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
  int i = (unsigned int)(rx_buffer->head + 1) % RX_BUFFER_SIZE;

  // if we should be storing the received character into the location
  // just before the tail (meaning that the head would advance to the
  // current location of the tail), we're about to overflow the buffer
  // and so we don't write the character or advance the head.
  if (i != rx_buffer->tail) {
    rx_buffer->buffer[rx_buffer->head] = c;
    rx_buffer->head = i;
  }
}

// Constructors ////////////////////////////////////////////////////////////////

HardwareSerial::HardwareSerial(
  ring_buffer *rx_buffer,
  USART_t     *usart,
  PORT_t      *port,
  uint8_t      in_bm,
  uint8_t      out_bm)
{
  this->_rx_buffer = rx_buffer;
  this->_usart     = usart;
  this->_port      = port;
  this->_in_bm     = in_bm;
  this->_out_bm    = out_bm;
}

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::begin(unsigned long baud)
{
  uint16_t baud_setting;
  uint8_t bscale = 0;
  uint32_t div1k;
  bool use_u2x;

  // TODO: Serial. Fix serial double clock.
  use_u2x = false;

  _port->DIRCLR = _in_bm;  // input
  _port->OUTSET = _out_bm; // set output high
  _port->DIRSET = _out_bm; // set to output

  // Reset flags
  _usart->CTRLB = 0;

  // set the baud rate
  if (baud > (F_CPU/(use_u2x ? 16 : 32))) return; // Baudrate is set too high

  div1k = ((F_CPU*(use_u2x ? 128UL : 64UL)) / baud) - 1024;
  while ((div1k < 2096640UL) && (bscale < 7)) {
    bscale++;
    div1k <<= 1;
  }

  baud_setting = div1k >> 10;

  _usart->BAUDCTRLA = baud_setting&0xff;
  _usart->BAUDCTRLB = (baud_setting>>8) | ((16-bscale) << 4);

  if(use_u2x)
	_usart->CTRLB |= USART_CLK2X_bm;

  // enable Rx and Tx
  _usart->CTRLB |= USART_RXEN_bm | USART_TXEN_bm;
  // enable interrupt
  _usart->CTRLA = (_usart->CTRLA & ~USART_RXCINTLVL_gm) | USART_RXCINTLVL_LO_gc;

  // Char size, parity and stop bits: 8N1
  _usart->CTRLC = USART_CHSIZE_8BIT_gc | USART_PMODE_DISABLED_gc;
}

void HardwareSerial::begin(unsigned long baud, byte config)
{
  begin(baud);

  // Set char size, parity and stop bits
  _usart->CTRLC = config;
}

void HardwareSerial::end()
{
  // disable Rx and Tx
  _usart->CTRLB &= ~(USART_RXEN_bm | USART_TXEN_bm);
  // disable interrupt
  _usart->CTRLA = (_usart->CTRLA & ~USART_RXCINTLVL_gm) | USART_RXCINTLVL_LO_gc;
}

int HardwareSerial::available(void)
{
  return (unsigned int)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
}

int HardwareSerial::peek(void)
{
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    return _rx_buffer->buffer[_rx_buffer->tail];
  }
}

int HardwareSerial::read(void)
{
  // if the head isn't ahead of the tail, we don't have any characters
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
    _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % RX_BUFFER_SIZE;
    return c;
  }
}

void HardwareSerial::flush()
{
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // were full, not empty.
  _rx_buffer->head = _rx_buffer->tail;
}

size_t HardwareSerial::write(uint8_t c)
{
  while ( !(_usart->STATUS & USART_DREIF_bm) );
  _usart->DATA = c;

  return 1;
}

void HardwareSerial::setIREnabled(bool enable)
{
	if(enable)
	{
		_usart->CTRLC |= USART_CMODE_IRDA_gc;
	}
	else
	{
		_usart->CTRLC &= ~USART_CMODE_IRDA_gc;
	}
}

HardwareSerial::operator bool() {
  return true;
}

#define SERIAL_DEFINE(name, usart_port, port_nr) \
ring_buffer name##rx_buffer = { { 0 }, 0, 0 }; \
ISR(USART##usart_port##port_nr##_RXC_vect) \
{ \
  unsigned char c = USART##usart_port##port_nr.DATA; \
  store_char(c, &name##rx_buffer); \
} \
HardwareSerial name (&name##rx_buffer, &USART##usart_port##port_nr, &PORT##usart_port, (port_nr ? PIN6_bm : PIN2_bm), (port_nr ? PIN7_bm : PIN3_bm));

#include "serial_init.inc"

// Assume that USART always start from C0 and goes up
// At this stage we are only interested in the amount of USARTs
#if defined(USARTC0_RXC_vect)
  void serialEvent() __attribute__((weak));
  void serialEvent() {}
  #define serialEvent_implemented
#endif
#if defined(USARTC1_RXC_vect)
  void serialEvent1() __attribute__((weak));
  void serialEvent1() {}
  #define serialEvent1_implemented
#endif
#if defined(USARTD0_RXC_vect)
  void serialEvent2() __attribute__((weak));
  void serialEvent2() {}
  #define serialEvent2_implemented
#endif
#if defined(USARTD1_RXC_vect)
  void serialEvent3() __attribute__((weak));
  void serialEvent3() {}
  #define serialEvent3_implemented
#endif
#if defined(USARTE0_RXC_vect)
  void serialEvent4() __attribute__((weak));
  void serialEvent4() {}
  #define serialEvent4_implemented
#endif
#if defined(USARTE1_RXC_vect)
  void serialEvent5() __attribute__((weak));
  void serialEvent5() {}
  #define serialEvent5_implemented
#endif
#if defined(USARTF0_RXC_vect)
  void serialEvent6() __attribute__((weak));
  void serialEvent6() {}
  #define serialEvent6_implemented
#endif
#if defined(USARTF1_RXC_vect)
  void serialEvent7() __attribute__((weak));
  void serialEvent7() {}
  #define serialEvent7_implemented
#endif

void serialEventRun(void)
{
#ifdef serialEvent_implemented
  if (Serial.available()) serialEvent();
#endif
#ifdef serialEvent1_implemented
  if (Serial1.available()) serialEvent1();
#endif
#ifdef serialEvent2_implemented
  if (Serial2.available()) serialEvent2();
#endif
#ifdef serialEvent3_implemented
  if (Serial3.available()) serialEvent3();
#endif
#ifdef serialEvent4_implemented
  if (Serial4.available()) serialEvent4();
#endif
#ifdef serialEvent5_implemented
  if (Serial5.available()) serialEvent5();
#endif
#ifdef serialEvent6_implemented
  if (Serial6.available()) serialEvent6();
#endif
#ifdef serialEvent7_implemented
  if (Serial7.available()) serialEvent7();
#endif
}
<commit_msg>improved performance of HardwareSerial<commit_after>/*
  HardwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

  Modified 23 November 2006 by David A. Mellis
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "Arduino.h"
#include "wiring_private.h"

#include "HardwareSerial.h"

// Define constants and variables for buffering incoming serial data.  We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail
// is the index of the location from which to read.
#define RX_BUFFER_SIZE 128

struct ring_buffer
{
  unsigned char buffer[RX_BUFFER_SIZE];
  int head;
  int tail;
};

inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
  int i = (unsigned int)(rx_buffer->head + 1) % RX_BUFFER_SIZE;

  // if we should be storing the received character into the location
  // just before the tail (meaning that the head would advance to the
  // current location of the tail), we're about to overflow the buffer
  // and so we don't write the character or advance the head.
  if (i != rx_buffer->tail) {
    rx_buffer->buffer[rx_buffer->head] = c;
    rx_buffer->head = i;
  }
}

// Constructors ////////////////////////////////////////////////////////////////

HardwareSerial::HardwareSerial(
  ring_buffer *rx_buffer,
  USART_t     *usart,
  PORT_t      *port,
  uint8_t      in_bm,
  uint8_t      out_bm)
{
  this->_rx_buffer = rx_buffer;
  this->_usart     = usart;
  this->_port      = port;
  this->_in_bm     = in_bm;
  this->_out_bm    = out_bm;
}

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::begin(unsigned long baud)
{
  uint16_t baud_setting;
  uint8_t bscale = 0;
  uint32_t div1k;
  bool use_u2x;

  // TODO: Serial. Fix serial double clock.
  use_u2x = false;

  _port->DIRCLR = _in_bm;  // input
  _port->OUTSET = _out_bm; // set output high
  _port->DIRSET = _out_bm; // set to output

  // Reset flags
  _usart->CTRLB = 0;

  // set the baud rate
  if (baud > (F_CPU/(use_u2x ? 16 : 32))) return; // Baudrate is set too high

  div1k = ((F_CPU*(use_u2x ? 128UL : 64UL)) / baud) - 1024;
  while ((div1k < 2096640UL) && (bscale < 7)) {
    bscale++;
    div1k <<= 1;
  }

  baud_setting = div1k >> 10;

  _usart->BAUDCTRLA = baud_setting&0xff;
  _usart->BAUDCTRLB = (baud_setting>>8) | ((16-bscale) << 4);

  if(use_u2x)
	_usart->CTRLB |= USART_CLK2X_bm;

  // enable Rx and Tx
  _usart->CTRLB |= USART_RXEN_bm | USART_TXEN_bm;
  // enable interrupt
  _usart->CTRLA = (_usart->CTRLA & ~USART_RXCINTLVL_gm) | USART_RXCINTLVL_LO_gc;

  // Char size, parity and stop bits: 8N1
  _usart->CTRLC = USART_CHSIZE_8BIT_gc | USART_PMODE_DISABLED_gc;
}

void HardwareSerial::begin(unsigned long baud, byte config)
{
  begin(baud);

  // Set char size, parity and stop bits
  _usart->CTRLC = config;
}

void HardwareSerial::end()
{
  // disable Rx and Tx
  _usart->CTRLB &= ~(USART_RXEN_bm | USART_TXEN_bm);
  // disable interrupt
  _usart->CTRLA = (_usart->CTRLA & ~USART_RXCINTLVL_gm) | USART_RXCINTLVL_LO_gc;
}

int HardwareSerial::available(void)
{
  return (unsigned int)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
}

int HardwareSerial::peek(void)
{
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    return _rx_buffer->buffer[_rx_buffer->tail];
  }
}

int HardwareSerial::read(void)
{
  // if the head isn't ahead of the tail, we don't have any characters
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
    _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % RX_BUFFER_SIZE;
    return c;
  }
}

void HardwareSerial::flush()
{
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // were full, not empty.
  _rx_buffer->head = _rx_buffer->tail;
}

size_t HardwareSerial::write(uint8_t c)
{
	_usart->DATA = c; 					//start TX

	if ( !(_usart->STATUS & USART_DREIF_bm) )
		while(!(_usart->STATUS & USART_TXCIF_bm)); 	//wait for TX to complete

	_usart->STATUS|=USART_TXCIF_bm;				//clear TX interrupt flag

	return 1;
}

void HardwareSerial::setIREnabled(bool enable)
{
	if(enable)
	{
		_usart->CTRLC |= USART_CMODE_IRDA_gc;
	}
	else
	{
		_usart->CTRLC &= ~USART_CMODE_IRDA_gc;
	}
}

HardwareSerial::operator bool() {
  return true;
}

#define SERIAL_DEFINE(name, usart_port, port_nr) \
ring_buffer name##rx_buffer = { { 0 }, 0, 0 }; \
ISR(USART##usart_port##port_nr##_RXC_vect) \
{ \
  unsigned char c = USART##usart_port##port_nr.DATA; \
  store_char(c, &name##rx_buffer); \
} \
HardwareSerial name (&name##rx_buffer, &USART##usart_port##port_nr, &PORT##usart_port, (port_nr ? PIN6_bm : PIN2_bm), (port_nr ? PIN7_bm : PIN3_bm));

#include "serial_init.inc"

// Assume that USART always start from C0 and goes up
// At this stage we are only interested in the amount of USARTs
#if defined(USARTC0_RXC_vect)
  void serialEvent() __attribute__((weak));
  void serialEvent() {}
  #define serialEvent_implemented
#endif
#if defined(USARTC1_RXC_vect)
  void serialEvent1() __attribute__((weak));
  void serialEvent1() {}
  #define serialEvent1_implemented
#endif
#if defined(USARTD0_RXC_vect)
  void serialEvent2() __attribute__((weak));
  void serialEvent2() {}
  #define serialEvent2_implemented
#endif
#if defined(USARTD1_RXC_vect)
  void serialEvent3() __attribute__((weak));
  void serialEvent3() {}
  #define serialEvent3_implemented
#endif
#if defined(USARTE0_RXC_vect)
  void serialEvent4() __attribute__((weak));
  void serialEvent4() {}
  #define serialEvent4_implemented
#endif
#if defined(USARTE1_RXC_vect)
  void serialEvent5() __attribute__((weak));
  void serialEvent5() {}
  #define serialEvent5_implemented
#endif
#if defined(USARTF0_RXC_vect)
  void serialEvent6() __attribute__((weak));
  void serialEvent6() {}
  #define serialEvent6_implemented
#endif
#if defined(USARTF1_RXC_vect)
  void serialEvent7() __attribute__((weak));
  void serialEvent7() {}
  #define serialEvent7_implemented
#endif

void serialEventRun(void)
{
#ifdef serialEvent_implemented
  if (Serial.available()) serialEvent();
#endif
#ifdef serialEvent1_implemented
  if (Serial1.available()) serialEvent1();
#endif
#ifdef serialEvent2_implemented
  if (Serial2.available()) serialEvent2();
#endif
#ifdef serialEvent3_implemented
  if (Serial3.available()) serialEvent3();
#endif
#ifdef serialEvent4_implemented
  if (Serial4.available()) serialEvent4();
#endif
#ifdef serialEvent5_implemented
  if (Serial5.available()) serialEvent5();
#endif
#ifdef serialEvent6_implemented
  if (Serial6.available()) serialEvent6();
#endif
#ifdef serialEvent7_implemented
  if (Serial7.available()) serialEvent7();
#endif
}
<|endoftext|>


<commit_before>#pragma once

#include <algorithm>
#include <array>
#include <iostream>
#include <vector>

#include "../loop/loop_nest.hpp"
#include "memory_layout_exception.hpp"
#include "tile_iterator.hpp"
#include "tiling_info_dim.hpp"
#include "util.hpp"

namespace memory_layout {

namespace detail {

template <size_t dim, typename T, typename U> // , size_t... indices
void tile_dim_indices(
    std::vector<T, U> &tiled, const std::vector<T, U> &org,
    const std::vector<tiling_info_dim> &tiling_info,
    std::array<size_t, dim> &tile_index) { // , std::index_sequence<indices...>
  // std::cout << "tile_index: ";
  // for (size_t d = 0; d < dim; d++) {
  //     if (d > 0) {
  //         std::cout << ", ";
  //     }
  //     std::cout << tile_index[d];
  // }
  // std::cout << std::endl;

  size_t cur_stride = 1;
  size_t skipped_blocks = 0;
  for (size_t d = 0; d < dim; d++) {
    skipped_blocks += tile_index[(dim - 1) - d] * cur_stride;
    cur_stride *= (tiling_info[(dim - 1) - d].stride /
                   tiling_info[(dim - 1) - d].tile_size_dir);
  }

  // std::cout << "skipped blocks: " << skipped_blocks << std::endl;

  for (size_t d = 0; d < dim; d++) {
    skipped_blocks *= tiling_info[d].tile_size_dir;
  }

  // std::array<size_t, dim> min;
  // std::fill_n(min.begin(), dim, 0);
  // size_t min[dim];
  std::array<size_t, dim> min;
  for (size_t d = 0; d < dim; d++) {
    min[d] = 0;
  }

  // size_t min[] = {(indices,0)...};
  // size_t max[] = {(tiling_info[indices].tile_size_dir)...};
  // size_t stride[] = {(indices,1)...};

  // size_t max[dim];
  std::array<size_t, dim> max;
  for (size_t d = 0; d < dim; d++) {
    max[d] = tiling_info[d].tile_size_dir;
  }
  // std::array<size_t, dim> stride;
  // std::fill_n(stride.begin(), dim, 1);

  // size_t stride[dim];
  std::array<size_t, dim> stride;
  for (size_t d = 0; d < dim; d++) {
    stride[d] = 1;
  }

  // std::cout << "skipped cells: " << skipped_blocks << std::endl;

  // std::cout << "min: ";
  // for (size_t d = 0; d < dim; d++) {
  //     if (d > 0) {
  //         std::cout << ", ";
  //     }
  //     std::cout << min[d];
  // }
  // std::cout << std::endl;

  // std::cout << "max: ";
  // for (size_t d = 0; d < dim; d++) {
  //     if (d > 0) {
  //         std::cout << ", ";
  //     }
  //     std::cout << max[d];
  // }
  // std::cout << std::endl;

  // std::cout << "stride: ";
  // for (size_t d = 0; d < dim; d++) {
  //     if (d > 0) {
  //         std::cout << ", ";
  //     }
  //     std::cout << stride[d];
  // }
  // std::cout << std::endl;

  opttmp::loop::dynamic_loop_nest<dim>(
      min, max, stride,
      [&tiled, &org, &tiling_info, &tile_index,
       skipped_blocks](const std::array<size_t, dim> &inner_index) {
        //                std::cout << "inner_index: ";
        //                for (size_t d = 0; d < dim; d++) {
        //                    if (d > 0) {
        //                        std::cout << ", ";
        //                    }
        //                    std::cout << inner_index[d];
        //                }
        //                std::cout << std::endl;

        size_t inner_flat_index = 0;
        size_t cur_stride = 1;
        for (size_t d = 0; d < dim; d++) {
          inner_flat_index += inner_index[(dim - 1) - d] * cur_stride;
          cur_stride *= tiling_info[(dim - 1) - d].tile_size_dir;
        }
        size_t original_flat_index = 0;
        cur_stride = 1;

        // std::cout << "org index: ";
        for (size_t d = 0; d < dim; d++) {
          // if (d > 0) {
          //     std::cout << ", ";
          // }
          // std::cout << (tile_index[(dim - 1) - d] * tiling_info[(dim - 1) -
          // d].tile_size_dir + inner_index[(dim - 1) - d]);
          original_flat_index += (tile_index[(dim - 1) - d] *
                                      tiling_info[(dim - 1) - d].tile_size_dir +
                                  inner_index[(dim - 1) - d]) *
                                 cur_stride;
          cur_stride *= tiling_info[(dim - 1) - d].stride;
        }
        // std::cout << std::endl;
        // std::cout << "inner flat index: " << inner_flat_index << std::endl;
        // std::cout << "inner skipped cells: " << (skipped_blocks +
        // inner_flat_index) << std::endl;
        // std::cout << "original flat index: " << (original_flat_index) <<
        // std::endl;
        tiled[skipped_blocks + inner_flat_index] = org[original_flat_index];
      });
}

template <size_t dim, size_t cur_dim, typename T, typename U>
typename std::enable_if<cur_dim == dim, void>::type
tile_dim(std::vector<T, U> &tiled, const std::vector<T, U> &org,
         const std::vector<tiling_info_dim> &tiling_info,
         std::array<size_t, dim> &tile_index) {
  tile_dim_indices<dim, T>(tiled, org, tiling_info,
                           tile_index); // , std::make_index_sequence<dim>()
}

template <size_t dim, size_t cur_dim, typename T, typename U>
typename std::enable_if<cur_dim != dim, void>::type
tile_dim(std::vector<T, U> &tiled, const std::vector<T, U> &org,
         const std::vector<tiling_info_dim> &tiling_info,
         std::array<size_t, dim> &partial_tile_index) {
  const tiling_info_dim &cur_info = tiling_info[cur_dim];
  for (size_t tile_index_1d = 0;
       tile_index_1d < cur_info.stride / cur_info.tile_size_dir;
       tile_index_1d += 1) {
    partial_tile_index[cur_dim] = tile_index_1d;
    tile_dim<dim, cur_dim + 1>(tiled, org, tiling_info, partial_tile_index);
  }
}
}

// dimension of matrix, dimension of tiles
template <size_t dim, typename T, typename U>
std::vector<T, U> make_tiled(std::vector<T, U> &org,
                             const std::vector<tiling_info_dim> &tiling_info) {
  std::vector<T, U> tiled;
  tiled.resize(org.size());
  if (tiling_info.size() != dim) {
    throw memory_layout_exception(
        "tiling_info doesn't match specified dimension");
  }

  std::array<size_t, dim> tile_index;
  detail::tile_dim<dim, 0>(tiled, org, tiling_info, tile_index);

  // // min, max index for iterating within tile
  // std::array<size_t, dim> min;
  // for (size_t d = 0; d < dim; d++) {
  //   min[d] = 0;
  // }
  // std::array<size_t, dim> max;
  // for (size_t d = 0; d < dim; d++) {
  //   max[d] = tiling_info[d].tile_size_dir;
  // }
  // // required for dynamic_loop_nest
  // std::array<size_t, dim> strides;
  // for (size_t d = 0; d < dim; d++) {
  //   strides[d] = 1;
  // }

  // // number of elements in dim
  // std::array<size_t, dim> untiled_strides;
  // for (size_t d = 0; d < dim; d++) {
  //   untiled_strides[d] = tiling_info[d].stride;
  // }

  // memory_layout::iterate_tiles<2>(
  //     tiled, tiling_info, [&org, &untiled_strides, &tiling_info, &min, &max,
  //                          &strides](auto view) {
  //       std::array<size_t, dim> &tile_index = view.get_tile_index();

  //       std::array<size_t, dim> index_offset;
  //       // std::cout << "---------next tile---------" << std::endl;
  //       for (size_t d = 0; d < dim; d++) {
  //         index_offset[d] = tile_index[d] * tiling_info[d].tile_size_dir;
  //         // std::cout << "index_offset[" << d << "] = " << index_offset[d]
  //         <<
  //         // std::endl;
  //       }

  //       opttmp::loop::dynamic_loop_nest<dim>(
  //           min, max, strides,
  //           [&view, &org, &tiling_info, &index_offset,
  //            &untiled_strides](const std::array<size_t, dim> &inner_index) {
  //             std::array<size_t, dim> outer_index;
  //             for (size_t d = 0; d < dim; d++) {
  //               outer_index[d] = inner_index[d] + index_offset[d];
  //               // std::cout << "outer_index[" << d << "] = " <<
  //               outer_index[d]
  //               // << std::endl;
  //             }
  //             size_t flat_outer_index =
  //                 flat_index(outer_index, untiled_strides);
  //             // std::cout << "flat_outer_index: " << flat_outer_index <<
  //             // std::endl;
  //             // std::cout << "view[index_offset] = " << view[inner_index] <<
  //             // std::endl;
  //             view[inner_index] = org[flat_outer_index];
  //           });

  //     });

  return tiled;
}

// dimension of matrix, dimension of tiles
// undo tiling inplace
template <size_t dim, typename T, typename U>
std::vector<T, U> undo_tiling(std::vector<T, U> &tiled,
                              const std::vector<tiling_info_dim> &tiling_info) {
  std::vector<T, U> untiled(tiled.size());
  // untiled.resize(tiled.size());
  if (tiling_info.size() != dim) {
    throw memory_layout_exception(
        "tiling_info doesn't match specified dimension");
  }

  // min, max index for iterating within tile
  std::array<size_t, dim> min;
  for (size_t d = 0; d < dim; d++) {
    min[d] = 0;
  }
  std::array<size_t, dim> max;
  for (size_t d = 0; d < dim; d++) {
    max[d] = tiling_info[d].tile_size_dir;
  }
  // required for dynamic_loop_nest
  std::array<size_t, dim> strides;
  for (size_t d = 0; d < dim; d++) {
    strides[d] = 1;
  }

  // number of elements in dim
  std::array<size_t, dim> untiled_strides;
  for (size_t d = 0; d < dim; d++) {
    untiled_strides[d] = tiling_info[d].stride;
  }

  memory_layout::iterate_tiles<2>(
      tiled, tiling_info, [&untiled, &untiled_strides, &tiling_info, &min, &max,
                           &strides](auto view) {
        std::array<size_t, dim> &tile_index = view.get_tile_index();

        std::array<size_t, dim> index_offset;
        std::cout << "---------next tile---------" << std::endl;
        for (size_t d = 0; d < dim; d++) {
          index_offset[d] = tile_index[d] * tiling_info[d].tile_size_dir;
          std::cout << "index_offset[" << d << "] = " << index_offset[d]
                    << std::endl;
        }

        opttmp::loop::dynamic_loop_nest<dim>(
            min, max, strides,
            [&view, &untiled, &tiling_info, &index_offset,
             &untiled_strides](const std::array<size_t, dim> &inner_index) {
              std::array<size_t, dim> outer_index;
              std::cout << "untiled index ";
              for (size_t d = 0; d < dim; d++) {
                outer_index[d] = inner_index[d] + index_offset[d];
                if (d > 0) {
                    std::cout << ", ";
                }
                std::cout << outer_index[d];
              }
              size_t flat_outer_index =
                  flat_index(outer_index, untiled_strides);
              std::cout << " flat_outer_index: " << flat_outer_index;
              std::cout << " view[index_offset] = " << view[inner_index]
                        << std::endl;
              untiled[flat_outer_index] = view[inner_index];
            });

      });
  return untiled;
}
}
<commit_msg>some cleanup<commit_after>#pragma once

#include <algorithm>
#include <array>
#include <iostream>
#include <vector>

#include "../loop/loop_nest.hpp"
#include "memory_layout_exception.hpp"
#include "tile_iterator.hpp"
#include "tiling_info_dim.hpp"
#include "util.hpp"

namespace memory_layout {

namespace detail {

template <size_t dim, typename T, typename U> // , size_t... indices
void tile_dim_indices(
    std::vector<T, U> &tiled, const std::vector<T, U> &org,
    const std::vector<tiling_info_dim> &tiling_info,
    std::array<size_t, dim> &tile_index) { // , std::index_sequence<indices...>
  // std::cout << "tile_index: ";
  // for (size_t d = 0; d < dim; d++) {
  //     if (d > 0) {
  //         std::cout << ", ";
  //     }
  //     std::cout << tile_index[d];
  // }
  // std::cout << std::endl;

  size_t cur_stride = 1;
  size_t skipped_blocks = 0;
  for (size_t d = 0; d < dim; d++) {
    skipped_blocks += tile_index[(dim - 1) - d] * cur_stride;
    cur_stride *= (tiling_info[(dim - 1) - d].stride /
                   tiling_info[(dim - 1) - d].tile_size_dir);
  }

  // std::cout << "skipped blocks: " << skipped_blocks << std::endl;

  for (size_t d = 0; d < dim; d++) {
    skipped_blocks *= tiling_info[d].tile_size_dir;
  }

  // std::array<size_t, dim> min;
  // std::fill_n(min.begin(), dim, 0);
  // size_t min[dim];
  std::array<size_t, dim> min;
  for (size_t d = 0; d < dim; d++) {
    min[d] = 0;
  }

  // size_t min[] = {(indices,0)...};
  // size_t max[] = {(tiling_info[indices].tile_size_dir)...};
  // size_t stride[] = {(indices,1)...};

  // size_t max[dim];
  std::array<size_t, dim> max;
  for (size_t d = 0; d < dim; d++) {
    max[d] = tiling_info[d].tile_size_dir;
  }
  // std::array<size_t, dim> stride;
  // std::fill_n(stride.begin(), dim, 1);

  // size_t stride[dim];
  std::array<size_t, dim> stride;
  for (size_t d = 0; d < dim; d++) {
    stride[d] = 1;
  }

  // std::cout << "skipped cells: " << skipped_blocks << std::endl;

  // std::cout << "min: ";
  // for (size_t d = 0; d < dim; d++) {
  //     if (d > 0) {
  //         std::cout << ", ";
  //     }
  //     std::cout << min[d];
  // }
  // std::cout << std::endl;

  // std::cout << "max: ";
  // for (size_t d = 0; d < dim; d++) {
  //     if (d > 0) {
  //         std::cout << ", ";
  //     }
  //     std::cout << max[d];
  // }
  // std::cout << std::endl;

  // std::cout << "stride: ";
  // for (size_t d = 0; d < dim; d++) {
  //     if (d > 0) {
  //         std::cout << ", ";
  //     }
  //     std::cout << stride[d];
  // }
  // std::cout << std::endl;

  opttmp::loop::dynamic_loop_nest<dim>(
      min, max, stride,
      [&tiled, &org, &tiling_info, &tile_index,
       skipped_blocks](const std::array<size_t, dim> &inner_index) {
        //                std::cout << "inner_index: ";
        //                for (size_t d = 0; d < dim; d++) {
        //                    if (d > 0) {
        //                        std::cout << ", ";
        //                    }
        //                    std::cout << inner_index[d];
        //                }
        //                std::cout << std::endl;

        size_t inner_flat_index = 0;
        size_t cur_stride = 1;
        for (size_t d = 0; d < dim; d++) {
          inner_flat_index += inner_index[(dim - 1) - d] * cur_stride;
          cur_stride *= tiling_info[(dim - 1) - d].tile_size_dir;
        }
        size_t original_flat_index = 0;
        cur_stride = 1;

        // std::cout << "org index: ";
        for (size_t d = 0; d < dim; d++) {
          // if (d > 0) {
          //     std::cout << ", ";
          // }
          // std::cout << (tile_index[(dim - 1) - d] * tiling_info[(dim - 1) -
          // d].tile_size_dir + inner_index[(dim - 1) - d]);
          original_flat_index += (tile_index[(dim - 1) - d] *
                                      tiling_info[(dim - 1) - d].tile_size_dir +
                                  inner_index[(dim - 1) - d]) *
                                 cur_stride;
          cur_stride *= tiling_info[(dim - 1) - d].stride;
        }
        // std::cout << std::endl;
        // std::cout << "inner flat index: " << inner_flat_index << std::endl;
        // std::cout << "inner skipped cells: " << (skipped_blocks +
        // inner_flat_index) << std::endl;
        // std::cout << "original flat index: " << (original_flat_index) <<
        // std::endl;
        tiled[skipped_blocks + inner_flat_index] = org[original_flat_index];
      });
}

template <size_t dim, size_t cur_dim, typename T, typename U>
typename std::enable_if<cur_dim == dim, void>::type
tile_dim(std::vector<T, U> &tiled, const std::vector<T, U> &org,
         const std::vector<tiling_info_dim> &tiling_info,
         std::array<size_t, dim> &tile_index) {
  tile_dim_indices<dim, T>(tiled, org, tiling_info,
                           tile_index); // , std::make_index_sequence<dim>()
}

template <size_t dim, size_t cur_dim, typename T, typename U>
typename std::enable_if<cur_dim != dim, void>::type
tile_dim(std::vector<T, U> &tiled, const std::vector<T, U> &org,
         const std::vector<tiling_info_dim> &tiling_info,
         std::array<size_t, dim> &partial_tile_index) {
  const tiling_info_dim &cur_info = tiling_info[cur_dim];
  for (size_t tile_index_1d = 0;
       tile_index_1d < cur_info.stride / cur_info.tile_size_dir;
       tile_index_1d += 1) {
    partial_tile_index[cur_dim] = tile_index_1d;
    tile_dim<dim, cur_dim + 1>(tiled, org, tiling_info, partial_tile_index);
  }
}
}

// dimension of matrix, dimension of tiles
template <size_t dim, typename T, typename U>
std::vector<T, U> make_tiled(std::vector<T, U> &org,
                             const std::vector<tiling_info_dim> &tiling_info) {
  std::vector<T, U> tiled;
  tiled.resize(org.size());
  if (tiling_info.size() != dim) {
    throw memory_layout_exception(
        "tiling_info doesn't match specified dimension");
  }

  std::array<size_t, dim> tile_index;
  detail::tile_dim<dim, 0>(tiled, org, tiling_info, tile_index);

  // // min, max index for iterating within tile
  // std::array<size_t, dim> min;
  // for (size_t d = 0; d < dim; d++) {
  //   min[d] = 0;
  // }
  // std::array<size_t, dim> max;
  // for (size_t d = 0; d < dim; d++) {
  //   max[d] = tiling_info[d].tile_size_dir;
  // }
  // // required for dynamic_loop_nest
  // std::array<size_t, dim> strides;
  // for (size_t d = 0; d < dim; d++) {
  //   strides[d] = 1;
  // }

  // // number of elements in dim
  // std::array<size_t, dim> untiled_strides;
  // for (size_t d = 0; d < dim; d++) {
  //   untiled_strides[d] = tiling_info[d].stride;
  // }

  // memory_layout::iterate_tiles<2>(
  //     tiled, tiling_info, [&org, &untiled_strides, &tiling_info, &min, &max,
  //                          &strides](auto view) {
  //       std::array<size_t, dim> &tile_index = view.get_tile_index();

  //       std::array<size_t, dim> index_offset;
  //       // std::cout << "---------next tile---------" << std::endl;
  //       for (size_t d = 0; d < dim; d++) {
  //         index_offset[d] = tile_index[d] * tiling_info[d].tile_size_dir;
  //         // std::cout << "index_offset[" << d << "] = " << index_offset[d]
  //         <<
  //         // std::endl;
  //       }

  //       opttmp::loop::dynamic_loop_nest<dim>(
  //           min, max, strides,
  //           [&view, &org, &tiling_info, &index_offset,
  //            &untiled_strides](const std::array<size_t, dim> &inner_index) {
  //             std::array<size_t, dim> outer_index;
  //             for (size_t d = 0; d < dim; d++) {
  //               outer_index[d] = inner_index[d] + index_offset[d];
  //               // std::cout << "outer_index[" << d << "] = " <<
  //               outer_index[d]
  //               // << std::endl;
  //             }
  //             size_t flat_outer_index =
  //                 flat_index(outer_index, untiled_strides);
  //             // std::cout << "flat_outer_index: " << flat_outer_index <<
  //             // std::endl;
  //             // std::cout << "view[index_offset] = " << view[inner_index] <<
  //             // std::endl;
  //             view[inner_index] = org[flat_outer_index];
  //           });

  //     });

  return tiled;
}

// dimension of matrix, dimension of tiles
// undo tiling inplace
template <size_t dim, typename T, typename U>
std::vector<T, U> undo_tiling(std::vector<T, U> &tiled,
                              const std::vector<tiling_info_dim> &tiling_info) {
  std::vector<T, U> untiled(tiled.size());
  // untiled.resize(tiled.size());
  if (tiling_info.size() != dim) {
    throw memory_layout_exception(
        "tiling_info doesn't match specified dimension");
  }

  // min, max index for iterating within tile
  std::array<size_t, dim> min;
  for (size_t d = 0; d < dim; d++) {
    min[d] = 0;
  }
  std::array<size_t, dim> max;
  for (size_t d = 0; d < dim; d++) {
    max[d] = tiling_info[d].tile_size_dir;
  }
  // required for dynamic_loop_nest
  std::array<size_t, dim> strides;
  for (size_t d = 0; d < dim; d++) {
    strides[d] = 1;
  }

  // number of elements in dim
  std::array<size_t, dim> untiled_strides;
  for (size_t d = 0; d < dim; d++) {
    untiled_strides[d] = tiling_info[d].stride;
  }

  memory_layout::iterate_tiles<2>(
      tiled, tiling_info, [&untiled, &untiled_strides, &tiling_info, &min, &max,
                           &strides](auto view) {
        std::array<size_t, dim> &tile_index = view.get_tile_index();

        std::array<size_t, dim> index_offset;
        // std::cout << "---------next tile---------" << std::endl;
        for (size_t d = 0; d < dim; d++) {
          index_offset[d] = tile_index[d] * tiling_info[d].tile_size_dir;
          // std::cout << "index_offset[" << d << "] = " << index_offset[d]
          //           << std::endl;
        }

        opttmp::loop::dynamic_loop_nest<dim>(
            min, max, strides,
            [&view, &untiled, &tiling_info, &index_offset,
             &untiled_strides](const std::array<size_t, dim> &inner_index) {
              std::array<size_t, dim> outer_index;
              // std::cout << "untiled index ";
              for (size_t d = 0; d < dim; d++) {
                outer_index[d] = inner_index[d] + index_offset[d];
                // if (d > 0) {
                //     std::cout << ", ";
                // }
                // std::cout << outer_index[d];
              }
              size_t flat_outer_index =
                  flat_index(outer_index, untiled_strides);
              // std::cout << " flat_outer_index: " << flat_outer_index;
              // std::cout << " view[index_offset] = " << view[inner_index]
              //           << std::endl;
              untiled[flat_outer_index] = view[inner_index];
            });

      });
  return untiled;
}
}
<|endoftext|>


<commit_before>#include <Windows.h>
#include "GL/glew.h"
#include "sys/FsWindow.h"
#include "util/FsLog.h"
#include "FsGlobal.h"
#include "scheduler/FsSchedulerTarget.h"
#include "scheduler/FsScheduler.h"
#include "sys/event/FsTouchDispatcher.h"

#define FS_DEFAULT_WINDOW_WIDTH 640
#define FS_DEFAULT_WINDOW_HEIGHT 480
#define FS_DEFAULT_WINDOW_BITS 32

NS_FS_BEGIN

class PlatformWindow;
class EventGraper:public SchedulerTarget
{
	public:
		static EventGraper* create(PlatformWindow* win);

	public:
		/* inherit SchedulerTarget */
		virtual void update(int priority,float dt);

	protected:
		EventGraper();
	private:
		PlatformWindow* m_window;
};

EventGraper::EventGraper()
{
	m_window=NULL;
}

EventGraper* EventGraper::create(PlatformWindow* win)
{
	EventGraper* ret=new EventGraper;
	ret->m_window=win;
	return ret;
}

void EventGraper::update(int priority,float dt)
{
	MSG msg;
	while(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

class PlatformWindow
{
	public:
		HGLRC hrc;
		HDC hdc;
		HWND hwnd;
		HINSTANCE hinstance;
		EventGraper* m_eventGrap;
	protected:
		bool initWin();
		bool initGL();

	public:
		static PlatformWindow* create();
		PlatformWindow();
		~PlatformWindow();

};

static bool pointInView(float x,float y)
{
	if(x>=0&&x<=1.0f)
	{
		if(y>=0&&y<=1.0f)
		{
			return true;
		}
	}
	return false;
}
static void transformViewPoint(float* x,float* y)
{
	int width=Global::window()->getWidth();
	int height=Global::window()->getHeight();
	*x=*x/width;
	*y=*y/height;
	*y=1.0f-*y;
}
static bool s_mouse_capture=false;

LRESULT s_input_dialog_proc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
     switch (Msg)
     {
     case WM_CLOSE:
         DestroyWindow(hDlg);
         return TRUE;
         break;
     case WM_DESTROY:
         PostQuitMessage(0);
         return TRUE;
     };
	 return DefWindowProc(hDlg,Msg,wParam,lParam);
}

LRESULT CALLBACK s_winproc(
		HWND hwnd,
		UINT umsg,
		WPARAM wparam,
		LPARAM lparam
		)
{

	switch(umsg)
	{
		case WM_LBUTTONDOWN:
			{
				float x=(float)LOWORD(lparam);
				float y=(float)HIWORD(lparam);
				transformViewPoint(&x,&y);
				if(pointInView(x,y))
				{
					TouchPoint p(0,x,y);

					Global::touchDispatcher()->dispatchEvent(
											new TouchEvent(TouchDispatcher::TOUCHES_BEGIN,1,&p));
					s_mouse_capture=true;
					SetCapture(hwnd);
				}

			}
			break;
		case WM_MOUSEMOVE:
			{
				if(wparam==MK_LBUTTON&&s_mouse_capture)
				{
					float x=(float)LOWORD(lparam);
					float y=(float)HIWORD(lparam);
					transformViewPoint(&x,&y);

					TouchPoint p(0,x,y);

					Global::touchDispatcher()->dispatchEvent(
											new TouchEvent(TouchDispatcher::TOUCHES_MOVE,1,&p));
				}
			}
			break;
		case WM_LBUTTONUP:
			{
				if(s_mouse_capture)
				{
					float x=(float)LOWORD(lparam);
					float y=(float)HIWORD(lparam);
					transformViewPoint(&x,&y);

					TouchPoint p(0,x,y);
					Global::touchDispatcher()->dispatchEvent(
											new TouchEvent(TouchDispatcher::TOUCHES_END,1,&p));
					ReleaseCapture();
					s_mouse_capture=false;
				}
			}
			break;

		case WM_CLOSE:
			Global::sysDispatcher()->dispatchEvent(new SysEvent(SysDispatcher::QUIT));
			break;

		case WM_DESTROY:
			Global::scheduler()->stop();
			break;

		case WM_KEYDOWN:
			Global::keypadDispatcher()->dispatchEvent(new KeypadEvent(wparam,KeypadEvent::KEYPAD_DOWN));
			break;

		case WM_KEYUP:
			Global::keypadDispatcher()->dispatchEvent(new KeypadEvent(wparam,KeypadEvent::KEYPAD_UP));
			break;

		case WM_SIZE:
			{
				switch(wparam)
				{
					case SIZE_RESTORED:
						Global::sysDispatcher()->dispatchEvent(new SysEvent(SysDispatcher::FOREGROUND));
						break;
					case SIZE_MINIMIZED:
						Global::sysDispatcher()->dispatchEvent(new SysEvent(SysDispatcher::BACKGROUND));
						break;
				}
				int height = HIWORD( lparam );
				int width = LOWORD( lparam );
			//	FS_TRACE_WARN("width=%d,height=%d",width,height);
				Render* render=Global::render();
				if(render)
				{
					render->setViewport(0,0,width,height);
				}
				break;
			}

		default:
			return DefWindowProc(hwnd,umsg,wparam,lparam);
	}
	return 0;
}

static void SetupPixelFormat(HDC hDC)
{
	int pixelFormat;

	PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),  // size
		1,                          // version
		PFD_SUPPORT_OPENGL |        // OpenGL window
		PFD_DRAW_TO_WINDOW |        // render to window
		PFD_DOUBLEBUFFER,           // support double-buffering

		PFD_TYPE_RGBA,              // color type
		32,                         // prefered color depth
		0, 0, 0, 0, 0, 0,           // color bits (ignored)
		0,                          // no alpha buffer
		0,                          // alpha bits (ignored)
		0,                          // no accumulation buffer
		0, 0, 0, 0,                 // accum bits (ignored)
		16,                         // depth buffer
		0,                          // no stencil buffer
		0,                          // no auxiliary buffers
		PFD_MAIN_PLANE,             // main layer
		0,                          // reserved
		0, 0, 0,                    // no layer, visible, damage masks
	};

	pixelFormat = ChoosePixelFormat(hDC, &pfd);
	SetPixelFormat(hDC, pixelFormat, &pfd);
}

PlatformWindow* PlatformWindow::create()
{
	PlatformWindow* ret=new PlatformWindow;
	if(!ret->initWin())
	{
		delete ret;
		return NULL;
	}
	return ret;
}
PlatformWindow::~PlatformWindow()
{
	if(hrc)
	{
		wglMakeCurrent(NULL,NULL);
		wglDeleteContext(hrc);
	}
	if(hdc)
	{
		ReleaseDC(hwnd,hdc);
	}
	if(hwnd)
	{
		DestroyWindow(hwnd);
	}
	UnregisterClass("FaerisWindow",hinstance);
	Global::scheduler()->remove(m_eventGrap,Scheduler::HIGHEST);
	m_eventGrap->decRef();
}

PlatformWindow::PlatformWindow()
{
	hwnd=0;
	hrc=0;
	hdc=0;
	hinstance=0;
	m_eventGrap=EventGraper::create(this);
	Global::scheduler()->add(m_eventGrap,Scheduler::HIGHEST);
}

bool PlatformWindow::initWin()
{

	hinstance=GetModuleHandle(NULL);

	/* window class */
	WNDCLASS wc;
	wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
	wc.lpfnWndProc=(WNDPROC) s_winproc;
	wc.cbClsExtra=0;
	wc.cbWndExtra=0;
	wc.hInstance=hinstance;
	wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);
	wc.hCursor=LoadCursor(NULL,IDC_ARROW);
	wc.hbrBackground=NULL;
	wc.lpszMenuName=NULL;
	wc.lpszClassName="FaerisWindow";
	if(!RegisterClass(&wc))
	{
		FS_TRACE_WARN("RegisterClass Failed");
		return false;
	}

	hwnd=CreateWindowEx(
			WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,
			"FaerisWindow",
			TEXT(FS_DEFAULT_WINDOW_NAME),
			WS_CAPTION|WS_POPUPWINDOW|WS_MINIMIZEBOX,
			0,0,
			FS_DEFAULT_WINDOW_WIDTH,
			FS_DEFAULT_WINDOW_HEIGHT,
			NULL,
			NULL,
			hinstance,
			NULL);
	if(!hwnd)
	{
		FS_TRACE_WARN("CreateWindow Failed");
		return false;
	}
	if(!initGL())
	{
		return false;
	}

	return true;
}

bool PlatformWindow::initGL()
{
	hdc=GetDC(hwnd);
	SetupPixelFormat(hdc);
	hrc=wglCreateContext(hdc);
	wglMakeCurrent(hdc,hrc);
	const GLubyte* gl_version=glGetString(GL_VERSION);
	FsUtil_Log("OpenGL Version=%s",gl_version);
	if(atof((char*)gl_version)<1.5)
	{
		char str_compain[256]={0};
		sprintf(str_compain,"OpenGL 1.5 or higher is required(your version is %s), \
				please upgrade the driver of your video card",gl_version);
		FsUtil_Log("%s",str_compain);
		return false;
	}
	GLenum ret=glewInit();
	if(ret!=GLEW_OK)
	{
		FsUtil_Log("Init Glew Failed %s",glewGetErrorString(ret));
		return false;
	}
	return true;

}

Window* Window::create()
{
	PlatformWindow* plt_window=PlatformWindow::create();
	if(plt_window==NULL)
	{
		return NULL;
	}
	Window* ret=new Window;
	ret->m_window=plt_window;
	return ret;
}

void Window::makeCurrent(Render* r)
{
	if(m_window)
	{
		wglMakeCurrent(m_window->hdc,m_window->hrc);
	}
	m_render=r;
}

void Window::loseCurrent(Render* r)
{
	if(m_window)
	{
		wglMakeCurrent(NULL,m_window->hrc);
	}
	m_render=NULL;
}

void Window::swapBuffers()
{
	if(m_window)
	{
		::SwapBuffers(m_window->hdc);
	}
}

void Window::setCaption(const char* name)
{

	if(m_window)
	{
		SetWindowTextA(m_window->hwnd,name);
		m_caption=name;
	}
}

void Window::setPosition(int x,int y)
{
	if(m_window)
	{
		SetWindowPos(m_window->hwnd, 0, x, y, 0, 0, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER);
	}
}

void Window::setSize(uint width,uint height)
{
	if(!m_window)
	{
		return;
	}
	RECT w_rect;
	RECT c_rect;
	GetWindowRect(m_window->hwnd,&w_rect);
	GetClientRect(m_window->hwnd,&c_rect);
	POINT diff;
	diff.x=(w_rect.right-w_rect.left)-c_rect.right;
	diff.y=(w_rect.bottom-w_rect.top)-c_rect.bottom;

	c_rect.right=c_rect.left+width;
	c_rect.bottom=c_rect.top+height;

	AdjustWindowRectEx(&c_rect,
			GetWindowLong(m_window->hwnd,GWL_STYLE),
			FALSE,
			GetWindowLong(m_window->hwnd,GWL_EXSTYLE)
			);

	SetWindowPos(m_window->hwnd,0,0,0,width+diff.x,height+diff.y,
			SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER
			);
}

void Window::show()
{
	if(m_window)
	{
		ShowWindow(m_window->hwnd,SW_SHOW);
	}

}

void Window::hide()
{
	if(m_window)
	{
		ShowWindow(m_window->hwnd,SW_HIDE);
	}
}

void Window::setStyle(long flags)
{
}

void Window::setFullScreen(bool full)
{
}

int Window::getWidth()
{
	if(m_window)
	{
		RECT rect;
		GetClientRect(m_window->hwnd,&rect);
		return rect.right-rect.left;
	}
	return 0;
}

int Window::getHeight()
{
	if(m_window)
	{
		RECT rect;
		GetClientRect(m_window->hwnd,&rect);
		return rect.bottom-rect.top;
	}
	return 0;
}

int Window::getPosX()
{
	if(m_window)
	{
		RECT w_rect;
		GetWindowRect(m_window->hwnd,&w_rect);
		return w_rect.left;
	}
	return 0;
}

int Window::getPosY()
{
	if(m_window)
	{
		RECT w_rect;
		GetWindowRect(m_window->hwnd,&w_rect);
		return w_rect.top;
	}
	return 0;
}

Window::~Window()
{
	if(m_render)
	{
		m_render->setRenderTarget(NULL);
		m_render=NULL;
	}
	delete m_window;
	m_window=NULL;

}

/* input method dialog */

NS_FS_END

<commit_msg>@fixbug:wrong touch event coord when mouse move outof window for win32<commit_after>#include <Windows.h>
#include "GL/glew.h"
#include "sys/FsWindow.h"
#include "util/FsLog.h"
#include "FsGlobal.h"
#include "scheduler/FsSchedulerTarget.h"
#include "scheduler/FsScheduler.h"
#include "sys/event/FsTouchDispatcher.h"

#define FS_DEFAULT_WINDOW_WIDTH 640
#define FS_DEFAULT_WINDOW_HEIGHT 480
#define FS_DEFAULT_WINDOW_BITS 32

NS_FS_BEGIN

class PlatformWindow;
class EventGraper:public SchedulerTarget
{
	public:
		static EventGraper* create(PlatformWindow* win);

	public:
		/* inherit SchedulerTarget */
		virtual void update(int priority,float dt);

	protected:
		EventGraper();
	private:
		PlatformWindow* m_window;
};

EventGraper::EventGraper()
{
	m_window=NULL;
}

EventGraper* EventGraper::create(PlatformWindow* win)
{
	EventGraper* ret=new EventGraper;
	ret->m_window=win;
	return ret;
}

void EventGraper::update(int priority,float dt)
{
	MSG msg;
	while(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

class PlatformWindow
{
	public:
		HGLRC hrc;
		HDC hdc;
		HWND hwnd;
		HINSTANCE hinstance;
		EventGraper* m_eventGrap;
	protected:
		bool initWin();
		bool initGL();

	public:
		static PlatformWindow* create();
		PlatformWindow();
		~PlatformWindow();

};

static bool pointInView(float x,float y)
{
	if(x>=0&&x<=1.0f)
	{
		if(y>=0&&y<=1.0f)
		{
			return true;
		}
	}
	return false;
}
static void transformViewPoint(float* x,float* y)
{
	int width=Global::window()->getWidth();
	int height=Global::window()->getHeight();
	*x=*x/width;
	*y=*y/height;
	*y=1.0f-*y;
}
static bool s_mouse_capture=false;

LRESULT s_input_dialog_proc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
     switch (Msg)
     {
     case WM_CLOSE:
         DestroyWindow(hDlg);
         return TRUE;
         break;
     case WM_DESTROY:
         PostQuitMessage(0);
         return TRUE;
     };
	 return DefWindowProc(hDlg,Msg,wParam,lParam);
}

LRESULT CALLBACK s_winproc(
		HWND hwnd,
		UINT umsg,
		WPARAM wparam,
		LPARAM lparam
		)
{

	switch(umsg)
	{
		case WM_LBUTTONDOWN:
			{
				float x=(float)(short)LOWORD(lparam);
				float y=(float)(short)HIWORD(lparam);
				transformViewPoint(&x,&y);
				if(pointInView(x,y))
				{
					TouchPoint p(0,x,y);

					Global::touchDispatcher()->dispatchEvent(
											new TouchEvent(TouchDispatcher::TOUCHES_BEGIN,1,&p));
					s_mouse_capture=true;
					SetCapture(hwnd);
				}

			}
			break;
		case WM_MOUSEMOVE:
			{
				if(wparam==MK_LBUTTON&&s_mouse_capture)
				{
					float x=(float)(short)LOWORD(lparam);
					float y=(float)(short)HIWORD(lparam);
					transformViewPoint(&x,&y);

					TouchPoint p(0,x,y);

					Global::touchDispatcher()->dispatchEvent(
											new TouchEvent(TouchDispatcher::TOUCHES_MOVE,1,&p));
				}
			}
			break;
		case WM_LBUTTONUP:
			{
				if(s_mouse_capture)
				{
					float x=(float)(short)LOWORD(lparam);
					float y=(float)(short)HIWORD(lparam);
					transformViewPoint(&x,&y);

					TouchPoint p(0,x,y);
					Global::touchDispatcher()->dispatchEvent(
											new TouchEvent(TouchDispatcher::TOUCHES_END,1,&p));
					ReleaseCapture();
					s_mouse_capture=false;
				}
			}
			break;

		case WM_CLOSE:
			Global::sysDispatcher()->dispatchEvent(new SysEvent(SysDispatcher::QUIT));
			break;

		case WM_DESTROY:
			Global::scheduler()->stop();
			break;

		case WM_KEYDOWN:
			Global::keypadDispatcher()->dispatchEvent(new KeypadEvent(wparam,KeypadEvent::KEYPAD_DOWN));
			break;

		case WM_KEYUP:
			Global::keypadDispatcher()->dispatchEvent(new KeypadEvent(wparam,KeypadEvent::KEYPAD_UP));
			break;

		case WM_SIZE:
			{
				switch(wparam)
				{
					case SIZE_RESTORED:
						Global::sysDispatcher()->dispatchEvent(new SysEvent(SysDispatcher::FOREGROUND));
						break;
					case SIZE_MINIMIZED:
						Global::sysDispatcher()->dispatchEvent(new SysEvent(SysDispatcher::BACKGROUND));
						break;
				}
				int height = HIWORD( lparam );
				int width = LOWORD( lparam );
			//	FS_TRACE_WARN("width=%d,height=%d",width,height);
				Render* render=Global::render();
				if(render)
				{
					render->setViewport(0,0,width,height);
				}
				break;
			}

		default:
			return DefWindowProc(hwnd,umsg,wparam,lparam);
	}
	return 0;
}

static void SetupPixelFormat(HDC hDC)
{
	int pixelFormat;

	PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),  // size
		1,                          // version
		PFD_SUPPORT_OPENGL |        // OpenGL window
		PFD_DRAW_TO_WINDOW |        // render to window
		PFD_DOUBLEBUFFER,           // support double-buffering

		PFD_TYPE_RGBA,              // color type
		32,                         // prefered color depth
		0, 0, 0, 0, 0, 0,           // color bits (ignored)
		0,                          // no alpha buffer
		0,                          // alpha bits (ignored)
		0,                          // no accumulation buffer
		0, 0, 0, 0,                 // accum bits (ignored)
		16,                         // depth buffer
		0,                          // no stencil buffer
		0,                          // no auxiliary buffers
		PFD_MAIN_PLANE,             // main layer
		0,                          // reserved
		0, 0, 0,                    // no layer, visible, damage masks
	};

	pixelFormat = ChoosePixelFormat(hDC, &pfd);
	SetPixelFormat(hDC, pixelFormat, &pfd);
}

PlatformWindow* PlatformWindow::create()
{
	PlatformWindow* ret=new PlatformWindow;
	if(!ret->initWin())
	{
		delete ret;
		return NULL;
	}
	return ret;
}
PlatformWindow::~PlatformWindow()
{
	if(hrc)
	{
		wglMakeCurrent(NULL,NULL);
		wglDeleteContext(hrc);
	}
	if(hdc)
	{
		ReleaseDC(hwnd,hdc);
	}
	if(hwnd)
	{
		DestroyWindow(hwnd);
	}
	UnregisterClass("FaerisWindow",hinstance);
	Global::scheduler()->remove(m_eventGrap,Scheduler::HIGHEST);
	m_eventGrap->decRef();
}

PlatformWindow::PlatformWindow()
{
	hwnd=0;
	hrc=0;
	hdc=0;
	hinstance=0;
	m_eventGrap=EventGraper::create(this);
	Global::scheduler()->add(m_eventGrap,Scheduler::HIGHEST);
}

bool PlatformWindow::initWin()
{

	hinstance=GetModuleHandle(NULL);

	/* window class */
	WNDCLASS wc;
	wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
	wc.lpfnWndProc=(WNDPROC) s_winproc;
	wc.cbClsExtra=0;
	wc.cbWndExtra=0;
	wc.hInstance=hinstance;
	wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);
	wc.hCursor=LoadCursor(NULL,IDC_ARROW);
	wc.hbrBackground=NULL;
	wc.lpszMenuName=NULL;
	wc.lpszClassName="FaerisWindow";
	if(!RegisterClass(&wc))
	{
		FS_TRACE_WARN("RegisterClass Failed");
		return false;
	}

	hwnd=CreateWindowEx(
			WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,
			"FaerisWindow",
			TEXT(FS_DEFAULT_WINDOW_NAME),
			WS_CAPTION|WS_POPUPWINDOW|WS_MINIMIZEBOX,
			0,0,
			FS_DEFAULT_WINDOW_WIDTH,
			FS_DEFAULT_WINDOW_HEIGHT,
			NULL,
			NULL,
			hinstance,
			NULL);
	if(!hwnd)
	{
		FS_TRACE_WARN("CreateWindow Failed");
		return false;
	}
	if(!initGL())
	{
		return false;
	}

	return true;
}

bool PlatformWindow::initGL()
{
	hdc=GetDC(hwnd);
	SetupPixelFormat(hdc);
	hrc=wglCreateContext(hdc);
	wglMakeCurrent(hdc,hrc);
	const GLubyte* gl_version=glGetString(GL_VERSION);
	FsUtil_Log("OpenGL Version=%s",gl_version);
	if(atof((char*)gl_version)<1.5)
	{
		char str_compain[256]={0};
		sprintf(str_compain,"OpenGL 1.5 or higher is required(your version is %s), \
				please upgrade the driver of your video card",gl_version);
		FsUtil_Log("%s",str_compain);
		return false;
	}
	GLenum ret=glewInit();
	if(ret!=GLEW_OK)
	{
		FsUtil_Log("Init Glew Failed %s",glewGetErrorString(ret));
		return false;
	}
	return true;

}

Window* Window::create()
{
	PlatformWindow* plt_window=PlatformWindow::create();
	if(plt_window==NULL)
	{
		return NULL;
	}
	Window* ret=new Window;
	ret->m_window=plt_window;
	return ret;
}

void Window::makeCurrent(Render* r)
{
	if(m_window)
	{
		wglMakeCurrent(m_window->hdc,m_window->hrc);
	}
	m_render=r;
}

void Window::loseCurrent(Render* r)
{
	if(m_window)
	{
		wglMakeCurrent(NULL,m_window->hrc);
	}
	m_render=NULL;
}

void Window::swapBuffers()
{
	if(m_window)
	{
		::SwapBuffers(m_window->hdc);
	}
}

void Window::setCaption(const char* name)
{

	if(m_window)
	{
		SetWindowTextA(m_window->hwnd,name);
		m_caption=name;
	}
}

void Window::setPosition(int x,int y)
{
	if(m_window)
	{
		SetWindowPos(m_window->hwnd, 0, x, y, 0, 0, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER);
	}
}

void Window::setSize(uint width,uint height)
{
	if(!m_window)
	{
		return;
	}
	RECT w_rect;
	RECT c_rect;
	GetWindowRect(m_window->hwnd,&w_rect);
	GetClientRect(m_window->hwnd,&c_rect);
	POINT diff;
	diff.x=(w_rect.right-w_rect.left)-c_rect.right;
	diff.y=(w_rect.bottom-w_rect.top)-c_rect.bottom;

	c_rect.right=c_rect.left+width;
	c_rect.bottom=c_rect.top+height;

	AdjustWindowRectEx(&c_rect,
			GetWindowLong(m_window->hwnd,GWL_STYLE),
			FALSE,
			GetWindowLong(m_window->hwnd,GWL_EXSTYLE)
			);

	SetWindowPos(m_window->hwnd,0,0,0,width+diff.x,height+diff.y,
			SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER
			);
}

void Window::show()
{
	if(m_window)
	{
		ShowWindow(m_window->hwnd,SW_SHOW);
	}

}

void Window::hide()
{
	if(m_window)
	{
		ShowWindow(m_window->hwnd,SW_HIDE);
	}
}

void Window::setStyle(long flags)
{
}

void Window::setFullScreen(bool full)
{
}

int Window::getWidth()
{
	if(m_window)
	{
		RECT rect;
		GetClientRect(m_window->hwnd,&rect);
		return rect.right-rect.left;
	}
	return 0;
}

int Window::getHeight()
{
	if(m_window)
	{
		RECT rect;
		GetClientRect(m_window->hwnd,&rect);
		return rect.bottom-rect.top;
	}
	return 0;
}

int Window::getPosX()
{
	if(m_window)
	{
		RECT w_rect;
		GetWindowRect(m_window->hwnd,&w_rect);
		return w_rect.left;
	}
	return 0;
}

int Window::getPosY()
{
	if(m_window)
	{
		RECT w_rect;
		GetWindowRect(m_window->hwnd,&w_rect);
		return w_rect.top;
	}
	return 0;
}

Window::~Window()
{
	if(m_render)
	{
		m_render->setRenderTarget(NULL);
		m_render=NULL;
	}
	delete m_window;
	m_window=NULL;

}

/* input method dialog */

NS_FS_END

<|endoftext|>


<commit_before>#include <cassert>
#include <set>

#include <llvm/Config/llvm-config.h>
#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR < 5))
#include <llvm/Support/CFG.h>
#else
#include <llvm/IR/CFG.h>
#endif

#include <llvm/IR/Constant.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/IntrinsicInst.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/raw_os_ostream.h>

#include <llvm/IR/Dominators.h>

#include "dg/ADT/Queue.h"
#include "dg/llvm/PointerAnalysis/PointerGraph.h"

#include "llvm/ForkJoin/ForkJoin.h"
#include "llvm/ReadWriteGraph/LLVMReadWriteGraphBuilder.h"
#include "llvm/llvm-utils.h"

namespace dg {
namespace dda {

llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const ValInfo &vi) {
    using namespace llvm;

    if (const auto *I = dyn_cast<Instruction>(vi.v)) {
        os << I->getParent()->getParent()->getName();
        if (auto &DL = I->getDebugLoc()) {
            os << " (line " << DL.getLine() << ", col" << DL.getCol() << ")";
        }
        os << " :: " << *I;
    } else if (const auto *A = dyn_cast<Argument>(vi.v)) {
        os << A->getParent()->getParent()->getName() << ":: (arg) " << *A;
    } else if (const auto *F = dyn_cast<Function>(vi.v)) {
        os << "(func) " << F->getName();
    } else {
        os << *vi.v;
    }

    return os;
}

///
// Map pointers of 'val' to def-sites.
// \param where  location in the program, for debugging
// \param size is the number of bytes used from the memory
std::vector<DefSite>
LLVMReadWriteGraphBuilder::mapPointers(const llvm::Value *where,
                                       const llvm::Value *val, Offset size) {
    std::vector<DefSite> result;

    auto psn = PTA->getLLVMPointsToChecked(val);
    if (!psn.first) {
        result.emplace_back(UNKNOWN_MEMORY);
#ifndef NDEBUG
        llvm::errs() << "[RWG] warning at: " << ValInfo(where) << "\n";
        llvm::errs() << "No points-to set for: " << ValInfo(val) << "\n";
#endif
        // don't have points-to information for used pointer
        return result;
    }

    if (psn.second.empty()) {
#ifndef NDEBUG
        llvm::errs() << "[RWG] warning at: " << ValInfo(where) << "\n";
        llvm::errs() << "Empty points-to set for: " << ValInfo(val) << "\n";
#endif
        // this may happen on invalid reads and writes to memory,
        // like when you try for example this:
        //
        //   int p, q;
        //   memcpy(p, q, sizeof p);
        //
        // (there should be &p and &q)
        // NOTE: maybe this is a bit strong to say unknown memory,
        // but better be sound then incorrect
        result.emplace_back(UNKNOWN_MEMORY);
        return result;
    }

    result.reserve(psn.second.size());

    if (psn.second.hasUnknown()) {
        result.emplace_back(UNKNOWN_MEMORY);
    }

    for (const auto &ptr : psn.second) {
        if (llvm::isa<llvm::Function>(ptr.value))
            continue;

        RWNode *ptrNode = getOperand(ptr.value);
        if (!ptrNode) {
            // keeping such set is faster then printing it all to terminal
            // ... and we don't flood the terminal that way
            static std::set<const llvm::Value *> warned;
            if (warned.insert(ptr.value).second) {
                llvm::errs() << "[RWG] error at " << ValInfo(where) << "\n";
                llvm::errs() << "[RWG] error for " << ValInfo(val) << "\n";
                llvm::errs() << "[RWG] error: Cannot find node for "
                             << ValInfo(ptr.value) << "\n";
            }
            continue;
        }

        // FIXME: we should pass just size to the DefSite ctor, but the old code
        // relies on the behavior that when offset is unknown, the length is
        // also unknown. So for now, mimic the old code. Remove it once we fix
        // the old code.
        result.emplace_back(ptrNode, ptr.offset,
                            ptr.offset.isUnknown() ? Offset::UNKNOWN : size);
    }

    return result;
}

RWNode *LLVMReadWriteGraphBuilder::getOperand(const llvm::Value *val) {
    auto *op = getNode(val);
    if (!op) {
        // lazily create allocations as these are targets in defsites
        // and may not have been created yet
        if (llvm::isa<llvm::AllocaInst>(val) ||
            // FIXME: check that it is allocation
            llvm::isa<llvm::CallInst>(val)) {
            op = buildNode(val).getRepresentant();
        }

        if (!op) {
            llvm::errs() << "[RWG] error: cannot find an operand: " << *val
                         << "\n";
            abort();
        }
    }
    assert(op && "Do not have an operand");
    return op;
}

} // namespace dda
} // namespace dg
<commit_msg>rwg: add a missing space in a message<commit_after>#include <cassert>
#include <set>

#include <llvm/Config/llvm-config.h>
#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR < 5))
#include <llvm/Support/CFG.h>
#else
#include <llvm/IR/CFG.h>
#endif

#include <llvm/IR/Constant.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/IntrinsicInst.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/raw_os_ostream.h>

#include <llvm/IR/Dominators.h>

#include "dg/ADT/Queue.h"
#include "dg/llvm/PointerAnalysis/PointerGraph.h"

#include "llvm/ForkJoin/ForkJoin.h"
#include "llvm/ReadWriteGraph/LLVMReadWriteGraphBuilder.h"
#include "llvm/llvm-utils.h"

namespace dg {
namespace dda {

llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const ValInfo &vi) {
    using namespace llvm;

    if (const auto *I = dyn_cast<Instruction>(vi.v)) {
        os << I->getParent()->getParent()->getName();
        if (auto &DL = I->getDebugLoc()) {
            os << " (line " << DL.getLine() << ", col " << DL.getCol() << ")";
        }
        os << " :: " << *I;
    } else if (const auto *A = dyn_cast<Argument>(vi.v)) {
        os << A->getParent()->getParent()->getName() << ":: (arg) " << *A;
    } else if (const auto *F = dyn_cast<Function>(vi.v)) {
        os << "(func) " << F->getName();
    } else {
        os << *vi.v;
    }

    return os;
}

///
// Map pointers of 'val' to def-sites.
// \param where  location in the program, for debugging
// \param size is the number of bytes used from the memory
std::vector<DefSite>
LLVMReadWriteGraphBuilder::mapPointers(const llvm::Value *where,
                                       const llvm::Value *val, Offset size) {
    std::vector<DefSite> result;

    auto psn = PTA->getLLVMPointsToChecked(val);
    if (!psn.first) {
        result.emplace_back(UNKNOWN_MEMORY);
#ifndef NDEBUG
        llvm::errs() << "[RWG] warning at: " << ValInfo(where) << "\n";
        llvm::errs() << "No points-to set for: " << ValInfo(val) << "\n";
#endif
        // don't have points-to information for used pointer
        return result;
    }

    if (psn.second.empty()) {
#ifndef NDEBUG
        llvm::errs() << "[RWG] warning at: " << ValInfo(where) << "\n";
        llvm::errs() << "Empty points-to set for: " << ValInfo(val) << "\n";
#endif
        // this may happen on invalid reads and writes to memory,
        // like when you try for example this:
        //
        //   int p, q;
        //   memcpy(p, q, sizeof p);
        //
        // (there should be &p and &q)
        // NOTE: maybe this is a bit strong to say unknown memory,
        // but better be sound then incorrect
        result.emplace_back(UNKNOWN_MEMORY);
        return result;
    }

    result.reserve(psn.second.size());

    if (psn.second.hasUnknown()) {
        result.emplace_back(UNKNOWN_MEMORY);
    }

    for (const auto &ptr : psn.second) {
        if (llvm::isa<llvm::Function>(ptr.value))
            continue;

        RWNode *ptrNode = getOperand(ptr.value);
        if (!ptrNode) {
            // keeping such set is faster then printing it all to terminal
            // ... and we don't flood the terminal that way
            static std::set<const llvm::Value *> warned;
            if (warned.insert(ptr.value).second) {
                llvm::errs() << "[RWG] error at " << ValInfo(where) << "\n";
                llvm::errs() << "[RWG] error for " << ValInfo(val) << "\n";
                llvm::errs() << "[RWG] error: Cannot find node for "
                             << ValInfo(ptr.value) << "\n";
            }
            continue;
        }

        // FIXME: we should pass just size to the DefSite ctor, but the old code
        // relies on the behavior that when offset is unknown, the length is
        // also unknown. So for now, mimic the old code. Remove it once we fix
        // the old code.
        result.emplace_back(ptrNode, ptr.offset,
                            ptr.offset.isUnknown() ? Offset::UNKNOWN : size);
    }

    return result;
}

RWNode *LLVMReadWriteGraphBuilder::getOperand(const llvm::Value *val) {
    auto *op = getNode(val);
    if (!op) {
        // lazily create allocations as these are targets in defsites
        // and may not have been created yet
        if (llvm::isa<llvm::AllocaInst>(val) ||
            // FIXME: check that it is allocation
            llvm::isa<llvm::CallInst>(val)) {
            op = buildNode(val).getRepresentant();
        }

        if (!op) {
            llvm::errs() << "[RWG] error: cannot find an operand: " << *val
                         << "\n";
            abort();
        }
    }
    assert(op && "Do not have an operand");
    return op;
}

} // namespace dda
} // namespace dg
<|endoftext|>