<commit_before>//
// Copyright (C) 2004, 2005 Pingtel Corp.
//
//
// $$
////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <assert.h>
#include <stdio.h>

#if defined(_WIN32)
#   include <winsock.h>
#elif defined(_VXWORKS)
#   include <inetLib.h>
#   include <netdb.h>
#   include <resolvLib.h>
#   include <sockLib.h>
#elif defined(__pingtel_on_posix__)
#   include <sys/types.h>
#   include <sys/socket.h>
#   include <netdb.h>
#   include <netinet/in.h>
#   include <arpa/inet.h>
#else
#error Unsupported target platform.
#endif

// APPLICATION INCLUDES

//SSL related includes
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#include "utl/UtlSListIterator.h"
#include "os/OsSSL.h"
#include "os/OsSSLConnectionSocket.h"
#include "os/OsUtil.h"
#include "os/OsSysLog.h"
#include "os/OsTask.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES

// CONSTANTS

// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
OsSSLConnectionSocket::OsSSLConnectionSocket(int connectedSocketDescriptor, long timeoutInSecs) :
    OsConnectionSocket(NULL, connectedSocketDescriptor),
    mSSL(NULL),
    mPeerIdentity(NOT_IDENTIFIED)
{
   if (mIsConnected)
   {
      mbExternalSSLSocket = FALSE;
      SSLInitSocket(connectedSocketDescriptor, timeoutInSecs);
      OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                    "OsSSLConnectionSocket::_(socket %d , timeout %ld)",
                    connectedSocketDescriptor, timeoutInSecs
                    );
   }
   else
   {
      OsSysLog::add(FAC_KERNEL, PRI_ERR,
                    "OsSSLConnectionSocket::_ underlying OsConnectionSocket not connected!!");
   }
}

OsSSLConnectionSocket::OsSSLConnectionSocket(SSL *s, int connectedSocketDescriptor) :
    OsConnectionSocket(NULL, connectedSocketDescriptor)
{
    mbExternalSSLSocket = TRUE;
    mSSL = s;
    socketDescriptor = connectedSocketDescriptor;
    OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                  "OsSSLConnectionSocket::_(SSL %p, socket %d)", s, connectedSocketDescriptor);
}

// Constructor
OsSSLConnectionSocket::OsSSLConnectionSocket(int serverPort, const char* serverName,
                                             long timeoutInSecs) :
    OsConnectionSocket(serverPort,serverName),
    mSSL(NULL)
{
    mbExternalSSLSocket = FALSE;
    if (mIsConnected)
    {
       SSLInitSocket(socketDescriptor, timeoutInSecs);
       OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                     "OsSSLConnectionSocket::_(port %d, name '%s', timeout %ld)",
                     serverPort, serverName, timeoutInSecs
                     );
    }
}

// Destructor
OsSSLConnectionSocket::~OsSSLConnectionSocket()
{
   OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                 "OsSSLConnectionSocket::~"
                 );
   remoteHostName = OsUtil::NULL_OS_STRING;
   mAltNames.destroyAll();
   close();
}

/* ============================ MANIPULATORS ============================== */

UtlBoolean OsSSLConnectionSocket::reconnect()
{
    return FALSE; //TODO
}

void OsSSLConnectionSocket::close()
{
    if (mSSL)
    {
       if (mIsConnected)
          SSL_shutdown(mSSL);
       else
          SSL_clear(mSSL);
    }

   /* Clean up. */
    OsConnectionSocket::close();

   if (mSSL)
   {
      SSL_free(mSSL);
      ERR_remove_state(0);
      mSSL = NULL;
   }
}

int OsSSLConnectionSocket::write(const char* buffer, int bufferLength)
{
    int bytesWritten = -1;

    bytesWritten = SSL_write (mSSL, buffer, bufferLength);

    return(bytesWritten);
}

int OsSSLConnectionSocket::write(const char* buffer, int bufferLength, long waitMilliseconds)
{
    int bytesWritten = -1;
    if(isReadyToWrite(waitMilliseconds))
    {
        bytesWritten = SSL_write (mSSL, buffer, bufferLength);
    }

    return(bytesWritten);
}

int OsSSLConnectionSocket::read(char* buffer, int bufferLength)
{
    // Use base class implementation
    int bytesRead = -1;

    bytesRead = SSL_read (mSSL, buffer, bufferLength);

#ifdef VALGRIND_MAKE_READABLE
    // If we are using Valgrind, we have to compensate for the fact that
    // Valgrind thinks all the output of SSL_read is undefined.
    // (This probably comes from SSL's use of uninitialized memory as part
    // of its key-generation algorithm.)
    VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(&bytesRead, sizeof (bytesRead)));
    if (bytesRead > 0)
    {
       VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(buffer, bytesRead));
    }
#endif /* VALGRIND_MAKE_READABLE */

    return(bytesRead);
}

int OsSSLConnectionSocket::read(char* buffer,
                             int bufferLength,
                             UtlString* ipAddress,
                             int* port)
{
    // Overide base class version as recvfrom does not
    // seem to return host info correctly for TCP
    // Use base class version without the remote host info
    int bytesRead = -1;

    bytesRead = SSL_read (mSSL, buffer, bufferLength);

#ifdef VALGRIND_MAKE_READABLE
    // If we are using Valgrind, we have to compensate for the fact that
    // Valgrind thinks all the output of SSL_read is undefined.
    // (This probably comes from SSL's use of uninitialized memory as part
    // of its key-generation algorithm.)
    VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(&bytesRead, sizeof (bytesRead)));
    if (bytesRead > 0)
    {
       VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(buffer, bytesRead));
    }
#endif /* VALGRIND_MAKE_READABLE */
    // Explicitly get the remote host info.
    getRemoteHostIp(ipAddress);
    *port = getRemoteHostPort();
    return(bytesRead);
}

// Because we have overided one read method, we
// must implement them all in OsSSLConnectionSocket or
// we end up hiding some of the methods.
int OsSSLConnectionSocket::read(char* buffer,
                            int bufferLength,
                            long waitMilliseconds)
{

    int bytesRead = -1;
    if(isReadyToRead(waitMilliseconds))
    {
        bytesRead = SSL_read (mSSL, buffer, bufferLength);
    }
#ifdef VALGRIND_MAKE_READABLE
    // If we are using Valgrind, we have to compensate for the fact that
    // Valgrind thinks all the output of SSL_read is undefined.
    // (This probably comes from SSL's use of uninitialized memory as part
    // of its key-generation algorithm.)
    VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(&bytesRead, sizeof (bytesRead)));
    if (bytesRead > 0)
    {
       VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(buffer, bytesRead));
    }
#endif /* VALGRIND_MAKE_READABLE */
    return(bytesRead);
}

/* ============================ ACCESSORS ================================= */
/* ============================ INQUIRY =================================== */
OsSocket::IpProtocolSocketType OsSSLConnectionSocket::getIpProtocol() const
{
    return(OsSocket::SSL_SOCKET);
}

/// Is this connection encrypted using TLS/SSL?
bool OsSSLConnectionSocket::isEncrypted() const
{
   return true;
}

/// Get any authenticated peer host names.
bool OsSSLConnectionSocket::peerIdentity( UtlSList* altNames
                                         ,UtlString* commonName
                                         ) const
{
   if (NOT_IDENTIFIED == mPeerIdentity)
   {
      // examine cert to get identity and cache the results
      mPeerIdentity = OsSSL::peerIdentity( mSSL, &mAltNames, &mCommonName )
         ? TRUSTED : UNTRUSTED;
      if ( TRUSTED == mPeerIdentity )
      {
         OsSysLog::add(FAC_SIP, PRI_INFO,
                       "OsSSLConnectionSocket::peerIdentity %p OsSSL returned trusted",
                       this);
      }
      else
      {
         OsSysLog::add(FAC_SIP, PRI_WARNING,
                       "OsSSLConnectionSocket::peerIdentity %p OsSSL returned NOT trusted",
                       this);
      }
   }

   /*
    * - true if the connection is TLS/SSL and the peer has presented
    *        a certificate signed by a trusted certificate authority
    * - false if not
    */
   if (commonName)
   {
      commonName->remove(0);
   }
   if (altNames)
   {
      altNames->destroyAll();
   }

   if (TRUSTED == mPeerIdentity)
   {
      if (commonName)
      {
         *commonName = mCommonName;
      }
      if (altNames)
      {
         UtlString* altName;
         UtlSListIterator names(mAltNames);
         while ( (altName = dynamic_cast<UtlString*>(names())) )
         {
            altNames->insert(new UtlString(*altName));
         }
      }
   }

   return TRUSTED == mPeerIdentity;
}

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

