<commit_before>/**
 * search.tcc -
 * @author: Jonathan Beard
 * @version: Thu Jun 19 14:07:49 2014
 *
 * Copyright 2014 Jonathan Beard
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef _SEARCH_TCC_
#define _SEARCH_TCC_  1
#include <cassert>
#include <cstring>
#include <vector>
#include <functional>
#include <cmath>
#include <sstream>
#include <fstream>
#include <thread>
#include <utility>
#include <algorithm>

#include "ringbuffer.tcc"

enum SearchAlgorithm
{
   RabinKarp,
   KnuthMorrisPratt,
   Automata
};

#define CHUNKSIZE 1024

struct Chunk
{
   Chunk() : start_position( 0 ),
             length( 0 )
   {
      std::memset( chunk, '\0', CHUNKSIZE );
   }

   Chunk( const Chunk &other ) : start_position( other.start_position ),
                                 length( other.length )
   {
      std::strncpy( chunk, other.chunk, CHUNKSIZE );
   }

   void operator = ( const Chunk &other )
   {
      start_position = other.start_position;
      length         = other.length;
      std::strncpy( chunk, other.chunk, CHUNKSIZE );
   }

   size_t start_position;
   size_t length;
   char   chunk[ CHUNKSIZE ];
};

typedef size_t Hit;

typedef RingBuffer< Chunk > InputBuffer;
typedef RingBuffer< Hit   > OutputBuffer;

template < size_t THREADS,
           size_t BUFFSIZE = 100 > class Search
{
public:
   Search()          = delete;
   virtual ~Search() = delete;

   template< SearchAlgorithm algorithm >
   static void search( const std::string           filename,
                       const std::string           search_term,
                       std::vector< Hit >  &hits )
   {

      std::array< std::thread*,  THREADS + 1 > thread_pool;
      std::array< InputBuffer*,  THREADS > input_buffer;
      std::array< OutputBuffer*, THREADS > output_buffer;

      /** allocate buffers **/
      for( size_t buff_id( 0 ); buff_id < THREADS; buff_id++ )
      {
         input_buffer  [  buff_id ] = new InputBuffer( BUFFSIZE );
         output_buffer [ buff_id  ] = new OutputBuffer( BUFFSIZE );
      }

      /** allocate consumer thread **/
      thread_pool[ THREADS ] = new std::thread( consumer_function,
                                                std::ref( output_buffer ),
                                                std::ref( hits ) );

      /** get input file **/
      std::ifstream file_input( filename, std::ifstream::binary );
      if( ! file_input.is_open() )
      {
         std::cerr << "Failed to open input file: " << filename << "\n";
         exit( EXIT_FAILURE );
      }

      /** declare iterations, needed to send stop signal **/
      int64_t  iterations( 0 );
      /**
       * get longest & smallest search term
       */
      const uint64_t search_term_length( search_term.length() );

      /**
       * get file length
       */
      file_input.seekg( 0, file_input.end );
      const auto file_length( file_input.tellg() );
      file_input.seekg( 0, file_input.beg );

      /** declare the worker thread function **/
      std::function< void( InputBuffer*, OutputBuffer* ) > worker_function;
      switch( algorithm )
      {
         case( RabinKarp ):
         {

            /**
             * calculate number of iterations needed to cover
             * entire file, last 1 is 2 b/c we need to subtract
             * one for the single byte overlap at the end of
             * the chunk
             */
            iterations =
               std::round( (double) file_length /
                           (double)( CHUNKSIZE - search_term_length - 1 ) );

            const uint64_t q( 33554393 );
            const uint64_t d( 0xff );
            /**
             * hash_function - used to compute initial hashes
             * for pattern values "p"
             * @param - line, full line to be hashed
             * @param - length, length from start ( 0 ) to be
             * hashed.  It is assumed that this function is only
             * used for the starts of lines.
             */
            auto hash_function = [&]( const std::string line,
                                      const size_t      length )
            {
               int64_t t( 0 );
               for( size_t i( 0 ); i < length; i++ )
               {
                  t = ( ( t * d ) + line[ i ] ) % q;
               }
               return( t );
            };

            /**
             * h - max radix power to subtract off in rolling hash
             */
            uint64_t h( 1 );
            /**
             * p - pattern hash value, only computed once and read
             * only after that
             */
            int64_t p(  hash_function( search_term, search_term_length ) );
            for( auto i( 1 ); i < search_term_length; i++ )
            {
               h = ( h * d ) % q;
            }

            auto rkfunction = [&]( Chunk &chunk, std::vector< Hit > &hits )
            {
               /**
                * here's the game plan:
                * 1) the thread shared patterns "p" are stored in a globally
                *    accessible variable "p" as uin64_t values.
                * 2) the max radix value to subtract off is stored for each
                *    pattern length in "h".
                * 3) here we need to compute the initial hash for each length
                *    of pattern.
                * 4) then we have to keep track of when to stop for pattern,
                *    obviously the longest is first but the shorter ones
                */
               /**
                * start by calculating initial hash values for line for each
                * of the pattern lengths, might be just as easy to "roll"
                * different lengths, but this seems like it might be a bit
                * faster to just keep |search_terms| hash values for each
                * pattern.
                */
               uint64_t t( hash_function( chunk.chunk,
                                          search_term_length ) );

               /** increment var for do loop below **/
               size_t s( 0 );
               do{
                  if( p == t )
                  {
                     hits.push_back( s + chunk.start_position );
                  }
                  /** calc new offsets **/
                  const auto remove_val( ( chunk.chunk[ s ] * h ) % q );
                  t = ( t + (d * q )- remove_val ) % q;
                  t = ( d * t ) % q;
                  t = ( t + chunk.chunk[ s + search_term_length ] ) % q;
                  s++;
               }while( s <= ( CHUNKSIZE - search_term_length ) );
            };
            /** assign the worker funciton for the Rabin Karp algorithm **/
            worker_function =
               std::bind( worker_function_base,
                          std::placeholders::_1,
                          std::placeholders::_2,
                          std::ref( rkfunction ) );
         }
         break;
         default:
            assert( false );
      }

      for( size_t thread_id( 0 ); thread_id < THREADS; thread_id++ )
      {
         thread_pool[ thread_id ] = new std::thread( worker_function,
                                                     input_buffer[  thread_id ],
                                                     output_buffer[ thread_id ] );
      }

      size_t output_stream( 0 );
      while( file_input.good() )
      {
         /** input stream with reference to the worker thread **/
         auto *input_stream( input_buffer[ output_stream ] );
         Chunk &chunk( input_stream->allocate() );
         chunk.start_position = file_input.tellg();
         file_input.read( chunk.chunk, CHUNKSIZE );
         chunk.length = ( size_t )file_input.gcount();
         if( iterations-- > THREADS )
         {
            input_stream->push( RBSignal::NONE );
         }
         else
         {
            input_stream->push( RBSignal::RBEOF );
         }
         if( iterations )
         {
            file_input.seekg(
               (size_t) file_input.tellg() - search_term_length - 1 );
         }
         output_stream = ( output_stream + 1 ) % THREADS;
      }

      /**
       * buffer might already have exited, but it won't hurt
       * to send another signal to be sure.
       */
      for( InputBuffer *buff : input_buffer )
      {
         buff->send_signal( RBSignal::TERM );
      }

      /** end of file, wait for results **/
      for( std::thread *th : thread_pool )
      {
         th->join();
         delete( th );
         th = nullptr;
      }

      for( InputBuffer *buff : input_buffer )
      {
         delete( buff );
         buff = nullptr;
      }

      for( OutputBuffer *buff : output_buffer )
      {
         delete( buff );
         buff = nullptr;
      }

      file_input.close();
   }
