text:
//  (C) Copyright Gennadiy Rozental 2005.
//  Use, modification, and distribution are subject to 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/test for the library home page.
//
//  File        : $RCSfile: parameter.hpp,v $
//
//  Version     : $Revision: 1.1 $
//
//  Description : defines model of formal parameter
// ***************************************************************************

#ifndef BOOST_RT_CLA_PARAMETER_HPP_062604GER
#define BOOST_RT_CLA_PARAMETER_HPP_062604GER

// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>

#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/utils/runtime/parameter.hpp>
#include <boost/test/utils/runtime/validation.hpp>

#include <boost/test/utils/runtime/cla/fwd.hpp>
#include <boost/test/utils/runtime/cla/modifier.hpp>
#include <boost/test/utils/runtime/cla/iface/argument_factory.hpp>
#include <boost/test/utils/runtime/cla/iface/id_policy.hpp>

// Boost.Test
#include <boost/test/utils/rtti.hpp>

namespace boost {

namespace BOOST_RT_PARAM_NAMESPACE {

namespace cla {

// ************************************************************************** //
// **************            runtime::cla::parameter           ************** //
// ************************************************************************** //

class parameter : public BOOST_RT_PARAM_NAMESPACE::parameter {
public:
    parameter( identification_policy& ID, argument_factory& F )
    : p_optional( false )
    , p_multiplicable( false )
    , p_optional_value( false )
    , m_id_policy( ID )
    , m_arg_factory( F )
    {}

    // Destructor
    virtual         ~parameter()                                {}

    unit_test::readwrite_property<bool>      p_optional;
    unit_test::readwrite_property<bool>      p_multiplicable;
    unit_test::readwrite_property<bool>      p_optional_value;
    unit_test::readwrite_property<dstring>   p_description;

    // parameter properties modification
    template<typename Modifier>
    void            accept_modifier( Modifier const& m )
    {
        if( m.has( optional_m ) )
            p_optional.value = true;

        if( m.has( required_m ) )
            p_optional.value = false;

        if( m.has( multiplicable_m ) )
            p_multiplicable.value = true;

        if( m.has( optional_value_m ) )
            p_optional_value.value = true;

        nfp::optionally_assign( p_description.value, m, description );
    }

    // access methods
    bool            has_argument() const                        { return m_actual_argument; }
    argument const& actual_argument() const                     { return *m_actual_argument; }
    argument_ptr    actual_argument()                           { return m_actual_argument; }

    // identification interface
    bool            responds_to( cstring name ) const           { return m_id_policy.responds_to( name ); }
    bool            conflict_with( parameter const& p ) const
    {
        return id_2_report() == p.id_2_report() && !id_2_report().is_empty()    ||
               m_id_policy.conflict_with( p.m_id_policy )                       ||
               p.m_id_policy.conflict_with( m_id_policy );
    }
    cstring         id_2_report() const                         { return m_id_policy.id_2_report(); }
    void            usage_info( format_stream& fs ) const
    {
        m_id_policy.usage_info( fs );
        if( p_optional_value )
            fs << BOOST_RT_PARAM_LITERAL( '[' );

        m_arg_factory.argument_usage_info( fs );

        if( p_optional_value )
            fs << BOOST_RT_PARAM_LITERAL( ']' );
    }

    // argument match/produce based on input
    bool            matching( argv_traverser& tr, bool primary ) const
    {
        return m_id_policy.matching( *this, tr, primary );
    }

    // argument production based on different source
    void            produce_argument( argv_traverser& tr )
    {
        m_id_policy.matching( *this, tr, true ); // !! could we save this position somehow
        m_actual_argument = m_arg_factory.produce_using( *this, tr );
    }
    void            produce_argument( parser const& p )
    {
        m_actual_argument = m_arg_factory.produce_using( *this, p );
    }

private:
    //Data members
    identification_policy&  m_id_policy;
    argument_factory&       m_arg_factory;
    argument_ptr            m_actual_argument;
};

//____________________________________________________________________________//

template<typename Parameter,typename Modifier>
inline shared_ptr<Parameter>
operator-( shared_ptr<Parameter> p, Modifier const& m )
{
    p->accept_modifier( m );

    return p;
}

//____________________________________________________________________________//

} // namespace cla

} // namespace BOOST_RT_PARAM_NAMESPACE

} // namespace boost

// ************************************************************************** //
//   Revision History:
//
//   $Log: parameter.hpp,v $
//   Revision 1.1  2005/04/12 06:42:43  rogeeff
//   Runtime.Param library initial commit
//
// ************************************************************************** //

#endif // BOOST_RT_CLA_PARAMETER_HPP_062604GER

max_stars_repo_name: dstrigl/mcotf

max_issues_repo_name: dstrigl/mcotf

max_forks_repo_name: dstrigl/mcotf


text:
#include <memory>

#include <boost/dll.hpp>
#include <boost/dll/runtime_symbol_info.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/log/trivial.hpp>

#include "common/refcounting_plugin_api.h"

#include "common/decoder_plugin_api.h"
#include "common/output_plugin_api.h"
#include "common/input_plugin_api.h"
#include "common/ui_plugin_api.h"
#include "core/decoder_plugins_manager.h"
#include "plugins/core_plugins/playlist_management_plugin/playlist_management_plugin.h"

#include "plugins_loader.h"

namespace mprt
{
	plugins_loader::plugins_loader()
		: _decoder_plugins_manager(std::make_shared<decoder_plugins_manager>())
	{

	}

	plugins_loader::~plugins_loader()
	{

	}

	void plugins_loader::init(void *args)
	{
		search_for_symbols(args);
	}

	bool plugins_loader::is_shared_library(const boost::filesystem::path& p)
	{
		const std::string s = p.string();
		return (s.find(".dll") != std::string::npos || s.find(".so") != std::string::npos || s.find(".dylib") != std::string::npos)
			&& s.find(".lib") == std::string::npos
			&& s.find(".exp") == std::string::npos
			&& s.find(".pdb") == std::string::npos
			&& s.find(".manifest") == std::string::npos
			&& s.find(".rsp") == std::string::npos
			&& s.find(".obj") == std::string::npos
			&& s.find(".a") == std::string::npos;
	}

	void plugins_loader::search_for_symbols(void * args)
	{
		auto curr_path = boost::dll::program_location().parent_path();

#ifndef _NDEBUG
		//curr_path /= "Debug";
#else
		//curr_path /= "Release";
#endif

		auto decoder_plugins{ std::make_shared < std::vector<std::shared_ptr<decoder_plugin_api>>>() };
		auto output_plugins{ std::make_shared < std::vector< std::shared_ptr<output_plugin_api>>>() };
		auto input_plugins{ std::make_shared < std::vector<std::shared_ptr<input_plugin_api>>>() };

		for (auto & entry : boost::make_iterator_range(boost::filesystem::directory_iterator(curr_path), {}))
		{
			auto filename = entry.path().filename();
			if (is_shared_library(entry.path()))
			{
				try
				{
					BOOST_LOG_TRIVIAL(debug) << "trying: " << entry;
					auto plugin = get_plugin(entry.path(), "create_refc_plugin");

					switch (plugin->plugin_type())
					{
					case plugin_types::decoder_plugin:
					{
						auto dec_plug_api{ std::dynamic_pointer_cast<decoder_plugin_api>(plugin) };
						dec_plug_api->init(args);
						decoder_plugins->push_back(dec_plug_api);
					}
					break;

					case plugin_types::output_plugin:
					{
						auto out_plug_api{ std::dynamic_pointer_cast<output_plugin_api>(plugin) };
						out_plug_api->init();
						output_plugins->push_back(out_plug_api);
					}
					break;

					case plugin_types::input_plugin:
					{
						auto in_plug_api{ std::dynamic_pointer_cast<input_plugin_api>(plugin) };
						in_plug_api->init(args);
						input_plugins->push_back(in_plug_api);
					}
					break;

					case plugin_types::server_plugin:
						break;

					case plugin_types::ui_plugin:
					{
						auto ui_plug_api{ std::dynamic_pointer_cast<ui_plugin_api>(plugin) };
						_ui_plugins.push_back(ui_plug_api);
					}
					break;

					case plugin_types::playlist_management_plugin:
						_playlist_management_plugin = std::dynamic_pointer_cast<playlist_management_plugin>(plugin);
						_playlist_management_plugin->init(args);
						break;

					default:
						break;
					}
				}
				catch (std::exception const& e)
				{
					BOOST_LOG_TRIVIAL(debug) << "plugin load err: " << e.what();
				}
				catch (...)
				{
					BOOST_LOG_TRIVIAL(debug) << "plugin unknown load err";

				}
			}
		}

		_decoder_plugins_manager->add_decoder_plugins(decoder_plugins);
		_decoder_plugins_manager->add_output_plugins(output_plugins);

		_playlist_management_plugin->set_input_plugins(input_plugins);
		_playlist_management_plugin->set_decoder_plugins_manager(_decoder_plugins_manager);
		_playlist_management_plugin->set_output_plugins(output_plugins);

		for (auto ui_plu : _ui_plugins)
		{
			ui_plu->_playlist_management_plugin = _playlist_management_plugin;
			ui_plu->init(args);
			while (!ui_plu->is_init_ok())
			{
				std::this_thread::sleep_for(std::chrono::milliseconds(100));
			}
		}
		_playlist_management_plugin->add_playlist("../deneme.m3u8");
		_playlist_management_plugin->start_play(0, 0);
	}

}

ext: cpp

max_stars_repo_name: atekin/mprt

max_issues_repo_name: atekin/mprt

max_forks_repo_name: atekin/mprt


text:
#include <string>
#include <iostream>
#include "UdpBundleSource.h"
#include <boost/lexical_cast.hpp>
#include <boost/make_shared.hpp>
#include <boost/make_unique.hpp>
#include <boost/endian/conversion.hpp>

static const boost::posix_time::time_duration static_tokenMaxLimitDurationWindow(boost::posix_time::milliseconds(100));
static const boost::posix_time::time_duration static_tokenRefreshTimeDurationWindow(boost::posix_time::milliseconds(20));

UdpBundleSource::UdpBundleSource(const uint64_t rateBps, const unsigned int maxUnacked) :
m_work(m_ioService), //prevent stopping of ioservice until destructor
m_resolver(m_ioService),
m_tokenRefreshTimer(m_ioService),
m_lastTimeTokensWereRefreshed(boost::posix_time::special_values::neg_infin),
m_udpSocket(m_ioService),
m_maxPacketsBeingSent(maxUnacked),
m_bytesToAckBySentCallbackCb(static_cast<uint32_t>(m_maxPacketsBeingSent + 10)),
m_bytesToAckBySentCallbackCbVec(m_maxPacketsBeingSent + 10),
m_readyToForward(false),
m_useLocalConditionVariableAckReceived(false), //for destructor only
m_tokenRefreshTimerIsRunning(false),
m_totalPacketsSentBySentCallback(0),
m_totalBytesSentBySentCallback(0),
m_totalPacketsDequeuedForSend(0),
m_totalBytesDequeuedForSend(0),
m_totalPacketsLimitedByRate(0)
{
    //m_rateManagerAsync.SetPacketsSentCallback(boost::bind(&UdpBundleSource::PacketsSentCallback, this));
    //const uint64_t minimumRateBytesPerSecond = 655360;
    //const uint64_t minimumRateBitsPerSecond = 655360 << 3;
    UpdateRate(rateBps);

    const uint64_t tokenLimit = m_tokenRateLimiter.GetRemainingTokens();
    std::cout << "UdpBundleSource: rate bitsPerSec = " << rateBps << "  token limit = " << tokenLimit << "\n";

    //The following error message should no longer be relevant since the Token Bucket is allowed to go negative if there is at least 1 token in the bucket.
    //std::cout << "UdpBundleSource: minimum rate bitsPerSec = " << minimumRateBitsPerSecond << " minimum rateBytesPerSecond = " << minimumRateBytesPerSecond << "\n";
    //if (tokenLimit < 65536u) {
    //    std::cout << "error in UdpBundleSource constructor: the token limit of " << tokenLimit << " bytes is less than the max udp packet size of 65536 bytes.  UDP packets may never be sent!\n";
    //}

    m_ioServiceThreadPtr = boost::make_unique<boost::thread>(boost::bind(&boost::asio::io_service::run, &m_ioService));

}