void OsSSLConnectionSocket::SSLInitSocket(int socket, long timeoutInSecs)
{
    if (mIsConnected)
    {
       int err = -1;

       // TODO: eventually this should allow for other SSL contexts...
       mSSL = OsSharedSSL::get()->getServerConnection();

       if (mSSL && (socketDescriptor > OS_INVALID_SOCKET_DESCRIPTOR))
       {
          SSL_set_fd (mSSL, socketDescriptor);

          err = SSL_connect(mSSL);
          if (err > 0)
          {
             OsSSL::logConnectParams(FAC_KERNEL, PRI_DEBUG,
                                     "OsSSLConnectionSocket",
                                     mSSL);
          }
          else
          {
             OsSSL::logError(FAC_KERNEL, PRI_ERR,
                             "OsSSLConnectionSocket SSL_connect failed: ",
                             SSL_get_error(mSSL, err));
             mIsConnected = FALSE;
             OsConnectionSocket::close();
             socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
          }
       }
       else
       {
          OsSysLog::add(FAC_KERNEL, PRI_DEBUG
                        , "OsSSLConnectionSocket bad parameters mSSL=%p,%d, closing socket..."
                        , mSSL, socketDescriptor);
          mIsConnected = FALSE;
          OsConnectionSocket::close();
          socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
       }
    }
    else
    {
       OsSysLog::add(FAC_KERNEL, PRI_ERR,
                     "OsSSLConnectionSocket::SSLInitSocket called on unconnected socket"
                     );
    }
}
/* ============================ FUNCTIONS ================================= */
<commit_msg>[XPL-181] Fix connection peer caching           (Initialize OsSSLConnectionSocket::mPeerIdentity in all           constructors).  Thanks to Dale for finding this.<commit_after>//
// Copyright (C) 2004, 2005 Pingtel Corp.
//
//
// $$
////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <assert.h>
#include <stdio.h>

#if defined(_WIN32)
#   include <winsock.h>
#elif defined(_VXWORKS)
#   include <inetLib.h>
#   include <netdb.h>
#   include <resolvLib.h>
#   include <sockLib.h>
#elif defined(__pingtel_on_posix__)
#   include <sys/types.h>
#   include <sys/socket.h>
#   include <netdb.h>
#   include <netinet/in.h>
#   include <arpa/inet.h>
#else
#error Unsupported target platform.
#endif

// APPLICATION INCLUDES

//SSL related includes
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#include "utl/UtlSListIterator.h"
#include "os/OsSSL.h"
#include "os/OsSSLConnectionSocket.h"
#include "os/OsUtil.h"
#include "os/OsSysLog.h"
#include "os/OsTask.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES

// CONSTANTS

// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
OsSSLConnectionSocket::OsSSLConnectionSocket(int connectedSocketDescriptor, long timeoutInSecs) :
   OsConnectionSocket(NULL, connectedSocketDescriptor),
   mSSL(NULL),
   mPeerIdentity(NOT_IDENTIFIED)
{
   if (mIsConnected)
   {
      mbExternalSSLSocket = FALSE;
      SSLInitSocket(connectedSocketDescriptor, timeoutInSecs);
      OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                    "OsSSLConnectionSocket::_(socket %d , timeout %ld)",
                    connectedSocketDescriptor, timeoutInSecs
                    );
   }
   else
   {
      OsSysLog::add(FAC_KERNEL, PRI_ERR,
                    "OsSSLConnectionSocket::_ underlying OsConnectionSocket not connected!!");
   }
}

OsSSLConnectionSocket::OsSSLConnectionSocket(SSL *s, int connectedSocketDescriptor) :
   OsConnectionSocket(NULL, connectedSocketDescriptor),
   mSSL(s),
   mPeerIdentity(NOT_IDENTIFIED)
{
    mbExternalSSLSocket = TRUE;
    socketDescriptor = connectedSocketDescriptor;
    OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                  "OsSSLConnectionSocket::_(SSL %p, socket %d)", s, connectedSocketDescriptor);
}

// Constructor
OsSSLConnectionSocket::OsSSLConnectionSocket(int serverPort, const char* serverName,
                                             long timeoutInSecs) :
   OsConnectionSocket(serverPort,serverName),
   mSSL(NULL),
   mPeerIdentity(NOT_IDENTIFIED)
{
    mbExternalSSLSocket = FALSE;
    if (mIsConnected)
    {
       SSLInitSocket(socketDescriptor, timeoutInSecs);
       OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                     "OsSSLConnectionSocket::_(port %d, name '%s', timeout %ld)",
                     serverPort, serverName, timeoutInSecs
                     );
    }
}

// Destructor
OsSSLConnectionSocket::~OsSSLConnectionSocket()
{
   OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                 "OsSSLConnectionSocket::~"
                 );
   remoteHostName = OsUtil::NULL_OS_STRING;
   mAltNames.destroyAll();
   close();
}

/* ============================ MANIPULATORS ============================== */

UtlBoolean OsSSLConnectionSocket::reconnect()
{
    return FALSE; //TODO
}

void OsSSLConnectionSocket::close()
{
    if (mSSL)
    {
       if (mIsConnected)
          SSL_shutdown(mSSL);
       else
          SSL_clear(mSSL);
    }

   /* Clean up. */
    OsConnectionSocket::close();

   if (mSSL)
   {
      SSL_free(mSSL);
      ERR_remove_state(0);
      mSSL = NULL;
   }
}

int OsSSLConnectionSocket::write(const char* buffer, int bufferLength)
{
    int bytesWritten = -1;

    bytesWritten = SSL_write (mSSL, buffer, bufferLength);

    return(bytesWritten);
}

int OsSSLConnectionSocket::write(const char* buffer, int bufferLength, long waitMilliseconds)
{
    int bytesWritten = -1;
    if(isReadyToWrite(waitMilliseconds))
    {
        bytesWritten = SSL_write (mSSL, buffer, bufferLength);
    }

    return(bytesWritten);
}

int OsSSLConnectionSocket::read(char* buffer, int bufferLength)
{
    // Use base class implementation
    int bytesRead = -1;

    bytesRead = SSL_read (mSSL, buffer, bufferLength);

#ifdef VALGRIND_MAKE_READABLE
    // If we are using Valgrind, we have to compensate for the fact that
    // Valgrind thinks all the output of SSL_read is undefined.
    // (This probably comes from SSL's use of uninitialized memory as part
    // of its key-generation algorithm.)
    VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(&bytesRead, sizeof (bytesRead)));
    if (bytesRead > 0)
    {
       VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(buffer, bytesRead));
    }
#endif /* VALGRIND_MAKE_READABLE */

    return(bytesRead);
}

int OsSSLConnectionSocket::read(char* buffer,
                             int bufferLength,
                             UtlString* ipAddress,
                             int* port)
{
    // Overide base class version as recvfrom does not
    // seem to return host info correctly for TCP
    // Use base class version without the remote host info
    int bytesRead = -1;

    bytesRead = SSL_read (mSSL, buffer, bufferLength);

#ifdef VALGRIND_MAKE_READABLE
    // If we are using Valgrind, we have to compensate for the fact that
    // Valgrind thinks all the output of SSL_read is undefined.
    // (This probably comes from SSL's use of uninitialized memory as part
    // of its key-generation algorithm.)
    VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(&bytesRead, sizeof (bytesRead)));
    if (bytesRead > 0)
    {
       VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(buffer, bytesRead));
    }
#endif /* VALGRIND_MAKE_READABLE */
    // Explicitly get the remote host info.
    getRemoteHostIp(ipAddress);
    *port = getRemoteHostPort();
    return(bytesRead);
}

// Because we have overided one read method, we
// must implement them all in OsSSLConnectionSocket or
// we end up hiding some of the methods.
int OsSSLConnectionSocket::read(char* buffer,
                            int bufferLength,
                            long waitMilliseconds)
{

    int bytesRead = -1;
    if(isReadyToRead(waitMilliseconds))
    {
        bytesRead = SSL_read (mSSL, buffer, bufferLength);
    }
#ifdef VALGRIND_MAKE_READABLE
    // If we are using Valgrind, we have to compensate for the fact that
    // Valgrind thinks all the output of SSL_read is undefined.
    // (This probably comes from SSL's use of uninitialized memory as part
    // of its key-generation algorithm.)
    VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(&bytesRead, sizeof (bytesRead)));
    if (bytesRead > 0)
    {
       VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(buffer, bytesRead));
    }