private:

   static void worker_function_base( InputBuffer *input,
                                     OutputBuffer *output,
                                     std::function<
                                     void ( Chunk&,
                                            std::vector< Hit >& ) >
                                             search_function )
   {
      assert( input != nullptr );
      assert( output != nullptr );
      std::vector< Hit > local_hits;
      RBSignal signal( RBSignal::NONE );
      while( signal != RBSignal::RBEOF )
      {
         if( input->size() > 0 )
         {
            auto &chunk( input->peek( &signal ) );
            search_function( chunk, local_hits );
            if( local_hits.size() > 0 )
            {
               output->insert( local_hits.begin(), local_hits.end(), signal );
               local_hits.clear();
            }
            input->recycle();
         }
      }
      /** we're at the end of file, send term signal **/
      output->send_signal( RBSignal::TERM );
      return;
   }

   static void consumer_function( std::array< OutputBuffer*, THREADS > &input,
                                  std::vector< Hit >                &hits )
   {
      int sig_count( 0 );
      Hit hit;
      RBSignal sig( RBSignal::NONE );
      //auto data = []( std::array< OutputBuffer*, THREADS > &in )
      //{
      //   for( auto *buff : in )
      //   {
      //      if( buff->size() > 0 ) return( true );
      //   }
      //   return( false );
      //};

      while( sig_count  < THREADS  /* ||   data( input ) */)
      {
         for( auto *buff : input )
         {
            if( buff->size() > 0 )
            {
               buff->pop( hit, &sig );
               hits.push_back( hit );
               if( sig == RBSignal::RBEOF )
               {
                  sig_count++;
               }
            }
            else if( buff->get_signal() == RBSignal::TERM )
            {
               sig_count++;
            }
         }
      }
      return;
   }
};
#endif /* END _SEARCH_TCC_ */
<commit_msg>broke the signalling logic, updating to fix<commit_after>/**
 * search.tcc -
 * @author: Jonathan Beard
 * @version: Thu Jun 19 14:07:49 2014
 *
 * Copyright 2014 Jonathan Beard
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef _SEARCH_TCC_
#define _SEARCH_TCC_  1
#include <cassert>
#include <cstring>
#include <vector>
#include <functional>
#include <cmath>
#include <sstream>
#include <fstream>
#include <thread>
#include <utility>
#include <algorithm>

#include "ringbuffer.tcc"

enum SearchAlgorithm
{
   RabinKarp,
   KnuthMorrisPratt,
   Automata
};

#define CHUNKSIZE 1024

struct Chunk
{
   Chunk() : start_position( 0 ),
             length( 0 )
   {
      std::memset( chunk, '\0', CHUNKSIZE );
   }

   Chunk( const Chunk &other ) : start_position( other.start_position ),
                                 length( other.length )
   {
      std::strncpy( chunk, other.chunk, CHUNKSIZE );
   }

   void operator = ( const Chunk &other )
   {
      start_position = other.start_position;
      length         = other.length;
      std::strncpy( chunk, other.chunk, CHUNKSIZE );
   }

   size_t start_position;
   size_t length;
   char   chunk[ CHUNKSIZE ];
};

typedef size_t Hit;

typedef RingBuffer< Chunk > InputBuffer;
typedef RingBuffer< Hit   > OutputBuffer;

template < size_t THREADS,
           size_t BUFFSIZE = 100 > class Search
{
public:
   Search()          = delete;
   virtual ~Search() = delete;

   template< SearchAlgorithm algorithm >
   static void search( const std::string           filename,
                       const std::string           search_term,
                       std::vector< Hit >  &hits )
   {

      std::array< std::thread*,  THREADS + 1 > thread_pool;
      std::array< InputBuffer*,  THREADS > input_buffer;
      std::array< OutputBuffer*, THREADS > output_buffer;

      /** allocate buffers **/
      for( size_t buff_id( 0 ); buff_id < THREADS; buff_id++ )
      {
         input_buffer  [  buff_id ] = new InputBuffer( BUFFSIZE );
         output_buffer [ buff_id  ] = new OutputBuffer( BUFFSIZE );
      }

      /** allocate consumer thread **/
      thread_pool[ THREADS ] = new std::thread( consumer_function,
                                                std::ref( output_buffer ),
                                                std::ref( hits ) );

      /** get input file **/
      std::ifstream file_input( filename, std::ifstream::binary );
      if( ! file_input.is_open() )
      {
         std::cerr << "Failed to open input file: " << filename << "\n";
         exit( EXIT_FAILURE );
      }

      /** declare iterations, needed to send stop signal **/
      int64_t  iterations( 0 );
      /**
       * get longest & smallest search term
       */
      const uint64_t search_term_length( search_term.length() );

      /**
       * get file length
       */
      file_input.seekg( 0, file_input.end );
      const auto file_length( file_input.tellg() );
      file_input.seekg( 0, file_input.beg );

      /** declare the worker thread function **/
      std::function< void( InputBuffer*, OutputBuffer* ) > worker_function;
      switch( algorithm )
      {
         case( RabinKarp ):
         {

            /**
             * calculate number of iterations needed to cover
             * entire file, last 1 is 2 b/c we need to subtract
             * one for the single byte overlap at the end of
             * the chunk
             */
            iterations =
               std::round( (double) file_length /
                           (double)( CHUNKSIZE - search_term_length - 1 ) );

            const uint64_t q( 33554393 );
            const uint64_t d( 0xff );
            /**
             * hash_function - used to compute initial hashes
             * for pattern values "p"
             * @param - line, full line to be hashed
             * @param - length, length from start ( 0 ) to be
             * hashed.  It is assumed that this function is only
             * used for the starts of lines.
             */
            auto hash_function = [&]( const std::string line,
                                      const size_t      length )
            {
               int64_t t( 0 );
               for( size_t i( 0 ); i < length; i++ )
               {
                  t = ( ( t * d ) + line[ i ] ) % q;
               }
               return( t );
            };

            /**
             * h - max radix power to subtract off in rolling hash
             */
            uint64_t h( 1 );
            /**
             * p - pattern hash value, only computed once and read
             * only after that
             */
            int64_t p(  hash_function( search_term, search_term_length ) );
            for( auto i( 1 ); i < search_term_length; i++ )
            {
               h = ( h * d ) % q;
            }

            auto rkfunction = [&]( Chunk &chunk, std::vector< Hit > &hits )
            {
               /**
                * here's the game plan:
                * 1) the thread shared patterns "p" are stored in a globally
                *    accessible variable "p" as uin64_t values.
                * 2) the max radix value to subtract off is stored for each
                *    pattern length in "h".
                * 3) here we need to compute the initial hash for each length
                *    of pattern.
                * 4) then we have to keep track of when to stop for pattern,
                *    obviously the longest is first but the shorter ones
                */
               /**
                * start by calculating initial hash values for line for each
                * of the pattern lengths, might be just as easy to "roll"
                * different lengths, but this seems like it might be a bit
                * faster to just keep |search_terms| hash values for each
                * pattern.
                */
               uint64_t t( hash_function( chunk.chunk,
                                          search_term_length ) );

               /** increment var for do loop below **/
               size_t s( 0 );
               do{
                  if( p == t )
                  {
                     hits.push_back( s + chunk.start_position );
                  }
                  /** calc new offsets **/
                  const auto remove_val( ( chunk.chunk[ s ] * h ) % q );
                  t = ( t + (d * q )- remove_val ) % q;
                  t = ( d * t ) % q;
                  t = ( t + chunk.chunk[ s + search_term_length ] ) % q;
                  s++;
               }while( s <= ( CHUNKSIZE - search_term_length ) );
            };
            /** assign the worker funciton for the Rabin Karp algorithm **/
            worker_function =
               std::bind( worker_function_base,
                          std::placeholders::_1,
                          std::placeholders::_2,
                          std::ref( rkfunction ) );
         }
         break;
         default:
            assert( false );
      }

      for( size_t thread_id( 0 ); thread_id < THREADS; thread_id++ )
      {
         thread_pool[ thread_id ] = new std::thread( worker_function,
                                                     input_buffer[  thread_id ],
                                                     output_buffer[ thread_id ] );
      }

      size_t output_stream( 0 );
      while( file_input.good() )
      {
         /** input stream with reference to the worker thread **/
         auto *input_stream( input_buffer[ output_stream ] );
         Chunk &chunk( input_stream->allocate() );
         chunk.start_position = file_input.tellg();
         file_input.read( chunk.chunk, CHUNKSIZE );
         chunk.length = ( size_t )file_input.gcount();
         if( iterations-- > THREADS )
         {
            input_stream->push( RBSignal::NONE );
         }
         else
         {
            input_stream->push( RBSignal::RBEOF );
         }
         if( iterations )
         {
            file_input.seekg(
               (size_t) file_input.tellg() - search_term_length - 1 );
         }
         output_stream = ( output_stream + 1 ) % THREADS;
      }

      /**
       * buffer might already have exited, but it won't hurt
       * to send another signal to be sure.
       */
      for( InputBuffer *buff : input_buffer )
      {
         buff->send_signal( RBSignal::TERM );
      }

      /** end of file, wait for results **/
      for( std::thread *th : thread_pool )
      {
         th->join();
         delete( th );
         th = nullptr;
      }

      for( InputBuffer *buff : input_buffer )
      {
         delete( buff );
         buff = nullptr;
      }

      for( OutputBuffer *buff : output_buffer )
      {
         delete( buff );
         buff = nullptr;
      }

      file_input.close();
   }
private:

   static void worker_function_base( InputBuffer *input,
                                     OutputBuffer *output,
                                     std::function<
                                     void ( Chunk&,
                                            std::vector< Hit >& ) >
                                             search_function )
   {
      assert( input != nullptr );
      assert( output != nullptr );
      std::vector< Hit > local_hits;
      RBSignal signal( RBSignal::NONE );
      while( signal != RBSignal::RBEOF && input->get_signal() != RBSignal::TERM )
      {
         if( input->size() > 0 )
         {
            auto &chunk( input->peek( &signal ) );
            search_function( chunk, local_hits );
            if( local_hits.size() > 0 )
            {
               output->insert( local_hits.begin(), local_hits.end(), signal );
               local_hits.clear();
            }
            input->recycle();
         }
      }
      output->send_signal( RBSignal::TERM );
      fprintf( stderr, "worker_exited\n" );
      return;
   }

   static void consumer_function( std::array< OutputBuffer*, THREADS > &input,
                                  std::vector< Hit >                &hits )
   {
      int sig_count( 0 );
      Hit hit;
      RBSignal sig( RBSignal::NONE );
      auto data = []( std::array< OutputBuffer*, THREADS > &in )
      {
         for( auto *buff : in )
         {
            if( buff->size() > 0 ) return( true );
         }
         return( false );
      };
      while( sig_count < THREADS )
      {
         for( auto *buff : input )
         {
            if( buff->size() > 0 )
            {
               buff->pop( hit, &sig );
               hits.push_back( hit );
            }
            if( buff->get_signal() == RBSignal::TERM )
            {

               sig_count++;
               std::cerr << sig_count << "\n";
            }
         }
      }
      fprintf( stderr, "consumer_exited\n");
      return;
   }
};
#endif /* END _SEARCH_TCC_ */
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* MSWorksImportFilter: Sets up the filter, and calls DocumentCollector
 * to do the actual filtering
 *
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <boost/scoped_ptr.hpp>
#include <com/sun/star/uno/Reference.h>
#include <cppuhelper/supportsservice.hxx>

#include <libwps/libwps.h>

#include "WPFTEncodingDialog.hxx"
#include "MSWorksImportFilter.hxx"

using com::sun::star::uno::Sequence;
using com::sun::star::uno::Reference;
using com::sun::star::uno::Any;
using com::sun::star::uno::XInterface;
using com::sun::star::uno::Exception;
using com::sun::star::uno::RuntimeException;
using com::sun::star::uno::XComponentContext;

static bool handleEmbeddedWKSObject(const librevenge::RVNGBinaryData &data, OdfDocumentHandler *pHandler,  const OdfStreamType streamType)
{
    OdsGenerator exporter;
    exporter.addDocumentHandler(pHandler, streamType);
    return libwps::WPSDocument::parse(data.getDataStream(), &exporter)==libwps::WPS_OK;
}

bool MSWorksImportFilter::doImportDocument(librevenge::RVNGInputStream &rInput, OdtGenerator &rGenerator, utl::MediaDescriptor &)
{
    libwps::WPSKind kind = libwps::WPS_TEXT;
    libwps::WPSCreator creator;
    bool needEncoding;
    const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind, creator, needEncoding);

    std::string fileEncoding("");
    try
    {
        if ((kind == libwps::WPS_TEXT) && (confidence == libwps::WPS_CONFIDENCE_EXCELLENT) && needEncoding)
        {
            const ScopedVclPtrInstance<writerperfect::WPFTEncodingDialog> pDlg(
                "Import MsWorks files(libwps)", "CP850");
            if (pDlg->Execute() == RET_OK)
            {
                if (!pDlg->GetEncoding().isEmpty())
                    fileEncoding=pDlg->GetEncoding().toUtf8().getStr();
            }
            // we can fail because we are in headless mode, the user has cancelled conversion, ...
            else if (pDlg->hasUserCalledCancel())
                return false;
        }
    }
    catch (css::uno::Exception &e)
    {
        SAL_WARN("writerperfect", "ignoring Exception " << e.Message);
    }
    return libwps::WPS_OK == libwps::WPSDocument::parse(&rInput, &rGenerator, "", fileEncoding.c_str());
}

bool MSWorksImportFilter::doDetectFormat(librevenge::RVNGInputStream &rInput, OUString &rTypeName)
{
    libwps::WPSKind kind = libwps::WPS_TEXT;
    libwps::WPSCreator creator;
    bool needEncoding;
    const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind, creator, needEncoding);

    if ((kind == libwps::WPS_TEXT) && (confidence == libwps::WPS_CONFIDENCE_EXCELLENT))
    {
        rTypeName = "writer_MS_Works_Document";
        return true;
    }

    return false;
}

void MSWorksImportFilter::doRegisterHandlers(OdtGenerator &rGenerator)
{
    rGenerator.registerEmbeddedObjectHandler("image/wks-ods", &handleEmbeddedWKSObject);
}

OUString MSWorksImportFilter_getImplementationName()
throw (RuntimeException)
{
    return OUString("com.sun.star.comp.Writer.MSWorksImportFilter");
}

Sequence< OUString > SAL_CALL MSWorksImportFilter_getSupportedServiceNames()
throw (RuntimeException)
{
    Sequence < OUString > aRet(2);
    OUString *pArray = aRet.getArray();
    pArray[0] =  "com.sun.star.document.ImportFilter";
    pArray[1] =  "com.sun.star.document.ExtendedTypeDetection";
    return aRet;
}
#undef SERVICE_NAME2
#undef SERVICE_NAME1

Reference< XInterface > SAL_CALL MSWorksImportFilter_createInstance(const Reference< XComponentContext > &rContext)
throw(Exception)
{
    return (cppu::OWeakObject *) new MSWorksImportFilter(rContext);
}

