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

#ifndef _TYPELIB_TYPEDESCRIPTION_H_
#include "typelib/typedescription.h"
#endif
#ifndef _typelib_TypeClass_H_
#include "typelib/typeclass.h"
#endif
#ifndef _UNO_SEQUENCE2_H_
#include "uno/sequence2.h"
#endif
#ifndef _UNO_ANY2_H_
#include "uno/any2.h"
#endif
#ifndef _UNO_DATA_H_
#include "uno/data.h"
#endif
#ifndef _UNO_MAPPING_H_
#include "uno/mapping.h"
#endif
#ifndef _UNO_DISPATCHER_H_
#include "uno/dispatcher.h"
#endif

#ifndef _OSL_INTERLCK_H
#include "osl/interlck.h"
#endif
#ifndef _OSL_DIAGNOSE_H_
#include "osl/diagnose.h"
#endif
#ifndef _RTL_USTRING_HXX
#include "rtl/ustring.hxx"
#endif
#ifndef _RTL_ALLOC_H_
#include "rtl/alloc.h"
#endif

#if OSL_DEBUG_LEVEL > 1
#include "rtl/ustrbuf.hxx"
#include "rtl/string.hxx"
#endif

namespace cppu
{

extern uno_Sequence g_emptySeq;
extern typelib_TypeDescriptionReference * g_pVoidType;

//--------------------------------------------------------------------------------------------------
inline void * _map(
    void * p,
    typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
    uno_Mapping * mapping )
    SAL_THROW( () )
{
    void * pRet = 0;
    if (p)
    {
        if (pTypeDescr)
        {
            (*mapping->mapInterface)(
                mapping, &pRet, p, (typelib_InterfaceTypeDescription *)pTypeDescr );
        }
        else
        {
            TYPELIB_DANGER_GET( &pTypeDescr, pType );
            (*mapping->mapInterface)(
                mapping, &pRet, p, (typelib_InterfaceTypeDescription *)pTypeDescr );
            TYPELIB_DANGER_RELEASE( pTypeDescr );
        }
    }
    return pRet;
}
//--------------------------------------------------------------------------------------------------
inline void _acquire( void * p, uno_AcquireFunc acquire ) SAL_THROW( () )
{
    if (p)
    {
        if (acquire)
        {
            (*acquire)( p );
        }
        else
        {
            (*((uno_Interface *)p)->acquire)( (uno_Interface *)p );
        }
    }
}
//--------------------------------------------------------------------------------------------------
inline void _release( void * p, uno_ReleaseFunc release ) SAL_THROW( () )
{
    if (p)
    {
        if (release)
        {
            (*release)( p );
        }
        else
        {
            (*((uno_Interface *)p)->release)( (uno_Interface *)p );
        }
    }
}

//------------------------------------------------------------------------------
inline sal_uInt32 calcSeqMemSize(
    sal_Int32 nElementSize, sal_Int32 nElements )
{
    sal_uInt64 nSize =
        (sal_uInt64) SAL_SEQUENCE_HEADER_SIZE +
        ((sal_uInt64) nElementSize * (sal_uInt64) nElements);
    if (nSize > 0xffffffffU)
        return 0;
    else
        return (sal_uInt32) nSize;
}

//--------------------------------------------------------------------------------------------------
inline uno_Sequence * createEmptySequence() SAL_THROW( () )
{
    ::osl_incrementInterlockedCount( &g_emptySeq.nRefCount );
    return &g_emptySeq;
}
//--------------------------------------------------------------------------------------------------
inline typelib_TypeDescriptionReference * _getVoidType()
    SAL_THROW( () )
{
    if (! g_pVoidType)
    {
        g_pVoidType = * ::typelib_static_type_getByTypeClass( typelib_TypeClass_VOID );
    }
    ::typelib_typedescriptionreference_acquire( g_pVoidType );
    return g_pVoidType;
}

//--------------------------------------------------------------------------------------------------
#if OSL_DEBUG_LEVEL > 0
#define CONSTRUCT_EMPTY_ANY( pAny ) \
(pAny)->pType = _getVoidType(); \
(pAny)->pData = (void *)0xdeadbeef;
#else
#define CONSTRUCT_EMPTY_ANY( pAny ) \
(pAny)->pType = _getVoidType(); \
(pAny)->pData = (pAny);
#endif

//--------------------------------------------------------------------------------------------------
#define TYPE_ACQUIRE( pType ) \
    ::osl_incrementInterlockedCount( &(pType)->nRefCount );

//--------------------------------------------------------------------------------------------------
extern "C" void * binuno_queryInterface(
    void * pUnoI, typelib_TypeDescriptionReference * pDestType );

//--------------------------------------------------------------------------------------------------
inline typelib_TypeDescriptionReference * _unionGetSetType(
    void * pUnion, typelib_TypeDescription * pTD )
    SAL_THROW( () )
{
    typelib_TypeDescriptionReference * pRet = 0;
    sal_Int32 nPos;

    sal_Int64 * pDiscr = ((typelib_UnionTypeDescription *)pTD)->pDiscriminants;
    sal_Int64 nDiscr   = *(sal_Int64 *)pUnion;
    for ( nPos = ((typelib_UnionTypeDescription *)pTD)->nMembers; nPos--; )
    {
        if (pDiscr[nPos] == nDiscr)
        {
            pRet = ((typelib_UnionTypeDescription *)pTD)->ppTypeRefs[nPos];
            break;
        }
    }
    if (nPos >= 0)
    {
        // default
        pRet = ((typelib_UnionTypeDescription *)pTD)->pDefaultTypeRef;
    }
    typelib_typedescriptionreference_acquire( pRet );
    return pRet;
}
//--------------------------------------------------------------------------------------------------
inline sal_Bool _type_equals(
    typelib_TypeDescriptionReference * pType1, typelib_TypeDescriptionReference * pType2 )
    SAL_THROW( () )
{
    return (pType1 == pType2 ||
            (pType1->eTypeClass == pType2->eTypeClass &&
             pType1->pTypeName->length == pType2->pTypeName->length &&
             ::rtl_ustr_compare( pType1->pTypeName->buffer, pType2->pTypeName->buffer ) == 0));
}

}

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.17.84); FILE MERGED 2008/04/01 15:10:35 thb 1.17.84.3: #i85898# Stripping all external header guards 2008/04/01 12:28:03 thb 1.17.84.2: #i85898# Stripping all external header guards 2008/03/31 07:23:22 rt 1.17.84.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: prim.hxx,v $
 * $Revision: 1.18 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef PRIM_HXX
#define PRIM_HXX

#include "typelib/typedescription.h"
#ifndef _typelib_TypeClass_H_
#include "typelib/typeclass.h"
#endif
#include "uno/sequence2.h"
#include "uno/any2.h"
#include "uno/data.h"
#include "uno/mapping.h"
#include "uno/dispatcher.h"

#ifndef _OSL_INTERLCK_H
#include "osl/interlck.h"
#endif
#include "osl/diagnose.h"
#ifndef _RTL_USTRING_HXX
#include "rtl/ustring.hxx"
#endif
#include "rtl/alloc.h"

#if OSL_DEBUG_LEVEL > 1
#include "rtl/ustrbuf.hxx"
#include "rtl/string.hxx"
#endif

namespace cppu
{

extern uno_Sequence g_emptySeq;
extern typelib_TypeDescriptionReference * g_pVoidType;

//--------------------------------------------------------------------------------------------------
inline void * _map(
    void * p,
    typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
    uno_Mapping * mapping )
    SAL_THROW( () )
{
    void * pRet = 0;
    if (p)
    {
        if (pTypeDescr)
        {
            (*mapping->mapInterface)(
                mapping, &pRet, p, (typelib_InterfaceTypeDescription *)pTypeDescr );
        }
        else
        {
            TYPELIB_DANGER_GET( &pTypeDescr, pType );
            (*mapping->mapInterface)(
                mapping, &pRet, p, (typelib_InterfaceTypeDescription *)pTypeDescr );
            TYPELIB_DANGER_RELEASE( pTypeDescr );
        }
    }
    return pRet;
}
//--------------------------------------------------------------------------------------------------
inline void _acquire( void * p, uno_AcquireFunc acquire ) SAL_THROW( () )
{
    if (p)
    {
        if (acquire)
        {
            (*acquire)( p );
        }
        else
        {
            (*((uno_Interface *)p)->acquire)( (uno_Interface *)p );
        }
    }
}
//--------------------------------------------------------------------------------------------------
inline void _release( void * p, uno_ReleaseFunc release ) SAL_THROW( () )
{
    if (p)
    {
        if (release)
        {
            (*release)( p );
        }
        else
        {
            (*((uno_Interface *)p)->release)( (uno_Interface *)p );
        }
    }
}

//------------------------------------------------------------------------------
inline sal_uInt32 calcSeqMemSize(
    sal_Int32 nElementSize, sal_Int32 nElements )
{
    sal_uInt64 nSize =
        (sal_uInt64) SAL_SEQUENCE_HEADER_SIZE +
        ((sal_uInt64) nElementSize * (sal_uInt64) nElements);
    if (nSize > 0xffffffffU)
        return 0;
    else
        return (sal_uInt32) nSize;
}

//--------------------------------------------------------------------------------------------------
inline uno_Sequence * createEmptySequence() SAL_THROW( () )
{
    ::osl_incrementInterlockedCount( &g_emptySeq.nRefCount );
    return &g_emptySeq;
}
//--------------------------------------------------------------------------------------------------
inline typelib_TypeDescriptionReference * _getVoidType()
    SAL_THROW( () )
{
    if (! g_pVoidType)
    {
        g_pVoidType = * ::typelib_static_type_getByTypeClass( typelib_TypeClass_VOID );
    }
    ::typelib_typedescriptionreference_acquire( g_pVoidType );
    return g_pVoidType;
}

//--------------------------------------------------------------------------------------------------
#if OSL_DEBUG_LEVEL > 0
#define CONSTRUCT_EMPTY_ANY( pAny ) \
(pAny)->pType = _getVoidType(); \
(pAny)->pData = (void *)0xdeadbeef;
#else
#define CONSTRUCT_EMPTY_ANY( pAny ) \
(pAny)->pType = _getVoidType(); \
(pAny)->pData = (pAny);
#endif

//--------------------------------------------------------------------------------------------------
#define TYPE_ACQUIRE( pType ) \
    ::osl_incrementInterlockedCount( &(pType)->nRefCount );

//--------------------------------------------------------------------------------------------------
extern "C" void * binuno_queryInterface(
    void * pUnoI, typelib_TypeDescriptionReference * pDestType );

//--------------------------------------------------------------------------------------------------
inline typelib_TypeDescriptionReference * _unionGetSetType(
    void * pUnion, typelib_TypeDescription * pTD )
    SAL_THROW( () )
{
    typelib_TypeDescriptionReference * pRet = 0;
    sal_Int32 nPos;

    sal_Int64 * pDiscr = ((typelib_UnionTypeDescription *)pTD)->pDiscriminants;
    sal_Int64 nDiscr   = *(sal_Int64 *)pUnion;
    for ( nPos = ((typelib_UnionTypeDescription *)pTD)->nMembers; nPos--; )
    {
        if (pDiscr[nPos] == nDiscr)
        {
            pRet = ((typelib_UnionTypeDescription *)pTD)->ppTypeRefs[nPos];
            break;
        }
    }
    if (nPos >= 0)
    {
        // default
        pRet = ((typelib_UnionTypeDescription *)pTD)->pDefaultTypeRef;
    }
    typelib_typedescriptionreference_acquire( pRet );
    return pRet;
}
//--------------------------------------------------------------------------------------------------
inline sal_Bool _type_equals(
    typelib_TypeDescriptionReference * pType1, typelib_TypeDescriptionReference * pType2 )
    SAL_THROW( () )
{
    return (pType1 == pType2 ||
            (pType1->eTypeClass == pType2->eTypeClass &&
             pType1->pTypeName->length == pType2->pTypeName->length &&
             ::rtl_ustr_compare( pType1->pTypeName->buffer, pType2->pTypeName->buffer ) == 0));
}

}

