<commit_before>#include <qdir.h>
#include <qprinter.h>
#include <qpainter.h>

#include <kiconloader.h>
#include <kmessagebox.h>
#include <kfiledialog.h>
#include <kmenubar.h>
#include <klocale.h>
#include <kconfig.h>
#include <kstdaction.h>

#include "ksync.h"
#include "ksync.moc"
#include "ksyncview.h"
#include <kstatusbar.h>

#define ID_STATUS_MSG 1

KSync::KSync(QWidget* , const char* name):KMainWindow(0, name)
{
  config=kapp->config();

  initStatusBar();
  initActions();
  initView();

  readOptions();

  // disable actions at startup
  fileSave->setEnabled(false);
  fileSaveAs->setEnabled(false);
  filePrint->setEnabled(false);
  editCut->setEnabled(false);
  editCopy->setEnabled(false);
  editPaste->setEnabled(false);
}

KSync::~KSync()
{

}

void KSync::initActions()
{
  fileNewWindow = new KAction(i18n("New &Window"), 0, 0, this, SLOT(slotFileNewWindow()), actionCollection(),"file_new_window");
  fileNew = KStdAction::openNew(this, SLOT(slotFileNew()), actionCollection());
  fileOpen = KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
  fileOpenRecent = KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection());
  fileSave = KStdAction::save(this, SLOT(slotFileSave()), actionCollection());
  fileSaveAs = KStdAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection());
  fileClose = KStdAction::close(this, SLOT(slotFileClose()), actionCollection());
  filePrint = KStdAction::print(this, SLOT(slotFilePrint()), actionCollection());
  fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
  editCut = KStdAction::cut(this, SLOT(slotEditCut()), actionCollection());
  editCopy = KStdAction::copy(this, SLOT(slotEditCopy()), actionCollection());
  editPaste = KStdAction::paste(this, SLOT(slotEditPaste()), actionCollection());
  viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()), actionCollection());
  viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()), actionCollection());

  fileNewWindow->setStatusText(i18n("Opens a new application window"));
  fileNew->setStatusText(i18n("Creates a new document"));
  fileOpen->setStatusText(i18n("Opens an existing document"));
  fileOpenRecent->setStatusText(i18n("Opens a recently used file"));
  fileSave->setStatusText(i18n("Saves the actual document"));
  fileSaveAs->setStatusText(i18n("Saves the actual document as..."));
  fileClose->setStatusText(i18n("Closes the actual document"));
  filePrint ->setStatusText(i18n("Prints out the actual document"));
  fileQuit->setStatusText(i18n("Quits the application"));
  editCut->setStatusText(i18n("Cuts the selected section and puts it to the clipboard"));
  editCopy->setStatusText(i18n("Copies the selected section to the clipboard"));
  editPaste->setStatusText(i18n("Pastes the clipboard contents to actual position"));
  viewToolBar->setStatusText(i18n("Enables/disables the toolbar"));
  viewStatusBar->setStatusText(i18n("Enables/disables the statusbar"));

  // use the absolute path to your ksyncui.rc file for testing purpose in createGUI();
  createGUI();

}

void KSync::initStatusBar()
{
  statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG);
}

void KSync::initView()
{
  mView = new KSyncView(this);
  setCentralWidget(mView);
//  setCaption(doc->URL().fileName(),false);
}

void KSync::openDocumentFile(const KURL& url)
{
  slotStatusMsg(i18n("Opening file..."));

//  doc->openDocument( url);
  fileOpenRecent->addURL( url );
  slotStatusMsg(i18n("Ready."));
}

void KSync::saveOptions()
{
  config->setGroup("General Options");
  config->writeEntry("Geometry", size());
  config->writeEntry("Show Toolbar", viewToolBar->isChecked());
  config->writeEntry("Show Statusbar",viewStatusBar->isChecked());
  config->writeEntry("ToolBarPos", (int) toolBar("mainToolBar")->barPos());
  fileOpenRecent->saveEntries(config,"Recent Files");

  mView->writeConfig(config);
}

void KSync::readOptions()
{
  config->setGroup("General Options");

  // bar status settings
  bool bViewToolbar = config->readBoolEntry("Show Toolbar", true);
  viewToolBar->setChecked(bViewToolbar);
  slotViewToolBar();

  bool bViewStatusbar = config->readBoolEntry("Show Statusbar", true);
  viewStatusBar->setChecked(bViewStatusbar);
  slotViewStatusBar();

  // bar position settings
  KToolBar::BarPosition toolBarPos;
  toolBarPos=(KToolBar::BarPosition) config->readNumEntry("ToolBarPos", KToolBar::Top);
  toolBar("mainToolBar")->setBarPos(toolBarPos);

  // initialize the recent file list
  fileOpenRecent->loadEntries(config,"Recent Files");

  QSize size=config->readSizeEntry("Geometry");
  if(!size.isEmpty())
  {
    resize(size);
  }

  mView->readConfig(config);
}

void KSync::saveProperties(KConfig *)
{
#if 0
  if(doc->URL().fileName()!=i18n("Untitled") && !doc->isModified())
  {
    // saving to tempfile not necessary

  }
  else
  {
    KURL url=doc->URL();
    _cfg->writeEntry("filename", url.url());
    _cfg->writeEntry("modified", doc->isModified());
    QString tempname = kapp->tempSaveName(url.url());
    QString tempurl= KURL::encode_string(tempname);
    KURL _url(tempurl);
    doc->saveDocument(_url);
  }
#endif
}

void KSync::readProperties(KConfig *)
{
#if 0
  QString filename = _cfg->readEntry("filename", "");
  KURL url(filename);
  bool modified = _cfg->readBoolEntry("modified", false);
  if(modified)
  {
    bool canRecover;
    QString tempname = kapp->checkRecoverFile(filename, canRecover);
    KURL _url(tempname);

    if(canRecover)
    {
      doc->openDocument(_url);
      doc->setModified();
      setCaption(_url.fileName(),true);
      QFile::remove(tempname);
    }
  }
  else
  {
    if(!filename.isEmpty())
    {
      doc->openDocument(url);
      setCaption(url.fileName(),false);
    }
  }
#endif
}

bool KSync::queryClose()
{
//  return doc->saveModified();
  return true;
}

bool KSync::queryExit()
{
  saveOptions();
  return true;
}