#endif /* VALGRIND_MAKE_READABLE */
    return(bytesRead);
}

/* ============================ ACCESSORS ================================= */
/* ============================ INQUIRY =================================== */
OsSocket::IpProtocolSocketType OsSSLConnectionSocket::getIpProtocol() const
{
    return(OsSocket::SSL_SOCKET);
}

/// Is this connection encrypted using TLS/SSL?
bool OsSSLConnectionSocket::isEncrypted() const
{
   return true;
}

/// Get any authenticated peer host names.
bool OsSSLConnectionSocket::peerIdentity( UtlSList* altNames
                                         ,UtlString* commonName
                                         ) const
{
   if (NOT_IDENTIFIED == mPeerIdentity)
   {
      // examine cert to get identity and cache the results
      mPeerIdentity = OsSSL::peerIdentity( mSSL, &mAltNames, &mCommonName )
         ? TRUSTED : UNTRUSTED;
      if ( TRUSTED == mPeerIdentity )
      {
         OsSysLog::add(FAC_SIP, PRI_INFO,
                       "OsSSLConnectionSocket::peerIdentity %p OsSSL returned trusted",
                       this);
      }
      else
      {
         OsSysLog::add(FAC_SIP, PRI_WARNING,
                       "OsSSLConnectionSocket::peerIdentity %p OsSSL returned NOT trusted",
                       this);
      }
   }

   /*
    * - true if the connection is TLS/SSL and the peer has presented
    *        a certificate signed by a trusted certificate authority
    * - false if not
    */
   if (commonName)
   {
      commonName->remove(0);
   }
   if (altNames)
   {
      altNames->destroyAll();
   }

   if (TRUSTED == mPeerIdentity)
   {
      if (commonName)
      {
         *commonName = mCommonName;
      }
      if (altNames)
      {
         UtlString* altName;
         UtlSListIterator names(mAltNames);
         while ( (altName = dynamic_cast<UtlString*>(names())) )
         {
            altNames->insert(new UtlString(*altName));
         }
      }
   }

   return TRUSTED == mPeerIdentity;
}

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

void OsSSLConnectionSocket::SSLInitSocket(int socket, long timeoutInSecs)
{
    if (mIsConnected)
    {
       int err = -1;

       // TODO: eventually this should allow for other SSL contexts...
       mSSL = OsSharedSSL::get()->getServerConnection();

       if (mSSL && (socketDescriptor > OS_INVALID_SOCKET_DESCRIPTOR))
       {
          SSL_set_fd (mSSL, socketDescriptor);

          err = SSL_connect(mSSL);
          if (err > 0)
          {
             OsSSL::logConnectParams(FAC_KERNEL, PRI_DEBUG,
                                     "OsSSLConnectionSocket",
                                     mSSL);
          }
          else
          {
             OsSSL::logError(FAC_KERNEL, PRI_ERR,
                             "OsSSLConnectionSocket SSL_connect failed: ",
                             SSL_get_error(mSSL, err));
             mIsConnected = FALSE;
             OsConnectionSocket::close();
             socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
          }
       }
       else
       {
          OsSysLog::add(FAC_KERNEL, PRI_DEBUG
                        , "OsSSLConnectionSocket bad parameters mSSL=%p,%d, closing socket..."
                        , mSSL, socketDescriptor);
          mIsConnected = FALSE;
          OsConnectionSocket::close();
          socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
       }
    }
    else
    {
       OsSysLog::add(FAC_KERNEL, PRI_ERR,
                     "OsSSLConnectionSocket::SSLInitSocket called on unconnected socket"
                     );
    }
}
/* ============================ FUNCTIONS ================================= */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: glshell.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: hr $ $Date: 2006-08-14 17:49:26 $
 *
 *  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
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _SFX_PRINTER_HXX //autogen
#include <sfx2/printer.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif
#ifndef _SFXSIDS_HRC //autogen
#include <sfx2/sfxsids.hrc>
#endif
#ifndef _SVX_SRCHITEM_HXX
#include <svx/srchitem.hxx>
#endif
#ifndef _SFXMACITEM_HXX
#include <svtools/macitem.hxx>
#endif
#ifndef _GLOSHDL_HXX
#include <gloshdl.hxx>
#endif

#include <svx/acorrcfg.hxx>
#include <sfx2/app.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/viewfrm.hxx>

#ifndef _UITOOL_HXX
#include <uitool.hxx>
#endif
#ifndef _WRTSH_HXX
#include <wrtsh.hxx>
#endif
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#ifndef _GLSHELL_HXX
#include <glshell.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _GLOSDOC_HXX
#include <glosdoc.hxx>
#endif
#ifndef _SHELLIO_HXX
#include <shellio.hxx>
#endif
#ifndef _INITUI_HXX
#include <initui.hxx>                   // fuer ::GetGlossaries()
#endif
#ifndef _CMDID_H
#include <cmdid.h>
#endif
#ifndef _SWERROR_H
#include <swerror.h>
#endif
#ifndef _MISC_HRC
#include <misc.hrc>
#endif

#define SwWebGlosDocShell
#define SwGlosDocShell
#ifndef _ITEMDEF_HXX
#include <itemdef.hxx>
#endif
#ifndef _SWSLOTS_HXX
#include <swslots.hxx>
#endif

SFX_IMPL_INTERFACE( SwGlosDocShell, SwDocShell, SW_RES(0) )
{
}

SFX_IMPL_INTERFACE( SwWebGlosDocShell, SwWebDocShell, SW_RES(0) )
{
}

TYPEINIT1( SwGlosDocShell, SwDocShell );
TYPEINIT1( SwWebGlosDocShell, SwWebDocShell );

void lcl_Execute( SwDocShell& rSh, SfxRequest& rReq )
{
    if ( rReq.GetSlot() == SID_SAVEDOC )
    {
        if( !rSh.HasName() )
        {
            rReq.SetReturnValue( SfxBoolItem( 0, rSh.Save() ) );
        }
        else
        {
            const SfxBoolItem* pRes = ( const SfxBoolItem* )
                                        rSh.ExecuteSlot( rReq,
                                        rSh.SfxObjectShell::GetInterface() );
            if( pRes->GetValue() )
                rSh.GetDoc()->ResetModified();
        }
    }
}

void lcl_GetState( SwDocShell& rSh, SfxItemSet& rSet )
{
    if( SFX_ITEM_AVAILABLE >= rSet.GetItemState( SID_SAVEDOC, FALSE ))
    {
        if( !rSh.GetDoc()->IsModified() )
            rSet.DisableItem( SID_SAVEDOC );
        else
            rSet.Put( SfxStringItem( SID_SAVEDOC, SW_RESSTR(STR_SAVE_GLOSSARY)));
    }
}

BOOL lcl_Save( SwWrtShell& rSh, const String& rGroupName,
                const String& rShortNm, const String& rLongNm )
{
    const SvxAutoCorrCfg* pCfg = SvxAutoCorrCfg::Get();
    SwTextBlocks * pBlock = ::GetGlossaries()->GetGroupDoc( rGroupName );

    SvxMacro aStart(aEmptyStr, aEmptyStr);
    SvxMacro aEnd(aEmptyStr, aEmptyStr);
    SwGlossaryHdl* pGlosHdl;

    pGlosHdl = rSh.GetView().GetGlosHdl();
    pGlosHdl->GetMacros( rShortNm, aStart, aEnd, pBlock );

    USHORT nRet = rSh.SaveGlossaryDoc( *pBlock, rLongNm, rShortNm,
                                pCfg->IsSaveRelFile(), pCfg->IsSaveRelNet(),
                                pBlock->IsOnlyTextBlock( rShortNm ) );

    if(aStart.GetMacName().Len() || aEnd.GetMacName().Len() )
    {
        SvxMacro* pStart = aStart.GetMacName().Len() ? &aStart : 0;
        SvxMacro* pEnd = aEnd.GetMacName().Len() ? &aEnd : 0;
        pGlosHdl->SetMacros( rShortNm, pStart, pEnd, pBlock );
    }

    rSh.EnterStdMode();
    if( USHRT_MAX != nRet )
        rSh.ResetModified();
    delete pBlock;
    return nRet != USHRT_MAX;
}

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

SwGlosDocShell::SwGlosDocShell( sal_Bool bNewShow)
    : bShow ( bNewShow )
    , SwDocShell( bShow ? SFX_CREATE_MODE_STANDARD : SFX_CREATE_MODE_INTERNAL )
{
    SetHelpId(SW_GLOSDOCSHELL);
}

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

SwGlosDocShell::~SwGlosDocShell(  )
{
}

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