UdpBundleSource::~UdpBundleSource() {
    Stop();
    //print stats
    std::cout << "m_totalPacketsSentBySentCallback " << m_totalPacketsSentBySentCallback << std::endl;
    std::cout << "m_totalBytesSentBySentCallback " << m_totalBytesSentBySentCallback << std::endl;
    std::cout << "m_totalPacketsDequeuedForSend " << m_totalPacketsDequeuedForSend << std::endl;
    std::cout << "m_totalBytesDequeuedForSend " << m_totalBytesDequeuedForSend << std::endl;
    std::cout << "m_totalPacketsLimitedByRate " << m_totalPacketsLimitedByRate << std::endl;
}

void UdpBundleSource::Stop() {
    //prevent UdpBundleSource from exiting before all bundles sent and acked
    boost::mutex localMutex;
    boost::mutex::scoped_lock lock(localMutex);
    m_useLocalConditionVariableAckReceived = true;
    std::size_t previousUnacked = std::numeric_limits<std::size_t>::max();
    for (unsigned int attempt = 0; attempt < 20; ++attempt) {
        const std::size_t numUnacked = GetTotalUdpPacketsUnacked();
        if (numUnacked) {
            std::cout << "notice: UdpBundleSource destructor waiting on " << numUnacked << " unacked bundles" << std::endl;

//            std::cout << "   acked by rate: " << m_totalUdpPacketsAckedByRate << std::endl;
//            std::cout << "   acked by cb: " << m_totalUdpPacketsAckedByUdpSendCallback << std::endl;
//            std::cout << "   total sent: " << m_totalUdpPacketsSent << std::endl;

            if (previousUnacked > numUnacked) {
                previousUnacked = numUnacked;
                attempt = 0;
            }
            m_localConditionVariableAckReceived.timed_wait(lock, boost::posix_time::milliseconds(500)); // call lock.unlock() and blocks the current thread
            //thread is now unblocked, and the lock is reacquired by invoking lock.lock()
            continue;
        }
        break;
    }

    DoUdpShutdown();
    while (m_udpSocket.is_open()) {
        boost::this_thread::sleep(boost::posix_time::milliseconds(250));
    }

    //This function does not block, but instead simply signals the io_service to stop
    //All invocations of its run() or run_one() member functions should return as soon as possible.
    //Subsequent calls to run(), run_one(), poll() or poll_one() will return immediately until reset() is called.
    if (!m_ioService.stopped()) {
        m_ioService.stop(); //ioservice requires stopping before join because of the m_work object
    }

    if(m_ioServiceThreadPtr) {
        m_ioServiceThreadPtr->join();
        m_ioServiceThreadPtr.reset(); //delete it
    }

}

void UdpBundleSource::UpdateRate(uint64_t rateBitsPerSec) {
    const uint64_t rateBytesPerSecond = rateBitsPerSec >> 3;
    m_tokenRateLimiter.SetRate(
        rateBytesPerSecond, // 20ms per token
        boost::posix_time::seconds(1),
        static_tokenMaxLimitDurationWindow //token limit of rateBytesPerSecond / (1000ms/100ms) = rateBytesPerSecond / 10
    );
}

bool UdpBundleSource::Forward(std::vector<uint8_t> & dataVec) {

    if(!m_readyToForward) {
        std::cerr << "link not ready to forward yet" << std::endl;
        return false;
    }

    const unsigned int writeIndexSentCallback = m_bytesToAckBySentCallbackCb.GetIndexForWrite(); //don't put this in tcp async write callback
    if (writeIndexSentCallback == UINT32_MAX) { //push check
        std::cerr << "Error in RateManagerAsync::SignalNewPacketDequeuedForSend.. too many unacked packets by tcp send callback" << std::endl;
        return false;
    }

    ++m_totalPacketsDequeuedForSend;
    m_totalBytesDequeuedForSend += dataVec.size();

    m_bytesToAckBySentCallbackCbVec[writeIndexSentCallback] = dataVec.size();
    m_bytesToAckBySentCallbackCb.CommitWrite(); //pushed

    boost::shared_ptr<std::vector<uint8_t> > udpDataToSendPtr = boost::make_shared<std::vector<uint8_t> >(std::move(dataVec));
    //dataVec invalid after this point
    boost::asio::post(m_ioService, boost::bind(&UdpBundleSource::HandlePostForUdpSendVecMessage, this, std::move(udpDataToSendPtr)));

    return true;
}

bool UdpBundleSource::Forward(zmq::message_t & dataZmq) {

    if (!m_readyToForward) {
        std::cerr << "link not ready to forward yet" << std::endl;
        return false;
    }

    const unsigned int writeIndexSentCallback = m_bytesToAckBySentCallbackCb.GetIndexForWrite(); //don't put this in tcp async write callback
    if (writeIndexSentCallback == UINT32_MAX) { //push check
        std::cerr << "Error in RateManagerAsync::SignalNewPacketDequeuedForSend.. too many unacked packets by tcp send callback" << std::endl;
        return false;
    }

    ++m_totalPacketsDequeuedForSend;
    m_totalBytesDequeuedForSend += dataZmq.size();

    m_bytesToAckBySentCallbackCbVec[writeIndexSentCallback] = dataZmq.size();
    m_bytesToAckBySentCallbackCb.CommitWrite(); //pushed

    boost::shared_ptr<zmq::message_t> zmqDataToSendPtr = boost::make_shared<zmq::message_t>(std::move(dataZmq));
    //dataZmq invalid after this point
    boost::asio::post(m_ioService, boost::bind(&UdpBundleSource::HandlePostForUdpSendZmqMessage, this, std::move(zmqDataToSendPtr)));
    return true;
}

bool UdpBundleSource::Forward(const uint8_t* bundleData, const std::size_t size) {
    std::vector<uint8_t> vec(bundleData, bundleData + size);
    return Forward(vec);
}

std::size_t UdpBundleSource::GetTotalUdpPacketsAcked() {
    return m_totalPacketsSentBySentCallback;
}

std::size_t UdpBundleSource::GetTotalUdpPacketsSent() {
    return m_totalPacketsDequeuedForSend;
}

std::size_t UdpBundleSource::GetTotalUdpPacketsUnacked() {
    return m_totalPacketsDequeuedForSend - m_totalPacketsSentBySentCallback;
}

std::size_t UdpBundleSource::GetTotalBundleBytesAcked() {
    return m_totalBytesSentBySentCallback;
}

std::size_t UdpBundleSource::GetTotalBundleBytesSent() {
    return m_totalBytesDequeuedForSend;
}

std::size_t UdpBundleSource::GetTotalBundleBytesUnacked() {
    return m_totalBytesDequeuedForSend - m_totalBytesSentBySentCallback;
}

void UdpBundleSource::Connect(const std::string & hostname, const std::string & port) {

    static const boost::asio::ip::resolver_query_base::flags UDP_RESOLVER_FLAGS = boost::asio::ip::resolver_query_base::canonical_name; //boost resolver flags
    std::cout << "udp resolving " << hostname << ":" << port << std::endl;
    boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), hostname, port, UDP_RESOLVER_FLAGS);
    m_resolver.async_resolve(query, boost::bind(&UdpBundleSource::OnResolve,
                                                this, boost::asio::placeholders::error,
                                                boost::asio::placeholders::results));
}

void UdpBundleSource::OnResolve(const boost::system::error_code & ec, boost::asio::ip::udp::resolver::results_type results) { // Resolved endpoints as a range.
    if(ec) {
        std::cerr << "Error resolving: " << ec.message() << std::endl;
    }
    else {
        m_udpDestinationEndpoint = *results;
        std::cout << "resolved host to " << m_udpDestinationEndpoint.address() << ":" << m_udpDestinationEndpoint.port() << ".  Binding..." << std::endl;
        try {
            m_udpSocket.open(boost::asio::ip::udp::v4());
            m_udpSocket.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)); //bind to 0 (random ephemeral port)

            std::cout << "UDP Bound on ephemeral port " << m_udpSocket.local_endpoint().port() << std::endl;
            std::cout << "UDP READY" << std::endl;
            m_readyToForward = true;

        }
        catch (const boost::system::system_error & e) {
            std::cerr << "Error in UdpBundleSource::OnResolve(): " << e.what() << std::endl;
            return;
        }
    }
}