// XServiceInfo
OUString SAL_CALL MSWorksImportFilter::getImplementationName()
throw (RuntimeException, std::exception)
{
    return MSWorksImportFilter_getImplementationName();
}
sal_Bool SAL_CALL MSWorksImportFilter::supportsService(const OUString &rServiceName)
throw (RuntimeException, std::exception)
{
    return cppu::supportsService(this, rServiceName);
}
Sequence< OUString > SAL_CALL MSWorksImportFilter::getSupportedServiceNames()
throw (RuntimeException, std::exception)
{
    return MSWorksImportFilter_getSupportedServiceNames();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>-fsanitize=bool (during CppunitTest_writerperfect_writer)<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* MSWorksImportFilter: Sets up the filter, and calls DocumentCollector
 * to do the actual filtering
 *
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <boost/scoped_ptr.hpp>
#include <com/sun/star/uno/Reference.h>
#include <cppuhelper/supportsservice.hxx>

#include <libwps/libwps.h>

#include "WPFTEncodingDialog.hxx"
#include "MSWorksImportFilter.hxx"

using com::sun::star::uno::Sequence;
using com::sun::star::uno::Reference;
using com::sun::star::uno::Any;
using com::sun::star::uno::XInterface;
using com::sun::star::uno::Exception;
using com::sun::star::uno::RuntimeException;
using com::sun::star::uno::XComponentContext;

static bool handleEmbeddedWKSObject(const librevenge::RVNGBinaryData &data, OdfDocumentHandler *pHandler,  const OdfStreamType streamType)
{
    OdsGenerator exporter;
    exporter.addDocumentHandler(pHandler, streamType);
    return libwps::WPSDocument::parse(data.getDataStream(), &exporter)==libwps::WPS_OK;
}

bool MSWorksImportFilter::doImportDocument(librevenge::RVNGInputStream &rInput, OdtGenerator &rGenerator, utl::MediaDescriptor &)
{
    libwps::WPSKind kind = libwps::WPS_TEXT;
    libwps::WPSCreator creator;
    bool needEncoding = false;
    const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind, creator, needEncoding);

    std::string fileEncoding("");
    try
    {
        if ((kind == libwps::WPS_TEXT) && (confidence == libwps::WPS_CONFIDENCE_EXCELLENT) && needEncoding)
        {
            const ScopedVclPtrInstance<writerperfect::WPFTEncodingDialog> pDlg(
                "Import MsWorks files(libwps)", "CP850");
            if (pDlg->Execute() == RET_OK)
            {
                if (!pDlg->GetEncoding().isEmpty())
                    fileEncoding=pDlg->GetEncoding().toUtf8().getStr();
            }
            // we can fail because we are in headless mode, the user has cancelled conversion, ...
            else if (pDlg->hasUserCalledCancel())
                return false;
        }
    }
    catch (css::uno::Exception &e)
    {
        SAL_WARN("writerperfect", "ignoring Exception " << e.Message);
    }
    return libwps::WPS_OK == libwps::WPSDocument::parse(&rInput, &rGenerator, "", fileEncoding.c_str());
}

bool MSWorksImportFilter::doDetectFormat(librevenge::RVNGInputStream &rInput, OUString &rTypeName)
{
    libwps::WPSKind kind = libwps::WPS_TEXT;
    libwps::WPSCreator creator;
    bool needEncoding;
    const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind, creator, needEncoding);

    if ((kind == libwps::WPS_TEXT) && (confidence == libwps::WPS_CONFIDENCE_EXCELLENT))
    {
        rTypeName = "writer_MS_Works_Document";
        return true;
    }

    return false;
}

void MSWorksImportFilter::doRegisterHandlers(OdtGenerator &rGenerator)
{
    rGenerator.registerEmbeddedObjectHandler("image/wks-ods", &handleEmbeddedWKSObject);
}

OUString MSWorksImportFilter_getImplementationName()
throw (RuntimeException)
{
    return OUString("com.sun.star.comp.Writer.MSWorksImportFilter");
}

Sequence< OUString > SAL_CALL MSWorksImportFilter_getSupportedServiceNames()
throw (RuntimeException)
{
    Sequence < OUString > aRet(2);
    OUString *pArray = aRet.getArray();
    pArray[0] =  "com.sun.star.document.ImportFilter";
    pArray[1] =  "com.sun.star.document.ExtendedTypeDetection";
    return aRet;
}
#undef SERVICE_NAME2
#undef SERVICE_NAME1

Reference< XInterface > SAL_CALL MSWorksImportFilter_createInstance(const Reference< XComponentContext > &rContext)
throw(Exception)
{
    return (cppu::OWeakObject *) new MSWorksImportFilter(rContext);
}