void KSync::slotFileNewWindow()
{
  slotStatusMsg(i18n("Opening a new application window..."));

  KSync *new_window= new KSync();
  new_window->show();

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileNew()
{
  slotStatusMsg(i18n("Creating new document..."));

#if 0
  if(!doc->saveModified())
  {
     // here saving wasn't successful

  }
  else
  {
    doc->newDocument();
    setCaption(doc->URL().fileName(), false);
  }
#endif

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileOpen()
{
  slotStatusMsg(i18n("Opening file..."));

#if 0
  if(!doc->saveModified())
  {
     // here saving wasn't successful

  }
  else
  {
    KURL url=KFileDialog::getOpenURL(QString::null,
        i18n("*|All files"), this, i18n("Open File..."));
    if(!url.isEmpty())
    {
      doc->openDocument(url);
      setCaption(url.fileName(), false);
      fileOpenRecent->addURL( url );
    }
  }
#endif

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileOpenRecent(const KURL&)
{
  slotStatusMsg(i18n("Opening file..."));

#if 0
  if(!doc->saveModified())
  {
     // here saving wasn't successful
  }
  else
  {
    doc->openDocument(url);
    setCaption(url.fileName(), false);
  }
#endif

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileSave()
{
  slotStatusMsg(i18n("Saving file..."));

//  doc->saveDocument(doc->URL());

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileSaveAs()
{
  slotStatusMsg(i18n("Saving file with a new filename..."));

  KURL url=KFileDialog::getSaveURL(QDir::currentDirPath(),
        i18n("*|All files"), this, i18n("Save As..."));
  if(!url.isEmpty())
  {
//    doc->saveDocument(url);
    fileOpenRecent->addURL(url);
//    setCaption(url.fileName(),doc->isModified());
  }

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileClose()
{
  slotStatusMsg(i18n("Closing file..."));

  close();

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFilePrint()
{
  slotStatusMsg(i18n("Printing..."));

  QPrinter printer;
  if (printer.setup(this))
  {
    mView->print(&printer);
  }

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileQuit()
{
  slotStatusMsg(i18n("Exiting..."));
  saveOptions();
  // close the first window, the list makes the next one the first again.
  // This ensures that queryClose() is called on each window to ask for closing
  KMainWindow* w;
  if(memberList)
  {
    for(w=memberList->first(); w!=0; w=memberList->first())
    {
      // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog,
      // the window and the application stay open.
      if(!w->close())
	break;
    }
  }
  slotStatusMsg(i18n("Ready."));
}

void KSync::slotEditCut()
{
  slotStatusMsg(i18n("Cutting selection..."));

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotEditCopy()
{
  slotStatusMsg(i18n("Copying selection to clipboard..."));

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotEditPaste()
{
  slotStatusMsg(i18n("Inserting clipboard contents..."));

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotViewToolBar()
{
  slotStatusMsg(i18n("Toggling toolbar..."));

  if(!viewToolBar->isChecked())
  {
    toolBar("mainToolBar")->hide();
  }
  else
  {
    toolBar("mainToolBar")->show();
  }

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotViewStatusBar()
{
  slotStatusMsg(i18n("Toggle the statusbar..."));

  if(!viewStatusBar->isChecked())
  {
    statusBar()->hide();
  }
  else
  {
    statusBar()->show();
  }

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotStatusMsg(const QString &text)
{
  statusBar()->clear();
  statusBar()->changeItem(text, ID_STATUS_MSG);
}

<commit_msg>CVS_SILENT Style guide fix<commit_after>#include <qdir.h>
#include <qprinter.h>
#include <qpainter.h>

#include <kiconloader.h>
#include <kmessagebox.h>
#include <kfiledialog.h>
#include <kmenubar.h>
#include <klocale.h>
#include <kconfig.h>
#include <kstdaction.h>

#include "ksync.h"
#include "ksync.moc"
#include "ksyncview.h"
#include <kstatusbar.h>

#define ID_STATUS_MSG 1

KSync::KSync(QWidget* , const char* name):KMainWindow(0, name)
{
  config=kapp->config();

  initStatusBar();
  initActions();
  initView();

  readOptions();

  // disable actions at startup
  fileSave->setEnabled(false);
  fileSaveAs->setEnabled(false);
  filePrint->setEnabled(false);
  editCut->setEnabled(false);
  editCopy->setEnabled(false);
  editPaste->setEnabled(false);
}

KSync::~KSync()
{

}

void KSync::initActions()
{
  fileNewWindow = new KAction(i18n("New &Window"), 0, 0, this, SLOT(slotFileNewWindow()), actionCollection(),"file_new_window");
  fileNew = KStdAction::openNew(this, SLOT(slotFileNew()), actionCollection());
  fileOpen = KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
  fileOpenRecent = KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection());
  fileSave = KStdAction::save(this, SLOT(slotFileSave()), actionCollection());
  fileSaveAs = KStdAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection());
  fileClose = KStdAction::close(this, SLOT(slotFileClose()), actionCollection());
  filePrint = KStdAction::print(this, SLOT(slotFilePrint()), actionCollection());
  fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
  editCut = KStdAction::cut(this, SLOT(slotEditCut()), actionCollection());
  editCopy = KStdAction::copy(this, SLOT(slotEditCopy()), actionCollection());
  editPaste = KStdAction::paste(this, SLOT(slotEditPaste()), actionCollection());
  viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()), actionCollection());
  viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()), actionCollection());

  fileNewWindow->setStatusText(i18n("Opens a new application window"));
  fileNew->setStatusText(i18n("Creates a new document"));
  fileOpen->setStatusText(i18n("Opens an existing document"));
  fileOpenRecent->setStatusText(i18n("Opens a recently used file"));
  fileSave->setStatusText(i18n("Saves the actual document"));
  fileSaveAs->setStatusText(i18n("Saves the actual document as..."));
  fileClose->setStatusText(i18n("Closes the actual document"));
  filePrint ->setStatusText(i18n("Prints out the actual document"));
  fileQuit->setStatusText(i18n("Quits the application"));
  editCut->setStatusText(i18n("Cuts the selected section and puts it to the clipboard"));
  editCopy->setStatusText(i18n("Copies the selected section to the clipboard"));
  editPaste->setStatusText(i18n("Pastes the clipboard contents to actual position"));
  viewToolBar->setStatusText(i18n("Enables/disables the toolbar"));
  viewStatusBar->setStatusText(i18n("Enables/disables the statusbar"));

  // use the absolute path to your ksyncui.rc file for testing purpose in createGUI();
  createGUI();

}

void KSync::initStatusBar()
{
  statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG);
}

void KSync::initView()
{
  mView = new KSyncView(this);
  setCentralWidget(mView);
//  setCaption(doc->URL().fileName(),false);
}

void KSync::openDocumentFile(const KURL& url)
{
  slotStatusMsg(i18n("Opening file..."));

//  doc->openDocument( url);
  fileOpenRecent->addURL( url );
  slotStatusMsg(i18n("Ready."));
}

void KSync::saveOptions()
{
  config->setGroup("General Options");
  config->writeEntry("Geometry", size());
  config->writeEntry("Show Toolbar", viewToolBar->isChecked());
  config->writeEntry("Show Statusbar",viewStatusBar->isChecked());
  config->writeEntry("ToolBarPos", (int) toolBar("mainToolBar")->barPos());
  fileOpenRecent->saveEntries(config,"Recent Files");

  mView->writeConfig(config);
}

void KSync::readOptions()
{
  config->setGroup("General Options");

  // bar status settings
  bool bViewToolbar = config->readBoolEntry("Show Toolbar", true);
  viewToolBar->setChecked(bViewToolbar);
  slotViewToolBar();

  bool bViewStatusbar = config->readBoolEntry("Show Statusbar", true);
  viewStatusBar->setChecked(bViewStatusbar);
  slotViewStatusBar();

  // bar position settings
  KToolBar::BarPosition toolBarPos;
  toolBarPos=(KToolBar::BarPosition) config->readNumEntry("ToolBarPos", KToolBar::Top);
  toolBar("mainToolBar")->setBarPos(toolBarPos);

  // initialize the recent file list
  fileOpenRecent->loadEntries(config,"Recent Files");

  QSize size=config->readSizeEntry("Geometry");
  if(!size.isEmpty())
  {
    resize(size);
  }

  mView->readConfig(config);
}

void KSync::saveProperties(KConfig *)
{
#if 0
  if(doc->URL().fileName()!=i18n("Untitled") && !doc->isModified())
  {
    // saving to tempfile not necessary

  }
  else
  {
    KURL url=doc->URL();
    _cfg->writeEntry("filename", url.url());
    _cfg->writeEntry("modified", doc->isModified());
    QString tempname = kapp->tempSaveName(url.url());
    QString tempurl= KURL::encode_string(tempname);
    KURL _url(tempurl);
    doc->saveDocument(_url);
  }
#endif
}

void KSync::readProperties(KConfig *)
{
#if 0
  QString filename = _cfg->readEntry("filename", "");
  KURL url(filename);
  bool modified = _cfg->readBoolEntry("modified", false);
  if(modified)
  {
    bool canRecover;
    QString tempname = kapp->checkRecoverFile(filename, canRecover);
    KURL _url(tempname);

    if(canRecover)
    {
      doc->openDocument(_url);
      doc->setModified();
      setCaption(_url.fileName(),true);
      QFile::remove(tempname);
    }
  }
  else
  {
    if(!filename.isEmpty())
    {
      doc->openDocument(url);
      setCaption(url.fileName(),false);
    }
  }
#endif
}

bool KSync::queryClose()
{
//  return doc->saveModified();
  return true;
}

bool KSync::queryExit()
{
  saveOptions();
  return true;
}

void KSync::slotFileNewWindow()
{
  slotStatusMsg(i18n("Opening a new application window..."));

  KSync *new_window= new KSync();
  new_window->show();

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileNew()
{
  slotStatusMsg(i18n("Creating new document..."));

#if 0
  if(!doc->saveModified())
  {
     // here saving wasn't successful

  }
  else
  {
    doc->newDocument();
    setCaption(doc->URL().fileName(), false);
  }
#endif

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileOpen()
{
  slotStatusMsg(i18n("Opening file..."));

#if 0
  if(!doc->saveModified())
  {
     // here saving wasn't successful

  }
  else
  {
    KURL url=KFileDialog::getOpenURL(QString::null,
        i18n("*|All files"), this, i18n("Open File"));
    if(!url.isEmpty())
    {
      doc->openDocument(url);
      setCaption(url.fileName(), false);
      fileOpenRecent->addURL( url );
    }
  }
#endif

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileOpenRecent(const KURL&)
{
  slotStatusMsg(i18n("Opening file..."));

#if 0
  if(!doc->saveModified())
  {
     // here saving wasn't successful
  }
  else
  {
    doc->openDocument(url);
    setCaption(url.fileName(), false);
  }
#endif

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileSave()
{
  slotStatusMsg(i18n("Saving file..."));

//  doc->saveDocument(doc->URL());

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileSaveAs()
{
  slotStatusMsg(i18n("Saving file with a new filename..."));

  KURL url=KFileDialog::getSaveURL(QDir::currentDirPath(),
        i18n("*|All files"), this, i18n("Save As"));
  if(!url.isEmpty())
  {
//    doc->saveDocument(url);
    fileOpenRecent->addURL(url);
//    setCaption(url.fileName(),doc->isModified());
  }

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileClose()
{
  slotStatusMsg(i18n("Closing file..."));

  close();

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFilePrint()
{
  slotStatusMsg(i18n("Printing..."));

  QPrinter printer;
  if (printer.setup(this))
  {
    mView->print(&printer);
  }

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotFileQuit()
{
  slotStatusMsg(i18n("Exiting..."));
  saveOptions();
  // close the first window, the list makes the next one the first again.
  // This ensures that queryClose() is called on each window to ask for closing
  KMainWindow* w;
  if(memberList)
  {
    for(w=memberList->first(); w!=0; w=memberList->first())
    {
      // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog,
      // the window and the application stay open.
      if(!w->close())
	break;
    }
  }
  slotStatusMsg(i18n("Ready."));
}

void KSync::slotEditCut()
{
  slotStatusMsg(i18n("Cutting selection..."));

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotEditCopy()
{
  slotStatusMsg(i18n("Copying selection to clipboard..."));

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotEditPaste()
{
  slotStatusMsg(i18n("Inserting clipboard contents..."));

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotViewToolBar()
{
  slotStatusMsg(i18n("Toggling toolbar..."));

  if(!viewToolBar->isChecked())
  {
    toolBar("mainToolBar")->hide();
  }
  else
  {
    toolBar("mainToolBar")->show();
  }

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotViewStatusBar()
{
  slotStatusMsg(i18n("Toggle the statusbar..."));

  if(!viewStatusBar->isChecked())
  {
    statusBar()->hide();
  }
  else
  {
    statusBar()->show();
  }

  slotStatusMsg(i18n("Ready."));
}

void KSync::slotStatusMsg(const QString &text)
{
  statusBar()->clear();
  statusBar()->changeItem(text, ID_STATUS_MSG);
}

<|endoftext|>


<commit_before>{{{header}}}
{{#includes}}
#include <{{{.}}}>
{{/includes}}
{{{precontent}}}
#include <boost/python.hpp>
#include <cmath>

/* postinclude */

void {{class.mangled_name}}()
{
::boost::python::object parent_object(::boost::python::scope(){{!
    }}{{#class.scope}}{{#name}}.attr("{{name}}"){{/name}}{{/class.scope}});
::boost::python::scope parent_scope(parent_object);

::boost::python::class_<{{{class.type}}}{{^class.is_copyable}}, {{!
        }}::boost::noncopyable{{/class.is_copyable}}{{#class.held_type}}, {{!
        }}{{{.}}}{{/class.held_type}}{{#class.bases?}}, {{!
        }}::boost::python::bases<{{!
            }}{{#class.bases}}{{{qualified_name}}}{{^last}}, {{/last}}{{/class.bases}}{{!
        }} >{{/class.bases?}} >("{{class.name}}", boost::python::no_init){{!

/* constructors */}}
{{#class.constructors}}{{!
}}{{#overloads}}{{!
    }}.def("__init__", ::boost::python::make_constructor({{!
        }}[]({{#params}}{{{type}}} {{name}}{{^last}}, {{/last}}{{/params}}){{!
        }} -> {{{class.type}}} * { {{!
        }}return new {{{class.type}}}({{#params}}{{name}}{{^last}}, {{/last}}{{/params}}); }{{!
        }}, ::boost::python::default_call_policies(){{!
        }}{{#params?}}, ({{#params}}::boost::python::arg("{{name}}"){{^last}}, {{/last}}{{/params}}){{/params?}}))
{{/overloads}}{{!
}}{{/class.constructors}}{{!

/* member functions */}}
{{#class.methods}}{{!
}}{{^is_static}}{{!
}}{{#overloads}}{{!
    }}.def("{{name}}", []({{#is_const}}const {{/is_const}}{{{class.type}}} *self{{#params}}, {{{type}}} {{name}}{{/params}}) -> {{{return_type}}} { {{!
    }}return self->{{name}}({{#params}}{{name}}{{^last}}, {{/last}}{{/params}}); }{{!
    }}{{#return_value_policy}}, ::boost::python::return_value_policy<{{{.}}} >(){{/return_value_policy}}{{!
    }}{{#params?}}, ({{#params}}::boost::python::arg("{{name}}"){{^last}}, {{/last}}{{/params}}){{/params?}})
{{/overloads}}{{!
}}{{/is_static}}{{!
}}{{/class.methods}}{{!

/* static member functions */}}
{{#class.methods}}{{!
}}{{#is_static}}{{!
}}{{#overloads}}{{!
    }}.def("{{name}}", []({{#params}}{{{type}}} {{name}}{{^last}}, {{/last}}{{/params}}) -> {{{return_type}}} { {{!
    }}return {{{class.qualified_name}}}::{{name}}({{#params}}{{name}}{{^last}}, {{/last}}{{/params}}); }{{!
    }}{{#return_value_policy}}, ::boost::python::return_value_policy<{{{.}}} >(){{/return_value_policy}}{{!
    }}{{#params?}}, ({{#params}}::boost::python::arg("{{name}}"){{^last}}, {{/last}}{{/params}}){{/params?}})
{{/overloads}}{{!
}}{{/is_static}}{{!
}}{{/class.methods}}
{{#class.static_methods}}{{!
    }}.staticmethod("{{.}}")
{{/class.static_methods}}{{!

/* fields */}}
{{#class.fields}}{{!
    }}{{#is_assignable}}.def_readwrite{{/is_assignable}}{{!
    }}{{^is_assignable}}.def_readonly{{/is_assignable}}{{!
    }}("{{name}}", &{{{qualified_name}}})
{{/class.fields}}{{!

/* static fields */
/* TODO: Add make_setter if this property is assignable */}}
{{#class.static_fields}}{{!
    }}.add_static_property("{{name}}", {{!
    }}::boost::python::make_getter({{{qualified_name}}}))
{{/class.static_fields}}
;
}
{{{postcontent}}}
{{{footer}}}
<commit_msg>Added CXXRecordDecl docstrings.<commit_after>{{{header}}}
{{#includes}}
#include <{{{.}}}>
{{/includes}}
{{{precontent}}}
#include <boost/python.hpp>
#include <cmath>

namespace {

{{#class.?comment}}{{!
}}constexpr char {{class.mangled_name}}_docstring[] = R"CHIMERA_STRING({{!
}}{{#class.comment}}{{!
}}{{{.}}}
{{/class.comment}}{{!
}})CHIMERA_STRING";
{{/class.?comment}}

} // namespace

void {{class.mangled_name}}()
{
::boost::python::object parent_object(::boost::python::scope(){{!
    }}{{#class.scope}}{{#name}}.attr("{{name}}"){{/name}}{{/class.scope}});
::boost::python::scope parent_scope(parent_object);

::boost::python::class_<{{{class.type}}}{{^class.is_copyable}}, {{!
        }}::boost::noncopyable{{/class.is_copyable}}{{#class.held_type}}, {{!
        }}{{{.}}}{{/class.held_type}}{{#class.bases?}}, {{!
        }}::boost::python::bases<{{!
            }}{{#class.bases}}{{{qualified_name}}}{{^last}}, {{/last}}{{/class.bases}}{{!
        }} >{{/class.bases?}} >("{{class.name}}",{{!
        }} {{class.mangled_name}}_docstring, boost::python::no_init){{!

/* constructors */}}
{{#class.constructors}}{{!
}}{{#overloads}}{{!
    }}.def("__init__", ::boost::python::make_constructor({{!
        }}[]({{#params}}{{{type}}} {{name}}{{^last}}, {{/last}}{{/params}}){{!
        }} -> {{{class.type}}} * { {{!
        }}return new {{{class.type}}}({{#params}}{{name}}{{^last}}, {{/last}}{{/params}}); }{{!
        }}, ::boost::python::default_call_policies(){{!
        }}{{#params?}}, ({{#params}}::boost::python::arg("{{name}}"){{^last}}, {{/last}}{{/params}}){{/params?}}))
{{/overloads}}{{!
}}{{/class.constructors}}{{!

/* member functions */}}
{{#class.methods}}{{!
}}{{^is_static}}{{!
}}{{#overloads}}{{!
    }}.def("{{name}}", []({{#is_const}}const {{/is_const}}{{{class.type}}} *self{{#params}}, {{{type}}} {{name}}{{/params}}) -> {{{return_type}}} { {{!
    }}return self->{{name}}({{#params}}{{name}}{{^last}}, {{/last}}{{/params}}); }{{!
    }}{{#return_value_policy}}, ::boost::python::return_value_policy<{{{.}}} >(){{/return_value_policy}}{{!
    }}{{#params?}}, ({{#params}}::boost::python::arg("{{name}}"){{^last}}, {{/last}}{{/params}}){{/params?}})
{{/overloads}}{{!
}}{{/is_static}}{{!
}}{{/class.methods}}{{!

/* static member functions */}}
{{#class.methods}}{{!
}}{{#is_static}}{{!
}}{{#overloads}}{{!
    }}.def("{{name}}", []({{#params}}{{{type}}} {{name}}{{^last}}, {{/last}}{{/params}}) -> {{{return_type}}} { {{!
    }}return {{{class.qualified_name}}}::{{name}}({{#params}}{{name}}{{^last}}, {{/last}}{{/params}}); }{{!
    }}{{#return_value_policy}}, ::boost::python::return_value_policy<{{{.}}} >(){{/return_value_policy}}{{!
    }}{{#params?}}, ({{#params}}::boost::python::arg("{{name}}"){{^last}}, {{/last}}{{/params}}){{/params?}})
{{/overloads}}{{!
}}{{/is_static}}{{!
}}{{/class.methods}}
{{#class.static_methods}}{{!
    }}.staticmethod("{{.}}")
{{/class.static_methods}}{{!

/* fields */}}
{{#class.fields}}{{!
    }}{{#is_assignable}}.def_readwrite{{/is_assignable}}{{!
    }}{{^is_assignable}}.def_readonly{{/is_assignable}}{{!
    }}("{{name}}", &{{{qualified_name}}})
{{/class.fields}}{{!

/* static fields */
/* TODO: Add make_setter if this property is assignable */}}
{{#class.static_fields}}{{!
    }}.add_static_property("{{name}}", {{!
    }}::boost::python::make_getter({{{qualified_name}}}))
{{/class.static_fields}}
;
}
{{{postcontent}}}
{{{footer}}}
<|endoftext|>


<commit_before>#include "axlib.h"
#include <vector>

#define internal static
#define local_persist static
#define CGSDefaultConnection _CGSDefaultConnection()

typedef int CGSConnectionID;
extern "C" CGSConnectionID _CGSDefaultConnection(void);
extern "C" CGError CGSGetOnScreenWindowCount(const CGSConnectionID CID, CGSConnectionID TID, int *Count);
extern "C" CGError CGSGetOnScreenWindowList(const CGSConnectionID CID, CGSConnectionID TID, int Count, int *List, int *OutCount);

internal ax_state *AXState;
internal carbon_event_handler *Carbon;
internal std::map<pid_t, ax_application> *AXApplications;
internal std::map<CGDirectDisplayID, ax_display> *AXDisplays;

internal inline AXUIElementRef
AXLibSystemWideElement()
{
    local_persist AXUIElementRef AXLibSystemWideElement;
    local_persist dispatch_once_t OnceToken;

    dispatch_once(&OnceToken, ^{
        AXLibSystemWideElement = AXUIElementCreateSystemWide();
    });

    return AXLibSystemWideElement;
}

/* NOTE(koekeishiya): Does AXLib already have an ax_application struct for the given process id (?) .*/
internal bool
AXLibIsApplicationCached(pid_t PID)
{
    std::map<pid_t, ax_application>::iterator It = AXApplications->find(PID);
    return It != AXApplications->end();
}

/* NOTE(koekeishiya): Returns a pointer to the ax_application struct corresponding to the given process id. */
ax_application *AXLibGetApplicationByPID(pid_t PID)
{
    return AXLibIsApplicationCached(PID) ? &(*AXApplications)[PID] : NULL;
}

/* NOTE(koekeishiya): Returns a pointer to the ax_application struct that is the current active application. */
ax_application *AXLibGetFocusedApplication()
{
    AXUIElementRef Ref = (AXUIElementRef) AXLibGetWindowProperty(AXLibSystemWideElement(), kAXFocusedApplicationAttribute);

    if(Ref)
    {
        pid_t PID;
        AXUIElementGetPid(Ref, &PID);
        CFRelease(Ref);

        return AXLibGetApplicationByPID(PID);
    }

    return NULL;
}

/* NOTE(koekeishiya): Returns a pointer to the ax_window struct that is the current focused window of an application. */
ax_window *AXLibGetFocusedWindow(ax_application *Application)
{
    AXUIElementRef Ref = (AXUIElementRef) AXLibGetWindowProperty(Application->Ref, kAXFocusedWindowAttribute);
    if(Ref)
    {
        uint32_t WID = AXLibGetWindowID(Ref);
        CFRelease(Ref);

        ax_window *Window = AXLibFindApplicationWindow(Application, WID);
        return Window;
    }

    return NULL;
}

/* NOTE(koekeishiya): The passed ax_window will now become the focused window of OSX. If the
                      application corresponding to this window is not active, it will be activated. */
void AXLibSetFocusedWindow(ax_window *Window)
{
    AXLibSetWindowProperty(Window->Ref, kAXMainAttribute, kCFBooleanTrue);
    AXLibSetWindowProperty(Window->Ref, kAXFocusedAttribute, kCFBooleanTrue);
    AXUIElementPerformAction(Window->Ref, kAXRaiseAction);
    SetFrontProcessWithOptions(&Window->Application->PSN, kSetFrontProcessFrontWindowOnly);

    /* NOTE(koekeishiya): Calling SetFrontProcessWithOptions is faster than performing this sequence of functions.
    if(!AXLibIsApplicationActive(Window->Application))
        AXLibActivateApplication(Window->Application);
    */
}

/* NOTE(koekeishiya): Returns a vector of all windows that we currently know about. This fuction is probably not necessary. */
std::vector<ax_window *> AXLibGetAllKnownWindows()
{
    std::vector<ax_window *> Windows;
    std::map<pid_t, ax_application>::iterator It;
    for(It = AXApplications->begin(); It != AXApplications->end(); ++It)
    {
        ax_application *Application = &It->second;
        std::map<uint32_t, ax_window*>::iterator WIt;
        for(WIt = Application->Windows.begin(); WIt != Application->Windows.end(); ++WIt)
            Windows.push_back(WIt->second);
    }

    return Windows;
}

internal inline bool
AXLibArrayContains(int *WindowList, int WindowCount, uint32_t WindowID)
{
    while(WindowCount > 0)
    {
        if(WindowList[--WindowCount] == WindowID)
            return true;
    }

    return false;
}

/* NOTE(koekeishiya): Returns a list of pointer to ax_window structs containing all windows currently visible,
                     filtering by their associated kAXWindowRole and kAXWindowSubrole. */
std::vector<ax_window *> AXLibGetAllVisibleWindows()
{
    std::vector<ax_window *> Windows;

    /* NOTE(koekeishiya): Is it necessary to actually decide how many windows are on the screen.
                          Can we just pass an estimated high enough number such as 200 (?) */
    int WindowCount = 0;
    CGError Error = CGSGetOnScreenWindowCount(CGSDefaultConnection, 0, &WindowCount);
    if(Error == kCGErrorSuccess)
    {
        /* NOTE(koekeishiya): This function seems to be pretty expensive.. Is CGWindowListCopyWindowInfo faster (?) */
        int WindowList[WindowCount];
        Error = CGSGetOnScreenWindowList(CGSDefaultConnection, 0, WindowCount, WindowList, &WindowCount);
        if(Error == kCGErrorSuccess)
        {
            std::map<pid_t, ax_application>::iterator It;
            for(It = AXApplications->begin(); It != AXApplications->end(); ++It)
            {
                ax_application *Application = &It->second;
                if(!AXLibIsApplicationHidden(Application))
                {
                    std::map<uint32_t, ax_window*>::iterator WIt;
                    for(WIt = Application->Windows.begin(); WIt != Application->Windows.end(); ++WIt)
                    {
                        ax_window *Window = WIt->second;
                        /* NOTE(koekeishiya): If a window is minimized, the ArrayContains check should fail
                                              if(!AXLibIsWindowMinimized(Window->Ref)) */

                        if((AXLibArrayContains(WindowList, WindowCount, Window->ID)) &&
                           (AXLibIsWindowStandard(Window) || AXLibIsWindowCustom(Window)) &&
                           (!AXLibHasFlags(Window, AXWindow_Floating)))
                        {
                            Windows.push_back(Window);
                        }
                    }
                }
            }
        }
    }

    return Windows;
}

/* NOTE(koekeishiya): Returns a list of pointer to ax_window structs containing all windows currently visible,
                      filtering by their associated kAXWindowRole and kAXWindowSubrole. The windows are
                      return in topmost order. The window at index zero is the window at the top.
                      If the topmost window is launchpad, or a context menu, this function will
                      return an empty list! */
#define CONTEXT_MENU_LAYER 101
std::vector<ax_window *> AXLibGetAllVisibleWindowsOrdered()
{
    std::vector<ax_window *> Windows;

    CGWindowListOption WindowListOption = kCGWindowListOptionOnScreenOnly |
                                          kCGWindowListExcludeDesktopElements;

    CFArrayRef WindowList = CGWindowListCopyWindowInfo(WindowListOption, kCGNullWindowID);
    if(WindowList)
    {
        CFIndex WindowCount = CFArrayGetCount(WindowList);
        for(std::size_t Index = 0; Index < WindowCount; ++Index)
        {
            uint32_t WindowID;
            uint32_t WindowLayer;
            CFNumberRef CFWindowNumber;
            CFNumberRef CFWindowLayer;
            CFDictionaryRef Elem = (CFDictionaryRef)CFArrayGetValueAtIndex(WindowList, Index);
            CFWindowNumber = (CFNumberRef) CFDictionaryGetValue(Elem, CFSTR("kCGWindowNumber"));
            CFWindowLayer = (CFNumberRef) CFDictionaryGetValue(Elem, CFSTR("kCGWindowLayer"));
            CFNumberGetValue(CFWindowNumber, kCFNumberSInt32Type, &WindowID);
            CFNumberGetValue(CFWindowLayer, kCFNumberSInt32Type, &WindowLayer);
            CFRelease(CFWindowNumber);
            CFRelease(CFWindowLayer);

            CFStringRef CFOwner = (CFStringRef) CFDictionaryGetValue(Elem, CFSTR("kCGWindowOwnerName"));
            CFStringRef CFName = (CFStringRef) CFDictionaryGetValue(Elem, CFSTR("kCGWindowName"));

            if(((CFOwner && (CFStringCompare(CFOwner, CFSTR("Dock"), 0) == kCFCompareEqualTo)) &&
                (CFName && (CFStringCompare(CFName, CFSTR("LPSpringboard"), 0) == kCFCompareEqualTo))) ||
                (WindowLayer == CONTEXT_MENU_LAYER))
            {
                CFRelease(WindowList);
                Windows.clear();
                return Windows;
            }

            std::map<pid_t, ax_application>::iterator It;
            for(It = AXApplications->begin(); It != AXApplications->end(); ++It)
            {
                /* NOTE(koekeishiya): This function call is incredibly expensive (roughly 70% of the cost of the entire function)
                                      and doesn't really give us any benefeits, ignore it.
                if(!AXLibIsApplicationHidden(Application)) */

                ax_application *Application = &It->second;
                ax_window *Window = AXLibFindApplicationWindow(Application, WindowID);
                if(Window)
                {
                    if((AXLibIsWindowStandard(Window) ||
                       (AXLibIsWindowCustom(Window))))
                    {
                        Windows.push_back(Window);
                    }
                    break;
                }
            }
        }

        CFRelease(WindowList);
    }

    return Windows;
}

/* NOTE(koekeishiya): Update state of known applications and their windows, stored inside the ax_state passed to AXLibInit(..). */
void AXLibRunningApplications()
{
    std::map<pid_t, std::string> List = SharedWorkspaceRunningApplications();

    std::map<pid_t, std::string>::iterator It;
    for(It = List.begin(); It != List.end(); ++It)
    {
        pid_t PID = It->first;
        if(!AXLibIsApplicationCached(PID))
        {
            std::string Name = It->second;
            (*AXApplications)[PID] = AXLibConstructApplication(PID, Name);
            AXLibInitializeApplication(&(*AXApplications)[PID]);
        }
        else
        {
            AXLibAddApplicationWindows(&(*AXApplications)[PID]);
        }
    }
}

/* NOTE(koekeishiya): This function is responsible for initializing internal variables used by AXLib, and must be
                      called before using any of the provided functions!  In addition to this, it will also
                      populate the display and running applications map in the ax_state struct.  */
void AXLibInit(ax_state *State)
{
    AXState = State;
    AXApplications = &AXState->Applications;
    AXDisplays = &AXState->Displays;
    Carbon = &AXState->Carbon;
    AXUIElementSetMessagingTimeout(AXLibSystemWideElement(), 1.0);
    AXLibInitializeCarbonEventHandler(Carbon, AXApplications);
    SharedWorkspaceInitialize(AXApplications);
    AXLibInitializeDisplays(AXDisplays);
    AXLibRunningApplications();
}
<commit_msg>fix paranthesis<commit_after>#include "axlib.h"
#include <vector>

#define internal static
#define local_persist static
#define CGSDefaultConnection _CGSDefaultConnection()

typedef int CGSConnectionID;
extern "C" CGSConnectionID _CGSDefaultConnection(void);
extern "C" CGError CGSGetOnScreenWindowCount(const CGSConnectionID CID, CGSConnectionID TID, int *Count);
extern "C" CGError CGSGetOnScreenWindowList(const CGSConnectionID CID, CGSConnectionID TID, int Count, int *List, int *OutCount);

internal ax_state *AXState;
internal carbon_event_handler *Carbon;
internal std::map<pid_t, ax_application> *AXApplications;
internal std::map<CGDirectDisplayID, ax_display> *AXDisplays;

internal inline AXUIElementRef
AXLibSystemWideElement()
{
    local_persist AXUIElementRef AXLibSystemWideElement;
    local_persist dispatch_once_t OnceToken;

    dispatch_once(&OnceToken, ^{
        AXLibSystemWideElement = AXUIElementCreateSystemWide();
    });

    return AXLibSystemWideElement;
}

/* NOTE(koekeishiya): Does AXLib already have an ax_application struct for the given process id (?) .*/
internal bool
AXLibIsApplicationCached(pid_t PID)
{
    std::map<pid_t, ax_application>::iterator It = AXApplications->find(PID);
    return It != AXApplications->end();
}

/* NOTE(koekeishiya): Returns a pointer to the ax_application struct corresponding to the given process id. */
ax_application *AXLibGetApplicationByPID(pid_t PID)
{
    return AXLibIsApplicationCached(PID) ? &(*AXApplications)[PID] : NULL;
}

/* NOTE(koekeishiya): Returns a pointer to the ax_application struct that is the current active application. */
ax_application *AXLibGetFocusedApplication()
{
    AXUIElementRef Ref = (AXUIElementRef) AXLibGetWindowProperty(AXLibSystemWideElement(), kAXFocusedApplicationAttribute);

    if(Ref)
    {
        pid_t PID;
        AXUIElementGetPid(Ref, &PID);
        CFRelease(Ref);

        return AXLibGetApplicationByPID(PID);
    }

    return NULL;
}

/* NOTE(koekeishiya): Returns a pointer to the ax_window struct that is the current focused window of an application. */
ax_window *AXLibGetFocusedWindow(ax_application *Application)
{
    AXUIElementRef Ref = (AXUIElementRef) AXLibGetWindowProperty(Application->Ref, kAXFocusedWindowAttribute);
    if(Ref)
    {
        uint32_t WID = AXLibGetWindowID(Ref);
        CFRelease(Ref);

        ax_window *Window = AXLibFindApplicationWindow(Application, WID);
        return Window;
    }

    return NULL;
}

/* NOTE(koekeishiya): The passed ax_window will now become the focused window of OSX. If the
                      application corresponding to this window is not active, it will be activated. */
void AXLibSetFocusedWindow(ax_window *Window)
{
    AXLibSetWindowProperty(Window->Ref, kAXMainAttribute, kCFBooleanTrue);
    AXLibSetWindowProperty(Window->Ref, kAXFocusedAttribute, kCFBooleanTrue);
    AXUIElementPerformAction(Window->Ref, kAXRaiseAction);
    SetFrontProcessWithOptions(&Window->Application->PSN, kSetFrontProcessFrontWindowOnly);

    /* NOTE(koekeishiya): Calling SetFrontProcessWithOptions is faster than performing this sequence of functions.
    if(!AXLibIsApplicationActive(Window->Application))
        AXLibActivateApplication(Window->Application);
    */
}

/* NOTE(koekeishiya): Returns a vector of all windows that we currently know about. This fuction is probably not necessary. */
std::vector<ax_window *> AXLibGetAllKnownWindows()
{
    std::vector<ax_window *> Windows;
    std::map<pid_t, ax_application>::iterator It;
    for(It = AXApplications->begin(); It != AXApplications->end(); ++It)
    {
        ax_application *Application = &It->second;
        std::map<uint32_t, ax_window*>::iterator WIt;
        for(WIt = Application->Windows.begin(); WIt != Application->Windows.end(); ++WIt)
            Windows.push_back(WIt->second);
    }

    return Windows;
}

internal inline bool
AXLibArrayContains(int *WindowList, int WindowCount, uint32_t WindowID)
{
    while(WindowCount > 0)
    {
        if(WindowList[--WindowCount] == WindowID)
            return true;
    }

    return false;
}

/* NOTE(koekeishiya): Returns a list of pointer to ax_window structs containing all windows currently visible,
                     filtering by their associated kAXWindowRole and kAXWindowSubrole. */
std::vector<ax_window *> AXLibGetAllVisibleWindows()
{
    std::vector<ax_window *> Windows;

    /* NOTE(koekeishiya): Is it necessary to actually decide how many windows are on the screen.
                          Can we just pass an estimated high enough number such as 200 (?) */
    int WindowCount = 0;
    CGError Error = CGSGetOnScreenWindowCount(CGSDefaultConnection, 0, &WindowCount);
    if(Error == kCGErrorSuccess)
    {
        /* NOTE(koekeishiya): This function seems to be pretty expensive.. Is CGWindowListCopyWindowInfo faster (?) */
        int WindowList[WindowCount];
        Error = CGSGetOnScreenWindowList(CGSDefaultConnection, 0, WindowCount, WindowList, &WindowCount);
        if(Error == kCGErrorSuccess)
        {
            std::map<pid_t, ax_application>::iterator It;
            for(It = AXApplications->begin(); It != AXApplications->end(); ++It)
            {
                ax_application *Application = &It->second;
                if(!AXLibIsApplicationHidden(Application))
                {
                    std::map<uint32_t, ax_window*>::iterator WIt;
                    for(WIt = Application->Windows.begin(); WIt != Application->Windows.end(); ++WIt)
                    {
                        ax_window *Window = WIt->second;
                        /* NOTE(koekeishiya): If a window is minimized, the ArrayContains check should fail
                                              if(!AXLibIsWindowMinimized(Window->Ref)) */

                        if((AXLibArrayContains(WindowList, WindowCount, Window->ID)) &&
                           (AXLibIsWindowStandard(Window) || AXLibIsWindowCustom(Window)) &&
                           (!AXLibHasFlags(Window, AXWindow_Floating)))
                        {
                            Windows.push_back(Window);
                        }
                    }
                }
            }
        }
    }

    return Windows;
}

/* NOTE(koekeishiya): Returns a list of pointer to ax_window structs containing all windows currently visible,
                      filtering by their associated kAXWindowRole and kAXWindowSubrole. The windows are
                      return in topmost order. The window at index zero is the window at the top.
                      If the topmost window is launchpad, or a context menu, this function will
                      return an empty list! */
#define CONTEXT_MENU_LAYER 101
std::vector<ax_window *> AXLibGetAllVisibleWindowsOrdered()
{
    std::vector<ax_window *> Windows;

    CGWindowListOption WindowListOption = kCGWindowListOptionOnScreenOnly |
                                          kCGWindowListExcludeDesktopElements;

    CFArrayRef WindowList = CGWindowListCopyWindowInfo(WindowListOption, kCGNullWindowID);
    if(WindowList)
    {
        CFIndex WindowCount = CFArrayGetCount(WindowList);
        for(std::size_t Index = 0; Index < WindowCount; ++Index)
        {
            uint32_t WindowID;
            uint32_t WindowLayer;
            CFNumberRef CFWindowNumber;
            CFNumberRef CFWindowLayer;
            CFDictionaryRef Elem = (CFDictionaryRef)CFArrayGetValueAtIndex(WindowList, Index);
            CFWindowNumber = (CFNumberRef) CFDictionaryGetValue(Elem, CFSTR("kCGWindowNumber"));
            CFWindowLayer = (CFNumberRef) CFDictionaryGetValue(Elem, CFSTR("kCGWindowLayer"));
            CFNumberGetValue(CFWindowNumber, kCFNumberSInt32Type, &WindowID);
            CFNumberGetValue(CFWindowLayer, kCFNumberSInt32Type, &WindowLayer);
            CFRelease(CFWindowNumber);
            CFRelease(CFWindowLayer);

            CFStringRef CFOwner = (CFStringRef) CFDictionaryGetValue(Elem, CFSTR("kCGWindowOwnerName"));
            CFStringRef CFName = (CFStringRef) CFDictionaryGetValue(Elem, CFSTR("kCGWindowName"));

            if(((CFOwner && (CFStringCompare(CFOwner, CFSTR("Dock"), 0) == kCFCompareEqualTo)) &&
                (CFName && (CFStringCompare(CFName, CFSTR("LPSpringboard"), 0) == kCFCompareEqualTo))) ||
                (WindowLayer == CONTEXT_MENU_LAYER))
            {
                CFRelease(WindowList);
                Windows.clear();
                return Windows;
            }

            std::map<pid_t, ax_application>::iterator It;
            for(It = AXApplications->begin(); It != AXApplications->end(); ++It)
            {
                /* NOTE(koekeishiya): This function call is incredibly expensive (roughly 70% of the cost of the entire function)
                                      and doesn't really give us any benefeits, ignore it.
                if(!AXLibIsApplicationHidden(Application)) */

                ax_application *Application = &It->second;
                ax_window *Window = AXLibFindApplicationWindow(Application, WindowID);
                if(Window)
                {
                    if((AXLibIsWindowStandard(Window)) ||
                       (AXLibIsWindowCustom(Window)))
                    {
                        Windows.push_back(Window);
                    }
                    break;
                }
            }
        }

        CFRelease(WindowList);
    }

    return Windows;
}

/* NOTE(koekeishiya): Update state of known applications and their windows, stored inside the ax_state passed to AXLibInit(..). */
void AXLibRunningApplications()
{
    std::map<pid_t, std::string> List = SharedWorkspaceRunningApplications();

    std::map<pid_t, std::string>::iterator It;
    for(It = List.begin(); It != List.end(); ++It)
    {
        pid_t PID = It->first;
        if(!AXLibIsApplicationCached(PID))
        {
            std::string Name = It->second;
            (*AXApplications)[PID] = AXLibConstructApplication(PID, Name);
            AXLibInitializeApplication(&(*AXApplications)[PID]);
        }
        else
        {
            AXLibAddApplicationWindows(&(*AXApplications)[PID]);
        }
    }
}

/* NOTE(koekeishiya): This function is responsible for initializing internal variables used by AXLib, and must be
                      called before using any of the provided functions!  In addition to this, it will also
                      populate the display and running applications map in the ax_state struct.  */
void AXLibInit(ax_state *State)
{
    AXState = State;
    AXApplications = &AXState->Applications;
    AXDisplays = &AXState->Displays;
    Carbon = &AXState->Carbon;
    AXUIElementSetMessagingTimeout(AXLibSystemWideElement(), 1.0);
    AXLibInitializeCarbonEventHandler(Carbon, AXApplications);
    SharedWorkspaceInitialize(AXApplications);
    AXLibInitializeDisplays(AXDisplays);
    AXLibRunningApplications();
}
<|endoftext|>


<commit_before>#include "config.h"
#include "util.hpp"
#include "network_manager.hpp"
#include "network_config.hpp"
#include "ipaddress.hpp"
#include "xyz/openbmc_project/Common/error.hpp"

#include <phosphor-logging/log.hpp>
#include <phosphor-logging/elog-errors.hpp>

#include <algorithm>
#include <bitset>
#include <map>
#include <fstream>

#include <arpa/inet.h>
#include <dirent.h>
#include <net/if.h>

#include <string>

namespace phosphor
{
namespace network
{

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;

Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath,
                 const std::string& path):
    details::VLANCreateIface(bus, objPath, true),
    bus(bus),
    objectPath(objPath)
{
    fs::path confDir(path);
    setConfDir(confDir);
}

void Manager::setConfDir(const fs::path& dir)
{
    confDir = dir;

    if (!fs::exists(confDir))
    {
        if (!fs::create_directories(confDir))
        {
            log<level::ERR>("Unable to create the network conf dir",
                            entry("DIR=%s", confDir.c_str()));
            elog<InternalFailure>();
        }
    }

}

void Manager::createInterfaces()
{
    //clear all the interfaces first
    interfaces.clear();

    auto interfaceInfoList = getInterfaceAddrs();

    for (const auto& intfInfo : interfaceInfoList)
    {
        fs::path objPath = objectPath;
        auto index = intfInfo.first.find(".");

        // interface can be of vlan type or normal ethernet interface.
        // vlan interface looks like "interface.vlanid",so here by looking
        // at the interface name we decide that we need
        // to create the vlaninterface or normal physical interface.
        if (index != std::string::npos)
        {
            //it is vlan interface
            auto interface = intfInfo.first.substr(0, index);
            auto vlanid = intfInfo.first.substr(index + 1);
            uint32_t vlanInt = std::stoul(vlanid);

            interfaces[interface]->loadVLAN(vlanInt);
            continue;
        }
        // normal ethernet inetrface
        objPath /= intfInfo.first;

        auto dhcp = getDHCPValue(confDir, intfInfo.first);

        auto intf =  std::make_shared<phosphor::network::EthernetInterface>(
                         bus,
                         objPath.string(),
                         dhcp,
                         *this);

        intf->createIPAddressObjects();

        this->interfaces.emplace(std::make_pair(
                                     intfInfo.first, std::move(intf)));

    }

}

void Manager::createChildObjects()
{
    // creates the ethernet interface dbus object.
    createInterfaces();
    // create the system conf object.
    fs::path objPath = objectPath;
    objPath /= "config";
    systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
                        bus, objPath.string(), *this);
    // create the dhcp conf object.
    objPath /= "dhcp";
    dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
                        bus, objPath.string(), *this);

}

void Manager::vLAN(IntfName interfaceName, uint32_t id)
{
    interfaces[interfaceName]->createVLAN(id);
}

void Manager::reset()
{
    const std::string networkConfig = confDir.string();
    bool interfacesMapped = false;

    if(fs::is_directory(networkConfig))
    {
        for(auto& file : fs::directory_iterator(networkConfig))
        {
            fs::remove(file.path());
        }

        for (auto& intf : interfaces)
        {
            auto fileName = systemd::config::networkFilePrefix + intf.first +
                            systemd::config::networkFileSuffix;

            fs::path  filePath = networkConfig;
            filePath /= fileName;

            bmc::writeDHCPDefault(filePath.string(), intf.first);
            interfacesMapped = true;
        }

        if(interfacesMapped)
        {
            log<level::INFO>("Network configuration reset to DHCP.");
        }
        else
        {
            log<level::ERR>("No network interfaces are mapped.");
            // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
        }
    }
    else
    {
        log<level::ERR>("Network configuration directory not found!");
        // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
    }

    return;
}

// Need to merge the below function with the code which writes the
// config file during factory reset.
//TODO openbmc/openbmc#1751
void Manager::writeToConfigurationFile()
{
    // write all the static ip address in the systemd-network conf file

    for (const auto& intf : interfaces)
    {
        intf.second->writeConfigurationFile();

    }
}

}//namespace network
}//namespace phosphor
<commit_msg>Network factory reset: Log InternalFailure in case of failure<commit_after>#include "config.h"
#include "util.hpp"
#include "network_manager.hpp"
#include "network_config.hpp"
#include "ipaddress.hpp"
#include "xyz/openbmc_project/Common/error.hpp"

#include <phosphor-logging/log.hpp>
#include <phosphor-logging/elog-errors.hpp>

#include <algorithm>
#include <bitset>
#include <map>
#include <fstream>

#include <arpa/inet.h>
#include <dirent.h>
#include <net/if.h>

#include <string>

namespace phosphor
{
namespace network
{

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;

Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath,
                 const std::string& path):
    details::VLANCreateIface(bus, objPath, true),
    bus(bus),
    objectPath(objPath)
{
    fs::path confDir(path);
    setConfDir(confDir);
}

void Manager::setConfDir(const fs::path& dir)
{
    confDir = dir;

    if (!fs::exists(confDir))
    {
        if (!fs::create_directories(confDir))
        {
            log<level::ERR>("Unable to create the network conf dir",
                            entry("DIR=%s", confDir.c_str()));
            elog<InternalFailure>();
        }
    }

}

void Manager::createInterfaces()
{
    //clear all the interfaces first
    interfaces.clear();

    auto interfaceInfoList = getInterfaceAddrs();

    for (const auto& intfInfo : interfaceInfoList)
    {
        fs::path objPath = objectPath;
        auto index = intfInfo.first.find(".");

        // interface can be of vlan type or normal ethernet interface.
        // vlan interface looks like "interface.vlanid",so here by looking
        // at the interface name we decide that we need
        // to create the vlaninterface or normal physical interface.
        if (index != std::string::npos)
        {
            //it is vlan interface
            auto interface = intfInfo.first.substr(0, index);
            auto vlanid = intfInfo.first.substr(index + 1);
            uint32_t vlanInt = std::stoul(vlanid);

            interfaces[interface]->loadVLAN(vlanInt);
            continue;
        }
        // normal ethernet inetrface
        objPath /= intfInfo.first;

        auto dhcp = getDHCPValue(confDir, intfInfo.first);

        auto intf =  std::make_shared<phosphor::network::EthernetInterface>(
                         bus,
                         objPath.string(),
                         dhcp,
                         *this);

        intf->createIPAddressObjects();

        this->interfaces.emplace(std::make_pair(
                                     intfInfo.first, std::move(intf)));

    }

}

void Manager::createChildObjects()
{
    // creates the ethernet interface dbus object.
    createInterfaces();
    // create the system conf object.
    fs::path objPath = objectPath;
    objPath /= "config";
    systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
                        bus, objPath.string(), *this);
    // create the dhcp conf object.
    objPath /= "dhcp";
    dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
                        bus, objPath.string(), *this);

}

void Manager::vLAN(IntfName interfaceName, uint32_t id)
{
    interfaces[interfaceName]->createVLAN(id);
}

void Manager::reset()
{
    const std::string networkConfig = confDir.string();
    bool interfacesMapped = false;

    if(fs::is_directory(networkConfig))
    {
        for(auto& file : fs::directory_iterator(networkConfig))
        {
            fs::remove(file.path());
        }

        for (auto& intf : interfaces)
        {
            auto fileName = systemd::config::networkFilePrefix + intf.first +
                            systemd::config::networkFileSuffix;

            fs::path  filePath = networkConfig;
            filePath /= fileName;

            bmc::writeDHCPDefault(filePath.string(), intf.first);
            interfacesMapped = true;
        }

        if(interfacesMapped)
        {
            log<level::INFO>("Network configuration reset to DHCP.");
        }
        else
        {
            log<level::ERR>("No network interfaces are mapped.");
            elog<InternalFailure>();
        }
    }
    else
    {
        log<level::ERR>("Network configuration directory not found!");
        elog<InternalFailure>();
    }

    return;
}

// Need to merge the below function with the code which writes the
// config file during factory reset.
//TODO openbmc/openbmc#1751
void Manager::writeToConfigurationFile()
{
    // write all the static ip address in the systemd-network conf file

    for (const auto& intf : interfaces)
    {
        intf.second->writeConfigurationFile();

    }
}

}//namespace network
}//namespace phosphor
<|endoftext|>


<commit_before>// Copyright (c) 2015
// Author: Chrono Law
#ifndef _NGX_CONFIG_HPP
#define _NGX_CONFIG_HPP

#include "NgxArray.hpp"

class NgxCommand final
{
private:
    ngx_command_t m_cmd = ngx_null_command;
public:
    template<typename T>
    NgxCommand(const ngx_str_t& n, ngx_uint_t t, T set,
            ngx_uint_t c = NGX_HTTP_LOC_CONF_OFFSET,
            ngx_uint_t off = 0, void* p = nullptr):
        m_cmd{n, t, set, c, off, p}     //do not use () to initilize
    {}

    NgxCommand() = default;
    ~NgxCommand() = default;
public:
    operator const ngx_command_t& () const
    {
        return m_cmd;
    }
};

class NgxTake final
{
public:
    NgxTake(ngx_uint_t conf, int m, int n = -1):
        m_type(conf | take(m, n))
    {}
    ~NgxTake() = default;
public:
    operator ngx_uint_t () const
    {
        return m_type;
    }
private:
    ngx_uint_t m_type = NGX_HTTP_LOC_CONF;
private:
    static ngx_uint_t take(int m, int n)
    {
        static
        ngx_uint_t takes[] = {
            NGX_CONF_NOARGS,
            NGX_CONF_TAKE1,
            NGX_CONF_TAKE2,
            NGX_CONF_TAKE3,
            NGX_CONF_TAKE4,
            NGX_CONF_TAKE5,
            NGX_CONF_TAKE6,
            NGX_CONF_TAKE7,
            //{8, },
        };

        if(n < 0 || n < m)
        {
            return takes[m];
        }

        if(n >= NGX_CONF_MAX_ARGS)
        {
            return m == 1 ?
                   NGX_CONF_1MORE :
                   NGX_CONF_2MORE;
        }

        ngx_uint_t tmp = 0;

        for(int i = m; i <= n; ++i)
        {
            tmp |= takes[i];
        }

        return tmp;
    }

};

class NgxConfig final
{
public:
    NgxConfig() = default;
    ~NgxConfig() = default;
public:
    static NgxStrArray args(ngx_conf_t* cf)
    {
        return NgxStrArray(cf->args);
    }
};

#include <boost/preprocessor/repetition/enum.hpp>

#define NGX_NULL_HELPER(z, n, t) t
#define NGX_MODULE_NULL(n)      \
    BOOST_PP_ENUM(n, NGX_NULL_HELPER, nullptr)

#endif  //_NGX_CONFIG_HPP

<commit_msg>add conf err macro<commit_after>// Copyright (c) 2015
// Author: Chrono Law
#ifndef _NGX_CONFIG_HPP
#define _NGX_CONFIG_HPP

#include "NgxArray.hpp"

class NgxCommand final
{
private:
    ngx_command_t m_cmd = ngx_null_command;
public:
    template<typename T>
    NgxCommand(const ngx_str_t& n, ngx_uint_t t, T set,
            ngx_uint_t c = NGX_HTTP_LOC_CONF_OFFSET,
            ngx_uint_t off = 0, void* p = nullptr):
        m_cmd{n, t, set, c, off, p}     //do not use () to initilize
    {}

    NgxCommand() = default;
    ~NgxCommand() = default;
public:
    operator const ngx_command_t& () const
    {
        return m_cmd;
    }
};

class NgxTake final
{
public:
    NgxTake(ngx_uint_t conf, int m, int n = -1):
        m_type(conf | take(m, n))
    {}
    ~NgxTake() = default;
public:
    operator ngx_uint_t () const
    {
        return m_type;
    }
private:
    ngx_uint_t m_type = NGX_HTTP_LOC_CONF;
private:
    static ngx_uint_t take(int m, int n)
    {
        static
        ngx_uint_t takes[] = {
            NGX_CONF_NOARGS,
            NGX_CONF_TAKE1,
            NGX_CONF_TAKE2,
            NGX_CONF_TAKE3,
            NGX_CONF_TAKE4,
            NGX_CONF_TAKE5,
            NGX_CONF_TAKE6,
            NGX_CONF_TAKE7,
            //{8, },
        };

        if(n < 0 || n < m)
        {
            return takes[m];
        }

        if(n >= NGX_CONF_MAX_ARGS)
        {
            return m == 1 ?
                   NGX_CONF_1MORE :
                   NGX_CONF_2MORE;
        }

        ngx_uint_t tmp = 0;

        for(int i = m; i <= n; ++i)
        {
            tmp |= takes[i];
        }

        return tmp;
    }

};

class NgxConfig final
{
public:
    NgxConfig() = default;
    ~NgxConfig() = default;
public:
    static NgxStrArray args(ngx_conf_t* cf)
    {
        return NgxStrArray(cf->args);
    }
};

// for config error message
#define NGX_CONF_ERROR_MSG(s)   const_cast<char*>(s)

// for module's null
#include <boost/preprocessor/repetition/enum.hpp>

#define NGX_NULL_HELPER(z, n, t) t
#define NGX_MODULE_NULL(n)      \
    BOOST_PP_ENUM(n, NGX_NULL_HELPER, nullptr)

#endif  //_NGX_CONFIG_HPP

<|endoftext|>


<commit_before>// Sorts.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <vector>
#include <utility>
#include <numeric>
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <map>

#include <random>
#include <chrono>
#include <fstream>

using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::swap;
using std::pair;
using std::make_pair;
using std::map;
using std::chrono::high_resolution_clock;

/* * *
* std::sort
*  RandomAccessIterator shall point to a type for which swap is properly
*  defined and which is both move-constructible and move-assignable.
*
*  std::swap looks like this in c++11 and above
*  https://stackoverflow.com/a/25286610/128581
*/

// selection sort
//  always n^2
//  find smallest remaining, swap
//  left of i = final order
template <class iter>
void selection_sort(iter &begin, iter &end)
{
  for (iter start_range = begin; start_range < end; start_range++)
  {
    auto min = start_range;

    for (iter curr = start_range; curr < end; curr++)
    {
      if (*min > *curr)
      {
        min = curr;
      }
    }

    swap(*start_range, *min);
  }
}

// insertion sort
//  n^2 worst/average, n best (already in order)
//  for each i, store j = i, increment j, find any smaller, swap left until sorted
template <class iter>
void insertion_sort(iter &begin, iter &end)
{
  for (iter i = begin; i < end; i++)
  {
    for (iter j = i + 1; j < end; j++)
    {
      if (*i > *j)
      {
        swap(*i, *j);

        for (j = i; j > begin; j--)
        {
          if (*j < *(j - 1))
          {
            swap(*j, *(j - 1));
          }
          else
          {
            break;
          }
        }

        break;
      }
    }
  }
}

// shellsort
//  n(log(n))^2 worst/average, n log(n) best
//  choose items that are h apart (stride length).
//  for instance = 9 items, h of 3 = 3 sublists
//  sublist 1 = {0, 3, 6}
//  sublist 2 = {1, 4, 7}
//  sublist 3 = {2, 5, 8}
//  insertion sort each one (called an h-sorting).
//  then h-sort with stride of 1 (standard insertion sort)
//  this reduces the over all swap count
//  the actual increment sequence for h is still being researched
//  knuth suggested 3x + 1, we'll go with that
template <class iter>
void shell_sort(iter &begin, iter &end)
{
  vector<size_t> strides{ 1 };
  size_t size = distance(begin, end);

  while ((3 * strides.back() + 1) < size)
  {
    strides.push_back(3 * strides.back() + 1);
  }

  for (auto h = strides.rbegin(); h < strides.rend(); h++)
  {
    // because non-1 strides are a bitch with checked iterators
    auto unchecked_begin = _Unchecked(begin);
    auto unchecked_end = _Unchecked(end);

    for (auto i = unchecked_begin; i < unchecked_end; i+=*h)
    {
      // left of i is already sorted
      for (auto j = (i + *h); j < unchecked_end; j+=*h)
      {
        if (*j < *i)
        {
          // start swapping back until we're in place
          swap(*j, *(j - *h));

          for (j = (j - *h); j > unchecked_begin; j -= *h)
          {
            if (*j < *(j - *h))
            {
              swap(*j, *(j - *h));
            }
            else
            {
              break;
            }
          }
        }
      }
    }
  }
}

template<class iter>
void debug_sort(iter sorted_data, iter original_data)
{
  for (auto n : sorted_data)
  {
    cout << n << " ";
  }

  cout << endl;
  cout << "is permutation: ";
  cout << std::boolalpha << std::is_permutation(sorted_data.begin(), sorted_data.end(), original_data.begin());
  cout << endl;
  cout << "is sorted: ";
  cout << std::boolalpha << std::is_sorted(sorted_data.begin(), sorted_data.end());
  cout << endl;
}

int main()
{
  constexpr size_t MAX_INPUT_SIZE = 250;
  constexpr size_t INPUT_STEP = 10;
  constexpr size_t ITERATION_COUNT = 50;

  std::default_random_engine eng;
  std::uniform_int_distribution<int> dis(0, 100);

  using SortTime = pair<int, double>;
  using SortData = vector<int>;
  using Iterator = vector<int>::iterator;
  using SortTimeEntry = pair<string, SortTime>;

  map<string, void(*)(Iterator&, Iterator&)> sort_functions {
    {"Selection Sort", &selection_sort<Iterator>},
    {"Insertion Sort", &insertion_sort<Iterator>},
    {"Shell Sort", &shell_sort<Iterator>}
  };

  vector<SortTimeEntry> sort_times;

  for (auto sort : sort_functions)
  {
    cout << "Start " << sort.first << endl;
    for (size_t input_size = 2; input_size < MAX_INPUT_SIZE; input_size += INPUT_STEP)
    {
      vector<double> iteration;
      SortData data;

      for (size_t i = 0; i < input_size; i++)
      {
        data.push_back(dis(eng));
      }

      for (size_t i = 0; i < ITERATION_COUNT; i++)
      {
        auto start = high_resolution_clock::now();
        sort.second(data.begin(), data.end());
        std::chrono::duration<double> sort_time = high_resolution_clock::now() - start;
        iteration.push_back(sort_time.count());
      }

      //double average_run_time = std::accumulate(iteration.begin(), iteration.end(), 0.0) / iteration.size();

      for (auto i = iteration.begin(); i < iteration.end(); i++)
      {
        SortTime run_time{ input_size, *i };
        SortTimeEntry entry{ sort.first, run_time };
        sort_times.push_back(entry);
      }

      cout << input_size << " done." << endl;
    }
  }

  std::ofstream csv;
  csv.open("sort_times.csv");

  if (csv)
  {
    csv << "Algorithm,Input Size,Time Elapsed" << endl;
    for (auto time : sort_times)
    {
      csv << time.first << "," << time.second.first << "," << time.second.second << endl;
    }

    csv.close();

    cout << "CSV of time elapsed written" << endl;
  }
  else
  {
    cout << "Cannot open sort file" << endl;
  }

  cin.get();

  return 0;
}

<commit_msg>Add merge sort<commit_after>// Sorts.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <vector>
#include <utility>
#include <numeric>
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <map>

#include <random>
#include <chrono>
#include <fstream>

using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::swap;
using std::pair;
using std::make_pair;
using std::map;
using std::chrono::high_resolution_clock;

using SortTime = pair<int, double>;
using SortData = vector<int>;
using Iterator = vector<int>::iterator;
using SortTimeEntry = pair<string, SortTime>;
using AlgorithmList = map<string, void(*)(Iterator&, Iterator&)>;

/* * *
* std::sort
*  RandomAccessIterator shall point to a type for which swap is properly
*  defined and which is both move-constructible and move-assignable.
*
*  std::swap looks like this in c++11 and above
*  https://stackoverflow.com/a/25286610/128581
*/

// selection sort
//  always n^2
//  find smallest remaining, swap
//  left of i = final order
template <class iter>
void selection_sort(iter &begin, iter &end)
{
  for (iter start_range = begin; start_range < end; start_range++)
  {
    auto min = start_range;

    for (iter curr = start_range; curr < end; curr++)
    {
      if (*min > *curr)
      {
        min = curr;
      }
    }

    swap(*start_range, *min);
  }
}

// insertion sort
//  n^2 worst/average, n best (already in order)
//  for each i, store j = i, increment j, find any smaller, swap left until sorted
template <class iter>
void insertion_sort(iter &begin, iter &end)
{
  for (iter i = begin; i < end; i++)
  {
    for (iter j = i + 1; j < end; j++)
    {
      if (*i > *j)
      {
        swap(*i, *j);

        for (j = i; j > begin; j--)
        {
          if (*j < *(j - 1))
          {
            swap(*j, *(j - 1));
          }
          else
          {
            break;
          }
        }

        break;
      }
    }
  }
}

// shellsort
//  n(log(n))^2 worst/average, n log(n) best
//  choose items that are h apart (stride length).
//  for instance = 9 items, h of 3 = 3 sublists
//  sublist 1 = {0, 3, 6}
//  sublist 2 = {1, 4, 7}
//  sublist 3 = {2, 5, 8}
//  insertion sort each one (called an h-sorting).
//  then h-sort with stride of 1 (standard insertion sort)
//  this reduces the over all swap count
//  the actual increment sequence for h is still being researched
//  knuth suggested 3x + 1, we'll go with that
template <class iter>
void shell_sort(iter &begin, iter &end)
{
  vector<size_t> strides{ 1 };
  size_t size = distance(begin, end);

  while ((3 * strides.back() + 1) < size)
  {
    strides.push_back(3 * strides.back() + 1);
  }

  for (auto h = strides.rbegin(); h < strides.rend(); h++)
  {
    // because non-1 strides are a bitch with checked iterators
    auto unchecked_begin = _Unchecked(begin);
    auto unchecked_end = _Unchecked(end);

    for (auto i = unchecked_begin; i < unchecked_end; i+=*h)
    {
      // left of i is already sorted
      for (auto j = (i + *h); j < unchecked_end; j+=*h)
      {
        if (*j < *i)
        {
          // start swapping back until we're in place
          swap(*j, *(j - *h));

          for (j = (j - *h); j > unchecked_begin; j -= *h)
          {
            if (*j < *(j - *h))
            {
              swap(*j, *(j - *h));
            }
            else
            {
              break;
            }
          }
        }
      }
    }
  }
}

// merge sort
//  n log(n) worst/average/best
//  dive array into two halves
//  recursively sort each half
//  merge two halves
template <class iter>
void merge_sort(iter &begin, iter &end)
{
  using val_type = std::iterator_traits<iter>::value_type;

  // divide
  // find midpoint
  size_t dis = distance(begin, end);

  if (dis <= 1) return;

  size_t mid = dis / 2;

  //cout << *begin << " to " << *(end - 1) << endl;

  // conquer
  // sort left and right halves
  merge_sort(begin, begin + mid);
  merge_sort(begin + mid, end);

  // merge
  //  i - first half index
  //  j - second half index
  //  k - index into sorted array
  // compare i and j, move smallest into k
  vector<val_type> aux(dis);
  iter i = begin;
  iter j = begin + mid;
  iter k = aux.begin();

  for (iter k = aux.begin(); k < aux.end(); k++)
  {
    if (j >= end)
    {
      std::copy(i, i + 1, k);
      i++;
    }
    else if (i >= (begin + mid))
    {
      std::copy(j, j + 1, k);
      j++;
    }
    else if (*i < *j)
    {
      std::copy(i, i + 1, k);
      i++;
    }
    else
    {
      std::copy(j, j + 1, k);
      j++;
    }
  }

  auto aux_begin = aux.begin();
  auto aux_end = aux.end();

  std::copy(aux_begin, aux_end, begin);
}

template<class iter>
void debug_sort(iter sorted_data, iter original_data)
{
  for (auto n : original_data)
  {
    cout << n << " ";
  }

  cout << endl;

  for (auto n : sorted_data)
  {
    cout << n << " ";
  }

  cout << endl;
  cout << "is permutation: ";
  cout << std::boolalpha << std::is_permutation(sorted_data.begin(), sorted_data.end(), original_data.begin());
  cout << endl;
  cout << "is sorted: ";
  cout << std::boolalpha << std::is_sorted(sorted_data.begin(), sorted_data.end());
  cout << endl;
}

SortData test_data(size_t input_size)
{
  std::random_device rd;
  std::mt19937 eng(rd());
  std::uniform_int_distribution<int> dis(0, 100);
  SortData data;

  for (size_t i = 0; i < input_size; i++)
  {
    data.push_back(dis(eng));
  }

  return data;
}

void time_sorts(AlgorithmList sort_functions = AlgorithmList({
  { "Selection Sort", &selection_sort<Iterator> },
  { "Insertion Sort", &insertion_sort<Iterator> },
  { "Shell Sort", &shell_sort<Iterator> },
  { "Merge Sort", &merge_sort<Iterator> }
}))
{
  constexpr size_t MAX_INPUT_SIZE = 400;
  constexpr size_t INPUT_STEP = 20;
  constexpr size_t ITERATION_COUNT = 25;

  vector<SortTimeEntry> sort_times;

  for (auto sort : sort_functions)
  {
    cout << "Start " << sort.first << endl;
    for (size_t input_size = 2; input_size < MAX_INPUT_SIZE; input_size += INPUT_STEP)
    {
      vector<double> iteration;
      SortData data = test_data(input_size);

      for (size_t i = 0; i < ITERATION_COUNT; i++)
      {
        auto start = high_resolution_clock::now();
        sort.second(data.begin(), data.end());
        std::chrono::duration<double> sort_time = high_resolution_clock::now() - start;
        iteration.push_back(sort_time.count());
      }

      for (auto i = iteration.begin(); i < iteration.end(); i++)
      {
        SortTime run_time{ input_size, *i };
        SortTimeEntry entry{ sort.first, run_time };
        sort_times.push_back(entry);
      }

      cout << input_size << " done." << endl;
    }
  }

  std::ofstream csv;
  csv.open("sort_times.csv");

  if (csv)
  {
    csv << "Algorithm,Input Size,Time Elapsed" << endl;
    for (auto time : sort_times)
    {
      csv << time.first << "," << time.second.first << "," << time.second.second << endl;
    }

    csv.close();

    cout << "CSV of time elapsed written" << endl;
  }
  else
  {
    cout << "Cannot open sort file" << endl;
  }
}

int main()
{
  time_sorts();

  cin.get();

  return 0;
}

<|endoftext|>


<commit_before>#ifndef CPPUT_TESTHARNESS_HPP
#define CPPUT_TESTHARNESS_HPP

///////////////////////////////////////////////////////////////////////////////
///
/// \brief    A light-weight and easy to use unit testing framework for C++
/// \details  Header-only unit testing framework that makes unit testing easy
///           and quick to set up.
/// \version  0.2.0
/// \date     December 2011
/// \author   Tommy Back
///
///
/// Simply include this header file to get started.
///
/// \code
/// #include <cpput/TestHarness.h>
/// #include <Foo.h>
///
/// TEST(Foo, some_descriptive_name)
/// {
///   // Arrange
///   Foo foo;
///   // Act
///   bool result = foo.isBar();
///   // Assert
///   ASSERT_TRUE(result);
/// }
/// \endcode
///
/// In case you want to keep a single file with tests that compile to an
/// executable you can also add the main function to the end of the file.
/// This is simple to do with the provided macro:
///
/// \code
/// CPPUT_TEST_MAIN;
/// \endcode
///
/// For larger test suits, it's recommended to group the tests per class
/// in separate files and let the compiler combine them into a single
/// executable which has a main.cpp file that only has the main function
/// declared.
///
/// \example
/// [Test_Foo.cpp]
///
/// \code
/// #include <cpput/TestHarness.h>
/// #include <Foo.h>
///
/// TEST(Foo, foo_bar_z)
/// {
///   ...
/// \endcode
///
/// [main.cpp]
///
/// \code
/// #include <cpput/TestHarness.h>
///
/// CPPUT_TEST_MAIN;
/// \endcode
///
///

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <sstream>
#include <ctime>

namespace cpput
{

struct Failure
{
  Failure(const std::string& filename, std::size_t line, const std::string& message)
    : filename_(filename)
    , line_(line)
    , message_(message)
  {
  }

  std::string filename_;
  std::size_t line_;
  std::string message_;
};

// ----------------------------------------------------------------------------

struct ResultWriter
{
  virtual ~ResultWriter() {}

  virtual void startTest(const std::string& className, const std::string& name) = 0;
  virtual void endTest(bool success) = 0;

  virtual void failure(const Failure& failure) = 0;
  virtual int getNumberOfFailures() const = 0;
};

// ----------------------------------------------------------------------------

class TextResultWriter : public ResultWriter
{
public:
  TextResultWriter()
    : testCount_(0)
  {
  }

  virtual ~TextResultWriter()
  {
    std::cout << "\n";
    if (failures_.empty())
    {
      std::cout << "All tests pass.\n";
      return;
    }
    // print details of all failures
    std::cout << "\n";
    for (std::size_t i=0; i<failures_.size(); ++i)
    {
      const Failure& f = failures_[i];
      std::cout << f.filename_ << ", line " << f.line_ << ": " << f.message_ << '\n';
    }
    std::cout << "\n" << failures_.size() << " out of " << testCount_ << " tests failed.\n";
  }

  virtual void startTest(const std::string&, const std::string&)
  {
    testCount_++;
  }

  virtual void endTest(bool success)
  {
    if (success)
      std::cout << '.';
    else
      std::cout << 'F';
  }

  virtual void failure(const Failure& failure)
  {
    failures_.push_back(failure);
  }

  virtual int getNumberOfFailures() const { return failures_.size(); }

private:
  int                  testCount_;
  std::vector<Failure> failures_;
};

// ----------------------------------------------------------------------------

class XmlResultWriter : public ResultWriter
{
public:
  XmlResultWriter()
    : startTime_(0)
  {
    std::cout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    std::cout << "<testsuite>\n";
  }

  virtual ~XmlResultWriter()
  {
    std::cout << "</testsuite>\n";
  }

  virtual void startTest(const std::string& className, const std::string& name)
  {
    startTime_ = std::clock();
    std::cout << "  <testcase classname=\""
              << className
              << "\" name=\""
              << name
              << "\" time=\"";
  }

  virtual void endTest(bool success)
  {
    if (success)
    {
      std::cout << static_cast<float>(std::clock()-startTime_)/CLOCKS_PER_SEC << "\"";
      std::cout << "/>\n";
    }
    else
      std::cout << "  </testcase>\n";
  }

  virtual void failure(const Failure& failure)
  {
    std::cout << static_cast<float>(std::clock()-startTime_)/CLOCKS_PER_SEC << "\"";
    std::cout << ">\n"
              << "    <failure>"
              << failure.message_
              << " in "
              << failure.filename_
              << ", line "
              << failure.line_
              << "</failure>\n";
    failureCount_++;
  }

  virtual int getNumberOfFailures() const
  {
    return failureCount_;
  }

private:
  std::clock_t startTime_;
  int          failureCount_;
};

// ----------------------------------------------------------------------------

struct Result
{
  Result(const std::string& testClassName,
         const std::string& testName,
         ResultWriter& out)
    : out_(out)
    , pass_(true)
  {
    out_.startTest(testClassName, testName);
  }

  ~Result()
  {
    out_.endTest(pass_);
  }

  template <typename T, typename U>
  void addFailure(const char* filename,
                  std::size_t line,
                  T expected,
                  U actual)
  {
    pass_ = false;
    std::stringstream ss;
    ss << std::setprecision(20)
       << "failed comparison, expected " << expected
       << " got " << actual << "\n";
    Failure f(filename, line, ss.str());
    out_.failure(f);
  }

  void addFailure(const char* filename,
                  std::size_t line,
                  const char* message)
  {
    pass_ = false;
    Failure f(filename, line, message);
    out_.failure(f);
  }

  ResultWriter& out_;
  bool        pass_;
};

// ----------------------------------------------------------------------------

class Repository;

class Case
{
  friend class Repository;

public:
  Case(const char* className, const char* name);
  virtual ~Case() {}

  void run(ResultWriter& out)
  {
    Result result(test_unit_class_name_, test_unit_name_, out);
    try
    {
      do_run(result);
    }
    catch (const std::exception& e)
    {
      result.addFailure(__FILE__, __LINE__, std::string("Unexpected exception: ").append(e.what()).c_str());
    }
    catch (...)
    {
      result.addFailure(__FILE__, __LINE__, "Unspecified exception!");
    }
  }

  Case* next() { return test_unit_next_; }

private:
  virtual void do_run(Result& testResult_) = 0;

private:
  std::string test_unit_class_name_;
  std::string test_unit_name_;
  Case*       test_unit_next_;
};

// ----------------------------------------------------------------------------

class Repository
{
public:
  static Repository& instance()
  {
    static Repository repo;
    return repo;
  }

  void add(Case* tc)
  {
    if (!cases_)
    {
      cases_ = tc;
      return;
    }

    // add as last
    Case* tmp = cases_;
    while (tmp->test_unit_next_)
      tmp = tmp->test_unit_next_;
    tmp->test_unit_next_ = tc;
  }

  Case* getCases() { return cases_; }

private:
  Repository() : cases_(0) {}
  Repository(const Repository& other);
  Repository& operator=(const Repository& rhs) const;

private:
  Case* cases_;
};

inline Case::Case(const char* className, const char* name)
  : test_unit_class_name_(className)
  , test_unit_name_(name)
  , test_unit_next_(0)
{
  Repository::instance().add(this);
}

// ----------------------------------------------------------------------------

inline int runAllTests(ResultWriter& writer)
{
  Case* c = Repository::instance().getCases();
  while (c)
  {
    c->run(writer);
    c = c->next();
  }
  return writer.getNumberOfFailures();
}

} // namespace cpput

// Convenience macro to get main function.
#define CPPUT_TEST_MAIN                               \
int main(int argc, char* argv[]) {                    \
  if (argc == 2 && std::string(argv[1]) == "--xml") { \
    cpput::XmlResultWriter writer;                    \
    return ::cpput::runAllTests(writer);              \
  }                                                   \
  cpput::TextResultWriter writer;                     \
  return ::cpput::runAllTests(writer);                \
}

// ----------------------------------------------------------------------------
// Test Case Macros
// ----------------------------------------------------------------------------

/// Stand-alone test case.
///
#define TEST(group,name) \
class group##name##Test : public cpput::Case \
{ \
public: \
  group##name##Test() : cpput::Case(#group,#name) {} \
  virtual ~group##name##Test() {} \
private: \
  virtual void do_run(cpput::Result& testResult_); \
} group##name##TestInstance; \
inline void group##name##Test::do_run(cpput::Result& testResult_)

/// Test case with fixture.
///
#define TEST_F(group,name) \
class group##name##FixtureTest : public group { \
public: \
    void do_run(cpput::Result& testResult_); \
}; \
class group##name##Test : public cpput::Case { \
public: \
    group##name##Test() : Case(#group,#name) {} \
    virtual void do_run(cpput::Result& testResult_); \
} group##name##TestInstance; \
inline void group##name##Test::do_run(cpput::Result& testResult_) { \
  group##name##FixtureTest test; \
  test.do_run(testResult_); \
} \
inline void group##name##FixtureTest::do_run(cpput::Result& testResult_)

// ----------------------------------------------------------------------------
// Assertion Macros
// ----------------------------------------------------------------------------

#define ASSERT_TRUE(expression) \
{ \
  if (expression) \
    return; \
  testResult_.addFailure(__FILE__, __LINE__, #expression); \
}

#define ASSERT_FALSE(expression) ASSERT_TRUE(!(expression))

#define ASSERT_EQ(expected,actual) \
{ \
  if (!((expected) == (actual))) \
  { \
    testResult_.addFailure(__FILE__, __LINE__, expected, actual); \
    return; \
  } \
}

#define ASSERT_NEQ(expected,actual) \
{ \
  if (((expected) == (actual))) \
  { \
    testResult_.addFailure(__FILE__, __LINE__, expected, actual); \
    return; \
  } \
}

#define ASSERT_STREQ(expected,actual) { \
  if (!(std::string(expected) == std::string(actual))) \
  { \
    testResult_.addFailure(__FILE__, __LINE__, expected, actual); \
    return; \
  } \
}

#define ASSERT_NEAR(expected,actual,epsilon) \
{ \
  double actualTmp = actual; \
  double expectedTmp = expected; \
  double diff = expectedTmp - actualTmp; \
  if ((diff > epsilon) || (-diff > epsilon)) \
  { \
    testResult_.addFailure(__FILE__, __LINE__, expectedTmp, actualTmp); \
    return; \
  } \
}

#endif // CPPUT_TESTHARNESS_HPP
<commit_msg>Removed Failure class.<commit_after>#ifndef CPPUT_TESTHARNESS_HPP
#define CPPUT_TESTHARNESS_HPP

///////////////////////////////////////////////////////////////////////////////
///
/// \brief    A light-weight and easy to use unit testing framework for C++
/// \details  Header-only unit testing framework that makes unit testing easy
///           and quick to set up.
/// \version  0.2.0
/// \date     December 2011
/// \author   Tommy Back
///
///
/// Simply include this header file to get started.
///
/// \code
/// #include <cpput/TestHarness.h>
/// #include <Foo.h>
///
/// TEST(Foo, some_descriptive_name)
/// {
///   // Arrange
///   Foo foo;
///   // Act
///   bool result = foo.isBar();
///   // Assert
///   ASSERT_TRUE(result);
/// }
/// \endcode
///
/// In case you want to keep a single file with tests that compile to an
/// executable you can also add the main function to the end of the file.
/// This is simple to do with the provided macro:
///
/// \code
/// CPPUT_TEST_MAIN;
/// \endcode
///
/// For larger test suits, it's recommended to group the tests per class
/// in separate files and let the compiler combine them into a single
/// executable which has a main.cpp file that only has the main function
/// declared.
///
/// \example
/// [Test_Foo.cpp]
///
/// \code
/// #include <cpput/TestHarness.h>
/// #include <Foo.h>
///
/// TEST(Foo, foo_bar_z)
/// {
///   ...
/// \endcode
///
/// [main.cpp]
///
/// \code
/// #include <cpput/TestHarness.h>
///
/// CPPUT_TEST_MAIN;
/// \endcode
///
///

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <ctime>

namespace cpput
{

struct ResultWriter
{
  virtual ~ResultWriter() {}

  virtual void startTest(const std::string& className, const std::string& name) = 0;
  virtual void endTest(bool success) = 0;

  virtual void failure(const std::string& filename, std::size_t line, const std::string& message) = 0;
  virtual int getNumberOfFailures() const = 0;
};

// ----------------------------------------------------------------------------

class TextResultWriter : public ResultWriter
{
public:
  TextResultWriter()
    : testCount_(0)
    , failures_(0)
  {
  }

  virtual ~TextResultWriter()
  {
    if (failures_ == 0)
    {
      std::cout << "\nAll tests pass.\n";
      return;
    }
    else
    {
      std::cout << "\n" << failures_ << " out of " << testCount_ << " tests failed.\n";
    }
  }

  virtual void startTest(const std::string&, const std::string&)
  {
    testCount_++;
  }

  virtual void endTest(bool success)
  {
    if (success)
      std::cout << '.';
    else
      std::cout << 'F';
  }

  virtual void failure(const std::string& filename, std::size_t line, const std::string& message)
  {
    failures_++;
    std::cout << "Failure: " << filename << ", line " << line << ": " << message << '\n';
  }

  virtual int getNumberOfFailures() const { return failures_; }

private:
  int testCount_;
  int failures_;
};

// ----------------------------------------------------------------------------

class XmlResultWriter : public ResultWriter
{
public:
  XmlResultWriter()
    : startTime_(0)
  {
    std::cout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    std::cout << "<testsuite>\n";
  }

  virtual ~XmlResultWriter()
  {
    std::cout << "</testsuite>\n";
  }

  virtual void startTest(const std::string& className, const std::string& name)
  {
    startTime_ = std::clock();
    std::cout << "  <testcase classname=\""
              << className
              << "\" name=\""
              << name
              << "\" time=\"";
  }

  virtual void endTest(bool success)
  {
    if (success)
    {
      std::cout << static_cast<float>(std::clock()-startTime_)/CLOCKS_PER_SEC << "\"";
      std::cout << "/>\n";
    }
    else
      std::cout << "  </testcase>\n";
  }

  virtual void failure(const std::string& filename, std::size_t line, const std::string& message)
  {
    std::cout << static_cast<float>(std::clock()-startTime_)/CLOCKS_PER_SEC << "\"";
    std::cout << ">\n"
              << "    <failure>"
              << message
              << " in "
              << filename
              << ", line "
              << line
              << "</failure>\n";
    failureCount_++;
  }

  virtual int getNumberOfFailures() const
  {
    return failureCount_;
  }

private:
  std::clock_t startTime_;
  int          failureCount_;
};

// ----------------------------------------------------------------------------

struct Result
{
  Result(const std::string& testClassName,
         const std::string& testName,
         ResultWriter& out)
    : out_(out)
    , pass_(true)
  {
    out_.startTest(testClassName, testName);
  }

  ~Result()
  {
    out_.endTest(pass_);
  }

  template <typename T, typename U>
  void addFailure(const char* filename,
                  std::size_t line,
                  T expected,
                  U actual)
  {
    pass_ = false;
    std::stringstream ss;
    ss << std::setprecision(20)
       << "failed comparison, expected " << expected
       << " got " << actual << "\n";
    out_.failure(filename, line, ss.str());
  }

  void addFailure(const char* filename,
                  std::size_t line,
                  const char* message)
  {
    pass_ = false;
    out_.failure(filename, line, message);
  }

  ResultWriter& out_;
  bool          pass_;
};

// ----------------------------------------------------------------------------

class Repository;

class Case
{
  friend class Repository;

public:
  Case(const char* className, const char* name);
  virtual ~Case() {}

  void run(ResultWriter& out)
  {
    Result result(test_unit_class_name_, test_unit_name_, out);
    try
    {
      do_run(result);
    }
    catch (const std::exception& e)
    {
      result.addFailure(__FILE__, __LINE__, std::string("Unexpected exception: ").append(e.what()).c_str());
    }
    catch (...)
    {
      result.addFailure(__FILE__, __LINE__, "Unspecified exception!");
    }
  }

  Case* next() { return test_unit_next_; }

private:
  virtual void do_run(Result& testResult_) = 0;

private:
  std::string test_unit_class_name_;
  std::string test_unit_name_;
  Case*       test_unit_next_;
};

// ----------------------------------------------------------------------------

class Repository
{
public:
  static Repository& instance()
  {
    static Repository repo;
    return repo;
  }

  void add(Case* tc)
  {
    if (!cases_)
    {
      cases_ = tc;
      return;
    }

    // add as last
    Case* tmp = cases_;
    while (tmp->test_unit_next_)
      tmp = tmp->test_unit_next_;
    tmp->test_unit_next_ = tc;
  }

  Case* getCases() { return cases_; }

private:
  Repository() : cases_(0) {}
  Repository(const Repository& other);
  Repository& operator=(const Repository& rhs) const;

private:
  Case* cases_;
};

inline Case::Case(const char* className, const char* name)
  : test_unit_class_name_(className)
  , test_unit_name_(name)
  , test_unit_next_(0)
{
  Repository::instance().add(this);
}

// ----------------------------------------------------------------------------

inline int runAllTests(ResultWriter& writer)
{
  Case* c = Repository::instance().getCases();
  while (c)
  {
    c->run(writer);
    c = c->next();
  }
  return writer.getNumberOfFailures();
}

} // namespace cpput

// Convenience macro to get main function.
#define CPPUT_TEST_MAIN                               \
int main(int argc, char* argv[]) {                    \
  if (argc == 2 && std::string(argv[1]) == "--xml") { \
    cpput::XmlResultWriter writer;                    \
    return ::cpput::runAllTests(writer);              \
  }                                                   \
  cpput::TextResultWriter writer;                     \
  return ::cpput::runAllTests(writer);                \
}

// ----------------------------------------------------------------------------
// Test Case Macros
// ----------------------------------------------------------------------------

/// Stand-alone test case.
///
#define TEST(group,name) \
class group##name##Test : public cpput::Case \
{ \
public: \
  group##name##Test() : cpput::Case(#group,#name) {} \
  virtual ~group##name##Test() {} \
private: \
  virtual void do_run(cpput::Result& testResult_); \
} group##name##TestInstance; \
inline void group##name##Test::do_run(cpput::Result& testResult_)

/// Test case with fixture.
///
#define TEST_F(group,name) \
class group##name##FixtureTest : public group { \
public: \
    void do_run(cpput::Result& testResult_); \
}; \
class group##name##Test : public cpput::Case { \
public: \
    group##name##Test() : Case(#group,#name) {} \
    virtual void do_run(cpput::Result& testResult_); \
} group##name##TestInstance; \
inline void group##name##Test::do_run(cpput::Result& testResult_) { \
  group##name##FixtureTest test; \
  test.do_run(testResult_); \
} \
inline void group##name##FixtureTest::do_run(cpput::Result& testResult_)

// ----------------------------------------------------------------------------
// Assertion Macros
// ----------------------------------------------------------------------------

#define ASSERT_TRUE(expression) \
{ \
  if (expression) \
    return; \
  testResult_.addFailure(__FILE__, __LINE__, #expression); \
}

#define ASSERT_FALSE(expression) ASSERT_TRUE(!(expression))

#define ASSERT_EQ(expected,actual) \
{ \
  if (!((expected) == (actual))) \
  { \
    testResult_.addFailure(__FILE__, __LINE__, expected, actual); \
    return; \
  } \
}

#define ASSERT_NEQ(expected,actual) \
{ \
  if (((expected) == (actual))) \
  { \
    testResult_.addFailure(__FILE__, __LINE__, expected, actual); \
    return; \
  } \
}

#define ASSERT_STREQ(expected,actual) { \
  if (!(std::string(expected) == std::string(actual))) \
  { \
    testResult_.addFailure(__FILE__, __LINE__, expected, actual); \
    return; \
  } \
}

#define ASSERT_NEAR(expected,actual,epsilon) \
{ \
  double actualTmp = actual; \
  double expectedTmp = expected; \
  double diff = expectedTmp - actualTmp; \
  if ((diff > epsilon) || (-diff > epsilon)) \
  { \
    testResult_.addFailure(__FILE__, __LINE__, expectedTmp, actualTmp); \
    return; \
  } \
}

#endif // CPPUT_TESTHARNESS_HPP
<|endoftext|>