void UdpBundleSource::HandlePostForUdpSendVecMessage(boost::shared_ptr<std::vector<boost::uint8_t> > & vecDataToSendPtr) {
    //now that the token rate limiter can be used entirely in one thread (the io_service thread), take tokens
    m_queueVecDataToSendPtrs.emplace(std::move(vecDataToSendPtr)); //put on the queue first (there might be other packets in there that need to be sent first)
    boost::shared_ptr<std::vector<boost::uint8_t> > & vecDataToSendFrontOfQueuePtr = m_queueVecDataToSendPtrs.front();
    //try to remove the front of the queue if tokens available
    if (m_tokenRateLimiter.TakeTokens(vecDataToSendFrontOfQueuePtr->size())) { //there are tokens available for the packet at the front of the queue, send this now
        boost::asio::const_buffer bufToSend = boost::asio::buffer(*vecDataToSendFrontOfQueuePtr);
        m_udpSocket.async_send_to(bufToSend, m_udpDestinationEndpoint,
            boost::bind(&UdpBundleSource::HandleUdpSendVecMessage, this, std::move(vecDataToSendFrontOfQueuePtr),
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
        m_queueVecDataToSendPtrs.pop();
        m_totalPacketsLimitedByRate += (!m_queueVecDataToSendPtrs.empty());
    }
    //else //no tokens available, the already queued packet will be processed by the m_tokenRefreshTimer expiration

    TryRestartTokenRefreshTimer(); //start the token refresh timer if and only if it is not already running
}

void UdpBundleSource::HandlePostForUdpSendZmqMessage(boost::shared_ptr<zmq::message_t> & zmqDataToSendPtr) {
    //now that the token rate limiter can be used entirely in one thread (the io_service thread), take tokens
    m_queueZmqDataToSendPtrs.emplace(std::move(zmqDataToSendPtr)); //put on the queue first (there might be other packets in there that need to be sent first)
    boost::shared_ptr<zmq::message_t> & zmqDataToSendFrontOfQueuePtr = m_queueZmqDataToSendPtrs.front();
    //try to remove the front of the queue if tokens available
    if (m_tokenRateLimiter.TakeTokens(zmqDataToSendFrontOfQueuePtr->size())) { //there are tokens available, send this now
        boost::asio::const_buffer bufToSend = boost::asio::buffer(zmqDataToSendFrontOfQueuePtr->data(), zmqDataToSendFrontOfQueuePtr->size());
        m_udpSocket.async_send_to(bufToSend, m_udpDestinationEndpoint,
            boost::bind(&UdpBundleSource::HandleUdpSendZmqMessage, this, std::move(zmqDataToSendFrontOfQueuePtr),
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
        m_queueZmqDataToSendPtrs.pop();
        m_totalPacketsLimitedByRate += (!m_queueZmqDataToSendPtrs.empty());
    }
    //else //no tokens available, the already queued packet will be processed by the m_tokenRefreshTimer expiration

    TryRestartTokenRefreshTimer(); //start the token refresh timer if and only if it is not already running
}

void UdpBundleSource::HandleUdpSendVecMessage(boost::shared_ptr<std::vector<boost::uint8_t> > & dataSentPtr, const boost::system::error_code& error, std::size_t bytes_transferred) {
    if (error) {
        std::cerr << "error in UdpBundleSource::HandleUdpSend: " << error.message() << std::endl;
        DoUdpShutdown();
    }
    else if (!ProcessPacketSent(bytes_transferred)) {
        DoUdpShutdown();
    }
}

void UdpBundleSource::HandleUdpSendZmqMessage(boost::shared_ptr<zmq::message_t> & dataZmqSentPtr, const boost::system::error_code& error, std::size_t bytes_transferred) {
    if (error) {
        std::cerr << "error in UdpBundleSource::HandleUdpSendZmqMessage: " << error.message() << std::endl;
        DoUdpShutdown();
    }
    else if(!ProcessPacketSent(bytes_transferred)) {
        DoUdpShutdown();
    }
}

bool UdpBundleSource::ProcessPacketSent(std::size_t bytes_transferred) {

    const unsigned int readIndex = m_bytesToAckBySentCallbackCb.GetIndexForRead();
    if (readIndex == UINT32_MAX) { //empty
        std::cerr << "error in UdpBundleSource::ProcessPacketSent: AckCallback called with empty queue" << std::endl;
        return false;
    }
    else if (m_bytesToAckBySentCallbackCbVec[readIndex] == bytes_transferred) {
        ++m_totalPacketsSentBySentCallback;
        m_totalBytesSentBySentCallback += m_bytesToAckBySentCallbackCbVec[readIndex];
        m_bytesToAckBySentCallbackCb.CommitRead();

        if (m_onSuccessfulAckCallback) {
            m_onSuccessfulAckCallback();
        }
        if (m_useLocalConditionVariableAckReceived) {
            m_localConditionVariableAckReceived.notify_one();
        }
        return true;
    }
    else {
        std::cerr << "error in UdpBundleSource::ProcessPacketSent: wrong bytes acked: expected " << m_bytesToAckBySentCallbackCbVec[readIndex] << " but got " << bytes_transferred << std::endl;
        return false;
    }
}

void UdpBundleSource::DoUdpShutdown() {
    boost::asio::post(m_ioService, boost::bind(&UdpBundleSource::DoHandleSocketShutdown, this));
}

void UdpBundleSource::DoHandleSocketShutdown() {
    //final code to shut down tcp sockets
    m_readyToForward = false;
    if (m_udpSocket.is_open()) {
        try {
            std::cout << "shutting down UdpBundleSource UDP socket.." << std::endl;
            m_udpSocket.shutdown(boost::asio::socket_base::shutdown_type::shutdown_both);
        }
        catch (const boost::system::system_error & e) {
            std::cerr << "error in UdpBundleSource::DoUdpShutdown: " << e.what() << std::endl;
        }
        try {
            std::cout << "closing UdpBundleSource UDP socket.." << std::endl;
            m_udpSocket.close();
        }
        catch (const boost::system::system_error & e) {
            std::cerr << "error in UdpBundleSource::DoUdpShutdown: " << e.what() << std::endl;
        }
    }
}

bool UdpBundleSource::ReadyToForward() const {
    return m_readyToForward;
}

void UdpBundleSource::SetOnSuccessfulAckCallback(const OnSuccessfulAckCallback_t & callback) {
    m_onSuccessfulAckCallback = callback;
}

//restarts the token refresh timer if it is not running from now
void UdpBundleSource::TryRestartTokenRefreshTimer() {
    if (!m_tokenRefreshTimerIsRunning) {
        const boost::posix_time::ptime nowPtime = boost::posix_time::microsec_clock::universal_time();
        if (m_lastTimeTokensWereRefreshed.is_neg_infinity()) {
            m_lastTimeTokensWereRefreshed = nowPtime;
        }
        m_tokenRefreshTimer.expires_at(nowPtime + static_tokenRefreshTimeDurationWindow);
        m_tokenRefreshTimer.async_wait(boost::bind(&UdpBundleSource::OnTokenRefresh_TimerExpired, this, boost::asio::placeholders::error));
        m_tokenRefreshTimerIsRunning = true;
    }
}
//restarts the token refresh timer if it is not running from the given ptime
void UdpBundleSource::TryRestartTokenRefreshTimer(const boost::posix_time::ptime & nowPtime) {
    if (!m_tokenRefreshTimerIsRunning) {
        if (m_lastTimeTokensWereRefreshed.is_neg_infinity()) {
            m_lastTimeTokensWereRefreshed = nowPtime;
        }
        m_tokenRefreshTimer.expires_at(nowPtime + static_tokenRefreshTimeDurationWindow);
        m_tokenRefreshTimer.async_wait(boost::bind(&UdpBundleSource::OnTokenRefresh_TimerExpired, this, boost::asio::placeholders::error));
        m_tokenRefreshTimerIsRunning = true;
    }
}

void UdpBundleSource::OnTokenRefresh_TimerExpired(const boost::system::error_code& e) {
    const boost::posix_time::ptime nowPtime = boost::posix_time::microsec_clock::universal_time();
    const boost::posix_time::time_duration diff = nowPtime - m_lastTimeTokensWereRefreshed;
    m_tokenRateLimiter.AddTime(diff);
    m_lastTimeTokensWereRefreshed = nowPtime;
    m_tokenRefreshTimerIsRunning = false;
    if (e != boost::asio::error::operation_aborted) {
        // Timer was not cancelled, take necessary action.
        while (!m_queueVecDataToSendPtrs.empty()) {
            boost::shared_ptr<std::vector<boost::uint8_t> > & vecDataToSendPtr = m_queueVecDataToSendPtrs.front();
            //empty the queue of rate limited packets
            if (m_tokenRateLimiter.TakeTokens(vecDataToSendPtr->size())) { //there are tokens available, send this now
                boost::asio::const_buffer bufToSend = boost::asio::buffer(*vecDataToSendPtr);
                m_udpSocket.async_send_to(bufToSend, m_udpDestinationEndpoint,
                    boost::bind(&UdpBundleSource::HandleUdpSendVecMessage, this, std::move(vecDataToSendPtr),
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));
                m_queueVecDataToSendPtrs.pop();
                ++m_totalPacketsLimitedByRate;
            }
            else { //no tokens available, empty the packet queue at the next m_tokenRefreshTimer expiration
                TryRestartTokenRefreshTimer(nowPtime);
                return;
            }
        }
        while (!m_queueZmqDataToSendPtrs.empty()) {
            boost::shared_ptr<zmq::message_t> & zmqDataToSendPtr = m_queueZmqDataToSendPtrs.front();
            //empty the queue of rate limited packets
            if (m_tokenRateLimiter.TakeTokens(zmqDataToSendPtr->size())) { //there are tokens available, send this now
                boost::asio::const_buffer bufToSend = boost::asio::buffer(zmqDataToSendPtr->data(), zmqDataToSendPtr->size());
                m_udpSocket.async_send_to(bufToSend, m_udpDestinationEndpoint,
                    boost::bind(&UdpBundleSource::HandleUdpSendZmqMessage, this, std::move(zmqDataToSendPtr),
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));
                m_queueZmqDataToSendPtrs.pop();
                ++m_totalPacketsLimitedByRate;
            }
            else { //no tokens available, empty the packet queue at the next m_tokenRefreshTimer expiration
                TryRestartTokenRefreshTimer(nowPtime);
                return;
            }
        }
        //If more tokens can be added, restart the timer so more tokens will be added at the next timer expiration.
        //Otherwise, if full, don't restart the timer and the next send packet operation will start it.
        if (!m_tokenRateLimiter.HasFullBucketOfTokens()) {
            TryRestartTokenRefreshTimer(nowPtime);
        }
    }
    else {
        //std::cout << "timer cancelled\n";
    }
}


text:
#ifndef GAME_CLASS_NAME
  #error "GAME_CASS_NAME not defined!"
#endif
#ifndef GAME_HEADER
  #error "GAME_HEADER not defined!"
#endif
#ifndef MODULE_NAME
  #error "MODULE_NAME not defined!"
#endif

#define XSTRINGIFY(x) STRINGIFY(x)  // NOLINT
#define STRINGIFY(x) #x             // NOLINT

#include <boost/python.hpp>
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>
#include <boost/python/numpy.hpp>

#include "Python.h"

#include XSTRINGIFY(GAME_HEADER)

namespace p = boost::python;
namespace np = boost::python::numpy;

using GameImpl = oaz::games::GAME_CLASS_NAME;

static GameImpl CreateGameFromNDArray(const np::ndarray& array) {
  GameImpl game;
  game.InitialiseFromState(
      reinterpret_cast<float*>(array.get_data()));  // NOLINT
  return game;
}

static GameImpl CreateGameFromNDArrayCanonical(const np::ndarray& array) {
  GameImpl game;
  game.InitialiseFromCanonicalState(
      reinterpret_cast<float*>(array.get_data()));  // NOLINT
  return game;
}

p::list GetAvailableMoves(const GameImpl& game) {
  p::list l;
  std::vector<size_t> available_moves;
  game.GetAvailableMoves(&available_moves);
  for (auto move : available_moves) {
    l.append(move);
  }
  return l;
}

np::ndarray GetBoard(const GameImpl& game) {
  np::ndarray board = np::zeros(p::tuple(game.ClassMethods().GetBoardShape()),
                                np::dtype::get_builtin<float>());
  game.WriteStateToTensorMemory(
      reinterpret_cast<float*>(board.get_data()));  // NOLINT
  return board;
}

np::ndarray GetCanonicalBoard(const GameImpl& game) {
  np::ndarray board = np::zeros(p::tuple(game.ClassMethods().GetBoardShape()),
                                np::dtype::get_builtin<float>());
  game.WriteCanonicalStateToTensorMemory(
      reinterpret_cast<float*>(board.get_data()));  // NOLINT
  return board;
}

BOOST_PYTHON_MODULE(MODULE_NAME) {  // NOLINT
  PyEval_InitThreads();
  np::initialize();

  p::class_<GameImpl, p::bases<oaz::games::Game> >(XSTRINGIFY(GAME_CLASS_NAME))
      .def("play_move", &GameImpl::PlayMove)
      .def("from_numpy", &CreateGameFromNDArray)
      .staticmethod("from_numpy")
      .def("from_numpy_canonical", &CreateGameFromNDArrayCanonical)
      .staticmethod("from_numpy_canonical")
      .add_property("current_player", &GameImpl::GetCurrentPlayer)
      .add_property("finished", &GameImpl::IsFinished)
      .add_property("score", &GameImpl::GetScore)
      .add_property("available_moves", &GetAvailableMoves)
      .add_property("board", &GetBoard)
      .add_property("canonical_board", &GetCanonicalBoard);
}

max_stars_repo_name: ameroueh/oaz

max_issues_repo_name: ameroueh/oaz

max_forks_repo_name: ameroueh/oaz


text:
/*
 * Copyright (c) 2018 Ryan Berryhill, University of Toronto
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "pme/id.h"
#include "pme/engine/variable_manager.h"
#include "pme/engine/global_state.h"
#include "pme/ivc/ivc.h"
#include "pme/ivc/caivc.h"
#include "pme/ivc/marco_ivc.h"
#include "pme/ivc/unified_ivc.h"
#include "pme/ivc/ivc_bf.h"
#include "pme/ivc/ivc_ucbf.h"

#define BOOST_TEST_MODULE IVCTest
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

#include <limits>

using namespace PME;

struct IVCFixture
{
    aiger * aig;
    ExternalID l0, l1, l2, l3, a0, a1, a2, a3, a4, a5, a6, o0;
    VariableManager vars;
    std::unique_ptr<TransitionRelation> tr;

    IVCFixture()
    {
        aig = aiger_init();

        l0 = 2;
        l1 = 4;
        l2 = 6;
        l3 = 8;
        a0 = 10;
        a1 = 12;
        a2 = 14;
        a3 = 16;
        a4 = 18;
        a5 = 20;
        a6 = 22;

        // l0' = l3
        aiger_add_latch(aig, l0, l3, "l0");

        // l1' = l0
        aiger_add_latch(aig, l1, l0, "l1");

        // l2' = l1
        aiger_add_latch(aig, l2, l1, "l2");

        // l3' = l2
        aiger_add_latch(aig, l3, l2, "l3");

        // a0-a3 are ands of each pair of adjacent latches
        // a4 and a5 are ands of adjacent pairs of a0 and a3
        // a6 = a4 & a5 = <every adjacent pair is high>
        // a6 <=> ALL(l0-l3), but the structure is important for IVCs
        // In particular, this circuit has different IVCs depending on the
        // initial state.
        aiger_add_and(aig, a0, l0, l1);
        aiger_add_and(aig, a1, l1, l2);
        aiger_add_and(aig, a2, l2, l3);
        aiger_add_and(aig, a3, l3, l0);
        aiger_add_and(aig, a4, a0, a1);
        aiger_add_and(aig, a5, a2, a3);
        aiger_add_and(aig, a6, a4, a5);
        aiger_add_output(aig, a6, "o0");
        o0 = a6;
        tr.reset(new TransitionRelation(vars, aig));
    }

    void setInit(ID latch, ID val)
    {
        tr->setInit(latch, val);
    }

    ~IVCFixture()
    {
        aiger_reset(aig);
        aig = nullptr;
    }
};

void sortIVCs(std::vector<IVC> & ivcs)
{
    for (IVC ivc : ivcs)
    {
        std::sort(ivc.begin(), ivc.end());
    }
    std::sort(ivcs.begin(), ivcs.end());
}

template<class T>
void runIVCTest(bool find_all)
{
    IVCFixture f;

    ID a0 = f.tr->toInternal(f.a0);
    ID a1 = f.tr->toInternal(f.a1);
    ID a2 = f.tr->toInternal(f.a2);
    ID a3 = f.tr->toInternal(f.a3);
    ID a4 = f.tr->toInternal(f.a4);
    ID a5 = f.tr->toInternal(f.a5);
    ID a6 = f.tr->toInternal(f.a6);

    std::vector<IVC> mivcs = { {a0, a4, a6},
                               {a1, a4, a6},
                               {a2, a5, a6},
                               {a3, a5, a6} };
    sortIVCs(mivcs);

    T finder(f.vars, *f.tr);
    finder.findIVCs();

    IVC min_ivc;
    if (find_all)
    {
        BOOST_CHECK_EQUAL(finder.numMIVCs(), mivcs.size());
        BOOST_REQUIRE(finder.minimumIVCKnown());
        min_ivc = finder.getMinimumIVC();
        std::sort(min_ivc.begin(), min_ivc.end());
    }

    bool min_found = false;

    size_t min_size = std::numeric_limits<size_t>::max();
    for (size_t i = 0; i < finder.numMIVCs(); ++i)
    {
        IVC mivc = finder.getMIVC(i);

        std::sort(mivc.begin(), mivc.end());

        auto it = std::find(mivcs.begin(), mivcs.end(), mivc);
        BOOST_CHECK(it != mivcs.end());

        min_size = std::min(min_size, mivc.size());

        if (mivc == min_ivc)
        {
            min_found = true;
        }
    }

    if (find_all)
    {
        BOOST_CHECK(min_found);
        BOOST_CHECK_EQUAL(finder.getMinimumIVC().size(), min_size);
    }
}

template<class T>
void runAllMIVCTest()
{
    runIVCTest<T>(true);
}

template<class T>
void runMIVCTest()
{
    runIVCTest<T>(false);
}

void defaultUIVCOptions()
{
    GlobalState::instance().resetOptions();

    GlobalState::options().uivc_mcs_finder_type = MCS_FINDER_BASIC;
    GlobalState::options().uivc_map_solver_type = MAP_SOLVER_MSU4;
    GlobalState::options().uivc_upfront_nmax = 0;
    GlobalState::options().uivc_direction_down = true;
    GlobalState::options().uivc_direction_up = false;
}

BOOST_AUTO_TEST_CASE(basic_ivc_caivc)
{
    defaultUIVCOptions();
    runAllMIVCTest<CAIVCFinder>();
}

BOOST_AUTO_TEST_CASE(basic_ivc_marco)
{
    defaultUIVCOptions();
    runAllMIVCTest<MARCOIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_marco_down)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = false;
    GlobalState::options().uivc_direction_down = true;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_upfront_nmax = 1;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_marco_up)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = false;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_upfront_nmax = 1;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_mcs_grow = true;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_check_map)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = false;
    GlobalState::options().uivc_direction_down = true;
    GlobalState::options().uivc_check_map = true;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = false;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_coi_hints)
{
    defaultUIVCOptions();

    // MARCO-UP
    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = false;
    GlobalState::options().uivc_coi_hints = true;
    runAllMIVCTest<UnifiedIVCFinder>();

    // MARCO-DOWN
    GlobalState::options().uivc_direction_up = false;
    GlobalState::options().uivc_direction_down = true;
    GlobalState::options().uivc_coi_hints = true;
    runAllMIVCTest<UnifiedIVCFinder>();

    // CAMUS
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = false;
    GlobalState::options().uivc_upfront_nmax = UINFINITY;
    GlobalState::options().uivc_coi_hints = true;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_proof_caching)
{
    defaultUIVCOptions();

    // MARCO-UP
    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = false;
    GlobalState::options().uivc_proof_cache = 4;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_shrink_cached_proofs = true;
    runAllMIVCTest<UnifiedIVCFinder>();

    // MARCO-DOWN
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = false;
    GlobalState::options().uivc_direction_down = true;
    GlobalState::options().uivc_proof_cache = 4;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_shrink_cached_proofs = true;
    runAllMIVCTest<UnifiedIVCFinder>();

    // CAMUS
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = false;
    GlobalState::options().uivc_upfront_nmax = UINFINITY;
    GlobalState::options().uivc_proof_cache = 4;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_shrink_cached_proofs = true;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_marco_zigzag)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = true;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_upfront_nmax = 1;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_mcs_grow = true;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_marco_arb_maxsat)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = false;
    GlobalState::options().uivc_direction_down = false;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_upfront_nmax = 1;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_mcs_grow = true;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_marco_down_bmc)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = false;
    GlobalState::options().uivc_direction_down = true;
    GlobalState::options().uivc_mcs_finder_type = MCS_FINDER_BMC;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_upfront_nmax = 1;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_marco_up_bmc)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = false;
    GlobalState::options().uivc_mcs_finder_type = MCS_FINDER_BMC;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_upfront_nmax = 1;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_mcs_grow = true;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_marco_zigzag_bmc)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = true;
    GlobalState::options().uivc_mcs_finder_type = MCS_FINDER_BMC;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_upfront_nmax = 1;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_mcs_grow = true;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_marco_arb_bmc)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = false;
    GlobalState::options().uivc_direction_down = false;
    GlobalState::options().uivc_mcs_finder_type = MCS_FINDER_BMC;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_upfront_nmax = 1;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_mcs_grow = true;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_marco_arb_sat)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = false;
    GlobalState::options().uivc_direction_down = false;
    GlobalState::options().uivc_map_solver_type = MAP_SOLVER_SAT;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_upfront_nmax = 1;
    runAllMIVCTest<UnifiedIVCFinder>();

    GlobalState::options().uivc_mcs_grow = true;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(uivc_camus)
{
    defaultUIVCOptions();
    GlobalState::options().uivc_direction_up = true;
    GlobalState::options().uivc_direction_down = false;
    GlobalState::options().uivc_upfront_nmax = UINFINITY;
    runAllMIVCTest<UnifiedIVCFinder>();
}

BOOST_AUTO_TEST_CASE(basic_ivc_ivc_bf)
{
    defaultUIVCOptions();
    runMIVCTest<IVCBFFinder>();
}

BOOST_AUTO_TEST_CASE(basic_ivc_ivc_ucbf)
{
    defaultUIVCOptions();
    runMIVCTest<IVCUCBFFinder>();
}

max_stars_repo_name: ryanberryhill/pme

max_issues_repo_name: ryanberryhill/pme

max_forks_repo_name: ryanberryhill/pme


text:
/**
 *  This file is part of dvo.
 *
 *  Copyright 2012 Christian Kerl <christian.kerl@in.tum.de> (Technical University of Munich)
 *  For more information see <http://vision.in.tum.de/data/software/dvo>.
 *
 *  dvo is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  dvo is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with dvo.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <dvo/visualization/point_cloud_aggregator.h>

#include <pcl/filters/approximate_voxel_grid.h>
#include <boost/bind.hpp>
#include <boost/thread/mutex.hpp>

namespace dvo
{
namespace visualization
{

typedef std::map<std::string, PointCloudAggregator::PointCloudBuilderCallable> PointCloudMap;

namespace internal
{
class PointCloudAggregatorImpl
{
public:
  PointCloudAggregatorImpl() {}
  ~PointCloudAggregatorImpl() {}

  PointCloudMap clouds_;
  boost::mutex clouds_mutex_;
};
} /* namespace internal */

dvo::visualization::AsyncPointCloudBuilder::PointCloud::Ptr passthroughPointCloudBuilder(const dvo::visualization::AsyncPointCloudBuilder::PointCloud::Ptr& cloud)
{
  return cloud;
}

PointCloudAggregator::PointCloudAggregator() :
    impl_(new internal::PointCloudAggregatorImpl()) {}
PointCloudAggregator::~PointCloudAggregator() {}

void PointCloudAggregator::add(const std::string& name, const dvo::visualization::AsyncPointCloudBuilder::PointCloud::Ptr& cloud)
{
  PointCloudBuilderCallable callable = boost::bind(&passthroughPointCloudBuilder, cloud);
  add(name, callable);
}

void PointCloudAggregator::add(const std::string& name, const PointCloudBuilderCallable& cloud)
{
  boost::mutex::scoped_lock(impl_->clouds_mutex_);
  impl_->clouds_[name] = cloud;
}

void PointCloudAggregator::remove(const std::string& name)
{
  boost::mutex::scoped_lock(impl_->clouds_mutex_);
  impl_->clouds_.erase(name);
}

AsyncPointCloudBuilder::PointCloud::Ptr PointCloudAggregator::build()
{
  AsyncPointCloudBuilder::PointCloud::Ptr highres_cloud(new AsyncPointCloudBuilder::PointCloud);
  AsyncPointCloudBuilder::PointCloud::Ptr downsampled_cloud(new AsyncPointCloudBuilder::PointCloud);

  PointCloudMap local;
  {
    boost::mutex::scoped_lock(impl_->clouds_mutex_);
    local = impl_->clouds_;
  }

  if(local.empty())
  {
    highres_cloud->points.push_back(AsyncPointCloudBuilder::PointCloud::PointType());
    return highres_cloud;
  }

  pcl::ApproximateVoxelGrid<AsyncPointCloudBuilder::PointCloud::PointType> vg;
  vg.setDownsampleAllData(true);
  vg.setLeafSize(0.01f, 0.01f, 0.01f);

  size_t step = std::max(local.size() / size_t(50), size_t(1));
  size_t k = 0;
  for(PointCloudMap::iterator it = local.begin(); it != local.end(); ++it, ++k)
  {
    if((k % step) == 0)
    {
      (*highres_cloud) += *(it->second());
    }
  }

  vg.setInputCloud(highres_cloud);
  vg.filter(*downsampled_cloud);

  return downsampled_cloud;
}

} /* namespace visualization */
} /* namespace dvo */


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

#ifndef VSOMEIP_V3_CONFIGURATION_CONFIGURATION_ELEMENT_HPP_
#define VSOMEIP_V3_CONFIGURATION_CONFIGURATION_ELEMENT_HPP_

#include <string>

#include <boost/property_tree/ptree.hpp>

namespace vsomeip_v3 {

struct configuration_element {
    std::string name_;
    boost::property_tree::ptree tree_;

    bool operator<(const configuration_element &_other) const {
        return (name_ < _other.name_);
    }
};

} // namespace vsomeip_v3

#endif // VSOMEIP_V3_CONFIGURATION_CONFIGURATION_ELEMENT_HPP_

ext: hpp

max_stars_repo_name: lixiaolia/ndk-someip-lib

max_issues_repo_name: lixiaolia/ndk-someip-lib

max_forks_repo_name: lixiaolia/ndk-someip-lib


text:
/**
 * @file GDirectSwarm.cpp
 */

/********************************************************************************
 *
 * This file is part of the Geneva library collection. The following license
 * applies to this file:
 *
 * ------------------------------------------------------------------------------
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ------------------------------------------------------------------------------
 *
 * Note that other files in the Geneva library collection may use a different
 * license. Please see the licensing information in each file.
 *
 ********************************************************************************
 *
 * Geneva was started by Dr. Rüdiger Berlich and was later maintained together
 * with Dr. Ariel Garcia under the auspices of Gemfony scientific. For further
 * information on Gemfony scientific, see http://www.gemfomy.eu .
 *
 * The majority of files in Geneva was released under the Apache license v2.0
 * in February 2020.
 *
 * See the NOTICE file in the top-level directory of the Geneva library
 * collection for a list of contributors and copyright information.
 *
 ********************************************************************************/

/*
 * *****************************************************************************
 * NOTE: This file shows how to access some of the optimization algorithms
 * directly (EA in this case), without going through the Go2 class. Usually, Go2
 * is the recommended way and will relieve you from many burdensome tasks you
 * otherwise have to perform. Thus, if you are new to Geneva, we recommend that
 * you start with example 01 first rather than following what is shown in this file.
 * *****************************************************************************
 */

// Standard header files go here
#include <iostream>
#include <cmath>
#include <sstream>
#include <chrono>

// Boost header files go here
#include <boost/lexical_cast.hpp>

// Geneva header files go here
#include "courtier/GAsioConsumerT.hpp"
#include "courtier/GStdThreadConsumerT.hpp"
#include "courtier/GSerialConsumerT.hpp"
#include "courtier/GCourtierEnums.hpp"
#include "common/GParserBuilder.hpp"
#include "geneva/GenevaInitializer.hpp"
#include "geneva/G_OptimizationAlgorithm_SwarmAlgorithm.hpp"

// The individual that should be optimized
#include "geneva-individuals/GFunctionIndividual.hpp"

using namespace Gem::Geneva;
using namespace Gem::Courtier;
using namespace Gem::Hap;
using namespace Gem::Common;

namespace po = boost::program_options;

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

const consumerType DEFAULTCONSUMERTYPE=consumerType::MULTITHREADED;
const unsigned short DEFAULTPORT=10000;
const std::string DEFAULTIP="localhost";
const std::uint16_t DEFAULTNPRODUCERTHREADS=10;
const Gem::Common::serializationMode DEFAULTSERMODE=Gem::Common::serializationMode::TEXT;
const bool DEFAULTADDLOCALCONSUMER=false;
const std::uint16_t DEFAULTNEVALUATIONTHREADS=4;
const std::uint32_t DEFAULTMAXITERATIONS=200;
const std::uint32_t DEFAULTREPORTITERATION=1;
const long DEFAULTMAXMINUTES=10;
const std::size_t DEFAULTNNEIGHBORHOODSAP=5;
const std::size_t DEFAULTNNEIGHBORHOODMEMBERSAP=20;
const double DEFAULTCPERSONALAP=2.;
const double DEFAULTCNEIGHBORHOODAP=2.;
const double DEFAULTCGLOBALAP=1.;
const double DEFAULTCVELOCITYAP=0.4;
const bool DEFAULTALLRANDOMINIT=true;
const std::size_t DEFAULTMAXRECONNECTS = 10;

/******************************************************************************/
/**
 * Parses the command line
 */
bool parseCommandLine(
	int argc, char **argv
	, consumerType& cType
	, bool& clientMode
	, std::string& ip
	, unsigned short& port
	, Gem::Common::serializationMode& serMode
	, std::size_t& nNeighborhoods
	, std::size_t& nNeighborhoodMembers
	, double& cPersonal
	, double& cNeighborhood
	, double& cGlobal
	, double& cVelocity
	, updateRule& ur
	, bool& allRandomInit
	, std::uint16_t& nProducerThreads
	, std::uint16_t& nEvaluationThreads
	, std::uint32_t& maxIterations
	, long& maxMinutes
	, std::uint32_t& reportIteration
	, std::size_t& maxReconnects
){
	// Create the parser builder
	Gem::Common::GParserBuilder gpb;

	gpb.registerCLParameter<consumerType>(
		"consumerType"
		, cType
		, DEFAULTCONSUMERTYPE
		, "The type of consumer to use: 0 (serial), 1 (multithreaded) or 2 (networked)"
	);

	gpb.registerCLParameter<bool>(
		"client,c"
		, clientMode
		, false // Use server mode, if no client option is specified
		, "Whether to run networked execution in server or client mode."
		, GCL_IMPLICIT_ALLOWED // Permit implicit values, so that we can say --server instead of --server=true
		, true // Use client mode, of only -c or --client was specified
	);

	gpb.registerCLParameter<std::string>(
		std::string("ip")
		, ip
		, DEFAULTIP
		, "The ip of the server"
	);

	gpb.registerCLParameter<unsigned short>(
		"port"
			, port
			, DEFAULTPORT
			, "The port on the server"
	);

	gpb.registerCLParameter<Gem::Common::serializationMode>(
		"serializationMode"
		, serMode
		, DEFAULTSERMODE
		, "Specifies whether serialization shall be done in TEXTMODE (0), XMLMODE (1) or BINARYMODE (2)"
	);

	gpb.registerCLParameter<std::size_t>(
		"nNeighborhoods"
		, nNeighborhoods
		, DEFAULTNNEIGHBORHOODSAP
		, "The number of neighborhoods in the population"
	);

	gpb.registerCLParameter<std::size_t>(
		"nNeighborhoodMembers"
		, nNeighborhoodMembers
		, DEFAULTNNEIGHBORHOODMEMBERSAP
		, "The default number of members in each neighborhood"
	);

	gpb.registerCLParameter<double>(
		"cPersonal"
		, cPersonal
		, DEFAULTCPERSONALAP
		, "A constant to be multiplied with the personal direction vector"
	);

	gpb.registerCLParameter<double>(
		"cNeighborhood"
		, cNeighborhood
		, DEFAULTCNEIGHBORHOODAP
		, "A constant to be multiplied with the neighborhood direction vector"
	);

	gpb.registerCLParameter<double>(
		"cGlobal"
		, cGlobal
		, DEFAULTCGLOBALAP
		, "A constant to be multiplied with the global direction vector"
	);

	gpb.registerCLParameter<double>(
		"cVelocity"
		, cVelocity
		, DEFAULTCVELOCITYAP
		, "A constant to be multiplied with the old velocity vector"
	);

	gpb.registerCLParameter<updateRule>(
		"updateRule"
		, ur
		, DEFAULTUPDATERULE
		, "Use linear (0) or classical (1) update rule"
	);

	gpb.registerCLParameter<bool>(
		"allRandomInit"
		, allRandomInit
		, DEFAULTALLRANDOMINIT
		, "If set, all individuals will be initialized randomly. If 0, all individuals in one neighborhood will have the same start value"
		, GCL_IMPLICIT_ALLOWED // Permit implicit values, so that we can say --server instead of --server=true
		, true // Always randomly initialize if set
	);

	gpb.registerCLParameter<std::uint16_t>(
		"nProducerThreads"
		, nProducerThreads
		, DEFAULTNPRODUCERTHREADS
		, "The amount of random number producer threads"
	);

	gpb.registerCLParameter<std::uint16_t>(
		"nEvaluationThreads"
		, nEvaluationThreads
		, DEFAULTNEVALUATIONTHREADS
		, "The amount of threads processing individuals simultaneously in multi-threaded mode"
	);

	gpb.registerCLParameter<std::uint32_t>(
		"maxIterations"
		, maxIterations
		, DEFAULTMAXITERATIONS
		, "Maximum number of iterations in the optimization"
	);

	gpb.registerCLParameter<std::uint32_t>(
		"reportIteration"
		, reportIteration
		, DEFAULTREPORTITERATION
		, "The number of iterations after which information should be emitted in the population"
	);

	gpb.registerCLParameter<long>(
		"maxMinutes"
		, maxMinutes
		, DEFAULTMAXMINUTES
		, "The maximum number of minutes the optimization of the population should run"
	);

	gpb.registerCLParameter<std::size_t>(
		"maxReconnects"
		, maxReconnects
		, DEFAULTMAXRECONNECTS
		, "The number of times a client will try to reconnect when it couldn't reach the server"
	);

	// Parse the command line and leave if the help flag was given. The parser
	// will emit an appropriate help message by itself
	if(Gem::Common::GCL_HELP_REQUESTED == gpb.parseCommandLine(argc, argv, true /*verbose*/)) {
		return false; // Do not continue
	}

	return true;
}

/******************************************************************************/
/**
 * The main function.
 */
int main(int argc, char **argv){
	consumerType cType;
	bool clientMode;
	std::string ip;
	unsigned short port;
	std::uint16_t nProducerThreads;
	std::uint16_t nEvaluationThreads;
	std::uint32_t maxIterations;
	long maxMinutes;
	std::uint32_t reportIteration;
	Gem::Common::serializationMode serMode;
	std::size_t nNeighborhoods;
	std::size_t nNeighborhoodMembers;
	double cPersonal;
	double cNeighborhood;
	double cGlobal;
	double cVelocity;
	updateRule ur;
	bool allRandomInit;
	std::size_t maxReconnects;

	/****************************************************************************/
	// Initialization of Geneva
	GenevaInitializer gi;

	/****************************************************************************/
	// Retrieve all necessary configuration data from the command line

	if(!parseCommandLine(
		argc, argv
		, cType
		, clientMode
		, ip
		, port
		, serMode
		, nNeighborhoods
		, nNeighborhoodMembers
		, cPersonal
		, cNeighborhood
		, cGlobal
		, cVelocity
		, ur
		, allRandomInit
		, nProducerThreads
		, nEvaluationThreads
		, maxIterations
		, maxMinutes
		, reportIteration
		, maxReconnects
	)) { exit(1); }

	/****************************************************************************/
	// Random numbers are our most valuable good. Set the number of threads
	GRANDOMFACTORY->setNProducerThreads(nProducerThreads);

	/****************************************************************************/
	// If this is a client in networked mode, we can just start the listener and
	// return when it has finished
	if(clientMode && cType == consumerType::NETWORKED) {
		std::shared_ptr<GAsioConsumerClientT<GParameterSet>> p(
			new GAsioConsumerClientT<GParameterSet>(
				ip
				, port
				, serMode
				, maxReconnects
			)
		);

		// Start the actual processing loop
		p->run();

		return 0;
	}

	/****************************************************************************/
	// We can now start creating populations. We refer to them through the base class

	// This smart pointer will hold the different population types
	std::shared_ptr<GSwarmAlgorithm> pop_ptr(new GSwarmAlgorithm(nNeighborhoods, nNeighborhoodMembers));

	// Create the actual populations
	switch(cType) {
		//---------------------------------------------------------------------------
		case consumerType::SERIAL: // Serial execution
		{
			std::shared_ptr<GSerialConsumerT<GParameterSet>> sc(new GSerialConsumerT<GParameterSet>());
			GBROKER(Gem::Geneva::GParameterSet)->enrol_consumer(sc);
		}
			break;

			//---------------------------------------------------------------------------
		case consumerType::MULTITHREADED: // Multi-threaded execution
		{
			std::shared_ptr<GStdThreadConsumerT<GParameterSet>> gbtc(
				new GStdThreadConsumerT<GParameterSet>(nEvaluationThreads)
			);
			GBROKER(Gem::Geneva::GParameterSet)->enrol_consumer(gbtc);
		}
			break;

			//---------------------------------------------------------------------------
		case consumerType::NETWORKED: // Networked execution (server-side)
		{
			// Create a network consumer and enrol_buffer_port it with the broker
			std::shared_ptr<GAsioConsumerT<GParameterSet>> gatc_ptr(new GAsioConsumerT<GParameterSet>());

			// Set the required options
			gatc_ptr->setServerName(ip);
			gatc_ptr->setPort(port);
			gatc_ptr->setSerializationMode(serMode);
			gatc_ptr->setNThreads(nEvaluationThreads);
			gatc_ptr->setMaxReconnects(maxReconnects);

			// Add the consumer to the broker
			GBROKER(Gem::Geneva::GParameterSet)->enrol_consumer(gatc_ptr);
		}
			break;

			//----------------------------------------------------------------------------
	}

	/****************************************************************************/
	// Create a factory for GFunctionIndividual objects. It performs
	// all necessary initial work related to the individual (i.e. the optimization problem)
	GFunctionIndividualFactory gfi("./config/GFunctionIndividual.json");

	// Create the first set of parent individuals
	std::vector<std::shared_ptr<GFunctionIndividual>> parentIndividuals;

	// Create initial individuals for the population
	if(allRandomInit) { // Random initialization of all individuals in the population
		for(std::size_t p = 0 ; p<pop_ptr->getDefaultPopulationSize(); p++) {
			parentIndividuals.push_back(gfi.get_as<GFunctionIndividual>());
		}
	} else { // Individuals of the same neighborhood start from the same location
		for(std::size_t n=0; n<nNeighborhoods; n++) {
			// Initialize the first individual of the neighborhood
			std::shared_ptr<GFunctionIndividual> functionIndividual_ptr
				= gfi.get_as<GFunctionIndividual>();

			// Now add the required number of clones to the neighborhood
			for(std::size_t p=1; p<nNeighborhoodMembers; p++) {
				parentIndividuals.push_back(functionIndividual_ptr->clone<GFunctionIndividual>());
			}
			parentIndividuals.push_back(functionIndividual_ptr);
		}
	}

	/****************************************************************************/
	// Now we have suitable populations and can fill them with data

	// Add individuals to the population. Many Geneva classes, such as
	// the optimization classes, feature an interface very similar to std::vector.
	for(std::size_t p = 0 ; p<parentIndividuals.size(); p++) {
		pop_ptr->push_back(parentIndividuals[p]);
	}

	// Specify some general population settings
	pop_ptr->setMaxIteration(maxIterations);
	pop_ptr->setMaxTime(std::chrono::minutes(maxMinutes));
	pop_ptr->setReportIteration(reportIteration);
	pop_ptr->setCPersonal(cPersonal);
	pop_ptr->setCGlobal(cGlobal);
	pop_ptr->setCNeighborhood(cNeighborhood);
	pop_ptr->setCVelocity(cVelocity);
	pop_ptr->setUpdateRule(ur);

	// Do the actual optimization
	pop_ptr->optimize();

	/****************************************************************************/
	// Do something with the best individual found
	std::shared_ptr<GFunctionIndividual> p = pop_ptr->getBestGlobalIndividual<GFunctionIndividual>();

	// Here you can do something with the best individual ("p") found.
	// We simply print its content here, by means of an operator<< implemented
	// in the GFunctionIndividual code.
	std::cout
	<< "Best result found:" << std::endl
	<< p << std::endl;

	/****************************************************************************/
	// Terminate
	return 0;
}

max_stars_repo_name: denisbertini/geneva

max_issues_repo_name: denisbertini/geneva

max_forks_repo_name: denisbertini/geneva


text:
// Copyright 2017-2018 Intel Corporation.

#include "tile/hal/cpu/executable.h"

#include <llvm/ExecutionEngine/ExecutionEngine.h>

#include <algorithm>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <utility>

#include <boost/asio.hpp>
#include <boost/asio/thread_pool.hpp>

#include "base/util/error.h"
#include "tile/hal/cpu/buffer.h"
#include "tile/hal/cpu/event.h"
#include "tile/hal/cpu/runtime.h"

namespace vertexai {
namespace tile {
namespace hal {
namespace cpu {
namespace {

const char invoker_prefix_[] = "__invoke_";

// std::thread::hardware_concurrency reports the number of cores including
// hyperthreaded cores, but hyperthreading does not help our performance and
// the overhead of additional threads harms it; we will therefore use only the
// physical number of cores when dividing up our workloads. This function takes
// a long time, so we'll perform the count only once at startup.
const size_t physical_cores_ = boost::thread::physical_concurrency();

}  // namespace

Executable::Executable(std::shared_ptr<llvm::LLVMContext> llvm_ctx,
                       std::vector<std::shared_ptr<llvm::ExecutionEngine>> engines, std::vector<lang::KernelInfo> kis,
                       std::shared_ptr<boost::asio::thread_pool> thread_pool)
    : llvm_context_{llvm_ctx}, engines_{engines}, kis_(kis), thread_pool_(thread_pool) {}

std::shared_ptr<hal::Event> Executable::Run(const context::Context& ctx, std::size_t kidx,
                                            const std::vector<std::shared_ptr<hal::Buffer>>& params,
                                            const std::vector<std::shared_ptr<hal::Event>>& dependencies,
                                            bool /* enable_profiling */) {
  context::Activity activity(ctx, "tile::hal::cpu::Kernel::Run");
  std::vector<std::shared_ptr<hal::Buffer>> param_refs{params};
  auto deps = Event::WaitFor(dependencies);
  auto evt = deps.then([params = std::move(param_refs), act = std::move(activity), engine = engines_[kidx],
                        invoker_name = InvokerName(kis_[kidx].kname), thread_pool = thread_pool_,
                        gwork = kis_[kidx].gwork](decltype(deps) future) -> std::shared_ptr<hal::Result> {
    future.get();
    auto start = std::chrono::high_resolution_clock::now();
    // Get the base address for all of these buffers, populating an argument
    // array, which we will pass in to the kernel's main function.
    std::vector<void*> args(params.size());
    for (size_t i = 0; i < args.size(); ++i) {
      args[i] = Buffer::Downcast(params[i])->base();
    }
    void* argvec = args.data();
    uint64_t entrypoint = engine->getFunctionAddress(invoker_name);
    // Iterate through the grid coordinates specified for this kernel, invoking
    // the kernel function once for each. We'll create one thread per core and
    // run one loop in each thread, staggering kernel invocations accordingly.
    size_t iterations = gwork[0] * gwork[1] * gwork[2];
    lang::GridSize denom = {{gwork[2] * gwork[1], gwork[2], 1}};
    size_t threads = std::min(iterations, physical_cores_);

    // The condition variable will guard the completion count. Each worker
    // will increment the completion count, and we'll wait until it reaches
    // the number of threads before returning.
    std::mutex mutex;
    std::condition_variable cv;
    size_t completed = 0;

    for (size_t offset = 0; offset < threads; ++offset) {
      boost::asio::post(*thread_pool, [=, &mutex, &cv, &completed]() {
        for (size_t i = offset; i < iterations; i += threads) {
          lang::GridSize index;
          index[0] = i / denom[0] % gwork[0];
          index[1] = i / denom[1] % gwork[1];
          index[2] = i / denom[2] % gwork[2];
          ((void (*)(void*, lang::GridSize*))entrypoint)(argvec, &index);
        }
        {
          std::unique_lock<std::mutex> lock{mutex};
          if (++completed == threads) {
            cv.notify_all();
          }
        }
      });
    }
    {
      std::unique_lock<std::mutex> lock{mutex};
      cv.wait(lock, [&]() { return threads <= completed; });
    }

    return std::make_shared<Result>(act.ctx(), "tile::hal::cpu::Executing", start,
                                    std::chrono::high_resolution_clock::now());
  });
  return std::make_shared<cpu::Event>(std::move(evt));
}

Executable::~Executable() { engines_.clear(); }

std::string Executable::InvokerName(std::string kname) { return invoker_prefix_ + kname; }

}  // namespace cpu
}  // namespace hal
}  // namespace tile
}  // namespace vertexai

ext: cc

max_stars_repo_name: TolyaTalamanov/plaidml

max_issues_repo_name: HubBucket-Team/plaidml

max_forks_repo_name: HubBucket-Team/plaidml


text:
/*
 * Copyright (c) 2016 Kevin Brightwell, Kenneth McIsaac
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#pragma once
#ifndef SE3313_MSG_VISITOR_HPP_
#define SE3313_MSG_VISITOR_HPP_

#include "error.hpp"
#include "instance.hpp"
#include "json.hpp"
#include "login.hpp"
#include "message.hpp"

#include <boost/property_tree/ptree.hpp>
#include <boost/optional.hpp>

#include <functional>
#include <sstream>
#include <string>
#include <unordered_map>

namespace se3313
{

namespace msg
{

namespace request {

/**
 * Represents a base type that "accepts" a json tree and calls a method based on what
 * type the tree represents.
 *
 * @param R The return type for all of the visit* methods.
 */
template <typename R = std::shared_ptr<se3313::msg::instance>>
class abstract_message_visitor {

public:

    /// The result type
    typedef R return_t;

    /// No-arg constructor, initalizes internal components.
    abstract_message_visitor();

    /// Default destructor
    virtual ~abstract_message_visitor() = default;

    /// Called when a login message is passed
    virtual
    return_t visitLogin(const request::login& /* request */ ) {
        return return_t();
    }

    /// Called when a message is passed
    virtual
    return_t visitMessage(const request::message& /* request */ ) {
        return return_t();
    }

    /// Called when an error occurs
    virtual
    return_t error(const std::string& /*originator*/,const ErrorCode /*code*/, const std::string& /*message*/)
    {
        return return_t();
    }

    /**
     * Provided function that will run the appropriate visitX function.
     *
     * \param json Tree structure parsed from a request
     */
    return_t visit(boost::property_tree::ptree& json)
    {
        const auto params = msg::instance::extractFrom(json);
        if (!params.is_initialized())
        {
            std::ostringstream ss;
            ss << "Invalid request specified (json=\"";
            boost::property_tree::write_json(ss, json, false);
            ss << "\")";
            return this->error(instance::UNKNOWN_SENDER, ErrorCode::MALFORMED_REQUEST_NO_TYPE, ss.str());
        }

        const std::string type = params->first;
        boost::property_tree::ptree obj = params->second;

        const auto visit_it = _propMap.find(type);
        if (visit_it != _propMap.end()) {
            return visit_it->second(obj);
        } else {
            std::ostringstream ss;
            ss << "Invalid object type tag specified (type=\"" << type << "\")";
            return this->error(instance::UNKNOWN_SENDER, ErrorCode::MALFORMED_REQUEST_NO_TYPE, ss.str());
        }
    }

private:

    /// Stores a mapping between TYPE and json tree extraction.
    std::unordered_map<std::string, std::function<return_t(boost::property_tree::ptree&)>> _propMap;

};

template <typename R>
abstract_message_visitor<R>::abstract_message_visitor()
{
    namespace pt = boost::property_tree;

    auto onError = [this](const std::string& type, pt::ptree& json) -> R
    {
        std::ostringstream ss;
        ss <<  "Object was incorrectly defined for " << type << ", json=" << msg::json::to(json);
        return this->error(instance::UNKNOWN_SENDER, ErrorCode::MALFORMED_REQUEST_BAD_OBJECT_DEF, ss.str());
    };

    _propMap[request::login::TYPE] =
        [this, onError](pt::ptree& json) {
            const std::shared_ptr<request::login> oVal = request::login::fromJson(json);

            if (oVal)
            {
                return this->visitLogin(*oVal);
            }
            else
            {
                return onError("login", json);
            }
        };

    _propMap[request::message::TYPE] =
        [this, onError](pt::ptree& json) {
            const std::shared_ptr<request::message> oVal = request::message::fromJson(json);

            if (oVal)
            {
                return this->visitMessage(*oVal);
            }
            else
            {
                return onError("message", json);
            }
        };
}

} // end request

namespace response {

/**
 * Represents a base type that "accepts" a json tree and calls a method based on what
 * type the tree represents.
 *
 * @param R The return type for all of the visit* methods.
 */
template <typename R = void>
class abstract_message_visitor {

public:

    /// The result type
    typedef R return_t;

    /// No-arg constructor, initalizes internal components.
    abstract_message_visitor();

    /// Default destructor
    virtual ~abstract_message_visitor() = default;

    /// Called when a login message is passed
    virtual
    return_t visitLogin(const response::login& /* request */ ) {
        return return_t();
    }

    /// Called when a message response is found
    virtual
    return_t visitMessage(const response::message& /* request */ ) {
        return return_t();
    }

    /// Called when an error message is required
    virtual
    return_t error(const std::string& /*originator*/, const ErrorCode /*code*/, const std::string& /*message*/)
    {
        return return_t();
    }

    /**
     * Provided function that will run the appropriate visitX function.
     *
     * \param json Tree structure parsed from a request
     */
    return_t visit(boost::property_tree::ptree& json)
    {
        const auto params = msg::instance::extractFrom(json);
        if (!params.is_initialized())
        {
            std::ostringstream ss;
            ss << "Invalid response specified (json=\"";
            boost::property_tree::write_json(ss, json, false);
            ss << "\")";
            return this->error(instance::UNKNOWN_SENDER, ErrorCode::MALFORMED_REQUEST_NO_TYPE, ss.str());
        }

        const std::string type = params->first;
        boost::property_tree::ptree obj = params->second;

        const auto visit_it = _propMap.find(type);
        if (visit_it != _propMap.end()) {
            return visit_it->second(obj);
        } else {
            std::ostringstream ss;
            ss << "Invalid object type tag specified (type=\"" << type << "\")";
            return this->error(instance::UNKNOWN_SENDER, ErrorCode::MALFORMED_REQUEST_NO_TYPE, ss.str());
        }
    }

private:

    /// Stores mapping between a TYPE and a parsing function
    std::unordered_map<std::string, std::function<return_t(boost::property_tree::ptree&)>> _propMap;

};

template <typename R>
abstract_message_visitor<R>::abstract_message_visitor()
{
    namespace pt = boost::property_tree;

    auto onError = [this](const std::string& type, pt::ptree& json) -> R
    {
        std::ostringstream ss;
        ss <<  "Object was incorrectly defined for " << type << ", json=" << msg::json::to(json);
        return this->error(instance::UNKNOWN_SENDER, ErrorCode::MALFORMED_REQUEST_BAD_OBJECT_DEF, ss.str());
    };

    _propMap[response::login::TYPE] =
        [this, onError](pt::ptree& json) {
            const std::shared_ptr<response::login> oVal = response::login::fromJson(json);

            if (oVal)
            {
                return this->visitLogin(*oVal);
            }
            else
            {
                return onError("login", json);
            }
        };

    _propMap[response::message::TYPE] =
        [this, onError](pt::ptree& json) {
            const std::shared_ptr<response::message> oVal = response::message::fromJson(json);

            if (oVal)
            {
                return this->visitMessage(*oVal);
            }
            else
            {
                return onError("message", json);
            }
        };
}

} // end namespace response

} // end namespace msg

} // end namespace se3313