// XServiceInfo
OUString SAL_CALL MSWorksImportFilter::getImplementationName()
throw (RuntimeException, std::exception)
{
    return MSWorksImportFilter_getImplementationName();
}
sal_Bool SAL_CALL MSWorksImportFilter::supportsService(const OUString &rServiceName)
throw (RuntimeException, std::exception)
{
    return cppu::supportsService(this, rServiceName);
}
Sequence< OUString > SAL_CALL MSWorksImportFilter::getSupportedServiceNames()
throw (RuntimeException, std::exception)
{
    return MSWorksImportFilter_getSupportedServiceNames();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// Apply tuple to a function
// C++14

#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>

template<typename F, typename Tuple, size_t ...S >
auto apply_tuple_impl(F&& fn, Tuple&& t, std::index_sequence<S...>)
{
	return std::forward<F>(fn)(std::get<S>(std::forward<Tuple>(t))...);
}

template<typename F, typename Tuple>
auto apply_from_tuple(F&& fn, Tuple&& t)
{
	std::size_t constexpr tSize
		= std::tuple_size<typename std::remove_reference<Tuple>::type>::value;

	return apply_tuple_impl(std::forward<F>(fn),
	                        std::forward<Tuple>(t),
	                        std::make_index_sequence<tSize>());
}

int do_sum(int a, int b)
{
	return a + b;
}

int main()
{
	int sum = apply_from_tuple(do_sum, std::make_tuple(10, 20));
}

// Unpack a tuple as the arguments of a function.
//
// The `apply_from_tuple` function template on [15-24] returns the
// result of applying the function `fn` to the values stored in the
// [`std::tuple`](cpp/utility/tuple) `t`. On [18-19], we store the
// size of `t` in `tSize`, which is declared `constexpr` because
// its value can be determined at compile-time. On [21-23], we call
// `apply_tuple_impl` passing `t`, `fn` and an
// [`std::index_sequence`](cpp/utility/integer_sequence)
// which carries a parameter pack containing a sequence of integers
// from `0` to `tSize - 1`.
//
// The `apply_tuple_impl` function template on [9-13] returns the
// result of applying the function `fn` using event element of the
// tuple `t` as arguments (on [12]). To do this, we expand the
// parameter pack carried by the `std::index_sequence` and apply
// [`std::get`](cpp/utility/tuple/get) to the tuple for each
// integer in the sequence. This way, all the elements of `t` are
// expanded and passed to the function.
//
// **Note**: a [`std::apply`](cpp/experimental/apply) function has
// been proposed as part of the Library Fundamentals TS for future
// standardization.
<commit_msg>Correction to apply tuple sample<commit_after>// Apply tuple to a function
// C++14

#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>

template<typename F, typename Tuple, size_t ...S >
auto apply_tuple_impl(F&& fn, Tuple&& t, std::index_sequence<S...>)
{
	return std::forward<F>(fn)(std::get<S>(std::forward<Tuple>(t))...);
}

template<typename F, typename Tuple>
auto apply_from_tuple(F&& fn, Tuple&& t)
{
	std::size_t constexpr tSize
		= std::tuple_size<typename std::remove_reference<Tuple>::type>::value;

	return apply_tuple_impl(std::forward<F>(fn),
	                        std::forward<Tuple>(t),
	                        std::make_index_sequence<tSize>());
}

int do_sum(int a, int b)
{
	return a + b;
}

int main()
{
	int sum = apply_from_tuple(do_sum, std::make_tuple(10, 20));
}

// Unpack a tuple as the arguments of a function.
//
// The `apply_from_tuple` function template on [15-24] returns the
// result of applying the function `fn` to the values stored in the
// [`std::tuple`](cpp/utility/tuple) `t`. On [18-19], we store the
// size of `t` in `tSize`, which is declared `constexpr` so that
// it can be evaluated at compile-time. On [21-23], we call
// `apply_tuple_impl` passing `t`, `fn` and an
// [`std::index_sequence`](cpp/utility/integer_sequence)
// which carries a parameter pack containing a sequence of integers
// from `0` to `tSize - 1`.
//
// The `apply_tuple_impl` function template on [9-13] returns the
// result of applying the function `fn` using event element of the
// tuple `t` as arguments (on [12]). To do this, we expand the
// parameter pack carried by the `std::index_sequence` and apply
// [`std::get`](cpp/utility/tuple/get) to the tuple for each
// integer in the sequence. This way, all the elements of `t` are
// expanded and passed to the function.
//
// **Note**: a [`std::apply`](cpp/experimental/apply) function has
// been proposed as part of the Library Fundamentals TS for future
// standardization.
<|endoftext|>


<commit_before>#include <Riostream.h>
#ifndef WIN32
# define stupre stupre_
#else
# define stupre STUPRE
#endif
//
// Fluka include
#include "Fdimpar.h"  //(DIMPAR) fluka include

// Fluka commons
#include "Fdblprc.h"  //(DBLPRC) fluka common
#include "Femfstk.h"  //(EMFSTK) fluka common
#include "Fevtflg.h"  //(EVTFLG) fluka common
#include "Fpaprop.h"  //(PAPROP) fluka common
#include "Ftrackr.h"  //(TRACKR) fluka common
#include "Femfrgn.h"  //(EFMRGN) fluka common

//Virtual MC
#include "TFluka.h"
#include "TFlukaCodes.h"
#include "TVirtualMCStack.h"
#include "TVirtualMCApplication.h"
#include "TParticle.h"
#include "TVector3.h"

extern "C" {
void stupre()
{
//*----------------------------------------------------------------------*
//*                                                                      *
//*  SeT User PRoperties for Emf particles                               *
//*                                                                      *
//*----------------------------------------------------------------------*
// Get the pointer to the VMC
  TFluka* fluka =  (TFluka*) gMC;
  static Double_t emassmev = PAPROP.am[kFLUKAelectron + 6] * 1000.;

  Int_t lbhabh = 0;
  if (EVTFLG.ldltry == 1) {
    if (EMFSTK.ichemf[EMFSTK.npemf-1] * EMFSTK.ichemf[EMFSTK.npemf-2] < 0) lbhabh = 1;
  }

// mkbmx1         = dimension for kwb real spare array in fluka stack in DIMPAR
// mkbmx2         = dimension for kwb int. spare array in fluka stack in DIMPAR
// EMFSTK.espark  = spare real variables available for
// EMFSTK.iespak  = spare integer variables available for
// TRACKR.spausr  = user defined spare variables for the current particle
// TRACKR.ispusr  = user defined spare flags for the current particle
// EMFSTK.louemf  = user flag
// TRACKR.llouse  = user defined flag for the current particle

  Int_t npnw, ispr;
  for (npnw = EMFSTK.npstrt-1; npnw <= EMFSTK.npemf-1; npnw++) {

      for (ispr = 0; ispr <= mkbmx1-1; ispr++)
          EMFSTK.espark[npnw][ispr] = TRACKR.spausr[ispr];

      for (ispr = 0; ispr <= mkbmx2-1; ispr++)
          EMFSTK.iespak[npnw][ispr] = TRACKR.ispusr[ispr];

      EMFSTK.louemf[npnw] = TRACKR.llouse;
  }

  Int_t verbosityLevel = fluka->GetVerbosityLevel();
  Bool_t debug = (verbosityLevel>=3)?kTRUE:kFALSE;
  debug = 100;

  fluka->SetTrackIsNew(kTRUE);

// Get the stack produced from the generator
  TVirtualMCStack* cppstack = fluka->GetStack();

// EVTFLG.ntrcks = track number
// Increment the track number and put it into the last flag

  Int_t kp;

  for (kp = EMFSTK.npstrt - 1; kp <= EMFSTK.npemf - 1; kp++) {

// Check transport cut first
    Int_t    ireg   = EMFSTK.iremf[kp];
    Double_t cut    = (TMath::Abs(EMFSTK.ichemf[kp]) == 1) ? EMFRGN.elethr[ireg-1] :  EMFRGN.phothr[ireg-1];
    Double_t e      = EMFSTK.etemf[kp];

    if ((e < cut)
        && (
            (EMFSTK.ichemf[kp] ==  0) ||
            (EMFSTK.ichemf[kp] == -1) ||
            (EMFSTK.ichemf[kp] ==  1 &&  EMFRGN.phothr[ireg-1] > emassmev)
            )
        )
    {
        EMFSTK.iespak[kp][mkbmx2-1] = TRACKR.ispusr[mkbmx2-1];
        EMFSTK.iespak[kp][mkbmx2-2] =  0;
        EMFSTK.iespak[kp][mkbmx2-3] = TRACKR.jtrack;
        EMFSTK.irlatt[kp] = TRACKR.lt1trk;
        continue;
    }

// Save the parent track number and reset it at each loop
    Int_t done = 0;
    Int_t parent =  TRACKR.ispusr[mkbmx2-1];
    Int_t flukaid = 0;

// Identify particle type
    if      (EMFSTK.ichemf[kp] == -1)  flukaid = kFLUKAelectron;
    else if (EMFSTK.ichemf[kp] ==  0)  flukaid = kFLUKAphoton;
    else if (EMFSTK.ichemf[kp] ==  1)  flukaid = kFLUKApositron;

    e *= emvgev;
    Int_t    pdg    = fluka->PDGFromId(flukaid);
    Double_t p      = sqrt(e * e - PAPROP.am[flukaid+6] * PAPROP.am[flukaid+6]);
    Double_t px     = p * EMFSTK.uemf[kp];
    Double_t py     = p * EMFSTK.vemf[kp];
    Double_t pz     = p * EMFSTK.wemf[kp];
    Double_t tof    = EMFSTK.agemf[kp];
    Double_t polx   = EMFSTK.upol[kp];
    Double_t poly   = EMFSTK.vpol[kp];
    Double_t polz   = EMFSTK.wpol[kp];
    Double_t vx     = EMFSTK.xemf[kp];
    Double_t vy     = EMFSTK.yemf[kp];
    Double_t vz     = EMFSTK.zemf[kp];
    Double_t weight = EMFSTK.wtemf[kp];

    Int_t ntr;
    TMCProcess mech;
    Int_t is = 0;

//* case of no parent left (pair, photoelectric, annihilation):
//* all secondaries are true
    if ((EVTFLG.lpairp == 1) || (EVTFLG.lphoel == 1) ||
        (EVTFLG.lannfl == 1) || (EVTFLG.lannrs == 1)) {

        if (EVTFLG.lpairp == 1) mech = kPPair;
        else if (EVTFLG.lphoel == 1) mech = kPPhotoelectric;
        else mech = kPAnnihilation;
        cppstack->PushTrack(done, parent, pdg,
                           px, py, pz, e, vx, vy, vz, tof,
                           polx, poly, polz, mech, ntr, weight, is);
        if (debug) cout << endl << " !!! stupre (PAIR, ..) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << " energy " << e-PAPROP.am[flukaid+6] << endl;

        EMFSTK.iespak[kp][mkbmx2-1] = ntr;
        EMFSTK.iespak[kp][mkbmx2-2] = 0;
    } // end of lpairp, lphoel, lannfl, lannrs

//* Compton: secondary is true only if charged (e+, e-)
    else if ((EVTFLG.lcmptn == 1)) {

        if (EMFSTK.ichemf[kp] != 0) {
            mech = kPCompton;
            cppstack->PushTrack(done, parent, pdg,
                               px, py, pz, e, vx, vy, vz, tof,
                               polx, poly, polz, mech, ntr, weight, is);
            if (debug) cout << endl << " !!! stupre (COMPTON) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << endl;
            EMFSTK.iespak[kp][mkbmx2-1] = ntr;
            EMFSTK.iespak[kp][mkbmx2-2] = 0;
        } else {
	    fluka->SetPint(px, py, pz, e);
	}
    } // end of lcmptn

//* Bremsstrahlung: true secondary only if charge = 0 (photon)
    else if ((EVTFLG.lbrmsp == 1)) {
        if (EMFSTK.ichemf[kp] == 0) {
            mech = kPBrem;
            cppstack->PushTrack(done, parent, pdg,
                               px, py, pz, e, vx, vy, vz, tof,
                               polx, poly, polz, mech, ntr, weight, is);
            if (debug) cout << endl << " !!! stupre (BREMS) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << endl;
            EMFSTK.iespak[kp][mkbmx2-1] = ntr;
            EMFSTK.iespak[kp][mkbmx2-2] = 0;
        } else {
	    fluka->SetPint(px, py, pz, e);
	}

    } // end of lbrmsp

//* Delta ray: If Bhabha, true secondary only if negative (electron)
    else if ((EVTFLG.ldltry == 1)) {
        if (lbhabh == 1) {
            if (EMFSTK.ichemf[kp] == -1) {
                mech = kPDeltaRay;
                cppstack->PushTrack(done, parent, pdg,
				    px, py, pz, e, vx, vy, vz, tof,
				    polx, poly, polz, mech, ntr, weight, is);
                EMFSTK.iespak[kp][mkbmx2-1] = ntr;
                EMFSTK.iespak[kp][mkbmx2-2] = 0;
		if (debug) cout << endl << " !!! stupre (BHABA) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << endl;
            } else {
		fluka->SetPint(px, py, pz, e);
	    }
        } // lbhabh == 1

//* Delta ray: Otherwise Moller: true secondary is the electron with
//*            lower energy, which has been put higher in the stack
        else if (kp == EMFSTK.npemf-1) {
            mech = kPDeltaRay;
            cppstack->PushTrack(done, parent, pdg,
                               px, py, pz, e, vx, vy, vz, tof,
                               polx, poly, polz, mech, ntr, weight, is);
            if (debug) cout << endl << " !!! stupre (Moller) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << endl;
            EMFSTK.iespak[kp][mkbmx2-1] = ntr;
            EMFSTK.iespak[kp][mkbmx2-2] = 0;
        } else {
	    fluka->SetPint(px, py, pz, e);
	}
    } // end of ldltry

  } // end of loop
} // end of stupre
} // end of extern "C"

<commit_msg>No debug by default.<commit_after>#include <Riostream.h>
#ifndef WIN32
# define stupre stupre_
#else
# define stupre STUPRE
#endif
//
// Fluka include
#include "Fdimpar.h"  //(DIMPAR) fluka include

// Fluka commons
#include "Fdblprc.h"  //(DBLPRC) fluka common
#include "Femfstk.h"  //(EMFSTK) fluka common
#include "Fevtflg.h"  //(EVTFLG) fluka common
#include "Fpaprop.h"  //(PAPROP) fluka common
#include "Ftrackr.h"  //(TRACKR) fluka common
#include "Femfrgn.h"  //(EFMRGN) fluka common

//Virtual MC
#include "TFluka.h"
#include "TFlukaCodes.h"
#include "TVirtualMCStack.h"
#include "TVirtualMCApplication.h"
#include "TParticle.h"
#include "TVector3.h"

extern "C" {
void stupre()
{
//*----------------------------------------------------------------------*
//*                                                                      *
//*  SeT User PRoperties for Emf particles                               *
//*                                                                      *
//*----------------------------------------------------------------------*
// Get the pointer to the VMC
  TFluka* fluka =  (TFluka*) gMC;
  static Double_t emassmev = PAPROP.am[kFLUKAelectron + 6] * 1000.;

  Int_t lbhabh = 0;
  if (EVTFLG.ldltry == 1) {
    if (EMFSTK.ichemf[EMFSTK.npemf-1] * EMFSTK.ichemf[EMFSTK.npemf-2] < 0) lbhabh = 1;
  }

// mkbmx1         = dimension for kwb real spare array in fluka stack in DIMPAR
// mkbmx2         = dimension for kwb int. spare array in fluka stack in DIMPAR
// EMFSTK.espark  = spare real variables available for
// EMFSTK.iespak  = spare integer variables available for
// TRACKR.spausr  = user defined spare variables for the current particle
// TRACKR.ispusr  = user defined spare flags for the current particle
// EMFSTK.louemf  = user flag
// TRACKR.llouse  = user defined flag for the current particle

  Int_t npnw, ispr;
  for (npnw = EMFSTK.npstrt-1; npnw <= EMFSTK.npemf-1; npnw++) {

      for (ispr = 0; ispr <= mkbmx1-1; ispr++)
          EMFSTK.espark[npnw][ispr] = TRACKR.spausr[ispr];

      for (ispr = 0; ispr <= mkbmx2-1; ispr++)
          EMFSTK.iespak[npnw][ispr] = TRACKR.ispusr[ispr];

      EMFSTK.louemf[npnw] = TRACKR.llouse;
  }

  Int_t verbosityLevel = fluka->GetVerbosityLevel();
  Bool_t debug = (verbosityLevel>=3)?kTRUE:kFALSE;

  fluka->SetTrackIsNew(kTRUE);

// Get the stack produced from the generator
  TVirtualMCStack* cppstack = fluka->GetStack();

// EVTFLG.ntrcks = track number
// Increment the track number and put it into the last flag

  Int_t kp;

  for (kp = EMFSTK.npstrt - 1; kp <= EMFSTK.npemf - 1; kp++) {

// Check transport cut first
    Int_t    ireg   = EMFSTK.iremf[kp];
    Double_t cut    = (TMath::Abs(EMFSTK.ichemf[kp]) == 1) ? EMFRGN.elethr[ireg-1] :  EMFRGN.phothr[ireg-1];
    Double_t e      = EMFSTK.etemf[kp];

    if ((e < cut)
        && (
            (EMFSTK.ichemf[kp] ==  0) ||
            (EMFSTK.ichemf[kp] == -1) ||
            (EMFSTK.ichemf[kp] ==  1 &&  EMFRGN.phothr[ireg-1] > emassmev)
            )
        )
    {
        EMFSTK.iespak[kp][mkbmx2-1] = TRACKR.ispusr[mkbmx2-1];
        EMFSTK.iespak[kp][mkbmx2-2] =  0;
        EMFSTK.iespak[kp][mkbmx2-3] = TRACKR.jtrack;
        EMFSTK.irlatt[kp] = TRACKR.lt1trk;
        continue;
    }

// Save the parent track number and reset it at each loop
    Int_t done = 0;
    Int_t parent =  TRACKR.ispusr[mkbmx2-1];
    Int_t flukaid = 0;

// Identify particle type
    if      (EMFSTK.ichemf[kp] == -1)  flukaid = kFLUKAelectron;
    else if (EMFSTK.ichemf[kp] ==  0)  flukaid = kFLUKAphoton;
    else if (EMFSTK.ichemf[kp] ==  1)  flukaid = kFLUKApositron;

    e *= emvgev;
    Int_t    pdg    = fluka->PDGFromId(flukaid);
    Double_t p      = sqrt(e * e - PAPROP.am[flukaid+6] * PAPROP.am[flukaid+6]);
    Double_t px     = p * EMFSTK.uemf[kp];
    Double_t py     = p * EMFSTK.vemf[kp];
    Double_t pz     = p * EMFSTK.wemf[kp];
    Double_t tof    = EMFSTK.agemf[kp];
    Double_t polx   = EMFSTK.upol[kp];
    Double_t poly   = EMFSTK.vpol[kp];
    Double_t polz   = EMFSTK.wpol[kp];
    Double_t vx     = EMFSTK.xemf[kp];
    Double_t vy     = EMFSTK.yemf[kp];
    Double_t vz     = EMFSTK.zemf[kp];
    Double_t weight = EMFSTK.wtemf[kp];

    Int_t ntr;
    TMCProcess mech;
    Int_t is = 0;

//* case of no parent left (pair, photoelectric, annihilation):
//* all secondaries are true
    if ((EVTFLG.lpairp == 1) || (EVTFLG.lphoel == 1) ||
        (EVTFLG.lannfl == 1) || (EVTFLG.lannrs == 1)) {

        if (EVTFLG.lpairp == 1) mech = kPPair;
        else if (EVTFLG.lphoel == 1) mech = kPPhotoelectric;
        else mech = kPAnnihilation;
        cppstack->PushTrack(done, parent, pdg,
                           px, py, pz, e, vx, vy, vz, tof,
                           polx, poly, polz, mech, ntr, weight, is);
        if (debug) cout << endl << " !!! stupre (PAIR, ..) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << " energy " << e-PAPROP.am[flukaid+6] << endl;

        EMFSTK.iespak[kp][mkbmx2-1] = ntr;
        EMFSTK.iespak[kp][mkbmx2-2] = 0;
    } // end of lpairp, lphoel, lannfl, lannrs

//* Compton: secondary is true only if charged (e+, e-)
    else if ((EVTFLG.lcmptn == 1)) {

        if (EMFSTK.ichemf[kp] != 0) {
            mech = kPCompton;
            cppstack->PushTrack(done, parent, pdg,
                               px, py, pz, e, vx, vy, vz, tof,
                               polx, poly, polz, mech, ntr, weight, is);
            if (debug) cout << endl << " !!! stupre (COMPTON) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << endl;
            EMFSTK.iespak[kp][mkbmx2-1] = ntr;
            EMFSTK.iespak[kp][mkbmx2-2] = 0;
        } else {
	    fluka->SetPint(px, py, pz, e);
	}
    } // end of lcmptn

//* Bremsstrahlung: true secondary only if charge = 0 (photon)
    else if ((EVTFLG.lbrmsp == 1)) {
        if (EMFSTK.ichemf[kp] == 0) {
            mech = kPBrem;
            cppstack->PushTrack(done, parent, pdg,
                               px, py, pz, e, vx, vy, vz, tof,
                               polx, poly, polz, mech, ntr, weight, is);
            if (debug) cout << endl << " !!! stupre (BREMS) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << endl;
            EMFSTK.iespak[kp][mkbmx2-1] = ntr;
            EMFSTK.iespak[kp][mkbmx2-2] = 0;
        } else {
	    fluka->SetPint(px, py, pz, e);
	}

    } // end of lbrmsp

//* Delta ray: If Bhabha, true secondary only if negative (electron)
    else if ((EVTFLG.ldltry == 1)) {
        if (lbhabh == 1) {
            if (EMFSTK.ichemf[kp] == -1) {
                mech = kPDeltaRay;
                cppstack->PushTrack(done, parent, pdg,
				    px, py, pz, e, vx, vy, vz, tof,
				    polx, poly, polz, mech, ntr, weight, is);
                EMFSTK.iespak[kp][mkbmx2-1] = ntr;
                EMFSTK.iespak[kp][mkbmx2-2] = 0;
		if (debug) cout << endl << " !!! stupre (BHABA) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << endl;
            } else {
		fluka->SetPint(px, py, pz, e);
	    }
        } // lbhabh == 1

//* Delta ray: Otherwise Moller: true secondary is the electron with
//*            lower energy, which has been put higher in the stack
        else if (kp == EMFSTK.npemf-1) {
            mech = kPDeltaRay;
            cppstack->PushTrack(done, parent, pdg,
                               px, py, pz, e, vx, vy, vz, tof,
                               polx, poly, polz, mech, ntr, weight, is);
            if (debug) cout << endl << " !!! stupre (Moller) : ntr=" << ntr << " pdg " << pdg << " parent=" << parent << endl;
            EMFSTK.iespak[kp][mkbmx2-1] = ntr;
            EMFSTK.iespak[kp][mkbmx2-2] = 0;
        } else {
	    fluka->SetPint(px, py, pz, e);
	}
    } // end of ldltry

  } // end of loop
} // end of stupre
} // end of extern "C"

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
//  TEST    Foundation::Traveral
#include    "Stroika/Foundation/StroikaPreComp.h"

#include    "Stroika/Foundation/Characters/String.h"
#include    "Stroika/Foundation/Containers/Sequence.h"
#include    "Stroika/Foundation/Containers/Mapping.h"
#include    "Stroika/Foundation/Configuration/Enumeration.h"
#include    "Stroika/Foundation/Debug/Assertions.h"
#include    "Stroika/Foundation/Traversal/DiscreteRange.h"
#include    "Stroika/Foundation/Traversal/FunctionalApplication.h"
#include    "Stroika/Foundation/Traversal/Range.h"

#include    "../TestHarness/TestHarness.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Traversal;

namespace   {

    void    Test_1_BasicRange_ ()
    {
        {
            Range<int> r (3, 5);
            VerifyTestResult (not r.empty ());
            VerifyTestResult (r.Contains (3));
        }
        {
            Range<double> r (3, 5);
            VerifyTestResult (not r.empty ());
            VerifyTestResult (r.Contains (3));
        }
        {
#if 0
            ////// MAYBE GET RID OF THIS???
            Range<int> r1 (3, 5);
            Range<int> r2 (5, 6);
            VerifyTestResult (not r1.Overlaps (r2));
            VerifyTestResult (not r2.Overlaps (r1));
            Range<int> r3  = r1;
            VerifyTestResult (r1.Overlaps (r3));
            VerifyTestResult (r3.Overlaps (r1));
#endif
        }
        {
            typedef ExplicitRangeTraits_Integral < int, -3, 100 , RangeBase::Openness::eClosed, RangeBase::Openness::eClosed, int, unsigned int > RT;
            Range<int, RT> x    =   Range<int, RT>::FullRange ();
            VerifyTestResult (x.begin () == -3);
            VerifyTestResult (x.end () == 100);
        }
    }

    void    Test_2_BasicDiscreteRangeIteration_ ()
    {
        {
            DiscreteRange<int> r (3, 5);
            VerifyTestResult (not r.empty ());
            VerifyTestResult (r.Contains (3));
        }
        {
            int nItemsHit = 0;
            int lastItemHit = 0;
            for (auto i : DiscreteRange<int> (3, 5)) {
                nItemsHit++;
                VerifyTestResult (lastItemHit < i);
                lastItemHit = i;
            }
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == 5);    /// IN DISCUSSION - OPEN ENDED RHS?
        }
    }

}