#endif
<|endoftext|>


<commit_before>#ifndef __TASK_DISTRIBUTION__RUNNABLE_HPP__
#define __TASK_DISTRIBUTION__RUNNABLE_HPP__

#include <boost/program_options.hpp>

#include "object_archive.hpp"
#include "task_manager.hpp"

namespace po = boost::program_options;

namespace TaskDistribution {
  class Runnable {
    public:
      Runnable(int argc, char* argv[], ObjectArchive<Key>& archive,
          TaskManager& task_manager);

      virtual void create_tasks() = 0;
      virtual void process_results() { }

      int process();
      void print_status();

      void check();
      void clean();
      void invalidate(std::string const& unit_name);
      void run();

      void update_unit_map();

    protected:
      void task_creation_handler(std::string const& name, Key const& key);
      void task_begin_handler(Key const& key);
      void task_end_handler(Key const& key);

      void clean_tasks();
      void invalidate_unit(std::string const& unit_name);
      void remove_result(Key const& task_key);
      size_t remove_task(Key const& task_key, KeySet& possible_removals);
      void clean_possible_removals(KeySet& possible_removals,
          KeySet const& created_tasks);
      void relocate_keys();
      void replace_key(Key const& task_key, Key const& current_key,
          Key const& new_key);

      struct UnitEntry {
        UnitEntry(): waiting(0), running(0), finished(0) { }

        KeySet keys;
        size_t waiting, running, finished;
      };

      std::map<std::string, UnitEntry> map_units_to_tasks_;

      ObjectArchive<Key>& archive_;
      TaskManager& task_manager_;

      po::variables_map vm;

      po::options_description cmd_args;
      po::options_description help_args;
      po::options_description invalidate_args;
  };
};

#endif
<commit_msg>Added documentation to runnable.hpp.<commit_after>// For better interface with the user and control of the tasks, a standard
// command line interface is defines in this file.
//
// A Runnable allows 4 kinds of commands:
// 1) check the list of tasks created;
// 2) clean the archive;
// 3) invalidate a given task set;
// 4) run the tasks.
//
// The "check" command only prints the status of each task type, with the number
// of tasks waiting execution and number of tasks finished.
//
// The "clean" command deletes everything from the archive that isn't used by
// the tasks provided. For instance, if some task isn't performed anymore, it
// may leave some debree inside the archive which occupies space, slows start-up
// and isn't useful. The command deletes these entries and re-arranges the keys
// to be occupy new free slots.
//
// The "invalidate" command MUST be used with an option "-i" to avoid mistakenly
// invalidating a task set. This command deletes every result of the set and
// every other task that depends on the original set. This should be used when
// the implementation of a task has changed.
//
// The "run" command just performs the computations, which can happen either
// with or without MPI.
//
// The current status of tasks is shown by commands "check", "clean" and
// "invalidate". The command "run" re-prints the table as each task is
// performed, allowing the user to keep track. The name used to print the table
// is the name associated with the computing unit.
//
// The user must inherit the class described here and provide:
// 1) the method "create_tasks()", which just creates all tasks to be computed;
// 2) the method "process_results()" is optional, and is called after all tasks
// are computed and every time the class is run.
//
// For an example on how to use it, check the file example/example.cpp.

#ifndef __TASK_DISTRIBUTION__RUNNABLE_HPP__
#define __TASK_DISTRIBUTION__RUNNABLE_HPP__

#include <boost/program_options.hpp>

#include "object_archive.hpp"
#include "task_manager.hpp"

namespace po = boost::program_options;

namespace TaskDistribution {
  class Runnable {
    public:
      Runnable(int argc, char* argv[], ObjectArchive<Key>& archive,
          TaskManager& task_manager);

      // Creates the tasks that must be computed.
      virtual void create_tasks() = 0;

      // Process the results of the tasks.
      virtual void process_results() { }

      // Interprets the command line arguments and returns 0 if everything was
      // OK.
      int process();

      // Creates the metadata displayed on the tasks table. This should be
      // called after create_tasks().
      void create_unit_map();

      // Prints the tasks status. This should be called after create_unit_map().
      void print_status();

      // Performs the check command.
      void check();

      // Performs the clean command.
      void clean();

      // Performs the invalidate command for a given unit name.
      void invalidate(std::string const& unit_name);

      // Performs the run command.
      void run();

    protected:
      // Handlers given to TaskManager to get feedback about what is happening
      // with the tasks.
      void task_creation_handler(std::string const& name, Key const& key);
      void task_begin_handler(Key const& key);
      void task_end_handler(Key const& key);

      // Removes everything from the archive that isn't used by the current
      // known tasks.
      void clean_tasks();

      // Invalidate all tasks of the given unit name.
      void invalidate_unit(std::string const& unit_name);

      // Removes the result associated with the given task and all its children.
      void remove_result(Key const& task_key);

      // Removes everything possible from a task and adds the rest to the set of
      // possible removals, as some data may be shared by multiple tasks.
      size_t remove_task(Key const& task_key, KeySet& possible_removals);

      // Remove everything from the set of possible removals that are used by
      // the known tasks.
      void clean_possible_removals(KeySet& possible_removals,
          KeySet const& created_tasks);

      // Changes keys to reduce sparsity.
      void relocate_keys();

      // Replaces a given key by another key in a task entry, described by the
      // task key.
      void replace_key(Key const& task_key, Key const& current_key,
          Key const& new_key);

      // Structure to hold every information required about a given unit.
      struct UnitEntry {
        UnitEntry(): waiting(0), running(0), finished(0) { }

        KeySet keys;
        // Number of tasks in each state.
        size_t waiting, running, finished;
      };

      // Map between unit names and their entries.
      std::map<std::string, UnitEntry> map_units_to_tasks_;

      ObjectArchive<Key>& archive_;
      TaskManager& task_manager_;

      // Command line interpretation variables.
      po::variables_map vm_;
      po::options_description cmd_args_;
      po::options_description help_args_;
      po::options_description invalidate_args_;
  };
};

#endif
<|endoftext|>


<commit_before>

#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "au/file.h"
#include "au/string.h"
#include "au/utils.h"

#include "au/console/ConsoleAutoComplete.h"  // Own interface

