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

#include "receivecoinsdialog.h"
#include "ui_receivecoinsdialog.h"

#include "addressbookpage.h"
#include "addresstablemodel.h"
#include "bitcoinunits.h"
#include "guiutil.h"
#include "optionsmodel.h"
#include "platformstyle.h"
#include "receiverequestdialog.h"
#include "recentrequeststablemodel.h"
#include "walletmodel.h"
#include "transactiontablemodel.h"
#include "validation.h"
#include "init.h"
#include "clientmodel.h"

#include <string>
#include <QAction>
#include <QCursor>
#include <QItemSelection>
#include <QMessageBox>
#include <QScrollBar>
#include <QTextDocument>
#include <QCompleter>
#include <boost/foreach.hpp>
#include <boost/thread.hpp>

using std::string;
extern QString gStrSafe;
extern boost::thread_group *g_threadGroup;

CCriticalSection cs_receive;

void RefreshReceiveCoinsData(ReceiveCoinsDialog* receiveCoinsDialog)
{
	SetThreadPriority(THREAD_PRIORITY_LOWEST);
	RenameThread("RefreshReceiveCoinsData");
	while (true)
	{
		boost::this_thread::interruption_point();

		std::vector<uint256>  assetIdVec;
		if (receiveCoinsDialog->bFirstInit)
		{
			receiveCoinsDialog->bFirstInit = false;
			GetAssetListInfo(assetIdVec);
		}

		{
			LOCK(cs_receive);

			while (!receiveCoinsDialog->assetToUpdate.isEmpty())
			{
				uint256 assetId = receiveCoinsDialog->assetToUpdate.pop();
				assetIdVec.push_back(assetId);
			}
		}

		if (assetIdVec.size() <= 0)
		{
			MilliSleep(1000);
			continue;
		}

		QMap<QString, CAssetId_AssetInfo_IndexValue> mapAssetInfo;

		BOOST_FOREACH(const uint256& assetId, assetIdVec)
		{
			boost::this_thread::interruption_point();
			if (assetId.IsNull())
			{
				continue;
			}

			CAssetId_AssetInfo_IndexValue assetInfo;
			if (!GetAssetInfoByAssetId(assetId, assetInfo))
			{
				continue;
			}

			QString assetName = QString::fromStdString(assetInfo.assetData.strAssetName);
			mapAssetInfo.insert(assetName, assetInfo);
		}

		assetIdVec.clear();
		Q_EMIT receiveCoinsDialog->refreshAssetsInfo(mapAssetInfo);

		MilliSleep(1000);
	}
}

static void AssetFound(ReceiveCoinsDialog* receive, const std::vector<uint256> &vtNewAssetId)
{
	QMetaObject::invokeMethod(receive, "updateAssetsFound", Qt::QueuedConnection,	Q_ARG(std::vector<uint256>, vtNewAssetId));
}

ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ReceiveCoinsDialog),
    columnResizingFixer(0),
    clientModel(0),
    model(0),
    platformStyle(platformStyle)
{
    ui->setupUi(this);
    QString theme = GUIUtil::getThemeName();

    if (!platformStyle->getImagesOnButtons()) {
        ui->clearButton->setIcon(QIcon());
        ui->receiveButton->setIcon(QIcon());
        ui->showRequestButton->setIcon(QIcon());
        ui->removeRequestButton->setIcon(QIcon());
    } else {
        ui->clearButton->setIcon(QIcon(":/icons/" + theme + "/remove"));
        ui->receiveButton->setIcon(QIcon(":/icons/" + theme + "/receiving_addresses"));
        ui->showRequestButton->setIcon(QIcon(":/icons/" + theme + "/edit"));
        ui->removeRequestButton->setIcon(QIcon(":/icons/" + theme + "/remove"));
    }

    // context menu actions
    QAction *copyURIAction = new QAction(tr("Copy URI"), this);
    QAction *copyLabelAction = new QAction(tr("Copy label"), this);
    QAction *copyMessageAction = new QAction(tr("Copy message"), this);
    QAction *copyAmountAction = new QAction(tr("Copy amount"), this);

    // context menu
    contextMenu = new QMenu(this);
    contextMenu->addAction(copyURIAction);
    contextMenu->addAction(copyLabelAction);
    contextMenu->addAction(copyMessageAction);
    contextMenu->addAction(copyAmountAction);
    contextMenu->setStyleSheet("font-size:12px;");

    //addSafeToCombox();

    // context menu signals
    connect(ui->recentRequestsView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint)));
    connect(copyURIAction, SIGNAL(triggered()), this, SLOT(copyURI()));
    connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
    connect(copyMessageAction, SIGNAL(triggered()), this, SLOT(copyMessage()));
    connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));

    connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
    connect(ui->reqLabel, SIGNAL(textChanged(QString)), this, SLOT(on_reqLabel_textChanged(QString)));
    connect(ui->reqMessage, SIGNAL(textChanged(QString)), this, SLOT(on_reqMessage_textChanged(QString)));
    fAssets = false;
    assetDecimal = 0;
    strAssetUnit = "";
	bFirstInit = true;

    completer = new QCompleter;
    stringListModel = new QStringListModel;

    completer->setCaseSensitivity(Qt::CaseInsensitive);
    completer->setCompletionMode(QCompleter::PopupCompletion);
    completer->setModel(stringListModel);
    completer->popup()->setStyleSheet("font: 12px;");
    ui->assetsComboBox->setCompleter(completer);
    ui->assetsComboBox->setEditable(true);
    ui->assetsComboBox->setStyleSheet("QComboBox{background-color:#FFFFFF;border:1px solid #82C3E6;font-size:12px;}");
    ui->assetsComboBox->addItem(gStrSafe);
    setMouseTracking(true);
    ui->frame->setMouseTracking(true);
    ui->frame2->setMouseTracking(true);

    QRegExp regExpReqLabelEdit;
    regExpReqLabelEdit.setPattern("[a-zA-Z\u4e00-\u9fa5][a-zA-Z0-9-+*/。，$%^&*,!?.()#_\u4e00-\u9fa5 ]{1,150}");
    ui->reqLabel->setValidator (new QRegExpValidator(regExpReqLabelEdit, this));
    QRegExp regExpReqMessageEdit;
    regExpReqMessageEdit.setPattern("[a-zA-Z\u4e00-\u9fa5][a-zA-Z0-9-+*/。，$%^&*,!?.()#_\u4e00-\u9fa5 ]{1,150}");
    ui->reqMessage->setValidator (new QRegExpValidator(regExpReqMessageEdit, this));
    initWidget();

	qRegisterMetaType<QMap<QString, CAssetId_AssetInfo_IndexValue> >("QMap<QString, CAssetId_AssetInfo_IndexValue>");
    qRegisterMetaType<std::vector<uint256> >("std::vector<uint256>");

    connect(this,SIGNAL(refreshAssetsInfo(QMap<QString, CAssetId_AssetInfo_IndexValue>)),this,SLOT(updateAssetsInfo(QMap<QString, CAssetId_AssetInfo_IndexValue>)));
    connect(ui->assetsComboBox,SIGNAL(currentIndexChanged(const QString&)),this,SLOT(updateCurrentAsset(const QString&)));
    if(g_threadGroup)
        g_threadGroup->create_thread(boost::bind(&RefreshReceiveCoinsData, this));

	uiInterface.AssetFound.connect(boost::bind(AssetFound, this, _1));
}

void ReceiveCoinsDialog::initWidget()
{
#if QT_VERSION >= 0x040700
    ui->reqLabel->setPlaceholderText(tr("Maximum 30 characters"));
    ui->reqMessage->setPlaceholderText(tr("Maximum 150 characters"));
#endif
}

ReceiveCoinsDialog::~ReceiveCoinsDialog()
{
	uiInterface.AssetFound.disconnect(boost::bind(AssetFound, this, _1));

    delete ui;
}

void ReceiveCoinsDialog::updateCurrentAsset(const QString &currText)
{
    if(currText==gStrSafe)
    {
        fAssets = false;
    }
    else
    {
        fAssets = true;
        if(!assetDataMap.contains(currText))
            return;
    }
    ui->checkUseInstantSend->setVisible(!fAssets);
    if(fAssets)
    {
        if(assetDataMap.contains(currText))
        {
            CAssetData& assetData = assetDataMap[currText];
            assetDecimal = assetData.nDecimals;
            strAssetUnit = QString::fromStdString(assetData.strAssetUnit);
        }
    }
    ui->reqAmount->updateAssetUnit(strAssetUnit,fAssets,assetDecimal);
}

void ReceiveCoinsDialog::updateAssetsFound(std::vector<uint256> vtNewAssetId)
{
    LOCK(cs_receive);
	for (int i = 0; i < vtNewAssetId.size(); i++)
	{
		assetToUpdate.push_back(vtNewAssetId[i]);
	}
}

void ReceiveCoinsDialog::updateAssetsInfo(QMap<QString, CAssetId_AssetInfo_IndexValue> mapAssetInfo)
{
	QMap<QString, CAssetId_AssetInfo_IndexValue>::iterator it = mapAssetInfo.begin();
	while (it != mapAssetInfo.end())
	{
		if (!assetDataMap.contains(it.key()))
		{
			assetDataMap.insert(it.key(), it.value().assetData);
		}

		it++;
	}

	QStringList listTemp;
	const QStringList &listNew = mapAssetInfo.keys();

	for (int i = 0; i < listNew.count(); i++)
	{
		if (ui->assetsComboBox->findText(listNew[i]) < 0)
		{
			listTemp.push_back(listNew[i]);
		}
	}

	if (listTemp.count() > 0)
	{
		stringListModel->setStringList(listTemp);
		ui->assetsComboBox->addItems(listTemp);
	}
}

void ReceiveCoinsDialog::setModel(WalletModel *model)
{
    this->model = model;

    if(model && model->getOptionsModel())
    {
        model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
        connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
        updateDisplayUnit();

        QTableView* tableView = ui->recentRequestsView;

        tableView->verticalHeader()->hide();
        tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        tableView->setModel(model->getRecentRequestsTableModel());
        tableView->setAlternatingRowColors(true);
        tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
        tableView->setSelectionMode(QAbstractItemView::ContiguousSelection);
        tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH);
        tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH);

        connect(tableView->selectionModel(),
            SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
            SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection)));
        // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready.
        columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);
    }
}

void ReceiveCoinsDialog::setClientModel(ClientModel *clientModel)
{
    this->clientModel = clientModel;
}

void ReceiveCoinsDialog::clear()
{
    ui->reqAmount->clear();
    ui->reqLabel->setText("");
    ui->reqMessage->setText("");
    ui->reuseAddress->setChecked(false);
    updateDisplayUnit();
}

void ReceiveCoinsDialog::reject()
{
    clear();
}

void ReceiveCoinsDialog::accept()
{
    clear();
}

void ReceiveCoinsDialog::updateDisplayUnit()
{
    if(model && model->getOptionsModel())
    {
        ui->reqAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
    }
}

void ReceiveCoinsDialog::on_reqLabel_textChanged(const QString &address)
{
    while(ui->reqLabel->text().trimmed().toStdString().size() > 30)
        ui->reqLabel->setText(ui->reqLabel->text().left(ui->reqLabel->text().trimmed().length()-1));
}

void ReceiveCoinsDialog::on_reqMessage_textChanged(const QString &address)
{
    while(ui->reqMessage->text().trimmed().toStdString().size() > 150)
        ui->reqMessage->setText(ui->reqMessage->text().left(ui->reqMessage->text().trimmed().length()-1));
}