namespace {
    void    Test_3_SimpleDiscreteRangeWithEnumsTest_ ()
    {
        enum    class   Color {
            red, blue, green,

            Stroika_Define_Enum_Bounds (red, green)
        };

        using   Memory::Optional;

        {
            Color min1 = DefaultDiscreteRangeTraits<Color>::kMin;
            Color max1 = DefaultDiscreteRangeTraits<Color>::kMax;
            Color min2 = DefaultDiscreteRangeTraits_Enum<Color>::kMin;
            Color max2 = DefaultDiscreteRangeTraits_Enum<Color>::kMax;
            Color min3 = ExplicitDiscreteRangeTraits<Color, Color::eSTART, Color::eLAST, int, unsigned int>::kMin;
            Color max3 = ExplicitDiscreteRangeTraits<Color, Color::eSTART, Color::eLAST, int, unsigned int>::kMax;
            Color min4 = ExplicitRangeTraits_Integral<Color, Color::eSTART, Color::eLAST, RangeBase::Openness::eClosed, RangeBase::Openness::eClosed, int, unsigned int>::kMin;
            Color max4 = ExplicitRangeTraits_Integral<Color, Color::eSTART, Color::eLAST, RangeBase::Openness::eClosed, RangeBase::Openness::eClosed, int, unsigned int>::kMax;
            VerifyTestResult (Color::red == Color::eSTART and Color::green == Color::eLAST);
            VerifyTestResult (min1 == Color::eSTART and max1 == Color::eLAST);
            VerifyTestResult (min2 == Color::eSTART and max2 == Color::eLAST);
            VerifyTestResult (min3 == Color::eSTART and max3 == Color::eLAST);
            VerifyTestResult (min4 == Color::eSTART and max4 == Color::eLAST);
        }
        {
            int nItemsHit = 0;
            Optional<Color> lastItemHit;
            for (auto i : DiscreteRange<Color>::FullRange ()) {
                nItemsHit++;
                VerifyTestResult (lastItemHit.empty () or * lastItemHit < i);
                lastItemHit = i;
            }
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == Color::green);
        }
        {
            int nItemsHit = 0;
            Optional<Color> lastItemHit;
            for (auto i : DiscreteRange<Color, DefaultDiscreteRangeTraits<Color>>::FullRange ()) {
                nItemsHit++;
                VerifyTestResult (lastItemHit.empty () or * lastItemHit < i);
                lastItemHit = i;
            }
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == Color::green);
        }
        {
            int nItemsHit = 0;
            Optional<Color> lastItemHit;
            for (auto i : DiscreteRange<Color> (Optional<Color> (), Optional<Color> ())) {
                nItemsHit++;
                VerifyTestResult (lastItemHit.empty () or * lastItemHit < i);
                lastItemHit = i;
            }
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == Color::green);
        }
        {
            int nItemsHit = 0;
            Optional<Color> lastItemHit;
            DiscreteRange<Color> (Optional<Color> (), Optional<Color> ()).Apply ([&nItemsHit, &lastItemHit] (Color i) {
                nItemsHit++;
                VerifyTestResult (lastItemHit.empty () or * lastItemHit < i);
                lastItemHit = i;
            });
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == Color::green);
        }
    }
}

namespace {
    void    Test4_MapTest_ ()
    {
        {
            Containers::Sequence<int>   n;
            n.Append (1);
            n.Append (2);
            n.Append (3);
            Containers::Sequence<int>   n1 = Containers::Sequence<int> (FunctionalApplicationContext<int> (n).Map<int> ([] (int i) -> int { return i + 1;}));
            VerifyTestResult (n1.size () == 3);
            VerifyTestResult (n1[0] == 2);
            VerifyTestResult (n1[1] == 3);
            VerifyTestResult (n1[2] == 4);
        }
    }
}

namespace {
    void    Test5_ReduceTest_ ()
    {
        {
            Containers::Sequence<int>   n;
            n.Append (1);
            n.Append (2);
            n.Append (3);
            int sum = FunctionalApplicationContext<int> (n).Reduce<int> ([] (int l, int r) -> int { return l + r; }, 0);
            VerifyTestResult (sum == 6);
        }
    }
}

