text:
#include <chrono>
#include <iostream>
#include <dlib/image_io.h>
#include <dlib/gui_widgets.h>
#include <dlib/image_processing/frontal_face_detector.h>

using namespace std;
using namespace dlib;

int main() {
    try {
        auto tempo_total_inicio = std::chrono::high_resolution_clock::now();
        // cout << "Criando Detector HOG" << endl;
        frontal_face_detector detectorHog = get_frontal_face_detector();
        // cout << "Criando Objeto de Imagem RGB" << endl;
        array2d<rgb_pixel> imagem;
        // cout << "Criando Objeto de Imagem Cinza" << endl;
        array2d<unsigned char> imagemCinza;
        string caminho_imagem = "fei/43-11.jpg";
        cout << "Carregando Imagem: " << caminho_imagem << endl;
        auto load_image_start = std::chrono::high_resolution_clock::now();
        load_image(imagem, caminho_imagem);
        auto load_image_end = std::chrono::high_resolution_clock::now();
        // cout << "Convertendo Imagem para Cinza" << endl;
        auto convert_image_start = std::chrono::high_resolution_clock::now();
        assign_image(imagemCinza, imagem);
        auto convert_image_end = std::chrono::high_resolution_clock::now();
        // cout << "Detectando Faces" << endl;
        auto detection_image_start = std::chrono::high_resolution_clock::now();
        std::vector<rectangle> facesDetectadasHog = detectorHog(imagemCinza);
        auto detection_image_end = std::chrono::high_resolution_clock::now();
        cout << "Faces:" << endl;
        for (auto& f : facesDetectadasHog) {
            cout << f << endl;
        }
        auto tempo_total_fim = std::chrono::high_resolution_clock::now();
        double tempo_carregamento = std::chrono::duration<double, std::milli>(load_image_end - load_image_start).count();
        double tempo_conversao = std::chrono::duration<double, std::milli>(convert_image_end - convert_image_start).count();
        double tempo_deteccao = std::chrono::duration<double, std::milli>(detection_image_end - detection_image_start).count();
        double tempo_total = std::chrono::duration<double, std::milli>(tempo_total_fim - tempo_total_inicio).count();
        cout << "Tempo Total: " << to_string(tempo_total) << endl;
        cout << "Tempo de Carregamento: " << to_string(tempo_carregamento) << endl;
        cout << "Tempo de Conversao: " << to_string(tempo_conversao) << endl;
        cout << "Tempo de Deteccao: " << to_string(tempo_deteccao) << endl;
        image_window my_window2(imagem, "Dlib Face Detection HOG");
        my_window2.add_overlay(facesDetectadasHog, rgb_pixel(0, 255, 0));
        my_window2.wait_until_closed();
        return 0;
    }
    catch (exception& e) {
        cout << "\nexception thrown!" << endl;
        cout << e.what() << endl;
        return 1;
    }
}

max_stars_repo_name: joaops/DlibFaceDetectionHOG

max_issues_repo_name: joaops/DlibFaceDetectionHOG

max_forks_repo_name: joaops/DlibFaceDetectionHOG


text:
//
// file SmiV.cc
// David Cosgrove
// AstraZeneca
// 9th February 2009.

#include "SmiV.H"
#include "SmivDataTable.H"
#include "SmiVFindMoleculeDialog.H"
#include "SmiVPanel.H"
#include "SmiVRecord.H"
#include "SmiVSettings.H"

#include "DACOEMolAtomIndex.H"
#include "SMARTSExceptions.H"
#include "QT4SelectItems.H"
#include "QTSmartsEditDialog.H"
#include "QTSmartsIntPickDialog.H"
#include "QTSmilesEditDialog.H"
#include "stddefs.H"

#include <QAction>
#include <QApplication>
#include <QFileDialog>
#include <QFileInfo>
#include <QHeaderView>
#include <QInputDialog>
#include <QLayout>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QPushButton>
#include <QSlider>
#include <QSplitter>
#include <QStatusBar>
#include <QTableView>

#include <oechem.h>

#include <fstream>
#include <iostream>
#include <iterator>

#include <boost/algorithm/string.hpp>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/scoped_ptr.hpp>

using namespace boost;
using namespace std;
using namespace OEChem;
using namespace OESystem;

extern string BUILD_TIME; // put together in build_time.cc

namespace DACLIB {
  void apply_daylight_aromatic_model( OEMolBase &mol );
  void read_smarts_file( const string &smarts_file ,
                         vector<pair<string,string> > &input_smarts ,
                         vector<pair<string,string> > &smarts_sub_defn );
  OESubSearch *create_eosubsearch( const string &smarts ,
                                   const string &smarts_name ,
                                   bool reorder ,
                                   vector<pair<string,string> > &sub_defns );
}

// ****************************************************************************
SmiV::SmiV() : QMainWindow() , find_mol_dialog_( 0 ) , smiles_edit_dialog_( 0 ) {

  build_actions();
  build_menubar();
  build_widget();

  last_dir_ = QString( "." );

  // turn off reporting of errors
  OEThrow.SetOutputStream( OEPlatform::oenul );

}

// ****************************************************************************
SmiV::~SmiV() {

}

// ****************************************************************************
void SmiV::parse_args( int argc , char **argv ) {

  SmiVSettings ss( argc , argv );
  if( !ss ) {
    return; // it's not the end of the world
  }

  if( !ss.mol_file().empty() ) {
    read_mol_file( QString( ss.mol_file().c_str() ) );
  }
  if( !ss.smarts_file().empty() ) {
    read_smarts_file( QString( ss.smarts_file().c_str() ));
  }
  if( !ss.mdl_file().empty() ) {
    read_mdl_query_file( QString( ss.mdl_file().c_str() ) );
  }
  if( !ss.data_file().empty() ) {
    read_data_file( QString( ss.data_file().c_str() ) );
  }
  usage_text_ = ss.usage_text();

}

// ****************************************************************************
void SmiV::slot_quit() {

  exit( 0 );

}

// ****************************************************************************
void SmiV::slot_file_read_mols() {

  QString filename =
      QFileDialog::getOpenFileName( this , "Choose molecule file" , last_dir_ ,
                                    "Molecules (*.smi *.mol2 *.sdf *.oeb)" );
  if( filename.isEmpty() ) {
    return;
  }

  read_mol_file( filename );

}

// ****************************************************************************
void SmiV::slot_file_reread_mols() {

  if( !last_mol_file_.isEmpty() ) {
    smiv_recs_.clear();
    read_mol_file( last_mol_file_ );
  } else {
    QMessageBox::warning( this , "No Mol file" , "You have not yet read a molecule file to re-read." );
  }
}

// ****************************************************************************
void SmiV::slot_file_read_smarts() {

  QString filename =
      QFileDialog::getOpenFileName( this , "Choose SMARTS file" , last_dir_ ,
                                    "SMARTS (*.smt);;Any File (*)" );
  if( filename.isEmpty() )
    return;

  read_smarts_file( filename );

}

// ****************************************************************************
void SmiV::slot_file_reread_smarts() {

  if( !last_smarts_file_.isEmpty() ) {
    smarts_.clear();
    smarts_sub_defn_.clear();
    read_smarts_file( last_smarts_file_ );
  } else {
    QMessageBox::warning( this , "No SMARTS file" , "You have not yet read a SMARTS file to re-read." );
  }

}

// ****************************************************************************
void SmiV::slot_file_read_mdl_query() {

  QString filename =
      QFileDialog::getOpenFileName( this , "Choose MDL Query file" , last_dir_ ,
                                    "MDL (*.mol)" );
  if( filename.isEmpty() )
    return;

  read_mdl_query_file( filename );

}

// ****************************************************************************
void SmiV::slot_file_read_data() {

  QString filename =
      QFileDialog::getOpenFileName( this , "Choose data file" , last_dir_ ,
                                    "CSV (*.csv);;Any File(*)" );
  if( filename.isEmpty() )
    return;

  read_data_file( filename );

}

// ****************************************************************************
void SmiV::slot_write_smiles() {

  QString filename =
    QFileDialog::getSaveFileName( this , "SMILES file" ,
                                  last_dir_ , "SMILES file (*.smi)" );

  if( filename.isEmpty() )
    return;

  write_smiles_file( filename );

}

// ****************************************************************************
void SmiV::slot_clear_molecules() {

  smiv_recs_.clear();
  left_panel_->add_data( smiv_recs_ );
  right_panel_->add_data( smiv_recs_ );
  right_panel_->hide();

}

// ****************************************************************************
void SmiV::slot_write_smarts() {

  QString filename =
    QFileDialog::getSaveFileName( this , "SMARTS file" ,
                                  last_dir_ , "SMARTS file (*.smt)" );

  if( filename.isEmpty() )
    return;

  write_smarts_file( filename );

}

// ****************************************************************************
void SmiV::slot_clear_smarts() {

  smarts_.clear();
  smarts_sub_defn_.clear();

}

// ****************************************************************************
void SmiV::slot_find_mol() {

  if( !find_mol_dialog_ ) {
    find_mol_dialog_ = new SmiVFindMoleculeDialog( this );
    connect( find_mol_dialog_ , SIGNAL( molecule_search_name( QString , int ) ) ,
             this , SLOT( slot_molecule_search_name( QString , int ) ) );
  }

  find_mol_dialog_->show();

}

// *****************************************************************************
void SmiV::slot_smarts_match() {

  if( smarts_.empty() ) {
    QMessageBox::information( this , "SMARTS Match" , "No SMARTS defined." );
    return;
  }

  do_smarts_matching();

}

// *****************************************************************************
void SmiV::slot_smarts_edit() {

  if( smarts_.empty() ) {
    slot_smarts_input_int_pick();
    return;
  }

  // first, select SMARTS pattern to edit
  vector<char> sel_smarts;
  get_query_to_use( sel_smarts , smarts_ , true );
  if( 0 == count( sel_smarts.begin() , sel_smarts.end() , 1 ) ) {
    return;
  }
  vector<char>::iterator p = std::find( sel_smarts.begin() , sel_smarts.end() , 1 );

  string int_pick_smi = get_active_smiles();

  QTSmartsIntPickDialog sipd( int_pick_smi , this );
  sipd.set_smarts_sub_defns( smarts_sub_defn_ );
  sipd.set_smarts( smarts_[distance( sel_smarts.begin() , p )].second.c_str() );
  sipd.set_smarts_name(smarts_[distance( sel_smarts.begin() , p )].first.c_str() );
  if( QDialog::Accepted != sipd.exec() ) {
    return;
  }

  add_smarts_definition( sipd );

}

// *****************************************************************************
void SmiV::slot_smarts_input_int_pick() {

  string int_pick_smi = get_active_smiles();

  QTSmartsIntPickDialog sipd( int_pick_smi , this );
  sipd.set_smarts_sub_defns( smarts_sub_defn_ );
  if( QDialog::Accepted != sipd.exec() ) {
    return;
  }

  add_smarts_definition( sipd );

}

// *****************************************************************************
void SmiV::slot_mdl_query_match() {

  if( mdl_queries_.empty() ) {
    QMessageBox::information( this , "MDL Query Match" , "No MDL query defined." );
    return;
  }

  do_mdl_query_matching();

}

// *****************************************************************************
void SmiV::slot_show_about_box() {

  QString msg;
  msg = QString( "SmiV\n"
                 "Copyright AstraZeneca 2016\n"
                 "Built on %1\nusing OEChem version %2\nand Qt version %3\n" )
    .arg( BUILD_TIME.c_str() ).arg( OEChemGetRelease() ).arg( QT_VERSION_STR );
  msg += usage_text_.c_str();

  QMessageBox::information( this , "About SmiV" , msg ,
                            QMessageBox::Ok | QMessageBox::Default );

}