void ReceiveCoinsDialog::on_receiveButton_clicked()
{
    if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
        return;

    string strreqLabel =ui->reqLabel->text().trimmed().toStdString();
    if(strreqLabel.size() > 30)
    {
        QMessageBox::warning(this, tr("Receive"),tr("Label input too long"),tr("Ok"));
        return;
    }

    string strreqMessage =ui->reqMessage->text().trimmed().toStdString();
    if(strreqMessage.size() > 150)
    {
        QMessageBox::warning(this, tr("Receive"),tr("Message input too long"),tr("Ok"));
        return;
    }

    QString currText = ui->assetsComboBox->currentText().trimmed();
    if(currText.isEmpty())
    {
        QMessageBox::warning(this, tr("Receive"),tr("Please select asset"),tr("Ok"));
        return;
    }
    int index = ui->assetsComboBox->findText(currText);
    if(index<0)
    {
        QMessageBox::warning(this,tr("Receive"),tr("Invalid asset name"),tr("Ok"));
        return;
    }

    QString address;
    QString label = ui->reqLabel->text();
    if(ui->reuseAddress->isChecked())
    {
        /* Choose existing receiving address */
        AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
        dlg.setModel(model->getAddressTableModel());
        if(dlg.exec())
        {
            address = dlg.getReturnValue();
            if(label.isEmpty()) /* If no label provided, use the previously used label */
            {
                label = model->getAddressTableModel()->labelForAddress(address);
            }
        } else {
            return;
        }
    } else {
        /* Generate new receiving address */
        address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "");
    }
    SendCoinsRecipient info(address, label,ui->reqAmount->value(), 0, ui->reqMessage->text(),"",fAssets,ui->assetsComboBox->currentText().trimmed(),assetDecimal,strAssetUnit);
    if(fAssets)
        info.fUseInstantSend = false;
    else
        info.fUseInstantSend = ui->checkUseInstantSend->isChecked();
    info.fAsset = fAssets;
    ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setModel(model->getOptionsModel());
    dialog->setInfo(info);
    dialog->show();
    clear();

    /* Store request for later reference */
    model->getRecentRequestsTableModel()->addNewRequest(info);
}

void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &index)
{
    const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
    ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
    dialog->setModel(model->getOptionsModel());
    dialog->setInfo(submodel->entry(index.row()).recipient);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->show();
}

void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
    // Enable Show/Remove buttons only if anything is selected.
    bool enable = !ui->recentRequestsView->selectionModel()->selectedRows().isEmpty();
    ui->showRequestButton->setEnabled(enable);
    ui->removeRequestButton->setEnabled(enable);
}

void ReceiveCoinsDialog::on_showRequestButton_clicked()
{
    if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
        return;
    QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();

    Q_FOREACH (const QModelIndex& index, selection) {
        on_recentRequestsView_doubleClicked(index);
    }
}

void ReceiveCoinsDialog::on_removeRequestButton_clicked()
{
    if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
        return;
    QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
    if(selection.empty())
        return;
    // correct for selection mode ContiguousSelection
    QModelIndex firstIndex = selection.at(0);
    model->getRecentRequestsTableModel()->removeRows(firstIndex.row(), selection.length(), firstIndex.parent());
}

// We override the virtual resizeEvent of the QWidget to adjust tables column
// sizes as the tables width is proportional to the dialogs width.
void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message);
}

void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Return)
    {
        // press return -> submit form
        if (ui->reqLabel->hasFocus() || ui->reqAmount->hasFocus() || ui->reqMessage->hasFocus())
        {
            event->ignore();
            on_receiveButton_clicked();
            return;
        }
    }

    this->QDialog::keyPressEvent(event);
}

QModelIndex ReceiveCoinsDialog::selectedRow()
{
    if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
        return QModelIndex();
    QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
    if(selection.empty())
        return QModelIndex();
    // correct for selection mode ContiguousSelection
    QModelIndex firstIndex = selection.at(0);
    return firstIndex;
}

// copy column of selected row to clipboard
void ReceiveCoinsDialog::copyColumnToClipboard(int column)
{
    QModelIndex firstIndex = selectedRow();
    if (!firstIndex.isValid()) {
        return;
    }
    GUIUtil::setClipboard(model->getRecentRequestsTableModel()->data(firstIndex.child(firstIndex.row(), column), Qt::EditRole).toString());
}

// context menu
void ReceiveCoinsDialog::showMenu(const QPoint &point)
{
    if (!selectedRow().isValid()) {
        return;
    }
    contextMenu->exec(QCursor::pos());
}

// context menu action: copy URI
void ReceiveCoinsDialog::copyURI()
{
    QModelIndex sel = selectedRow();
    if (!sel.isValid()) {
        return;
    }

    const RecentRequestsTableModel * const submodel = model->getRecentRequestsTableModel();
    const QString uri = GUIUtil::formatBitcoinURI(submodel->entry(sel.row()).recipient);
    GUIUtil::setClipboard(uri);
}

// context menu action: copy label
void ReceiveCoinsDialog::copyLabel()
{
    copyColumnToClipboard(RecentRequestsTableModel::Label);
}

// context menu action: copy message
void ReceiveCoinsDialog::copyMessage()
{
    copyColumnToClipboard(RecentRequestsTableModel::Message);
}

// context menu action: copy amount
void ReceiveCoinsDialog::copyAmount()
{
    copyColumnToClipboard(RecentRequestsTableModel::Amount);
}

void ReceiveCoinsDialog::addSafeToCombox()
{
	QStringList stringList;
	stringList.append(gStrSafe);

	stringListModel->setStringList(stringList);
	ui->assetsComboBox->addItems(stringList);
}

void ReceiveCoinsDialog::clearData()
{
	bFirstInit = true;
}

max_stars_repo_name: SAFE-anwang/safe

max_issues_repo_name: SAFE-anwang/safe

max_forks_repo_name: CryptoCoinLab/safe


text:
//==================================================================================================
/**
  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
**/
//==================================================================================================
#include <boost/simd/function/shuffle.hpp>
#include <boost/simd/function/deinterleave_first.hpp>
#include <boost/simd/function/deinterleave_second.hpp>
#include <boost/simd/constant/valmin.hpp>
#include <boost/simd/constant/valmax.hpp>
#include <boost/simd/pack.hpp>
#include <simd_test.hpp>

namespace bs = boost::simd;

STF_CASE_TPL( "deinterleave shuffle with front 0s", STF_NUMERIC_TYPES)
{
  // cardinal 2
  {
    bs::pack<T,2> a{ bs::Valmax<T>(), T(42) };
    bs::pack<T,2> b{ T(13), bs::Valmin<T>() };
    bs::pack<T,2> z(0);

    STF_ALL_EQUAL( (bs::shuffle<-1,2>(a,b)), (bs::deinterleave_first (z,b)) );
    STF_ALL_EQUAL( (bs::shuffle<-1,3>(a,b)), (bs::deinterleave_second(z,b)) );
    STF_ALL_EQUAL( (bs::shuffle<-1,0>(a,b)), (bs::deinterleave_first (z,a)) );
    STF_ALL_EQUAL( (bs::shuffle<-1,1>(a,b)), (bs::deinterleave_second(z,a)) );
  }

 // cardinal 4
  {
    bs::pack<T,4> a{ bs::Valmax<T>(), T(42), T(69), bs::Valmin<T>() };
    bs::pack<T,4> b{ T(13), bs::Valmin<T>(), T(37), bs::Valmax<T>() };
    bs::pack<T,4> z(0);

    STF_ALL_EQUAL( (bs::shuffle<-1,-1,4,6>(a,b)), (bs::deinterleave_first (z,b)) );
    STF_ALL_EQUAL( (bs::shuffle<-1,-1,5,7>(a,b)), (bs::deinterleave_second(z,b)) );
    STF_ALL_EQUAL( (bs::shuffle<-1,-1,0,2>(a,b)), (bs::deinterleave_first (z,a)) );
    STF_ALL_EQUAL( (bs::shuffle<-1,-1,1,3>(a,b)), (bs::deinterleave_second(z,a)) );
  }

  // cardinal 8
  {
    bs::pack<T,8> a { bs::Valmax<T>(),T(66),T(99),T(55), T(-1),T(77), T(23), bs::Valmin<T>()};
    bs::pack<T,8> b{ T(13), bs::Valmin<T>(), T(37), bs::Valmax<T>(), T(54),T(13),T(37),T(69) };
    bs::pack<T,8> z(0);

    STF_ALL_EQUAL( (bs::shuffle<-1,-1,-1,-1,8,10,12,14>(a,b)), (bs::deinterleave_first(z,b)) );
    STF_ALL_EQUAL( (bs::shuffle<-1,-1,-1,-1,9,11,13,15>(a,b)), (bs::deinterleave_second(z,b)) );
    STF_ALL_EQUAL( (bs::shuffle<-1,-1,-1,-1,0,2,4,6>(a,b)), (bs::deinterleave_first (z,a)) );
    STF_ALL_EQUAL( (bs::shuffle<-1,-1,-1,-1,1,3,5,7>(a,b)), (bs::deinterleave_second(z,a)) );
  }
}

ext: cpp


text:
#pragma once
#include <Eigen/Dense>
#include <fstream>
#include <iostream>
#include <list>
#include <string>
#include <iomanip>
#include <limits>
#include <vector>
#include "interpolator.hpp"
#include "system.hpp"
#include "rksolver.hpp"
#include "wkbsolver.hpp"

/** A class to store all information related to a numerical solution run.  */
class Solution
{
    private:
    double t, tf, rtol, atol, h0;
    std::complex<double> x, dx;
    int order;
    const char* fo;
    WKBSolver * wkbsolver;
    WKBSolver1 wkbsolver1;
    WKBSolver2 wkbsolver2;
    WKBSolver3 wkbsolver3;
    /** A \a de_system object to carry information about the ODE. */
    de_system *de_sys_;
    /** These define the event at which integration finishes (currently: when tf
     * is reached. */
    double fend, fnext;
    /** a boolean encoding the direction of integration: 1/True for forward. */
    bool sign;

    public:
    Solution(de_system &de_sys, std::complex<double> x0, std::complex<double>
    dx0, double t_i, double t_f, int o=3, double r_tol=1e-4, double a_tol=0.0,
    double h_0=1, const char* full_output="");

    template<typename X = double> Solution(de_system &de_sys,
    std::complex<double> x0, std::complex<double> dx0, double t_i, double t_f,
    const X &do_times, int o=3, double r_tol=1e-4, double a_tol=0.0,
    double h_0=1, const char* full_output="");

    void solve();

    /** Object to call RK steps */
    RKSolver rksolver;

    /** Successful, total attempted, and successful WKB steps the solver took,
     * respectively  */
    int ssteps,totsteps,wkbsteps;
    /** Lists to contain the solution and its derivative evaluated at internal
     * points taken by the solver (i.e. not dense output) after a run */
    std::list<std::complex<double>> sol, dsol;
    /** List to contain the timepoints at which the solution and derivative are
     * internally evaluated by the solver */
    std::list<double> times;
    /** List to contain the "type" of each step (RK/WKB) taken internally by the
     * solver after a run */
    std::list<bool> wkbs;
    /** Lists to contain the timepoints at which dense output was evaluated */
    std::list<double> dotimes, dotimes_rk;
    /** Lists to contain the dense output of the solution and its derivative */
    std::list<std::complex<double>> dosol, dodsol, dosol_rk, dodsol_rk;
    /** Iterator to iterate over the dense output timepoints, for when these
     * need to be written out to file */
    std::list<double>::iterator dotit;

};

/** Constructor for when dense output was not requested. Sets up solution of the
 * ODE.
 *
 * @param[in] de_sys de_system object carrying information about the ODE being
 * solved
 * @param[in] x0, dx0 initial conditions for the ODE, \f$ x(t) \f$, \f$ \frac{dx}{dt} \f$ evaluated at
 * the start of the integration range
 * @param[in] t_i start of integration range
 * @param[in] t_f end of integration range
 * @param[in] o order of WKB approximation to be used
 * @param[in] r_tol (local) relative tolerance
 * @param[in] a_tol (local) absolute tolerance
 * @param[in] h_0 initial stepsize to use
 * @param[in] full_output file name to write results to
 *
 */