void SwGlosDocShell::Execute( SfxRequest& rReq )
{
    ::lcl_Execute( *this, rReq );
}

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

void SwGlosDocShell::GetState( SfxItemSet& rSet )
{
    ::lcl_GetState( *this, rSet );
}

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

BOOL SwGlosDocShell::Save()
{
    // In case of an API object which holds this document, it is possible that the WrtShell is already
    // dead. For instance, if the doc is modified via this API object, and then, upon office shutdown,
    // the document's view is closed (by the SFX framework) _before_ the API object is release and
    // tries to save the doc, again.
    // 96380 - 2002-03-03 - fs@openoffice.org
    if ( GetWrtShell() )
        return ::lcl_Save( *GetWrtShell(), aGroupName, aShortName, aLongName );
    else
    {
        SetModified( FALSE );
        return FALSE;
    }
}

/**/

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

SwWebGlosDocShell::SwWebGlosDocShell()
    : SwWebDocShell( SFX_CREATE_MODE_STANDARD )
{
    SetHelpId(SW_WEBGLOSDOCSHELL);
}

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

SwWebGlosDocShell::~SwWebGlosDocShell(  )
{
}

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

void SwWebGlosDocShell::Execute( SfxRequest& rReq )
{
    ::lcl_Execute( *this, rReq );
}
/*--------------------------------------------------------------------
    Beschreibung:
 --------------------------------------------------------------------*/

void SwWebGlosDocShell::GetState( SfxItemSet& rSet )
{
    ::lcl_GetState( *this, rSet );
}

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

BOOL SwWebGlosDocShell::Save()
{
    // same comment as in SwGlosDocShell::Save - see there
    if ( GetWrtShell() )
        return ::lcl_Save( *GetWrtShell(), aGroupName, aShortName, aLongName );
    else
    {
        SetModified( FALSE );
        return FALSE;
    }
}

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

SV_IMPL_REF ( SwDocShell )

SwDocShellRef SwGlossaries::EditGroupDoc( const String& rGroup, const String& rShortName, BOOL bShow )
{
    SwDocShellRef xDocSh;

    SwTextBlocks* pGroup = GetGroupDoc( rGroup );
    if( pGroup && pGroup->GetCount() )
    {
        // erfrage welche View registriert ist. Im WebWriter gibts es keine
        // normale View
        USHORT nViewId = 0 != &SwView::Factory() ? 2 : 6;
        String sLongName = pGroup->GetLongName(pGroup->GetIndex( rShortName ));

        if( 6 == nViewId )
        {
            SwWebGlosDocShell* pDocSh = new SwWebGlosDocShell();
            xDocSh = pDocSh;
            pDocSh->DoInitNew( 0 );
            pDocSh->SetLongName( sLongName );
            pDocSh->SetShortName( rShortName);
            pDocSh->SetGroupName( rGroup );
        }
        else
        {
            SwGlosDocShell* pDocSh = new SwGlosDocShell(bShow);
            xDocSh = pDocSh;
            pDocSh->DoInitNew( 0 );
            pDocSh->SetLongName( sLongName );
            pDocSh->SetShortName( rShortName );
            pDocSh->SetGroupName( rGroup );
        }

        // Dokumenttitel setzen
        SfxViewFrame* pFrame = SfxViewFrame::CreateViewFrame( *xDocSh, nViewId, !bShow );
        String aDocTitle(SW_RES( STR_GLOSSARY ));
        aDocTitle += ' ';
        aDocTitle += sLongName;

        BOOL bDoesUndo = xDocSh->GetDoc()->DoesUndo();
        xDocSh->GetDoc()->DoUndo( FALSE );

        xDocSh->GetWrtShell()->InsertGlossary( *pGroup, rShortName );
        if( !xDocSh->GetDoc()->getPrinter( false ) )
        {
            // wir erzeugen einen default SfxPrinter.
            // Das ItemSet wird vom Sfx geloescht!
            SfxItemSet *pSet = new SfxItemSet( xDocSh->GetDoc()->GetAttrPool(),
                        FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER,
                        SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
                        SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
                        0 );
            SfxPrinter* pPrinter = new SfxPrinter( pSet );

            // und haengen ihn ans Dokument.
            xDocSh->GetDoc()->setPrinter( pPrinter, true, true );
        }

        xDocSh->SetTitle( aDocTitle );
        xDocSh->GetDoc()->DoUndo( bDoesUndo );
        xDocSh->GetDoc()->ResetModified();
        if ( bShow )
            pFrame->GetFrame()->Appear();

        delete pGroup;
    }
    return xDocSh;
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.14.2); FILE MERGED 2006/09/01 17:53:14 kaib 1.14.2.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: glshell.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 23:07:18 $
 *
 *  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 _LIST_HXX //autogen
#include <tools/list.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _SFX_PRINTER_HXX //autogen
#include <sfx2/printer.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif
#ifndef _SFXSIDS_HRC //autogen
#include <sfx2/sfxsids.hrc>
#endif
#ifndef _SVX_SRCHITEM_HXX
#include <svx/srchitem.hxx>
#endif
#ifndef _SFXMACITEM_HXX
#include <svtools/macitem.hxx>
#endif
#ifndef _GLOSHDL_HXX
#include <gloshdl.hxx>
#endif

#include <svx/acorrcfg.hxx>
#include <sfx2/app.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/viewfrm.hxx>

#ifndef _UITOOL_HXX
#include <uitool.hxx>
#endif
#ifndef _WRTSH_HXX
#include <wrtsh.hxx>
#endif
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#ifndef _GLSHELL_HXX
#include <glshell.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _GLOSDOC_HXX
#include <glosdoc.hxx>
#endif
#ifndef _SHELLIO_HXX
#include <shellio.hxx>
#endif
#ifndef _INITUI_HXX
#include <initui.hxx>                   // fuer ::GetGlossaries()
#endif
#ifndef _CMDID_H
#include <cmdid.h>
#endif
#ifndef _SWERROR_H
#include <swerror.h>
#endif
#ifndef _MISC_HRC
#include <misc.hrc>
#endif

#define SwWebGlosDocShell
#define SwGlosDocShell
#ifndef _ITEMDEF_HXX
#include <itemdef.hxx>
#endif
#ifndef _SWSLOTS_HXX
#include <swslots.hxx>
#endif

SFX_IMPL_INTERFACE( SwGlosDocShell, SwDocShell, SW_RES(0) )
{
}

SFX_IMPL_INTERFACE( SwWebGlosDocShell, SwWebDocShell, SW_RES(0) )
{
}

TYPEINIT1( SwGlosDocShell, SwDocShell );
TYPEINIT1( SwWebGlosDocShell, SwWebDocShell );

void lcl_Execute( SwDocShell& rSh, SfxRequest& rReq )
{
    if ( rReq.GetSlot() == SID_SAVEDOC )
    {
        if( !rSh.HasName() )
        {
            rReq.SetReturnValue( SfxBoolItem( 0, rSh.Save() ) );
        }
        else
        {
            const SfxBoolItem* pRes = ( const SfxBoolItem* )
                                        rSh.ExecuteSlot( rReq,
                                        rSh.SfxObjectShell::GetInterface() );
            if( pRes->GetValue() )
                rSh.GetDoc()->ResetModified();
        }
    }
}

void lcl_GetState( SwDocShell& rSh, SfxItemSet& rSet )
{
    if( SFX_ITEM_AVAILABLE >= rSet.GetItemState( SID_SAVEDOC, FALSE ))
    {
        if( !rSh.GetDoc()->IsModified() )
            rSet.DisableItem( SID_SAVEDOC );
        else
            rSet.Put( SfxStringItem( SID_SAVEDOC, SW_RESSTR(STR_SAVE_GLOSSARY)));
    }
}

BOOL lcl_Save( SwWrtShell& rSh, const String& rGroupName,
                const String& rShortNm, const String& rLongNm )
{
    const SvxAutoCorrCfg* pCfg = SvxAutoCorrCfg::Get();
    SwTextBlocks * pBlock = ::GetGlossaries()->GetGroupDoc( rGroupName );

    SvxMacro aStart(aEmptyStr, aEmptyStr);
    SvxMacro aEnd(aEmptyStr, aEmptyStr);
    SwGlossaryHdl* pGlosHdl;

    pGlosHdl = rSh.GetView().GetGlosHdl();
    pGlosHdl->GetMacros( rShortNm, aStart, aEnd, pBlock );

    USHORT nRet = rSh.SaveGlossaryDoc( *pBlock, rLongNm, rShortNm,
                                pCfg->IsSaveRelFile(), pCfg->IsSaveRelNet(),
                                pBlock->IsOnlyTextBlock( rShortNm ) );

    if(aStart.GetMacName().Len() || aEnd.GetMacName().Len() )
    {
        SvxMacro* pStart = aStart.GetMacName().Len() ? &aStart : 0;
        SvxMacro* pEnd = aEnd.GetMacName().Len() ? &aEnd : 0;
        pGlosHdl->SetMacros( rShortNm, pStart, pEnd, pBlock );
    }

    rSh.EnterStdMode();
    if( USHRT_MAX != nRet )
        rSh.ResetModified();
    delete pBlock;
    return nRet != USHRT_MAX;
}

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