// ****************************************************************************
// search mode is 0 for Exact Match, 1 for Starts With, 2 for Contains
void SmiV::slot_molecule_search_name( QString search_name , int search_mode ) {

#ifdef NOTYET
  cout << "Looking for " << search_name.toStdString() << " in mode " << search_mode
      << endl;
#endif

  SmiVPanel *panel = get_active_panel();
  bool found_in_panel = panel->show_molecule( search_name.toLocal8Bit().data() , search_mode );
  if( !found_in_panel ) {
    panel = get_inactive_panel();
    if( !panel->isHidden() ) {
      panel->show_molecule( search_name.toLocal8Bit().data() , search_mode );
    }
  }

}

// ****************************************************************************
void SmiV::slot_panel_selection_changed( QWidget *panel ) {

  if( panel == left_panel_ ) {
    right_panel_->set_selected( !left_panel_->is_selected() );
  } else {
    left_panel_->set_selected( !right_panel_->is_selected() );
  }

}

// ****************************************************************************
void SmiV::slot_input_smiles() {

#ifdef NOTYET
  cout << "SmiV::slot_input_smiles" << endl;
#endif

  if( !smiles_edit_dialog_ ) {
    smiles_edit_dialog_ = new DACLIB::QTSmilesEditDialog( this );
    connect( smiles_edit_dialog_ , SIGNAL( new_smiles( QString , QString ) ) ,
             this , SLOT( slot_new_smiles( QString , QString ) ) );
  }

  if( QDialog::Accepted != smiles_edit_dialog_->exec() ) {
    return;
  }

}

// ****************************************************************************
void SmiV::slot_edit_smiles() {

  if( !smiles_edit_dialog_ ) {
    smiles_edit_dialog_ = new DACLIB::QTSmilesEditDialog( this );
    connect( smiles_edit_dialog_ , SIGNAL( new_smiles( QString , QString ) ) ,
             this , SLOT( slot_new_smiles( QString , QString ) ) );
  }

  SmiVPanel *sp = get_active_panel();
  pSmiVRec smiv_rec = sp->current_smiv_rec();
  if( smiv_rec ) {
    smiles_edit_dialog_->set_smiles( smiv_rec->in_smi().c_str() );
    smiles_edit_dialog_->set_name( smiv_rec->smi_name().c_str() );
  }

  if( QDialog::Accepted != smiles_edit_dialog_->exec() ) {
    return;
  }

}

// ****************************************************************************
void SmiV::slot_new_smiles( QString new_smiles , QString new_name ) {

  cout << "slot_new_smiles : " << new_smiles.toStdString() << " : " << new_name.toStdString() << endl;
  update_smiv_recs( new_smiles.toLocal8Bit().data() ,
                    new_name.toLocal8Bit().data() );

}

// ****************************************************************************
void SmiV::slot_full_list() {

  right_panel_->hide();
  left_panel_->add_data( smiv_recs_ );
  left_panel_->set_title( "All Molecules" );

}

// ****************************************************************************
void SmiV::slot_new_mol_list() {

  new_mol_list( QString( "" ) );

}

// ****************************************************************************
void SmiV::slot_save_mol_list() {

  // just writes the names
  QString filename = QFileDialog::getSaveFileName( this , "What filename?" , last_dir_);
  if( filename.isEmpty() ) {
    return;
  }
  ofstream ofs( filename.toLocal8Bit().data() );
  if( !ofs ) {
    QString msg = QString( "Couldn't open %1 for writing.").arg( filename );
    QMessageBox::warning( this , "Bad File" , msg );
    return;
  }

  SmiVPanel *sp = get_active_panel();
  vector<pSmiVRec> these_recs = sp->smiv_recs();
  transform( these_recs.begin() , these_recs.end() ,
             ostream_iterator<string>( ofs , "\n" ) , bind( &SmiVRecord::smi_name , _1 ) );

}

// ****************************************************************************
void SmiV::slot_show_mol_list() {

  QAction *action = qobject_cast<QAction *>(sender());
  if( action ) {
    show_mol_list( action->text() );
  }

}

// ****************************************************************************
void SmiV::slot_sort_data_table( int col_num ) {

  if( Qt::DescendingOrder == data_table_->last_sort_order() ) {
    data_table_->sort( col_num , Qt::AscendingOrder );
  } else {
    data_table_->sort( col_num , Qt::DescendingOrder );
  }

}

// ****************************************************************************
void SmiV::slot_data_table_cell_double_clicked( const QModelIndex &ind ) {

  int row_num( ind.row() );
  int col_num( ind.column() );

  if( row_num < 0 || row_num >= data_table_->rowCount() ||
      col_num < 0 || col_num >= data_table_->columnCount() ) {
    return; // not a useful cell
  }

  if( col_num == get_data_table_column_number( QString( "CoreSmiles" ) ) ) {
    show_core_smiles_molecule( row_num );
  } else if( col_num == get_data_table_column_number( QString( "CoreSmarts" ) ) ) {
    search_with_core_smarts( row_num );
  } else {
    show_molecule_from_data_table( row_num );
  }

}

// *****************************************************************************************
void SmiV::slot_data_table_show_row( QString row_name ) {

  // assume the compound name is in the first column of the table
  for( unsigned int i = 0 , is = data_table_->rowCount() ; i < is ; ++i ) {
    if( data_table_->data( i , 0 ).toString() == row_name ) {
      data_table_view_->scrollTo( data_table_->index( i , 0 ) );
      break;
    }
  }

}

// ****************************************************************************
void SmiV::build_actions() {

  build_file_actions();
  build_smarts_actions();
  build_mdl_query_actions();
  build_molecule_actions();
  build_help_actions();

}

// **************************************************************************
void SmiV::build_file_actions() {

  file_read_data_ = new QAction( "Read Data File" , this );
  file_read_data_->setStatusTip( "Read arbitrary data file into table" );
  connect( file_read_data_ , SIGNAL( triggered() ) , this , SLOT( slot_file_read_data() ) );

  file_quit_ = new QAction( "Quit" , this );
  file_quit_->setShortcut( QString( "Ctrl+Q" ) );
  file_quit_->setStatusTip( "Exit the application" );
  connect( file_quit_ , SIGNAL( triggered() ) , this , SLOT( slot_quit() ) );

}

// **************************************************************************
void SmiV::build_smarts_actions() {

  file_read_smarts_ = new QAction( "Read SMARTS File" , this );
  connect( file_read_smarts_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_file_read_smarts() ) );

  file_reread_smarts_ = new QAction( "Re-Read last SMARTS File" , this );
  connect( file_reread_smarts_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_file_reread_smarts() ) );

  smarts_match_ = new QAction( "Match" , this );
  connect( smarts_match_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_smarts_match() ) );
  smarts_match_->setShortcut( QString( "Ctrl+M" ) );

  smarts_input_edit_ = new QAction( "Edit Existing" , this );
  connect( smarts_input_edit_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_smarts_edit() ) );

  smarts_input_int_pick_ = new QAction( "Interactive Pick" , this );
  connect( smarts_input_int_pick_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_smarts_input_int_pick() ) );

  smarts_write_ = new QAction( "Write File" , this );
  connect( smarts_write_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_write_smarts() ) );

  clear_smarts_ = new QAction( "Clear SMARTS" , this );
  connect( clear_smarts_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_clear_smarts() ) );

}

// **************************************************************************
void SmiV::build_mdl_query_actions() {

  file_read_mdl_query_ = new QAction( "Read MDL Query File" , this );
  connect( file_read_mdl_query_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_file_read_mdl_query() ) );

  mdl_query_match_ = new QAction( "Match" , this );
  connect( mdl_query_match_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_mdl_query_match() ) );

}

// **************************************************************************
void SmiV::build_molecule_actions() {

  file_read_mol_ = new QAction( "Read Molecule File" , this );
  file_read_mol_->setShortcut( QString( "Ctrl+R" ) );
  connect( file_read_mol_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_file_read_mols() ) );
  file_reread_mol_ = new QAction( "Re-Read Last Molecule File" , this );
  connect( file_reread_mol_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_file_reread_mols() ) );

  file_write_smiles_ = new QAction( "Write SMILES File" , this );
  file_write_smiles_->setShortcut( QString( "Ctrl+W" ) );
  connect( file_write_smiles_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_write_smiles() ) );

  find_mol_ = new QAction( "Find Mol." , this );
  find_mol_->setShortcut( QString( "Ctrl+F" ) );
  connect( find_mol_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_find_mol() ) );

  input_smiles_ = new QAction( "Input SMILES" , this );
  connect( input_smiles_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_input_smiles() ) );

  edit_smiles_ = new QAction( "Edit SMILES" , this );
  connect( edit_smiles_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_edit_smiles() ) );

  new_list_ = new QAction( "Create New" , this );
  new_list_->setShortcut( QString( "Ctrl+L") );
  connect( new_list_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_new_mol_list() ) );

  save_list_ = new QAction( "Save" , this );
  connect( save_list_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_save_mol_list() ) );

  full_list_ = new QAction( "Full Set" , this );
  full_list_->setShortcut( QString( "Ctrl+A") );
  connect( full_list_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_full_list() ) );

  clear_mols_ = new QAction( "Clear Molecules" , this );
  connect( clear_mols_ , SIGNAL( triggered() ) ,
           this , SLOT( slot_clear_molecules() ) );

}

// **************************************************************************
void SmiV::build_help_actions() {

  help_show_about_ = new QAction( "About SmiV" , this );
  connect( help_show_about_ , SIGNAL( triggered() ) ,
	   this , SLOT( slot_show_about_box() ) );

}

// ****************************************************************************
void SmiV::build_menubar() {

  QMenu *file_menu = menuBar()->addMenu( "File" );
  file_menu->addAction( file_read_mol_ );
  file_menu->addAction( file_reread_mol_ );
  file_menu->addAction( file_read_smarts_ );
  file_menu->addAction( file_reread_smarts_ );
  file_menu->addAction( file_read_mdl_query_ );
  file_menu->addAction( file_read_data_ );
  file_menu->addSeparator();
  file_menu->addAction( file_quit_ );

  QMenu *smarts_menu = menuBar()->addMenu( "SMARTS" );
  smarts_menu->addAction( smarts_match_ );
  smarts_menu->addAction( smarts_input_edit_ );
  smarts_menu->addAction( smarts_input_int_pick_ );
  smarts_menu->addAction( file_read_smarts_ );
  smarts_menu->addAction( file_reread_smarts_ );
  smarts_menu->addAction( smarts_write_ );
  smarts_menu->addAction( clear_smarts_ );

  QMenu *mdl_query_menu = menuBar()->addMenu( "MDL Query" );
  mdl_query_menu->addAction( mdl_query_match_ );

  QMenu *mol_menu = menuBar()->addMenu( "Molecules" );
  mol_menu->addAction( file_read_mol_ );
  mol_menu->addAction( file_reread_mol_ );
  mol_menu->addAction( file_write_smiles_ );
  mol_menu->addAction( find_mol_ );
  mol_menu->addAction( input_smiles_ );
  mol_menu->addAction( edit_smiles_ );
  mol_menu->addAction( clear_mols_ );
  mol_lists_menu_ = mol_menu->addMenu( "Lists");
  mol_lists_menu_->addAction( full_list_ );
  mol_list_separator_ = mol_lists_menu_->addSeparator(); // so we can insert ahead of it in menu
  mol_lists_menu_->addAction( new_list_ );
  mol_lists_menu_->addAction( save_list_ );

  QMenu *help_menu = menuBar()->addMenu( "Help" );
  help_menu->addAction( help_show_about_ );

}