Solution::Solution(de_system &de_sys, std::complex<double> x0,
std::complex<double> dx0, double t_i, double t_f, int o, double r_tol, double
a_tol, double h_0, const char* full_output){

    // Make underlying equation system accessible
    de_sys_ = &de_sys;

    // Set parameters for solver
    x = x0;
    dx = dx0;
    t = t_i;
    tf = t_f;
    order = o;
    rtol = r_tol;
    atol = a_tol;
    h0 = h_0;
    fo = full_output;
    rksolver = RKSolver(*de_sys_);

    // Determine direction of integration, fend>0 and integration ends when
    // it crosses zero
    if((t>=tf) and h0<0){
        // backwards
        fend = t-tf;
        fnext = fend;
        if(de_sys_->is_interpolated == 1){
            de_sys_->Winterp.sign_ = 0;
            de_sys_->Ginterp.sign_ = 0;
        }
        else
            sign = 0;

    }
    else if((t<=tf) and h0>0){
        // forward
        fend = tf-t;
        fnext = fend;
        if(de_sys_->is_interpolated == 1){
            de_sys_->Winterp.sign_ = 1;
            de_sys_->Ginterp.sign_ = 1;
        }
        else
            sign = 1;
    }
    else{
        throw "Direction of integration in conflict with direction of initial step, terminating. Please check your values for ti, tf, and h. ";
        return;
    }

    // No dense output desired if this constructor was called, so only output
    // answer at t_i and t_f
    dotimes.push_back(t_i);
    dotimes.push_back(t_f);
    dosol.push_back(x0);
    dodsol.push_back(dx0);
    dotit = dotimes.end();

    switch(order){
        case 1: wkbsolver1 = WKBSolver1(*de_sys_, order);
                wkbsolver = &wkbsolver1;
                break;
        case 2: wkbsolver2 = WKBSolver2(*de_sys_, order);
                wkbsolver = &wkbsolver2;
                break;
        case 3: wkbsolver3 = WKBSolver3(*de_sys_, order);
                wkbsolver = &wkbsolver3;
                break;
    };
};

/** Constructor for when dense output was requested. Sets up solution of the
 * ODE.
 *
 * @param[in] de_sys de_system object carrying information about the ODE being
 * solved
 * @param[in] x0, dx0 initial conditions for the ODE, \f$ x(t) \f$, \f$ \frac{dx}{dt} \f$ evaluated at
 * the start of the integration range
 * @param[in] t_i start of integration range
 * @param[in] t_f end of integration range
 * @param[in] do_times timepoints at which dense output is to be produced
 * @param[in] o order of WKB approximation to be used
 * @param[in] r_tol (local) relative tolerance
 * @param[in] a_tol (local) absolute tolerance
 * @param[in] h_0 initial stepsize to use
 * @param[in] full_output file name to write results to
 *
 */
template<typename X> Solution::Solution(de_system &de_sys, std::complex<double> x0,
std::complex<double> dx0, double t_i, double t_f, const X &do_times, int o, double r_tol, double
a_tol, double h_0, const char* full_output){

    // Make underlying equation system accessible
    de_sys_ = &de_sys;
    // Set parameters for solver
    x = x0;
    dx = dx0;
    t = t_i;
    tf = t_f;
    order = o;
    rtol = r_tol;
    atol = a_tol;
    h0 = h_0;
    fo = full_output;
    rksolver = RKSolver(*de_sys_);

    // Determine direction of integration, fend>0 and integration ends when
    // it crosses zero
    if((t>=tf) and h0<0){
        // backwards
        fend = t-tf;
        fnext = fend;
        if(de_sys_->is_interpolated == 1){
            de_sys_->Winterp.sign_ = 0;
            de_sys_->Ginterp.sign_ = 0;
        }
        else
            sign = 0;
    }
    else if((t<=tf) and h0>0){
        // forward
        fend = tf-t;
        fnext = fend;
        if(de_sys_->is_interpolated == 1){
            de_sys_->Winterp.sign_ = 1;
            de_sys_->Ginterp.sign_ = 1;
        }
        else
            sign = 1;
    }
    else{
        throw "Direction of integration in conflict with direction of initial step, terminating. Please check your values for ti, tf, and h. ";
        return;
    }

    // Dense output checks:
    int dosize = do_times.size();
    dotimes.resize(dosize);
    dosol.resize(dosize);
    dodsol.resize(dosize);
    int docount = 0;
    auto doit = do_times.begin();
    if(de_sys_->Winterp.sign_ == 1){
        for(auto it=dotimes.begin(); it!=dotimes.end(); it++){
            *it = *doit;
            docount++; doit++;
        }
    }
    else{
         for(auto it=dotimes.rbegin(); it!=dotimes.rend(); ++it){
            *it = *doit;
            docount++; ++doit;
        }
    }
    dotit = dotimes.begin();
    switch(order){
        case 1: wkbsolver1 = WKBSolver1(*de_sys_, order);
                wkbsolver = &wkbsolver1;
                break;
        case 2: wkbsolver2 = WKBSolver2(*de_sys_, order);
                wkbsolver = &wkbsolver2;
                break;
        case 3: wkbsolver3 = WKBSolver3(*de_sys_, order);
                wkbsolver = &wkbsolver3;
                break;
    };
};

/** \brief Function to solve the ODE \f$ \ddot{x} + 2\gamma(t)\dot{x} +
 * \omega^2(t)x = 0 \f$ for \f$ x(t), \frac{dx}{dt} \f$.
 *
 * While solving the ODE, this function will populate the \a Solution object
 * with the following results:
 *
 */
void Solution::solve(){

    int nrk, nwkb1, nwkb2;
    // Settings for MS
    nrk = 5;
    nwkb1 = 2;
    nwkb2 = 4;
    Eigen::Matrix<std::complex<double>,2,2> rkstep;
    Eigen::Matrix<std::complex<double>,3,2> wkbstep;
    Eigen::Matrix<std::complex<double>,1,2> rkx, wkbx;
    Eigen::Matrix<std::complex<double>,1,2> rkerr, wkberr, truncerr;
    Eigen::Matrix<double,1,2> errmeasure_rk;
    Eigen::Matrix<double,1,4> errmeasure_wkb;
    double tnext, hnext, h, hrk, hwkb;
    double wkbdelta, rkdelta;
    std::complex<double> xnext, dxnext;
    bool wkb = false;
    Eigen::Index maxindex_wkb, maxindex_rk;
    h = h0;
    tnext = t+h;
    // Initialise stats
    sol.push_back(x);
    dsol.push_back(dx);
    times.push_back(t);
    wkbs.push_back(false);
    ssteps = 0;
    totsteps = 0;
    wkbsteps = 0;
    // Dense output
    std::list<double> inner_dotimes;
    std::list<std::complex<double>> inner_dosols, inner_dodsols;
    auto it_dosol = dosol.begin();
    auto it_dodsol = dodsol.begin();
    Eigen::Matrix<std::complex<double>,1,2> y_dense_rk;
    std::complex<double> x_dense_rk, dx_dense_rk;

    while(fend > 0){
        // Check if we are reaching the end of integration
        if(fnext < 0){
            h = tf - t;
            tnext = tf;
        };

        // Keep updating stepsize until step is accepted
        while(true){
            // RK step
            rkstep = rksolver.step(x, dx, t, h);
            rkx << rkstep(0,0), rkstep(0,1);
            rkerr << rkstep(1,0), rkstep(1,1);
            // WKB step
            wkbstep = wkbsolver->step(x, dx, t, h, rksolver.ws, rksolver.gs, rksolver.ws5, rksolver.gs5);
            wkbx = wkbstep.row(0);
            wkberr = wkbstep.row(2);
            truncerr = wkbstep.row(1);
            // Safety feature for when all wkb steps are 0 (truncer=0), but not
            // necessarily in good WKB regime:
            truncerr(0) = std::max(1e-10,abs(truncerr(0)));
            truncerr(1) = std::max(1e-10,abs(truncerr(1)));
            // dominant error calculation
            // Error scale measures
            errmeasure_rk << std::abs(rkerr(0))/(std::abs(rkx(0))*rtol+atol), std::abs(rkerr(1))/(std::abs(rkx(1))*rtol+atol);
            errmeasure_wkb << std::abs(truncerr(0))/(std::abs(wkbx(0))*rtol+atol),
            std::abs(truncerr(1))/(std::abs(wkbx(1))*rtol+atol),
            std::abs(wkberr(0))/(std::abs(wkbx(0))*rtol+atol),
            std::abs(wkberr(1))/(std::abs(wkbx(1))*rtol+atol);
            rkdelta = std::max(1e-10, errmeasure_rk.maxCoeff(&maxindex_rk));
            if(std::isnan(errmeasure_wkb.maxCoeff())==false &&
               std::isinf(std::real(wkbx(0)))==false &&
               std::isinf(std::imag(wkbx(0)))==false &&
               std::isinf(std::real(wkbx(1)))==false &&
               std::isinf(std::imag(wkbx(1)))==false &&
               std::isnan(std::real(wkbx(0)))==false &&
               std::isnan(std::imag(wkbx(0)))==false &&
               std::isnan(std::real(wkbx(1)))==false &&
               std::isnan(std::imag(wkbx(1)))==false){
                wkbdelta = std::max(1e-10, errmeasure_wkb.maxCoeff(&maxindex_wkb));
            }
            else{
                wkbdelta = std::numeric_limits<double>::infinity();
            }

            // predict next stepsize
            hrk = h*std::pow((1.0/rkdelta),1.0/nrk);
            if(maxindex_wkb<=1)
                hwkb = h*std::pow(1.0/wkbdelta,1.0/nwkb1);
            else
                hwkb = h*std::pow(1.0/wkbdelta,1.0/nwkb2);
            // choose step with larger predicted stepsize
            if(std::abs(hwkb) >= std::abs(hrk)){
                wkb = true;
            }
            else{
                wkb = false;
            }
            if(wkb){
                xnext = wkbx(0);
                dxnext = wkbx(1);
                // if wkb step chosen, ignore truncation error in
                // stepsize-increase
                wkbdelta = std::max(1e-10, errmeasure_wkb.tail(2).maxCoeff());
                hnext = h*std::pow(1.0/wkbdelta,1.0/nwkb2);
            }
            else{
                xnext = rkx(0);
                dxnext = rkx(1);
                hnext = hrk;
            };
            totsteps += 1;
            // Checking for too many steps and low acceptance ratio:
            if(totsteps % 5000 == 0){
                std::cerr << "Warning: the solver took " << totsteps << " steps, and may take a while to converge." << std::endl;
                if(ssteps/totsteps < 0.05){
                    std::cerr << "Warning: the step acceptance ratio is below 5%, the solver may take a while to converge." << std::endl;
                }
            }

            // check if chosen step was successful
            if(std::abs(hnext)>=std::abs(h)){
                if(dotit!=dotimes.end()){
                    while((*dotit-t>=0 && tnext-*dotit>=0) or (*dotit-t<=0 && tnext-*dotit<=0)){
                        inner_dotimes.push_back(*dotit);
                        dotit++;
                    }
                    if(inner_dotimes.size() > 0){
                        inner_dosols.resize(inner_dotimes.size());
                        inner_dodsols.resize(inner_dotimes.size());
                        if(wkb){
                            // Dense output after successful WKB step
                            wkbsolver->dense_step(t,inner_dotimes,inner_dosols,inner_dodsols);
                        }
                        else{
                            // Dense output after successful RK step
                            for(auto it=inner_dotimes.begin(); it!=inner_dotimes.end(); it++)
                                rksolver.dense_step(t,h,x,dx,inner_dotimes,inner_dosols,inner_dodsols);
                        }
                    }
                }
                auto inner_it=inner_dosols.begin();
                auto inner_dit=inner_dodsols.begin();
                while(inner_it!=inner_dosols.end() && it_dosol!=dosol.end() && inner_dit!=inner_dodsols.end() && it_dodsol!=dodsol.end()){
                    *it_dosol = *inner_it;
                    *it_dodsol = *inner_dit;
                    it_dodsol++;
                    it_dosol++;
                    inner_it++;
                    inner_dit++;
                }
                inner_dotimes.resize(0);
                inner_dosols.resize(0);
                inner_dodsols.resize(0);

                // record type of step
                if(wkb){
                    wkbsteps +=1;
                    wkbs.push_back(true);
                }
                else{
                    wkbs.push_back(false);
                }
                sol.push_back(xnext);
                dsol.push_back(dxnext);
                times.push_back(tnext);
                tnext += hnext;
                x = xnext;
                dx = dxnext;
                t += h;
                h = hnext;
                if(h>0){
                    fend=tf-t;
                    fnext=tf-tnext;
                }
                else{
                    fend=t-tf;
                    fnext=tnext-tf;
                };
                ssteps +=1;
                // Update interpolation bounds
                if(de_sys_->is_interpolated == 1){
                    de_sys_->Winterp.update_interp_bounds();
                    de_sys_->Ginterp.update_interp_bounds();
                }

                break;
            }
            else{
                if(wkb){
                    if(maxindex_wkb<=1){
                        if(nwkb1 > 1)
                            hnext = h*std::pow(1.0/wkbdelta,1.0/(nwkb1-1));
                        else
                            hnext = 0.95*h*1.0/wkbdelta;
                    }
                    else
                        hnext = h*std::pow(1.0/wkbdelta,1.0/(nwkb2-1));
                }
                else
                    hnext = h*std::pow(1.0/rkdelta,1.0/(nrk-1));
                h = hnext;
                tnext = t + hnext;
                if(h>0){
                    fnext=tf-tnext;
                }
                else{
                    fnext=tnext-tf;
                };
            };
        };
    };

    // If integrating backwards, reverse dense output (because it will have been
    // reversed at the start)
    if(de_sys_->is_interpolated == 1){
        if(de_sys_->Winterp.sign_ == 0){
            dosol.reverse();
            dodsol.reverse();
        }
    }
    else{
        if(sign == 0){
            dosol.reverse();
            dodsol.reverse();
        }
    }

    // Write output to file if prompted
    if(not (*fo==0)){
        std::string output(fo);
        std::ofstream f;
        f.open(output);
        f << "# Summary:\n# total steps taken: " + std::to_string(totsteps) +
        "\n# of which successful: " + std::to_string(ssteps) + "\n# of which"+
        +" wkb: " + std::to_string(wkbsteps) + "\n# time, sol, dsol, wkb? (type)\n";
        auto it_t = times.begin();
        auto it_w = wkbs.begin();
        auto it_x = sol.begin();
        auto it_dx = dsol.begin();
        for(int i=0; i<=ssteps; i++){
            f << std::setprecision(15) << *it_t << ";" <<
            std::setprecision(15) << *it_x << ";" << std::setprecision(15) <<
            *it_dx << ";" << *it_w << "\n";
            ++it_t;
            ++it_x;
            ++it_dx;
            ++it_w;
        }
        // print all dense output to file
        int dosize = dosol.size();
        auto it_dosol = dosol.begin();
        auto it_dotimes = dotimes.begin();
        auto it_dodsol = dodsol.begin();
        for(int i=0; i<dosize; i++){
            f << std::setprecision(20) << *it_dotimes << ";" << std::setprecision(20) << *it_dosol << ";" << *it_dodsol << ";\n";
            ++it_dosol;
            ++it_dodsol;
            ++it_dotimes;
        }

        f.close();
    }

};