SwGlosDocShell::SwGlosDocShell( sal_Bool bNewShow)
    : bShow ( bNewShow )
    , SwDocShell( bShow ? SFX_CREATE_MODE_STANDARD : SFX_CREATE_MODE_INTERNAL )
{
    SetHelpId(SW_GLOSDOCSHELL);
}

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

SwGlosDocShell::~SwGlosDocShell(  )
{
}

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

void SwGlosDocShell::Execute( SfxRequest& rReq )
{
    ::lcl_Execute( *this, rReq );
}

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

void SwGlosDocShell::GetState( SfxItemSet& rSet )
{
    ::lcl_GetState( *this, rSet );
}

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

BOOL SwGlosDocShell::Save()
{
    // In case of an API object which holds this document, it is possible that the WrtShell is already
    // dead. For instance, if the doc is modified via this API object, and then, upon office shutdown,
    // the document's view is closed (by the SFX framework) _before_ the API object is release and
    // tries to save the doc, again.
    // 96380 - 2002-03-03 - fs@openoffice.org
    if ( GetWrtShell() )
        return ::lcl_Save( *GetWrtShell(), aGroupName, aShortName, aLongName );
    else
    {
        SetModified( FALSE );
        return FALSE;
    }
}

/**/

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

SwWebGlosDocShell::SwWebGlosDocShell()
    : SwWebDocShell( SFX_CREATE_MODE_STANDARD )
{
    SetHelpId(SW_WEBGLOSDOCSHELL);
}

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

SwWebGlosDocShell::~SwWebGlosDocShell(  )
{
}

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

void SwWebGlosDocShell::Execute( SfxRequest& rReq )
{
    ::lcl_Execute( *this, rReq );
}
/*--------------------------------------------------------------------
    Beschreibung:
 --------------------------------------------------------------------*/

void SwWebGlosDocShell::GetState( SfxItemSet& rSet )
{
    ::lcl_GetState( *this, rSet );
}

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

BOOL SwWebGlosDocShell::Save()
{
    // same comment as in SwGlosDocShell::Save - see there
    if ( GetWrtShell() )
        return ::lcl_Save( *GetWrtShell(), aGroupName, aShortName, aLongName );
    else
    {
        SetModified( FALSE );
        return FALSE;
    }
}

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

SV_IMPL_REF ( SwDocShell )

SwDocShellRef SwGlossaries::EditGroupDoc( const String& rGroup, const String& rShortName, BOOL bShow )
{
    SwDocShellRef xDocSh;

    SwTextBlocks* pGroup = GetGroupDoc( rGroup );
    if( pGroup && pGroup->GetCount() )
    {
        // erfrage welche View registriert ist. Im WebWriter gibts es keine
        // normale View
        USHORT nViewId = 0 != &SwView::Factory() ? 2 : 6;
        String sLongName = pGroup->GetLongName(pGroup->GetIndex( rShortName ));

        if( 6 == nViewId )
        {
            SwWebGlosDocShell* pDocSh = new SwWebGlosDocShell();
            xDocSh = pDocSh;
            pDocSh->DoInitNew( 0 );
            pDocSh->SetLongName( sLongName );
            pDocSh->SetShortName( rShortName);
            pDocSh->SetGroupName( rGroup );
        }
        else
        {
            SwGlosDocShell* pDocSh = new SwGlosDocShell(bShow);
            xDocSh = pDocSh;
            pDocSh->DoInitNew( 0 );
            pDocSh->SetLongName( sLongName );
            pDocSh->SetShortName( rShortName );
            pDocSh->SetGroupName( rGroup );
        }

        // Dokumenttitel setzen
        SfxViewFrame* pFrame = SfxViewFrame::CreateViewFrame( *xDocSh, nViewId, !bShow );
        String aDocTitle(SW_RES( STR_GLOSSARY ));
        aDocTitle += ' ';
        aDocTitle += sLongName;

        BOOL bDoesUndo = xDocSh->GetDoc()->DoesUndo();
        xDocSh->GetDoc()->DoUndo( FALSE );

        xDocSh->GetWrtShell()->InsertGlossary( *pGroup, rShortName );
        if( !xDocSh->GetDoc()->getPrinter( false ) )
        {
            // wir erzeugen einen default SfxPrinter.
            // Das ItemSet wird vom Sfx geloescht!
            SfxItemSet *pSet = new SfxItemSet( xDocSh->GetDoc()->GetAttrPool(),
                        FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER,
                        SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
                        SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
                        0 );
            SfxPrinter* pPrinter = new SfxPrinter( pSet );

            // und haengen ihn ans Dokument.
            xDocSh->GetDoc()->setPrinter( pPrinter, true, true );
        }

        xDocSh->SetTitle( aDocTitle );
        xDocSh->GetDoc()->DoUndo( bDoesUndo );
        xDocSh->GetDoc()->ResetModified();
        if ( bShow )
            pFrame->GetFrame()->Appear();

        delete pGroup;
    }
    return xDocSh;
}

<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_INTERFACES_HH
#define DUNE_GDT_OPERATORS_INTERFACES_HH

#include <type_traits>

#include <dune/common/dynmatrix.hh>
#include <dune/common/fvector.hh>

#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/la/container/pattern.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/common/configuration.hh>

#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/discretefunction/default.hh>

#include "../products/interfaces.hh"

namespace Dune {
namespace GDT {

template <class Traits>
class OperatorInterface : public ProductInterface<Traits>
{
  typedef ProductInterface<Traits> BaseType;

public:
  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;

  template <class SourceType, class RangeType>
  void apply(const SourceType& source, RangeType& range) const
  {
    CHECK_CRTP(this->as_imp(*this).apply(source, range));
    return this->as_imp(*this).apply(source, range);
  }

  template <class S, class R>
  FieldType apply2(const Stuff::LA::VectorInterface<S, FieldType>& source,
                   const Stuff::LA::VectorInterface<R, FieldType>& range) const
  {
    auto tmp = range.copy();
    apply(source.as_imp(source), tmp);
    return range.dot(tmp);
  } // ... apply2(...)

  template <class SS, class SV, class RS, class RV>
  FieldType apply2(const ConstDiscreteFunction<SS, SV>& source, const ConstDiscreteFunction<RS, RV>& range) const
  {
    auto tmp_vector = range.copy();
    DiscreteFunction<RS, RV> tmp_function(range.space(), tmp_vector);
    apply(source, tmp_function);
    return range.vector().dot(tmp_vector);
  }
}; // class OperatorInterface

template <class Traits>
class LocalizableOperatorInterface : public Stuff::CRTPInterface<LocalizableOperatorInterface<Traits>, Traits>
{
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::SourceType SourceType;
  typedef typename Traits::RangeType RangeType;
  typedef typename Traits::FieldType FieldType;

  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridViewType::dimension;

private:
  static_assert(std::is_base_of<Stuff::IsLocalizableFunction, SourceType>::value,
                "SourceType has to be derived from Stuff::IsLocalizableFunction!");
  static_assert(std::is_base_of<DiscreteFunction<typename RangeType::SpaceType, typename RangeType::VectorType>,
                                RangeType>::value,
                "RangeType has to be derived from DiscreteFunction!");
  static_assert(std::is_same<typename SourceType::EntityType, EntityType>::value,
                "The EntityType of SourceType and GridViewType have to match!");
  static_assert(std::is_same<typename RangeType::EntityType, EntityType>::value,
                "The EntityType of RangeType and GridViewType have to match!");
  static_assert(std::is_same<typename SourceType::DomainFieldType, DomainFieldType>::value,
                "The DomainFieldType of SourceType and GridViewType have to match!");
  static_assert(std::is_same<typename RangeType::DomainFieldType, DomainFieldType>::value,
                "The DomainFieldType of RangeType and GridViewType have to match!");
  static_assert(SourceType::dimDomain == dimDomain, "The dimDomain of SourceType and GridViewType have to match!");
  static_assert(RangeType::dimDomain == dimDomain, "The dimDomain of RangeType and GridViewType have to match!");

public:
  const GridViewType& grid_view() const
  {
    CHECK_CRTP(this->as_imp(*this).grid_view());
    return this->as_imp(*this).grid_view();
  }