// ****************************************************************************
void SmiV::build_widget() {

  QSplitter *splitter = new QSplitter;
  splitter->setOrientation( Qt::Vertical );

  QHBoxLayout *hbox = new QHBoxLayout;

  left_panel_ = new SmiVPanel;
  left_panel_->set_selected( true );
  hbox->addWidget( left_panel_ );

  connect( left_panel_ , SIGNAL( selection_box_changed( QWidget * ) ) ,
           this , SLOT( slot_panel_selection_changed( QWidget * ) ) );
  connect( left_panel_ , SIGNAL( new_display_mol( QString ) ) ,
           this , SLOT( slot_data_table_show_row( QString ) ) );

  right_panel_ = new SmiVPanel;
  hbox->addWidget( right_panel_ );
  right_panel_->hide();

  connect( right_panel_ , SIGNAL( selection_box_changed( QWidget * ) ) ,
           this , SLOT( slot_panel_selection_changed( QWidget * ) ) );
  connect( right_panel_ , SIGNAL( new_display_mol( QString ) ) ,
           this , SLOT( slot_data_table_show_row( QString ) ) );

  data_table_ = new SmivDataTable;
  data_table_view_ = new QTableView;
  data_table_view_->setModel( data_table_ );
  data_table_view_->hide();
  connect( data_table_view_->horizontalHeader() , SIGNAL( sectionClicked( int ) ) ,
           this , SLOT( slot_sort_data_table( int ) ) );

  connect( data_table_view_ , SIGNAL( doubleClicked( const QModelIndex & ) ) ,
           this , SLOT( slot_data_table_cell_double_clicked( const QModelIndex & ) ) );

  QWidget *hbox_wid = new QWidget;
  hbox_wid->setLayout( hbox );
  splitter->addWidget( hbox_wid );
  splitter->addWidget( data_table_view_ );
  setCentralWidget( splitter );

}

// ****************************************************************************
void SmiV::read_mol_file( const QString &filename ) {

  QFileInfo fi( filename );
  if( !fi.exists() ) {
    return;
  }

  last_mol_file_ = filename;
  last_dir_ = fi.absolutePath();

  if( filename.endsWith( ".smi") || filename.endsWith( ".smi.gz") ) {
    read_smiles_file( filename );
  } else {
    read_other_mol_file( filename );
  }

  show_all_molecules();
  update_status_count();

}

// *****************************************************************************
void SmiV::read_smiles_file( const QString &filename ) {

  QFileInfo fi( filename );
  if( !fi.exists() ) {
    return;
  }

  last_dir_ = fi.absolutePath();

  ifstream file( filename.toLocal8Bit().data() , ios_base::in | ios_base::binary );
  boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
  if( filename.endsWith( ".smi.gz" ) ) {
    in.push( boost::iostreams::gzip_decompressor() );
  }
  in.push( file );

  istreambuf_iterator<char> init( &in ) , eos;

  vector<char> nextline;
  vector<pair<string,string> > in_smiles;

  while( init != eos ) {
    nextline.clear();
    while( init != eos && *init != '\n' ) {
      nextline.push_back( *init );
      ++init;
    }
    boost::trim( nextline );
    if( !nextline.empty() ) {
      vector<string> split_line;
      split( split_line , nextline , is_any_of( " ,\t" ) );
      if( !split_line.empty() ) {
        string mol_name;
        if( split_line.size() > 1 ) {
          mol_name = string( nextline.begin() + split_line[0].length() + 1 ,
                             nextline.end() );
          boost::trim( mol_name );
        } else {
          mol_name = string( "Mol" ) + lexical_cast<string>( smiv_recs_.size() + 1 );
        }
        SmiVRecord *smiv_rec = new SmiVRecord( split_line[0] , mol_name );
        smiv_recs_.push_back( pSmiVRec( smiv_rec ) );
      }
    }
    ++init; // get past '\n'
  }

}

// ****************************************************************************
void SmiV::read_other_mol_file( const QString &filename ) {

  QFileInfo fi( filename );
  if( !fi.exists() ) {
    return;
  }

  last_dir_ = fi.absolutePath();

  oemolistream ims( filename.toLocal8Bit().data() );
  OEMol mol;
  while( ims >> mol ) {
    DACLIB::apply_daylight_aromatic_model( mol );
    SmiVRecord *smiv_rec = new SmiVRecord( mol );
    smiv_recs_.push_back( pSmiVRec( smiv_rec ) );
  }

}

// ****************************************************************************
void SmiV::read_smarts_file( const QString &filename ) {

  QFileInfo fi( filename );
  if( !fi.exists() ) {
    return;
  }

  last_smarts_file_ = filename;
  last_dir_ = fi.absolutePath();

  try {
    DACLIB::read_smarts_file( filename.toLocal8Bit().data() ,
                              smarts_ , smarts_sub_defn_ );
  } catch( DACLIB::SMARTSSubDefnError &e ) {
    cout << e.what() << endl;
    QMessageBox::warning( this , "SMARTS file error" , e.what() );
    return;
  } catch( DACLIB::SMARTSFileError &e ) {
    cout << e.what() << endl;
    QMessageBox::warning( this , "SMARTS file error" , e.what() );
    return;
  }

  update_status_count();

}

// ****************************************************************************
void SmiV::read_mdl_query_file( const QString &filename ) {

  cout << "Reading MDL query file " << filename.toLocal8Bit().data() << endl;

  QFileInfo fi( filename );
  if( !fi.exists() ) {
    return;
  }

  last_dir_ = fi.absolutePath();

  ifstream ifs( filename.toLocal8Bit().data() );
  if( !ifs || !ifs.good() ) {
    QMessageBox::warning( this , "MDL query file error" ,
                          QString( "Couldn't open %1 for reading.").arg( filename ) );
    return;
  }

  int count = 0;
  string next_line;
  vector<string> next_query;
  while( 1 ) {
    getline( ifs , next_line );
    if( ifs.eof() || !ifs.good() ) {
      ++count;
      store_next_mdl_query( next_query , filename , count );
      break;
    }
    if( next_line == string( "$$$$") ) {
      ++count;
      store_next_mdl_query( next_query , filename , count );
      next_query.clear();
    } else {
      next_query.push_back( next_line );
    }

  }

  update_status_count();

}

// ****************************************************************************
void SmiV::read_data_file( const QString &filename ) {

  QFileInfo fi( filename );
  if( !fi.exists() ) {
    return;
  }

  last_dir_ = fi.absolutePath();

  data_table_->read_data_from_file( this , filename );

  statusBar()->showMessage( QString( "Read %1 lines of data." ).arg( data_table_->rowCount() ) , 2000 );

  data_table_view_->show();

}

// ****************************************************************************
void SmiV::write_smiles_file( const QString &filename ) {

  QFileInfo fi( filename );
  last_dir_ = fi.absolutePath();

  ofstream ofs( filename.toLocal8Bit().data() );
  if( !ofs.good() ) {
    QMessageBox::warning( this , "File Open Error" ,
			  QString( "Couldn't open file \n%1\nfor writing." ).arg( filename ) );
    return;
  }

  get_active_panel()->write_smiles_to_stream( ofs );

}

// ****************************************************************************
void SmiV::write_smarts_file( const QString &filename ) {

  QFileInfo fi( filename );
  last_dir_ = fi.absolutePath();

  ofstream ofs( filename.toLocal8Bit().data() );
  if( !ofs.good() ) {
    QMessageBox::warning( this , "File Open Error" ,
              QString( "Couldn't open file \n%1\nfor writing." ).arg( filename ) );
    return;
  }

  ofs << "#" << endl
      << "# SMARTS file written by SmiV" << endl
      << "#" << endl
      << "# Full Definitions" << endl
      << "#" << endl;

  for( int i = 0 , is = smarts_.size() ; i < is ; ++i ) {
    ofs << smarts_[i].first << "\t" << smarts_[i].second << "\t" << "1\t1" << endl;
  }

  ofs << "#" << endl
      << "# Sub-Definitions (Vector Bindings)" << endl
      << "#" << endl;

  for( int i = 0 , is = smarts_sub_defn_.size() ; i < is ; ++i ) {
    // don't write the sub def if it's also a SMARTS def, as we don't want things
    // in the file twice
    if( smarts_.end() == std::find_if( smarts_.begin() , smarts_.end() ,
                                       bind( std::equal_to<string>() ,
                                                    bind( &pair<string,string>::first , _1 ) ,
                                                    smarts_sub_defn_[i].first ) ) ) {
      ofs << smarts_sub_defn_[i].first << "\t" << smarts_sub_defn_[i].second << "\t" << "1\t0" << endl;
    }
  }

}

// ****************************************************************************
void SmiV::update_status_count() {

  QString msg = QString( "Now have %1 active molecules, %2 SMARTS definitions, %3 MDL queries." )
    .arg( smiv_recs_.size() ).arg( smarts_.size() ).arg( mdl_queries_.size() );
  statusBar()->showMessage( msg , 0 );

}

// ****************************************************************************
// reset to just left_panel_, showing all molecules
void SmiV::show_all_molecules() {

  right_panel_->hide();
  left_panel_->add_data( smiv_recs_ );
  left_panel_->set_title( QString( "All Molecules" ) );

}

// ****************************************************************************
// reset to just left_panel_, showing all molecules
void SmiV::show_mol_list( const QString &list_name ) {

  vector<pair<string,vector<pSmiVRec> > >::iterator p =
      find_if( rec_lists_.begin() , rec_lists_.end() ,
               bind( equal_to<string>() ,
                     bind( &pair<string,vector<pSmiVRec> >::first , _1 ) ,
                     list_name.toLocal8Bit().data() ) );
  right_panel_->hide();
  left_panel_->add_data( p->second );
  left_panel_->set_title( list_name );

}

// ****************************************************************************
// get name of molecule in row_num of data table and show whichever panel currently has it
void SmiV::show_molecule_from_data_table( int row_num ) {

  slot_molecule_search_name( data_table_->data( row_num , 0 ).toString() , 0 );

}

// ****************************************************************************
// do smarts matching on contents of left panel only
void SmiV::do_smarts_matching() {

  // first, select one or more SMARTS patterns to use
  vector<char> sel_smarts;
  get_query_to_use( sel_smarts , smarts_ , false );
  if( 0 == count( sel_smarts.begin() , sel_smarts.end() , 1 ) ) {
    show_all_molecules();
    return;
  }

  vector<pair<boost::shared_ptr<OESubSearch>,string> > sub_searches;
  QString smarts_list;
  build_sub_searches_from_smarts( sel_smarts , smarts_list , sub_searches );
  do_substructure_matching( sub_searches , smarts_list , true );

}

// ****************************************************************************
// do MDL query matching on contents of left panel only
void SmiV::do_mdl_query_matching() {

  cout << "SmiV::do_mdl_query_matching()" << endl;
  vector<char> sel_query;
  get_query_to_use( sel_query , mdl_queries_ , false );
  if( 0 == count( sel_query.begin() , sel_query.end() , 1 ) ) {
    show_all_molecules();
    return;
  }

  vector<pair<boost::shared_ptr<OESubSearch>,string> > sub_searches;
  QString query_list;
  build_sub_searches_from_mdl_queries( sel_query , query_list , sub_searches );
  do_substructure_matching( sub_searches , query_list , true );

}