namespace {
    void    Test6_FunctionApplicationContext_ ()
    {
        using Containers::Sequence;

        {
#if     qCompilerAndStdLib_Supports_initializer_lists
            Containers::Sequence<int> s =   { 1, 2, 3};
#else
            Containers::Sequence<int> s;
            s.Append (1);
            s.Append (2);
            s.Append (3);
#endif
            {
                shared_ptr<int> countSoFar = shared_ptr<int> (new int (0));
                int answer =
                    FunctionalApplicationContext<int>(s).
                    Filter<int> ([countSoFar] (int) -> bool { ++(*countSoFar); return (*countSoFar) & 1; }).
                Map<int> ([] (int s) { return s + 5; }).
                Reduce<size_t> ([] (int s, size_t memo) { return memo + 1; })
                ;
                VerifyTestResult (answer == 2);
            }
            {
                int countSoFar = 0; // ONLY OK - cuz FunctionalApplicationContext <> and resulting iterators go
                // out of scope before this does
                int answer =
                    FunctionalApplicationContext<int>(s).
                    Filter<int> ([&countSoFar] (int) -> bool { ++countSoFar; return countSoFar & 1; }).
                Map<int> ([] (int s) { return s + 5; }).
                Reduce<size_t> ([] (int s, size_t memo) { return memo + 1; });
                VerifyTestResult (answer == 2);
            }
            {
                int countSoFar = 0; // ONLY OK - cuz FunctionalApplicationContext <> and resulting iterators go
                // out of scope before this does
                Containers::Sequence<int> r = Containers::Sequence<int> (
                                                  FunctionalApplicationContext<int>(s).
                                                  Filter<int> ([&countSoFar] (int) -> bool { ++countSoFar; return countSoFar & 1; }).
                Map<int> ([] (int s) { return s + 5; })
                                              );
                VerifyTestResult (r.length () == 2);
                VerifyTestResult (r[0] == 6 and r[1] == 8);
            }
            {
                Memory::Optional<int> answer =
                    FunctionalApplicationContext<int>(s).
                    Filter<int> ([] (int i) -> bool { return (i & 1); }).
                    Find<int> ([] (int i) -> bool { return i == 1 ; })
                    ;
                VerifyTestResult (*answer == 1);
            }
            {
                Memory::Optional<int> answer =
                    FunctionalApplicationContext<int>(s).
                    Filter<int> ([] (int i) -> bool { return (i & 1); }).
                    Find<int> ([] (int i) -> bool { return i == 8 ; })
                    ;
                VerifyTestResult (answer.empty ());
            }
        }

        {
            using   Characters::String;
#if     qCompilerAndStdLib_Supports_initializer_lists
            Sequence<String> s = { L"alpha", L"beta", L"gamma" };
#else
            Containers::Sequence<String> s;
            s.Append (L"alpha");
            s.Append ( L"beta");
            s.Append (L"gamma");
#endif
            {
                int countSoFar = 0; // ONLY OK - cuz FunctionalApplicationContext <> and resulting iterators go
                // out of scope before this does
                int answer =
                    FunctionalApplicationContext<String>(s).
                    Filter<String> ([&countSoFar] (String) -> bool { ++countSoFar; return countSoFar & 1; }).
                Map<String> ([] (String s) { return s + L" hello"; }).
                Reduce<size_t> ([] (String s, size_t memo) { return memo + 1; });
                VerifyTestResult (answer == 2);
            }
            {
                int countSoFar = 0; // ONLY OK - cuz FunctionalApplicationContext <> and resulting iterators go
                // out of scope before this does
                Containers::Sequence<String> r = Containers::Sequence<String> (
                                                     FunctionalApplicationContext<String>(s).
                                                     Filter<String> ([&countSoFar] (String) -> bool { ++countSoFar; return countSoFar & 1; }).
                Map<String> ([] (String s) { return s + L" hello"; })
                                                 );
                VerifyTestResult (r.length () == 2);
                VerifyTestResult (r[0] == L"alpha hello" and r[1] == L"gamma hello");
            }
        }
    }
    void    Test7_FunctionApplicationContextWithDiscreteRangeEtc_ ()
    {
        using   Containers::Sequence;
        {
            const uint32_t  kRefCheck_[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };
            auto isPrimeCheck = [] (uint32_t n) -> bool { return Math::IsPrime (n); };
            for (auto i : FunctionalApplicationContext<uint32_t> (DiscreteRange<uint32_t> (1, 100)).Filter<uint32_t> (isPrimeCheck)) {
                VerifyTestResult (Math::IsPrime (i));
            }
            Sequence<uint32_t> s = Sequence<uint32_t> (FunctionalApplicationContext<uint32_t> (DiscreteRange<uint32_t> (1, 100)).Filter<uint32_t> (isPrimeCheck));
            VerifyTestResult (s == Sequence<uint32_t> (begin (kRefCheck_), end (kRefCheck_)));
            VerifyTestResult (NEltsOf (kRefCheck_) == FunctionalApplicationContext<uint32_t> (DiscreteRange<uint32_t> (1, 100)).Filter<uint32_t> (isPrimeCheck).GetLength ());
        }
    }
}

namespace   {

    void    DoRegressionTests_ ()
    {
        Test_1_BasicRange_ ();
        Test_2_BasicDiscreteRangeIteration_ ();
        Test_3_SimpleDiscreteRangeWithEnumsTest_ ();
        Test4_MapTest_ ();
        Test5_ReduceTest_ ();
        Test6_FunctionApplicationContext_ ();
        Test7_FunctionApplicationContextWithDiscreteRangeEtc_ ();
    }
}

int     main (int argc, const char* argv[])
{
    Stroika::TestHarness::Setup ();
    Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
    return EXIT_SUCCESS;
}

<commit_msg>fixed regression test for recent Range changes<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
//  TEST    Foundation::Traveral
#include    "Stroika/Foundation/StroikaPreComp.h"

#include    "Stroika/Foundation/Characters/String.h"
#include    "Stroika/Foundation/Containers/Sequence.h"
#include    "Stroika/Foundation/Containers/Mapping.h"
#include    "Stroika/Foundation/Configuration/Enumeration.h"
#include    "Stroika/Foundation/Debug/Assertions.h"
#include    "Stroika/Foundation/Traversal/DiscreteRange.h"
#include    "Stroika/Foundation/Traversal/FunctionalApplication.h"
#include    "Stroika/Foundation/Traversal/Range.h"

#include    "../TestHarness/TestHarness.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Traversal;

namespace   {

    void    Test_1_BasicRange_ ()
    {
        {
            Range<int> r (3, 5);
            VerifyTestResult (not r.empty ());
            VerifyTestResult (r.Contains (3));
        }
        {
            Range<double> r (3, 5);
            VerifyTestResult (not r.empty ());
            VerifyTestResult (r.Contains (3));
        }
        {
#if 0
            ////// MAYBE GET RID OF THIS???
            Range<int> r1 (3, 5);
            Range<int> r2 (5, 6);
            VerifyTestResult (not r1.Overlaps (r2));
            VerifyTestResult (not r2.Overlaps (r1));
            Range<int> r3  = r1;
            VerifyTestResult (r1.Overlaps (r3));
            VerifyTestResult (r3.Overlaps (r1));
#endif
        }
        {
            typedef RangeTraits::ExplicitRangeTraits_Integral < int, -3, 100 , Openness::eClosed, Openness::eClosed, int, unsigned int > RT;
            Range<int, RT> x    =   Range<int, RT>::FullRange ();
            VerifyTestResult (x.begin () == -3);
            VerifyTestResult (x.end () == 100);
        }
    }

    void    Test_2_BasicDiscreteRangeIteration_ ()
    {
        {
            DiscreteRange<int> r (3, 5);
            VerifyTestResult (not r.empty ());
            VerifyTestResult (r.Contains (3));
        }
        {
            int nItemsHit = 0;
            int lastItemHit = 0;
            for (auto i : DiscreteRange<int> (3, 5)) {
                nItemsHit++;
                VerifyTestResult (lastItemHit < i);
                lastItemHit = i;
            }
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == 5);    /// IN DISCUSSION - OPEN ENDED RHS?
        }
    }

}

namespace {
    void    Test_3_SimpleDiscreteRangeWithEnumsTest_ ()
    {
        enum    class   Color {
            red, blue, green,

            Stroika_Define_Enum_Bounds (red, green)
        };

        using   Memory::Optional;

        {
            Color min1 = RangeTraits::DefaultDiscreteRangeTraits<Color>::kMin;
            Color max1 = RangeTraits::DefaultDiscreteRangeTraits<Color>::kMax;
            Color min2 = RangeTraits::DefaultDiscreteRangeTraits_Enum<Color>::kMin;
            Color max2 = RangeTraits::DefaultDiscreteRangeTraits_Enum<Color>::kMax;
            Color min3 = RangeTraits::ExplicitDiscreteRangeTraits<Color, Color::eSTART, Color::eLAST, int, unsigned int>::kMin;
            Color max3 = RangeTraits::ExplicitDiscreteRangeTraits<Color, Color::eSTART, Color::eLAST, int, unsigned int>::kMax;
            Color min4 = RangeTraits::ExplicitRangeTraits_Integral<Color, Color::eSTART, Color::eLAST, Openness::eClosed, Openness::eClosed, int, unsigned int>::kMin;
            Color max4 = RangeTraits::ExplicitRangeTraits_Integral<Color, Color::eSTART, Color::eLAST, Openness::eClosed, Openness::eClosed, int, unsigned int>::kMax;
            VerifyTestResult (Color::red == Color::eSTART and Color::green == Color::eLAST);
            VerifyTestResult (min1 == Color::eSTART and max1 == Color::eLAST);
            VerifyTestResult (min2 == Color::eSTART and max2 == Color::eLAST);
            VerifyTestResult (min3 == Color::eSTART and max3 == Color::eLAST);
            VerifyTestResult (min4 == Color::eSTART and max4 == Color::eLAST);
        }
        {
            int nItemsHit = 0;
            Optional<Color> lastItemHit;
            for (auto i : DiscreteRange<Color>::FullRange ()) {
                nItemsHit++;
                VerifyTestResult (lastItemHit.empty () or * lastItemHit < i);
                lastItemHit = i;
            }
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == Color::green);
        }
        {
            int nItemsHit = 0;
            Optional<Color> lastItemHit;
            for (auto i : DiscreteRange<Color, RangeTraits::DefaultDiscreteRangeTraits<Color>>::FullRange ()) {
                nItemsHit++;
                VerifyTestResult (lastItemHit.empty () or * lastItemHit < i);
                lastItemHit = i;
            }
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == Color::green);
        }
        {
            int nItemsHit = 0;
            Optional<Color> lastItemHit;
            for (auto i : DiscreteRange<Color> (Optional<Color> (), Optional<Color> ())) {
                nItemsHit++;
                VerifyTestResult (lastItemHit.empty () or * lastItemHit < i);
                lastItemHit = i;
            }
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == Color::green);
        }
        {
            int nItemsHit = 0;
            Optional<Color> lastItemHit;
            DiscreteRange<Color> (Optional<Color> (), Optional<Color> ()).Apply ([&nItemsHit, &lastItemHit] (Color i) {
                nItemsHit++;
                VerifyTestResult (lastItemHit.empty () or * lastItemHit < i);
                lastItemHit = i;
            });
            VerifyTestResult (nItemsHit == 3);
            VerifyTestResult (lastItemHit == Color::green);
        }
    }
}

namespace {
    void    Test4_MapTest_ ()
    {
        {
            Containers::Sequence<int>   n;
            n.Append (1);
            n.Append (2);
            n.Append (3);
            Containers::Sequence<int>   n1 = Containers::Sequence<int> (FunctionalApplicationContext<int> (n).Map<int> ([] (int i) -> int { return i + 1;}));
            VerifyTestResult (n1.size () == 3);
            VerifyTestResult (n1[0] == 2);
            VerifyTestResult (n1[1] == 3);
            VerifyTestResult (n1[2] == 4);
        }
    }
}

namespace {
    void    Test5_ReduceTest_ ()
    {
        {
            Containers::Sequence<int>   n;
            n.Append (1);
            n.Append (2);
            n.Append (3);
            int sum = FunctionalApplicationContext<int> (n).Reduce<int> ([] (int l, int r) -> int { return l + r; }, 0);
            VerifyTestResult (sum == 6);
        }
    }
}