namespace au {
char get_last_char(std::string txt) {
  if (txt.length() == 0) {
    return 0;
  } else {
    return txt[ txt.length() - 1 ];
  }
}

ConsoleAutoComplete::ConsoleAutoComplete(std::string command) {
  current_command = command;

  // Get all the words so far and the last word
  au::split(command, ' ', previous_words);
  if (command.length() > 0) {
    if (command[command.length() - 1] != ' ') {
      last_word = previous_words.back();
      previous_words.pop_back();
    }
  }
  add_space_if_unique_alternative = true;
}

int ConsoleAutoComplete::completingWord() {
  return previous_words.size();
}

std::string ConsoleAutoComplete::firstWord() {
  if (previous_words.size() < 1) {
    return "";
  }
  return previous_words[0];
}

std::string ConsoleAutoComplete::lastCompletedWord() {
  if (previous_words.size() > 0) {
    return previous_words[ previous_words.size() - 1 ];
  }
  return "";
}

std::string ConsoleAutoComplete::secondWord() {
  if (previous_words.size() < 2) {
    return "";
  }
  return previous_words[1];
}

bool ConsoleAutoComplete::completingSecondWord(std::string first_word) {
  if (previous_words.size() == 1) {
    if (previous_words[0] == first_word) {
      return true;
    }
  }
  return false;
}

bool ConsoleAutoComplete::completingFirstWord() {
  return (previous_words.size() == 0);
}

bool ConsoleAutoComplete::completingSecondWord() {
  return (previous_words.size() == 1);
}

bool ConsoleAutoComplete::completingThirdWord() {
  return (previous_words.size() == 2);
}

bool ConsoleAutoComplete::completingThirdWord(std::string first_word, std::string second_word) {
  if (previous_words.size() != 2) {
    return false;
  }

  if (( first_word != "*" ) && ( previous_words[0] != first_word )) {
    return false;
  }
  if (( second_word != "*" ) && ( previous_words[1] != second_word )) {
    return false;
  }

  return true;
}

std::string ConsoleAutoComplete::getCurrentCommand() {
  return current_command;
}

void ConsoleAutoComplete::add(const std::string& command) {
  add(ConsoleAutoCompleteAlternative(command));
}

void ConsoleAutoComplete::add(std::vector<std::string> commands) {
  for (size_t i = 0; i <  commands.size(); i++) {
    add(commands[i]);
  }
}

void ConsoleAutoComplete::add(const std::string& label, const std::string& command, bool add_space) {
  add(ConsoleAutoCompleteAlternative(label, command, add_space));
}

void ConsoleAutoComplete::add(ConsoleAutoCompleteAlternative alternative) {
  if (alternative.command.length() < last_word.length()) {
    return;   // Not valid candidate
  }
  // Check if it was previously included...
  for (size_t i = 0; i < last_word_alternatives.size(); i++) {
    if (last_word_alternatives[i].command == alternative.command) {
      return;
    }
  }

  if (strings_begin_equal(alternative.command, last_word)) {
    last_word_alternatives.push_back(alternative);
  }
}

void ConsoleAutoComplete::auto_complete_files(std::string file_selector) {
  std::string directory = get_directory_from_path(last_word);      // By default, take the last work as the directory to go
  std::string base = path_remove_last_component(last_word);

  if (( base.length() > 0 ) && ( base != "/" )) {
    base.append("/");  // printf("Last word '%s' dir='%s' base='%s'\n", last_word.c_str() , directory.c_str() , base.c_str() );
  }
  // Try to open directory
  DIR *dp;
  struct dirent *dirp;
  if ((dp  = opendir(directory.c_str())) == NULL) {
    return;   // Nothing else to do...
  }
  while ((dirp = readdir(dp)) != NULL) {
    std::string fileName = dirp->d_name;

    // Skip ".files"
    if (fileName.length() > 0) {
      if (fileName[0] == '.') {
        continue;  // Full path of the file
      }
    }
    std::string path = path_from_directory(directory, dirp->d_name);

    struct ::stat info;
    stat(path.c_str(), &info);

    if (S_ISREG(info.st_mode)) {
      if (string_ends(path, file_selector)) {
        // Final string to show
        size_t size = info.st_size;

        add(
          au::str("%s (%s)", fileName.c_str(), au::str(size, "B").c_str())
          , base + fileName
          , true
          );
      }
    } else if (S_ISDIR(info.st_mode)) {
      add(fileName + "/", base + fileName + "/", false);
    }
  }

  closedir(dp);
}

void ConsoleAutoComplete::setHelpMessage(std::string _help_message) {
  help_message = _help_message;
}

int ConsoleAutoComplete::common_chars_in_last_word_alternative() {
  if (last_word_alternatives.size() == 0) {
    return 0;
  }

  int common_chars = last_word_alternatives[0].command.length();
  for (size_t i = 1; i < last_word_alternatives.size(); i++) {
    int n = getCommonChars(last_word_alternatives[i].command, last_word_alternatives[i - 1].command);
    if (n < common_chars) {
      common_chars = n;
    }
  }

  return common_chars;
}

std::string ConsoleAutoComplete::stringToAppend() {
  // If no options, return the previous one...
  if (last_word_alternatives.size() == 0) {
    return "";
  }

  int last_word_length = last_word.length();
  int common_chars = common_chars_in_last_word_alternative();

  std::string complete_text = last_word_alternatives[0].command.substr(last_word_length,
                                                                       common_chars - last_word_length);

  // printf("Complete %s", complete_text.c_str());
  if (last_word_alternatives.size() == 1) {
    if (last_word_alternatives[0].add_space_if_unique) {
      return complete_text + " ";
    } else {
      return complete_text;
    }
  } else {
    return complete_text;
  }
}

std::string ConsoleAutoComplete::getHelpMessage() {
  return help_message;
}

bool ConsoleAutoComplete::necessary_print_last_words_alternatives() {
  if (last_word_alternatives.size() == 0) {
    return false;
  }

  if (last_word_alternatives.size() == 1) {
    return false;
  }

  int last_word_length = last_word.length();
  int common_chars = common_chars_in_last_word_alternative();

  return (last_word_length == common_chars);
}

void ConsoleAutoComplete::print_last_words_alternatives() {
  if (!necessary_print_last_words_alternatives()) {
    return;
  }

  int columns = getTerminalColumns();
  int max_length = 0;
  for (size_t i = 0; i < last_word_alternatives.size(); i++) {
    int n = last_word_alternatives[i].label.length();
    if (n > max_length) {
      max_length = n;
    }
  }

  int num_words_per_row = columns / ( max_length + 1 );
  if (num_words_per_row == 0) {
    num_words_per_row = 1;
  }
  for (size_t i = 0; i < last_word_alternatives.size(); i++)
  {

    std::ostringstream output;

    output << last_word_alternatives[i].bold_label( last_word );
    for ( int j = 0 ; j < ( max_length  - last_word_alternatives[i].label.length() ) ; j++ )
      output << " ";
    output << " ";

    // Print command and help
    printf("%s",output.str().c_str());

    if ((i % num_words_per_row) == (size_t)(num_words_per_row - 1)) {
      printf("\n");
    }
  }

  if (((last_word_alternatives.size() - 1) % num_words_per_row) != (size_t)(num_words_per_row - 1)) {
    printf("\n");
  }
}
}
<commit_msg>Fix minor error for compilation in al linux platforms<commit_after>

#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "au/file.h"
#include "au/string.h"
#include "au/utils.h"

#include "au/console/ConsoleAutoComplete.h"  // Own interface

namespace au {
char get_last_char(std::string txt) {
  if (txt.length() == 0) {
    return 0;
  } else {
    return txt[ txt.length() - 1 ];
  }
}

ConsoleAutoComplete::ConsoleAutoComplete(std::string command) {
  current_command = command;

  // Get all the words so far and the last word
  au::split(command, ' ', previous_words);
  if (command.length() > 0) {
    if (command[command.length() - 1] != ' ') {
      last_word = previous_words.back();
      previous_words.pop_back();
    }
  }
  add_space_if_unique_alternative = true;
}

int ConsoleAutoComplete::completingWord() {
  return previous_words.size();
}

std::string ConsoleAutoComplete::firstWord() {
  if (previous_words.size() < 1) {
    return "";
  }
  return previous_words[0];
}

std::string ConsoleAutoComplete::lastCompletedWord() {
  if (previous_words.size() > 0) {
    return previous_words[ previous_words.size() - 1 ];
  }
  return "";
}

std::string ConsoleAutoComplete::secondWord() {
  if (previous_words.size() < 2) {
    return "";
  }
  return previous_words[1];
}

bool ConsoleAutoComplete::completingSecondWord(std::string first_word) {
  if (previous_words.size() == 1) {
    if (previous_words[0] == first_word) {
      return true;
    }
  }
  return false;
}

bool ConsoleAutoComplete::completingFirstWord() {
  return (previous_words.size() == 0);
}

bool ConsoleAutoComplete::completingSecondWord() {
  return (previous_words.size() == 1);
}

bool ConsoleAutoComplete::completingThirdWord() {
  return (previous_words.size() == 2);
}

bool ConsoleAutoComplete::completingThirdWord(std::string first_word, std::string second_word) {
  if (previous_words.size() != 2) {
    return false;
  }

  if (( first_word != "*" ) && ( previous_words[0] != first_word )) {
    return false;
  }
  if (( second_word != "*" ) && ( previous_words[1] != second_word )) {
    return false;
  }

  return true;
}

std::string ConsoleAutoComplete::getCurrentCommand() {
  return current_command;
}

void ConsoleAutoComplete::add(const std::string& command) {
  add(ConsoleAutoCompleteAlternative(command));
}

void ConsoleAutoComplete::add(std::vector<std::string> commands) {
  for (size_t i = 0; i <  commands.size(); i++) {
    add(commands[i]);
  }
}

void ConsoleAutoComplete::add(const std::string& label, const std::string& command, bool add_space) {
  add(ConsoleAutoCompleteAlternative(label, command, add_space));
}

void ConsoleAutoComplete::add(ConsoleAutoCompleteAlternative alternative) {
  if (alternative.command.length() < last_word.length()) {
    return;   // Not valid candidate
  }
  // Check if it was previously included...
  for (size_t i = 0; i < last_word_alternatives.size(); i++) {
    if (last_word_alternatives[i].command == alternative.command) {
      return;
    }
  }

  if (strings_begin_equal(alternative.command, last_word)) {
    last_word_alternatives.push_back(alternative);
  }
}

void ConsoleAutoComplete::auto_complete_files(std::string file_selector) {
  std::string directory = get_directory_from_path(last_word);      // By default, take the last work as the directory to go
  std::string base = path_remove_last_component(last_word);

  if (( base.length() > 0 ) && ( base != "/" )) {
    base.append("/");  // printf("Last word '%s' dir='%s' base='%s'\n", last_word.c_str() , directory.c_str() , base.c_str() );
  }
  // Try to open directory
  DIR *dp;
  struct dirent *dirp;
  if ((dp  = opendir(directory.c_str())) == NULL) {
    return;   // Nothing else to do...
  }
  while ((dirp = readdir(dp)) != NULL) {
    std::string fileName = dirp->d_name;

    // Skip ".files"
    if (fileName.length() > 0) {
      if (fileName[0] == '.') {
        continue;  // Full path of the file
      }
    }
    std::string path = path_from_directory(directory, dirp->d_name);

    struct ::stat info;
    stat(path.c_str(), &info);

    if (S_ISREG(info.st_mode)) {
      if (string_ends(path, file_selector)) {
        // Final string to show
        size_t size = info.st_size;

        add(
          au::str("%s (%s)", fileName.c_str(), au::str(size, "B").c_str())
          , base + fileName
          , true
          );
      }
    } else if (S_ISDIR(info.st_mode)) {
      add(fileName + "/", base + fileName + "/", false);
    }
  }

  closedir(dp);
}

void ConsoleAutoComplete::setHelpMessage(std::string _help_message) {
  help_message = _help_message;
}

int ConsoleAutoComplete::common_chars_in_last_word_alternative() {
  if (last_word_alternatives.size() == 0) {
    return 0;
  }

  int common_chars = last_word_alternatives[0].command.length();
  for (size_t i = 1; i < last_word_alternatives.size(); i++) {
    int n = getCommonChars(last_word_alternatives[i].command, last_word_alternatives[i - 1].command);
    if (n < common_chars) {
      common_chars = n;
    }
  }

  return common_chars;
}

std::string ConsoleAutoComplete::stringToAppend() {
  // If no options, return the previous one...
  if (last_word_alternatives.size() == 0) {
    return "";
  }

  int last_word_length = last_word.length();
  int common_chars = common_chars_in_last_word_alternative();

  std::string complete_text = last_word_alternatives[0].command.substr(last_word_length,
                                                                       common_chars - last_word_length);

  // printf("Complete %s", complete_text.c_str());
  if (last_word_alternatives.size() == 1) {
    if (last_word_alternatives[0].add_space_if_unique) {
      return complete_text + " ";
    } else {
      return complete_text;
    }
  } else {
    return complete_text;
  }
}

std::string ConsoleAutoComplete::getHelpMessage() {
  return help_message;
}

bool ConsoleAutoComplete::necessary_print_last_words_alternatives() {
  if (last_word_alternatives.size() == 0) {
    return false;
  }

  if (last_word_alternatives.size() == 1) {
    return false;
  }

  int last_word_length = last_word.length();
  int common_chars = common_chars_in_last_word_alternative();

  return (last_word_length == common_chars);
}

void ConsoleAutoComplete::print_last_words_alternatives() {
  if (!necessary_print_last_words_alternatives()) {
    return;
  }

  int columns = getTerminalColumns();
  int max_length = 0;
  for (size_t i = 0; i < last_word_alternatives.size(); i++) {
    int n = last_word_alternatives[i].label.length();
    if (n > max_length) {
      max_length = n;
    }
  }

  int num_words_per_row = columns / ( max_length + 1 );
  if (num_words_per_row == 0) {
    num_words_per_row = 1;
  }
  for (size_t i = 0; i < last_word_alternatives.size(); i++)
  {

    std::ostringstream output;

    output << last_word_alternatives[i].bold_label( last_word );
    for ( int j = 0 ; j < (int)( max_length  - last_word_alternatives[i].label.length() ) ; j++ )
      output << " ";
    output << " ";

    // Print command and help
    printf("%s",output.str().c_str());

    if ((i % num_words_per_row) == (size_t)(num_words_per_row - 1)) {
      printf("\n");
    }
  }

  if (((last_word_alternatives.size() - 1) % num_words_per_row) != (size_t)(num_words_per_row - 1)) {
    printf("\n");
  }
}
}
<|endoftext|>