// ****************************************************************************
void SmiV::do_substructure_matching( vector<pair<boost::shared_ptr<OESubSearch>,string> > &sub_searches ,
                                     const QString &list_name , bool show_non_matches ) {

  vector<pSmiVRec> ones_to_do = left_panel_->smiv_recs();

  QApplication::setOverrideCursor( Qt::WaitCursor );
  vector<pSmiVRec> left_list , right_list;
  for( int i = 0 , is = ones_to_do.size() ; i < is ; ++i ) {
    scoped_ptr<OEMolBase> mol( OENewMolBase( OEMolBaseType::OEDefault ) );
    OEParseSmiles( *mol ,  ones_to_do[i]->in_smi() );
    DACLIB::apply_daylight_aromatic_model( *mol );
    bool match_found( false );
    for( int j = 0 , js = sub_searches.size() ; j < js ; ++j ) {
      if( sub_searches[j].first->SingleMatch( *mol ) ) {
        match_found = true;
        break;
      }
    }
    if( match_found ) {
      left_list.push_back( ones_to_do[i] );
    } else {
      right_list.push_back( ones_to_do[i] );
    }
  }
  QApplication::restoreOverrideCursor();

  left_panel_->add_data( left_list );
  left_panel_->set_subsearches( sub_searches );
  QString title = "Matched : " + list_name;
  left_panel_->set_title( title );

  if( show_non_matches ) {
    right_panel_->show();
    right_panel_->add_data( right_list );
    title = "Didn't Match : " + list_name;
    right_panel_->set_title( title );
  } else {
    right_panel_->hide();
  }

}

// ****************************************************************************
void SmiV::get_query_to_use( vector<char> &sel_query ,
                             const vector<pair<string,string> > &query_set ,
                             bool single_sel ) {

  sel_query = vector<char>( query_set.size() , 0 );
  vector<QString> query_names;
  typedef pair<string,string> QP;
  BOOST_FOREACH( const QP query , query_set ) {
    query_names.push_back( QString( query.first.c_str() ) );
  }

  QT4SelectItems si( "Which query to Use?" , query_names , sel_query , single_sel , this );
  si.exec();

}

// ****************************************************************************
void SmiV::build_sub_searches_from_smarts( const vector<char> &sel_smarts ,
                                           QString &smarts_list ,
                                           vector<pair<boost::shared_ptr<OESubSearch>,string> > &sub_searches ) {

  smarts_list = "";
  for( int i = 0 , is = sel_smarts.size() ; i < is ; ++i ) {
    if( !sel_smarts[i] ) {
      continue;
    }
    if( smarts_list.isEmpty() ) {
      smarts_list = smarts_[i].first.c_str();
    } else {
      smarts_list += QString( "|%1" ).arg( smarts_[i].first.c_str() );
    }

    OESubSearch *subs;
    try {
      subs = DACLIB::create_eosubsearch( smarts_[i].second , smarts_[i].first ,
                                         false , smarts_sub_defn_ );
    } catch( DACLIB::SMARTSSubDefnError &e ) {
      QMessageBox::warning( this , "SMARTS Error" , e.what() );
      continue;
    } catch( DACLIB::SMARTSDefnError &e ) {
      QMessageBox::warning( this , "SMARTS Error" , e.what() );
      continue;
    }
    sub_searches.push_back( make_pair( boost::shared_ptr<OESubSearch>( subs ) ,
                                       smarts_[i].first ) );
  }

}

// ****************************************************************************
void SmiV::build_sub_searches_from_mdl_queries( const vector<char> &sel_mdl_queries ,
                                                QString &mdl_list ,
                                                vector<pair<boost::shared_ptr<OESubSearch>,string> > &sub_searches ) {

  mdl_list = "";
  for( int i = 0 , is = sel_mdl_queries.size() ; i < is ; ++i ) {
    if( !sel_mdl_queries[i] ) {
      continue;
    }
    if( mdl_list.isEmpty() ) {
      mdl_list = mdl_queries_[i].first.c_str();
    } else {
      mdl_list += QString( "|%1" ).arg( mdl_queries_[i].first.c_str() );
    }

    oemolistream ims;
    ims.openstring( mdl_queries_[i].second );
    unsigned int aromodel = OEIFlavor::Generic::OEAroModelDaylight;
    unsigned int qflavor  = ims.GetFlavor( OEFormat::MDL );
    ims.SetFlavor( OEFormat::MDL , qflavor|aromodel );

    OEQMol qmol;
    OEReadMDLQueryFile( ims , qmol , OEMDLQueryOpts::Default );

    OESubSearch *subs = new OESubSearch( qmol );
    sub_searches.push_back( make_pair( boost::shared_ptr<OESubSearch>( subs ) ,
                                       mdl_queries_[i].first ) );
  }

}

// ****************************************************************************
void SmiV::add_smarts_definition( const QString &smarts_name , const QString &smarts_def ) {

  string smt_name( smarts_name.toLocal8Bit().data() );
  bool over_write = false;
  bool found_in_full = check_existing_smarts( smt_name , smarts_ , over_write );
  if( found_in_full ) {
    cout << "check_existing_smarts 1 true" << endl;
    if( !over_write ) {
      return;
    }
  }
  bool found_in_sub = true; // if it's found_in_full, it must be found_in_sub
  if( !found_in_full ) {
    found_in_sub = check_existing_smarts( smt_name , smarts_sub_defn_ , over_write );
  }

  if( (found_in_full || found_in_sub ) && !over_write ) {
    cout << "not over-writing" << endl;
    return;
  }

  if( !found_in_full && !found_in_sub ) {
    // it's all new, so put it in both. All smarts_ entries should also be in smarts_sub_defn_.
    smarts_.push_back( make_pair( smarts_name.toLocal8Bit().data() , smarts_def.toLocal8Bit().data() ) );
    smarts_sub_defn_.push_back( smarts_.back() );
    return;
  }

  vector<pair<string,string> >::iterator ssdp =
      find_if( smarts_sub_defn_.begin() , smarts_sub_defn_.end() ,
               bind( std::equal_to<string>() ,
                     bind( &pair<string,string>::first , _1 ) , smt_name ) );

  if( found_in_sub && !found_in_full ) {
    // if only in smarts_sub_defn, just replace what's there
    ssdp->second = smarts_def.toLocal8Bit().data();
  } else if( found_in_full && found_in_sub ) {
    // if in both, replace both
    vector<pair<string,string> >::iterator fsp =
        find_if( smarts_.begin() , smarts_.end() ,
                 bind( std::equal_to<string>() ,
                       bind( &pair<string,string>::first , _1 ) , smt_name ) );
    fsp->second = smarts_def.toLocal8Bit().data();
    ssdp->second = smarts_def.toLocal8Bit().data();
  }

}

// ****************************************************************************
void SmiV::add_smarts_definition( QTSmartsEditDialog &sed ) {

  QString smt_string = sed.get_smarts();
  QString smt_name = sed.get_smarts_name();
#ifdef NOTYET
  cout << "SMARTS : " << smt_name.toStdString() << " = "
      << smt_string.toStdString() << endl;
#endif
  add_smarts_definition( smt_name , smt_string );

}

// ****************************************************************************
void SmiV::store_next_mdl_query( const vector<string>  &next_query ,
                                 const QString &filename , int count ) {

  // the query needs a little TLC, as if it has R Groups in it, it may have
  // extraneous guff that OEChem doesn't seem to deal with
  // first, strip out everything that starts with a $. Then, as soon as
  // we hit M  END, stop as we don't want anything after that.
  string query_string;
  BOOST_FOREACH( string next_line , next_query ) {
    if( '$' != next_line[0] ) {
      query_string += next_line + '\n';
    }
    if( string( "M  END") == next_line.substr( 0 , 6 ) ) {
      cout << "breaking on M  END" << endl;
      break;
    }

  }

  QString short_name( filename.section( "/" , -1 ) );
  string query_name = string( short_name.toLocal8Bit().data() ) + "_" +
                      lexical_cast<string>( count );
  mdl_queries_.push_back( make_pair( query_name , query_string ) );

}

// ****************************************************************************
// sees if the SMARTS name is already used. If it does, see what the user
// wants to do about it - returns true if user wants to leave it as it is,
// false if it's to be overwritten or it wasn't found
bool SmiV::check_existing_smarts( const string &smarts_name ,
                                  const vector<pair<string,string> > &smarts_defs ,
                                  bool &over_write ) {

  vector<pair<string,string> >::const_iterator p =
      find_if( smarts_defs.begin() , smarts_defs.end() ,
               bind( std::equal_to<string>() ,
                     bind( &pair<string,string>::first , _1 ) , smarts_name ) );
  if( p == smarts_defs.end() ) {
    over_write = false;
    return false;
  }

  QString msg = QString( "SMARTS named %1 already exists.\n Overwrite?").arg( smarts_name.c_str() );
  over_write = bool( QMessageBox::Yes == QMessageBox::question( this , "Existing SMARTS" , msg ,
                                                               QMessageBox::Yes | QMessageBox::No ,
                                                               QMessageBox::Yes ) );
  return true;

}

// ****************************************************************************
string SmiV::get_active_smiles() const {

  string act_smi;
  SmiVPanel *panel = get_active_panel();
  pSmiVRec smiv_rec = panel->current_smiv_rec();
  if( smiv_rec ) {
    act_smi = smiv_rec->in_smi();
  }

  return act_smi;

}

// ****************************************************************************
SmiVPanel *SmiV::get_active_panel() const {

  SmiVPanel *panel = left_panel_;
  if( !right_panel_->isHidden() && right_panel_->is_selected() ) {
    panel = right_panel_;
  }

  return panel;

}

// ****************************************************************************
SmiVPanel *SmiV::get_inactive_panel() const {

  SmiVPanel *panel = get_active_panel();

  if( panel == left_panel_ ) {
    return right_panel_;
  } else {
    return left_panel_;
  }

}

// ****************************************************************************
void SmiV::update_smiv_recs( const string &new_smiles , const string &new_name ) {

  pSmiVRec new_rec( new SmiVRecord( new_smiles , new_name ) );
  vector<pSmiVRec>::iterator p = find_if( smiv_recs_.begin() , smiv_recs_.end() ,
                                          bind( equal_to<string>() ,
                                                bind( &SmiVRecord::smi_name , _1 ) ,
                                                new_rec->smi_name() ) );
  if( p != smiv_recs_.end() ) {
    bool ok = true;
    QString msg = QString( "%1 already used. Please supply a new one or Ok to over-write.").arg( new_name.c_str() );
    QString nm = QInputDialog::getText( this , "New Molecule Name" , msg , QLineEdit::Normal , new_name.c_str() , &ok );
    if( !ok ) {
      QString nm1 = QInputDialog::getText( this , "New Molecule Name" , "New name?" , QLineEdit::Normal , nm , &ok );
      if( !ok ) {
        return;
      }
      if( nm1 != nm )  {
        // make sure this new name's ok
        update_smiv_recs( new_smiles , nm1.toLocal8Bit().data() );
        return;
      }
    } else {
      string nms( nm.toLocal8Bit().data() );
      if( nms != new_name )  {
        // make sure this new name's ok
        update_smiv_recs( new_smiles , nms );
        return;
      } else {
        new_rec->set_smi_name( nms );
      }
    }
    *p = new_rec;
  } else {
    smiv_recs_.push_back( new_rec );
  }

  if( right_panel_->isHidden() ) {
    left_panel_->add_data( smiv_recs_);
  }

}

// ****************************************************************************
void SmiV::add_mol_list( const string &list_name ) {

  SmiVPanel *sp = get_active_panel();
  add_mol_list( list_name , sp->smiv_recs() );

}

