text:
/* Hector -- A Simple Climate Model
   Copyright (C) 2014-2015  Battelle Memorial Institute

   Please see the accompanying file LICENSE.md for additional licensing
   information.
*/
/*
 *  forcing_component.cpp
 *  hector
 *
 *  Created by Ben on 02 March 2011.
 *
 */

#include <boost/array.hpp>
#include <math.h>

#include "forcing_component.hpp"
#include "halocarbon_component.hpp"
#include "core.hpp"
#include "dependency_finder.hpp"
#include "h_util.hpp"
#include "avisitor.hpp"

namespace Hector {

/* These next two arrays and the map that connects them are a
 * workaround for the problems created by storing the halocarbon
 * forcings in the halocarbon components.  Because the halocarbon
 * components don't know about the base year adjustments, they can't
 * provide the forcings relative to the base year, which is what
 * outside callers will generally want.  Internally, however, we still
 * need to be able to get the raw forcings from the halocarbon
 * components, so we can't just change everything to point at the
 * forcing component (which would return the base year adjusted value).
 *
 * The solution we adopted was to create a second set of capabilities
 * to refer to the adjusted values, and we let the forcing component
 * intercept those.  However, the forcing values themselves are stored
 * under the names used for the unadjusted values, so we have to have
 * a name translation table so that we can find the data that the
 * message is asking for.  In the end, the whole process winds up
 * being a little ugly, but it gets the job done.
 */

const char *ForcingComponent::adjusted_halo_forcings[N_HALO_FORCINGS] = {
    D_RFADJ_CF4,
    D_RFADJ_C2F6,
    D_RFADJ_HFC23,
    D_RFADJ_HFC32,
    D_RFADJ_HFC4310,
    D_RFADJ_HFC125,
    D_RFADJ_HFC134a,
    D_RFADJ_HFC143a,
    D_RFADJ_HFC227ea,
    D_RFADJ_HFC245fa,
    D_RFADJ_SF6,
    D_RFADJ_CFC11,
    D_RFADJ_CFC12,
    D_RFADJ_CFC113,
    D_RFADJ_CFC114,
    D_RFADJ_CFC115,
    D_RFADJ_CCl4,
    D_RFADJ_CH3CCl3,
    D_RFADJ_HCF22,
    D_RFADJ_HCF141b,
    D_RFADJ_HCF142b,
    D_RFADJ_halon1211,
    D_RFADJ_halon1301,
    D_RFADJ_halon2402,
    D_RFADJ_CH3Cl,
    D_RFADJ_CH3Br
};

const char *ForcingComponent::halo_forcing_names[N_HALO_FORCINGS] = {
    D_RF_CF4,
    D_RF_C2F6,
    D_RF_HFC23,
    D_RF_HFC32,
    D_RF_HFC4310,
    D_RF_HFC125,
    D_RF_HFC134a,
    D_RF_HFC143a,
    D_RF_HFC227ea,
    D_RF_HFC245fa,
    D_RF_SF6,
    D_RF_CFC11,
    D_RF_CFC12,
    D_RF_CFC113,
    D_RF_CFC114,
    D_RF_CFC115,
    D_RF_CCl4,
    D_RF_CH3CCl3,
    D_RF_HCF22,
    D_RF_HCF141b,
    D_RF_HCF142b,
    D_RF_halon1211,
    D_RF_halon1301,
    D_RF_halon2402,
    D_RF_CH3Cl,
    D_RF_CH3Br
};

std::map<std::string, std::string> ForcingComponent::forcing_name_map;

using namespace std;

//------------------------------------------------------------------------------
/*! \brief Constructor
 */
ForcingComponent::ForcingComponent() {
}

//------------------------------------------------------------------------------
/*! \brief Destructor
 */
ForcingComponent::~ForcingComponent() {
}

//------------------------------------------------------------------------------
// documentation is inherited
string ForcingComponent::getComponentName() const {
    const string name = FORCING_COMPONENT_NAME;
    return name;
}

//------------------------------------------------------------------------------
// documentation is inherited
void ForcingComponent::init( Core* coreptr ) {

    logger.open( getComponentName(), false, coreptr->getGlobalLogger().getEchoToFile(), coreptr->getGlobalLogger().getMinLogLevel() );
    H_LOG( logger, Logger::DEBUG ) << "hello " << getComponentName() << std::endl;

    core = coreptr;

    baseyear = 0.0;
    currentYear = 0.0;

    Ftot_constrain.allowInterp( true );
    Ftot_constrain.name = D_RF_TOTAL;

    // Register the data we can provide
    core->registerCapability( D_RF_TOTAL, getComponentName() );
    core->registerCapability( D_RF_BASEYEAR, getComponentName() );
    core->registerCapability( D_RF_CO2, getComponentName());
    core->registerCapability( D_RF_CH4, getComponentName());
    core->registerCapability( D_RF_N2O, getComponentName());
    core->registerCapability( D_RF_H2O, getComponentName());
    core->registerCapability( D_RF_O3, getComponentName());
    core->registerCapability( D_RF_BC, getComponentName());
    core->registerCapability( D_RF_OC, getComponentName());
    core->registerCapability( D_RF_SO2d, getComponentName());
    core->registerCapability( D_RF_SO2i, getComponentName());
    core->registerCapability( D_RF_SO2, getComponentName());
    core->registerCapability( D_RF_VOL, getComponentName());
    for(int i=0; i<N_HALO_FORCINGS; ++i) {
        core->registerCapability(adjusted_halo_forcings[i], getComponentName());
        forcing_name_map[adjusted_halo_forcings[i]] = halo_forcing_names[i];
    }

    // Register our dependencies

    core->registerDependency( D_ATMOSPHERIC_CH4, getComponentName() );
    core->registerDependency( D_ATMOSPHERIC_CO2, getComponentName() );
    core->registerDependency( D_ATMOSPHERIC_O3, getComponentName() );
    core->registerDependency( D_EMISSIONS_BC, getComponentName() );
    core->registerDependency( D_EMISSIONS_OC, getComponentName() );
    core->registerDependency( D_NATURAL_SO2, getComponentName() );
    core->registerDependency( D_ATMOSPHERIC_N2O, getComponentName() );

    core->registerDependency( D_RF_CF4, getComponentName() );
    core->registerDependency( D_RF_C2F6, getComponentName() );
    core->registerDependency( D_RF_HFC23, getComponentName() );
    core->registerDependency( D_RF_HFC32, getComponentName() );
    core->registerDependency( D_RF_HFC4310, getComponentName() );
    core->registerDependency( D_RF_HFC125, getComponentName() );
    core->registerDependency( D_RF_HFC134a, getComponentName() );
    core->registerDependency( D_RF_HFC143a, getComponentName() );
    core->registerDependency( D_RF_HFC227ea, getComponentName() );
    core->registerDependency( D_RF_HFC245fa, getComponentName() );
    core->registerDependency( D_RF_SF6, getComponentName() );
    core->registerDependency( D_RF_CFC11, getComponentName() );
    core->registerDependency( D_RF_CFC12, getComponentName() );
    core->registerDependency( D_RF_CFC113, getComponentName() );
    core->registerDependency( D_RF_CFC114, getComponentName() );
    core->registerDependency( D_RF_CFC115, getComponentName() );
    core->registerDependency( D_RF_CCl4, getComponentName() );
    core->registerDependency( D_RF_CH3CCl3, getComponentName() );
    core->registerDependency( D_RF_HCF22, getComponentName() );
    core->registerDependency( D_RF_HCF141b, getComponentName() );
    core->registerDependency( D_RF_HCF142b, getComponentName() );
    core->registerDependency( D_RF_halon1211, getComponentName() );
    core->registerDependency( D_RF_halon1301, getComponentName() );
    core->registerDependency( D_RF_halon2402, getComponentName() );
    core->registerDependency( D_RF_CH3Br, getComponentName() );
    core->registerDependency( D_RF_CH3Cl, getComponentName() );
    core->registerDependency( D_RF_T_ALBEDO, getComponentName() );
}

//------------------------------------------------------------------------------
// documentation is inherited
unitval ForcingComponent::sendMessage( const std::string& message,
                                      const std::string& datum,
                                      const message_data info ) throw ( h_exception )
{
    unitval returnval;

    if( message==M_GETDATA ) {          //! Caller is requesting data
        return getData( datum, info.date );

    } else if( message==M_SETDATA ) {   //! Caller is requesting to set data
        //TODO: call setData below
        //TODO: change core so that parsing is routed through sendMessage
        //TODO: make setData private

    } else {                        //! We don't handle any other messages
        H_THROW( "Caller sent unknown message: "+message );
    }

    return returnval;
}

//------------------------------------------------------------------------------
// documentation is inherited
void ForcingComponent::setData( const string& varName,
                                const message_data& data ) throw ( h_exception )
{
    H_LOG( logger, Logger::DEBUG ) << "Setting " << varName << "[" << data.date << "]=" << data.value_str << std::endl;

    try {
        if( varName == D_RF_BASEYEAR ) {
            H_ASSERT( data.date == Core::undefinedIndex(), "date not allowed" );
            baseyear = data.getUnitval(U_UNDEFINED);
        } else if( varName == D_FTOT_CONSTRAIN ) {
            H_ASSERT( data.date != Core::undefinedIndex(), "date required" );
            Ftot_constrain.set(data.date, data.getUnitval(U_W_M2));
        } else {
            H_LOG( logger, Logger::DEBUG ) << "Unknown variable " << varName << std::endl;
            H_THROW( "Unknown variable name while parsing "+ getComponentName() + ": "
                    + varName );
        }
    } catch( h_exception& parseException ) {
        H_RETHROW( parseException, "Could not parse var: "+varName );
    }
}

//------------------------------------------------------------------------------
// documentation is inherited
void ForcingComponent::prepareToRun() throw ( h_exception ) {

    H_LOG( logger, Logger::DEBUG ) << "prepareToRun " << std::endl;

    if( baseyear==0.0 )
        baseyear = core->getStartDate() + 1;        // default, if not supplied by user
    H_LOG( logger, Logger::DEBUG ) << "Base year for reporting is " << baseyear << std::endl;

    H_ASSERT( baseyear > core->getStartDate(), "Base year must be >= model start date" );

    if( Ftot_constrain.size() ) {
        Logger& glog = core->getGlobalLogger();
        H_LOG( glog, Logger::WARNING ) << "Total forcing will be overwritten by user-supplied values!" << std::endl;
    }

    baseyear_forcings.clear();
}

//------------------------------------------------------------------------------
// documentation is inherited
void ForcingComponent::run( const double runToDate ) throw ( h_exception ) {

    // Calculate instantaneous radiative forcing for any & all agents
    // As each is computed, push it into 'forcings' map for Ftot calculation.
	// Note that forcings have to be mutually exclusive, there are no subtotals for different species.
    H_LOG( logger, Logger::DEBUG ) << "-----------------------------" << std::endl;
    currentYear = runToDate;

    if( runToDate < baseyear ) {
        H_LOG( logger, Logger::DEBUG ) << "not yet at baseyear" << std::endl;
    } else {
        forcings_t forcings;

        // ---------- CO2 ----------
        // Instantaneous radiative forcings for CO2, CH4, and N2O from http://www.esrl.noaa.gov/gmd/aggi/
        // These are in turn from IPCC (2001)

        // This is identical to that of MAGICC; see Meinshausen et al. (2011)
        unitval Ca = core->sendMessage( M_GETDATA, D_ATMOSPHERIC_CO2 );
        if( runToDate==baseyear )
            C0 = Ca;
        forcings[D_RF_CO2 ].set( 5.35 * log( Ca/C0 ), U_W_M2 );

        // ---------- Terrestrial albedo ----------
        if( core->checkCapability( D_RF_T_ALBEDO ) ) {
            forcings[ D_RF_T_ALBEDO ] = core->sendMessage( M_GETDATA, D_RF_T_ALBEDO, message_data( runToDate ) );
        }

        // ---------- N2O and CH4 ----------
        // Equations from Joos et al., 2001
        if( core->checkCapability( D_ATMOSPHERIC_CH4 ) && core->checkCapability( D_ATMOSPHERIC_N2O ) ) {

#define f(M,N) 0.47 * log( 1 + 2.01 * 1e-5 * pow( M * N, 0.75 ) + 5.31 * 1e-15 * M * pow( M * N, 1.52 ) )
            double Ma = core->sendMessage( M_GETDATA, D_ATMOSPHERIC_CH4, message_data( runToDate ) ).value( U_PPBV_CH4 );
            double M0 = core->sendMessage( M_GETDATA, D_PREINDUSTRIAL_CH4 ).value( U_PPBV_CH4 );
            double Na = core->sendMessage( M_GETDATA, D_ATMOSPHERIC_N2O, message_data( runToDate ) ).value( U_PPBV_N2O );
            double N0 = core->sendMessage( M_GETDATA, D_PREINDUSTRIAL_N2O ).value( U_PPBV_N2O );

            double fch4 =  0.036 * ( sqrt( Ma ) - sqrt( M0 ) ) - ( f( Ma, N0 ) - f( M0, N0 ) );
            forcings[D_RF_CH4].set( fch4, U_W_M2 );

            double fn2o =  0.12 * ( sqrt( Na ) - sqrt( N0 ) ) - ( f( M0, Na ) - f( M0, N0 ) );
            forcings[D_RF_N2O].set( fn2o, U_W_M2 );

            // ---------- Stratospheric H2O from CH4 oxidation ----------
            // From Tanaka et al, 2007, but using Joos et al., 2001 value of 0.05
            const double fh2o = 0.05 * ( 0.036 * ( sqrt( Ma ) - sqrt( M0 ) ) );
            forcings[D_RF_H2O].set( fh2o, U_W_M2 );
        }

        // ---------- Troposheric Ozone ----------
        if( core->checkCapability( D_ATMOSPHERIC_O3 ) ) {
            //from Tanaka et al, 2007
            const double ozone = core->sendMessage( M_GETDATA, D_ATMOSPHERIC_O3, message_data( runToDate ) ).value( U_DU_O3 );
            const double fo3 = 0.042 * ozone;
            forcings[D_RF_O3].set( fo3, U_W_M2 );
        }

        // ---------- Halocarbons ----------
        // TODO: Would like to just 'know' all the halocarbon instances out there
        boost::array<string, 26> halos = {
            {
                D_RF_CF4,
                D_RF_C2F6,
                D_RF_HFC23,
                D_RF_HFC32,
                D_RF_HFC4310,
                D_RF_HFC125,
                D_RF_HFC134a,
                D_RF_HFC143a,
                D_RF_HFC227ea,
                D_RF_HFC245fa,
                D_RF_SF6,
                D_RF_CFC11,
                D_RF_CFC12,
                D_RF_CFC113,
                D_RF_CFC114,
                D_RF_CFC115,
                D_RF_CCl4,
                D_RF_CH3CCl3,
                D_RF_HCF22,
                D_RF_HCF141b,
                D_RF_HCF142b,
                D_RF_halon1211,
                D_RF_halon1301,
                D_RF_halon2402,
                D_RF_CH3Cl,
                D_RF_CH3Br
            }
        };

        // Halocarbons can be disabled individually via the input file, so we run through all possible ones
         for (unsigned hc=0; hc<halos.size(); ++hc) {
            if( core->checkCapability( halos[hc] ) ) {
                // Forcing values are actually computed by the halocarbon itself
                forcings[ halos[hc] ] = core->sendMessage( M_GETDATA, halos[hc], message_data( runToDate ) );
                }
        }

        // ---------- Black carbon ----------
        if( core->checkCapability( D_EMISSIONS_BC ) ) {
            double fbc = 0.0743 * core->sendMessage( M_GETDATA, D_EMISSIONS_BC, message_data( runToDate ) ).value( U_TG );
            forcings[D_RF_BC].set( fbc, U_W_M2 );
            // includes both indirect and direct forcings from Bond et al 2013, Journal of Geophysical Research Atmo (table C1 - Central)
        }

        // ---------- Organic carbon ----------
        if( core->checkCapability( D_EMISSIONS_OC ) ) {
            double foc = -0.0128 * core->sendMessage( M_GETDATA, D_EMISSIONS_OC, message_data( runToDate ) ).value( U_TG );
            forcings[D_RF_OC].set( foc, U_W_M2 );
            // includes both indirect and direct forcings from Bond et al 2013, Journal of Geophysical Research Atmo (table C1 - Central).
            // The fossil fuel and biomass are weighted (-4.5) then added to the snow and clouds for a total of -12.8 (personal communication Steve Smith, PNNL)
        }

        // ---------- Sulphate Aerosols ----------
        if( core->checkCapability( D_NATURAL_SO2 ) && core->checkCapability( D_EMISSIONS_SO2 ) ) {

            unitval S0 = core->sendMessage( M_GETDATA, D_2000_SO2 );
            unitval SN = core->sendMessage( M_GETDATA, D_NATURAL_SO2 );

            // Includes only direct forcings from Forster et al 2007 (IPCC)
            // Equations from Joos et al., 2001
            H_ASSERT( S0.value( U_GG_S ) >0, "S0 is 0" );
            unitval emission = core->sendMessage( M_GETDATA, D_EMISSIONS_SO2, message_data( runToDate ) );
            double fso2d = -0.35 * emission/S0;
            forcings[D_RF_SO2d].set( fso2d, U_W_M2 );
            // includes only direct forcings from Forster etal 2007 (IPCC)

            // Indirect aerosol effect via changes in cloud properties
            const double a = -0.6 * ( log( ( SN.value( U_GG_S ) + emission.value( U_GG_S ) ) / SN.value( U_GG_S ) ) ); // -.6
            const double b =  pow ( log ( ( SN.value( U_GG_S ) + S0.value( U_GG_S ) ) / SN.value( U_GG_S ) ), -1 );
            double fso2i = a * b;
            forcings[D_RF_SO2i].set( fso2i, U_W_M2 );
        }

        if( core->checkCapability( D_VOLCANIC_SO2 ) ) {
            // Volcanic forcings
            forcings[D_RF_VOL] = core->sendMessage( M_GETDATA, D_VOLCANIC_SO2, message_data( runToDate ) );
        }

        // ---------- Total ----------
        unitval Ftot( 0.0, U_W_M2 );  // W/m2
        for( forcingsIterator it = forcings.begin(); it != forcings.end(); ++it ) {
            Ftot = Ftot + ( *it ).second;
            H_LOG( logger, Logger::DEBUG ) << "forcing " << ( *it).first << " in " << runToDate << " is " << ( *it ).second << std::endl;
        }

        // If the user has supplied total forcing data, use that
        if( Ftot_constrain.size() && runToDate <= Ftot_constrain.lastdate() ) {
            H_LOG( logger, Logger::WARNING ) << "** Overwriting total forcing with user-supplied value" << std::endl;
            forcings[ D_RF_TOTAL ] = Ftot_constrain.get( runToDate );
        } else {
            forcings[ D_RF_TOTAL ] = Ftot;
        }
        H_LOG( logger, Logger::DEBUG ) << "forcing total is " << forcings[ D_RF_TOTAL ] << std::endl;

        //---------- Change to relative forcing ----------
        // Note that the code below assumes model is always consistently run from base-year forward.
        // Results will not be consistent if parameters are changed but base-year is not re-run.

       // At this point, we've computed all absolute forcings. If base year, save those values
        if( runToDate==baseyear ) {
            H_LOG( logger, Logger::DEBUG ) << "** At base year! Storing current forcing values" << std::endl;
            baseyear_forcings = forcings;
        }

        // Subtract base year forcing values from forcings, i.e. make them relative to base year
        for( forcingsIterator it = forcings.begin(); it != forcings.end(); ++it ) {
            forcings[ ( *it ).first ] = ( *it ).second - baseyear_forcings[ ( *it ).first ];
        }

        // Store the forcings that we have calculated
        forcings_ts.set(runToDate, forcings);
    }
}

//------------------------------------------------------------------------------
// documentation is inherited
unitval ForcingComponent::getData( const std::string& varName,
                                  const double date ) throw ( h_exception ) {

    unitval returnval;
    double getdate = date;             // This is why I hate declaring PBV args as const!

    if(getdate == Core::undefinedIndex()) {
        // If no date specified, provide the current date
        getdate = currentYear;
    }

    if(getdate < baseyear) {
        // Forcing component hasn't run yet, so there is no data to get.
        returnval.set(0.0, U_W_M2);
        return returnval;
    }

    H_LOG(logger, Logger::DEBUG) << "getData request, time= "
                                 << getdate
                                 << "  baseyear = "
                                 << baseyear
                                 << std::endl;

    forcings_t forcings(forcings_ts.get(getdate));

    if( varName == D_RF_BASEYEAR ) {
        returnval.set( baseyear, U_UNITLESS );
    } else if (varName == D_RF_SO2) {
        // total SO2 forcing
        std::map<std::string, unitval>::const_iterator forcing_SO2d = forcings.find( D_RF_SO2d );
        std::map<std::string, unitval>::const_iterator forcing_SO2i = forcings.find( D_RF_SO2i );
        if ( forcing_SO2d != forcings.end() ) {
            if ( forcing_SO2i != forcings.end() ) {
                returnval = forcing_SO2d->second + forcing_SO2i->second;
            } else {
                returnval = forcing_SO2d->second;
            }
        } else {
            if ( forcing_SO2i != forcings.end() ) {
                returnval = forcing_SO2i->second;
            } else {
                returnval.set( 0.0, U_W_M2 );
            }
        }
    } else {
        std::string forcing_name;
        auto forcit = forcing_name_map.find(varName);
        if(forcit != forcing_name_map.end()) {
            forcing_name = forcing_name_map[varName];
        }
        else {
            forcing_name = varName;
        }
        std::map<std::string, unitval>::const_iterator forcing = forcings.find(forcing_name);
        if ( forcing != forcings.end() ) {
            // from the forcing map
            returnval = forcing->second;
        } else {
            if (currentYear < baseyear) {
                returnval.set( 0.0, U_W_M2 );
            } else {
                H_THROW( "Caller is requesting unknown variable: " + varName );
            }
        }
    }

    return returnval;
}

void ForcingComponent::reset(double time) throw(h_exception)
{
    // Set the current year to the reset year, and drop outputs after the reset year.
    currentYear = time;
    forcings_ts.truncate(time);
    H_LOG(logger, Logger::NOTICE)
        << getComponentName() << " reset to time= " << time << "\n";
}

//------------------------------------------------------------------------------
// documentation is inherited
void ForcingComponent::shutDown() {
	H_LOG( logger, Logger::DEBUG ) << "goodbye " << getComponentName() << std::endl;
    logger.close();
}

//------------------------------------------------------------------------------
// documentation is inherited
void ForcingComponent::accept( AVisitor* visitor ) {
    visitor->visit( this );
}

}