<commit_before>#pragma once

#include <cstdint>

namespace stx {

namespace hash_type {

struct fnv_1a_64bit {
	using value_type = uint64_t;
	using state_type = uint64_t;

	constexpr static uint64_t FnvPrime    = 1099511628211UL;
	constexpr static uint64_t OffsetBasis = 14695981039346656037UL;

	constexpr static inline
	state_type create_state() noexcept {
		return OffsetBasis;
	}

	constexpr static inline
	state_type increment_hash(state_type state, const char* data, std::size_t len) noexcept {
		for (std::size_t i = 0; i < len; i++) {
			state ^= data[i];
			state *= FnvPrime;
		}
		return state;
	}

	template<std::size_t len> constexpr static inline
	value_type constexpr_hash_strn(const char (&strn)[len]) noexcept {
		state_type state = create_state();
		for(char c : strn) {
			state ^= c;
			state *= FnvPrime;
		}
		return state;
	}
};

struct fnv_1a_32bit {
	using value_type = uint32_t;
	using state_type = uint32_t;

	constexpr static uint32_t FnvPrime    = 16777619U;
	constexpr static uint32_t OffsetBasis = 2166136261U;

	constexpr static inline
	state_type create_state() noexcept {
		return OffsetBasis;
	}

	constexpr static
	state_type increment_hash(state_type state, const char* data, std::size_t len) noexcept {
		for (std::size_t i = 0; i < len; i++) {
			state ^= data[i];
			state *= FnvPrime;
		}
		return state;
	}

	template<std::size_t len> constexpr static
	value_type constexpr_hash_strn(const char (&strn)[len]) noexcept {
		state_type state = create_state();
		for(char c : strn) {
			state ^= c;
			state *= FnvPrime;
		}
		return state;
	}
};

struct fnv_1a_32bit_xor_folded {
	using value_type = uint16_t;
	using state_type = typename fnv_1a_32bit::state_type;

	constexpr static inline
	state_type create_state() noexcept {
		return fnv_1a_32bit::create_state();
	}

	constexpr static inline
	state_type increment_hash(const state_type& state, const char* data, std::size_t len) noexcept {
		return fnv_1a_32bit::increment_hash(state, data, len);
	}

	constexpr static inline
	value_type collapse_hash(const state_type& state) noexcept {
		return ((state << 16) ^ state);
	}

	template<std::size_t len> constexpr static inline
	value_type constexpr_hash_strn(const char (&strn)[len]) noexcept {
		value_type val = fnv_1a_32bit::constexpr_hash_strn(strn);
		return ((val << 16) ^ val);
	}
};

using fast64 = fnv_1a_64bit;
using fast32 = fnv_1a_32bit;
using fast   = fnv_1a_64bit;

using default_hash = fast64;

} // namespace hash_type

template<typename hashtype = hash_type::default_hash>
struct basic_hash {
	using value_type = typename hashtype::value_type;
	using state_type = typename hashtype::state_type;

	value_type value;

	inline
	operator value_type() const noexcept { return value; }
};

template<typename hashtype = hash_type::default_hash>
struct basic_symbol {
	const typename hashtype::value_type hash;
	const char*                         value;
	const std::size_t                   length;

	template<std::size_t len> constexpr // implicit
	basic_symbol(const char (&strn)[len]) :
		hash(hashtype::constexpr_hash_strn(strn)),
		value(strn),
		length(len)
	{}
};

using hash   = basic_hash<>;
using symbol = basic_symbol<>;

using hash16   = basic_hash<hash_type::fnv_1a_32bit_xor_folded>;
using symbol16 = basic_symbol<hash_type::fnv_1a_32bit_xor_folded>;

using hash32   = basic_hash<hash_type::fnv_1a_32bit>;
using symbol32 = basic_symbol<hash_type::fnv_1a_32bit>;

using hash64   = basic_hash<hash_type::fnv_1a_64bit>;
using symbol64 = basic_symbol<hash_type::fnv_1a_64bit>;

} // namespace stx

namespace std {

template<typename T>
struct hash;

template<typename H>
struct hash<::stx::basic_symbol<H>> {
	size_t operator()(const ::stx::basic_symbol<H>& sym) const noexcept {
		return sym.hash;
	}
};

template<typename H>
struct hash<stx::basic_hash<H>> {
	size_t operator()(const stx::basic_hash<H>& h) const noexcept {
		return h.value;
	}
};

} // namespace std
<commit_msg>Further implemented hash.hpp (e.g. added finalize_hash everywhere)<commit_after>#pragma once

#include <cstdint>

namespace stx {

namespace hash_type {

struct fnv_1a_64bit {
	using value_type = uint64_t;
	using state_type = uint64_t;

	constexpr static uint64_t FnvPrime    = 1099511628211UL;
	constexpr static uint64_t OffsetBasis = 14695981039346656037UL;

	constexpr static inline
	state_type create_state() noexcept {
		return OffsetBasis;
	}

	constexpr static inline
	state_type increment_hash(state_type state, const char* data, std::size_t len) noexcept {
		for (std::size_t i = 0; i < len; i++) {
			state ^= data[i];
			state *= FnvPrime;
		}
		return state;
	}

	constexpr static inline
	value_type finalize_hash(const state_type& state) noexcept {
		return state;
	}

	template<std::size_t len> constexpr static inline
	value_type constexpr_hash_strn(const char (&strn)[len]) noexcept {
		state_type state = create_state();
		for(char c : strn) {
			state ^= c;
			state *= FnvPrime;
		}
		return state;
	}
};

struct fnv_1a_32bit {
	using value_type = uint32_t;
	using state_type = uint32_t;

	constexpr static uint32_t FnvPrime    = 16777619U;
	constexpr static uint32_t OffsetBasis = 2166136261U;

	constexpr static inline
	state_type create_state() noexcept {
		return OffsetBasis;
	}

	constexpr static
	state_type increment_hash(state_type state, const char* data, std::size_t len) noexcept {
		for (std::size_t i = 0; i < len; i++) {
			state ^= data[i];
			state *= FnvPrime;
		}
		return state;
	}

	constexpr static inline
	value_type finalize_hash(const state_type& state) noexcept {
		return state;
	}

	template<std::size_t len> constexpr static
	value_type constexpr_hash_strn(const char (&strn)[len]) noexcept {
		state_type state = create_state();
		for(char c : strn) {
			state ^= c;
			state *= FnvPrime;
		}
		return state;
	}
};

struct fnv_1a_32bit_xor_folded {
	using value_type = uint16_t;
	using state_type = typename fnv_1a_32bit::state_type;

	constexpr static inline
	state_type create_state() noexcept {
		return fnv_1a_32bit::create_state();
	}

	constexpr static inline
	state_type increment_hash(const state_type& state, const char* data, std::size_t len) noexcept {
		return fnv_1a_32bit::increment_hash(state, data, len);
	}

	constexpr static inline
	value_type finalize_hash(const state_type& state) noexcept {
		return ((state << 16) ^ state);
	}

	template<std::size_t len> constexpr static inline
	value_type constexpr_hash_strn(const char (&strn)[len]) noexcept {
		value_type val = fnv_1a_32bit::constexpr_hash_strn(strn);
		return ((val << 16) ^ val);
	}
};

using fast64 = fnv_1a_64bit;
using fast32 = fnv_1a_32bit;
using fast   = fnv_1a_64bit;

using default_hash = fast64;

} // namespace hash_type

template<typename hashtype = hash_type::default_hash>
struct basic_hash {
	using value_type = typename hashtype::value_type;
	using state_type = typename hashtype::state_type;

	value_type value;

	inline
	operator value_type() const noexcept { return value; }
};

template<typename hashtype = hash_type::default_hash>
class basic_symbol {
	using Tself = basic_symbol<hashtype>;
	using hash_value = typename hashtype::value_type;

	constexpr inline
	basic_symbol(const char* v, std::size_t len, hash_value h) :
		hash(h),
		value(v),
		length(len)
	{}
public:
	const hash_value  hash;
	const char*       value;
	const std::size_t length;

	template<std::size_t len> constexpr // implicit
	basic_symbol(const char (&strn)[len]) :
		hash(hashtype::constexpr_hash_strn(strn)),
		value(strn),
		length(len)
	{}

	constexpr inline
	static Tself unsafe_construct(const char* data, std::size_t len) {
		auto hash = hashtype::finalize_hash(
			hashtype::increment_hash(
				hashtype::create_state(),
				data, len
			)
		);
		return Tself(data, len, hash);
	}

	constexpr inline
	operator const char*() const noexcept {
		return value;
	}

	constexpr inline
	operator hash_value() const noexcept {
		return hash;
	}
};

using hash   = basic_hash<>;
using symbol = basic_symbol<>;

using hash16   = basic_hash<hash_type::fnv_1a_32bit_xor_folded>;
using symbol16 = basic_symbol<hash_type::fnv_1a_32bit_xor_folded>;

using hash32   = basic_hash<hash_type::fnv_1a_32bit>;
using symbol32 = basic_symbol<hash_type::fnv_1a_32bit>;

using hash64   = basic_hash<hash_type::fnv_1a_64bit>;
using symbol64 = basic_symbol<hash_type::fnv_1a_64bit>;

constexpr inline
symbol operator "" _sym(const char* strn, std::size_t len) {
	return symbol::unsafe_construct(strn, len);
}

} // namespace stx

namespace std {

template<typename T>
struct hash;

template<typename H>
struct hash<::stx::basic_symbol<H>> {
	size_t operator()(const ::stx::basic_symbol<H>& sym) const noexcept {
		return sym.hash;
	}
};

template<typename H>
struct hash<stx::basic_hash<H>> {
	size_t operator()(const stx::basic_hash<H>& h) const noexcept {
		return h.value;
	}
};

} // namespace std
<|endoftext|>