ext: hpp

max_stars_repo_name: lukashergt/oscode

max_issues_repo_name: lukashergt/oscode

max_forks_repo_name: lukashergt/oscode


text:
/*
    This file is part of solidity.

    solidity is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    solidity is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Christian <c@ethdev.com>
 * @date 2016
 * Unit tests for inline assembly.
 */

#include <test/Common.h>

#include <test/libsolidity/ErrorCheck.h>

#include <libsolidity/ast/AST.h>

#include <libyul/AssemblyStack.h>

#include <liblangutil/Scanner.h>
#include <liblangutil/Exceptions.h>
#include <liblangutil/SourceReferenceFormatter.h>

#include <libevmasm/Assembly.h>

#include <boost/algorithm/string/replace.hpp>
#include <boost/test/unit_test.hpp>

#include <memory>
#include <optional>
#include <string>

using namespace std;
using namespace solidity::langutil;
using namespace solidity::yul;

namespace solidity::frontend::test
{

namespace
{

std::optional<Error> parseAndReturnFirstError(
	string const& _source,
	bool _assemble = false,
	bool _allowWarnings = true,
	AssemblyStack::Language _language = AssemblyStack::Language::Assembly,
	AssemblyStack::Machine _machine = AssemblyStack::Machine::EVM
)
{
	AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), _language, solidity::frontend::OptimiserSettings::none());
	bool success = false;
	try
	{
		success = stack.parseAndAnalyze("", _source);
		if (success && _assemble)
			stack.assemble(_machine);
	}
	catch (FatalError const&)
	{
		BOOST_FAIL("Fatal error leaked.");
		success = false;
	}
	shared_ptr<Error const> error;
	for (auto const& e: stack.errors())
	{
		if (_allowWarnings && e->type() == Error::Type::Warning)
			continue;
		if (error)
		{
			string errors;
			for (auto const& err: stack.errors())
				errors += SourceReferenceFormatter::formatErrorInformation(*err);
			BOOST_FAIL("Found more than one error:\n" + errors);
		}
		error = e;
	}
	if (!success)
		BOOST_REQUIRE(error);
	if (error)
		return *error;
	return {};
}

bool successParse(
	string const& _source,
	bool _assemble = false,
	bool _allowWarnings = true,
	AssemblyStack::Language _language = AssemblyStack::Language::Assembly,
	AssemblyStack::Machine _machine = AssemblyStack::Machine::EVM
)
{
	return !parseAndReturnFirstError(_source, _assemble, _allowWarnings, _language, _machine);
}

bool successAssemble(string const& _source, bool _allowWarnings = true, AssemblyStack::Language _language = AssemblyStack::Language::Assembly)
{
	return
		successParse(_source, true, _allowWarnings, _language, AssemblyStack::Machine::EVM) &&
		successParse(_source, true, _allowWarnings, _language, AssemblyStack::Machine::EVM15);
}

Error expectError(
	std::string const& _source,
	bool _assemble,
	bool _allowWarnings = false,
	AssemblyStack::Language _language = AssemblyStack::Language::Assembly
)
{

	auto error = parseAndReturnFirstError(_source, _assemble, _allowWarnings, _language);
	BOOST_REQUIRE(error);
	return *error;
}

void parsePrintCompare(string const& _source, bool _canWarn = false)
{
	AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
	BOOST_REQUIRE(stack.parseAndAnalyze("", _source));
	if (_canWarn)
		BOOST_REQUIRE(Error::containsOnlyWarnings(stack.errors()));
	else
		BOOST_REQUIRE(stack.errors().empty());
	string expectation = "object \"object\" {\n    code " + boost::replace_all_copy(_source, "\n", "\n    ") + "\n}\n";
	BOOST_CHECK_EQUAL(stack.print(), expectation);
}

}

#define CHECK_ERROR_LANG(text, assemble, typ, substring, warnings, language) \
do \
{ \
	Error err = expectError((text), (assemble), warnings, (language)); \
	BOOST_CHECK(err.type() == (Error::Type::typ)); \
	BOOST_CHECK(searchErrorMessage(err, (substring))); \
} while(0)

#define CHECK_ERROR(text, assemble, typ, substring, warnings) \
CHECK_ERROR_LANG(text, assemble, typ, substring, warnings, AssemblyStack::Language::Assembly)

#define CHECK_PARSE_ERROR(text, type, substring) \
CHECK_ERROR(text, false, type, substring, false)

#define CHECK_PARSE_WARNING(text, type, substring) \
CHECK_ERROR(text, false, type, substring, false)

#define CHECK_ASSEMBLE_ERROR(text, type, substring) \
CHECK_ERROR(text, true, type, substring, false)

#define CHECK_STRICT_ERROR(text, type, substring) \
CHECK_ERROR_LANG(text, false, type, substring, false, AssemblyStack::Language::StrictAssembly)

#define CHECK_STRICT_WARNING(text, type, substring) \
CHECK_ERROR(text, false, type, substring, false, AssemblyStack::Language::StrictAssembly)

#define SUCCESS_STRICT(text) \
do { successParse((text), false, false, AssemblyStack::Language::StrictAssembly); } while (false)

BOOST_AUTO_TEST_SUITE(SolidityInlineAssembly)

BOOST_AUTO_TEST_SUITE(Parsing)

BOOST_AUTO_TEST_CASE(smoke_test)
{
	BOOST_CHECK(successParse("{ }"));
}

BOOST_AUTO_TEST_CASE(surplus_input)
{
	CHECK_PARSE_ERROR("{ } { }", ParserError, "Expected end of source but got '{'");
}

BOOST_AUTO_TEST_CASE(simple_instructions)
{
	BOOST_CHECK(successParse("{ let y := mul(0x10, mul(0x20, mload(0x40)))}"));
}

BOOST_AUTO_TEST_CASE(selfdestruct)
{
	BOOST_CHECK(successParse("{ selfdestruct(0x02) }"));
}

BOOST_AUTO_TEST_CASE(keywords)
{
	BOOST_CHECK(successParse("{ return (byte(1, 2), 2) pop(address()) }"));
}

BOOST_AUTO_TEST_CASE(constants)
{
	BOOST_CHECK(successParse("{ pop(mul(7, 8)) }"));
}

BOOST_AUTO_TEST_CASE(vardecl)
{
	BOOST_CHECK(successParse("{ let x := 7 }"));
}

BOOST_AUTO_TEST_CASE(vardecl_name_clashes)
{
	CHECK_PARSE_ERROR("{ let x := 1 let x := 2 }", DeclarationError, "Variable name x already taken in this scope.");
}

BOOST_AUTO_TEST_CASE(vardecl_multi)
{
	BOOST_CHECK(successParse("{ function f() -> x, y {} let x, y := f() }"));
}

BOOST_AUTO_TEST_CASE(vardecl_multi_conflict)
{
	CHECK_PARSE_ERROR("{ function f() -> x, y {} let x, x := f() }", DeclarationError, "Variable name x already taken in this scope.");
}

BOOST_AUTO_TEST_CASE(vardecl_bool)
{
	successParse("{ let x := true }");
	successParse("{ let x := false }");
}

BOOST_AUTO_TEST_CASE(vardecl_empty)
{
	BOOST_CHECK(successParse("{ let x }"));
}

BOOST_AUTO_TEST_CASE(functional)
{
	BOOST_CHECK(successParse("{ let x := 2 x := add(add(7, mul(6, x)), mul(7, 8)) }"));
}

BOOST_AUTO_TEST_CASE(functional_partial)
{
	CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected '(' but got '}'");
}

BOOST_AUTO_TEST_CASE(functional_partial_success)
{
	BOOST_CHECK(successParse("{ let x := byte(1, 2) }"));
}

BOOST_AUTO_TEST_CASE(functional_assignment)
{
	BOOST_CHECK(successParse("{ let x := 2 x := 7 }"));
}