max_stars_repo_name: bvegawe/hector

max_issues_repo_name: bvegawe/hector

max_forks_repo_name: bvegawe/hector


text:
//          Copyright Tunc Bahcecioglu 2012 - 2013.
// 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)

#include <boost/test/unit_test.hpp>

#include <shiva/tagdispatcher.h>
#include <shiva\point2point.h>

BOOST_AUTO_TEST_SUITE(P2PTests)

BOOST_AUTO_TEST_CASE(StandardSRTest)
{
	shiva::communicator world;
	const int mpi_size = world.size();
	const int mpi_rank = world.rank();

	double msg_1 = 23.3;
	double msg_2 = 20.3;

	if (mpi_rank == 0) {
		shiva::send(world, shiva::make_message(msg_1), 1);
		shiva::send(world, shiva::make_message(msg_2), 2);
	}

	if (mpi_rank == 1) {
		double rec;
		shiva::receive(world, shiva::make_message(rec));
		BOOST_CHECK_EQUAL(rec, msg_1);
	} else if (mpi_rank == 2) {
		double rec;
		shiva::receive(world, shiva::make_message(rec));
		BOOST_CHECK_EQUAL(rec, msg_2);
	}
}

BOOST_AUTO_TEST_CASE(StandardSRProtocolTest)
{
	shiva::communicator world;
	const int mpi_size = world.size();
	const int mpi_rank = world.rank();

	double msg_1 = 23.3;
	double msg_2 = 20.3;

	if (mpi_rank == 0) {
		shiva::send(world, shiva::make_message(msg_1), 1, shiva::protocol::synchronous);
		shiva::send(world, shiva::make_message(msg_2), 2, shiva::protocol::ready);
	}

	if (mpi_rank == 1) {
		double rec;
		shiva::receive(world, shiva::make_message(rec));
		BOOST_CHECK_EQUAL(rec, msg_1);
	} else if (mpi_rank == 2) {
		double rec;
		shiva::receive(world, shiva::make_message(rec));
		BOOST_CHECK_EQUAL(rec, msg_2);
	}
}

BOOST_AUTO_TEST_SUITE_END()

ext: cpp

max_stars_repo_name: tuncb/shiva

max_issues_repo_name: tuncb/shiva

max_forks_repo_name: tuncb/shiva