<commit_before>//
// Created by david on 2018-10-30.
//

#include "arpack_solver.h"
#include "matrix_product_dense.h"
#include "matrix_product_hamiltonian.h"
#include "matrix_product_sparse.h"
#include <general/nmspc_sfinae.h>

#if defined(_MKL_LAPACK_H_)
    #error MKL_LAPACK IS NOT SUPPOSED TO BE DEFINED HERE
#endif

#if defined(LAPACK_H)
    #error LAPACK IS NOT SUPPOSED TO BE DEFINED HERE
#endif

#if defined(__clang__)
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Woverloaded-virtual"
#elif defined(__GNUC__) || defined(__GNUG__)
#endif

#if __has_include(<arpackpp/arcomp.h>)
    #include <arpackpp/arcomp.h>
    #include <arpackpp/ardnsmat.h>
    #include <arpackpp/ardscomp.h>
    #include <arpackpp/arsnsym.h>
    #include <arpackpp/arssym.h>
#elif __has_include(<arpack++/arcomp.h>)
    #include <arpack++/ardnsmat.h>
    #include <arpack++/ardscomp.h>
    #include <arpack++/arsnsym.h>
    #include <arpack++/arssym.h>
#else
    #error Could not include arpack headers correctly
#endif

#if defined(__clang__)
    // turn the warnings back on
    #pragma clang diagnostic pop
#elif defined(__GNUC__) || defined(__GNUG__)
#endif

namespace tc = sfinae;
using namespace eig;

template<typename MatrixType>
eig::arpack_solver<MatrixType>::arpack_solver(MatrixType &matrix_, eig::settings &config_, eig::solution &result_, Scalar *residual_)
    : matrix(matrix_), config(config_), result(result_), residual(residual_) {
    t_sol.set_properties(profile_arpack, 10, "Time iterating  ");
    t_get.set_properties(profile_arpack, 10, "Time getting result");
    t_sub.set_properties(profile_arpack, 10, "Time subtracting");
    t_all.set_properties(profile_arpack, 10, "Time doing all  ");
    nev_internal = std::min(matrix.rows() / 2, static_cast<int>(config.eigMaxNev.value()));
    ncv_internal = static_cast<int>(std::max(config.eigMaxNcv.value(), 2 + config.eigMaxNev.value()));
    ncv_internal = std::min(ncv_internal, matrix.rows());
}

template<typename MatrixType>
void eig::arpack_solver<MatrixType>::eigs() {
    auto loglevel = tools::Logger::getLogLevel(eig::log);
    eig::log      = tools::Logger::setLogger("eigs", loglevel);

    result.reset();
    nev_internal = std::min(matrix.rows() / 2, static_cast<int>(config.eigMaxNev.value()));
    ncv_internal = static_cast<int>(std::max(config.eigMaxNcv.value(), 2 + config.eigMaxNev.value()));
    ncv_internal = std::min(ncv_internal, matrix.rows());
    assert(nev_internal >= 1 and nev_internal <= matrix.rows() / 2);

    config.checkRitz();
    matrix.set_mode(config.form.value());
    matrix.set_side(config.side.value());

    // Dispatch to symmetric or nonsymmetric. If complex, there's only a nonsymmetric option available.
    if constexpr(std::is_same<Scalar, std::complex<double>>::value) {
        eigs_comp();
    } else {
        if(config.form == Form::SYMM)
            eigs_sym();
        else
            eigs_nsym();
    }
    eig::log = tools::Logger::setLogger("eigs", loglevel);
}

template<typename MatrixType>
void eig::arpack_solver<MatrixType>::eigs_sym() {
    if constexpr(std::is_same<Scalar, double>::value) {
        assert(config.form == Form::SYMM and "ERROR: config not SYMMETRIC");
        assert(matrix.get_form() == Form::SYMM and "ERROR: matrix not SYMMETRIC");
        ARSymStdEig<double, MatrixType> solver(matrix.rows(), nev_internal, &matrix, &MatrixType::MultAx, config.get_ritz_string().data(), ncv_internal,
                                               config.eigThreshold.value(), static_cast<int>(config.eigMaxIter.value()), residual);

        if(config.sigma) {
            if(config.shift_invert == Shinv::ON) {
                if constexpr(MatrixType::can_shift_invert) {
                    eig::log->trace("Enabling shift-invert mode with sigma = {}", std::real(config.sigma.value()));
                    // Calculate shift-inverse mat-vec mult operator by LU decomposition
                    matrix.set_shift(config.sigma.value());
                    matrix.FactorOP();
                    if constexpr(std::is_same_v<Scalar, cplx>) solver.SetShiftInvertMode(config.sigma.value(), &matrix, &MatrixType::MultOPv);
                    if constexpr(std::is_same_v<Scalar, real>) solver.SetShiftInvertMode(std::real(config.sigma.value()), &matrix, &MatrixType::MultOPv);
                } else
                    throw std::runtime_error("Tried to shift-invert an incompatible matrix");
            } else {
                if constexpr(MatrixType::can_shift) {
                    eig::log->trace("Setting shift with sigma = {}", std::real(config.sigma.value()));
                    matrix.set_shift(config.sigma.value());
                } else
                    throw std::runtime_error("Tried to apply shift on an incompatible matrix");
            }
        }
        find_solution(solver, config.eigMaxNev.value());
        copy_solution(solver);

    } else {
        eig::log->critical("Called eigs_sym() with wrong type: " + std::string(tc::type_name<MatrixType>()));
        throw std::runtime_error("Called eigs_sym() with wrong type: " + std::string(tc::type_name<MatrixType>()));
    }
}

template<typename MatrixType>
void eig::arpack_solver<MatrixType>::eigs_nsym() {
    if constexpr(std::is_same<Scalar, double>::value) {
        assert(config.form == Form::NSYM and "ERROR: config not NSYM");
        assert(matrix.get_form() == Form::NSYM and "ERROR: matrix not NSYM");
        if(nev_internal == 1) { nev_internal++; }

        ARNonSymStdEig<double, MatrixType> solver(matrix.rows(), nev_internal, &matrix, &MatrixType::MultAx, config.get_ritz_string().data(), ncv_internal,
                                                  config.eigThreshold.value(), config.eigMaxIter.value(), residual);

        if(config.sigma) {
            if(config.shift_invert == Shinv::ON) {
                if constexpr(MatrixType::can_shift_invert) {
                    eig::log->trace("Enabling shift-invert mode with sigma = {}", std::real(config.sigma.value()));
                    // Calculate shift-inverse mat-vec mult operator by LU decomposition
                    matrix.set_shift(config.sigma.value());
                    matrix.FactorOP();
                    if constexpr(std::is_same_v<Scalar, cplx>) solver.SetShiftInvertMode(config.sigma.value(), &matrix, &MatrixType::MultOPv);
                    if constexpr(std::is_same_v<Scalar, real>) solver.SetShiftInvertMode(std::real(config.sigma.value()), &matrix, &MatrixType::MultOPv);
                } else
                    throw std::runtime_error("Tried to shift-invert an incompatible matrix");
            } else {
                if constexpr(MatrixType::can_shift) {
                    eig::log->trace("Setting shift with sigma = {}", std::real(config.sigma.value()));
                    matrix.set_shift(config.sigma.value());
                } else
                    throw std::runtime_error("Tried to apply shift on an incompatible matrix");
            }
        }

        find_solution(solver, config.eigMaxNev.value());
        copy_solution(solver);
    } else {
        throw std::runtime_error("Called eigs_nsym() with wrong type: " + std::string(tc::type_name<MatrixType>()));
    }
}

template<typename MatrixType>
void eig::arpack_solver<MatrixType>::eigs_comp() {
    if constexpr(std::is_same<Scalar, std::complex<double>>::value) {
        ARCompStdEig<double, MatrixType> solver(matrix.rows(), nev_internal, &matrix, &MatrixType::MultAx, config.get_ritz_string().data(), ncv_internal,
                                                config.eigThreshold.value(), config.eigMaxIter.value(), residual);
        if(config.sigma) {
            if(config.shift_invert == Shinv::ON) {
                if constexpr(MatrixType::can_shift_invert) {
                    eig::log->trace("Enabling shift-invert mode with sigma = {}", std::real(config.sigma.value()));
                    // Calculate shift-inverse mat-vec mult operator by LU decomposition
                    matrix.set_shift(config.sigma.value());
                    matrix.FactorOP();
                    if constexpr(std::is_same_v<Scalar, cplx>) solver.SetShiftInvertMode(config.sigma.value(), &matrix, &MatrixType::MultOPv);
                    if constexpr(std::is_same_v<Scalar, real>) solver.SetShiftInvertMode(std::real(config.sigma.value()), &matrix, &MatrixType::MultOPv);
                } else
                    throw std::runtime_error("Tried to shift-invert an incompatible matrix");
            } else {
                if constexpr(MatrixType::can_shift) {
                    eig::log->trace("Setting shift with sigma = {}", std::real(config.sigma.value()));
                    matrix.set_shift(config.sigma.value());
                } else
                    throw std::runtime_error("Tried to apply shift on an incompatible matrix");
            }
        }
        find_solution(solver, config.eigMaxNev.value());
        copy_solution(solver);
    } else {
        throw std::runtime_error("Called eigs_nsym() with wrong type: " + std::string(tc::type_name<MatrixType>()));
    }
}