#endif // SE3313_MSG_VISITOR_HPP_


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

#include <string>
#include <boost/bind.hpp>
#include <gtest/gtest.h>

#include "runtime/thread-resource-mgr.h"
#include "util/cpu-info.h"

#include "common/names.h"

namespace impala {

class NotifiedCounter {
 public:
  NotifiedCounter() : counter_(0) {
  }

  void Notify(ThreadResourceMgr::ResourcePool* consumer) {
    DCHECK(consumer != NULL);
    DCHECK_LT(consumer->num_threads(), consumer->quota());
    ++counter_;
  }

  int counter() const { return counter_; }

 private:
  int counter_;
};

TEST(ThreadResourceMgr, BasicTest) {
  ThreadResourceMgr mgr(5);
  NotifiedCounter counter1, counter2;

  ThreadResourceMgr::ResourcePool* c1 = mgr.RegisterPool();
  c1->SetThreadAvailableCb(bind<void>(mem_fn(&NotifiedCounter::Notify), &counter1, _1));
  c1->AcquireThreadToken();
  c1->AcquireThreadToken();
  c1->AcquireThreadToken();
  EXPECT_EQ(c1->num_threads(), 3);
  EXPECT_EQ(c1->num_required_threads(), 3);
  EXPECT_EQ(c1->num_optional_threads(), 0);
  EXPECT_EQ(counter1.counter(), 0);
  c1->ReleaseThreadToken(true);
  EXPECT_EQ(c1->num_threads(), 2);
  EXPECT_EQ(c1->num_required_threads(), 2);
  EXPECT_EQ(c1->num_optional_threads(), 0);
  EXPECT_EQ(counter1.counter(), 1);
  bool is_reserved = false;
  c1->ReserveOptionalTokens(1);
  EXPECT_TRUE(c1->TryAcquireThreadToken(&is_reserved));
  EXPECT_TRUE(is_reserved);
  EXPECT_TRUE(c1->TryAcquireThreadToken(&is_reserved));
  EXPECT_FALSE(is_reserved);
  EXPECT_TRUE(c1->TryAcquireThreadToken(&is_reserved));
  EXPECT_FALSE(is_reserved);
  EXPECT_FALSE(c1->TryAcquireThreadToken(&is_reserved));
  EXPECT_FALSE(is_reserved);
  EXPECT_EQ(c1->num_threads(), 5);
  EXPECT_EQ(c1->num_required_threads(), 2);
  EXPECT_EQ(c1->num_optional_threads(), 3);
  c1->ReleaseThreadToken(true);
  c1->ReleaseThreadToken(false);
  EXPECT_EQ(counter1.counter(), 3);

  // Register a new consumer, quota is cut in half
  ThreadResourceMgr::ResourcePool* c2 = mgr.RegisterPool();
  c2->SetThreadAvailableCb(bind<void>(mem_fn(&NotifiedCounter::Notify), &counter2, _1));
  EXPECT_FALSE(c1->TryAcquireThreadToken());
  EXPECT_EQ(c1->num_threads(), 3);
  c1->AcquireThreadToken();
  EXPECT_EQ(c1->num_threads(), 4);
  EXPECT_EQ(c1->num_required_threads(), 2);
  EXPECT_EQ(c1->num_optional_threads(), 2);

  mgr.UnregisterPool(c1);
  mgr.UnregisterPool(c2);
  EXPECT_EQ(counter1.counter(), 3);
  EXPECT_EQ(counter2.counter(), 1);
}

}

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  impala::CpuInfo::Init();
  return RUN_ALL_TESTS();
}