text:
/*
 * Copyright (c) 2014, Stanislav Vorobiov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. 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.
 *
 * 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 OWNER 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 "FloatComponent.h"
#include "SceneObject.h"
#include "Scene.h"
#include "SequentialTweening.h"
#include "af/Utils.h"
#include <boost/make_shared.hpp>

namespace af
{
    FloatComponent::FloatComponent(float t, float distance, float force)
    : TargetableComponent(phaseThink),
      force_(force)
    {
        SequentialTweeningPtr tweening =
            boost::make_shared<SequentialTweening>(true);

        tweening->addTweening(boost::make_shared<SingleTweening>(t / 2.0f, EaseInQuad, distance / 2.0f, -distance / 2.0f));
        tweening->addTweening(boost::make_shared<SingleTweening>(t / 2.0f, EaseOutQuad, -distance / 2.0f, distance / 2.0f));

        tweening_= tweening;
        tweenTime_ = getRandom(0.0f, tweening_->duration());
    }

    FloatComponent::~FloatComponent()
    {
    }

    void FloatComponent::accept(ComponentVisitor& visitor)
    {
        visitor.visitPhasedComponent(shared_from_this());
    }

    void FloatComponent::update(float dt)
    {
        float value = 0.0f;

        if (tweening_) {
            value = tweening_->getValue(tweenTime_);
        }

        b2Vec2 tmp = pos_ + value * dir_ - target()->pos();
        tmp.Normalize();

        target()->applyForceToCenter(force_ * tmp, true);

        tweenTime_ += dt;
    }

    void FloatComponent::stop()
    {
        tweening_.reset();
    }

    void FloatComponent::onRegister()
    {
        pos_ = target()->pos();
        dir_ = target()->getDirection(1.0f);
    }

    void FloatComponent::onUnregister()
    {
        setTarget(SceneObjectPtr());
    }
}

max_stars_repo_name: Sheph/TriggerTime

max_issues_repo_name: Sheph/TriggerTime

max_forks_repo_name: Sheph/TriggerTime


text:
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2012. 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)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
//[doc_where_allocate
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
//<-
#include "../test/get_process_id_name.hpp"
//->

int main ()
{
   using namespace boost::interprocess;
   //Typedefs
   typedef allocator<char, managed_shared_memory::segment_manager>
      CharAllocator;
   typedef basic_string<char, std::char_traits<char>, CharAllocator>
      MyShmString;
   typedef allocator<MyShmString, managed_shared_memory::segment_manager>
      StringAllocator;
   typedef vector<MyShmString, StringAllocator>
      MyShmStringVector;

   //Open shared memory
   //Remove shared memory on construction and destruction
   struct shm_remove
   {
   //<-
   #if 1
      shm_remove() { shared_memory_object::remove(test::get_process_id_name()); }
      ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); }
   #else
   //->
      shm_remove() { shared_memory_object::remove("MySharedMemory"); }
      ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
   //<-
   #endif
   //->
   } remover;
   //<-
   (void)remover;
   //->

   //<-
   #if 1
   managed_shared_memory shm(create_only, test::get_process_id_name(), 10000);
   #else
   //->
   managed_shared_memory shm(create_only, "MySharedMemory", 10000);
   //<-
   #endif
   //->

   //Create allocators
   CharAllocator     charallocator  (shm.get_segment_manager());
   StringAllocator   stringallocator(shm.get_segment_manager());

   //This string is in only in this process (the pointer pointing to the
   //buffer that will hold the text is not in shared memory).
   //But the buffer that will hold "this is my text" is allocated from
   //shared memory
   MyShmString mystring(charallocator);
   mystring = "this is my text";

   //This vector is only in this process (the pointer pointing to the
   //buffer that will hold the MyShmString-s is not in shared memory).
   //But the buffer that will hold 10 MyShmString-s is allocated from
   //shared memory using StringAllocator. Since strings use a shared
   //memory allocator (CharAllocator) the 10 buffers that hold
   //"this is my text" text are also in shared memory.
   MyShmStringVector myvector(stringallocator);
   myvector.insert(myvector.begin(), 10, mystring);

   //This vector is fully constructed in shared memory. All pointers
   //buffers are constructed in the same shared memory segment
   //This vector can be safely accessed from other processes.
   MyShmStringVector *myshmvector =
      shm.construct<MyShmStringVector>("myshmvector")(stringallocator);
   myshmvector->insert(myshmvector->begin(), 10, mystring);

   //Destroy vector. This will free all strings that the vector contains
   shm.destroy_ptr(myshmvector);
   return 0;
}
//]
#include <boost/interprocess/detail/config_end.hpp>

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema


text:
/*******************************************************************************
 *         Copyright 2003 & onward LASMEA UMR 6602 CNRS/Univ. Clermont II
 *         Copyright 2009 & onward LRI    UMR 8623 CNRS/Univ Paris Sud XI
 *
 *          Distributed under the Boost Software License, Version 1.0.
 *                 See accompanying file LICENSE.txt or copy at
 *                     http://www.boost.org/LICENSE_1_0.txt
 ******************************************************************************/
#include <time.h>
#include <boost/config.hpp>
#include <nt2/sdk/details/timestamp.hpp>

#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable: 4996)
#endif

namespace nt2 { namespace sys
{
  //////////////////////////////////////////////////////////////////////////////
  // Return a string with time stamp in readable human format
  //////////////////////////////////////////////////////////////////////////////
  std::string timestamp()
  {
    time_t rawtime;
    char buffer[64];

    time(&rawtime);
    strftime(buffer,64,"%c",localtime(&rawtime));

    return std::string(buffer);
  }
} }

#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif


text:
// Copyright 2018 IOTA Foundation

#include <map>
#include <mutex>
#include <random>
#include <thread>
#include <vector>

#include <gtest/gtest.h>

#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm/copy.hpp>

#include "hub/commands/create_user.h"
#include "hub/commands/get_balance.h"
#include "hub/commands/helper.h"
#include "hub/commands/process_transfer_batch.h"
#include "hub/commands/tests/helper.h"

#include "runner.h"

using namespace hub;
using namespace hub::tests;
using namespace sqlpp;

namespace {
static constexpr int64_t USER_BALANCE = 10000;
static constexpr int64_t MAX_TRANSFER_UNIT = 50;
static constexpr uint32_t NUM_USERS = 100;
static constexpr uint32_t NUM_TRANSFERS = 200;

class ProcessTransferBatchTest : public CommandTest {};

void processRandomTransfer(std::map<uint64_t, std::string>& idsToUsers,
                           std::map<uint64_t, int64_t>& idsToBalances,
                           std::shared_ptr<common::ClientSession> session,
                           bool threadSafe = false) {
  static std::mutex m;
  std::random_device rd;   // obtain a random number from hardware
  std::mt19937 eng(rd());  // seed the generator
  std::uniform_int_distribution<> distr(1,
                                        MAX_TRANSFER_UNIT);  // define the range
  std::vector<std::string> users;
  boost::copy(idsToUsers | boost::adaptors::map_values,
              std::inserter(users, users.begin()));
  cmd::ProcessTransferBatch cmd(std::move(session));

  for (uint32_t i = 0; i < NUM_TRANSFERS; ++i) {
    cmd::ProcessTransferBatchRequest req;
    cmd::ProcessTransferBatchReply res;

    auto idsToAmounts = createZigZagTransfer(users, req, distr(eng));
    bool cmdOK = false;
    try {
      auto status = cmd.process(&req, &res);
      cmdOK = (status == common::cmd::OK);
    } catch (const sqlpp::exception& ex) {
    }

    if (threadSafe) {
      if (cmdOK) {
        std::unique_lock<std::mutex> lock(m);
        for (auto& kv : idsToBalances) {
          idsToBalances[kv.first] += idsToAmounts[kv.first];
        }
      }
    } else {
      if (cmdOK) {
        for (auto& kv : idsToBalances) {
          idsToBalances[kv.first] += idsToAmounts[kv.first];
        }
      }
    }
  }
}

TEST_F(ProcessTransferBatchTest, FailOnNonExistingUserId) {
  cmd::ProcessTransferBatchRequest req;
  cmd::ProcessTransferBatchReply res;

  constexpr static auto userId = "Imaginary User";

  req.transfers.emplace_back(
      cmd::UserTransfer{.userId = userId, .amount = 100});
  req.transfers.emplace_back(
      cmd::UserTransfer{.userId = userId, .amount = -100});

  cmd::ProcessTransferBatch command(session());

  auto status = command.process(&req, &res);

  ASSERT_EQ(status, common::cmd::USER_DOES_NOT_EXIST);
}

TEST_F(ProcessTransferBatchTest, ZeroAmountTransferFails) {
  cmd::ProcessTransferBatchRequest req;
  cmd::ProcessTransferBatchReply res;

  auto userId = "User Id";
  auto status = createUser(session(), userId);
  ASSERT_TRUE(status == common::cmd::OK);

  req.transfers.emplace_back(cmd::UserTransfer{.userId = userId, .amount = 0});

  cmd::ProcessTransferBatch command(session());

  status = command.process(&req, &res);
  ASSERT_EQ(status, common::cmd::BATCH_INVALID);
}

TEST_F(ProcessTransferBatchTest, TransfersAreRecorded) {
  cmd::ProcessTransferBatchRequest req;
  cmd::ProcessTransferBatchReply res;
  std::vector<std::string> users;
  std::vector<uint64_t> userIds;
  cmd::ProcessTransferBatch command(session());
  int64_t absAmount = 10;

  for (auto i = 0; i < 10; ++i) {
    users.push_back("User " + std::to_string(i + 1));
    userIds.push_back(i + 1);  // incremental keys are predictable
    auto status = createUser(session(), users[i]);
    ASSERT_TRUE(status == common::cmd::OK);
  }
  createBalanceForUsers(userIds, USER_BALANCE);
  createZigZagTransfer(users, req, absAmount);
  auto status = command.process(&req, &res);

  ASSERT_TRUE(status == common::cmd::OK);

  cmd::GetBalance balCmd(session());
  cmd::GetBalanceRequest getBalReq;
  cmd::GetBalanceReply getBalRep;

  for (uint32_t i = 0; i < users.size(); ++i) {
    getBalReq.userId = users[i];
    int64_t amount = (i % 2) ? absAmount : -absAmount;
    ASSERT_TRUE(balCmd.process(&getBalReq, &getBalRep) == common::cmd::OK);
    ASSERT_EQ(USER_BALANCE + amount, getBalRep.available);
  }
}

TEST_F(ProcessTransferBatchTest, TransfersAreRecordedGroupingUserBalances) {
  cmd::ProcessTransferBatchRequest req;
  cmd::ProcessTransferBatchReply res;
  std::vector<std::string> users;
  std::vector<uint64_t> userIds;
  cmd::ProcessTransferBatch command(session());
  int64_t absAmount = 50;

  for (auto i = 0; i < 10; ++i) {
    users.push_back("User " + std::to_string(i + 1));
    userIds.push_back(i + 1);  // incremental keys are predictable
    auto status = createUser(session(), users[i]);
    ASSERT_TRUE(status == common::cmd::OK);
  }
  createBalanceForUsers(userIds, USER_BALANCE / 2);
  createBalanceForUsers(userIds, USER_BALANCE / 2);
  createZigZagTransfer(users, req, absAmount);
  auto status = command.process(&req, &res);

  ASSERT_TRUE(status == common::cmd::OK);

  cmd::GetBalance balCmd(session());
  cmd::GetBalanceRequest getBalReq;
  cmd::GetBalanceReply getBalRep;

  for (uint32_t i = 0; i < users.size(); ++i) {
    getBalReq.userId = users[i];
    int64_t amount = (i % 2) ? absAmount : -absAmount;
    ASSERT_TRUE(balCmd.process(&getBalReq, &getBalRep) == common::cmd::OK);
    ASSERT_EQ(USER_BALANCE + amount, getBalRep.available);
  }
}

TEST_F(ProcessTransferBatchTest, TransfersMustBeZeroSummed) {
  cmd::ProcessTransferBatchRequest req;
  cmd::ProcessTransferBatchReply res;
  std::vector<std::string> users;
  std::vector<uint64_t> userIds;
  cmd::ProcessTransferBatch command(session());

  for (auto i = 0; i < 9; ++i) {
    users.push_back("User " + std::to_string(i + 1));
    userIds.push_back(i + 1);  // incremental keys are predictable
    auto status = createUser(session(), users[i]);
    ASSERT_TRUE(status == common::cmd::OK);
  }
  createBalanceForUsers(userIds, USER_BALANCE);
  createZigZagTransfer(users, req, USER_BALANCE / 2);
  auto status = command.process(&req, &res);

  ASSERT_FALSE(status == common::cmd::OK);
  ASSERT_EQ(status, common::cmd::BATCH_AMOUNT_NOT_ZERO);
}

TEST_F(ProcessTransferBatchTest, TransferMustHaveSufficientFunds) {
  cmd::ProcessTransferBatchRequest req;
  cmd::ProcessTransferBatchReply res;
  std::vector<std::string> users;
  std::vector<uint64_t> userIds;
  cmd::ProcessTransferBatch command(session());

  for (auto i = 0; i < 2; ++i) {
    users.push_back("User " + std::to_string(i + 1));
    userIds.push_back(i + 1);  // incremental keys are predictable
    auto status = createUser(session(), users[i]);
    ASSERT_TRUE(status == common::cmd::OK);
  }
  createBalanceForUsers(userIds, USER_BALANCE);
  createZigZagTransfer(users, req, USER_BALANCE + 1);
  auto status = command.process(&req, &res);

  ASSERT_EQ(status, common::cmd::BATCH_INCONSISTENT);
}

TEST_F(ProcessTransferBatchTest, SequentialTransfersAreConsistent) {
  std::map<uint64_t, std::string> idsToUsers;
  std::map<uint64_t, int64_t> idsToBalances;

  for (uint32_t i = 0; i < NUM_USERS; ++i) {
    idsToUsers[i + 1] = "User " + std::to_string(i + 1);
    auto status = createUser(session(), idsToUsers[i + 1]);
    ASSERT_EQ(status, common::cmd::OK);
  }

  std::vector<uint64_t> userIds;
  boost::copy(idsToUsers | boost::adaptors::map_keys,
              std::inserter(userIds, userIds.begin()));

  idsToBalances = createBalanceForUsers(userIds, USER_BALANCE);

  for (auto i = 0; i < 10; ++i) {
    processRandomTransfer(idsToUsers, idsToBalances, session());
  }

  cmd::GetBalance balCmd(session());
  cmd::GetBalanceRequest getBalReq;
  cmd::GetBalanceReply getBalRep;

  for (auto& kv : idsToUsers) {
    getBalReq.userId = kv.second;
    ASSERT_EQ(balCmd.process(&getBalReq, &getBalRep), common::cmd::OK);
    ASSERT_EQ(idsToBalances[kv.first], getBalRep.available);
  }
}

TEST_F(ProcessTransferBatchTest, ConcurrentTransfersAreConsistent) {
  static constexpr uint32_t NUM_THREADS = 20;

  std::vector<std::thread> threads(NUM_THREADS);
  std::map<uint64_t, std::string> idsToUsers;
  std::map<uint64_t, int64_t> idsToBalances;

  for (uint32_t i = 0; i < NUM_USERS; ++i) {
    idsToUsers[i + 1] = "User " + std::to_string(i + 1);
    auto status = createUser(session(), idsToUsers[i + 1]);
    ASSERT_EQ(status, common::cmd::OK);
  }

  std::vector<uint64_t> userIds;
  boost::copy(idsToUsers | boost::adaptors::map_keys,
              std::inserter(userIds, userIds.begin()));
  idsToBalances = createBalanceForUsers(userIds, USER_BALANCE);

  for (uint32_t i = 0; i < NUM_THREADS; ++i) {
    std::thread t(processRandomTransfer, std::ref(idsToUsers),
                  std::ref(idsToBalances), session(), true);
    threads[i] = std::move(t);
  }

  for (auto& t : threads) {
    t.join();
  }

  cmd::GetBalance balCmd(session());
  cmd::GetBalanceRequest getBalReq;
  cmd::GetBalanceReply getBalRep;

  for (auto& kv : idsToUsers) {
    getBalReq.userId = kv.second;
    ASSERT_EQ(balCmd.process(&getBalReq, &getBalRep), common::cmd::OK);
    ASSERT_EQ(idsToBalances[kv.first], getBalRep.available);
  }
}

};  // namespace