namespace {
    void    Test6_FunctionApplicationContext_ ()
    {
        using Containers::Sequence;

        {
#if     qCompilerAndStdLib_Supports_initializer_lists
            Containers::Sequence<int> s =   { 1, 2, 3};
#else
            Containers::Sequence<int> s;
            s.Append (1);
            s.Append (2);
            s.Append (3);
#endif
            {
                shared_ptr<int> countSoFar = shared_ptr<int> (new int (0));
                int answer =
                    FunctionalApplicationContext<int>(s).
                    Filter<int> ([countSoFar] (int) -> bool { ++(*countSoFar); return (*countSoFar) & 1; }).
                Map<int> ([] (int s) { return s + 5; }).
                Reduce<size_t> ([] (int s, size_t memo) { return memo + 1; })
                ;
                VerifyTestResult (answer == 2);
            }
            {
                int countSoFar = 0; // ONLY OK - cuz FunctionalApplicationContext <> and resulting iterators go
                // out of scope before this does
                int answer =
                    FunctionalApplicationContext<int>(s).
                    Filter<int> ([&countSoFar] (int) -> bool { ++countSoFar; return countSoFar & 1; }).
                Map<int> ([] (int s) { return s + 5; }).
                Reduce<size_t> ([] (int s, size_t memo) { return memo + 1; });
                VerifyTestResult (answer == 2);
            }
            {
                int countSoFar = 0; // ONLY OK - cuz FunctionalApplicationContext <> and resulting iterators go
                // out of scope before this does
                Containers::Sequence<int> r = Containers::Sequence<int> (
                                                  FunctionalApplicationContext<int>(s).
                                                  Filter<int> ([&countSoFar] (int) -> bool { ++countSoFar; return countSoFar & 1; }).
                Map<int> ([] (int s) { return s + 5; })
                                              );
                VerifyTestResult (r.length () == 2);
                VerifyTestResult (r[0] == 6 and r[1] == 8);
            }
            {
                Memory::Optional<int> answer =
                    FunctionalApplicationContext<int>(s).
                    Filter<int> ([] (int i) -> bool { return (i & 1); }).
                    Find<int> ([] (int i) -> bool { return i == 1 ; })
                    ;
                VerifyTestResult (*answer == 1);
            }
            {
                Memory::Optional<int> answer =
                    FunctionalApplicationContext<int>(s).
                    Filter<int> ([] (int i) -> bool { return (i & 1); }).
                    Find<int> ([] (int i) -> bool { return i == 8 ; })
                    ;
                VerifyTestResult (answer.empty ());
            }
        }

        {
            using   Characters::String;
#if     qCompilerAndStdLib_Supports_initializer_lists
            Sequence<String> s = { L"alpha", L"beta", L"gamma" };
#else
            Containers::Sequence<String> s;
            s.Append (L"alpha");
            s.Append ( L"beta");
            s.Append (L"gamma");
#endif
            {
                int countSoFar = 0; // ONLY OK - cuz FunctionalApplicationContext <> and resulting iterators go
                // out of scope before this does
                int answer =
                    FunctionalApplicationContext<String>(s).
                    Filter<String> ([&countSoFar] (String) -> bool { ++countSoFar; return countSoFar & 1; }).
                Map<String> ([] (String s) { return s + L" hello"; }).
                Reduce<size_t> ([] (String s, size_t memo) { return memo + 1; });
                VerifyTestResult (answer == 2);
            }
            {
                int countSoFar = 0; // ONLY OK - cuz FunctionalApplicationContext <> and resulting iterators go
                // out of scope before this does
                Containers::Sequence<String> r = Containers::Sequence<String> (
                                                     FunctionalApplicationContext<String>(s).
                                                     Filter<String> ([&countSoFar] (String) -> bool { ++countSoFar; return countSoFar & 1; }).
                Map<String> ([] (String s) { return s + L" hello"; })
                                                 );
                VerifyTestResult (r.length () == 2);
                VerifyTestResult (r[0] == L"alpha hello" and r[1] == L"gamma hello");
            }
        }
    }
    void    Test7_FunctionApplicationContextWithDiscreteRangeEtc_ ()
    {
        using   Containers::Sequence;
        {
            const uint32_t  kRefCheck_[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };
            auto isPrimeCheck = [] (uint32_t n) -> bool { return Math::IsPrime (n); };
            for (auto i : FunctionalApplicationContext<uint32_t> (DiscreteRange<uint32_t> (1, 100)).Filter<uint32_t> (isPrimeCheck)) {
                VerifyTestResult (Math::IsPrime (i));
            }
            Sequence<uint32_t> s = Sequence<uint32_t> (FunctionalApplicationContext<uint32_t> (DiscreteRange<uint32_t> (1, 100)).Filter<uint32_t> (isPrimeCheck));
            VerifyTestResult (s == Sequence<uint32_t> (begin (kRefCheck_), end (kRefCheck_)));
            VerifyTestResult (NEltsOf (kRefCheck_) == FunctionalApplicationContext<uint32_t> (DiscreteRange<uint32_t> (1, 100)).Filter<uint32_t> (isPrimeCheck).GetLength ());
        }
    }
}

namespace   {

    void    DoRegressionTests_ ()
    {
        Test_1_BasicRange_ ();
        Test_2_BasicDiscreteRangeIteration_ ();
        Test_3_SimpleDiscreteRangeWithEnumsTest_ ();
        Test4_MapTest_ ();
        Test5_ReduceTest_ ();
        Test6_FunctionApplicationContext_ ();
        Test7_FunctionApplicationContextWithDiscreteRangeEtc_ ();
    }
}