max_stars_repo_name: drankye/recordservice

max_issues_repo_name: drankye/recordservice

max_forks_repo_name: drankye/recordservice


text:
#include <ctime>
#include <iostream>
#include <string>
#include <memory>
#include <functional>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;
using namespace std;

void process_client(shared_ptr<tcp::socket> client)
{
    time_t now = time(0);
    shared_ptr<string> message(new string(ctime(&now)));

    auto callback = [=](const boost::system::error_code &err, size_t size) {
        if ((int)size == message->length())
            cout << "write completed" << endl;
    };

    client->async_send(boost::asio::buffer(*message), callback);
}

typedef function<void(const boost::system::error_code &)> accept_callback;
void start_accept(tcp::acceptor &server)
{
    shared_ptr<tcp::socket> client(new tcp::socket(server.get_executor()));
    accept_callback callback = [&server, client](const boost::system::error_code &error) {
        if (!error)
            process_client(client);

        start_accept(server);
    };

    server.async_accept(*client, callback);
}

int main()
{
    try
    {
        boost::asio::io_service io_service;
        tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3200));
        start_accept(acceptor);
        io_service.run();
    }
    catch (std::exception &e)
    {
        std::cerr << e.what() << std::endl;
    }
    return 0;
}

max_stars_repo_name: RyougiTale/poker-fight