// ****************************************************************************
void SmiV::add_mol_list( const string &list_name ,
                         const vector<pSmiVRec> &new_recs ) {

  rec_lists_.push_back( make_pair( list_name , new_recs ) );
  QAction *list_action = new QAction( list_name.c_str() , this );
  mol_lists_menu_->insertAction( mol_list_separator_ , list_action );
  connect( list_action , SIGNAL( triggered() ) , this , SLOT( slot_show_mol_list() ) );

}

// ****************************************************************************
void SmiV::new_mol_list( QString list_name ) {

  bool ok;
  list_name = QInputDialog::getText( this , "List Name" , "What name for list?" ,
                                             QLineEdit::Normal , list_name , &ok );
  if( !ok || list_name.isEmpty() ) {
    return;
  }

  string sln( list_name.toLocal8Bit().data() );
  vector<pair<string,vector<pSmiVRec> > >::iterator p =
      find_if( rec_lists_.begin() , rec_lists_.end() ,
               bind( equal_to<string>() ,
                     bind( &pair<string,vector<pSmiVRec> >::first , _1 ) ,
                     sln ) );
  if( p == rec_lists_.end() ) {
    add_mol_list( sln );
  } else {
    if( QMessageBox::Ok == QMessageBox::question( this , "List Name Already Used" ,
                                                  "That name is already in use. Over-write?" ) ) {
      SmiVPanel *sp = get_active_panel();
      p->second = sp->smiv_recs();
    }
  }

}

// ****************************************************************************
// for the special case when the data file that has been read into the table contained the columns
// CoreSmiles and CoreSmarts - extract the SMILES/SMARTS strings into the relevant lists
void SmiV::build_core_smiles_list() {

  int smiles_col = get_data_table_column_number( QString( "CoreSmiles" ) );
  if( -1 == smiles_col ) {
    // need an error message
    return;
  }

  vector<pair<string,vector<pSmiVRec> > >::iterator p =
      find_if( rec_lists_.begin() , rec_lists_.end() ,
               bind( equal_to<string>() ,
                     bind( &pair<string,vector<pSmiVRec> >::first , _1 ) ,
                     string( "CoreSmiles" ) ) );
  if( p == rec_lists_.end() ) {
    add_mol_list( "CoreSmiles" , vector<pSmiVRec>() );
    p = rec_lists_.begin() + ( rec_lists_.size() - 1 );
  }

  for( int i = 0 , is = data_table_->rowCount() ; i < is ; ++i ) {
    SmiVRecord *smiv_rec = new SmiVRecord( data_table_->data( i , smiles_col ).toString().toLocal8Bit().data() ,
                                           data_table_->data( i , 0 ).toString().toLocal8Bit().data() );
    smiv_recs_.push_back( pSmiVRec( smiv_rec ) );
    p->second.push_back( smiv_recs_.back() );
  }

}

// ****************************************************************************
void SmiV::build_core_smarts_list() {

  int smarts_col = get_data_table_column_number( QString( "CoreSmarts" ) );
  if( -1 == smarts_col ) {
    // need an error message
    return;
  }

  for( int i = 0 , is = data_table_->rowCount() ; i < is ; ++i ) {
    add_smarts_definition( data_table_->data( i , 0 ).toString() ,
                           data_table_->data( i , smarts_col ).toString() );
  }

}

// ****************************************************************************
void SmiV::show_core_smiles_molecule( int mol_num ) {

  show_mol_list( QString( "CoreSmiles" ) );
  string mol_name( data_table_->data( mol_num , 0 ).toString().toLocal8Bit().data() );
  left_panel_->go_to_first_mol();
  left_panel_->show_molecule( mol_name , 0 );

}

// ****************************************************************************
void SmiV::search_with_core_smarts( int smarts_num ) {

  string smarts_name( data_table_->data( smarts_num , 0 ).toString().toLocal8Bit().data() );
  vector<char> smarts_to_use( smarts_.size() , 0 );
  vector<pair<string,string> >::iterator p =
      find_if( smarts_.begin() , smarts_.end() ,
               bind( std::equal_to<string>() ,
                     bind( &pair<string,string>::first , _1 ) , smarts_name ) );
  if( p == smarts_.end() ) {
    return; // something's badly awry, however
  }

  smarts_to_use[distance( smarts_.begin() , p )] = 1;
  vector<pair<boost::shared_ptr<OESubSearch>,string> > sub_searches;
  QString smarts_list;
  build_sub_searches_from_smarts( smarts_to_use , smarts_list , sub_searches );
  show_all_molecules();
  do_substructure_matching( sub_searches , smarts_list , false );
  left_panel_->go_to_first_mol();

  new_mol_list( QString( smarts_name.c_str() ) );

}

// ****************************************************************************
// for all the CoreSmarts column in the data_table_, run against the full molecule list and
// calculate the number of R Group subst points round each core that are used, and the number
// of unique R Groups, feeding the results back into the columns RgroupPositions and
// NumberOfUniqueRgroups
void SmiV::do_rgroup_analysis_of_core_smarts() {

  vector<char> smarts_to_use( smarts_.size() , 1 );
  vector<pair<boost::shared_ptr<OESubSearch>,string> > sub_searches;
  QString smarts_list;
  build_sub_searches_from_smarts( smarts_to_use , smarts_list , sub_searches );
  vector<set<int> > rgroup_pos( smarts_.size() , set<int>() );
  vector<set<string> > unique_rgroups( smarts_.size() , set<string>() );
  vector<int> core_counts( smarts_.size() , 0 );

  BOOST_FOREACH( pSmiVRec rec , smiv_recs_ ) {
#ifdef NOTYET
      cout << "doing molecule " << rec->smi_name() << " : " << rec->in_smi() << endl;
#endif
      OEGraphMol mol;
      OEParseSmiles( mol , rec->in_smi() );
      bool core_mol( rec->smi_name().substr( 0 , 4 ) == string( "core" ) );
      for( int i = 0 , is = sub_searches.size() ; i < is ; ++i ) {
#ifdef NOTYET
        cout << "doing smarts " << i << " : " << sub_searches[i].second << " : " << smarts_[i].first << " : " << smarts_[i].second << endl;
#endif
        if( sub_searches[i].second.substr( 0 , 4 ) == string( "core" ) ) {
          if( core_mol ) {
            rgroup_core_count( mol , sub_searches[i].first , core_counts[i] );
          } else {
            rgroup_counts_and_strip( mol , sub_searches[i].first , rgroup_pos[i] , unique_rgroups[i] );
          }
        }
      }
  }

  update_rgroup_position_counts( rgroup_pos , unique_rgroups , core_counts );

}

// ****************************************************************************

void SmiV::rgroup_counts_and_strip( OEGraphMol &mol , boost::shared_ptr<OESubSearch> &sub ,
                                    set<int> &rgroup_pos , set<string> &unique_rgroups ) {

  // just want the first match, I think.  Symmetry issues aren't of interest.
  OEIter<OEMatchBase> match = sub->Match( mol , true );
  if( !match ) {
    return;
  }
  vector<unsigned int> in_core( DACLIB::max_atom_index( mol ) , 0 );
  for( OEIter<OEAtomBase> atom = match->GetTargetAtoms() ; atom ; ++atom ) {
    in_core[DACLIB::atom_index( *atom )] = 1;
  }
  int i = 0;
  for( OEIter<OEAtomBase> atom = match->GetTargetAtoms() ; atom ; ++atom , ++i ) {
    for( OEIter<OEAtomBase> conn = atom->GetAtoms() ; conn ; ++conn ) {
      if( !in_core[DACLIB::atom_index( *conn )] ) {
        rgroup_pos.insert( i );
        unique_rgroups.insert( generate_rgroup_smiles( mol , conn , in_core ) );
      }
    }
  }

}

// ****************************************************************************
string SmiV::generate_rgroup_smiles( OEGraphMol &mol , OEAtomBase &first_atom ,
                                     const vector<unsigned int> &in_core ) {

  string rgroup_smi;

  OEGraphMol mol_copy( mol );
  vector<unsigned int> ats_to_keep( DACLIB::max_atom_index( mol_copy ) , 0 );
  list<OEAtomBase *> to_do( 1 , &first_atom );
  vector<unsigned int> done_atoms( in_core );
  while( !to_do.empty() ) {
    OEAtomBase *next_at = to_do.front();
    done_atoms[DACLIB::atom_index( *next_at )] = 1;
    to_do.pop_front();
    ats_to_keep[DACLIB::atom_index( *next_at )] = 1;
    for( OEIter<OEAtomBase> conn_ats = next_at->GetAtoms() ; conn_ats ; ++conn_ats ) {
      if( !done_atoms[DACLIB::atom_index( *conn_ats )] ) {
        to_do.push_back( conn_ats );
      }
    }
  }

  for( OEIter<OEAtomBase> atom = mol_copy.GetAtoms() ; atom ; ++atom ) {
    // if the atom going is attached to a keep atom, then put something on to show this.
    // if the keep atom is the first atom, then put attach an Xe, otherwise attach
    // a Y.
    if( !ats_to_keep[DACLIB::atom_index( *atom )] ) {
      for( OEIter<OEAtomBase> conn_at = atom->GetAtoms() ; conn_at ; ++conn_at ) {
        if( ats_to_keep[DACLIB::atom_index( *conn_at )] ) {
          unsigned int tag_atom = OEElemNo::H;
          if( DACLIB::atom_index( *conn_at ) == DACLIB::atom_index( first_atom ) ) {
            tag_atom = OEElemNo::Xe;
          } else {
            tag_atom = OEElemNo::Y;
          }
          OEAtomBase *new_at = mol_copy.NewAtom( tag_atom );
          mol_copy.NewBond( new_at , conn_at , mol_copy.GetBond( atom , conn_at )->GetOrder() );
        }
      }
      mol_copy.DeleteAtom( atom );
    }
  }
  OECreateCanSmiString( rgroup_smi , mol_copy );

  return rgroup_smi;

}

// ****************************************************************************
void SmiV::update_rgroup_position_counts( const vector<set<int> > &rgroup_pos ,
                                          const vector<set<string> > &unique_rgroups ,
                                          const vector<int> &core_counts ) {

  int pos_count_col = get_data_table_column_number( "RgroupPositions" );
  if( -1 == pos_count_col ) {
    QMessageBox::warning( this , "No column" , "No column named RgroupPositions for R Group counts, so skipping." );
    return;
  }
  int uniq_count_col = get_data_table_column_number( "NumberOfUniqueRgroups" );
  if( -1 == uniq_count_col ) {
    QMessageBox::warning( this , "No column" , "No column named NumberOfUniqueRgroups for R Group counts, so skipping." );
    return;
  }
  int core_count_col = get_data_table_column_number( "CoreContainedIn" );
  if( -1 == core_count_col ) {
    QMessageBox::warning( this , "No column" , "No column named CoreContainedIn for R Group counts, so skipping." );
    return;
  }

  for( int i = 0 , is = rgroup_pos.size() ; i < is ; ++i ) {
    if( rgroup_pos[i].size() ) {
      data_table_->change_data( i , pos_count_col , QVariant( static_cast<int>( rgroup_pos[i].size() ) ) );
      data_table_->change_data( i , uniq_count_col , QVariant( static_cast<int>( unique_rgroups[i].size() ) ) );
      data_table_->change_data( i , core_count_col , QVariant( core_counts[i] ) );
    }
  }

}

// ****************************************************************************
// when molecule and subsearch are both cores, count whether mol contains sub
void SmiV::rgroup_core_count( OEChem::OEGraphMol &mol , boost::shared_ptr<OESubSearch> &sub ,
                              int &core_count ) {

  if( sub->SingleMatch( mol ) ) {
    ++core_count;
  }

}