ext: cc

max_stars_repo_name: Tsangares/rpchub

max_issues_repo_name: Tsangares/rpchub

max_forks_repo_name: Tsangares/rpchub


text:
#include <boost/python.hpp>
#include <boost/cstdint.hpp>

#include <Magick++/Include.h>

using namespace boost::python;

void __QuantumType()
{
    enum_< Magick::QuantumType >("QuantumType")
        .value("IndexQuantum", Magick::IndexQuantum)
        .value("GrayQuantum", Magick::GrayQuantum)
        .value("IndexAlphaQuantum", Magick::IndexAlphaQuantum)
        .value("GrayAlphaQuantum", Magick::GrayAlphaQuantum)
        .value("RedQuantum", Magick::RedQuantum)
        .value("CyanQuantum", Magick::CyanQuantum)
        .value("GreenQuantum", Magick::GreenQuantum)
        .value("YellowQuantum", Magick::YellowQuantum)
        .value("BlueQuantum", Magick::BlueQuantum)
        .value("MagentaQuantum", Magick::MagentaQuantum)
        .value("AlphaQuantum", Magick::AlphaQuantum)
        .value("BlackQuantum", Magick::BlackQuantum)
        .value("RGBQuantum", Magick::RGBQuantum)
        .value("RGBAQuantum", Magick::RGBAQuantum)
        .value("CMYKQuantum", Magick::CMYKQuantum)
#ifdef PGMAGICK_LIB_GRAPHICSMAGICK_1_3_x
        .value("CIEYQuantum", Magick::CIEYQuantum)
        .value("CIEXYZQuantum", Magick::CIEXYZQuantum)
#endif
    ;
}

max_stars_repo_name: veryhappythings/pgmagick

max_issues_repo_name: veryhappythings/pgmagick

max_forks_repo_name: veryhappythings/pgmagick


text:
#py from parse import parse
#py import model
#py plugin = parse(pycpp.params['xml_file'])
#include "stubs.h"

#include <cstdlib>
#include <iostream>

#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>

#define CATCH_AND_RETHROW(prefix)   \
    catch(std::exception &ex)       \
    {                               \
        std::string msg = prefix;   \
        msg += ex.what();           \
        throw exception(msg);       \
    }                               \
    catch(std::string& s)           \
    {                               \
        std::string msg = prefix;   \
        msg += s;                   \
        throw exception(msg);       \
    }                               \
    catch(int& n)                   \
    {                               \
        std::stringstream msg;      \
        msg << prefix;              \
        msg << "error #" << n;      \
        throw exception(msg.str()); \
    }

bool isDebugStubsEnabled()
{
    static int enabled = -1;

    if(enabled == 0) return false;
    if(enabled == 1) return true;

    char *val = std::getenv("DEBUG_STUBS");
    if(!val) enabled = 0;
    else enabled = boost::lexical_cast<int>(val) != 0 ? 1 : 0;
    return enabled;
}

simInt simRegisterScriptCallbackFunctionE(const simChar *funcNameAtPluginName, const simChar *callTips, simVoid (*callBack)(struct SScriptCallBack *cb))
{
    simInt ret = simRegisterScriptCallbackFunction(funcNameAtPluginName, callTips, callBack);
    if(ret == 0)
    {
        std::cout << "Plugin '`plugin.name`': warning: replaced function '" << funcNameAtPluginName << "'" << std::endl;
    }
    if(ret == -1)
        throw exception("simRegisterScriptCallbackFunction: error");
    return ret;
}

simInt simRegisterScriptVariableE(const simChar *varName, const simChar *varValue, simInt stackID)
{
    simInt ret = simRegisterScriptVariable(varName, varValue, stackID);
    if(ret == 0)
    {
        std::cout << "Plugin '`plugin.name`': warning: replaced variable '" << varName << "'" << std::endl;
    }
    if(ret == -1)
        throw exception("simRegisterScriptVariable: error");
    return ret;
}

simVoid simCallScriptFunctionExE(simInt scriptHandleOrType,const simChar* functionNameAtScriptName,simInt stackId)
{
    if(simCallScriptFunctionEx(scriptHandleOrType, functionNameAtScriptName, stackId) == -1)
        throw exception("simCallScriptFunctionEx: error");
}

simInt simCreateStackE()
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simCreateStack()" << std::endl;
    }
#endif // DEBUG

    simInt ret = simCreateStack();
    if(ret == -1)
        throw exception("simCreateStack: error");
    return ret;
}

simVoid simReleaseStackE(simInt stackHandle)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simReleaseStack(stack)" << std::endl;
    }
#endif // DEBUG

    if(simReleaseStack(stackHandle) != 1)
        throw exception("simReleaseStack: error");
}

simInt simCopyStackE(simInt stackHandle)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simCopyStack(stack)" << std::endl;
    }
#endif // DEBUG

    simInt ret = simCopyStack(stackHandle);
    if(ret == -1)
        throw exception("simCopyStack: error");
    return ret;
}

simVoid simPushNullOntoStackE(simInt stackHandle)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushNullOntoStack(stack)" << std::endl;
    }
#endif // DEBUG

    if(simPushNullOntoStack(stackHandle) == -1)
        throw exception("simPushNullOntoStack: error");
}

simVoid simPushBoolOntoStackE(simInt stackHandle, simBool value)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushBoolOntoStack(stack, " << value << ")" << std::endl;
    }
#endif // DEBUG

    if(simPushBoolOntoStack(stackHandle, value) == -1)
        throw exception("simPushBoolOntoStack: error");
}

simVoid simPushInt32OntoStackE(simInt stackHandle, simInt value)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushInt32OntoStack(stack, " << value << ")" << std::endl;
    }
#endif // DEBUG

    if(simPushInt32OntoStack(stackHandle, value) == -1)
        throw exception("simPushInt32OntoStack: error");
}

simVoid simPushFloatOntoStackE(simInt stackHandle, simFloat value)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushFloatOntoStack(stack, " << value << ")" << std::endl;
    }
#endif // DEBUG

    if(simPushFloatOntoStack(stackHandle, value) == -1)
        throw exception("simPushFloatOntoStack: error");
}

simVoid simPushDoubleOntoStackE(simInt stackHandle, simDouble value)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushDoubleOntoStack(stack, " << value << ")" << std::endl;
    }
#endif // DEBUG

    if(simPushDoubleOntoStack(stackHandle, value) == -1)
        throw exception("simPushDoubleOntoStack: error");
}

simVoid simPushStringOntoStackE(simInt stackHandle, const simChar *value, simInt stringSize)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushStringOntoStack(stack, \"" << value << "\" [" << stringSize << "])" << std::endl;
    }
#endif // DEBUG

    if(simPushStringOntoStack(stackHandle, value, stringSize) == -1)
        throw exception("simPushStringOntoStack: error");
}

simVoid simPushUInt8TableOntoStackE(simInt stackHandle, const simUChar *values, simInt valueCnt)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushUInt8TableOntoStack(stack, <" << valueCnt << " values>)" << std::endl;
    }
#endif // DEBUG

    if(simPushUInt8TableOntoStack(stackHandle, values, valueCnt) == -1)
        throw exception("simPushUInt8TableOntoStack: error");
}

simVoid simPushInt32TableOntoStackE(simInt stackHandle, const simInt *values, simInt valueCnt)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushInt32TableOntoStack(stack, <" << valueCnt << " values>)" << std::endl;
    }
#endif // DEBUG

    if(simPushInt32TableOntoStack(stackHandle, values, valueCnt) == -1)
        throw exception("simPushInt32TableOntoStack: error");
}

simVoid simPushFloatTableOntoStackE(simInt stackHandle, const simFloat *values, simInt valueCnt)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushFloatTableOntoStack(stack, <" << valueCnt << " values>)" << std::endl;
    }
#endif // DEBUG

    if(simPushFloatTableOntoStack(stackHandle, values, valueCnt) == -1)
        throw exception("simPushFloatTableOntoStack: error");
}

simVoid simPushDoubleTableOntoStackE(simInt stackHandle, const simDouble *values, simInt valueCnt)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushDoubleTableOntoStack(stack, <" << valueCnt << " values>)" << std::endl;
    }
#endif // DEBUG

    if(simPushDoubleTableOntoStack(stackHandle, values, valueCnt) == -1)
        throw exception("simPushDoubleTableOntoStack: error");
}

simVoid simPushTableOntoStackE(simInt stackHandle)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPushTableOntoStack(stack)" << std::endl;
    }
#endif // DEBUG

    if(simPushTableOntoStack(stackHandle) == -1)
        throw exception("simPushTableOntoStack: error");
}

simVoid simInsertDataIntoStackTableE(simInt stackHandle)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simInsertDataIntoStackTable(stack)" << std::endl;
    }