  const SourceType& source() const
  {
    CHECK_CRTP(this->as_imp(*this).source());
    return this->as_imp(*this).source();
  }

  const RangeType& range() const
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  RangeType& range()
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  void apply()
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).apply());
  }
}; // class LocalizableOperatorInterface

template <class Traits>
class AssemblableOperatorInterface : public AssemblableProductInterface<Traits>
{
  typedef AssemblableProductInterface<Traits> BaseType;

public:
  typedef typename BaseType::derived_type derived_type;

  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;
  using typename BaseType::SourceSpaceType;
  using typename BaseType::RangeSpaceType;
  using typename BaseType::MatrixType;

  using typename BaseType::EntityType;
  using typename BaseType::DomainFieldType;
  using BaseType::dimDomain;
  using typename BaseType::PatternType;

  template <class S, class R>
  void apply(const Stuff::LA::VectorInterface<S, DomainFieldType>& source,
             Stuff::LA::VectorInterface<R, FieldType>& range)
  {
    CHECK_CRTP(this->as_imp().apply(source.as_imp(), range.as_imp()));
    return this->as_imp().apply(source.as_imp(), range.as_imp());
  }

  template <class S, class R>
  void apply(const ConstDiscreteFunction<SourceSpaceType, S>& source, ConstDiscreteFunction<RangeSpaceType, R>& range)
  {
    apply(source.vector(), range.vector());
  }

  static std::vector<std::string> invert_options()
  {
    return derived_type::invert_options();
  }

  static Stuff::Common::Configuration invert_options(const std::string& type)
  {
    return derived_type::invert_options(type);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     const Stuff::LA::VectorInterface<S, FieldType>& source)
  {
    apply_inverse(range, source, invert_options()[0]);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     Stuff::LA::VectorInterface<S, FieldType>& source, const std::string& opt)
  {
    apply_inverse(range, source, invert_options(opt));
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     Stuff::LA::VectorInterface<S, FieldType>& source, const Stuff::Common::Configuration& opts)
  {
    CHECK_CRTP(this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts));
    return this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts);
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source)
  {
    apply_inverse(range.vector(), source.vector());
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source, const std::string& opt)
  {
    apply_inverse(range.vector(), source.vector(), opt);
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source, const Stuff::Common::Configuration& opts)
  {
    apply_inverse(range.vector(), source.vector(), opts);
  }

  template <class R, class S, class P>
  FieldType apply2(const Stuff::LA::VectorInterface<R, FieldType>& range,
                   const Stuff::LA::VectorInterface<S, FieldType>& source,
                   const AssemblableProductInterface<P>& product)
  {
    auto tmp = range.copy();
    apply(source, tmp);
    return product.apply2(tmp, source);
  }

  template <class R, class S>
  FieldType apply2(const Stuff::LA::VectorInterface<R, FieldType>& range,
                   const Stuff::LA::VectorInterface<S, FieldType>& source)
  {
    this->assemble();
    auto tmp = range.copy();
    this->matrix().mv(source.as_imp(), tmp);
    return range.dot(tmp);
  }

  template <class S, class R>
  FieldType apply2(const ConstDiscreteFunction<SourceSpaceType, S>& source,
                   const ConstDiscreteFunction<RangeSpaceType, R>& range)
  {
    return apply2(range.vector(), source.vector());
  }
}; // class AssemblableOperatorInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_INTERFACES_HH
<commit_msg>[operators.interfaces] modernize<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_INTERFACES_HH
#define DUNE_GDT_OPERATORS_INTERFACES_HH

#include <type_traits>

#include <dune/common/dynmatrix.hh>
#include <dune/common/fvector.hh>

#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/la/container/pattern.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/common/configuration.hh>

#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/discretefunction/default.hh>

#include "../products/interfaces.hh"

namespace Dune {
namespace GDT {

template <class Traits>
class OperatorInterface : public ProductInterface<Traits>
{
  typedef ProductInterface<Traits> BaseType;

public:
  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;

  template <class SourceType, class RangeType>
  void apply(const SourceType& source, RangeType& range) const
  {
    CHECK_CRTP(this->as_imp(*this).apply(source, range));
    return this->as_imp(*this).apply(source, range);
  }

  template <class S, class R>
  FieldType apply2(const Stuff::LA::VectorInterface<S, FieldType>& source,
                   const Stuff::LA::VectorInterface<R, FieldType>& range) const
  {
    auto tmp = range.copy();
    apply(source.as_imp(source), tmp);
    return range.dot(tmp);
  } // ... apply2(...)

  template <class SS, class SV, class RS, class RV>
  FieldType apply2(const ConstDiscreteFunction<SS, SV>& source, const ConstDiscreteFunction<RS, RV>& range) const
  {
    auto tmp_vector = range.copy();
    DiscreteFunction<RS, RV> tmp_function(range.space(), tmp_vector);
    apply(source, tmp_function);
    return range.vector().dot(tmp_vector);
  }
}; // class OperatorInterface

template <class Traits>
class LocalizableOperatorInterface : public Stuff::CRTPInterface<LocalizableOperatorInterface<Traits>, Traits>
{
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::SourceType SourceType;
  typedef typename Traits::RangeType RangeType;
  typedef typename Traits::FieldType FieldType;

  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridViewType::dimension;

private:
  static_assert(Stuff::is_localizable_function<SourceType>::value,
                "SourceType has to be derived from Stuff::IsLocalizableFunction!");
  static_assert(is_discrete_function<RangeType>::value, "RangeType has to be derived from DiscreteFunction!");
  static_assert(std::is_same<typename SourceType::EntityType, EntityType>::value,
                "The EntityType of SourceType and GridViewType have to match!");
  static_assert(std::is_same<typename RangeType::EntityType, EntityType>::value,
                "The EntityType of RangeType and GridViewType have to match!");
  static_assert(std::is_same<typename SourceType::DomainFieldType, DomainFieldType>::value,
                "The DomainFieldType of SourceType and GridViewType have to match!");
  static_assert(std::is_same<typename RangeType::DomainFieldType, DomainFieldType>::value,
                "The DomainFieldType of RangeType and GridViewType have to match!");
  static_assert(SourceType::dimDomain == dimDomain, "The dimDomain of SourceType and GridViewType have to match!");
  static_assert(RangeType::dimDomain == dimDomain, "The dimDomain of RangeType and GridViewType have to match!");

public:
  const GridViewType& grid_view() const
  {
    CHECK_CRTP(this->as_imp(*this).grid_view());
    return this->as_imp(*this).grid_view();
  }

  const SourceType& source() const
  {
    CHECK_CRTP(this->as_imp(*this).source());
    return this->as_imp(*this).source();
  }

  const RangeType& range() const
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  RangeType& range()
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  void apply()
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).apply());
  }
}; // class LocalizableOperatorInterface

template <class Traits>
class AssemblableOperatorInterface : public AssemblableProductInterface<Traits>
{
  typedef AssemblableProductInterface<Traits> BaseType;

public:
  typedef typename BaseType::derived_type derived_type;

  using typename BaseType::FieldType;
  using typename BaseType::SourceSpaceType;
  using typename BaseType::RangeSpaceType;
  using typename BaseType::DomainFieldType;

  template <class S, class R>
  void apply(const Stuff::LA::VectorInterface<S, DomainFieldType>& source,
             Stuff::LA::VectorInterface<R, FieldType>& range)
  {
    CHECK_CRTP(this->as_imp().apply(source.as_imp(), range.as_imp()));
    return this->as_imp().apply(source.as_imp(), range.as_imp());
  }

  template <class S, class R>
  void apply(const ConstDiscreteFunction<SourceSpaceType, S>& source, ConstDiscreteFunction<RangeSpaceType, R>& range)
  {
    apply(source.vector(), range.vector());
  }

  static std::vector<std::string> invert_options()
  {
    return derived_type::invert_options();
  }