// ****************************************************************************
// return the number of the named column, or -1 if it wasn't found
int SmiV::get_data_table_column_number( const QString &col_name ) const {

  for( int i = 0 , is = data_table_->columnCount() ; i < is ; ++i ) {
    if( col_name == data_table_->headerData( i , Qt::Horizontal ).toString() ) {
      return i;
    }
  }

  return -1;

}

ext: cc

max_stars_repo_name: OpenEye-Contrib/SmiV

max_issues_repo_name: OpenEye-Contrib/SmiV

max_forks_repo_name: OpenEye-Contrib/SmiV


text:
// Copyright 2014 The CRAVE developers. All rights reserved.//

#pragma once

#include <boost/foreach.hpp>
#include <string>
#include <vector>

#include "VariableSolver.hpp"

namespace crave {

/**
     *
     */
struct VariableGenerator {
  typedef boost::shared_ptr<VariableSolver> VarSolverPtr;

  explicit VariableGenerator(const VariableContainer& vcon);

  virtual void reset(std::vector<ConstraintPartition>& partitions);

  virtual bool solve();

  template <typename T>
  bool read(const Variable<T>& var, T* value) const {
    BOOST_FOREACH(VarSolverPtr vs, solvers_) {
      if (vs->read(var, value)) return true;
    }
    return false;
  }

  std::vector<std::vector<std::string> > analyseContradiction();

  std::vector<std::string> getInactiveSofts() const;

 protected:
  const VariableContainer& var_ctn_;
  std::vector<VarSolverPtr> solvers_;
};
}  // namespace crave

ext: hpp


text:
// The Reactive C++ Toolbox.
// Copyright (C) 2013-2019 Swirly Cloud Limited
// Copyright (C) 2020 Reactive Markets Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <cstdint>
#include <utility>

#include <boost/mp11/algorithm.hpp>

#include <toolbox/io/Reactor.hpp>
#include <toolbox/sys/Error.hpp>

#include "toolbox/io/Handle.hpp"
#include "toolbox/io/Reactor.hpp"

#include <toolbox/io/Epoll.hpp>
#include <toolbox/io/Qpoll.hpp>

#include <toolbox/io/EventFd.hpp>

#include <toolbox/io/Runner.hpp>

#include <toolbox/util/Tuple.hpp>

namespace toolbox {
inline namespace io {

/// polls multiple implementations
template<typename...ImplsT>
class BasicMultiReactor : public Reactor
{
public:
    using Self = BasicMultiReactor<ImplsT...>;
    using Base = Reactor;
    using Handle = PollHandle;
    using ImplsTuple = std::tuple<ImplsT...>;
    constexpr static std::size_t ImplsSize = sizeof...(ImplsT);
    static_assert(ImplsSize>0, "at least one implementation required");

    static constexpr unsigned CustomFDBits = 12;            // per reactor
    static constexpr unsigned CustomFDMask = (1U<<12)-1;    // per reactor
    static constexpr int HighBitFDMask = (1U<<31);           // high bit means custom fd
public:
    using Base::Base;
    using Base::timers, Base::hooks, Base::next_expiry;

    template<typename...ArgsT>
    explicit BasicMultiReactor(ArgsT...args)
    : impls_(std::forward<ArgsT>(args)...)                                        // data
    {}

    /// return poll ctl function from file descriptor
    IPoller* poller(int fd) override {
        std::size_t ix = fd & (~CustomFDMask);
        std::size_t rix = ix >> CustomFDBits;
        if((fd & HighBitFDMask)==0) {
            rix = ImplsSize-1;
        }
        IPoller* poller=nullptr;
        tuple_for_each(impls_, [&poller, &rix](auto &impl) {
            if(rix==0) {
                poller = &impl;
            }
            rix--;
        });
        return poller;
    }

    template<typename T>
    auto& get() {
        return std::get<boost::mp11::mp_find<ImplsTuple, T>::value>(impls_);
    }

    template<typename T>
    int socket() {
        constexpr std::size_t index = boost::mp11::mp_find<ImplsTuple, T>::value;
        return ((index<<CustomFDBits)|HighBitFDMask) + get<T>().socket();
    }
    /// event loop cycle
    void run() override {
        state(State::PendingOpen);
        state(State::Open);
        std::size_t i {0};
        while (!Base::stop_.load(std::memory_order_acquire)) {
            // Busy-wait for a small number of cycles after work was done.
            if (poll(CyclTime::now(), i++ < 100 ? 0s : NoTimeout) > 0) {
                // Reset counter when work has been done.
                i = 0;
            }
        }
        state(State::PendingClosed);
        state(State::Closed);
    }

    /// busy poll for events, uses inlined implementations
    int poll(CyclTime now, Duration timeout = NoTimeout)
    {
        using namespace std::chrono;

        // If timeout is zero then the wait_until time should also be zero to signify no wait.
        MonoTime wait_until{};
        if (!is_zero(timeout) && hooks().empty()) {
            const MonoTime next = next_expiry(timeout == NoTimeout ? MonoClock::max() : now.mono_time() + timeout);
            if (next > now.mono_time()) {
                wait_until = next;
            }
        }
        int rn = 0;
        std::size_t i = ImplsSize;
        tuple_for_each(impls_, [&](auto &r) {
            i--;
            int n = 0;
            std::error_code ec;
            if(i>0) {
                n = r.wait(MonoTime{}, ec); // no blocking on pollers except last one
            } else if (wait_until < MonoClock::max()) {
                // The wait function will not block if time is zero.
                n = r.wait(wait_until, ec);
            } else {
                // Block indefinitely.
                n = r.wait(ec);
            }
            if (ec) {
                if (ec.value() != EINTR) {
                    throw std::system_error{ec};
                }
            } else {
                // If the epoller call was a blocking call, then acquire the current time.
                if (!is_zero(wait_until)) {
                    now = CyclTime::now();
                }
                rn += timers(Priority::High).dispatch(now) + r.dispatch(now);
                // Low priority timers are only dispatched during empty cycles.
                if (i==0 && n == 0) {
                    rn += timers(Priority::Low).dispatch(now);
                }
            }
        });
        io::dispatch(now, hooks());
        return rn;
    }

    /// wakeup, could be called from another thread
    void wakeup() noexcept override {
        if(state()==State::Open) {
            // wakeup last reactor since others are always busy-polled
            std::get<ImplsSize-1>(impls_).wakeup();
        }
    }
protected:
    std::tuple<ImplsT...> impls_;
};
} // namespace io
} // namespace toolbox

namespace toolbox {
    namespace os {
        /// default linux reactor
        using Reactor = BasicMultiReactor<Epoll>;
        using ReactorRunner = BasicRunner<Reactor>;
    }
}

max_stars_repo_name: mmitkevich/toolbox-cpp

max_issues_repo_name: mmitkevich/toolbox-cpp

max_forks_repo_name: mmitkevich/toolbox-cpp


text:
/*
 * oper_matrix.cpp
 *
 *  Created on: 2017. 6. 6.
 *      Author: cho
 */

#include <random>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/lu.hpp>
#include <boost/numeric/ublas/triangular.hpp>
#include <boost/numeric/ublas/io.hpp>
//#include "io.hpp"

using namespace std;
namespace ublas = boost::numeric::ublas;

/// number of data
const unsigned int N = 5;

int main() {
	cout << "==== START " << endl;
	random_device rd;     // seed, rd()
	mt19937_64 gen(4);    // random number generator

	ublas::vector<double> t (N); // time vector, sec
	for (unsigned i = 0; i < t.size(); ++i) t(i) = i+1;
	cout << "t("<<N<<") = " << t << endl;

	uniform_int_distribution<int> dis_y( 0, 10 );
	ublas::vector<double> y (N); // measured value
	for (unsigned i = 0; i < y.size(); ++i) y(i) = dis_y(gen);
	cout << "y("<<N<<") = " << y << endl;

	//const double m_init[N][N] = { {1, 2}, {3, 4} };
	ublas::matrix<double> m( N, N );
	for (unsigned i = 0; i < m.size1 (); ++ i)
		for (unsigned j = 0; j < m.size2 (); ++ j)
			m (i, j) = i*2 + j + 1;
			//m(i,j) = m_init[i][j];
	m(N-1,N-1) = 3;
	cout << "matrix = " << m << endl;

	cout << "\n==== standard operation : +, -, *(scalar), /(scalar) " << endl;
	{
		cout << "t+y = " << t+y << endl;
		cout << "t-y = " << t-y << endl;
		cout << "2*t = " << 2*t << endl;
		cout << "t*3 = " << t*3 << endl;
		cout << "t/2 = " << t/3 << endl;
		cout << "-t  = " << -t << endl;
	}

	cout << "\n==== inner, outer and other products " << endl;
	{
		cout << "inner_prod(t, y) = " << inner_prod( t, y ) << endl;
		cout << "inner_prod(y, t) = " << inner_prod( y, t ) << endl;
		cout << "outer_prod(t, y) = " << outer_prod( t, y ) << endl;
		cout << "outer_prod(y, t) = " << outer_prod( y, t ) << endl;
		cout << "element_prod(t, y) = " << element_prod(t, y) << endl;
		cout << "element_prod(y, t) = " << element_prod(y, t) << endl;
		cout << "element_div(t, y)  = " << element_div(t, y) << endl;
		cout << "element_div(y, t)  = " << element_div(y, t) << endl;
		cout << "prod(m, t)  = " << prod(m, t) << endl;
		cout << "prod(t, m)  = " << prod(t, m) << endl;
		cout << "prec_prod(t, m)  = " << prec_prod(t, m) << endl;
		cout << "prec_prod(m, t)  = " << prec_prod(m, t) << endl;
	}

	cout << "\n==== transformations " << endl;
	{
		cout << "trans(m) = " << ublas::trans(m) << endl;
	}

	cout << "\n==== triangular matrix " << endl;
	{
		auto L  = ublas::triangular_adaptor<ublas::matrix<double>, ublas::lower> (m);
		auto SL = ublas::triangular_adaptor<ublas::matrix<double>, ublas::strict_lower> (m);
		auto UL = ublas::triangular_adaptor<ublas::matrix<double>, ublas::unit_lower> (m);
		cout << "lower        L  = " << L << endl;
		cout << "strict lower SL = " << SL << endl;
		cout << "unit lower   UL = " << UL << endl;

		auto U =  ublas::triangular_adaptor<ublas::matrix<double>, ublas::upper> (m);
		auto SU = ublas::triangular_adaptor<ublas::matrix<double>, ublas::strict_upper> (m);
		auto UU = ublas::triangular_adaptor<ublas::matrix<double>, ublas::unit_upper> (m);
		cout << "upper        U  = " << U << endl;
		cout << "strict upper SU = " << SU << endl;
		cout << "unit upper   UU = " << UU << endl;

		cout << "prod( U, m ) = " << prod(U, m) << endl;

		ublas::vector<double> x(m.size1());
		ublas::vector<double> b(m.size1(), 1);
		cout << "inplace_solve(UL, b, ) : b = " << b << endl;
		inplace_solve( UL, b, ublas::unit_lower_tag() );
		cout << "inplace_solve(UL, b, ) : b = " << b << endl;
		cout << "prod( UL, b ) = " << prod( UL, b ) << endl;
	}

	cout << "\n==== pumutation matrix " << endl;
	{
		ublas::permutation_matrix<size_t> pm(N);
		pm(0) = 1;
		cout << "-- pm = " << pm << endl;
		ublas::swap_rows( pm, m);
		cout << "-- swap_rows( pm, m) = " << m << endl;
		pm(0) = 0; pm(1) = 0;
		cout << "-- pm = " << pm << endl;
		ublas::swap_rows( pm, m);
		cout << "-- swap_rows( pm, m) = " << m << endl;
		pm(0) = 0; pm(1) = 1; pm(2) = 0;
		cout << "-- pm = " << pm << endl;
		ublas::swap_rows( pm, m);
		cout << "-- swap_rows( pm, m) = " << m << endl;
	}

	cout << "\n==== LU factorization" << endl;
	{
		ublas::matrix<double> A(m);
		ublas::permutation_matrix<double> pm(N);
		cout << "-- pm = " << pm << endl;
		bool singular = ublas::lu_factorize( A, pm);
		cout << "-- return = " << singular << endl;
		cout << "-- A  = " << A << endl;
		cout << "-- pm = " << pm << endl;

		auto L = ublas::triangular_adaptor<ublas::matrix<double>, ublas::unit_lower>(A);
		cout << "-- L = " << L << endl;
		auto U = ublas::triangular_adaptor<ublas::matrix<double>, ublas::upper>(A);
		cout << "-- U = " << U << endl;
		cout << "-- LU = " << prod(L,U) << endl;
		ublas::matrix<double> pmA( m ); // pmA means pm*A, at first init as m
		swap_rows(pm, pmA);
		cout << "-- swap_rows(pm,A) = " << pmA << endl;

		cout << "-- solve Lz = b -------------" << endl;
		ublas::vector<double> b( N ); b(0) = 1; b(1) = 2; b(2) = 3;
		ublas::vector<double> z( b );
		cout << "-- L " << L << endl;
		cout << "-- b " << b << endl;
		ublas::inplace_solve( A, z, ublas::unit_lower_tag() );
		cout << "-- z = " << z << endl;
		cout << "-- confirm Lz = " << prod( L, z ) << endl;

		cout << "-- solve Ux = z -------------" << endl;
		ublas::vector<double> x( z );
		cout << "-- U " << U << endl;
		cout << "-- z " << z << endl;
		inplace_solve( A, x, ublas::upper_tag() );
		cout << "-- x = " << x << endl;
		cout << "-- confirm Ux = " << prod( U, x ) << endl;
	}

	cout << "==== END " << endl;
}