#endif // DEBUG

    if(simInsertDataIntoStackTable(stackHandle) == -1)
        throw exception("simInsertDataIntoStackTable: error");
}

simInt simGetStackSizeE(simInt stackHandle)
{
    simInt ret = simGetStackSize(stackHandle);

#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simGetStackSize(stack) -> " << ret << std::endl;
    }
#endif // DEBUG

    if(ret == -1)
        throw exception("simGetStackSize: error");
    return ret;
}

simInt simPopStackItemE(simInt stackHandle, simInt count)
{
    simInt ret = simPopStackItem(stackHandle, count);

#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simPopStackItem(stack, " << count << ") -> " << ret << std::endl;
    }
#endif // DEBUG

    if(ret == -1)
        throw exception("simPopStackItem: error");
    return ret;
}

simVoid simMoveStackItemToTopE(simInt stackHandle, simInt cIndex)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simMoveStackItemToTop(stack, " << cIndex << ")" << std::endl;
    }
#endif // DEBUG

    if(simMoveStackItemToTop(stackHandle, cIndex) == -1)
        throw exception("simMoveStackItemToTop: error");
}

simInt simIsStackValueNullE(simInt stackHandle)
{
    simInt ret = simIsStackValueNull(stackHandle);
    if(ret == -1)
        throw exception("simIsStackValueNull: error");
    return ret;
}

simInt simGetStackBoolValueE(simInt stackHandle, simBool *boolValue)
{
    simInt ret = simGetStackBoolValue(stackHandle, boolValue);
    if(ret == -1)
        throw exception("simGetStackBoolValue: error");
    return ret;
}

simInt simGetStackInt32ValueE(simInt stackHandle, simInt *numberValue)
{
    simInt ret = simGetStackInt32Value(stackHandle, numberValue);
    if(ret == -1)
        throw exception("simGetStackInt32Value: error");
    return ret;
}

simInt simGetStackFloatValueE(simInt stackHandle, simFloat *numberValue)
{
    simInt ret = simGetStackFloatValue(stackHandle, numberValue);
    if(ret == -1)
        throw exception("simGetStackFloatValue: error");
    return ret;
}

simInt simGetStackDoubleValueE(simInt stackHandle, simDouble *numberValue)
{
    simInt ret = simGetStackDoubleValue(stackHandle, numberValue);
    if(ret == -1)
        throw exception("simGetStackDoubleValue: error");
    return ret;
}

simChar* simGetStackStringValueE(simInt stackHandle, simInt *stringSize)
{
    simChar *ret = simGetStackStringValue(stackHandle, stringSize);
    // if stringSize is NULL, we cannot distinguish error (-1) from type error (0)
    if(ret == NULL && stringSize && *stringSize == -1)
        throw exception("simGetStackStringValue: error");
    return ret;
}

simInt simGetStackTableInfoE(simInt stackHandle, simInt infoType)
{
    simInt ret = simGetStackTableInfo(stackHandle, infoType);

#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simGetStackTableInfo(stack, " << infoType << ") -> " << ret << std::endl;
    }
#endif // DEBUG

    if(ret == -1)
        throw exception("simGetStackTableInfo: error");
    return ret;
}

simInt simGetStackUInt8TableE(simInt stackHandle, simUChar *array, simInt count)
{
    simInt ret = simGetStackUInt8Table(stackHandle, array, count);
    if(ret == -1)
        throw exception("simGetStackUInt8Table: error");
    return ret;
}

simInt simGetStackInt32TableE(simInt stackHandle, simInt *array, simInt count)
{
    simInt ret = simGetStackInt32Table(stackHandle, array, count);
    if(ret == -1)
        throw exception("simGetStackInt32Table: error");
    return ret;
}

simInt simGetStackFloatTableE(simInt stackHandle, simFloat *array, simInt count)
{
    simInt ret = simGetStackFloatTable(stackHandle, array, count);
    if(ret == -1)
        throw exception("simGetStackFloatTable: error");
    return ret;
}

simInt simGetStackDoubleTableE(simInt stackHandle, simDouble *array, simInt count)
{
    simInt ret = simGetStackDoubleTable(stackHandle, array, count);
    if(ret == -1)
        throw exception("simGetStackDoubleTable: error");
    return ret;
}

simVoid simUnfoldStackTableE(simInt stackHandle)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: simUnfoldStackTable(stack)" << std::endl;
    }
#endif // DEBUG

    if(simUnfoldStackTable(stackHandle) == -1)
        throw exception("simUnfoldStackTable: error");
}

simInt simGetInt32ParameterE(simInt parameter)
{
    simInt ret;
    if(simGetInt32Parameter(parameter, &ret) == -1)
        throw exception("simGetInt32Parameter: error");
    return ret;
}

simChar* simCreateBufferE(simInt size)
{
    simChar *ret = simCreateBuffer(size);
    if(ret == NULL)
        throw exception("simCreateBuffer: error");
    return ret;
}

simVoid simReleaseBufferE(simChar *buffer)
{
    if(simReleaseBuffer(buffer) == -1)
        throw exception("simReleaseBuffer: error");
}

void read__bool(int stack, bool *value)
{
    simBool v;
    if(simGetStackBoolValueE(stack, &v) == 1)
    {
        *value = v;
        simPopStackItemE(stack, 1);
    }
    else
    {
        throw exception("expected bool");
    }
}

void read__int(int stack, int *value)
{
    int v;
    if(simGetStackInt32ValueE(stack, &v) == 1)
    {
        *value = v;
        simPopStackItemE(stack, 1);
    }
    else
    {
        throw exception("expected int");
    }
}

void read__float(int stack, float *value)
{
    simFloat v;
    if(simGetStackFloatValueE(stack, &v) == 1)
    {
        *value = v;
        simPopStackItemE(stack, 1);
    }
    else
    {
        throw exception("expected float");
    }
}

void read__double(int stack, double *value)
{
    simDouble v;
    if(simGetStackDoubleValueE(stack, &v) == 1)
    {
        *value = v;
        simPopStackItemE(stack, 1);
    }
    else
    {
        throw exception("expected double");
    }
}

void read__std__string(int stack, std::string *value)
{
    simChar *str;
    simInt strSize;
    if((str = simGetStackStringValueE(stack, &strSize)) != NULL && strSize >= 0)
    {
        *value = std::string(str, strSize);
        simPopStackItemE(stack, 1);
        simReleaseBufferE(str);
    }
    else
    {
        throw exception("expected string");
    }
}

#py for struct in plugin.structs:
void read__`struct.name`(int stack, `struct.name` *value)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: reading struct \"`struct.name`\"..." << std::endl;
    }
#endif // DEBUG

    try
    {
        simInt info = simGetStackTableInfoE(stack, 0);
        if(info == sim_stack_table_empty)
            return;
        if(info != sim_stack_table_map)
        {
#ifdef DEBUG
            if(isDebugStubsEnabled())
                simDebugStack(stack, -1);
#endif // DEBUG
            throw exception("expected a table");
        }

        int oldsz = simGetStackSizeE(stack);
        simUnfoldStackTableE(stack);
        int numItems = (simGetStackSizeE(stack) - oldsz + 1) / 2;

        char *str;
        int strSz;

        while(numItems >= 1)
        {
            simMoveStackItemToTopE(stack, oldsz - 1); // move key to top
            if((str = simGetStackStringValueE(stack, &strSz)) != NULL && strSz >= 0)
            {
                simPopStackItemE(stack, 1);

                simMoveStackItemToTopE(stack, oldsz - 1); // move value to top

                if(0) {}
#py for field in struct.fields:
                else if(strcmp(str, "`field.name`") == 0)
                {
#ifdef DEBUG
                    if(isDebugStubsEnabled())
                        std::cout << "DEBUG_STUBS: reading field \"`field.name`\"..." << std::endl;
#endif // DEBUG

                    try
                    {
#py if isinstance(field, model.ParamTable):
                        // read field '`field.name`' of type array of `field.ctype()`
                        simMoveStackItemToTopE(stack, 0);
                        int i = simGetStackTableInfoE(stack, 0);
                        if(i < 0)
                        {
#ifdef DEBUG
                            if(isDebugStubsEnabled())
                                simDebugStack(stack, -1);
#endif // DEBUG
                            throw exception((boost::format("expected array (simGetStackTableInfo(stack, 0) returned %d)") % i).str());
                        }
                        int oldsz = simGetStackSizeE(stack);
                        simUnfoldStackTableE(stack);
                        int sz = (simGetStackSizeE(stack) - oldsz + 1) / 2;
                        for(int i = 0; i < sz; i++)
                        {
                            simMoveStackItemToTopE(stack, oldsz - 1);
                            int j;
                            read__int(stack, &j);
                            simMoveStackItemToTop(stack, oldsz - 1);
                            `field.ctype_normalized()` v;
                            read__`field.ctype_normalized()`(stack, &v);
                            value->`field.name`.push_back(v);
                        }
#py if field.minsize > 0 and field.minsize == field.maxsize:
                        if(value->`field.name`.size() != `field.minsize`)
                            throw exception("must have exactly `field.minsize` elements");
#py else:
#py if field.minsize > 0:
                        if(value->`field.name`.size() < `field.minsize`)
                            throw exception("must have at least `field.minsize` elements");
#py endif
#py if field.maxsize is not None:
                        if(value->`field.name`.size() > `field.maxsize`)
                            throw exception("must have at most `field.maxsize` elements");
#py endif
#py endif
#py else:
                        // read field '`field.name`' of type `field.ctype()`
                        read__`field.ctype_normalized()`(stack, &(value->`field.name`));
#py endif
                    }
                    CATCH_AND_RETHROW("field '`field.name`': ")
                }
#py endfor
                else
                {
                    std::string msg = "unexpected key: ";
                    msg += str;
                    throw exception(msg);
                }
            }
            numItems = (simGetStackSizeE(stack) - oldsz + 1) / 2;
        }
    }
    CATCH_AND_RETHROW("read__`struct.name`: ")
}

#py endfor
void write__bool(bool value, int stack)
{
    simBool v = value;
    simPushBoolOntoStackE(stack, v);
}

void write__int(int value, int stack)
{
    simInt v = value;
    simPushInt32OntoStackE(stack, v);
}

void write__float(float value, int stack)
{
    simFloat v = value;
    simPushFloatOntoStackE(stack, v);
}

void write__double(double value, int stack)
{
    simDouble v = value;
    simPushDoubleOntoStackE(stack, v);
}

void write__std__string(std::string value, int stack)
{
    const simChar *v = value.c_str();
    simPushStringOntoStackE(stack, v, value.length());
}

#py for struct in plugin.structs:
void write__`struct.name`(`struct.name` *value, int stack)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: writing struct \"`struct.name`\"..." << std::endl;
    }
#endif // DEBUG

    try
    {
        simPushTableOntoStackE(stack);

#py for field in struct.fields:
        try
        {
#ifdef DEBUG
            if(isDebugStubsEnabled())
                std::cout << "DEBUG_STUBS: writing field \"`field.name`\"..." << std::endl;
#endif // DEBUG

            simPushStringOntoStackE(stack, "`field.name`", 0);
#py if isinstance(field, model.ParamTable):
            // write field '`field.name`' of type array of `field.ctype()`
            simPushTableOntoStackE(stack);
            for(int i = 0; i < value->`field.name`.size(); i++)
            {
                write__int(i + 1, stack);
                write__`field.ctype_normalized()`(`field.argmod()`(value->`field.name`[i]), stack);
                simInsertDataIntoStackTableE(stack);
            }
#py else:
            // write field '`field.name`' of type `field.ctype()`
            write__`field.ctype_normalized()`(`field.argmod()`(value->`field.name`), stack);
#py endif
            simInsertDataIntoStackTableE(stack);
        }
        CATCH_AND_RETHROW("field '`field.name`': ")
#py endfor
    }
    CATCH_AND_RETHROW("write__`struct.name`: ")
}

#py endfor
#py for struct in plugin.structs:
`struct.name`::`struct.name`()
{
#py for field in struct.fields:
#py if field.default:
    `field.name` = `field.cdefault()`;
#py endif
#py endfor
}