int     main (int argc, const char* argv[])
{
    Stroika::TestHarness::Setup ();
    Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
    return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "itkGradientMagnitudeImageFilter.h"
#include "itkSobelEdgeDetectionImageFilter.h"
//#include "itkCannyEdgeDetectionImageFilter.h"
#include "otbTouziEdgeDetectorImageFilter.h"

#include "otbMultiToMonoChannelExtractROI.h"

namespace otb
{
namespace Wrapper
{

class EdgeExtraction : public Application
{
public:
/** Standard class typedefs. */
typedef EdgeExtraction                Self;
typedef Application                   Superclass;
typedef itk::SmartPointer<Self>       Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;

typedef MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType,FloatImageType::InternalPixelType>
                                                    ExtractorFilterType;
typedef itk::GradientMagnitudeImageFilter<FloatImageType, FloatImageType>
                                                    GradientFilterType;
typedef itk::SobelEdgeDetectionImageFilter<FloatImageType, FloatImageType>
                                                    SobelFilterType;
//typedef itk::CannyEdgeDetectionImageFilter<FloatImageType, FloatImageType>
//                                                    CannyFilterType;
typedef TouziEdgeDetectorImageFilter<FloatImageType, FloatImageType>
                                                    TouziFilterType;

/** Standard macro */
itkNewMacro(Self);

itkTypeMacro(EdgeExtraction, otb::Application);

private:

void DoInit()
{
SetName("EdgeExtraction");
SetDescription("Computes edge features on every pixel of the input image selected channel");

// Documentation
SetDocName("Edge Feature Extraction");
SetDocLongDescription("This application computes edge features on a mono band image");
SetDocLimitations("None");
SetDocAuthors("OTB-Team");
SetDocSeeAlso("otb class");

AddDocTag("Edge");
AddDocTag(Tags::FeatureExtraction);

AddParameter(ParameterType_InputImage, "in",  "Input Image");
SetParameterDescription("in", "The input image to compute the features on.");

AddParameter(ParameterType_Int,  "channel",  "Selected Channel");
SetParameterDescription("channel", "The selected channel index");
SetDefaultParameterInt("channel", 1);
SetMinimumParameterIntValue("channel", 1);

AddRAMParameter();

AddParameter(ParameterType_Choice, "filter", "Edge feature");
SetParameterDescription("filter", "Choice of edge feature");

//Gradient Section
AddChoice("filter.gradient", "Gradient");

//Sobel Section
AddChoice("filter.sobel", "Sobel");

//Touzi Section
AddChoice("filter.touzi", "Touzi");
AddParameter(ParameterType_Int, "filter.touzi.xradius", "The X Radius");
SetDefaultParameterInt("filter.touzi.xradius", 1);
AddParameter(ParameterType_Int, "filter.touzi.yradius", "The Y Radius");
SetDefaultParameterInt("filter.touzi.yradius", 1);

//Canny Section
/*
AddChoice("filter.canny", "Canny");
AddParameter(ParameterType_Float, "filter.canny.variance", "");
SetDefaultParameterFloat("filter.canny.variance", 1.0);
AddParameter(ParameterType_Float, "filter.canny.maximumerror", "");
SetDefaultParameterFloat("filter.canny.maximumerror", 0.01);
AddParameter(ParameterType_Float, "filter.canny.upperthreshold", "");
SetDefaultParameterFloat("filter.canny.upperthreshold", 15.0);
AddParameter(ParameterType_Float, "filter.canny.lowerthreshold", "");
SetDefaultParameterFloat("filter.canny.lowerthreshold", 3.0);
*/

AddParameter(ParameterType_OutputImage, "out", "Feature Output Image");
SetParameterDescription("out", "Output image containing the local statistic features.");

// Doc example parameter settings
SetDocExampleParameterValue("in", "qb_RoadExtract.tif");
SetDocExampleParameterValue("channel", "1");
SetDocExampleParameterValue("out", "Edges.tif");
}

void DoUpdateParameters()
{
  // Nothing to do here : all parameters are independent
}

void DoExecute()
{
  FloatVectorImageType::Pointer inImage = GetParameterImage("in");
  inImage->UpdateOutputInformation();

  if( GetParameterInt("channel") > inImage->GetNumberOfComponentsPerPixel() )
    {
    otbAppLogCRITICAL("Selected band is not available...");
    return;
    }

  const std::string edgeType = GetParameterString("filter");

  m_ExtractorFilter = ExtractorFilterType::New();
  m_ExtractorFilter->SetInput(inImage);
  m_ExtractorFilter->SetStartX(inImage->GetLargestPossibleRegion().GetIndex(0));
  m_ExtractorFilter->SetStartY(inImage->GetLargestPossibleRegion().GetIndex(1));
  m_ExtractorFilter->SetSizeX(inImage->GetLargestPossibleRegion().GetSize(0));
  m_ExtractorFilter->SetSizeY(inImage->GetLargestPossibleRegion().GetSize(1));
  m_ExtractorFilter->SetChannel(GetParameterInt("channel"));
  m_ExtractorFilter->UpdateOutputInformation();

  m_GradientFilter    = GradientFilterType::New();
  m_SobelFilter       = SobelFilterType::New();
  m_TouziFilter       = TouziFilterType::New();
  m_CannyFilter       = CannyFilterType::New();

  if( edgeType == "gradient" )
    {
    m_GradientFilter->SetInput(const_cast<FloatImageType*>(m_ExtractorFilter->GetOutput()));
    SetParameterOutputImage("out", m_GradientFilter->GetOutput());
    }

  if( edgeType == "sobel" )
    {
    m_SobelFilter->SetInput(const_cast<FloatImageType*>(m_ExtractorFilter->GetOutput()));
    SetParameterOutputImage("out", m_SobelFilter->GetOutput());
    }

  if( edgeType == "touzi" )
    {
    m_TouziFilter->SetInput(const_cast<FloatImageType*>(m_ExtractorFilter->GetOutput()));
    TouziFilterType::SizeType rad;
    rad[0] = this->GetParameterInt("filter.touzi.xradius");
    rad[1] = this->GetParameterInt("filter.touzi.yradius");
    m_TouziFilter->SetRadius(rad);
    SetParameterOutputImage("out", m_TouziFilter->GetOutput());
    }
/*
  if( edgeType == "canny" )
    {

    m_CannyFilter->SetInput(const_cast<FloatImageType*>(m_ExtractorFilter->GetOutput()));
    m_CannyFilter->SetVariance(GetParameterFloat("filter.canny.variance"));
    m_CannyFilter->SetMaximumError(GetParameterFloat("filter.canny.maximumerror"));
    m_CannyFilter->SetUpperThreshold(GetParameterFloat("filter.canny.upperthreshold"));
    m_CannyFilter->SetLowerThreshold(GetParameterFloat("filter.canny.lowerthreshold"));

    SetParameterOutputImage("out", m_CannyFilter->GetOutput());
    }
*/
}

ExtractorFilterType::Pointer m_ExtractorFilter;
GradientFilterType::Pointer  m_GradientFilter;
SobelFilterType::Pointer     m_SobelFilter;
TouziFilterType::Pointer     m_TouziFilter;
CannyFilterType::Pointer     m_CannyFilter;
};
}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::EdgeExtraction)
<commit_msg>ENH: completed the cleaning<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "itkGradientMagnitudeImageFilter.h"
#include "itkSobelEdgeDetectionImageFilter.h"
//#include "itkCannyEdgeDetectionImageFilter.h"
#include "otbTouziEdgeDetectorImageFilter.h"

#include "otbMultiToMonoChannelExtractROI.h"

namespace otb
{
namespace Wrapper
{

class EdgeExtraction : public Application
{
public:
/** Standard class typedefs. */
typedef EdgeExtraction                Self;
typedef Application                   Superclass;
typedef itk::SmartPointer<Self>       Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;

typedef MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType,FloatImageType::InternalPixelType>
                                                    ExtractorFilterType;
typedef itk::GradientMagnitudeImageFilter<FloatImageType, FloatImageType>
                                                    GradientFilterType;
typedef itk::SobelEdgeDetectionImageFilter<FloatImageType, FloatImageType>
                                                    SobelFilterType;
//typedef itk::CannyEdgeDetectionImageFilter<FloatImageType, FloatImageType>
//                                                    CannyFilterType;
typedef TouziEdgeDetectorImageFilter<FloatImageType, FloatImageType>
                                                    TouziFilterType;

/** Standard macro */
itkNewMacro(Self);

itkTypeMacro(EdgeExtraction, otb::Application);

private:

void DoInit()
{
SetName("EdgeExtraction");
SetDescription("Computes edge features on every pixel of the input image selected channel");

// Documentation
SetDocName("Edge Feature Extraction");
SetDocLongDescription("This application computes edge features on a mono band image");
SetDocLimitations("None");
SetDocAuthors("OTB-Team");
SetDocSeeAlso("otb class");

AddDocTag("Edge");
AddDocTag(Tags::FeatureExtraction);

AddParameter(ParameterType_InputImage, "in",  "Input Image");
SetParameterDescription("in", "The input image to compute the features on.");

AddParameter(ParameterType_Int,  "channel",  "Selected Channel");
SetParameterDescription("channel", "The selected channel index");
SetDefaultParameterInt("channel", 1);
SetMinimumParameterIntValue("channel", 1);

AddRAMParameter();

AddParameter(ParameterType_Choice, "filter", "Edge feature");
SetParameterDescription("filter", "Choice of edge feature");

//Gradient Section
AddChoice("filter.gradient", "Gradient");

//Sobel Section
AddChoice("filter.sobel", "Sobel");

//Touzi Section
AddChoice("filter.touzi", "Touzi");
AddParameter(ParameterType_Int, "filter.touzi.xradius", "The X Radius");
SetDefaultParameterInt("filter.touzi.xradius", 1);
AddParameter(ParameterType_Int, "filter.touzi.yradius", "The Y Radius");
SetDefaultParameterInt("filter.touzi.yradius", 1);

//Canny Section
/*
AddChoice("filter.canny", "Canny");
AddParameter(ParameterType_Float, "filter.canny.variance", "");
SetDefaultParameterFloat("filter.canny.variance", 1.0);
AddParameter(ParameterType_Float, "filter.canny.maximumerror", "");
SetDefaultParameterFloat("filter.canny.maximumerror", 0.01);
AddParameter(ParameterType_Float, "filter.canny.upperthreshold", "");
SetDefaultParameterFloat("filter.canny.upperthreshold", 15.0);
AddParameter(ParameterType_Float, "filter.canny.lowerthreshold", "");
SetDefaultParameterFloat("filter.canny.lowerthreshold", 3.0);
*/

AddParameter(ParameterType_OutputImage, "out", "Feature Output Image");
SetParameterDescription("out", "Output image containing the local statistic features.");

// Doc example parameter settings
SetDocExampleParameterValue("in", "qb_RoadExtract.tif");
SetDocExampleParameterValue("channel", "1");
SetDocExampleParameterValue("out", "Edges.tif");
}

void DoUpdateParameters()
{
  // Nothing to do here : all parameters are independent
}

void DoExecute()
{
  FloatVectorImageType::Pointer inImage = GetParameterImage("in");
  inImage->UpdateOutputInformation();

  if( GetParameterInt("channel") > inImage->GetNumberOfComponentsPerPixel() )
    {
    otbAppLogCRITICAL("Selected band is not available...");
    return;
    }

  const std::string edgeType = GetParameterString("filter");

  m_ExtractorFilter = ExtractorFilterType::New();
  m_ExtractorFilter->SetInput(inImage);
  m_ExtractorFilter->SetStartX(inImage->GetLargestPossibleRegion().GetIndex(0));
  m_ExtractorFilter->SetStartY(inImage->GetLargestPossibleRegion().GetIndex(1));
  m_ExtractorFilter->SetSizeX(inImage->GetLargestPossibleRegion().GetSize(0));
  m_ExtractorFilter->SetSizeY(inImage->GetLargestPossibleRegion().GetSize(1));
  m_ExtractorFilter->SetChannel(GetParameterInt("channel"));
  m_ExtractorFilter->UpdateOutputInformation();

  m_GradientFilter    = GradientFilterType::New();
  m_SobelFilter       = SobelFilterType::New();
  m_TouziFilter       = TouziFilterType::New();
  //m_CannyFilter       = CannyFilterType::New();

  if( edgeType == "gradient" )
    {
    m_GradientFilter->SetInput(const_cast<FloatImageType*>(m_ExtractorFilter->GetOutput()));
    SetParameterOutputImage("out", m_GradientFilter->GetOutput());
    }

  if( edgeType == "sobel" )
    {
    m_SobelFilter->SetInput(const_cast<FloatImageType*>(m_ExtractorFilter->GetOutput()));
    SetParameterOutputImage("out", m_SobelFilter->GetOutput());
    }

  if( edgeType == "touzi" )
    {
    m_TouziFilter->SetInput(const_cast<FloatImageType*>(m_ExtractorFilter->GetOutput()));
    TouziFilterType::SizeType rad;
    rad[0] = this->GetParameterInt("filter.touzi.xradius");
    rad[1] = this->GetParameterInt("filter.touzi.yradius");
    m_TouziFilter->SetRadius(rad);
    SetParameterOutputImage("out", m_TouziFilter->GetOutput());
    }
/*
  if( edgeType == "canny" )
    {

    m_CannyFilter->SetInput(const_cast<FloatImageType*>(m_ExtractorFilter->GetOutput()));
    m_CannyFilter->SetVariance(GetParameterFloat("filter.canny.variance"));
    m_CannyFilter->SetMaximumError(GetParameterFloat("filter.canny.maximumerror"));
    m_CannyFilter->SetUpperThreshold(GetParameterFloat("filter.canny.upperthreshold"));
    m_CannyFilter->SetLowerThreshold(GetParameterFloat("filter.canny.lowerthreshold"));

    SetParameterOutputImage("out", m_CannyFilter->GetOutput());
    }
*/
}

ExtractorFilterType::Pointer m_ExtractorFilter;
GradientFilterType::Pointer  m_GradientFilter;
SobelFilterType::Pointer     m_SobelFilter;
TouziFilterType::Pointer     m_TouziFilter;
//CannyFilterType::Pointer     m_CannyFilter;
};
}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::EdgeExtraction)
<|endoftext|>


<commit_before>#ifndef DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH
#define DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH

#include <iostream>

#include <dune/common/densevector.hh>
#include <dune/common/dynvector.hh>
#include <dune/common/fvector.hh>
#include <dune/common/deprecated.hh>

#include <dune/stuff/la/container/interface.hh>
#include <dune/stuff/la/container/eigen.hh>
#include "float_cmp.hh"

namespace Dune {
namespace Stuff {
namespace Common {

template< class VectorImp >
inline void clear(Dune::DenseVector< VectorImp >& vector)
{
  vector *= typename Dune::DenseVector< VectorImp >::value_type(0);
}

/**
 *  \brief  Clears s vector.
 *  \note   This default implementation is not optimal. Add a specialization for each implementation below!
 */
template< class T >
inline void clear(LA::VectorInterface< T > & vector)
{
  for (size_t ii = 0; ii < vector.size(); ++ii)
    vector.set(ii, typename LA::VectorInterface< T >::ElementType(0));
}

#if HAVE_EIGEN
template< class T >
inline void clear(LA::EigenDenseVector< T > & vector)
{
  vector.backend() *= typename LA::EigenDenseVector< T >::ElementType(0);
}
#endif

/**
 *  \brief Compare x and y component-wise for almost equality.
 *
 *  Applies Dune::FloatCmp::eq() componentwise.
 */
template< class Field, int size >
bool DUNE_DEPRECATED_MSG("Use Dune::Stuff::Common::FloatCMP::eq() instead!") float_cmp(const Dune::FieldVector< Field, size >& x,
                                     const Dune::FieldVector< Field, size >& y,
                                     const Field tol)
{
  return FloatCmp::eq(x, y, tol);
}

template< class T >
DUNE_DEPRECATED_MSG("THIS WILL BE REMOVED ONCE ExtendedParameterTree::getVector() IS PROPERLY IMPLEMENTED!")
Dune::DynamicVector< T > resize(const Dune::DynamicVector< T >& inVector,
                                const size_t newSize,
                                const T fill = T(0))
{
  Dune::DynamicVector< T > outVector(newSize);
  for (size_t ii = 0; ii < std::min(inVector.size(), newSize); ++ii)
    outVector[ii] = inVector[ii];
  for (size_t ii = std::min(inVector.size(), newSize); ii < newSize; ++ii)
    outVector[ii] = fill;
  return outVector;
}

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH
<commit_msg>[common.vector] updated due to new containers<commit_after>#ifndef DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH
#define DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH

#include <iostream>

#include <dune/common/densevector.hh>
#include <dune/common/dynvector.hh>
#include <dune/common/fvector.hh>
#include <dune/common/deprecated.hh>

#include <dune/stuff/la/container/interface.hh>
#include <dune/stuff/la/container/eigen.hh>
#include "float_cmp.hh"

namespace Dune {
namespace Stuff {
namespace Common {

template< class VectorImp >
inline void clear(Dune::DenseVector< VectorImp >& vector)
{
  vector *= typename Dune::DenseVector< VectorImp >::value_type(0);
}

/**
 *  \brief  Clears s vector.
 *  \note   This default implementation is not optimal. Add a specialization for each implementation below!
 */
template< class T >
inline void clear(LA::VectorInterface< T > & vector)
{
  for (size_t ii = 0; ii < vector.size(); ++ii)
    vector.set(ii, typename LA::VectorInterface< T >::ScalarType(0));
}

#if HAVE_EIGEN
template< class T >
inline void clear(LA::EigenDenseVector< T > & vector)
{
  vector.backend() *= typename LA::EigenDenseVector< T >::ScalarType(0);
}
#endif

/**
 *  \brief Compare x and y component-wise for almost equality.
 *
 *  Applies Dune::FloatCmp::eq() componentwise.
 */
template< class Field, int size >
bool DUNE_DEPRECATED_MSG("Use Dune::Stuff::Common::FloatCMP::eq() instead!") float_cmp(const Dune::FieldVector< Field, size >& x,
                                     const Dune::FieldVector< Field, size >& y,
                                     const Field tol)
{
  return FloatCmp::eq(x, y, tol);
}

template< class T >
DUNE_DEPRECATED_MSG("THIS WILL BE REMOVED ONCE ExtendedParameterTree::getVector() IS PROPERLY IMPLEMENTED!")
Dune::DynamicVector< T > resize(const Dune::DynamicVector< T >& inVector,
                                const size_t newSize,
                                const T fill = T(0))
{
  Dune::DynamicVector< T > outVector(newSize);
  for (size_t ii = 0; ii < std::min(inVector.size(), newSize); ++ii)
    outVector[ii] = inVector[ii];
  for (size_t ii = std::min(inVector.size(), newSize); ii < newSize; ++ii)
    outVector[ii] = fill;
  return outVector;
}

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH
<|endoftext|>