ext: cpp


text:
// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef VSOMEIP_EVENTGROUPINFO_HPP
#define VSOMEIP_EVENTGROUPINFO_HPP

#include <chrono>
#include <list>
#include <memory>
#include <set>
#include <mutex>
#include <atomic>

#include <boost/asio/ip/address.hpp>

#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>

#include "types.hpp"

namespace vsomeip {

class endpoint_definition;
class event;

class eventgroupinfo {
public:
    struct target_t {
        std::shared_ptr<endpoint_definition> endpoint_;
        std::chrono::steady_clock::time_point expiration_;

        bool operator==(const target_t &_other) const {
            return (endpoint_ == _other.endpoint_);
        }
    };

    VSOMEIP_EXPORT eventgroupinfo();
    VSOMEIP_EXPORT eventgroupinfo(major_version_t _major, ttl_t _ttl);
    VSOMEIP_EXPORT ~eventgroupinfo();

    VSOMEIP_EXPORT major_version_t get_major() const;
    VSOMEIP_EXPORT void set_major(major_version_t _major);

    VSOMEIP_EXPORT ttl_t get_ttl() const;
    VSOMEIP_EXPORT void set_ttl(ttl_t _ttl);

    VSOMEIP_EXPORT bool is_multicast() const;
    VSOMEIP_EXPORT bool get_multicast(boost::asio::ip::address &_address,
            uint16_t &_port) const;
    VSOMEIP_EXPORT void set_multicast(const boost::asio::ip::address &_address,
            uint16_t _port);
    VSOMEIP_EXPORT bool is_sending_multicast() const;

    VSOMEIP_EXPORT const std::set<std::shared_ptr<event> > get_events() const;
    VSOMEIP_EXPORT void add_event(std::shared_ptr<event> _event);
    VSOMEIP_EXPORT void remove_event(std::shared_ptr<event> _event);
    VSOMEIP_EXPORT void get_reliability(bool& _has_reliable, bool& _has_unreliable) const;

    VSOMEIP_EXPORT const std::list<target_t> get_targets() const;
    VSOMEIP_EXPORT uint32_t get_unreliable_target_count() const;

    VSOMEIP_EXPORT bool add_target(const target_t &_target);
    VSOMEIP_EXPORT bool add_target(const target_t &_target, const target_t &_subscriber);
    VSOMEIP_EXPORT bool update_target(
            const std::shared_ptr<endpoint_definition> &_target,
            const std::chrono::steady_clock::time_point &_expiration);
    VSOMEIP_EXPORT bool remove_target(
            const std::shared_ptr<endpoint_definition> &_target);
    VSOMEIP_EXPORT void clear_targets();

    VSOMEIP_EXPORT void add_multicast_target(const target_t &_multicast_target);
    VSOMEIP_EXPORT void clear_multicast_targets();
    VSOMEIP_EXPORT const std::list<target_t> get_multicast_targets() const;

    VSOMEIP_EXPORT uint8_t get_threshold() const;
    VSOMEIP_EXPORT void set_threshold(uint8_t _threshold);

    VSOMEIP_EXPORT std::unique_lock<std::mutex> get_subscription_lock();

    VSOMEIP_EXPORT pending_subscription_id_t add_pending_subscription(
            pending_subscription_t _pending_subscription);

    VSOMEIP_EXPORT std::vector<pending_subscription_t> remove_pending_subscription(
            pending_subscription_id_t _subscription_id);

    VSOMEIP_EXPORT void clear_pending_subscriptions();
private:
    std::atomic<major_version_t> major_;
    std::atomic<ttl_t> ttl_;

    mutable std::mutex address_mutex_;
    boost::asio::ip::address address_;
    uint16_t port_;

    mutable std::mutex events_mutex_;
    std::set<std::shared_ptr<event> > events_;
    mutable std::mutex targets_mutex_;
    std::list<target_t> targets_;
    mutable std::mutex multicast_targets_mutex_;
    std::list<target_t> multicast_targets_;

    std::atomic<uint8_t> threshold_;
    std::mutex subscription_mutex_;

    std::atomic<bool> has_reliable_;
    std::atomic<bool> has_unreliable_;

    std::mutex pending_subscriptions_mutex_;
    std::map<pending_subscription_id_t, pending_subscription_t> pending_subscriptions_;
    std::map<std::tuple<boost::asio::ip::address, std::uint16_t, bool>,
            std::vector<pending_subscription_id_t>> pending_subscriptions_by_remote_;
    pending_subscription_id_t subscription_id_;
};

} // namespace vsomeip

#endif // VSOMEIP_EVENTGROUPINFO_HPP

max_stars_repo_name: MicrochipTech/some-ip

max_issues_repo_name: MicrochipTech/some-ip

max_forks_repo_name: MicrochipTech/some-ip


text:
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2004 Ferdinando Ametrano
 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/license.shtml>.

 This program 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 license for more details.
*/

/*! \file actual365fixed.hpp
    \brief Actual/365 (Fixed) day counter
*/

#ifndef quantlib_actual365fixed_day_counter_h
#define quantlib_actual365fixed_day_counter_h

#include <ql/time/daycounter.hpp>

namespace QuantLib {

    //! Actual/365 (Fixed) day count convention
    /*! "Actual/365 (Fixed)" day count convention, also know as
        "Act/365 (Fixed)", "A/365 (Fixed)", or "A/365F".

        \warning According to ISDA, "Actual/365" (without "Fixed") is
                 an alias for "Actual/Actual (ISDA)" (see
                 ActualActual.)  If Actual/365 is not explicitly
                 specified as fixed in an instrument specification,
                 you might want to double-check its meaning.

        \ingroup daycounters
    */
    class Actual365Fixed : public DayCounter {
      public:
        enum Convention { Standard, Canadian, NoLeap };
        explicit Actual365Fixed(Convention c = Actual365Fixed::Standard)
        : DayCounter(implementation(c)) {}

      private:
        class Impl : public DayCounter::Impl {
          public:
            std::string name() const { return std::string("Actual/365 (Fixed)"); }
            Time yearFraction(const Date& d1,
                              const Date& d2,
                              const Date&,
                              const Date&) const {
                return daysBetween(d1,d2)/365.0;
            }
        };
        class CA_Impl : public DayCounter::Impl {
          public:
            std::string name() const {
                return std::string("Actual/365 (Fixed) Canadian Bond");
            }
            Time yearFraction(const Date& d1,
                              const Date& d2,
                              const Date& refPeriodStart,
                              const Date& refPeriodEnd) const;
        };
        class NL_Impl : public DayCounter::Impl {
          public:
            std::string name() const {
                return std::string("Actual/365 (No Leap)");
            }
            Date::serial_type dayCount(const Date& d1,
                                       const Date& d2) const;
            Time yearFraction(const Date& d1,
                              const Date& d2,
                              const Date& refPeriodStart,
                              const Date& refPeriodEnd) const;
        };
        static boost::shared_ptr<DayCounter::Impl> implementation(Convention);
    };

}

/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/license.shtml>.

 This program 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 license for more details.
*/

#include <boost/make_shared.hpp>

namespace QuantLib {

    inline boost::shared_ptr<DayCounter::Impl>
    Actual365Fixed::implementation(Actual365Fixed::Convention c) {
        switch (c) {
          case Standard:
            return boost::shared_ptr<DayCounter::Impl>(new Impl);
          case Canadian:
            return boost::shared_ptr<DayCounter::Impl>(new CA_Impl);
          case NoLeap:
            return boost::shared_ptr<DayCounter::Impl>(new NL_Impl);
          default:
            QL_FAIL("unknown Actual/365 (Fixed) convention");
        }
    }

    inline Time Actual365Fixed::CA_Impl::yearFraction(const Date& d1,
                                               const Date& d2,
                                               const Date& refPeriodStart,
                                               const Date& refPeriodEnd) const {
        // Need the period to calculate frequency
        QL_REQUIRE(refPeriodStart != Date(),"invalid refPeriodStart");
        QL_REQUIRE(refPeriodEnd != Date(),"invalid refPeriodEnd");

        Time dcs = daysBetween(d1,d2);
        Time dcc = daysBetween(refPeriodStart,refPeriodEnd);
        Integer months = Integer(0.5+12*dcc/365);
        Integer frequency = Integer( 12/months);

        if ( dcs < 365/frequency)
            return dcs/365.0;

        return 1./frequency - (dcc-dcs)/365.0;

    }

    inline Date::serial_type Actual365Fixed::NL_Impl::dayCount(const Date& d1,
                                                        const Date& d2) const {

        static const Integer MonthOffset[] = {
            0,  31,  59,  90, 120, 151,  // Jan - Jun
            181, 212, 243, 273, 304, 334   // Jun - Dec
        };

        Date::serial_type s1 = d1.dayOfMonth()
                             + MonthOffset[d1.month()-1] + (d1.year() * 365);
        Date::serial_type s2 = d2.dayOfMonth()
                             + MonthOffset[d2.month()-1] + (d2.year() * 365);

        if (d1.month() == Feb && d1.dayOfMonth() == 29) {
            --s1;
        }

        if (d2.month() == Feb && d2.dayOfMonth() == 29) {
            --s2;
        }

        return s2 - s1;
    }

    inline Time Actual365Fixed::NL_Impl::yearFraction(const Date& d1,
                                               const Date& d2,
                                               const Date& d3,
                                               const Date& d4) const {
        return dayCount(d1, d2)/365.0;
    }

}

#endif

max_stars_repo_name: markxio/Quantuccia

max_issues_repo_name: markxio/Quantuccia