#py endfor
bool registerScriptStuff()
{
    try
    {
        {
            simInt vrepVer = 0, vrepRev = 0, vrepMinVer = 30400, vrepMinRev = 9;
            simGetIntegerParameter(sim_intparam_program_version, &vrepVer);
            simGetIntegerParameter(sim_intparam_program_revision, &vrepRev);
            if(vrepVer < vrepMinVer || (vrepVer == vrepMinVer && vrepRev < vrepMinRev))
            {
                std::stringstream ss;
                ss << "this plugin requires at least V-REP " << (vrepMinVer / 10000) << "." << (vrepMinVer / 100 % 100) << "." << (vrepMinVer % 100) << " rev" << vrepMinRev;
                throw exception(ss.str());
            }
        }
        try
        {
#py if plugin.short_name:
            simRegisterScriptVariableE("sim`plugin.short_name`", "{}", 0);
            simRegisterScriptVariableE("sim`plugin.short_name`", "require('simExt`plugin.name`')", 0);
#py endif

#py if plugin.short_name:
            // register new-style short-version varables
#py for enum in plugin.enums:
            simRegisterScriptVariableE("sim`plugin.short_name`.`enum.name`", "{}", 0);
#py for item in enum.items:
            simRegisterScriptVariableE("sim`plugin.short_name`.`enum.name`.`item`", (boost::lexical_cast<std::string>(sim_`plugin.short_name.lower()`_`enum.item_prefix``item`)).c_str(), 0);
#py endfor
#py endfor
            // register new-style short-version commands
#py for cmd in plugin.commands:
            simRegisterScriptCallbackFunctionE("sim`plugin.short_name`.`cmd.name`@`plugin.name`", "`cmd.help_out_args_text`sim`plugin.short_name`.`cmd.name`(`cmd.help_in_args_text`)`cmd.documentation`", `cmd.name`_callback);
#py endfor
#py endif

#py if plugin.short_name:
            // commands simExt<PLUGIN_NAME>_<COMMAND_NAME> (deprecated)
#py for cmd in plugin.commands:
            simRegisterScriptCallbackFunctionE("`plugin.command_prefix``cmd.name`@`plugin.name`", "`cmd.help_text`\n\n(DEPRECATED, please use sim`plugin.short_name`.`cmd.name`)", `cmd.name`_callback);
#py endfor
            // register variables (deprecated)
#py for enum in plugin.enums:
#py for item in enum.items:
            simRegisterScriptVariableE("sim_`plugin.name.lower()`_`enum.item_prefix``item`", (boost::lexical_cast<std::string>(sim_`plugin.name.lower()`_`enum.item_prefix``item`)).c_str(), -1);
#py endfor
#py endfor
#py else:
            // commands simExt<PLUGIN_NAME>_<COMMAND_NAME>
#py for cmd in plugin.commands:
            simRegisterScriptCallbackFunctionE("`plugin.command_prefix``cmd.name`@`plugin.name`", "`cmd.help_text``cmd.documentation`", `cmd.name`_callback);
#py endfor
            // register variables
#py for enum in plugin.enums:
#py for item in enum.items:
            simRegisterScriptVariableE("sim_`plugin.name.lower()`_`enum.item_prefix``item`", (boost::lexical_cast<std::string>(sim_`plugin.name.lower()`_`enum.item_prefix``item`)).c_str(), 0);
#py endfor
#py endfor
#py endif

#include "lua_calltips.cpp"
        }
        CATCH_AND_RETHROW("Initialization failed (registerScriptStuff): ")
    }
    catch(exception& ex)
    {
        std::cout << ex.what() << std::endl;
        return false;
    }
    return true;
}

#py for enum in plugin.enums:
const char* `enum.name.lower()`_string(`enum.name` x)
{
    switch(x)
    {
#py for item in enum.items:
        case sim_`plugin.name.lower()`_`enum.item_prefix``item`: return "sim_`plugin.name.lower()`_`enum.item_prefix``item`";
#py endfor
        default: return "???";
    }
}

#py endfor
#py for cmd in plugin.commands:
`cmd.name`_in::`cmd.name`_in()
{
#py for p in cmd.params:
#py if p.cdefault() is not None:
    `p.name` = `p.cdefault()`;
#py endif
#py endfor
}

`cmd.name`_out::`cmd.name`_out()
{
#py for p in cmd.returns:
#py if p.cdefault() is not None:
    `p.name` = `p.cdefault()`;
#py endif
#py endfor
}

void `cmd.name`(SScriptCallBack *p, `cmd.name`_in *in_args, `cmd.name`_out *out_args)
{
    `cmd.name`(p, "`plugin.command_prefix``cmd.name`", in_args, out_args);
}

#py if len(cmd.returns) == 1:
`cmd.returns[0].ctype()` `cmd.name`(`cmd.c_arg_list(pre_args=['SScriptCallBack *p'])`)
{
    `cmd.name`_in in_args;
#py for p in cmd.params:
    in_args.`p.name` = `p.name`;
#py endfor
    `cmd.name`_out out_args;
    `cmd.name`(p, &in_args, &out_args);
    return out_args.`cmd.returns[0].name`;
}

#py endif
#py if len(cmd.returns) == 0:
void `cmd.name`(`cmd.c_arg_list(pre_args=['SScriptCallBack *p'])`)
{
    `cmd.name`_in in_args;
#py for p in cmd.params:
    in_args.`p.name` = `p.name`;
#py endfor
    `cmd.name`_out out_args;
    `cmd.name`(p, &in_args, &out_args);
}

#py endif
void `cmd.name`(`cmd.c_arg_list(pre_args=['SScriptCallBack *p', '%s_out *out_args' % cmd.name])`)
{
    `cmd.name`_in in_args;
#py for p in cmd.params:
    in_args.`p.name` = `p.name`;
#py endfor
    `cmd.name`(p, &in_args, out_args);
}

void `cmd.name`_callback(SScriptCallBack *p)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: script callback for \"`cmd.name`\"..." << std::endl;
        std::cout << "DEBUG_STUBS: reading input arguments..." << std::endl;
        simDebugStack(p->stackID, -1);
    }
#endif // DEBUG

    const char *cmd = "`plugin.command_prefix``cmd.name`";

    `cmd.name`_in in_args;
    `cmd.name`_out out_args;

    try
    {
        // check argument count

        int numArgs = simGetStackSizeE(p->stackID);
        if(numArgs < `cmd.params_min`)
            throw exception("not enough arguments");
        if(numArgs > `cmd.params_max`)
            throw exception("too many arguments");

        // read input arguments from stack

#py for i, p in enumerate(cmd.params):
        if(numArgs >= `i+1`)
        {
#ifdef DEBUG
            if(isDebugStubsEnabled())
                std::cout << "DEBUG_STUBS: reading input argument `i+1` (`p.name`)..." << std::endl;
#endif // DEBUG

            try
            {
#py if isinstance(p, model.ParamTable):
#py if p.itype in ('float', 'double', 'int'):
                // read input argument `i+1` (`p.name`) of type array of `p.ctype()` using fast function
                simMoveStackItemToTopE(p->stackID, 0);
                int sz = simGetStackTableInfoE(p->stackID, 0);
                if(sz < 0)
                {
#ifdef DEBUG
                    if(isDebugStubsEnabled())
                        simDebugStack(p->stackID, -1);
#endif // DEBUG
                    throw exception((boost::format("expected array (simGetStackTableInfo(stack, 0) returned %d)") % sz).str());
                }
                if(simGetStackTableInfoE(p->stackID, 2) != 1)
                {
                    throw exception("fast_write_type reader exception #1 (simGetStackTableInfo(stack, 2) returned error)");
                }
                in_args.`p.name`.resize(sz);
#py if p.itype == 'float':
                simGetStackFloatTableE(p->stackID, &(in_args.`p.name`[0]), sz);
#py elif p.itype == 'double':
                simGetStackDoubleTableE(p->stackID, &(in_args.`p.name`[0]), sz);
#py elif p.itype == 'int':
                simGetStackInt32TableE(p->stackID, &(in_args.`p.name`[0]), sz);
#py endif
                simPopStackItemE(p->stackID, 1);
#py else:
                // read input argument `i+1` (`p.name`) of type array of `p.ctype()`
                simMoveStackItemToTopE(p->stackID, 0);
                int i = simGetStackTableInfoE(p->stackID, 0);
                if(i < 0)
                {
#ifdef DEBUG
                    if(isDebugStubsEnabled())
                        simDebugStack(p->stackID, -1);
#endif // DEBUG
                    throw exception((boost::format("expected array (simGetStackTableInfo(stack, 0) returned %d)") % i).str());
                }
                int oldsz = simGetStackSizeE(p->stackID);
                simUnfoldStackTableE(p->stackID);
                int sz = (simGetStackSizeE(p->stackID) - oldsz + 1) / 2;
                for(int i = 0; i < sz; i++)
                {
                    simMoveStackItemToTopE(p->stackID, oldsz - 1);
                    int j;
                    read__int(p->stackID, &j);
                    simMoveStackItemToTop(p->stackID, oldsz - 1);
                    `p.item_dummy().ctype()` v;
                    read__`p.ctype_normalized()`(p->stackID, &v);
                    in_args.`p.name`.push_back(v);
                }
#py endif

#py if p.minsize > 0 and p.minsize == p.maxsize:
                if(in_args.`p.name`.size() != `p.minsize`)
                    throw exception("must have exactly `p.minsize` elements");
#py else:
#py if p.minsize > 0:
                if(in_args.`p.name`.size() < `p.minsize`)
                    throw exception("must have at least `p.minsize` elements");
#py endif
#py if p.maxsize is not None:
                if(in_args.`p.name`.size() > `p.maxsize`)
                    throw exception("must have at most `p.maxsize` elements");
#py endif
#py endif
#py else:
                // read input argument `i+1` (`p.name`) of type `p.ctype()`
                simMoveStackItemToTopE(p->stackID, 0);
                read__`p.ctype_normalized()`(p->stackID, &(in_args.`p.name`));
#py endif
            }
            CATCH_AND_RETHROW("read in arg `i+1` (`p.name`): ")
        }

#py endfor

#ifdef DEBUG
        if(isDebugStubsEnabled())
            simDebugStack(p->stackID, -1);
#endif // DEBUG

#py if cmd.clear_stack_after_reading_input:
        // clear stack
        simPopStackItemE(p->stackID, 0);

#py endif
        `cmd.name`(p, cmd, &in_args, &out_args);
    }
    catch(std::exception& e)
    {
#ifdef DEBUG
        std::cerr << cmd << ": " << e.what() << std::endl;
#endif
        simSetLastError(cmd, e.what());
    }
    catch(std::string& s)
    {
#ifdef DEBUG
        std::cerr << cmd << ": " << s << std::endl;
#endif
        simSetLastError(cmd, s.c_str());
    }
    catch(int& n)
    {
        std::stringstream ss;
        ss << "error #" << n;
#ifdef DEBUG
        std::cerr << cmd << ": " << ss.str() << std::endl;
#endif
        simSetLastError(cmd, ss.str().c_str());
    }

    try
    {
#ifdef DEBUG
        if(isDebugStubsEnabled())
        {
            std::cout << "DEBUG_STUBS: writing output arguments..." << std::endl;
            simDebugStack(p->stackID, -1);
        }
#endif // DEBUG

#py if cmd.clear_stack_before_writing_output:
        // clear stack
        simPopStackItemE(p->stackID, 0);

#py endif

        // write output arguments to stack

#py for i, p in enumerate(cmd.returns):
        try
        {
#ifdef DEBUG
            if(isDebugStubsEnabled())
                std::cout << "DEBUG_STUBS: writing output argument `i+1` (`p.name`)..." << std::endl;
#endif // DEBUG

#py if isinstance(p, model.ParamTable):
            // write output argument `i+1` (`p.name`) of type array of `p.ctype()`
            simPushTableOntoStackE(p->stackID);
            for(int i = 0; i < out_args.`p.name`.size(); i++)
            {
                write__int(i + 1, p->stackID);
                write__`p.ctype_normalized()`(`p.argmod()`(out_args.`p.name`[i]), p->stackID);
                simInsertDataIntoStackTableE(p->stackID);
            }
#py else:
            // write output argument `i+1` (`p.name`) of type `p.ctype()`
            write__`p.ctype_normalized()`(`p.argmod()`(out_args.`p.name`), p->stackID);
#py endif
        }
        CATCH_AND_RETHROW("write out arg `i+1` (`p.name`): ")
#py endfor

#ifdef DEBUG
        if(isDebugStubsEnabled())
            simDebugStack(p->stackID, -1);
#endif // DEBUG
    }
    catch(std::exception& e)
    {
#ifdef DEBUG
        std::cerr << cmd << ": " << e.what() << std::endl;
#endif
        simSetLastError(cmd, e.what());
        // clear stack
        simPopStackItem(p->stackID, 0); // don't throw
    }
    catch(std::string& s)
    {
#ifdef DEBUG
        std::cerr << cmd << ": " << s << std::endl;
#endif
        simSetLastError(cmd, s.c_str());
        // clear stack
        simPopStackItem(p->stackID, 0); // don't throw
    }
    catch(int& n)
    {
        std::stringstream ss;
        ss << "error #" << n;
#ifdef DEBUG
        std::cerr << cmd << ": " << ss.str() << std::endl;
#endif
        simSetLastError(cmd, ss.str().c_str());
        // clear stack
        simPopStackItem(p->stackID, 0); // don't throw
    }
}