  static Stuff::Common::Configuration invert_options(const std::string& type)
  {
    return derived_type::invert_options(type);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     const Stuff::LA::VectorInterface<S, FieldType>& source)
  {
    apply_inverse(range, source, invert_options()[0]);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     Stuff::LA::VectorInterface<S, FieldType>& source, const std::string& opt)
  {
    apply_inverse(range, source, invert_options(opt));
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     Stuff::LA::VectorInterface<S, FieldType>& source, const Stuff::Common::Configuration& opts)
  {
    CHECK_CRTP(this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts));
    return this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts);
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source)
  {
    apply_inverse(range.vector(), source.vector());
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source, const std::string& opt)
  {
    apply_inverse(range.vector(), source.vector(), opt);
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source, const Stuff::Common::Configuration& opts)
  {
    apply_inverse(range.vector(), source.vector(), opts);
  }

  template <class R, class S, class P>
  FieldType apply2(const Stuff::LA::VectorInterface<R, FieldType>& range,
                   const Stuff::LA::VectorInterface<S, FieldType>& source,
                   const AssemblableProductInterface<P>& product)
  {
    auto tmp = range.copy();
    apply(source, tmp);
    return product.apply2(tmp, source);
  }

  template <class R, class S>
  FieldType apply2(const Stuff::LA::VectorInterface<R, FieldType>& range,
                   const Stuff::LA::VectorInterface<S, FieldType>& source)
  {
    this->assemble();
    auto tmp = range.copy();
    this->matrix().mv(source.as_imp(), tmp);
    return range.dot(tmp);
  }

  template <class S, class R>
  FieldType apply2(const ConstDiscreteFunction<SourceSpaceType, S>& source,
                   const ConstDiscreteFunction<RangeSpaceType, R>& range)
  {
    return apply2(range.vector(), source.vector());
  }
}; // class AssemblableOperatorInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_INTERFACES_HH
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_INTERFACES_HH
#define DUNE_GDT_OPERATORS_INTERFACES_HH

#include <type_traits>

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/dynmatrix.hh>
# include <dune/common/fvector.hh>
#include <dune/stuff/common/reenable_warnings.hh>

#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/la/container/pattern.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/common/configuration.hh>

#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/discretefunction/default.hh>

#include "../products/interfaces.hh"

namespace Dune {
namespace GDT {

template< class Traits >
class OperatorInterface
  : public ProductInterface< Traits >
{
  typedef ProductInterface< Traits > BaseType;
public:
  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;

  template< class SourceType, class RangeType >
  void apply(const SourceType& source, RangeType& range) const
  {
    CHECK_CRTP(this->as_imp(*this).apply(source, range));
    return this->as_imp(*this).apply(source, range);
  }

  template< class S, class R >
  FieldType apply2(const Stuff::LA::VectorInterface< S, FieldType >& source,
                   const Stuff::LA::VectorInterface< R, FieldType >& range) const
  {
    auto tmp = range.copy();
    apply(source.as_imp(source), tmp);
    return range.dot(tmp);
  } // ... apply2(...)

  template< class SS, class SV, class RS, class RV >
  FieldType apply2(const ConstDiscreteFunction< SS, SV >& source, const ConstDiscreteFunction< RS, RV >& range) const
  {
    auto tmp_vector = range.copy();
    DiscreteFunction< RS, RV > tmp_function(range.space(), tmp_vector);
    apply(source, tmp_function);
    return range.vector().dot(tmp_vector);
  }
}; // class OperatorInterface

template< class Traits >
class LocalizableOperatorInterface
  : public Stuff::CRTPInterface< LocalizableOperatorInterface< Traits >, Traits >
{
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::SourceType   SourceType;
  typedef typename Traits::RangeType    RangeType;
  typedef typename Traits::FieldType    FieldType;

  typedef typename GridViewType::template Codim< 0 >::Entity  EntityType;
  typedef typename GridViewType::ctype                        DomainFieldType;
  static const unsigned int                                   dimDomain = GridViewType::dimension;

private:
  static_assert(std::is_base_of< Stuff::IsLocalizableFunction, SourceType >::value,
                "SourceType has to be derived from Stuff::IsLocalizableFunction!");
  static_assert(std::is_base_of< DiscreteFunction< typename RangeType::SpaceType, typename RangeType::VectorType >
                               , RangeType >::value,
                "RangeType has to be derived from DiscreteFunction!");
  static_assert(std::is_same< typename SourceType::EntityType, EntityType >::value,
                "The EntityType of SourceType and GridViewType have to match!");
  static_assert(std::is_same< typename RangeType::EntityType, EntityType >::value,
                "The EntityType of RangeType and GridViewType have to match!");
  static_assert(std::is_same< typename SourceType::DomainFieldType, DomainFieldType >::value,
                "The DomainFieldType of SourceType and GridViewType have to match!");
  static_assert(std::is_same< typename RangeType::DomainFieldType, DomainFieldType >::value,
                "The DomainFieldType of RangeType and GridViewType have to match!");
  static_assert(SourceType::dimDomain == dimDomain, "The dimDomain of SourceType and GridViewType have to match!");
  static_assert(RangeType::dimDomain == dimDomain, "The dimDomain of RangeType and GridViewType have to match!");

public:
  const GridViewType& grid_view() const
  {
    CHECK_CRTP(this->as_imp(*this).grid_view());
    return this->as_imp(*this).grid_view();
  }

  const SourceType& source() const
  {
    CHECK_CRTP(this->as_imp(*this).source());
    return this->as_imp(*this).source();
  }

  const RangeType& range() const
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  RangeType& range()
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  void apply()
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).apply());
  }
}; // class LocalizableOperatorInterface

template< class Traits >
class AssemblableOperatorInterface
  : public AssemblableProductInterface< Traits >
{
  typedef AssemblableProductInterface< Traits > BaseType;
public:
  typedef typename BaseType::derived_type derived_type;

  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;
  using typename BaseType::SourceSpaceType;
  using typename BaseType::RangeSpaceType;
  using typename BaseType::MatrixType;

  using typename BaseType::EntityType;
  using typename BaseType::DomainFieldType;
  using BaseType::dimDomain;
  using typename BaseType::PatternType;

  template< class S, class R >
  void apply(const Stuff::LA::VectorInterface< S, DomainFieldType >& source,
             Stuff::LA::VectorInterface< R, FieldType >& range)
  {
    CHECK_CRTP(this->as_imp(*this).apply(source.as_imp(source), range.as_imp(range)));
    return this->as_imp(*this).apply(source.as_imp(source), range.as_imp(range));
  }

  template< class S, class R >
  void apply(const ConstDiscreteFunction< SourceSpaceType, S >& source,
             ConstDiscreteFunction< RangeSpaceType, R >& range)
  {
    apply(source.vector(), range.vector());
  }

  static std::vector< std::string > invert_options()
  {
    return derived_type::invert_options();
  }

  static Stuff::Common::Configuration invert_options(const std::string& type)
  {
    return derived_type::invert_options(type);
  }

  template< class R, class S >
  void apply_inverse(const Stuff::LA::VectorInterface< R, FieldType >& range,
                     const Stuff::LA::VectorInterface< S, FieldType >& source)
  {
    apply_inverse(range, source, invert_options()[0]);
  }

  template< class R, class S >
  void apply_inverse(const Stuff::LA::VectorInterface< R, FieldType >& range,
                     Stuff::LA::VectorInterface< S, FieldType >& source,
                     const std::string& opt)
  {
    apply_inverse(range, source, invert_options(opt));
  }

  template< class R, class S >
  void apply_inverse(const Stuff::LA::VectorInterface< R, FieldType >& range,
                     Stuff::LA::VectorInterface< S, FieldType >& source,
                     const Stuff::Common::Configuration& opts)
  {
    CHECK_CRTP(this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts));
    return this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts);
  }

  template< class R, class S >
  void apply_inverse(const ConstDiscreteFunction< SourceSpaceType, R >& range,
                     ConstDiscreteFunction< RangeSpaceType, S >& source)
  {
    apply_inverse(range.vector(), source.vector());
  }

  template< class R, class S >
  void apply_inverse(const ConstDiscreteFunction< SourceSpaceType, R >& range,
                     ConstDiscreteFunction< RangeSpaceType, S >& source,
                     const std::string& opt)
  {
    apply_inverse(range.vector(), source.vector(), opt);
  }

  template< class R, class S >
  void apply_inverse(const ConstDiscreteFunction< SourceSpaceType, R >& range,
                     ConstDiscreteFunction< RangeSpaceType, S >& source,
                     const Stuff::Common::Configuration& opts)
  {
    apply_inverse(range.vector(), source.vector(), opts);
  }

  template< class R, class S, class P >
  FieldType apply2(const Stuff::LA::VectorInterface< R, FieldType >& range,
                   const Stuff::LA::VectorInterface< S, FieldType >& source,
                   const AssemblableProductInterface< P >& product)
  {
    apply(source, range);
    return product.apply2(range, source);
  }

  template< class R, class S, class P >
  FieldType apply2(const Stuff::LA::VectorInterface< R, FieldType >& range,
                   const Stuff::LA::VectorInterface< S, FieldType >& source)
  {
    this->assemble();
    auto tmp = range.copy();
    this->matrix().mv(source.as_imp(source), tmp);
    return range.dot(tmp);
  }

  template< class S, class R >
  FieldType apply2(const ConstDiscreteFunction< SourceSpaceType, S >& source,
                   const ConstDiscreteFunction< RangeSpaceType, R >& range)
  {
    return apply2(range.vector(), source.vector());
  }

}; // class AssemblableOperatorInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_INTERFACES_HH
<commit_msg>[operators.interfaces] fix apply2 implementations<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_INTERFACES_HH
#define DUNE_GDT_OPERATORS_INTERFACES_HH