max_forks_repo_name: markxio/Quantuccia


text:
/**
 * Copyright (c) 2016-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

#include "AliasedRegisters.h"

#include <algorithm>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/optional.hpp>
#include <boost/range/iterator_range.hpp>
#include <limits>
#include <unordered_set>

// Implemented by an undirected graph where nodes are Registers and edges are an
// alias between them.

void AliasedRegisters::make_aliased(const RegisterValue& r1, const RegisterValue& r2) {
  if (r1 != r2) {
    vertex_t v1 = find_or_create(r1);
    vertex_t v2 = find_or_create(r2);
    boost::add_edge(v1, v2, m_graph);
    invalidate_cache();
  }
}

void AliasedRegisters::break_alias(const RegisterValue& r) {
  const auto& v = find(r);
  const auto& end = boost::vertices(m_graph).second;
  if (v != end) {
    // clear removes all edges incident to r
    boost::clear_vertex(*v, m_graph);
    invalidate_cache();
  }
}

bool AliasedRegisters::are_aliases(const RegisterValue& r1, const RegisterValue& r2) {
  if (r1 == r2) {
    return true;
  }

  const auto& v1 = find(r1);
  const auto& v2 = find(r2);
  const auto& end = boost::vertices(m_graph).second;
  if (v1 == end || v2 == end) {
    // if either register is not in the graph, then
    // they cannot be aliases
    return false;
  }

  return path_exists(*v1, *v2);
}

template <typename T>
bool contains(const std::unordered_set<T>& set, const T& val) {
  return set.count(val) > 0;
}

/**
 * Return a representative for this register.
 *
 * Return the lowest numbered register that this value is an alias with.
 */
boost::optional<Register> AliasedRegisters::get_representative(
    const RegisterValue& r) {

  // if r is not in the graph, then it has no representative
  const auto& v = find(r);
  const auto& end = boost::vertices(m_graph).second;
  if (v == end) {
    return boost::none;
  }

  // compute connected components
  // (or use cached value when graph hasn't changed)
  auto num_vertices = boost::num_vertices(m_graph);
  if (m_conn_components.empty()) {
    m_conn_components.resize(num_vertices);
    boost::connected_components(m_graph, m_conn_components.data());
  }
  int component_of_v = m_conn_components.at(*v);

  // find the lowest numbered register in the same component as `v`
  Register result = std::numeric_limits<Register>::max();
  for (vertex_t candidate = 0; candidate < num_vertices; ++candidate) {
    const RegisterValue& val = m_graph[candidate];
    if (component_of_v == m_conn_components.at(candidate) &&
        val.kind == RegisterValue::Kind::REGISTER) {
      result = std::min<Register>(result, val.reg);
    }
  }
  if (result == std::numeric_limits<Register>::max()) {
    return boost::none;
  }
  return result;
}

const boost::range_detail::integer_iterator<AliasedRegisters::vertex_t>
AliasedRegisters::find(const RegisterValue& r) const {
  const auto& iters = boost::vertices(m_graph);
  const auto& begin = iters.first;
  const auto& end = iters.second;
  for (auto it = begin; it != end; ++it) {
    if (m_graph[*it] == r) {
      return it;
    }
  }
  return end;
}

// returns the vertex holding `r` or creates a new (unconnected)
// vertex if `r` is not in m_graph
AliasedRegisters::vertex_t AliasedRegisters::find_or_create(const RegisterValue& r) {
  const auto& it = find(r);
  const auto& end = boost::vertices(m_graph).second;
  if (it != end) {
    return *it;
  } else {
    invalidate_cache();
    return boost::add_vertex(r, m_graph);
  }
}

// return true if there exists a path from `start` to `end`
//
// Implemented with recursive DFS, stopping as soon as `end` is found
// (or traversing the entire graph then returning false)
bool AliasedRegisters::path_exists(AliasedRegisters::vertex_t start,
                                   AliasedRegisters::vertex_t end) const {
  std::unordered_set<AliasedRegisters::vertex_t> visited;
  const auto& graph = m_graph;
  std::function<bool(vertex_t)> recurse =
      [&recurse, &graph, &visited, end](AliasedRegisters::vertex_t v) {
        if (v == end) {
          return true;
        }
        visited.insert(v);
        const auto& adj_vertices = boost::adjacent_vertices(v, graph);
        for (auto it = adj_vertices.first; it != adj_vertices.second; ++it) {
          if (!contains(visited, *it) && recurse(*it)) {
            return true;
          }
        }
        return false;
      };
  return recurse(start);
}

bool AliasedRegisters::has_edge_between(const RegisterValue& r1,
                                        const RegisterValue& r2) const {
  // make sure we have both vertices
  const auto& search1 = find(r1);
  const auto& search2 = find(r2);
  const auto& end = boost::vertices(m_graph).second;
  if (search1 == end || search2 == end) {
    return false;
  }

  // and check that they have an edge between them
  const auto& adj = boost::adjacent_vertices(*search1, m_graph);
  const auto& adj_begin = adj.first;
  const auto& adj_end = adj.second;
  const auto& edge_search = std::find(adj_begin, adj_end, *search2);
  if (edge_search == adj_end) {
    return false;
  }
  return true;
}

// call this when m_graph changes
void AliasedRegisters::invalidate_cache() { m_conn_components.clear(); }

// ---- extends AbstractValue ----

void AliasedRegisters::clear() {
  m_graph.clear();
  invalidate_cache();
}

AliasedRegisters::Kind AliasedRegisters::kind() const {
  return (boost::num_edges(m_graph) > 0) ? AliasedRegisters::Kind::Value
                                         : AliasedRegisters::Kind::Top;
}

/**
 * The lattice looks like this:
 *
 *             T (graphs with no edges)
 *      graphs with 1 edge                  ^  join moves up (edge intersection)
 *      graphs with 2 edges                 |
 *            ...                           v  meet moves down (edge union)
 *      graphs with n edges
 *            ...
 *            _|_
 *
 * So, leq is the superset relation on the edge set
 */
bool AliasedRegisters::leq(const AliasedRegisters& other) const {
  if (boost::num_edges(m_graph) < boost::num_edges(other.m_graph)) {
    // this cannot be a superset of other if this has fewer edges
    return false;
  }

  // for all edges in other (the potential subset), make sure this contains that
  // edge.
  const auto& iters = boost::edges(other.m_graph);
  const auto& begin = iters.first;
  const auto& end = iters.second;
  for (auto it = begin; it != end; ++it) {
    const RegisterValue& r1 = other.m_graph[boost::source(*it, other.m_graph)];
    const RegisterValue& r2 = other.m_graph[boost::target(*it, other.m_graph)];
    if (!has_edge_between(r1, r2)) {
      return false;
    }
  }
  return true;
}

/*
 * returns true iff they have exactly the same edges between the same
 * RegisterValues
 */
bool AliasedRegisters::equals(const AliasedRegisters& other) const {
  return boost::num_edges(m_graph) == boost::num_edges(other.m_graph) &&
         leq(other);
}

// edge union
AliasedRegisters::Kind AliasedRegisters::meet_with(
    const AliasedRegisters& other) {
  const auto& iters = boost::edges(other.m_graph);
  const auto& begin = iters.first;
  const auto& end = iters.second;
  for (auto it = begin; it != end; ++it) {
    const RegisterValue& r1 = other.m_graph[boost::source(*it, other.m_graph)];
    const RegisterValue& r2 = other.m_graph[boost::target(*it, other.m_graph)];
    this->make_aliased(r1, r2);
  }
  this->invalidate_cache();
  return AliasedRegisters::Kind::Value;
}

AliasedRegisters::Kind AliasedRegisters::narrow_with(
    const AliasedRegisters& other) {
  return join_with(other);
}

// edge intersection
AliasedRegisters::Kind AliasedRegisters::join_with(
    const AliasedRegisters& other) {

  // fill `deletes` with edges that aren't in `other`
  std::vector<std::pair<vertex_t, vertex_t>> deletes;
  const auto& iters = boost::edges(this->m_graph);
  const auto& begin = iters.first;
  const auto& end = iters.second;
  for (auto it = begin; it != end; ++it) {
    vertex_t v1 = boost::source(*it, this->m_graph);
    vertex_t v2 = boost::target(*it, this->m_graph);
    const RegisterValue& r1 = this->m_graph[v1];
    const RegisterValue& r2 = this->m_graph[v2];
    if (!other.has_edge_between(r1, r2)) {
      deletes.emplace_back(v1, v2);
    }
  }

  for (const auto& edge : deletes) {
    boost::remove_edge(edge.first, edge.second, this->m_graph);
  }

  this->invalidate_cache();
  return AliasedRegisters::Kind::Value;
}

AliasedRegisters::Kind AliasedRegisters::widen_with(
    const AliasedRegisters& other) {
  return meet_with(other);
}

max_stars_repo_name: thezhangwei/redex

max_issues_repo_name: thezhangwei/redex

max_forks_repo_name: thezhangwei/redex


text:
// Copyright (c) 2020 The DRiyal Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/test/unit_test.hpp>
#include <consensus/validation.h>
#include <primitives/block.h>
#include <scheduler.h>
#include <test/util/setup_common.h>
#include <util/check.h>
#include <validationinterface.h>

BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, TestingSetup)

struct TestSubscriberNoop final : public CValidationInterface {
    void BlockChecked(const CBlock&, const BlockValidationState&) override {}
};

BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
{
    std::atomic<bool> generate{true};

    // Start thread to generate notifications
    std::thread gen{[&] {
        const CBlock block_dummy;
        BlockValidationState state_dummy;
        while (generate) {
            GetMainSignals().BlockChecked(block_dummy, state_dummy);
        }
    }};

    // Start thread to consume notifications
    std::thread sub{[&] {
        // keep going for about 1 sec, which is 250k iterations
        for (int i = 0; i < 250000; i++) {
            auto sub = std::make_shared<TestSubscriberNoop>();
            RegisterSharedValidationInterface(sub);
            UnregisterSharedValidationInterface(sub);
        }
        // tell the other thread we are done
        generate = false;
    }};

    gen.join();
    sub.join();
    BOOST_CHECK(!generate);
}

class TestInterface : public CValidationInterface
{
public:
    TestInterface(std::function<void()> on_call = nullptr, std::function<void()> on_destroy = nullptr)
        : m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy))
    {
    }
    virtual ~TestInterface()
    {
        if (m_on_destroy) m_on_destroy();
    }
    void BlockChecked(const CBlock& block, const BlockValidationState& state) override
    {
        if (m_on_call) m_on_call();
    }
    static void Call()
    {
        CBlock block;
        BlockValidationState state;
        GetMainSignals().BlockChecked(block, state);
    }
    std::function<void()> m_on_call;
    std::function<void()> m_on_destroy;
};

// Regression test to ensure UnregisterAllValidationInterfaces calls don't
// destroy a validation interface while it is being called. Bug:
// https://github.com/driyal/driyal/pull/18551
BOOST_AUTO_TEST_CASE(unregister_all_during_call)
{
    bool destroyed = false;
    RegisterSharedValidationInterface(std::make_shared<TestInterface>(
        [&] {
            // First call should decrements reference count 2 -> 1
            UnregisterAllValidationInterfaces();
            BOOST_CHECK(!destroyed);
            // Second call should not decrement reference count 1 -> 0
            UnregisterAllValidationInterfaces();
            BOOST_CHECK(!destroyed);
        },
        [&] { destroyed = true; }));
    TestInterface::Call();
    BOOST_CHECK(destroyed);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: driyal/driyal

max_issues_repo_name: driyal/driyal

max_forks_repo_name: driyal/driyal