#py endfor
#py for fn in plugin.script_functions:
`fn.name`_in::`fn.name`_in()
{
#py for p in fn.params:
#py if p.default is not None:
    `p.name` = `p.cdefault()`;
#py endif
#py endfor
}

`fn.name`_out::`fn.name`_out()
{
#py for p in fn.returns:
#py if p.default is not None:
    `p.name` = `p.cdefault()`;
#py endif
#py endfor
}

bool `fn.name`(simInt scriptId, const char *func, `fn.name`_in *in_args, `fn.name`_out *out_args)
{
#ifdef DEBUG
    if(isDebugStubsEnabled())
    {
        std::cout << "DEBUG_STUBS: script callback function for \"`fn.name`\"..." << std::endl;
        std::cout << "DEBUG_STUBS: writing input arguments..." << std::endl;
    }
#endif // DEBUG

    int stackID = -1;

    try
    {
        stackID = simCreateStackE();

        // write input arguments to stack

#py for i, p in enumerate(fn.params):
        try
        {
#py if isinstance(p, model.ParamTable):
            // write input argument `i+1` (`p.name`) of type array of `p.ctype()`
            simPushTableOntoStackE(stackID);
            for(int i = 0; i < in_args->`p.name`.size(); i++)
            {
                write__int(i + 1, stackID);
                write__`p.ctype_normalized()`(`p.argmod()`(in_args->`p.name`[i]), stackID);
                simInsertDataIntoStackTableE(stackID);
            }
#py else:
            // write input argument `i+1` (`p.name`) of type `p.ctype()`
            write__`p.ctype_normalized()`(`p.argmod()`(in_args->`p.name`), stackID);
#py endif
        }
        CATCH_AND_RETHROW("writing input argument `i+1` (`p.name`): ")
#py endfor

#ifdef DEBUG
        if(isDebugStubsEnabled())
            simDebugStack(stackID, -1);
#endif // DEBUG

        simCallScriptFunctionExE(scriptId, func, stackID);

        // read output arguments from stack

#ifdef DEBUG
        if(isDebugStubsEnabled())
            std::cout << "DEBUG_STUBS: reading output arguments..." << std::endl;
#endif // DEBUG

#py for i, p in enumerate(fn.returns):
        try
        {
#py if isinstance(p, model.ParamTable):
            // read output argument `i+1` (`p.name`) of type array of `p.ctype()`
            simMoveStackItemToTopE(stackID, 0);
            int i = simGetStackTableInfoE(stackID, 0);
            if(i < 0)
            {
#ifdef DEBUG
                if(isDebugStubsEnabled())
                    simDebugStack(stackID, -1);
#endif // DEBUG
                throw exception((boost::format("expected array (simGetStackTableInfo(stack, 0) returned %d)") % i).str());
            }
            int oldsz = simGetStackSizeE(stackID);
            simUnfoldStackTableE(stackID);
            int sz = (simGetStackSizeE(stackID) - oldsz + 1) / 2;
            for(int i = 0; i < sz; i++)
            {
                simMoveStackItemToTopE(stackID, oldsz - 1);
                int j;
                read__int(stackID, &j);
                simMoveStackItemToTop(stackID, oldsz - 1);
                `p.ctype_normalized()` v;
                read__`p.ctype_normalized()`(stackID, &v);
                out_args->`p.name`.push_back(v);
            }
#py if p.minsize > 0 and p.minsize == p.maxsize:
            if(out_args->`p.name`.size() != `p.minsize`)
                throw exception("must have exactly `p.minsize` elements");
#py else:
#py if p.minsize > 0:
            if(out_args->`p.name`.size() < `p.minsize`)
                throw exception("must have at least `p.minsize` elements");
#py endif
#py if p.maxsize is not None:
            if(out_args->`p.name`.size() > `p.maxsize`)
                throw exception("must have at most `p.maxsize` elements");
#py endif
#py endif
#py else:
            // read output argument `i+1` (`p.name`) of type `p.ctype()`
            read__`p.ctype_normalized()`(stackID, &(out_args->`p.name`));
#py endif
        }
        CATCH_AND_RETHROW("read out arg `i+1` (`p.name`): ")
#py endfor

#ifdef DEBUG
        if(isDebugStubsEnabled())
            simDebugStack(stackID, -1);
#endif // DEBUG

        simReleaseStackE(stackID);
        stackID = -1;
    }
    catch(std::exception& ex)
    {
        if(stackID != -1)
            simReleaseStack(stackID); // don't throw
        simSetLastError(func, ex.what());
        return false;
    }
    catch(std::string& s)
    {
        if(stackID != -1)
            simReleaseStack(stackID); // don't throw
        simSetLastError(func, s.c_str());
        return false;
    }
    catch(int& n)
    {
        if(stackID != -1)
            simReleaseStack(stackID); // don't throw
        std::stringstream ss;
        ss << "error #" << n;
        simSetLastError(func, ss.str().c_str());
        return false;
    }

    return true;
}

#py endfor


text:
//  Copyright (c) 2015 Hartmut Kaiser
//
//  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)

#include <hpx/hpx.hpp>
#include <hpx/hpx_init.hpp>
#include <hpx/include/parallel_algorithm.hpp>

#include <boost/range/functions.hpp>

#include <cstddef>
#include <cstdlib>
#include <iostream>
#include <utility>
#include <vector>

///////////////////////////////////////////////////////////////////////////////
template <typename T>
struct safe_object
{
private:
    HPX_MOVABLE_ONLY(safe_object);

public:
    safe_object()
      : data_(hpx::get_os_thread_count())
    {
    }

    safe_object(safe_object && rhs)
      : data_(std::move(rhs.data_))
    {}

    safe_object& operator=(safe_object && rhs)
    {
        if (this != &rhs)
            data_ = std::move(rhs.data_);
        return *this;
    }

    T& get()
    {
        std::size_t idx = hpx::get_worker_thread_num();
        HPX_ASSERT(idx < hpx::get_os_thread_count());
        return data_[idx];
    }

    T const& get() const
    {
        std::size_t idx = hpx::get_worker_thread_num();
        HPX_ASSERT(idx < hpx::get_os_thread_count());
        return data_[idx];
    }

    template <typename F>
    void reduce (F const& f) const
    {
        for (T const& d : data_)
        {
            f(d);
        }
    }

private:
    std::vector<T> data_;
};

///////////////////////////////////////////////////////////////////////////////
std::vector<int> random_fill(std::size_t size)
{
    std::vector<int> c(size);
    std::generate(boost::begin(c), boost::end(c), std::rand);
    return c;
}

inline bool satisfies_criteria(int d)
{
    return d > 500 && (d % 7) == 0;
}

int hpx_main(int argc, char* argv[])
{
    using hpx::parallel::for_each;
    using hpx::parallel::execution::par;

    // initialize data
    std::vector<int> data = random_fill(1000);

    // run a parallel loop to demonstrate thread safety of safe-object
    safe_object<std::vector<int> > ho;
    for_each(par, boost::begin(data), boost::end(data),
        [&ho](int d)
        {
            if (satisfies_criteria(d))
                ho.get().push_back(d);
        });

    // invoke the given reduce operation on the safe-object
    std::vector<int> result;
    ho.reduce(
        [&result](std::vector<int> const& chunk)
        {
            result.insert(result.end(), chunk.begin(), chunk.end());
        });

    // make sure all numbers conform to criteria
    for (int i : result)
    {
        if (!satisfies_criteria(i))
        {
            std::cout << "Number does not satisfy given criteria: " << i << "\n";
        }
    }

    return hpx::finalize();
}

int main(int argc, char* argv[])
{
    // Initialize and run HPX
    return hpx::init(argc, argv);
}

max_stars_repo_name: STEllAR-GROUP/hpxML

max_issues_repo_name: STEllAR-GROUP/hpxML

max_forks_repo_name: STEllAR-GROUP/hpxML


text:
//------------------------------------------------------------------------------
/// \file WordCountingState_tests.cpp
//------------------------------------------------------------------------------
#include "Categories/AlgebraicDataTypes/WordCountingState.h"

#include "Tools/TemporaryDirectory.h"

#include <boost/test/unit_test.hpp>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>

using Categories::AlgebraicDataTypes::WordCounting::ProgramT;
using Categories::AlgebraicDataTypes::WordCounting::States::RunningT;

using Tools::TemporaryDirectory;