//
//
template<typename MatrixType>
template<typename Derived>
void eig::arpack_solver<MatrixType>::find_solution(Derived &solver, eig::size_type nev) {
    if(config.compute_eigvecs) {
        eig::log->trace("Finding eigenvectors");
        solver.FindEigenvectors();
        if(config.side == eig::Side::L)
            result.meta.eigvecsL_found = solver.EigenvectorsFound();
        else
            result.meta.eigvecsR_found = solver.EigenvectorsFound(); // BOOL!

        result.meta.eigvals_found = solver.EigenvaluesFound(); // BOOL!
        result.meta.iter          = solver.GetIter();
        result.meta.n             = solver.GetN();
        result.meta.nev           = std::min(nev, static_cast<eig::size_type>(solver.GetNev()));
        result.meta.nev_converged = solver.ConvergedEigenvalues();
        result.meta.ncv_used      = solver.GetNcv();
        result.meta.rows          = solver.GetN();
        result.meta.cols          = result.meta.nev;
        result.meta.counter       = matrix.counter;
        result.meta.form          = config.form.value();
        result.meta.type          = config.type.value();
        /* clang-format off */
        eig::log->trace("- {:<30} = {}" ,"eigvals_found",  result.meta.eigvals_found);
        eig::log->trace("- {:<30} = {}" ,"eigvecsR_found", result.meta.eigvecsR_found);
        eig::log->trace("- {:<30} = {}" ,"eigvecsL_found", result.meta.eigvecsL_found);
        eig::log->trace("- {:<30} = {}" ,"iter",           result.meta.iter);
        eig::log->trace("- {:<30} = {}" ,"n",              result.meta.n);
        eig::log->trace("- {:<30} = {}" ,"nev",            result.meta.nev);
        eig::log->trace("- {:<30} = {}" ,"nev_converged",  result.meta.nev_converged);
        eig::log->trace("- {:<30} = {}" ,"ncv_used",       result.meta.ncv_used);
        eig::log->trace("- {:<30} = {}" ,"rows",           result.meta.rows);
        eig::log->trace("- {:<30} = {}" ,"cols",           result.meta.cols);
        eig::log->trace("- {:<30} = {}" ,"counter",        result.meta.counter);
        /* clang-format on */
        assert(result.meta.nev_converged >= result.meta.nev and "Not enough eigenvalues converged");
        assert(result.meta.eigvals_found and "Eigenvalues were not found");
        assert(solver.EigenvectorsFound() and "Eigenvectors were not found");

    } else {
        eig::log->trace("Finding eigenvalues");
        solver.FindEigenvalues();
        result.meta.eigvals_found = solver.EigenvaluesFound();
        result.meta.iter          = solver.GetIter();
        result.meta.n             = solver.GetN();
        result.meta.nev           = std::min(nev, static_cast<eig::size_type>(solver.GetNev()));
        result.meta.nev_converged = solver.ConvergedEigenvalues();
        result.meta.ncv_used      = solver.GetNcv();
        result.meta.rows          = solver.GetN();
        result.meta.cols          = result.meta.nev;
        result.meta.counter       = matrix.counter;
        result.meta.form          = config.form.value();
        result.meta.type          = config.type.value();
        /* clang-format off */
        eig::log->trace("- {:<30} = {}" ,"eigvals_found",  result.meta.eigvals_found);
        eig::log->trace("- {:<30} = {}" ,"eigvecsR_found", result.meta.eigvecsR_found);
        eig::log->trace("- {:<30} = {}" ,"eigvecsL_found", result.meta.eigvecsL_found);
        eig::log->trace("- {:<30} = {}" ,"iter",           result.meta.iter);
        eig::log->trace("- {:<30} = {}" ,"n",              result.meta.n);
        eig::log->trace("- {:<30} = {}" ,"nev",            result.meta.nev);
        eig::log->trace("- {:<30} = {}" ,"nev_converged",  result.meta.nev_converged);
        eig::log->trace("- {:<30} = {}" ,"ncv_used",       result.meta.ncv_used);
        eig::log->trace("- {:<30} = {}" ,"rows",           result.meta.rows);
        eig::log->trace("- {:<30} = {}" ,"cols",           result.meta.cols);
        eig::log->trace("- {:<30} = {}" ,"counter",        result.meta.counter);
        /* clang-format on */

        assert(result.meta.nev_converged >= result.meta.nev and "Not enough eigenvalues converged");
        assert(result.meta.eigvals_found and "Eigenvalues were not found");
    }
}

template class eig::arpack_solver<MatrixProductDense<real>>;
template class eig::arpack_solver<MatrixProductDense<cplx>>;
template class eig::arpack_solver<MatrixProductSparse<real>>;
template class eig::arpack_solver<MatrixProductSparse<cplx>>;
template class eig::arpack_solver<MatrixProductHamiltonian<real>>;
template class eig::arpack_solver<MatrixProductHamiltonian<cplx>>;
<commit_msg>Warn instead of assert when eigenvalue solver fails<commit_after>//
// Created by david on 2018-10-30.
//

#include "arpack_solver.h"
#include "matrix_product_dense.h"
#include "matrix_product_hamiltonian.h"
#include "matrix_product_sparse.h"
#include <general/nmspc_sfinae.h>

#if defined(_MKL_LAPACK_H_)
    #error MKL_LAPACK IS NOT SUPPOSED TO BE DEFINED HERE
#endif

#if defined(LAPACK_H)
    #error LAPACK IS NOT SUPPOSED TO BE DEFINED HERE
#endif

#if defined(__clang__)
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Woverloaded-virtual"
#elif defined(__GNUC__) || defined(__GNUG__)
#endif

#if __has_include(<arpackpp/arcomp.h>)
    #include <arpackpp/arcomp.h>
    #include <arpackpp/ardnsmat.h>
    #include <arpackpp/ardscomp.h>
    #include <arpackpp/arsnsym.h>
    #include <arpackpp/arssym.h>
#elif __has_include(<arpack++/arcomp.h>)
    #include <arpack++/ardnsmat.h>
    #include <arpack++/ardscomp.h>
    #include <arpack++/arsnsym.h>
    #include <arpack++/arssym.h>
#else
    #error Could not include arpack headers correctly
#endif

#if defined(__clang__)
    // turn the warnings back on
    #pragma clang diagnostic pop
#elif defined(__GNUC__) || defined(__GNUG__)
#endif

namespace tc = sfinae;
using namespace eig;

template<typename MatrixType>
eig::arpack_solver<MatrixType>::arpack_solver(MatrixType &matrix_, eig::settings &config_, eig::solution &result_, Scalar *residual_)
    : matrix(matrix_), config(config_), result(result_), residual(residual_) {
    t_sol.set_properties(profile_arpack, 10, "Time iterating  ");
    t_get.set_properties(profile_arpack, 10, "Time getting result");
    t_sub.set_properties(profile_arpack, 10, "Time subtracting");
    t_all.set_properties(profile_arpack, 10, "Time doing all  ");
    nev_internal = std::min(matrix.rows() / 2, static_cast<int>(config.eigMaxNev.value()));
    ncv_internal = static_cast<int>(std::max(config.eigMaxNcv.value(), 2 + config.eigMaxNev.value()));
    ncv_internal = std::min(ncv_internal, matrix.rows());
}

template<typename MatrixType>
void eig::arpack_solver<MatrixType>::eigs() {
    auto loglevel = tools::Logger::getLogLevel(eig::log);
    eig::log      = tools::Logger::setLogger("eigs", loglevel);

    result.reset();
    nev_internal = std::min(matrix.rows() / 2, static_cast<int>(config.eigMaxNev.value()));
    ncv_internal = static_cast<int>(std::max(config.eigMaxNcv.value(), 2 + config.eigMaxNev.value()));
    ncv_internal = std::min(ncv_internal, matrix.rows());
    assert(nev_internal >= 1 and nev_internal <= matrix.rows() / 2);

    config.checkRitz();
    matrix.set_mode(config.form.value());
    matrix.set_side(config.side.value());

    // Dispatch to symmetric or nonsymmetric. If complex, there's only a nonsymmetric option available.
    if constexpr(std::is_same<Scalar, std::complex<double>>::value) {
        eigs_comp();
    } else {
        if(config.form == Form::SYMM)
            eigs_sym();
        else
            eigs_nsym();
    }
    eig::log = tools::Logger::setLogger("eigs", loglevel);
}

template<typename MatrixType>
void eig::arpack_solver<MatrixType>::eigs_sym() {
    if constexpr(std::is_same<Scalar, double>::value) {
        assert(config.form == Form::SYMM and "ERROR: config not SYMMETRIC");
        assert(matrix.get_form() == Form::SYMM and "ERROR: matrix not SYMMETRIC");
        ARSymStdEig<double, MatrixType> solver(matrix.rows(), nev_internal, &matrix, &MatrixType::MultAx, config.get_ritz_string().data(), ncv_internal,
                                               config.eigThreshold.value(), static_cast<int>(config.eigMaxIter.value()), residual);

        if(config.sigma) {
            if(config.shift_invert == Shinv::ON) {
                if constexpr(MatrixType::can_shift_invert) {
                    eig::log->trace("Enabling shift-invert mode with sigma = {}", std::real(config.sigma.value()));
                    // Calculate shift-inverse mat-vec mult operator by LU decomposition
                    matrix.set_shift(config.sigma.value());
                    matrix.FactorOP();
                    if constexpr(std::is_same_v<Scalar, cplx>) solver.SetShiftInvertMode(config.sigma.value(), &matrix, &MatrixType::MultOPv);
                    if constexpr(std::is_same_v<Scalar, real>) solver.SetShiftInvertMode(std::real(config.sigma.value()), &matrix, &MatrixType::MultOPv);
                } else
                    throw std::runtime_error("Tried to shift-invert an incompatible matrix");
            } else {
                if constexpr(MatrixType::can_shift) {
                    eig::log->trace("Setting shift with sigma = {}", std::real(config.sigma.value()));
                    matrix.set_shift(config.sigma.value());
                } else
                    throw std::runtime_error("Tried to apply shift on an incompatible matrix");
            }
        }
        find_solution(solver, config.eigMaxNev.value());
        copy_solution(solver);

    } else {
        eig::log->critical("Called eigs_sym() with wrong type: " + std::string(tc::type_name<MatrixType>()));
        throw std::runtime_error("Called eigs_sym() with wrong type: " + std::string(tc::type_name<MatrixType>()));
    }
}

template<typename MatrixType>
void eig::arpack_solver<MatrixType>::eigs_nsym() {
    if constexpr(std::is_same<Scalar, double>::value) {
        assert(config.form == Form::NSYM and "ERROR: config not NSYM");
        assert(matrix.get_form() == Form::NSYM and "ERROR: matrix not NSYM");
        if(nev_internal == 1) { nev_internal++; }

        ARNonSymStdEig<double, MatrixType> solver(matrix.rows(), nev_internal, &matrix, &MatrixType::MultAx, config.get_ritz_string().data(), ncv_internal,
                                                  config.eigThreshold.value(), config.eigMaxIter.value(), residual);

        if(config.sigma) {
            if(config.shift_invert == Shinv::ON) {
                if constexpr(MatrixType::can_shift_invert) {
                    eig::log->trace("Enabling shift-invert mode with sigma = {}", std::real(config.sigma.value()));
                    // Calculate shift-inverse mat-vec mult operator by LU decomposition
                    matrix.set_shift(config.sigma.value());
                    matrix.FactorOP();
                    if constexpr(std::is_same_v<Scalar, cplx>) solver.SetShiftInvertMode(config.sigma.value(), &matrix, &MatrixType::MultOPv);
                    if constexpr(std::is_same_v<Scalar, real>) solver.SetShiftInvertMode(std::real(config.sigma.value()), &matrix, &MatrixType::MultOPv);
                } else
                    throw std::runtime_error("Tried to shift-invert an incompatible matrix");
            } else {
                if constexpr(MatrixType::can_shift) {
                    eig::log->trace("Setting shift with sigma = {}", std::real(config.sigma.value()));
                    matrix.set_shift(config.sigma.value());
                } else
                    throw std::runtime_error("Tried to apply shift on an incompatible matrix");
            }
        }

        find_solution(solver, config.eigMaxNev.value());
        copy_solution(solver);
    } else {
        throw std::runtime_error("Called eigs_nsym() with wrong type: " + std::string(tc::type_name<MatrixType>()));
    }
}