max_issues_repo_name: RyougiTale/poker-fight

max_forks_repo_name: RyougiTale/poker-fight


text:
#include <string>
#include <algorithm>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/assign/list_of.hpp> //for ref_list_of
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/progress.hpp>

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <geometry_msgs/Twist.h>
#include <sensor_msgs/Joy.h>
#include "joystick.hpp"

int main(int argc, char **argv)
{

    ros::init(argc, argv, "JoyTestNode");
    Joystick joyhandle;

    joyhandle.init();
    joyhandle.procReadPub();
    return 0;

}


text:
#pragma once

#include <Eigen/Core>
#include <Eigen/Sparse>

namespace ipc::rigid {

Eigen::SparseMatrix<double> multiply(
    const Eigen::VectorXd& x,
    const std::vector<Eigen::SparseMatrix<double>>& y);

} // namespace ipc::rigid

max_stars_repo_name: ipc-sim/rigid-ipc

max_issues_repo_name: ipc-sim/rigid-ipc

max_forks_repo_name: ipc-sim/rigid-ipc


text:
//    Copyright 2017 Rainer Gemulla
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
/** \file
 *
 * Illustrates matrix factorization with GNMF. */
#include <iostream>

#include <boost/math/distributions/normal.hpp>
#include <boost/math/distributions/binomial.hpp>
#include <boost/random/uniform_real.hpp>