BOOST_AUTO_TEST_SUITE(Categories)
BOOST_AUTO_TEST_SUITE(AlgebraicDataTypes)
BOOST_AUTO_TEST_SUITE(WordCountingState_tests)

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(StatesConstructs)
{
  BOOST_TEST(true);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(RunningTCountsWords)
{
  {
    const std::string& file_name {"main.cpp"};
    std::ifstream file_eg {file_name};
    auto count {
      std::distance(
        std::istream_iterator<std::string>(file_eg),
        std::istream_iterator<std::string>())};

    std::cout << count << std::endl;
  }

  RunningT running {"WordCountingState_tests.cpp"};
  running.count_words();
  std::cout << running.count() << std::endl;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ProgramTCountsWords)
{
  ProgramT program;
  program.count_words("main.cpp");
  std::cout << "Program count : " << program.count() << std::endl;
  BOOST_TEST(program.count() == 0);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ProgramTCounts)
{
  // cf. https://en.cppreference.com/w/cpp/io/basic_ifstream
  TemporaryDirectory temp_dir {"/temp"};
  std::string filename {"Test.txt"};
  const std::string full_filepath {temp_dir.path() + "/" + filename};
  std::ofstream temp_out {full_filepath};
  temp_out << "As we knelt on the kitchen floor \n" <<
    "I said mommy Imma love you till you don't hurt no more \n" <<
    "And when I'm older, you aint gotta work no more \n" <<
    "And Imma get you that mansion that we couldn't afford \n" <<
    "See you're, unbreakable, unmistakable \n" <<
    "Highly capable, lady that's makin loot \n" <<
    "A livin legend too, just look at what heaven do \n" <<
    "Send us an angel, and I thank you (Hey Mama) \n";
  temp_out.close();

  std::ifstream temp_in {full_filepath};
  std::cout << temp_in.rdbuf() << '\n';
  std::ifstream temp_in2 {full_filepath};
  std::cout << temp_in2.rdbuf() << '\n';
  std::ifstream temp_in3 {full_filepath};
  std::istream_iterator<std::string> temp_iter {temp_in3};

  auto temp_distance =
    std::distance(temp_iter, std::istream_iterator<std::string>());
  std::cout << " temp distance : " << temp_distance << '\n';

  RunningT running {full_filepath};
  running.count_words();
  BOOST_TEST(running.count() == 69);

  ProgramT program;
  BOOST_TEST(program.count() == 0);
  program.count_words(full_filepath);
  std::cout << "Program count : " << program.count() << std::endl;
  BOOST_TEST(program.count() == 69);
}

BOOST_AUTO_TEST_SUITE_END() // WordCountingState_tests
BOOST_AUTO_TEST_SUITE_END() // AlgebraicDataTypes
BOOST_AUTO_TEST_SUITE_END() // Categories

max_stars_repo_name: ernestyalumni/HrdwCCppCUDA

max_issues_repo_name: ernestyalumni/HrdwCCppCUDA

max_forks_repo_name: ernestyalumni/HrdwCCppCUDA


text:
#pragma once

#include <vector>

#include <Eigen/Geometry>
#include <iostream>
#include <geometry_msgs/Vector3.h>
#include <moveit/robot_state/robot_state.h>
#include <moveit/robot_model/robot_model.h>

#include "../include/util/typedefs.hpp"

class OmniMath {
    private:

    MovingAverage moving_average(5,6);

    const bool enable_moving_average;

    public:

    template <typename Type>
    Type saturate(Type value, Type min, Type max) {
        if (value < min) {
            return min;
        }
        if (value > max) {
            return max;
        }
        return value;
    }

    template <typename Type>
    std::vector<Type> saturate(std::vector<Type> values, Type min, Type max) {
        std::vector<Type> s(values.size())
        for (auto iter = values.begin(); iter < values.end(); ++iter) {
            s[iter-values.begin()] = saturate(*iter, min, max);
        }
        return s;
    }

    Eigen::Affine3d fowardKinematics(
        robot_state::RobotStatePtr kinematic_state,
        std::string link_name) {
            return kinematic_state->getGlobalLinkTransform(link_name);
    }

    Eigen::Vector3d OmniBase::calculateTorqueFeedback(
        robot_state::RobotStatePtr kinematic_state,
        robot_state::JointModelGroup* joint_model_group,
        //const Eigen::Vector3d& force,
        const Eigen::Vector3d force,
        Eigen::Matrix3d rot_link_to_teleop,
        double feedback_gain,
        std::string end_effector_name,
        const robot_state::LinkModel* end_effector_link_model) {
            if (feedback_gain == 0)
                return Eigen::Vector3d::Zero();

            // Get the Jacobian matrix written on the base frame
            Eigen::Vector3d origin(0,0.08,0);
            Eigen::MatrixXd jacobian;
            auto link_model = kinematic_state->getLinkModel(end_effector_name);
            kinematic_state->getJacobian(joint_model_group, link_model, origin, jacobian, false);

            // Rotate the force vector from the desired frame to the base frame
            Eigen::Vector3d force_on_link_frame = rot_link_to_teleop * force;
            //
            auto quat_base_link = fowardKinematics(kinematic_state, end_effector_name)
            force_on_link_frame = quat_base_link.conjugate() * force_on_link_frame;

            auto ret = feedback_gain * jacobian.block<3,3>(0,0).transpose() * force_on_link_frame;
            return ret.block<3,1>(0,0);
        }

    Eigen::VectorXd jerkSaturationFilter(
        Eigen::VectorXd previous_calculated_velocities,
        Eigen::VectorXd current_calculated_velocities,
        double max_jerk) {
            std:vector<double> saturated_velocities(6);
            for (int i = 0; i < 6; ++i) {
                if ( std::abs(current_calculated_velocities[i] - previous_calculated_velocites[i]) < max_jerk ) {
                    saturated_velocities[i] = current_calculated_velocities[i];
                }
                else {
                    saturated_velocities[i] = previous_calculated_velocities[i];
                }
            }
            Eigen::VectorXd eigen_vector(saturated_velocities.data());
            return eigen_vector;
        }

    Eigen::VectorXd calculateVelocities(
        Time previous_measurement_time,
        Time current_measurement_time,
        Eigen::VectorXd previous_measurement,
        Eigen::VecotrXd current_measurement,
        bool enable_moving_average) {
            double delta_angle;
            double delta_t = (current_measurement_time - previous_measurement_time).total_microseconds();
            std::vector<double> calculated_velocities(6);
            for (int i = 0; i < 6; ++i) {
                deltaAngle = current_measurement[i] - previous_measurement[i];
                calculated_velocities[i] = deltaAngle * 1000000 / dt;
            }
            if (enable_moving_average) {
                moving_average.input(calculated_velocities);
                Eigen::VectorXd joint_velocities(moving_average.mean.data());
            }
            else Eigen::VectorXd joint_velocities(calculated_velocities.data());
            return joint_velocities(6);
        }

    Eigen::VectorXd calculateTwist(
        robot_state::RobotStatePtr kinematic_state,
        robot_state::JointModelGroup* joint_model_group,
        robot_state::LinkModel* end_effector_link_model,
        Eigen::VectorXd current_joint_velocities) {
        std::vector<double> twist;
        Eigen::Vector3d origin(0,0,0);
        Eigen::MatrixXd jacobian(6,6);
        kinematic_state->getJacobian(joint_model_group, end_effector_link_model, origin, jacobian, false);
        return jacobian * current_joint_velocities;
    }

public:
    /**
     * @brief OmniBase constructor, sets some members and prepares ros topics and publishers.
     * @param name Reference to string of omni name.
     */
    explicit OmniMath(const bool enable_moving_average);
};

ext: hpp


text:
#pragma once

#include <wls/app/plugin.hpp>
#include <boost/any.hpp>

namespace wls {
    namespace plugin {
        namespace changelog {

            namespace detail { class changelog_impl; }

            typedef std::vector<std::string> changelog_block;

            using app::application;

            class changelog_plugin : public wls::app::plugin {
                std::shared_ptr<detail::changelog_impl> my;
            public:
                /**
                * The plugin requires a constructor which takes app.  This is called regardless of whether the plugin is loaded.
                * The app parameter should be passed up to the superclass constructor.
                */
                changelog_plugin(application *app);

                /**
                * Plugin is destroyed via base class pointer, so a virtual destructor must be provided.
                */
                virtual ~changelog_plugin();

                /**
                * Every plugin needs a name.
                */
                virtual std::string plugin_name() const override;

                /**
                * Called when the plugin is enabled, but before the database has been created.
                */
                virtual void plugin_initialize(const boost::program_options::variables_map &options) override;

                /**
                * Called when the plugin is enabled.
                */
                virtual void plugin_startup() override;

                /**
                * Called when the plugin is shutdown.
                */
                virtual void plugin_shutdown() override;

                ////////////////////////////////////////////////////////////////////////////////
                DB *get_changelog_db();

            private:
            };

        }
    }
}

max_stars_repo_name: pranishg/VIDPOW

max_issues_repo_name: pranishg/VIDPOW

max_forks_repo_name: pranishg/VIDPOW


text:
#include <stdio.h>
#include <string>
#include <map>
#include <fstream>
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <array>
#include <regex>
#include "helper.h"
#include "klee/ExecutionState.h"
#include "Executor.h"
#include <cmath>
#include <math.h>
#include <vector>
#include <boost/lambda/lambda.hpp>
#include <boost/math/distributions/beta.hpp>
#include "TeleScopeHandler.h"

using namespace klee;
using namespace std;
using namespace llvm;

//==============================================
//============= TeleScopeHandler ===============
//==============================================

TeleScopeHandler::TeleScopeHandler(int n)
{
   numLoop = n;
}

int TeleScopeHandler::ProcessAllPaths(vector<ExecutionState *> states)
{
   LOG(LOG_MASK_TS, "Telescoping done, final result is %g",
       TeleScopeData::finalResult / numLoop);
   return 0;
}

int TeleScopeHandler::ts_init_handler(ExecutionState *state,
                                      int small_thres, int real_thres)
{
   state->tsData.ts_init(state, small_thres, real_thres);
   return 0;
}

int TeleScopeHandler::ts_pkt_handler(ExecutionState *state,
                                      int pktID, int cur_reg)
{
   assert(state == state->tsData.getState());
   state->tsData.ts_pkt(pktID, cur_reg);
   return 0;
}

int TeleScopeHandler::ts_handler(ExecutionState *state, int cur_reg)
{
   assert(state == state->tsData.getState());
   state->tsData.ts_final(cur_reg);
   return 0;
}

int TeleScopeHandler::ts_cmin_pkt_handler(ExecutionState *state,
                                          int pktID)
{
   assert(state == state->tsData.getState());
   int cmin_max = state->cmin->getMaxValue();
   state->tsData.ts_pkt(pktID, cmin_max);
   return 0;
}

int TeleScopeHandler::ts_cmin_handler(ExecutionState *state)
{
   assert(state == state->tsData.getState());
   int cmin_max = state->cmin->getMaxValue();
   state->tsData.ts_final(cmin_max);
   return 0;
}

//==============================================
//============= TeleScopeData ==================
//==============================================

double TeleScopeData::finalResult = 0.0;

TeleScopeData::TeleScopeData():
   reg(0),
   smallThres(0),
   realThres(0),
   pktProbs(0)
{}

TeleScopeData::TeleScopeData(const TeleScopeData &_tsData):
   state(_tsData.state),
   reg(_tsData.reg),
   smallThres(_tsData.smallThres),
   realThres(_tsData.realThres),
   perPktProbs(_tsData.perPktProbs),
   pktProbs(_tsData.pktProbs),
   pktRegs(_tsData.pktRegs)
{

}

void TeleScopeData::dump()
{
   uint32_t i;
   LOG(LOG_MASK_TS, "state %d has %ld pkt probs", state->id, perPktProbs.size());
   for (i = 0; i < pktProbs.size(); i ++) {
      LOG(LOG_MASK_TS, "pkt[%d] prob=%g", i, perPktProbs[i])
   }

   LOG(LOG_MASK_TS, "state %d has %ld pkt regs", state->id, pktRegs.size());
   for (i = 0; i < pktRegs.size(); i ++) {
      LOG(LOG_MASK_TS, "pkt[%d] reg=%d", i, pktRegs[i])
   }
}

int TeleScopeData::ts_init(ExecutionState *s, int small_thres, int real_thres)
{
   LOG(LOG_MASK_TS, "Initing TsData, small thres=%d, real thres=%d",
       small_thres, real_thres);
   state = s;
   smallThres = small_thres;
   realThres  = real_thres;
   return 0;
}

int TeleScopeData::ts_pkt(int pktID, int cur_reg)
{
   //LOG(LOG_MASK_TS, "Updating TsData for pkt=%d, pathProb=%g, reg: %d->%d",
   //    pktID, state->getPathProb(), reg, cur_reg);

   if (int(pktRegs.size()) != pktID) {
      WARN("pktregs size=%ld, pktID=%d\n", pktRegs.size(), pktID);
      assert(0);
   }
   assert(int(pktRegs.size()) == pktID);
   assert(int(perPktProbs.size()) == pktID);
   assert(int(pktProbs.size()) == pktID);

   reg = cur_reg;

   // TODO; Update per-packet constraints and probs
   double pathProb = state->getPathProb();
   pktProbs.push_back(pathProb);
   if (pktID == 0) {
      perPktProbs.push_back(pathProb);
   } else {
      double lastProb = pktProbs[pktID - 1];
      perPktProbs.push_back(pathProb / lastProb);
   }
   pktRegs.push_back(cur_reg);

   return 0;
}

bool AlmostEqual2sComplement(float A, float B, int maxUlps)
{
    // Make sure maxUlps is non-negative and small enough that the
    // default NAN won't compare as equal to anything.
    assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
    int aInt = *(int*)&A;
    // Make aInt lexicographically ordered as a twos-complement int
    if (aInt < 0)
        aInt = 0x80000000 - aInt;
    // Make bInt lexicographically ordered as a twos-complement int
    int bInt = *(int*)&B;
    if (bInt < 0)
        bInt = 0x80000000 - bInt;
    int intDiff = abs(aInt - bInt);
    if (intDiff <= maxUlps)
        return true;
    return false;
}

static int checkVectorSame(vector<double> v)
{
   int ret = 0;
   double first = v[0];
   for (auto val: v) {
      if (!AlmostEqual2sComplement(val, first, 1)) {
         ret = 1;
      }
   }
   if (ret == 0) {
      return 0;
   }

   assert(ret == 1);
   double second = v[1];
   for (uint32_t i = 2; i < v.size(); i ++) {
      if (!AlmostEqual2sComplement(v[i], second, 1)) {
         ret = 2;
      }
   }
   return ret;
}

TeleScopeData::PeriodicityType TeleScopeData::ts_periodicity()
{
   // TODO: for now, we only distinguish two types by comparing
   // TODO: Also check per-packet constraint for periodicity

   int ret = checkVectorSame(perPktProbs);
   if (ret == 0) {
      return REPEAT_ALL;
   } else if (ret == 1) {
      return REPEAT_FROM_SECOND;
   } else {
      return NO_PERIODICITY;
   }
}

int TeleScopeData::ts_final(int cur_reg)
{
   assert(reg == cur_reg);
   //LOG(LOG_MASK_TS, "Telescoping state %d with reg=%d, smallThres=%d, real=%d",
   //    state->id, reg, smallThres, realThres);

   // check if this state is telescopable
   if (reg == smallThres) {
      LOG(LOG_MASK_TS, "state %d (cur_reg = smallThres = %d) "
          "seems telescopable", state->id, reg);
      dump();

      // infer the final prob result
      double result = 0.0;
      TeleScopeData::PeriodicityType ptype = ts_periodicity();

      if (ptype == NO_PERIODICITY) {
         LOG(LOG_MASK_TS, "state %d turns out not telescopable", state->id);
      } else {
         if (ptype == REPEAT_ALL) {
            result = pow(perPktProbs[0], realThres);
         } else if (ptype == REPEAT_FROM_SECOND) {
            result = perPktProbs[0] * pow(perPktProbs[1], realThres-1);
         }
         LOG(LOG_MASK_TS, "telescoping state %d inferred prob of reg==%d is %g",
             state->id, realThres, result);
         finalResult += result;
      }
   } else {
      //LOG(LOG_MASK_TS, "state %d (cur_reg=%d smallThres=%d) "
      //    "seems not telescopable", state->id, cur_reg, smallThres);
   }

   return 0;
}