#include <type_traits>

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/dynmatrix.hh>
# include <dune/common/fvector.hh>
#include <dune/stuff/common/reenable_warnings.hh>

#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/la/container/pattern.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/common/configuration.hh>

#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/discretefunction/default.hh>

#include "../products/interfaces.hh"

namespace Dune {
namespace GDT {

template< class Traits >
class OperatorInterface
  : public ProductInterface< Traits >
{
  typedef ProductInterface< Traits > BaseType;
public:
  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;

  template< class SourceType, class RangeType >
  void apply(const SourceType& source, RangeType& range) const
  {
    CHECK_CRTP(this->as_imp(*this).apply(source, range));
    return this->as_imp(*this).apply(source, range);
  }

  template< class S, class R >
  FieldType apply2(const Stuff::LA::VectorInterface< S, FieldType >& source,
                   const Stuff::LA::VectorInterface< R, FieldType >& range) const
  {
    auto tmp = range.copy();
    apply(source.as_imp(source), tmp);
    return range.dot(tmp);
  } // ... apply2(...)

  template< class SS, class SV, class RS, class RV >
  FieldType apply2(const ConstDiscreteFunction< SS, SV >& source, const ConstDiscreteFunction< RS, RV >& range) const
  {
    auto tmp_vector = range.copy();
    DiscreteFunction< RS, RV > tmp_function(range.space(), tmp_vector);
    apply(source, tmp_function);
    return range.vector().dot(tmp_vector);
  }
}; // class OperatorInterface

template< class Traits >
class LocalizableOperatorInterface
  : public Stuff::CRTPInterface< LocalizableOperatorInterface< Traits >, Traits >
{
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::SourceType   SourceType;
  typedef typename Traits::RangeType    RangeType;
  typedef typename Traits::FieldType    FieldType;

  typedef typename GridViewType::template Codim< 0 >::Entity  EntityType;
  typedef typename GridViewType::ctype                        DomainFieldType;
  static const unsigned int                                   dimDomain = GridViewType::dimension;

private:
  static_assert(std::is_base_of< Stuff::IsLocalizableFunction, SourceType >::value,
                "SourceType has to be derived from Stuff::IsLocalizableFunction!");
  static_assert(std::is_base_of< DiscreteFunction< typename RangeType::SpaceType, typename RangeType::VectorType >
                               , RangeType >::value,
                "RangeType has to be derived from DiscreteFunction!");
  static_assert(std::is_same< typename SourceType::EntityType, EntityType >::value,
                "The EntityType of SourceType and GridViewType have to match!");
  static_assert(std::is_same< typename RangeType::EntityType, EntityType >::value,
                "The EntityType of RangeType and GridViewType have to match!");
  static_assert(std::is_same< typename SourceType::DomainFieldType, DomainFieldType >::value,
                "The DomainFieldType of SourceType and GridViewType have to match!");
  static_assert(std::is_same< typename RangeType::DomainFieldType, DomainFieldType >::value,
                "The DomainFieldType of RangeType and GridViewType have to match!");
  static_assert(SourceType::dimDomain == dimDomain, "The dimDomain of SourceType and GridViewType have to match!");
  static_assert(RangeType::dimDomain == dimDomain, "The dimDomain of RangeType and GridViewType have to match!");

public:
  const GridViewType& grid_view() const
  {
    CHECK_CRTP(this->as_imp(*this).grid_view());
    return this->as_imp(*this).grid_view();
  }

  const SourceType& source() const
  {
    CHECK_CRTP(this->as_imp(*this).source());
    return this->as_imp(*this).source();
  }

  const RangeType& range() const
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  RangeType& range()
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  void apply()
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).apply());
  }
}; // class LocalizableOperatorInterface

template< class Traits >
class AssemblableOperatorInterface
  : public AssemblableProductInterface< Traits >
{
  typedef AssemblableProductInterface< Traits > BaseType;
public:
  typedef typename BaseType::derived_type derived_type;

  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;
  using typename BaseType::SourceSpaceType;
  using typename BaseType::RangeSpaceType;
  using typename BaseType::MatrixType;

  using typename BaseType::EntityType;
  using typename BaseType::DomainFieldType;
  using BaseType::dimDomain;
  using typename BaseType::PatternType;

  template< class S, class R >
  void apply(const Stuff::LA::VectorInterface< S, DomainFieldType >& source,
             Stuff::LA::VectorInterface< R, FieldType >& range)
  {
    CHECK_CRTP(this->as_imp(*this).apply(source.as_imp(source), range.as_imp(range)));
    return this->as_imp(*this).apply(source.as_imp(source), range.as_imp(range));
  }

  template< class S, class R >
  void apply(const ConstDiscreteFunction< SourceSpaceType, S >& source,
             ConstDiscreteFunction< RangeSpaceType, R >& range)
  {
    apply(source.vector(), range.vector());
  }

  static std::vector< std::string > invert_options()
  {
    return derived_type::invert_options();
  }

  static Stuff::Common::Configuration invert_options(const std::string& type)
  {
    return derived_type::invert_options(type);
  }

  template< class R, class S >
  void apply_inverse(const Stuff::LA::VectorInterface< R, FieldType >& range,
                     const Stuff::LA::VectorInterface< S, FieldType >& source)
  {
    apply_inverse(range, source, invert_options()[0]);
  }

  template< class R, class S >
  void apply_inverse(const Stuff::LA::VectorInterface< R, FieldType >& range,
                     Stuff::LA::VectorInterface< S, FieldType >& source,
                     const std::string& opt)
  {
    apply_inverse(range, source, invert_options(opt));
  }

  template< class R, class S >
  void apply_inverse(const Stuff::LA::VectorInterface< R, FieldType >& range,
                     Stuff::LA::VectorInterface< S, FieldType >& source,
                     const Stuff::Common::Configuration& opts)
  {
    CHECK_CRTP(this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts));
    return this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts);
  }

  template< class R, class S >
  void apply_inverse(const ConstDiscreteFunction< SourceSpaceType, R >& range,
                     ConstDiscreteFunction< RangeSpaceType, S >& source)
  {
    apply_inverse(range.vector(), source.vector());
  }

  template< class R, class S >
  void apply_inverse(const ConstDiscreteFunction< SourceSpaceType, R >& range,
                     ConstDiscreteFunction< RangeSpaceType, S >& source,
                     const std::string& opt)
  {
    apply_inverse(range.vector(), source.vector(), opt);
  }

  template< class R, class S >
  void apply_inverse(const ConstDiscreteFunction< SourceSpaceType, R >& range,
                     ConstDiscreteFunction< RangeSpaceType, S >& source,
                     const Stuff::Common::Configuration& opts)
  {
    apply_inverse(range.vector(), source.vector(), opts);
  }

  template< class R, class S, class P >
  FieldType apply2(const Stuff::LA::VectorInterface< R, FieldType >& range,
                   const Stuff::LA::VectorInterface< S, FieldType >& source,
                   const AssemblableProductInterface< P >& product)
  {
    auto tmp = range.copy();
    apply(source, tmp);
    return product.apply2(tmp, source);
  }

  template< class R, class S >
  FieldType apply2(const Stuff::LA::VectorInterface< R, FieldType >& range,
                   const Stuff::LA::VectorInterface< S, FieldType >& source)
  {
    this->assemble();
    auto tmp = range.copy();
    this->matrix().mv(source.as_imp(), tmp);
    return range.dot(tmp);
  }

  template< class S, class R >
  FieldType apply2(const ConstDiscreteFunction< SourceSpaceType, S >& source,
                   const ConstDiscreteFunction< RangeSpaceType, R >& range)
  {
    return apply2(range.vector(), source.vector());
  }
}; // class AssemblableOperatorInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_INTERFACES_HH
<|endoftext|>