#include <util/evaluation.h>
#include <util/io.h>

#include <mf/mf.h>

using namespace std;
using namespace mf;
using namespace rg;
using namespace boost::numeric::ublas;

log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("main"));

int main(int argc, char* argv[]) {
#ifndef NDEBUG
	LOG4CXX_WARN(logger, "Warning: Debug mode activated (runtimes may be slow).");
#endif

	// parameters for the factorization
	mf_size_type size1 = 100; //10000;
	mf_size_type size2 = 100; //10000;
	mf_size_type nnz = 50; //5000000;
	mf_size_type r = 2; // 10

	// parameters for GNMF
	unsigned epochs = 1600;
	mf_size_type testNnz = nnz/100;

	BalanceType type = BALANCE_L2;;
	BalanceMethod method = BALANCE_OPTIMAL;

	// generate original factors by sampling from a uniform[0,1] distribution
	Random32 random; // note: this takes a default seed (not randomized!)
	DenseMatrix wIn(size1, r);
	DenseMatrixCM hIn(r, size2);
	generateRandom(wIn, random, boost::uniform_real<>(0,1));
	generateRandom(hIn, random, boost::uniform_real<>(0,1));

	// clear one row
	for (mf_size_type k=0; k<r; k++) {
		wIn(0,k) = 0;
	}

	// generate a sparse matrix by selecting random entries from the generated factors
	// and add small Gaussian noise
	SparseMatrix v;
	generateRandom(v, nnz, wIn, hIn, random);
	//addRandom(v, random, boost::normal_distribution<>(0, 0.1));
	LOG4CXX_INFO(logger, "Data matrix: "
		<< v.size1() << " x " << v.size2() << ", " << v.nnz() << " nonzeros");
	v.sort();
	//LOG4CXX_INFO(logger, "Loss with original factors: " << loss((FactorizationData<>(v, wIn, hIn))));
	SparseMatrixCM vc;
	copyCm(v, vc);

	// create a test matrix (without noise)
	SparseMatrix vTest;
	generateRandom(vTest, testNnz, wIn, hIn, random);
	LOG4CXX_INFO(logger, "Test matrix: "
		<< v.size1() << " x " << v.size2() << ", " << vTest.nnz() << " nonzeros");

	// generate initial factors by sampling from a uniform[0,1] distribution
	DenseMatrix w(size1, r);
	DenseMatrixCM h(r, size2);
	generateRandom(w, random, boost::uniform_real<>(0,1));
	LOG4CXX_INFO(logger, "Row factors: " << w.size1() << " x " << w.size2());
	generateRandom(h, random, boost::uniform_real<>(0,1));
	LOG4CXX_INFO(logger, "Column factors: " << h.size1() << " x " << h.size2());

	// initialize
	FactorizationData<> data(v, w, h, 1, &vc);
	FactorizationData<> testJob(vTest,w,h);
	Trace trace;
	Timer t;

	LOG4CXX_INFO(logger, "Start");
	// run GNMF to try to reconstruct the original factors
	t.start();
	gnmf(data, epochs, trace, type, method, &testJob);
	t.stop();
	LOG4CXX_INFO(logger, "Total time: " << t);

	// write trace to an R file
	LOG4CXX_INFO(logger, "Writing trace to " << "/tmp/gnmf-trace.R");
	trace.toRfile("/tmp/gnmf-trace.R", "gnmf");

	return 0;
}