BOOST_AUTO_TEST_CASE(functional_assignment_complex)
{
	BOOST_CHECK(successParse("{ let x := 2 x := add(add(7, mul(6, x)), mul(7, 8)) }"));
}

BOOST_AUTO_TEST_CASE(vardecl_complex)
{
	BOOST_CHECK(successParse("{ let y := 2 let x := add(add(7, mul(6, y)), mul(7, 8)) }"));
}

BOOST_AUTO_TEST_CASE(variable_use_before_decl)
{
	CHECK_PARSE_ERROR("{ x := 2 let x := 3 }", DeclarationError, "Variable x used before it was declared.");
	CHECK_PARSE_ERROR("{ let x := mul(2, x) }", DeclarationError, "Variable x used before it was declared.");
}

BOOST_AUTO_TEST_CASE(if_statement)
{
	BOOST_CHECK(successParse("{ if 42 {} }"));
	BOOST_CHECK(successParse("{ if 42 { let x := 3 } }"));
	BOOST_CHECK(successParse("{ function f() -> x {} if f() { pop(f()) } }"));
}

BOOST_AUTO_TEST_CASE(if_statement_scope)
{
	BOOST_CHECK(successParse("{ let x := 2 if 42 { x := 3 } }"));
	CHECK_PARSE_ERROR("{ if 32 { let x := 3 } x := 2 }", DeclarationError, "Variable not found or variable not lvalue.");
}

BOOST_AUTO_TEST_CASE(if_statement_invalid)
{
	CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' but got '{'");
	BOOST_CHECK("{ if calldatasize() {}");
	CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", TypeError, "Expected expression to evaluate to one value, but got 0 values instead.");
	CHECK_PARSE_ERROR("{ if 32 let x := 3 }", ParserError, "Expected '{' but got reserved keyword 'let'");
}

BOOST_AUTO_TEST_CASE(switch_statement)
{
	BOOST_CHECK(successParse("{ switch 42 default {} }"));
	BOOST_CHECK(successParse("{ switch 42 case 1 {} }"));
	BOOST_CHECK(successParse("{ switch 42 case 1 {} case 2 {} }"));
	BOOST_CHECK(successParse("{ switch 42 case 1 {} default {} }"));
	BOOST_CHECK(successParse("{ switch 42 case 1 {} case 2 {} default {} }"));
	BOOST_CHECK(successParse("{ switch mul(1, 2) case 1 {} case 2 {} default {} }"));
	BOOST_CHECK(successParse("{ function f() -> x {} switch f() case 1 {} case 2 {} default {} }"));
}

BOOST_AUTO_TEST_CASE(switch_no_cases)
{
	CHECK_PARSE_ERROR("{ switch 42 }", ParserError, "Switch statement without any cases.");
}

BOOST_AUTO_TEST_CASE(switch_duplicate_case)
{
	CHECK_PARSE_ERROR("{ switch 42 case 1 {} case 1 {} default {} }", DeclarationError, "Duplicate case defined.");
}

BOOST_AUTO_TEST_CASE(switch_invalid_expression)
{
	CHECK_PARSE_ERROR("{ switch {} case 1 {} default {} }", ParserError, "Literal or identifier expected.");
	CHECK_PARSE_ERROR(
		"{ switch mload case 1 {} default {} }",
		ParserError,
		"Expected '(' but got reserved keyword 'case'"
	);
	CHECK_PARSE_ERROR(
		"{ switch mstore(1, 1) case 1 {} default {} }",
		TypeError,
		"Expected expression to evaluate to one value, but got 0 values instead."
	);
}

BOOST_AUTO_TEST_CASE(switch_default_before_case)
{
	CHECK_PARSE_ERROR("{ switch 42 default {} case 1 {} }", ParserError, "Case not allowed after default case.");
}

BOOST_AUTO_TEST_CASE(switch_duplicate_default_case)
{
	CHECK_PARSE_ERROR("{ switch 42 default {} default {} }", ParserError, "Only one default case allowed.");
}

BOOST_AUTO_TEST_CASE(switch_invalid_case)
{
	CHECK_PARSE_ERROR("{ switch 42 case mul(1, 2) {} case 2 {} default {} }", ParserError, "Literal expected.");
}

BOOST_AUTO_TEST_CASE(switch_invalid_body)
{
	CHECK_PARSE_ERROR("{ switch 42 case 1 mul case 2 {} default {} }", ParserError, "Expected '{' but got identifier");
}

BOOST_AUTO_TEST_CASE(for_statement)
{
	BOOST_CHECK(successParse("{ for {} 1 {} {} }"));
	BOOST_CHECK(successParse("{ for { let i := 1 } lt(i, 5) { i := add(i, 1) } {} }"));
}

BOOST_AUTO_TEST_CASE(for_invalid_expression)
{
	CHECK_PARSE_ERROR("{ for {} {} {} {} }", ParserError, "Literal or identifier expected.");
	CHECK_PARSE_ERROR("{ for 1 1 {} {} }", ParserError, "Expected '{' but got 'Number'");
	CHECK_PARSE_ERROR("{ for {} 1 1 {} }", ParserError, "Expected '{' but got 'Number'");
	CHECK_PARSE_ERROR("{ for {} 1 {} 1 }", ParserError, "Expected '{' but got 'Number'");
	CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected '(' but got '{'");
	CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", TypeError, "Expected expression to evaluate to one value, but got 0 values instead.");
}

BOOST_AUTO_TEST_CASE(for_visibility)
{
	BOOST_CHECK(successParse("{ for { let i := 1 } i { pop(i) } { pop(i) } }"));
	CHECK_PARSE_ERROR("{ for {} i { let i := 1 } {} }", DeclarationError, "Identifier not found");
	CHECK_PARSE_ERROR("{ for {} 1 { let i := 1 } { pop(i) } }", DeclarationError, "Identifier not found");
	CHECK_PARSE_ERROR("{ for {} 1 { pop(i) } { let i := 1 } }", DeclarationError, "Identifier not found");
	CHECK_PARSE_ERROR("{ for { pop(i) } 1 { let i := 1 } {} }", DeclarationError, "Identifier not found");
	CHECK_PARSE_ERROR("{ for { pop(i) } 1 { } { let i := 1 } }", DeclarationError, "Identifier not found");
	CHECK_PARSE_ERROR("{ for {} i {} { let i := 1 } }", DeclarationError, "Identifier not found");
	CHECK_PARSE_ERROR("{ for {} 1 { pop(i) } { let i := 1 } }", DeclarationError, "Identifier not found");
	CHECK_PARSE_ERROR("{ for { let x := 1 } 1 { let x := 1 } {} }", DeclarationError, "Variable name x already taken in this scope");
	CHECK_PARSE_ERROR("{ for { let x := 1 } 1 {} { let x := 1 } }", DeclarationError, "Variable name x already taken in this scope");
	CHECK_PARSE_ERROR("{ let x := 1 for { let x := 1 } 1 {} {} }", DeclarationError, "Variable name x already taken in this scope");
	CHECK_PARSE_ERROR("{ let x := 1 for {} 1 { let x := 1 } {} }", DeclarationError, "Variable name x already taken in this scope");
	CHECK_PARSE_ERROR("{ let x := 1 for {} 1 {} { let x := 1 } }", DeclarationError, "Variable name x already taken in this scope");
	// Check that body and post are not sub-scopes of each other.
	BOOST_CHECK(successParse("{ for {} 1 { let x := 1 } { let x := 1 } }"));
}

BOOST_AUTO_TEST_CASE(blocks)
{
	BOOST_CHECK(successParse("{ let x := 7 { let y := 3 } { let z := 2 } }"));
}

BOOST_AUTO_TEST_CASE(number_literals)
{
	BOOST_CHECK(successParse("{ let x := 1 }"));
	CHECK_PARSE_ERROR("{ let x := .1 }", ParserError, "Invalid number literal.");
	CHECK_PARSE_ERROR("{ let x := 1e5 }", ParserError, "Invalid number literal.");
	CHECK_PARSE_ERROR("{ let x := 67.235 }", ParserError, "Invalid number literal.");
	CHECK_STRICT_ERROR("{ let x := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff }", TypeError, "Number literal too large (> 256 bits)");
}

BOOST_AUTO_TEST_CASE(function_definitions)
{
	BOOST_CHECK(successParse("{ function f() { } function g(a) -> x { } }"));
}

BOOST_AUTO_TEST_CASE(function_definitions_multiple_args)
{
	BOOST_CHECK(successParse("{ function f(a, d) { } function g(a, d) -> x, y { } }"));
}

BOOST_AUTO_TEST_CASE(function_calls)
{
	BOOST_CHECK(successParse("{ function f(a) -> b {} function g(a, b, c) {} function x() { g(1, 2, f(mul(2, 3))) x() } }"));
}

BOOST_AUTO_TEST_CASE(opcode_for_functions)
{
	CHECK_PARSE_ERROR("{ function gas() { } }", ParserError, "Cannot use builtin");
}

BOOST_AUTO_TEST_CASE(opcode_for_function_args)
{
	CHECK_PARSE_ERROR("{ function f(gas) { } }", ParserError, "Cannot use builtin");
	CHECK_PARSE_ERROR("{ function f() -> gas { } }", ParserError, "Cannot use builtin");
}

BOOST_AUTO_TEST_CASE(name_clashes)
{
	CHECK_PARSE_ERROR("{ let g := 2 function g() { } }", DeclarationError, "Variable name g already taken in this scope");
}

BOOST_AUTO_TEST_CASE(name_clashes_function_subscope)
{
	CHECK_PARSE_ERROR("{ function g() { function g() {} } }", DeclarationError, "Function name g already taken in this scope");
}

BOOST_AUTO_TEST_CASE(name_clashes_function_subscope_reverse)
{
	CHECK_PARSE_ERROR("{ { function g() {} } function g() { } }", DeclarationError, "Function name g already taken in this scope");
}

BOOST_AUTO_TEST_CASE(name_clashes_function_variable_subscope)
{
	CHECK_PARSE_ERROR("{ function g() { let g := 0 } }", DeclarationError, "Variable name g already taken in this scope");
}

BOOST_AUTO_TEST_CASE(name_clashes_function_variable_subscope_reverse)
{
	CHECK_PARSE_ERROR("{ { let g := 0 } function g() { } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(functions_in_parallel_scopes)
{
	BOOST_CHECK(successParse("{ { function g() {} } { function g() {} } }"));
}

BOOST_AUTO_TEST_CASE(variable_access_cross_functions)
{
	CHECK_PARSE_ERROR("{ let x := 2 function g() { pop(x) } }", DeclarationError, "Identifier not found.");
}

BOOST_AUTO_TEST_CASE(invalid_tuple_assignment)
{
	CHECK_PARSE_ERROR("{ let x, y := 1 }", DeclarationError, "Variable count mismatch: 2 variables and 1 values");
}

BOOST_AUTO_TEST_CASE(instruction_too_few_arguments)
{
	CHECK_PARSE_ERROR("{ pop(mul()) }", TypeError, "Function expects 2 arguments but got 0.");
	CHECK_PARSE_ERROR("{ pop(mul(1)) }", TypeError, "Function expects 2 arguments but got 1.");
}

BOOST_AUTO_TEST_CASE(instruction_too_many_arguments)
{
	CHECK_PARSE_ERROR("{ pop(mul(1, 2, 3)) }", TypeError, "Function expects 2 arguments but got 3");
}

BOOST_AUTO_TEST_CASE(recursion_depth)
{
	string input;
	for (size_t i = 0; i < 20000; i++)
		input += "{";
	input += "let x := 0";
	for (size_t i = 0; i < 20000; i++)
		input += "}";

	CHECK_PARSE_ERROR(input, ParserError, "recursion");
}

BOOST_AUTO_TEST_CASE(multiple_assignment)
{
	CHECK_PARSE_ERROR("{ let x function f() -> a, b {} 123, x := f() }", ParserError, "Variable name must precede \",\" in multiple assignment.");
	CHECK_PARSE_ERROR("{ let x function f() -> a, b {} x, 123 := f() }", ParserError, "Variable name must precede \":=\" in assignment.");

	/// NOTE: Travis hiccups if not having a variable
	char const* text = R"(
	{
		function f(a) -> r1, r2 {
			r1 := a
			r2 := 7
		}
		let x := 9
		let y := 2
		x, y := f(x)
	}
	)";
	BOOST_CHECK(successParse(text));
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE(Printing)

BOOST_AUTO_TEST_CASE(print_smoke)
{
	parsePrintCompare("{ }");
}

BOOST_AUTO_TEST_CASE(print_instructions)
{
	parsePrintCompare("{ pop(7) }");
}

BOOST_AUTO_TEST_CASE(print_subblock)
{
	parsePrintCompare("{ { pop(7) } }");
}

BOOST_AUTO_TEST_CASE(print_functional)
{
	parsePrintCompare("{ let x := mul(sload(0x12), 7) }");
}

BOOST_AUTO_TEST_CASE(print_assignments)
{
	parsePrintCompare("{\n    let x := mul(2, 3)\n    pop(7)\n    x := add(1, 2)\n}");
}

BOOST_AUTO_TEST_CASE(print_multi_assignments)
{
	parsePrintCompare("{\n    function f() -> x, y\n    { }\n    let x, y := f()\n}");
}

BOOST_AUTO_TEST_CASE(print_string_literals)
{
	parsePrintCompare("{ let x := \"\\n'\\xab\\x95\\\"\" }");
}

BOOST_AUTO_TEST_CASE(print_string_literal_unicode)
{
	string source = "{ let x := \"\\u1bac\" }";
	string parsed = "object \"object\" {\n    code { let x := \"\\xe1\\xae\\xac\" }\n}\n";
	AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
	BOOST_REQUIRE(stack.parseAndAnalyze("", source));
	BOOST_REQUIRE(stack.errors().empty());
	BOOST_CHECK_EQUAL(stack.print(), parsed);

	string parsedInner = "{ let x := \"\\xe1\\xae\\xac\" }";
	parsePrintCompare(parsedInner);
}

BOOST_AUTO_TEST_CASE(print_if)
{
	parsePrintCompare("{ if 2 { pop(mload(0)) } }");
}

BOOST_AUTO_TEST_CASE(print_switch)
{
	parsePrintCompare("{\n    switch 42\n    case 1 { }\n    case 2 { }\n    default { }\n}");
}

BOOST_AUTO_TEST_CASE(print_for)
{
	parsePrintCompare("{\n    let ret := 5\n    for { let i := 1 } lt(i, 15) { i := add(i, 1) }\n    { ret := mul(ret, i) }\n}");
}

BOOST_AUTO_TEST_CASE(function_definitions_multiple_args)
{
	parsePrintCompare("{\n    function f(a, d)\n    { mstore(a, d) }\n    function g(a, d) -> x, y\n    { }\n}");
}

BOOST_AUTO_TEST_CASE(function_calls)
{
	string source = R"({
	function y()
	{ }
	function f(a) -> b
	{ }
	function g(a, b, c)
	{ }
	g(1, mul(2, address()), f(mul(2, caller())))
	y()
})";
	boost::replace_all(source, "\t", "    ");
	parsePrintCompare(source);
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE(Analysis)

BOOST_AUTO_TEST_CASE(string_literals)
{
	BOOST_CHECK(successAssemble("{ let x := \"12345678901234567890123456789012\" }"));
}

BOOST_AUTO_TEST_CASE(oversize_string_literals)
{
	CHECK_ASSEMBLE_ERROR("{ let x := \"123456789012345678901234567890123\" }", TypeError, "String literal too long");
}

BOOST_AUTO_TEST_CASE(magic_variables)
{
	CHECK_ASSEMBLE_ERROR("{ pop(this) }", DeclarationError, "Identifier not found");
	CHECK_ASSEMBLE_ERROR("{ pop(ecrecover) }", DeclarationError, "Identifier not found");
	BOOST_CHECK(successAssemble("{ let ecrecover := 1 pop(ecrecover) }"));
}

BOOST_AUTO_TEST_CASE(stack_variables)
{
	BOOST_CHECK(successAssemble("{ let y := 3 { let z := 2 { let x := y } } }"));
}

BOOST_AUTO_TEST_CASE(designated_invalid_instruction)
{
	BOOST_CHECK(successAssemble("{ invalid() }"));
}

BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration)
{
	CHECK_ASSEMBLE_ERROR("{ let gas := 1 }", ParserError, "Cannot use builtin");
}

BOOST_AUTO_TEST_CASE(revert)
{
	BOOST_CHECK(successAssemble("{ revert(0, 0) }"));
}

BOOST_AUTO_TEST_CASE(function_calls)
{
	BOOST_CHECK(successAssemble("{ function f() {} }"));
	BOOST_CHECK(successAssemble("{ function f() { let y := 2 } }"));
	BOOST_CHECK(successAssemble("{ function f() -> z { let y := 2 } }"));
	BOOST_CHECK(successAssemble("{ function f(a) { let y := 2 } }"));
	BOOST_CHECK(successAssemble("{ function f(a) { let y := a } }"));
	BOOST_CHECK(successAssemble("{ function f() -> x, y, z {} }"));
	BOOST_CHECK(successAssemble("{ function f(x, y, z) {} }"));
	BOOST_CHECK(successAssemble("{ function f(a, b) -> x, y, z { y := a } }"));
	BOOST_CHECK(successAssemble("{ function f() {} f() }"));
	BOOST_CHECK(successAssemble("{ function f() -> x, y { x := 1 y := 2} let a, b := f() }"));
	BOOST_CHECK(successAssemble("{ function f(a, b) -> x, y { x := b y := a } let a, b := f(2, 3) }"));
	BOOST_CHECK(successAssemble("{ function rec(a) { rec(sub(a, 1)) } rec(2) }"));
	BOOST_CHECK(successAssemble("{ let r := 2 function f() -> x, y { x := 1 y := 2} let a, b := f() b := r }"));
	BOOST_CHECK(successAssemble("{ function f() { g() } function g() { f() } }"));
}

BOOST_AUTO_TEST_CASE(embedded_functions)
{
	BOOST_CHECK(successAssemble("{ function f(r, s) -> x { function g(a) -> b { } x := g(2) } let x := f(2, 3) }"));
}

BOOST_AUTO_TEST_CASE(switch_statement)
{
	BOOST_CHECK(successAssemble("{ switch 1 default {} }"));
	BOOST_CHECK(successAssemble("{ switch 1 case 1 {} default {} }"));
	BOOST_CHECK(successAssemble("{ switch 1 case 1 {} }"));
	BOOST_CHECK(successAssemble("{ let a := 3 switch a case 1 { a := 1 } case 2 { a := 5 } a := 9}"));
	BOOST_CHECK(successAssemble("{ let a := 2 switch calldataload(0) case 1 { a := 1 } case 2 { a := 5 } }"));
}

BOOST_AUTO_TEST_CASE(for_statement)
{
	BOOST_CHECK(successAssemble("{ for {} 1 {} {} }"));
	BOOST_CHECK(successAssemble("{ let x := calldatasize() for { let i := 0} lt(i, x) { i := add(i, 1) } { mstore(i, 2) } }"));
}

BOOST_AUTO_TEST_CASE(if_statement)
{
	BOOST_CHECK(successAssemble("{ if 1 {} }"));
	BOOST_CHECK(successAssemble("{ let x := 0 if eq(calldatasize(), 0) { x := 1 } mstore(0, x) }"));
}

BOOST_AUTO_TEST_CASE(large_constant)
{
	auto source = R"({
		switch mul(1, 2)
		case 0x0000000000000000000000000000000000000000000000000000000026121ff0 {
		}
	})";
	BOOST_CHECK(successAssemble(source));
}