template<typename MatrixType>
void eig::arpack_solver<MatrixType>::eigs_comp() {
    if constexpr(std::is_same<Scalar, std::complex<double>>::value) {
        ARCompStdEig<double, MatrixType> solver(matrix.rows(), nev_internal, &matrix, &MatrixType::MultAx, config.get_ritz_string().data(), ncv_internal,
                                                config.eigThreshold.value(), config.eigMaxIter.value(), residual);
        if(config.sigma) {
            if(config.shift_invert == Shinv::ON) {
                if constexpr(MatrixType::can_shift_invert) {
                    eig::log->trace("Enabling shift-invert mode with sigma = {}", std::real(config.sigma.value()));
                    // Calculate shift-inverse mat-vec mult operator by LU decomposition
                    matrix.set_shift(config.sigma.value());
                    matrix.FactorOP();
                    if constexpr(std::is_same_v<Scalar, cplx>) solver.SetShiftInvertMode(config.sigma.value(), &matrix, &MatrixType::MultOPv);
                    if constexpr(std::is_same_v<Scalar, real>) solver.SetShiftInvertMode(std::real(config.sigma.value()), &matrix, &MatrixType::MultOPv);
                } else
                    throw std::runtime_error("Tried to shift-invert an incompatible matrix");
            } else {
                if constexpr(MatrixType::can_shift) {
                    eig::log->trace("Setting shift with sigma = {}", std::real(config.sigma.value()));
                    matrix.set_shift(config.sigma.value());
                } else
                    throw std::runtime_error("Tried to apply shift on an incompatible matrix");
            }
        }
        find_solution(solver, config.eigMaxNev.value());
        copy_solution(solver);
    } else {
        throw std::runtime_error("Called eigs_nsym() with wrong type: " + std::string(tc::type_name<MatrixType>()));
    }
}

//
//
template<typename MatrixType>
template<typename Derived>
void eig::arpack_solver<MatrixType>::find_solution(Derived &solver, eig::size_type nev) {
    if(config.compute_eigvecs) {
        eig::log->trace("Finding eigenvectors");
        solver.FindEigenvectors();
        if(config.side == eig::Side::L)
            result.meta.eigvecsL_found = solver.EigenvectorsFound();
        else
            result.meta.eigvecsR_found = solver.EigenvectorsFound(); // BOOL!

        result.meta.eigvals_found = solver.EigenvaluesFound(); // BOOL!
        result.meta.iter          = solver.GetIter();
        result.meta.n             = solver.GetN();
        result.meta.nev           = std::min(nev, static_cast<eig::size_type>(solver.GetNev()));
        result.meta.nev_converged = solver.ConvergedEigenvalues();
        result.meta.ncv_used      = solver.GetNcv();
        result.meta.rows          = solver.GetN();
        result.meta.cols          = result.meta.nev;
        result.meta.counter       = matrix.counter;
        result.meta.form          = config.form.value();
        result.meta.type          = config.type.value();
        /* clang-format off */
        eig::log->trace("- {:<30} = {}" ,"eigvals_found",  result.meta.eigvals_found);
        eig::log->trace("- {:<30} = {}" ,"eigvecsR_found", result.meta.eigvecsR_found);
        eig::log->trace("- {:<30} = {}" ,"eigvecsL_found", result.meta.eigvecsL_found);
        eig::log->trace("- {:<30} = {}" ,"iter",           result.meta.iter);
        eig::log->trace("- {:<30} = {}" ,"n",              result.meta.n);
        eig::log->trace("- {:<30} = {}" ,"nev",            result.meta.nev);
        eig::log->trace("- {:<30} = {}" ,"nev_converged",  result.meta.nev_converged);
        eig::log->trace("- {:<30} = {}" ,"ncv_used",       result.meta.ncv_used);
        eig::log->trace("- {:<30} = {}" ,"rows",           result.meta.rows);
        eig::log->trace("- {:<30} = {}" ,"cols",           result.meta.cols);
        eig::log->trace("- {:<30} = {}" ,"counter",        result.meta.counter);
        /* clang-format on */
//        assert(result.meta.nev_converged >= result.meta.nev and "Not enough eigenvalues converged");
//        assert(result.meta.eigvals_found and "Eigenvalues were not found");
        if(result.meta.nev_converged < result.meta.nev) eig::log->warn("Not enough eigenvalues converged");
        if(not result.meta.eigvals_found) eig::log->warn("Eigenvalues were not found");
        if(not solver.EigenvectorsFound()) eig::log->warn("Eigenvectors were not found");
    } else {
        eig::log->trace("Finding eigenvalues");
        solver.FindEigenvalues();
        result.meta.eigvals_found = solver.EigenvaluesFound();
        result.meta.iter          = solver.GetIter();
        result.meta.n             = solver.GetN();
        result.meta.nev           = std::min(nev, static_cast<eig::size_type>(solver.GetNev()));
        result.meta.nev_converged = solver.ConvergedEigenvalues();
        result.meta.ncv_used      = solver.GetNcv();
        result.meta.rows          = solver.GetN();
        result.meta.cols          = result.meta.nev;
        result.meta.counter       = matrix.counter;
        result.meta.form          = config.form.value();
        result.meta.type          = config.type.value();
        /* clang-format off */
        eig::log->trace("- {:<30} = {}" ,"eigvals_found",  result.meta.eigvals_found);
        eig::log->trace("- {:<30} = {}" ,"eigvecsR_found", result.meta.eigvecsR_found);
        eig::log->trace("- {:<30} = {}" ,"eigvecsL_found", result.meta.eigvecsL_found);
        eig::log->trace("- {:<30} = {}" ,"iter",           result.meta.iter);
        eig::log->trace("- {:<30} = {}" ,"n",              result.meta.n);
        eig::log->trace("- {:<30} = {}" ,"nev",            result.meta.nev);
        eig::log->trace("- {:<30} = {}" ,"nev_converged",  result.meta.nev_converged);
        eig::log->trace("- {:<30} = {}" ,"ncv_used",       result.meta.ncv_used);
        eig::log->trace("- {:<30} = {}" ,"rows",           result.meta.rows);
        eig::log->trace("- {:<30} = {}" ,"cols",           result.meta.cols);
        eig::log->trace("- {:<30} = {}" ,"counter",        result.meta.counter);
        /* clang-format on */

//        assert(result.meta.nev_converged >= result.meta.nev and "Not enough eigenvalues converged");
//        assert(result.meta.eigvals_found and "Eigenvalues were not found");
        if(result.meta.nev_converged < result.meta.nev) eig::log->warn("Not enough eigenvalues converged");
        if(not result.meta.eigvals_found) eig::log->warn("Eigenvalues were not found");
    }
}

template class eig::arpack_solver<MatrixProductDense<real>>;
template class eig::arpack_solver<MatrixProductDense<cplx>>;
template class eig::arpack_solver<MatrixProductSparse<real>>;
template class eig::arpack_solver<MatrixProductSparse<cplx>>;
template class eig::arpack_solver<MatrixProductHamiltonian<real>>;
template class eig::arpack_solver<MatrixProductHamiltonian<cplx>>;
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "debugutil_p.h"

#include <QEventLoop>
#include <QTimer>

bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) {
    QEventLoop loop;
    QTimer timer;
    timer.setSingleShot(true);
    QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
    QObject::connect(receiver, member, &loop, SLOT(quit()));
    timer.start(timeout);
    loop.exec();
    return timer.isActive();
}

QQmlDebugTestClient::QQmlDebugTestClient(const QString &s, QQmlDebugConnection *c)
    : QQmlDebugClient(s, c)
{
}

QByteArray QQmlDebugTestClient::waitForResponse()
{
    lastMsg.clear();
    QQmlDebugTest::waitForSignal(this, SIGNAL(serverMessage(QByteArray)));
    if (lastMsg.isEmpty()) {
        qWarning() << "tst_QQmlDebugTestClient: no response from server!";
        return QByteArray();
    }
    return lastMsg;
}

void QQmlDebugTestClient::stateChanged(State stat)
{
    QCOMPARE(stat, state());
    emit stateHasChanged();
}

void QQmlDebugTestClient::messageReceived(const QByteArray &ba)
{
    lastMsg = ba;
    emit serverMessage(ba);
}

QQmlDebugProcess::QQmlDebugProcess(const QString &executable)
    : m_executable(executable)
    , m_started(false)
{
    m_process.setProcessChannelMode(QProcess::MergedChannels);
    m_timer.setSingleShot(true);
    m_timer.setInterval(5000);
    connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput()));
    connect(&m_timer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit()));
}

QQmlDebugProcess::~QQmlDebugProcess()
{
    stop();
}

void QQmlDebugProcess::start(const QStringList &arguments)
{
    m_mutex.lock();
    m_process.setEnvironment(m_environment);
    m_process.start(m_executable, arguments);
    m_process.waitForStarted();
    m_timer.start();
    m_mutex.unlock();
}

void QQmlDebugProcess::stop()
{
    if (m_process.state() != QProcess::NotRunning) {
        m_process.kill();
        m_process.waitForFinished(5000);
    }
}

bool QQmlDebugProcess::waitForSessionStart()
{
    if (m_process.state() != QProcess::Running) {
        qWarning() << "Could not start up " << m_executable;
        return false;
    }
    m_eventLoop.exec();

    return m_started;
}

void QQmlDebugProcess::setEnvironment(const QStringList &environment)
{
    m_environment = environment;
}

QString QQmlDebugProcess::output() const
{
    return m_output;
}

void QQmlDebugProcess::processAppOutput()
{
    m_mutex.lock();

    QString newOutput = m_process.readAll();
    m_output.append(newOutput);
    m_outputBuffer.append(newOutput);

    while (true) {
        const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
        if (nlIndex < 0) // no further complete lines
            break;
        const QString line = m_outputBuffer.left(nlIndex);
        m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);

        if (line.startsWith("QML debugging is enabled")) // ignore
            continue;
        if (line.startsWith("QML Debugger:")) {
            if (line.contains("Waiting for connection ")) {
                m_started = true;
                m_eventLoop.quit();
                continue;
            }
            if (line.contains("Connection established.")) {
                continue;
            }
        }
    }
    m_mutex.unlock();
}
<commit_msg>irrelevant qDebug removed<commit_after>/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "debugutil_p.h"