max_stars_repo_name: Hui-Li/DSGDPP

max_issues_repo_name: Hui-Li/DSGDPP

max_forks_repo_name: Hui-Li/DSGDPP


text:
//==================================================================================================
/*!
  @file

  @copyright 2016 NumScale SAS
  @copyright 2016 J.T.Lapreste

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_DEFINITION_ONEPLUS_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_DEFINITION_ONEPLUS_HPP_INCLUDED

#include <boost/simd/config.hpp>
#include <boost/dispatch/function/make_callable.hpp>
#include <boost/dispatch/hierarchy/functions.hpp>
#include <boost/simd/detail/dispatch.hpp>

namespace boost { namespace simd
{
  namespace tag
  {
    BOOST_DISPATCH_MAKE_TAG(ext, oneplus_, boost::dispatch::elementwise_<oneplus_>);
  }

  namespace ext
  {
    BOOST_DISPATCH_FUNCTION_DECLARATION(tag, oneplus_);
  }

  BOOST_DISPATCH_CALLABLE_DEFINITION(tag::oneplus_,oneplus);

} }

#endif


text:
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#include "geom.h"

#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/index/rtree.hpp>

#include "geometry/correct.hpp"

#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/irange.hpp>

typedef boost::geometry::model::segment<Point> simplify_segment;
typedef boost::geometry::index::rtree<simplify_segment, boost::geometry::index::quadratic<16>> simplify_rtree;

template<typename GeometryType>
static inline void simplify_ring(GeometryType const &input, GeometryType &output, double distance, simplify_rtree const &outer_rtree = simplify_rtree())
{
    std::deque<std::size_t> nodes(input.size());
    for(std::size_t i = 0; i < input.size(); ++i)
        nodes[i] = i;

	simplify_rtree rtree(
		boost::irange<std::size_t>(0, input.size() - 1)
		| boost::adaptors::transformed(std::function<simplify_segment(std::size_t)>([&input](std::size_t i) {
			return simplify_segment(input[i], input[i+1]);
		})));

    Box envelope; boost::geometry::envelope(input, envelope);

	for(std::size_t pq = input.size() - 2; pq--; ) {
        auto entry = pq;

        auto start = nodes[entry];
        auto middle = nodes[entry + 1];
        auto end = nodes[entry + 2];

        if (input[middle].x()==envelope.min_corner().x() ||
            input[middle].y()==envelope.min_corner().y() ||
            input[middle].x()==envelope.max_corner().x() ||
            input[middle].y()==envelope.max_corner().y()) continue;

        simplify_segment line(input[start], input[end]);

        double max_comp_distance = 0.0;
		std::size_t max_comp_i = start + 1;

        for(auto i = start + 1; i < end; ++i) {
			auto comp_distance = boost::geometry::comparable_distance(line, input[i]);
            if(comp_distance > max_comp_distance) {
				max_comp_distance = comp_distance;
				max_comp_i = i;
			}
		}

        if(boost::geometry::distance(line, input[max_comp_i]) < distance) {
			std::size_t query_count = 0;
            for(auto const &result: rtree | boost::geometry::index::adaptors::queried(boost::geometry::index::intersects(line)))
				++query_count;
            for(auto const &result: outer_rtree | boost::geometry::index::adaptors::queried(boost::geometry::index::intersects(line)))
				++query_count;

			std::size_t expected_count = std::min<std::size_t>(4, nodes.size() - 1);
            if(query_count == expected_count) {
                nodes.erase(nodes.begin() + entry + 1);
                rtree.remove(simplify_segment(input[start], input[middle]));
                rtree.remove(simplify_segment(input[middle], input[end]));
                rtree.insert(line);
            }
        }
    }

	output.resize(nodes.size());
	for(std::size_t i = 0; i < nodes.size(); ++i)
		output[i] = input[nodes[i]];
}

Polygon simplify(Polygon const &p, double max_distance)
{
	Polygon result;

	simplify_rtree outer_rtree(
		boost::irange<std::size_t>(0, p.outer().size() - 1)
		| boost::adaptors::transformed(std::function<simplify_segment(std::size_t)>([&p](std::size_t i) {
			return simplify_segment(p.outer()[i], p.outer()[i+1]);
		})));

	for(auto const &inner: p.inners()) {
		Ring new_inner;
		simplify_ring(inner, new_inner, max_distance, outer_rtree);

		std::reverse(new_inner.begin(), new_inner.end());
		if(new_inner.size() > 3 && boost::geometry::perimeter(new_inner) > 3 * max_distance) {
			simplify_combine(result.inners(), std::move(new_inner));
		}
	}

	simplify_rtree inners_rtree;
	for(auto &inner: result.inners()) {
		std::reverse(inner.begin(), inner.end());

		inners_rtree.insert(
			boost::irange<std::size_t>(0, inner.size() - 1)
			| boost::adaptors::transformed(std::function<simplify_segment(std::size_t)>([&inner](std::size_t i) {
				return simplify_segment(inner[i], inner[i+1]);
			})));
	}

	simplify_ring(p.outer(), result.outer(), max_distance, inners_rtree);
	if(result.outer().size() > 3 && boost::geometry::perimeter(result.outer()) > 3 * max_distance) {
		return result;
	}

	result = Polygon();
	return result;
}

Linestring simplify(Linestring const &ls, double max_distance)
{
	Linestring result;
	boost::geometry::simplify(ls, result, max_distance);
	return result;
}

MultiPolygon simplify(MultiPolygon const &mp, double max_distance)
{
	MultiPolygon result_mp;
	for(auto const &p: mp) {
		Polygon new_p = simplify(p, max_distance);
    	if(!new_p.outer().empty()) {
			simplify_combine(result_mp, std::move(new_p));
		}
	}

	return result_mp;
}

void make_valid(MultiPolygon &mp)
{
	MultiPolygon result;
	for(auto const &p: mp) {
		geometry::correct(p, result, 1E-12);
	}
	mp = result;
}

max_stars_repo_name: nadabyte/tilemaker

max_issues_repo_name: nadabyte/tilemaker

max_forks_repo_name: nadabyte/tilemaker