BOOST_AUTO_TEST_CASE(keccak256)
{
	BOOST_CHECK(successAssemble("{ pop(keccak256(0, 0)) }"));
}

BOOST_AUTO_TEST_CASE(returndatasize)
{
	if (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
		return;
	BOOST_CHECK(successAssemble("{ let r := returndatasize() }"));
}

BOOST_AUTO_TEST_CASE(returndatacopy)
{
	if (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
		return;
	BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }"));
}

BOOST_AUTO_TEST_CASE(returndatacopy_functional)
{
	if (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
		return;
	BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }"));
}

BOOST_AUTO_TEST_CASE(staticcall)
{
	if (!solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
		return;
	BOOST_CHECK(successAssemble("{ pop(staticcall(10000, 0x123, 64, 0x10, 128, 0x10)) }"));
}

BOOST_AUTO_TEST_CASE(create2)
{
	if (!solidity::test::CommonOptions::get().evmVersion().hasCreate2())
		return;
	BOOST_CHECK(successAssemble("{ pop(create2(10, 0x123, 32, 64)) }"));
}

BOOST_AUTO_TEST_CASE(shift)
{
	if (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
		return;
	BOOST_CHECK(successAssemble("{ pop(shl(10, 32)) }"));
	BOOST_CHECK(successAssemble("{ pop(shr(10, 32)) }"));
	BOOST_CHECK(successAssemble("{ pop(sar(10, 32)) }"));
}

BOOST_AUTO_TEST_CASE(shift_constantinople_warning)
{
	if (solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
		return;
	CHECK_PARSE_WARNING("{ shl(10, 32) }", TypeError, "The \"shl\" instruction is only available for Constantinople-compatible VMs");
	CHECK_PARSE_WARNING("{ shr(10, 32) }", TypeError, "The \"shr\" instruction is only available for Constantinople-compatible VMs");
	CHECK_PARSE_WARNING("{ sar(10, 32) }", TypeError, "The \"sar\" instruction is only available for Constantinople-compatible VMs");
}

BOOST_AUTO_TEST_CASE(jump_error)
{
	CHECK_PARSE_WARNING("{ jump(44) }", DeclarationError, "Function not found.");
	CHECK_PARSE_WARNING("{ jumpi(44, 2) }", DeclarationError, "Function not found.");
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()

} // end namespaces


text:
#pragma once

#ifndef RECEIVE_TCP_PACKAGE_OPERATIONS_HPP
#define RECEIVE_TCP_PACKAGE_OPERATIONS_HPP

#include <memory>
#include <cstddef>

#include <boost/asio/read.hpp>

#include "logger.hpp"
#include "tcp/tcp_package.hpp"

namespace es {
namespace tcp {
namespace operations {

template <class ConnectionType, class DynamicBuffer, class CompletionToken>
class read_message_handler
{
public:
	using connection_type = ConnectionType;
	using dynamic_buffer_type = DynamicBuffer;

	explicit read_message_handler(
		std::shared_ptr<connection_type> const& connection,
		dynamic_buffer_type& buffer,
		CompletionToken&& token
	) : connection_(connection), buffer_(buffer), token_(std::forward<CompletionToken>(token))
	{}

	void operator()(boost::system::error_code ec, std::size_t bytes_read)
	{
		if (connection_.expired())
		{
			buffer_.consume(4);
			return;
		}

		// regardless of error code, call token
		if (ec)
		{
			ES_ERROR("failed to read tcp frame message, {}", ec.message());
			buffer_.consume(4);
		}
		else
		{
			buffer_.commit(bytes_read);
		}

		token_(ec, bytes_read + 4);
	}
private:
	std::weak_ptr<connection_type> connection_;
	dynamic_buffer_type& buffer_;
	CompletionToken token_;
};

template <class ConnectionType, class DynamicBuffer, class CompletionToken>
class length_check_handler
{
public:
	using connection_type = ConnectionType;
	using dynamic_buffer_type = DynamicBuffer;

	explicit length_check_handler(
		std::shared_ptr<connection_type> const& connection,
		dynamic_buffer_type& buffer,
		CompletionToken&& token
	) : connection_(connection), buffer_(buffer), token_(std::forward<CompletionToken>(token))
	{}

	void operator()(boost::system::error_code ec, std::size_t bytes_read)
	{
		if (connection_.expired()) return;
		auto conn = connection_.lock();

		if (!ec)
		{
			auto* ptr = const_cast<void*>(buffer_.data().data());
			int length = *reinterpret_cast<int*>(ptr);

			if (length < detail::tcp::kMandatorySize - detail::tcp::kCommandOffset || length > detail::tcp::kMaxPackageSize)
			{
				ec = make_error_code(communication_errors::bad_length_prefix);
				token_(ec, bytes_read);
				return;
			}

			// commit length prefix
			buffer_.commit(4);

			boost::asio::async_read(
				conn->socket(),
				//boost::asio::buffer(buffer_ + 4, length),
				buffer_.prepare(length),
				read_message_handler<connection_type, dynamic_buffer_type, CompletionToken>(conn, buffer_, std::move(token_))
			);
			return;
		}
		else
		{
			ES_ERROR("failed to read tcp frame length, {}", ec.message());
			token_(ec, bytes_read);
			return;
		}
	}
private:
	std::weak_ptr<connection_type> connection_;
	dynamic_buffer_type& buffer_;
	CompletionToken token_;
};

template <class ConnectionType, class DynamicBuffer>
class read_tcp_package_op
{
public:
	using connection_type = ConnectionType;
	using dynamic_buffer_type = DynamicBuffer;

	explicit read_tcp_package_op(
		std::shared_ptr<connection_type> const& connection,
		dynamic_buffer_type& buffer
	) : connection_(connection), buffer_(buffer)
	{}

	template <class CompletionToken>
	void initiate(CompletionToken&& token)
	{
		// set error message !!
		if (connection_.expired()) return;
		auto conn = connection_.lock();

		length_check_handler<connection_type, dynamic_buffer_type, CompletionToken> handler(conn, buffer_, std::move(token));

		// not sure if this is what we want, maybe we want more flexiblity, this works well for single threaded code ...
		buffer_.consume(buffer_.size());

		boost::asio::async_read(
			conn->socket(),
			/*boost::asio::buffer(buffer_, 4),*/
			buffer_.prepare(4),
			std::move(handler)
		);
	}
private:
	std::weak_ptr<connection_type> connection_;
	dynamic_buffer_type& buffer_;
};

} // operations
} // tcp
} // es

#endif // RECEIVE_TCP_PACKAGE_OPERATIONS_HPP


text:
// Copyright (C) 2009-2020 Christian@Schladetsch.com
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_HETEROGENOUS_ADAPTOR_HPP
#define BOOST_HETEROGENOUS_ADAPTOR_HPP

#include <boost/heterogenous/detail/prefix.hpp>
#include <boost/heterogenous/cloneable.hpp>

namespace boost
{
    namespace heterogenous
    {
        /// an adaptor for an existing class
        ///
        /// this is a type that can be used in an homogenous container
        ///
        /// ...this may or may not be a good idea...
        template <class T, class Base>//, class AbstractBase>
        struct adaptor : T, cloneable<adaptor<T, Base/*, AbstractBase*/>, Base/*, AbstractBase*/>
        {
            adaptor() { }

            template <class A0>
            adaptor(A0 a0) : T(a0)
            {
            }
            template <class A0, class A1>
            adaptor(A0 a0, A1 a1) : T(a0, a1)
            {
            }
            template <class A0, class A1, class A2>
            adaptor(A0 a0, A1 a1, A2 a2) : T(a0, a1, a2)
            {
            }
        };

    } // namespace heterogenous

} // namespace boost

#include <boost/heterogenous/detail/suffix.hpp>

#endif // BOOST_HETEROGENOUS_ADAPTOR_HPP

//EOF

max_stars_repo_name: cschladetsch/Monotonic

max_issues_repo_name: cschladetsch/Monotonic

max_forks_repo_name: cschladetsch/Monotonic


text:
#pragma once
#ifndef TABLESTORE_UTIL_THREADING_HPP
#define TABLESTORE_UTIL_THREADING_HPP
/*
BSD 3-Clause License

Copyright (c) 2017, Alibaba Cloud
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "tablestore/util/move.hpp"
#include "tablestore/util/timestamp.hpp"
#include "tablestore/util/prettyprint.hpp"
#include <boost/noncopyable.hpp>
#include <boost/atomic.hpp>
#include <tr1/functional>
#include <tr1/memory>
#include <memory>
#include <string>
#include <stdint.h>

namespace aliyun {
namespace tablestore {
namespace util {

namespace impl {
class Thread;
} // namespace impl

class Thread: private boost::noncopyable
{
public:
    explicit Thread(const std::tr1::function<void()>&);
    explicit Thread();
    explicit Thread(const MoveHolder<Thread>&);
    Thread& operator=(const MoveHolder<Thread>&);

    ~Thread();
    void join();

private:
    impl::Thread* mImpl;
};

namespace impl {
class Mutex;
} // namespace impl

class Mutex: private boost::noncopyable
{
public:
    explicit Mutex();
    ~Mutex();

    void lock();
    void unlock();

private:
    impl::Mutex* mMutex;
};

class ScopedLock: private boost::noncopyable
{
public:
    explicit ScopedLock(Mutex& mutex);
    ~ScopedLock();

private:
    Mutex& mMutex;
};

namespace impl {
class Semaphore;
} // namespace impl

class Semaphore: private boost::noncopyable
{
public:
    enum Status
    {
        kInTime,
        kTimeout,
    };

    explicit Semaphore(int64_t init);
    ~Semaphore();

    void post();
    void wait();
    Status waitFor(Duration);

private:
    impl::Semaphore* mImpl;
};

namespace impl {
class ActionQueue;
} // namespace impl

class Actor
{
    static const int64_t kMaxBatchSize = 1000;

public:
    typedef std::tr1::function<void()> Action;

    explicit Actor();
    ~Actor();

    void pushBack(const Action&);

private:
    void acting();

private:
    Thread mThread;
    Semaphore mSem;
    boost::atomic<bool> mStopper;
    impl::ActionQueue* mScript;
};

} // namespace util
} // namespace tablestore
} // namespace aliyun

namespace pp {
namespace impl {

template<>
struct PrettyPrinter<aliyun::tablestore::util::Semaphore::Status, void>
{
    void operator()(std::string&, aliyun::tablestore::util::Semaphore::Status) const;
};

} // namespace impl
} // namespace pp
#endif

max_stars_repo_name: TimeExceed/aliyun-tablestore-cpp-sdk

max_issues_repo_name: TimeExceed/aliyun-tablestore-cpp-sdk

max_forks_repo_name: TimeExceed/aliyun-tablestore-cpp-sdk


text:
#include <rabbitxx/graph.hpp>
#include <rabbitxx/log.hpp>

#include <boost/graph/breadth_first_search.hpp>
#include <boost/mpi.hpp>

#include <iostream>

using rabbitxx::logging;

class bfs_print_visitor : public boost::default_bfs_visitor
{
public:
    template<typename Vertex, typename Graph>
    void discover_vertex(Vertex v, const Graph& g) const
    {
        logging::debug() << "VERTEX # " << v << " " << g[v].name() << " @ " << g[v].id();
    }

    template<typename Edge, typename Graph>
    void examine_edge(Edge e, const Graph& g)
    {
        const auto src_v = source(e,g);
        const auto trg_v = target(e,g);

        logging::debug() << "EDGE from " << g[src_v].name() << " @ " << g[src_v].id()
            << " -> " << g[trg_v].name() << " @ " << g[trg_v].id();

    }
};

int main(int argc, char** argv)
{
    boost::mpi::environment env(argc, argv);
    boost::mpi::communicator world;

    if (argc < 2) {
        logging::fatal() << "usage ./" << argv[0] << " <input-trace> ";
        env.abort(1);
        return 1;
    }

    auto g = rabbitxx::make_graph<rabbitxx::graph::OTF2_Io_Graph_Builder>(argv[1], world);
    bfs_print_visitor vis;
    boost::breadth_first_search(*g.get(), vertex(0, *g.get()), boost::visitor(vis));

    return 0;
}

max_stars_repo_name: blastmaster/rabbitxx

max_issues_repo_name: blastmaster/rabbitxx

max_forks_repo_name: blastmaster/rabbitxx


text:
//
// Created by denn nevera on 2019-09-03.
//

#pragma once

#include <armadillo>

namespace dehancer{

        namespace math {

            using float2x2 = arma::fmat::fixed<2, 2>;
            using float3x3 = arma::fmat::fixed<3, 3>;
            using float4x4 = arma::fmat::fixed<4, 4>;
        }
}

max_stars_repo_name: dehancer/dehancer-maths-cpp

max_issues_repo_name: dehancer/dehancer-maths-cpp

max_forks_repo_name: dehancer/dehancer-maths-cpp


text:
#ifndef GSPAN_HELPERS_HPP
#define GSPAN_HELPERS_HPP

#include "gspan_types.hpp"
#include <iterator>
#include <boost/range/adaptor/reversed.hpp>

namespace gspan {

template <typename G, typename VPTag, typename EPTag>
typename gspan_traits<G, VPTag, EPTag>::MG
make_ec(typename gspan_traits<G, VPTag, EPTag>::VI vi_src,
        typename gspan_traits<G, VPTag, EPTag>::VI vi_dst,
        const typename gspan_traits<G, VPTag, EPTag>::MG* prev_ec,
        typename boost::graph_traits<G>::edge_descriptor e,
        const G& g,
        VPTag vptag,
        EPTag eptag)
{
    using Ec = typename gspan_traits<G, VPTag, EPTag>::MG;
    return Ec(vi_src,
              vi_dst,
              get(vptag, g, source(e, g)),
              get(vptag, g, target(e, g)),
              get(eptag, g, e),
              prev_ec);
}

} // namespace gspan

namespace std {
template <typename Iter>
Iter
begin(const std::pair<Iter, Iter>& p)
{
    return p.first;
}

template <typename Iter>
Iter
end(const std::pair<Iter, Iter>& p)
{
    return p.second;
}
}

#endif

max_stars_repo_name: dtchuink/DFG-Pattern-Generator

max_issues_repo_name: dtchuink/DFG-Pattern-Generator

max_forks_repo_name: dtchuink/DFG-Pattern-Generator


text:
/*
 * Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cmath>
#include <boost/foreach.hpp>

#include "hazelcast/util/impl/SimpleExecutorService.h"
#include "hazelcast/util/HashUtil.h"

namespace hazelcast {
    namespace util {
        namespace impl {
            int32_t SimpleExecutorService::DEFAULT_EXECUTOR_QUEUE_CAPACITY = INT32_MAX;

            SimpleExecutorService::SimpleExecutorService(ILogger &logger, const std::string &threadNamePrefix,
                                                         int threadCount,
                                                         int32_t maximumQueueCapacity)
                    : logger(logger), threadNamePrefix(threadNamePrefix), threadCount(threadCount), live(true),
                      threadIdGenerator(0), workers(threadCount), maximumQueueCapacity(maximumQueueCapacity) {
                startWorkers();
            }

            SimpleExecutorService::SimpleExecutorService(ILogger &logger, const std::string &threadNamePrefix,
                                                         int threadCount)
                    : logger(logger), threadNamePrefix(threadNamePrefix), threadCount(threadCount), live(true),
                      threadIdGenerator(0), workers(threadCount),
                      maximumQueueCapacity(DEFAULT_EXECUTOR_QUEUE_CAPACITY) {
                startWorkers();
            }

            void SimpleExecutorService::startWorkers() {
                // `maximumQueueCapacity` is the given max capacity for this executor. Each worker in this executor should consume
                // only a portion of that capacity. Otherwise we will have `threadCount * maximumQueueCapacity` instead of
                // `maximumQueueCapacity`.
                int32_t perThreadMaxQueueCapacity = static_cast<int32_t>(ceil(
                        (double) 1.0 * maximumQueueCapacity / threadCount));
                for (int i = 0; i < threadCount; i++) {
                    workers[i].reset(new Worker(*this, perThreadMaxQueueCapacity));
                    workers[i]->start();
                }
            }

            void SimpleExecutorService::execute(const boost::shared_ptr<Runnable> &command) {
                if (command.get() == NULL) {
                    throw client::exception::NullPointerException("SimpleExecutor::execute", "command can't be null");
                }

                if (!live) {
                    throw client::exception::RejectedExecutionException("SimpleExecutor::execute",
                                                                        "Executor is terminated!");
                }

                boost::shared_ptr<Worker> worker = getWorker(command);
                worker->schedule(command);
            }

            boost::shared_ptr<SimpleExecutorService::Worker>
            SimpleExecutorService::getWorker(const boost::shared_ptr<Runnable> &runnable) {
                int32_t key;
                if (runnable->isStriped()) {
                    key = boost::static_pointer_cast<StripedRunnable>(runnable)->getKey();
                } else {
                    key = (int32_t) rand();
                }
                int index = HashUtil::hashToIndex(key, threadCount);
                return workers[index];
            }

            void SimpleExecutorService::shutdown() {
                if (!live.compareAndSet(true, false)) {
                    return;
                }

                BOOST_FOREACH(boost::shared_ptr<Worker> &worker, workers) {
                                worker->shutdown();
                            }

                boost::shared_ptr<util::Thread> runner;
                while ((runner = delayedRunners.poll()).get()) {
                    boost::static_pointer_cast<DelayedRunner>(runner->getTarget())->shutdown();
                    runner->cancel();
                    runner->join();
                }
            }

            SimpleExecutorService::~SimpleExecutorService() {
                shutdown();
            }

            void SimpleExecutorService::schedule(const boost::shared_ptr<util::Runnable> &command,
                                                 int64_t initialDelayInMillis) {
                if (command.get() == NULL) {
                    throw client::exception::NullPointerException("SimpleExecutor::schedule", "command can't be null");
                }

                if (!live) {
                    throw client::exception::RejectedExecutionException("SimpleExecutor::schedule",
                                                                        "Executor is terminated!");
                }

                boost::shared_ptr<DelayedRunner> delayedRunner(new DelayedRunner(command, initialDelayInMillis));
                boost::shared_ptr<util::Thread> thread(new util::Thread(delayedRunner));
                delayedRunner->setStartTimeMillis(thread.get());
                thread->start();
                delayedRunners.offer(thread);
            }

            void SimpleExecutorService::scheduleAtFixedRate(const boost::shared_ptr<util::Runnable> &command,
                                                            int64_t initialDelayInMillis, int64_t periodInMillis) {
                if (command.get() == NULL) {
                    throw client::exception::NullPointerException("SimpleExecutor::scheduleAtFixedRate",
                                                                  "command can't be null");
                }

                if (!live) {
                    throw client::exception::RejectedExecutionException("SimpleExecutor::scheduleAtFixedRate",
                                                                        "Executor is terminated!");
                }

                boost::shared_ptr<RepeatingRunner> repeatingRunner(
                        new RepeatingRunner(command, initialDelayInMillis, periodInMillis));
                boost::shared_ptr<util::Thread> thread(new util::Thread(repeatingRunner));
                repeatingRunner->setStartTimeMillis(thread.get());
                thread->start();
                delayedRunners.offer(thread);
            }

            void SimpleExecutorService::Worker::run() {
                boost::shared_ptr<Runnable> task;
                while (executorService.live || !workQueue.isEmpty()) {
                    try {
                        task = workQueue.pop();
                        if (task.get()) {
                            task->run();
                        }
                    } catch (client::exception::InterruptedException &) {
                        executorService.logger.finest() << getName() << " is interrupted .";
                    } catch (client::exception::IException &t) {
                        executorService.logger.warning() << getName() << " caused an exception" << t;
                    }
                }

                assert(workQueue.isEmpty());
            }

            SimpleExecutorService::Worker::~Worker() {
            }

            void SimpleExecutorService::Worker::schedule(const boost::shared_ptr<Runnable> &runnable) {
                workQueue.push(runnable);
            }

            void SimpleExecutorService::Worker::start() {
                thread.start();
            }

            const std::string SimpleExecutorService::Worker::getName() const {
                return name;
            }

            std::string SimpleExecutorService::Worker::generateThreadName(const std::string &prefix) {
                std::ostringstream out;
                out << prefix << (++executorService.threadIdGenerator);
                return out.str();
            }

            void SimpleExecutorService::Worker::shutdown() {
                workQueue.interrupt();
                thread.cancel();
                thread.join();
            }

            SimpleExecutorService::Worker::Worker(SimpleExecutorService &executorService, int32_t maximumQueueCapacity)
                    :
                    executorService(executorService), name(generateThreadName(executorService.threadNamePrefix)),
                    workQueue((size_t) maximumQueueCapacity),
                    thread(boost::shared_ptr<util::Runnable>(new util::RunnableDelegator(*this))) {
            }

            SimpleExecutorService::RepeatingRunner::RepeatingRunner(
                    const boost::shared_ptr<util::Runnable> &command, int64_t initialDelayInMillis,
                    int64_t periodInMillis) : DelayedRunner(command, initialDelayInMillis, periodInMillis) {
            }

            const std::string SimpleExecutorService::RepeatingRunner::getName() const {
                return command->getName();
            }

            SimpleExecutorService::DelayedRunner::DelayedRunner(
                    const boost::shared_ptr<util::Runnable> &command, int64_t initialDelayInMillis) : command(
                    command), initialDelayInMillis(initialDelayInMillis), periodInMillis(-1), live(true),
                                                                                startTimeMillis(
                                                                                0),
                                                                                runnerThread(
                                                                                NULL) {
            }

            SimpleExecutorService::DelayedRunner::DelayedRunner(
                    const boost::shared_ptr<util::Runnable> &command, int64_t initialDelayInMillis,
                    int64_t periodInMillis) : command(command), initialDelayInMillis(initialDelayInMillis),
                                              periodInMillis(periodInMillis), live(true), startTimeMillis(0),
                                              runnerThread(NULL) {}

            void SimpleExecutorService::DelayedRunner::shutdown() {
                live = false;
            }

            void SimpleExecutorService::DelayedRunner::run() {
                bool isNotRepeating = periodInMillis < 0;
                while (live || isNotRepeating) {
                    if (live) {
                        int64_t waitTimeMillis = startTimeMillis - util::currentTimeMillis();
                        if (waitTimeMillis > 0) {
                            assert(runnerThread != NULL);
                            runnerThread->interruptibleSleepMillis(waitTimeMillis);
                        }
                    }

                    try {
                        command->run();
                    } catch (client::exception::IException &e) {
                        ILogger &iLogger = util::ILogger::getLogger();
                        if (isNotRepeating) {
                            iLogger.warning() << "Runnable " << getName() << " run method caused exception:" << e;
                        } else {
                            iLogger.warning() << "Repeated runnable " << getName() << " run method caused exception:" << e;
                        }
                    }

                    if (isNotRepeating) {
                        return;
                    }

                    startTimeMillis += periodInMillis;
                }
            }

            const std::string SimpleExecutorService::DelayedRunner::getName() const {
                return command->getName();
            }

            void SimpleExecutorService::DelayedRunner::setStartTimeMillis(Thread *pThread) {
                runnerThread = pThread;
                startTimeMillis = util::currentTimeMillis() + initialDelayInMillis;
            }

        }

        boost::shared_ptr<ExecutorService> Executors::newSingleThreadExecutor(const std::string &name) {
            return boost::shared_ptr<ExecutorService>(
                    new impl::SimpleExecutorService(util::ILogger::getLogger(), name, 1));
        }

    }
}

max_stars_repo_name: pirog-spb/hazelcast-cpp-client

max_issues_repo_name: pirog-spb/hazelcast-cpp-client

max_forks_repo_name: pirog-spb/hazelcast-cpp-client


text:
#include "TerrainImages.h"
#include <boost/filesystem.hpp>
#include <functional>

void TerrainImages::rearrangeTile(sf::Texture& t)
{
    auto resolution = t.getSize();
    sf::Vector2i origin(0, 0);
    sf::Vector2i middle(resolution.x / 2, resolution.y / 2);
    sf::Vector2i middle_to_end = sf::Vector2i(resolution) - middle;
    sf::RenderTexture new_tile;
    new_tile.create(resolution.x, resolution.y);
    sf::Sprite corner;
    corner.setTexture(t);
    auto draw_corner = [&](sf::Vector2i from,
                           sf::Vector2i to,
                           sf::Vector2i size)
    {
        corner.setTextureRect(sf::IntRect(from.x, from.y, size.x, size.y));
        corner.setPosition((float)to.x, (float)to.y);
        new_tile.draw(corner);
    };
    draw_corner(origin, middle, middle_to_end);
    draw_corner({origin.x, middle_to_end.y}, {middle.x, origin.y}, {middle_to_end.x, middle.y});
    draw_corner({middle_to_end.x, origin.y}, {origin.x, middle.y}, {middle.x, middle_to_end.y});
    draw_corner(middle_to_end, origin, middle);
    new_tile.display();
    t = new_tile.getTexture();
}

void TerrainImages::addTerrain(TerrainID tid, std::string image_filename, std::string json_filename,
                               size_t offset_x, size_t offset_y, sf::Vector2u resolution)
{
    std::string filename = image_filename;
    // TODO(serin-delaunay): use mOptions.directory
    boost::filesystem::path p(json_filename);
    p.remove_filename();
    p.append(filename);
    filename = p.string();
    auto it = source_images.find(filename);
    if (it == source_images.end())
    {
        sf::Image img;
        if (!img.loadFromFile(filename))
            throw std::runtime_error("Couldn't read image");
        it = source_images.insert({ filename, img }).first;
    }
    sf::Vector2i offset(offset_x, offset_y);
    sf::Texture tex;
    if (!tex.loadFromImage((*it).second, sf::IntRect(offset, sf::Vector2i(resolution))))
        throw std::runtime_error("Couldn't make texture from image");
    rearrangeTile(tex);
    terrain_textures.insert({ tid, tex });
}


text:
// -*- C++ -*-
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//                                   Jiao Lin
//                      California Institute of Technology
//                      (C) 2007-2014 All Rights Reserved
//
// {LicenseText}
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

#include <sstream>
#include <boost/python.hpp>
#include "mccomponents/kernels/sample/ConstantvQEKernel.h"
#include "mccomponents/boostpython_binding/wrap_kernel.h"

namespace wrap_mccomponents {

  void wrap_ConstantvQEKernel()
  {
    using namespace boost::python;
    using namespace mccomponents::boostpython_binding;

    typedef mccomponents::kernels::ConstantvQEKernel w_t;

    kernel_wrapper<w_t>::wrap
      ("ConstantvQEKernel",
       init<double, double, double,
       double, double,
       double, double> ()
       )
      ;
  }

}

// version
// $Id$

// End of file

ext: cc

max_stars_repo_name: mcvine/mcvine

max_issues_repo_name: mcvine/mcvine

max_forks_repo_name: mcvine/mcvine