#include <QEventLoop>
#include <QTimer>

bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) {
    QEventLoop loop;
    QTimer timer;
    timer.setSingleShot(true);
    QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
    QObject::connect(receiver, member, &loop, SLOT(quit()));
    timer.start(timeout);
    loop.exec();
    return timer.isActive();
}

QQmlDebugTestClient::QQmlDebugTestClient(const QString &s, QQmlDebugConnection *c)
    : QQmlDebugClient(s, c)
{
}

QByteArray QQmlDebugTestClient::waitForResponse()
{
    lastMsg.clear();
    QQmlDebugTest::waitForSignal(this, SIGNAL(serverMessage(QByteArray)));
    if (lastMsg.isEmpty()) {
        qWarning() << "tst_QQmlDebugTestClient: no response from server!";
        return QByteArray();
    }
    return lastMsg;
}

void QQmlDebugTestClient::stateChanged(State stat)
{
    QCOMPARE(stat, state());
    emit stateHasChanged();
}

void QQmlDebugTestClient::messageReceived(const QByteArray &ba)
{
    lastMsg = ba;
    emit serverMessage(ba);
}

QQmlDebugProcess::QQmlDebugProcess(const QString &executable)
    : m_executable(executable)
    , m_started(false)
{
    m_process.setProcessChannelMode(QProcess::MergedChannels);
    m_timer.setSingleShot(true);
    m_timer.setInterval(5000);
    connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput()));
    connect(&m_timer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit()));
}

QQmlDebugProcess::~QQmlDebugProcess()
{
    stop();
}

void QQmlDebugProcess::start(const QStringList &arguments)
{
    m_mutex.lock();
    m_process.setEnvironment(m_environment);
    m_process.start(m_executable, arguments);
    m_process.waitForStarted();
    m_timer.start();
    m_mutex.unlock();
}

void QQmlDebugProcess::stop()
{
    if (m_process.state() != QProcess::NotRunning) {
        m_process.kill();
        m_process.waitForFinished(5000);
    }
}

bool QQmlDebugProcess::waitForSessionStart()
{
    if (m_process.state() != QProcess::Running) {
        qWarning() << "Could not start up " << m_executable;
        return false;
    }
    m_eventLoop.exec();

    return m_started;
}

void QQmlDebugProcess::setEnvironment(const QStringList &environment)
{
    m_environment = environment;
}

QString QQmlDebugProcess::output() const
{
    return m_output;
}

void QQmlDebugProcess::processAppOutput()
{
    m_mutex.lock();

    QString newOutput = m_process.readAll();
    m_output.append(newOutput);
    m_outputBuffer.append(newOutput);

    while (true) {
        const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
        if (nlIndex < 0) // no further complete lines
            break;
        const QString line = m_outputBuffer.left(nlIndex);
        m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);

        if (line.startsWith("QML debugging is enabled")) // ignore
            continue;
        if (line.startsWith("QML Debugger:")) {
            if (line.contains("Waiting for connection ")) {
                m_started = true;
                m_eventLoop.quit();
                continue;
            }
        }
    }
    m_mutex.unlock();
}
<|endoftext|>


<commit_before><commit_msg>Update Ring For Android<commit_after><|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "CompressIndices.h"

#include <cstring>
#include <algorithm>
#include <Corrade/Containers/Array.h>

#include "Magnum/Math/Functions.h"

namespace Magnum { namespace MeshTools {

namespace {

template<class T> inline Containers::Array<char> compress(const std::vector<UnsignedInt>& indices) {
    Containers::Array<char> buffer(indices.size()*sizeof(T));
    for(std::size_t i = 0; i != indices.size(); ++i) {
        T index = static_cast<T>(indices[i]);
        std::memcpy(buffer.begin()+i*sizeof(T), &index, sizeof(T));
    }

    return buffer;
}

}

std::tuple<Containers::Array<char>, Mesh::IndexType, UnsignedInt, UnsignedInt> compressIndices(const std::vector<UnsignedInt>& indices) {
    /** @todo Performance hint when range can be represented by smaller value? */
    auto minmax = std::minmax_element(indices.begin(), indices.end());
    Containers::Array<char> data;
    Mesh::IndexType type;
    switch(Math::log(256, *minmax.second)) {
        case 0:
            data = compress<UnsignedByte>(indices);
            type = Mesh::IndexType::UnsignedByte;
            break;
        case 1:
            data = compress<UnsignedShort>(indices);
            type = Mesh::IndexType::UnsignedShort;
            break;
        case 2:
        case 3:
            data = compress<UnsignedInt>(indices);
            type = Mesh::IndexType::UnsignedInt;
            break;

        default:
            CORRADE_ASSERT(false, "MeshTools::compressIndices(): no type able to index" << *minmax.second << "elements.", {});
    }

    return std::make_tuple(std::move(data), type, *minmax.first, *minmax.second);
}

}}
<commit_msg>MeshTools: const++.<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "CompressIndices.h"

#include <cstring>
#include <algorithm>
#include <Corrade/Containers/Array.h>

#include "Magnum/Math/Functions.h"

namespace Magnum { namespace MeshTools {

namespace {

template<class T> inline Containers::Array<char> compress(const std::vector<UnsignedInt>& indices) {
    Containers::Array<char> buffer(indices.size()*sizeof(T));
    for(std::size_t i = 0; i != indices.size(); ++i) {
        T index = static_cast<T>(indices[i]);
        std::memcpy(buffer.begin()+i*sizeof(T), &index, sizeof(T));
    }

    return buffer;
}

}

std::tuple<Containers::Array<char>, Mesh::IndexType, UnsignedInt, UnsignedInt> compressIndices(const std::vector<UnsignedInt>& indices) {
    /** @todo Performance hint when range can be represented by smaller value? */
    const auto minmax = std::minmax_element(indices.begin(), indices.end());
    Containers::Array<char> data;
    Mesh::IndexType type;
    switch(Math::log(256, *minmax.second)) {
        case 0:
            data = compress<UnsignedByte>(indices);
            type = Mesh::IndexType::UnsignedByte;
            break;
        case 1:
            data = compress<UnsignedShort>(indices);
            type = Mesh::IndexType::UnsignedShort;
            break;
        case 2:
        case 3:
            data = compress<UnsignedInt>(indices);
            type = Mesh::IndexType::UnsignedInt;
            break;

        default:
            CORRADE_ASSERT(false, "MeshTools::compressIndices(): no type able to index" << *minmax.second << "elements.", {});
    }

    return std::make_tuple(std::move(data), type, *minmax.first, *minmax.second);
}

}}
<|endoftext|>


<commit_before>#ifndef __HIERARCHY_TEMPLATES_HPP_INCLUDED
#define __HIERARCHY_TEMPLATES_HPP_INCLUDED

#include "cpp/ylikuutio/hierarchy/hierarchy.hpp"

// Include standard headers
#include <vector>    // std::vector

namespace hierarchy
{
    void set_child_pointer(uint32_t childID, void* child_pointer, std::vector<void*> &child_pointer_vector, std::queue<uint32_t> &free_childID_queue);
    uint32_t get_childID(std::vector<void*> &child_pointer_vector, std::queue<uint32_t> &free_childID_queue);

    template<class T1>
        void bind_child_to_parent(T1 child_pointer, std::vector<void*> &child_pointer_vector, std::queue<uint32_t> &free_childID_queue)
        {
            // get childID from the parent, because every child deserves a unique ID!
            child_pointer->childID = get_childID(child_pointer_vector, free_childID_queue);
            // set pointer to the child in parent's child pointer vector so that parent knows about children's whereabouts!
            set_child_pointer(child_pointer->childID, child_pointer, child_pointer_vector, free_childID_queue);
        }

    template <class T1, class T2>
        void bind_child_to_new_parent(
                T1 child_pointer,
                T2 new_parent_pointer,
                std::vector<void*> &old_child_pointer_vector,
                std::queue<uint32_t> &old_free_childID_queue)
        {
            // set pointer to this child to nullptr in the old parent.
            set_child_pointer(child_pointer->childID, nullptr, old_child_pointer_vector, old_free_childID_queue);
            // set the new parent pointer.
            child_pointer->parent_pointer = new_parent_pointer;
            // bind to the new parent.
            child_pointer->bind_to_parent();
        }

    template<class T1>
        void delete_children(std::vector<void*> &child_pointer_vector)
        {
            for (uint32_t child_i = 0; child_i < child_pointer_vector.size(); child_i++)
            {
                delete static_cast<T1>(child_pointer_vector[child_i]);
            }
        }
}

#endif
<commit_msg>Edited comments.<commit_after>#ifndef __HIERARCHY_TEMPLATES_HPP_INCLUDED
#define __HIERARCHY_TEMPLATES_HPP_INCLUDED

#include "cpp/ylikuutio/hierarchy/hierarchy.hpp"

// Include standard headers
#include <vector>    // std::vector

namespace hierarchy
{
    void set_child_pointer(uint32_t childID, void* child_pointer, std::vector<void*> &child_pointer_vector, std::queue<uint32_t> &free_childID_queue);
    uint32_t get_childID(std::vector<void*> &child_pointer_vector, std::queue<uint32_t> &free_childID_queue);

    template<class T1>
        void bind_child_to_parent(T1 child_pointer, std::vector<void*> &child_pointer_vector, std::queue<uint32_t> &free_childID_queue)
        {
            // If a class' instances have parents, this function must be
            // called in the constructor. The call must be done only once
            // in each constructor, usually after setting
            // `this->parent_pointer`. So, get `childID` from the parent,
            // because every child deserves a unique ID!
            child_pointer->childID = get_childID(child_pointer_vector, free_childID_queue);
            // set pointer to the child in parent's child pointer vector so that parent knows about children's whereabouts!
            set_child_pointer(child_pointer->childID, child_pointer, child_pointer_vector, free_childID_queue);
        }

    template <class T1, class T2>
        void bind_child_to_new_parent(
                T1 child_pointer,
                T2 new_parent_pointer,
                std::vector<void*> &old_child_pointer_vector,
                std::queue<uint32_t> &old_free_childID_queue)
        {
            // set pointer to this child to nullptr in the old parent.
            set_child_pointer(child_pointer->childID, nullptr, old_child_pointer_vector, old_free_childID_queue);
            // set the new parent pointer.
            child_pointer->parent_pointer = new_parent_pointer;
            // bind to the new parent.
            child_pointer->bind_to_parent();
        }

    template<class T1>
        void delete_children(std::vector<void*> &child_pointer_vector)
        {
            for (uint32_t child_i = 0; child_i < child_pointer_vector.size(); child_i++)
            {
                delete static_cast<T1>(child_pointer_vector[child_i]);
            }
        }
}

#endif
<|endoftext|>