text:
#include <vector>
#include <iostream>
#include <map>
#include <cstring>
#include <list>
#include <memory>
#include <chrono>
#include <thread>
#include <cassert>
#include <csignal>
#include <cmath>
#include <variant>
#include <random>
#include <algorithm>
#include <numeric>
#include <iterator>
#include <fstream>
#include <time.h>

#define RESOURCES_DATA_PATH (std::string) "resources/data"

#ifdef WITH_BOOST

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

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

#endif

#include "MUtil.h"
#include "DGen.hpp"
#include "NNet.hpp"
#include "CEng.hpp"
#include "tests.hpp"

int main() {

	#ifdef WITH_BOOST
	Py_Initialize();

	boost::python::numpy::initialize();
	#endif

	dgen_tests();

	std::cout << "LOAD MNIST" << std::endl;

	#define IN_T float
	#define HL_T float

	auto datain = DGen::LoadMnist<DEBUG0>("data");

	constexpr size_t INPUT_LAYER = datain.get_pattern_size();
	constexpr size_t OUTPUT_LAYER = datain.get_labels_size();
	constexpr size_t B = datain.get_train_batch_size();
	constexpr size_t mB = 1000;

	{
		TIME_START

		//auto xtrainBegin = mnist->begin<DGen::data_e::TRAIN_IMG>();
		//auto xtrainEnd = mnist->end<DGen::data_e::TRAIN_IMG>();

		//auto f = std::accumulate(xtrainBegin, xtrainEnd, 0.f, [&](MNIST_IN_t in, MNIST_IN_t &x) {return in + x;});

		//std::cout << "sum = " << f / double{256} << std::endl;

		TIME_CHECK
	}

	std::srand(0);

	auto layersMaker = NNet::LayersMaker<IN_T, HL_T, B, mB, INPUT_LAYER, 20, OUTPUT_LAYER>();

	auto layers = layersMaker.alloc<DEBUG1>();

	auto datagen = DGen::Datagen<HL_T, DGen::RANDOM_NORMAL>();

	auto engine = CEng::Engine();

	auto network = NNet::Network(layersMaker, layers, engine, datain, datagen);

	network.print();

	network.init<DEBUG1>();

	network.compute<DEBUG2>();

	TIME_START
	for (int i = 0; i < 10000000; i++) {
		network.compute<DEBUG0>();
	}
	TIME_CHECK

/*	auto start = clock();

	size_t o = 0;
	for (size_t i = 0; i < 1000; i++) {
		o += 1;
		compute<DEBUG0, Layers_t, I, shapeNN...>(1, layersWrap, enginePtr);
	}

	std::cout << "Took " << clock() - start << " ms" << std::endl;

	std::cout << o << std::endl;
*/

	//auto * lh = (LayerHidden<int, 100, 100, mB> * ) layersWrap.layersTraining[1];
	//lh->V;
	//layersWrap->print();

	std::cout << "Done." << std::endl;

	return 0;
}

ext: cpp


text:
#include "ublox.hpp"

#include <chrono>
#include <fstream>
#include <thread>
#include <generic_logger/generic_logger.hpp>
#include <boost/algorithm/string.hpp>

#include "exception.hpp"
#include "internal/protocol.hpp"

namespace sensor_ublox {

GNSSReceiver::GNSSReceiver(const GNSSReceiverOptions& opts) : opts_(opts) {
    configHandler_ = std::make_unique<internal::UbxConfigHandler>(opts.configFile, opts.baseConfigFile);
    initializeConnection();
}

GNSSReceiver::~GNSSReceiver() {
    stop();
}

void GNSSReceiver::initializeConnection() {
    ioService_ = std::make_unique<baio::io_service>();
    try {
        serialPort_ = std::make_unique<boost::asio::serial_port>(*ioService_);
        // open serial port
        serialPort_->open(opts_.deviceName.string());
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        // setup serial port
        serialPort_->set_option(baio::serial_port_base::baud_rate(configHandler_->config().baudRate));
        serialPort_->set_option(baio::serial_port_base::character_size(8));
        serialPort_->set_option(baio::serial_port_base::flow_control(baio::serial_port_base::flow_control::none));
        serialPort_->set_option(baio::serial_port_base::parity(baio::serial_port_base::parity::none));
        serialPort_->set_option(baio::serial_port_base::stop_bits(baio::serial_port_base::stop_bits::one));

        DEBUG_STREAM("Connection to serial port '" << opts_.deviceName.string() << "' established");
    } catch (std::runtime_error& e) {
        throw GNSSException(std::string("Failed to open serial port: ") + e.what());
    }
}

void GNSSReceiver::waitForAcknowledgement(const std::chrono::microseconds& timeout) {
    auto waitTimePoint = std::chrono::high_resolution_clock::now() + timeout;
    while (acknowledgement_ == UbxAcknowledgement::WAIT && std::chrono::high_resolution_clock::now() < waitTimePoint) {
        asyncWorker_->wait(timeout);
    }
}

void GNSSReceiver::run() {
    dataStreamReader_ = std::make_unique<internal::UbxDataStreamReader>();

    asyncWorker_ = std::make_shared<internal::AsyncWorker>(*serialPort_, *ioService_);
    asyncWorker_->setCallback(
        [this](const uint8_t* data, const size_t numBytes) { this->asyncReadCallback(data, numBytes); });
    asyncWorker_->run();
    loadConfiguration();
    if (configHandler_->config().dgps.enabled == true) {
        rtcmListener_ =
            std::make_unique<internal::RTCMListener>(asyncWorker_, configHandler_->config().dgps.serialDevicePath);
        rtcmListener_->startListener();
    }
}

void GNSSReceiver::loadConfiguration() {
    const auto& streams = configHandler_->getConfigStreams();
    auto timeout = std::chrono::milliseconds(20);
    for (const auto& s : streams) {
        for (uint32_t i = 0; i < 10; i++) {
            acknowledgement_ = UbxAcknowledgement::WAIT;
            asyncWorker_->send(s);
            waitForAcknowledgement(timeout);
            if (acknowledgement_ == UbxAcknowledgement::ACK) {
                INFO_STREAM("Uploading of configuration '" << static_cast<int32_t>(s[2]) << " - "
                                                           << static_cast<int32_t>(s[3]) << "' succeeded");
                break;
            } else if (acknowledgement_ == UbxAcknowledgement::NACK) {
                ERROR_STREAM("Uploading of configuration '" << static_cast<int32_t>(s[2]) << " - "
                                                            << static_cast<int32_t>(s[3]) << "' failed");
                break;
            } else {
                DEBUG_STREAM("No status received from device - trying again ...");
            }
        }
    }
}

void GNSSReceiver::stop() {
    if (rtcmListener_) {
        rtcmListener_->stopListener();
    }
    asyncWorker_->stop();
    condVarShutdown_.notify_all();
}

void GNSSReceiver::asyncReadCallback(const uint8_t* data, const size_t numBytes) {
    dataStreamReader_->addData(data, numBytes);
    auto nextUbxObject = dataStreamReader_->get();
    while (nextUbxObject != dataStreamReader_->end()) {
        if (nextUbxObject.classID() == 0x05) {
            // handle acknowledgements differently
            DEBUG_STREAM("Acknowledgement packet received: " << (nextUbxObject.messageID() == 0x00 ? "NACK" : "ACK"));
            acknowledgement_ = (nextUbxObject.messageID() == 0x00) ? UbxAcknowledgement::NACK : UbxAcknowledgement::ACK;
        } else {
            auto key = internal::ObjectFactory::key_type(nextUbxObject.classID(), nextUbxObject.messageID());
            DEBUG_STREAM("Data packet received: " << static_cast<int64_t>(nextUbxObject.classID()) << " / "
                                                  << static_cast<int64_t>(nextUbxObject.messageID()));
            std::lock_guard<std::mutex> guard(factoryMutex_);
            //            for (const auto& m : callbackFactory_) {
            //                DEBUG_STREAM("Mapping: " << (int)m.first.first << " / " << (int)m.first.second);
            //            }
            auto itLower = callbackFactory_.lower_bound(key);
            auto itUpper = callbackFactory_.upper_bound(key);
            for (auto it = itLower; it != itUpper; ++it) {
                it->second->handleData(nextUbxObject);
            }
        }
        nextUbxObject = dataStreamReader_->get();
    }
}

bool GNSSReceiver::uploadConfiguration(const internal::DataBuffer& cfgBuffer) {
    auto timeout = std::chrono::milliseconds(500);
    acknowledgement_ = UbxAcknowledgement::WAIT;
    asyncWorker_->send(cfgBuffer);
    waitForAcknowledgement(timeout);
    return acknowledgement_ == UbxAcknowledgement::ACK;
}

std::vector<std::pair<uint8_t, uint8_t>> GNSSReceiver::getEnabledMessages() const {
    std::vector<std::pair<uint8_t, uint8_t>> enabledMessages;
    for (const auto& m : configHandler_->config().msgs) {
        if (m.rate > 0) {
            enabledMessages.push_back(m.msgID);
        }
    }
    return enabledMessages;
}

} // namespace sensor_ublox


text:
#pragma once
#include <atomic>
#include <boost/beast/core/buffers_to_string.hpp>
#include <memory>
#include <string>
#include <tracy/tracy.hpp>

#include "beast-compact.hpp"
#include "context.hpp"
#include "log/log.hpp"
#include "session.hpp"

template<class Derived>
class websocket_client_session_t : public ws_session_abstract_t {
public:
    websocket_client_session_t(
        session_handler_t* session_handler,
        log_t& log)
        : session_handler_(session_handler)
        , id_(reinterpret_cast<std::uintptr_t>(this))
        , log_(log.clone()) {
        ZoneScoped;
    }

    ~websocket_client_session_t() = default;

    auto run(
        const host_t& host,
        const port_t& port,
        const std::string& init_message) -> void {
        ZoneScoped;
        log_.trace("{} +++", GET_TRACE());
        host_.assign(host);
        port_.assign(port);
        init_message_.assign(init_message);
        derived().resolver().async_resolve(
            host_,
            port_,
            beast::bind_front_handler(
                &websocket_client_session_t::on_resolve,
                derived().shared_from_this()));
    }

protected:
    void write_impl(ws_message_ptr message) override {
        ZoneScoped;
        log_.trace("{} {} : response.size() = {} +++",
                   GET_TRACE(), id_, message->size());
    }
    //@TODO !!! double close safety
    void close_impl() override {
        ZoneScoped;
        std::string str("exited");
        auto size = str.size();
        session_handler_->ws_dispatch(id_, std::move(str), size);
        buffer_.consume(buffer_.size());
        buffer_.clear();
    }

    bool is_close_impl() override {
        ZoneScoped;
        return false;
    }

private:
    // Access the derived class, this is part of
    // the Curiously Recurring Template Pattern idiom.
    Derived& derived() {
        ZoneScoped;
        return static_cast<Derived&>(*this);
    }

    session_handler_t* session_handler_;
    const std::uintptr_t id_;
    beast::flat_buffer buffer_;
    log_t log_;

    host_t host_;
    port_t port_;
    std::string init_message_;

private:
    void on_resolve(
        beast::error_code ec,
        tcp::resolver::results_type results) {
        ZoneScoped;
        log_.trace("{} +++", GET_TRACE());
        if (ec) {
            log_.error("{} : !!! Failed: {} !!!", GET_TRACE(), ec.message());
            session_handler_->close(id_);
            return;
        }

        // Set the timeout for the operation
        beast::get_lowest_layer(derived().ws()).expires_after(std::chrono::seconds(30));

        // Make the connection on the IP address we get from a lookup
        beast::get_lowest_layer(derived().ws()).async_connect(results, beast::bind_front_handler(&websocket_client_session_t::on_connect, derived().shared_from_this()));
    }

    void on_connect(
        beast::error_code ec,
        tcp::resolver::results_type::endpoint_type ep) {
        ZoneScoped;
        log_.trace("{} +++", GET_TRACE());
        if (ec) {
            log_.error("{} : !!! Failed: {} !!!", GET_TRACE(), ec.message());
            session_handler_->close(id_);
            return;
        }

        // Turn off the timeout on the tcp_stream, because
        // the websocket stream has its own timeout system.
        beast::get_lowest_layer(derived().ws()).expires_never();

        // Set suggested timeout settings for the websocket
        /*derived().ws().set_option(
            websocket::stream_base::timeout::suggested(
                beast::role_type::client));*/

        // Set a decorator to change the User-Agent of the handshake
        derived().ws().set_option(websocket::stream_base::decorator(
            [](websocket::request_type& req) {
                /*req.set(http::field::user_agent,
                    std::string(BOOST_BEAST_VERSION_STRING) +
                        " websocket-client-async");*/
            }));

        websocket::stream_base::timeout opt{
            std::chrono::seconds(30),       // handshake timeout
            websocket::stream_base::none(), // idle timeout. no data recv from peer for 6 sec, then it is timeout
            true                            //enable ping-pong to keep alive
        };

        derived().ws().set_option(opt);

        derived().ws().read_message_max(20ull << 20); // sets the limit to 20 miB

        // Update the host_ string. This will provide the value of the
        // Host HTTP header during the WebSocket handshake.
        // See https://tools.ietf.org/html/rfc7230#section-5.4
        host_ += ':' + std::to_string(ep.port());

        // Perform the websocket handshake
        derived().ws().async_handshake(
            host_, "/",
            beast::bind_front_handler(
                &websocket_client_session_t::on_handshake,
                derived().shared_from_this()));
    }

    void on_handshake(beast::error_code ec) {
        ZoneScoped;
        log_.trace("{} +++", GET_TRACE());
        if (ec) {
            log_.error("{} : !!! Failed: {} !!!", GET_TRACE(), ec.message());
            session_handler_->close(id_);
            return;
        }

        // Send the message
        derived().ws().async_write(
            net::buffer(init_message_),
            beast::bind_front_handler(
                &websocket_client_session_t::on_write,
                derived().shared_from_this()));
    }

    void on_write(
        beast::error_code ec,
        std::size_t bytes_transferred) {
        ZoneScoped;
        log_.trace("{} bytes_transferred = {} +++",
                   GET_TRACE(), bytes_transferred);

        if (ec) {
            log_.error("{} : !!! Failed: {} !!!", GET_TRACE(), ec.message());
            session_handler_->close(id_);
            return;
        }

        // Read a message into our buffer
        derived().ws().async_read(
            buffer_,
            beast::bind_front_handler(
                &websocket_client_session_t::on_read,
                derived().shared_from_this()));
    }

    void on_read(
        beast::error_code ec,
        std::size_t bytes_transferred) {
        ZoneScoped;
        log_.trace("{} bytes_transferred = {} +++", GET_TRACE(), bytes_transferred);

        if (ec) {
            log_.error("{} : !!! Failed: {} !!!", GET_TRACE(), ec.message());
            session_handler_->close(id_);
            return;
        }

        log_.trace("{} buffer_.consume {} bytes", GET_TRACE(), buffer_.size());
        auto buf_str = beast::buffers_to_string(buffer_.data());
        auto buf_size = buf_str.size();
        session_handler_->ws_dispatch(id_, std::move(buf_str), buf_size);
        buffer_.consume(buf_size);

        // Read a message into our buffer
        derived().ws().async_read(
            buffer_,
            beast::bind_front_handler(
                &websocket_client_session_t::on_read,
                derived().shared_from_this()));
    }
};

template<class Derived>
class websocket_session_t : public ws_session_abstract_t {
public:
    websocket_session_t(session_handler_t* session_handler, log_t& log)
        : session_handler_(session_handler)
        , log_(log.clone())
        , id_(reinterpret_cast<std::uintptr_t>(this))
        , is_writing_(false) {
        ZoneScoped;
    }

    // https://github.com/boostorg/beast/blob/develop/example/websocket/server/async/websocket_server_async.cpp
    // Get on the correct executor
    template<class Body, class Allocator>
    auto run(http::request<Body, http::basic_fields<Allocator>> req)
        -> void {
        ZoneScoped;
        // We need to be executing within a strand to perform async operations
        // on the I/O objects in this session. Although not strictly necessary
        // for single-threaded contexts, this example code is written to be
        // thread-safe by default.
        net::dispatch(
            derived().ws().get_executor(),
            beast::bind_front_handler(
                &websocket_session_t::do_accept<Body, Allocator>,
                derived().shared_from_this(),
                std::move(req)));
        //do_accept(std::move(req));
    }

protected:
    void write_impl(ws_message_ptr message) override {
        ZoneScoped;
        if (!message)
            return;
        log_.debug("{} {} : message.size() = {} +++",
                   GET_TRACE(), id_, message->size());
        send(message);
    }
    //@TODO !!! double close safety
    void close_impl() override {
        ZoneScoped;
        std::string str("exited");
        auto size = str.size();
        session_handler_->ws_dispatch(id_, std::move(str), size);
        buffer_.consume(buffer_.size());
        buffer_.clear();
    }

    bool is_close_impl() override {
        ZoneScoped;
        return false;
    }

private:
    // Access the derived class, this is part of
    // the Curiously Recurring Template Pattern idiom.
    Derived& derived() {
        ZoneScoped;
        return static_cast<Derived&>(*this);
    }

    session_handler_t* session_handler_;
    log_t log_;
    const std::uintptr_t id_;
    beast::flat_buffer buffer_;

    std::atomic_bool is_writing_;

    // Start the asynchronous operation
    template<class Body, class Allocator>
    void
    do_accept(http::request<Body, http::basic_fields<Allocator>> req) {
        ZoneScoped;

        // Turn off the timeout on the tcp_stream, because
        // the websocket stream has its own timeout system.
        beast::get_lowest_layer(derived().ws()).expires_never();

        // Standard suggested timeout:
        /*derived().ws().set_option(
            websocket::stream_base::timeout::suggested(
                beast::role_type::server));*/

        derived().ws().set_option(
            websocket::stream_base::decorator(
                [](websocket::response_type& res) {

                }));

        websocket::stream_base::timeout opt{
            std::chrono::seconds(30),       // handshake timeout
            websocket::stream_base::none(), // idle timeout. no data recv from peer for 6 sec, then it is timeout
            true                            //enable ping-pong to keep alive
        };

        derived().ws().set_option(opt);

        derived().ws().read_message_max(20ull << 20); // sets the limit to 20 miB

        derived().ws().async_accept(
            req,
            beast::bind_front_handler(
                &websocket_session_t::on_accept,
                derived().shared_from_this()));
    }

    void on_accept(beast::error_code ec) {
        ZoneScoped;
        if (ec) {
            log_.error("{} {} : !!! {} !!!",
                       GET_TRACE(), id_, ec.message());
            session_handler_->close(id_);
            return;
        }

        // Read a message
        net::post(
            derived().ws().get_executor(),
            beast::bind_front_handler(
                &websocket_session_t::do_read,
                derived().shared_from_this()));
    }

    void do_read() {
        ZoneScoped;
        log_.trace("{} {} +++", GET_TRACE(), id_);
        // Read a message into our buffer
        derived().ws().async_read(
            buffer_,
            beast::bind_front_handler(
                &websocket_session_t::on_read,
                derived().shared_from_this()));

        log_.trace("{} {} ---", GET_TRACE(), id_);
    }

    void on_read(beast::error_code ec,
                 std::size_t bytes_transferred) {
        ZoneScoped;
        log_.trace("{} {} bytes_transferred = {} +++",
                   GET_TRACE(), id_, bytes_transferred);

        // This indicates that the websocket_session was closed
        if (ec == websocket::error::closed) {
            log_.debug("{} {} : the websocket_session was closed",
                       GET_TRACE(), id_);
            session_handler_->close(id_);
            return;
        }

        if (ec) {
            log_.error("{} {} : !!! {} !!!",
                       GET_TRACE(), id_, ec.message());
            dequeue();
            session_handler_->close(id_);
            return;
        }

        auto buf_str = beast::buffers_to_string(buffer_.data());
        auto buf_size = buf_str.size();
        session_handler_->ws_dispatch(id_, std::move(buf_str), buf_size);
        buffer_.consume(buf_size);

        net::post(
            derived().ws().get_executor(),
            beast::bind_front_handler(
                &websocket_session_t::do_read,
                derived().shared_from_this()));
    }

    void
    run_async_write() {
        ZoneScoped;

        log_.trace("{} {} +++", GET_TRACE(), id_);

        if (is_empty())
            return;

        auto& task = front();
        log_.trace("{} {} : derived().ws().async_write {} ... .. .", GET_TRACE(), id_, task.message_->size());

        derived().ws().text(task.message_->is_text());
        derived().ws().async_write(
            net::buffer(task.message_->data(), task.message_->size()),
            beast::bind_front_handler(
                &websocket_session_t::on_write,
                derived().shared_from_this()));
    }

    void
    on_write(
        beast::error_code ec,
        std::size_t bytes_transferred) {
        ZoneScoped;

        log_.trace("{} {} +++", GET_TRACE(), id_);

        if (ec) {
            log_.error("{} {} : !!! {} !!!",
                       GET_TRACE(), id_, ec.message());
            dequeue();
            session_handler_->close(id_);
            return;
        }

        log_.debug("{} {} bytes_transferred = {} +++",
                   GET_TRACE(), id_, bytes_transferred);

        dequeue();
        log_.trace("{} {} ---", GET_TRACE(), id_);

        // https://github.com/boostorg/beast/blob/c4813a5ac79d802951cf70b811ded94ce7ef7d79/example/cppcon2018/websocket_session.cpp#L87
        // https://github.com/boostorg/beast/issues/1381
        net::post(
            derived().ws().get_executor(),
            beast::bind_front_handler(
                &websocket_session_t::run_async_write,
                derived().shared_from_this()));
    }

    class task_t final {
    public:
        task_t(ws_message_ptr message)
            : message_(message) {}
        task_t(task_t&&) = default;
        task_t(const task_t&) = default;
        ~task_t() = default;

        ws_message_ptr message_;
    };

    /**
     * IMPORTANT @NOTE:
     * On multi-async operation catch this:
     *
     * /include/boost/beast/websocket/detail/soft_mutex.hpp:79
     *  template<class T>
        bool
        try_lock(T const*)
        {
            // If this assert goes off it means you are attempting to
            // simultaneously initiate more than one of same asynchronous
            // operation, which is not allowed. For example, you must wait
            // for an async_read to complete before performing another
            // async_read.
            //
            BOOST_ASSERT(id_ != T::id);
            if(id_ != 0)
                return false;
            id_ = T::id;
            return true;
        }
     *
     **/

    void send_loop() {
        ZoneScoped;
        log_.trace("{} {} +++", GET_TRACE(), id_);

        // https://github.com/boostorg/beast/blob/c4813a5ac79d802951cf70b811ded94ce7ef7d79/example/cppcon2018/websocket_session.cpp#L87
        // https://github.com/boostorg/beast/issues/1381
        // Are we already writing?
        if (size() > 1)
            return;

        net::post(
            derived().ws().get_executor(),
            beast::bind_front_handler(
                &websocket_session_t::run_async_write,
                derived().shared_from_this()));
    }

    void send(ws_message_ptr message) {
        ZoneScoped;
        log_.trace("{} {} +++", GET_TRACE(), id_);
        task_t task(message);
        if (enqueue(task_t(message))) {
            send_loop();
        } else {
            log_.debug("{} {} : not enqueue ", GET_TRACE(), id_);
        }
    }

    // Add new element to the end of dequeue
    bool enqueue(task_t&& task) {
        ZoneScoped;
        log_.trace("{} : ", GET_TRACE());
        emplace_back(std::move(task));
        return !is_empty();
    }

    bool dequeue() {
        ZoneScoped;
        log_.trace("{} : ", GET_TRACE());
        if (!is_empty())
            pop_front();
        return !is_empty();
    }

    std::deque<task_t> tx_;

    size_t size() const {
        return tx_.size();
    }

    bool is_empty() const {
        return tx_.empty();
    }

    task_t& back() {
        assert(!is_empty());
        return tx_.back();
    }

    task_t& front() {
        assert(!is_empty());
        return tx_.front();
    }

    void pop_front() {
        assert(!is_empty());
        tx_.pop_front();
    }

    void pop_back() {
        assert(!is_empty());
        tx_.pop_back();
    }

    void emplace_front(task_t&& task) {
        tx_.emplace_front(std::move(task));
    }

    void emplace_back(task_t&& task) {
        tx_.emplace_back(std::move(task));
    }
};

ext: hpp

max_stars_repo_name: jinntechio/RocketJoe

max_issues_repo_name: jinntechio/RocketJoe

max_forks_repo_name: jinntechio/RocketJoe


text:
//  (C) Copyright Gennadiy Rozental 2005-2007.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision: 43798 $
//
//  Description : global framework level forward declaration
// ***************************************************************************

#ifndef BOOST_RT_FWD_HPP_062604GER
#define BOOST_RT_FWD_HPP_062604GER

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

// Boost
#include <boost/shared_ptr.hpp>

namespace boost {

namespace BOOST_RT_PARAM_NAMESPACE {

class parameter;

class argument;
typedef shared_ptr<argument> argument_ptr;
typedef shared_ptr<argument const> const_argument_ptr;

template<typename T> class value_interpreter;
template<typename T> class typed_argument;

} // namespace BOOST_RT_PARAM_NAMESPACE

} // namespace boost

#endif // BOOST_RT_FWD_HPP_062604GER


text:
#ifndef KA_OPT_HPP
#define KA_OPT_HPP
#pragma once
#include <algorithm>
#include <iterator>
#include <boost/optional/optional.hpp>
#include "functional.hpp"
#include "macro.hpp"
#include "macroregular.hpp"
#include "scoped.hpp"
#include "src.hpp"
#include "typetraits.hpp"
#include "utility.hpp"

namespace ka
{
  namespace detail {
    /// Flattens an `opt_t<opt_t<T>>` into a `opt_t<T>`.
    ///
    /// Returns the internal optional value if it exists, empty otherwise.
    template<typename T> constexpr
    auto flatten_impl(opt_t<opt_t<T>> const& o) noexcept -> opt_t<T> {
      return o.empty() ? opt_t<T>{} : *o;
    }

    /// Rvalue-ref overload of `flatten` of `opt_t`.
    template<typename T> constexpr
    auto flatten_impl(opt_t<opt_t<T>>&& o) noexcept -> opt_t<T> {
      return o.empty() ? opt_t<T>{} : std::move(*o);
    }
  } // namespace detail

  /// Contains a value or nothing.
  ///
  /// This type is similar to `std::optional` but has two distinctive features:
  ///
  /// 1) It has a `void` specialization that strives to make generic programming
  ///    easier.
  ///
  /// 2) It is a standard sequence (containing at most one element)
  ///
  /// Due to the exceptional nature of `void` amongst C++ types, the API
  /// of this type is slightly different than the one of `std::optional` (see
  /// below).
  ///
  ///
  /// # Basic usage
  ///
  /// Example: Setting a value in a non-`void` `opt_t`
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /// opt_t<int> o;
  /// o.set(1);
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ///
  /// Example: Setting a value in a `void` `opt_t`
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /// opt_t<void> o;
  /// o.set();
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ///
  /// In the above examples, `set` is used instead of `=` because there is no
  /// way to assign a void value (except by calling `operator=()` directly,
  /// which defeat the readability purpose of operators...).
  ///
  ///
  /// # Complex usage: generic code
  ///
  /// ## Problem
  ///
  /// In generic code, we often want to call an arbitrary procedure and put its
  /// result in an optional. The problem is the procedure might return `void`.
  /// Consider the following example:
  ///
  /// Example: Conditionally calling a procedure and returning an `opt_t`
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /// // KO: THIS WON'T COMPILE (SEE BELOW)
  ///
  /// // Procedure<Ret (Args...)> Proc
  /// template<typename Proc, typename... Args>
  /// auto exec_conditionally(Proc proc, Args const&... args)
  ///   -> decltype(opt_t<decltype(proc(args...))>) // simplification: should decay
  /// {
  ///   opt_t<decltype(proc(args...))> opt;
  ///
  ///   // Some pre-processing...
  ///
  ///   if (/* Some condition */) {
  ///     opt.set(proc(args...)); // KO if `proc(args...)` returns `void`
  ///   }
  ///
  ///   // Some post-processing...
  ///   return opt;
  /// }
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ///
  /// In the above example, if the procedure returns `void` the code won't
  /// compile. This is because the following code is unfortunately illegal:
  ///
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /// void f(int) { // returns `void`
  ///   // ...
  /// }
  ///
  /// bool g() { // takes `void`
  ///   // ...
  /// }
  ///
  /// // On call site.
  /// g(f(1)); // KO: doesn't compile.
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ///
  /// ## Solution
  ///
  /// Consequently, a dedicated method is provided for this case.
  ///
  /// Example: Conditionally calling a procedure and returning an `opt_t`
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /// // OK: THIS COMPILES
  ///
  /// // Procedure<Ret (Args...)> Proc
  /// template<typename Proc, typename... Args>
  /// auto exec_conditionally(Proc proc, Args const&... args)
  ///   -> decltype(opt_t<decltype(proc(args...))>) // simplification: should decay
  /// {
  ///   opt_t<decltype(proc(args...))> opt;
  ///
  ///   // Some pre-processing...
  ///
  ///   if (/* Some condition */) {
  ///     opt.call_set(proc, args...); // ok: handles the `void` case
  ///   }
  ///
  ///   // Some post-processing...
  ///   return opt;
  /// }
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ///
  ///
  /// # Sequence
  ///
  /// An optional can be viewed as a sequence whose maximum size is one.
  /// Consequently sequence operations that would make the size exceed one will
  /// throw an exception.
  /// `opt_t` models the standard concept `SequenceContainer` and this notably
  /// allows the use of all standard algorithms.
  ///
  /// `Container` methods include:
  /// - iterator methods: begin, end, cbegin...
  /// - size methods: empty, size...
  /// - swap
  ///
  /// `SequenceContainer` methods include:
  /// - insert methods: constructor taking ranges, insert, emplace, push_back...
  /// - erase methods: erase, clear, pop_back...
  /// - accessors: [], at, front, back...
  ///
  /// TODO: Simplify the implementation by using a `boost::static_vector` when
  /// it is stable (see https://svn.boost.org/trac10/ticket/11957 and
  /// https://github.com/boostorg/container/issues/78).
  template<typename T>
  class opt_t {
    boost::optional<T> opt;

    template<typename I>
    using EnableIfIterator = EnableIf<std::is_base_of<
      std::input_iterator_tag, typename std::iterator_traits<I>::iterator_category
    >::value>;
  public:
  // Regular:
    opt_t() = default;
    KA_GENERATE_FRIEND_REGULAR_OPS_1(opt_t, opt)

    // TODO: remove this when get rid of VS2013.
#if KA_COMPILER_VS2013_OR_BELOW
    opt_t(opt_t const& x) : opt(x.opt) {
    }
    opt_t& operator=(opt_t const& x) {
      opt = x.opt;
      return *this;
    }
    opt_t(opt_t&& x) : opt(std::move(x.opt)) {
    }
    opt_t& operator=(opt_t&& x) {
      opt = std::move(x.opt);
      return *this;
    }
#else
    opt_t(opt_t const&) = default;
    opt_t& operator=(opt_t const&) = default;
    opt_t(opt_t&&) = default;
    opt_t& operator=(opt_t&&) = default;
#endif

#if KA_COMPILER_SUPPORTS_MEMBER_FUNCTION_REF_QUALIFIERS
  // Readable:
    T const& operator*() const & {
      return *opt;
    }

  // Mutable:
    T& operator*() & {
      return *opt;
    }

  // ...:
    T operator*() && {
      return std::move(*opt);
    }
#else
  // Readable:
    T const& operator*() const {
      return *opt;
    }

  // Mutable:
    T& operator*() {
      return *opt;
    }

  // ...:
#endif

    template<typename U>
    opt_t& set(U&& x) {
      opt = fwd<U>(x);
      return *this;
    }

    /// Procedure<T (Args...)> Proc
    template<typename Proc, typename... Args>
    opt_t& call_set(Proc&& p, Args&&... args) {
      return set(fwd<Proc>(p)(fwd<Args>(args)...));
    }

    T const* get_ptr() const KA_NOEXCEPT_EXPR(opt.get_ptr()) {
      return opt.get_ptr();
    }

    T* get_ptr() KA_NOEXCEPT_EXPR(opt.get_ptr()) {
      return opt.get_ptr();
    }

  // ContiguousContainer:
    using value_type = T;
    using reference = T&;
    using const_reference = T const&;
    using iterator = T*;
    using const_iterator = T const*;
    using difference_type = typename std::iterator_traits<iterator>::difference_type;
    using size_type = std::size_t;

    // Default constructor, copy constructor, assignment and destruction defined
    // above.

    iterator begin() KA_NOEXCEPT(true) {
      return opt.get_ptr();
    }

    const_iterator begin() const KA_NOEXCEPT(true) {
      return const_cast<opt_t&>(*this).begin();
    }

    iterator end() KA_NOEXCEPT(true) {
      return begin() + size();
    }

    const_iterator end() const KA_NOEXCEPT(true) {
      return const_cast<opt_t&>(*this).end();
    }

    const_iterator cbegin() const KA_NOEXCEPT(true) {
      return begin();
    }

    const_iterator cend() const KA_NOEXCEPT(true) {
      return end();
    }

    // Equality and difference defined above.

    void swap(opt_t& x) KA_NOEXCEPT_EXPR(std::swap(x, x)) {
      std::swap(*this, x);
    }

    friend
    void swap(opt_t& x, opt_t& y) KA_NOEXCEPT_EXPR(x.swap(y)) {
      x.swap(y);
    }

    KA_CONSTEXPR
    size_type size() const KA_NOEXCEPT(true) {
      return empty() ? 0 : 1;
    }

    KA_CONSTEXPR
    size_type max_size() const KA_NOEXCEPT(true) {
      return 1;
    }

    KA_CONSTEXPR
    bool empty() const KA_NOEXCEPT_EXPR(!static_cast<bool>(opt)) {
      return !static_cast<bool>(opt);
    }

  // ContainerSequence:
    /// Throws: `std::length_error` if `n > 1`
    ///
    /// T constructible from U
    template<typename U>
    opt_t(size_type n, U&& u) {
      if (n == 0) {
        return;
      }
      if (n > 1) {
        throw std::length_error{"opt_t(n, u): n greater than 1."};
      }
      opt = fwd<U>(u);
    }

    /// Precondition: bounded_range(i, j)
    /// Throws: `std::length_error` if `std::distance(i, j) > 1`
    ///
    /// InputIterator<T> I
    template<typename I, typename = EnableIfInputIterator<I>>
    opt_t(I i, I const& j) {
      if (i == j) {
        return;
      }
      opt = src(i);
      ++i;
      if (! (i == j)) {
        throw std::length_error{"opt_t(i, j): range [i, j) greater than 1."};
      }
    }

    /// Throws: `std::length_error` if `l.size() > 1`
    opt_t(std::initializer_list<T> l) : opt_t(l.begin(), l.end()) {
    }

    /// Throws: `std::length_error` if `l.size() > 1`
    opt_t& operator=(std::initializer_list<T> l) {
      *this = opt_t(l);
      return *this;
    }

    /// Throws: `std::length_error` if `!empty()`
    /// Throws: `std::runtime_error` if `p != end()`
    template<typename... Args>
    iterator emplace(const_iterator p, Args&&... args) {
      if (!empty()) {
        throw std::length_error{"opt_t::emplace(p, args): opt not empty."};
      }
      if (p != end()) {
        throw std::runtime_error{"opt_t::emplace(p, args): invalid iterator."};
      }
      opt.emplace(fwd<Args>(args)...);
      return begin();
    }

    /// Throws: `std::length_error` if `!empty()`
    /// Throws: `std::runtime_error` if `p != end()`
    template<typename U>
    iterator insert(const_iterator p, U&& u) {
      return emplace(p, fwd<U>(u));
    }

    /// Throws: `std::length_error` if `n > 1 || !empty()`
    /// Throws: `std::runtime_error` if `p != end()`
    template<typename U>
    iterator insert(const_iterator p, size_type n, U&& u) {
      if (n == 0) {
        return const_cast<iterator>(p);
      }
      if (n > 1) {
        throw std::length_error{"opt_t::insert(p, n, u): n greater than 1."};
      }
      return insert(p, fwd<U>(u));
    }

    /// Precondition: bounded_range(i, j)
    /// Throws: `std::length_error` if `std::distance(i, j) > 1 || !empty()`
    /// Throws: `std::runtime_error` if `p != end()`
    ///
    /// InputIterator<T> I
    template<typename I>
    iterator insert(const_iterator p, I i, I const& j) {
      if (i == j) {
        return const_cast<iterator>(p);
      }
      bool must_erase = true;
      auto _ = scoped(insert(p, src(i)), [&](const_iterator q) {
        if (must_erase) {
          erase(q);
        }
      });
      ++i;
      if (i == j) {
        must_erase = false;
        return begin();
      }
      // Will raise an exception because too many elements.
      return insert(p, max_size() + 1, src(i));
    }

    /// Throws: `std::length_error` if `l.size() > 1 || !empty()`
    /// Throws: `std::runtime_error` if `p != end()`
    iterator insert(const_iterator p, std::initializer_list<T> l) {
      return insert(p, l.begin(), l.end());
    }

    /// Throws: `std::length_error` if `empty()`
    /// Throws: `std::runtime_error` if `q != begin()`
    iterator erase(const_iterator const& q) {
      if (empty()) {
        throw std::length_error{"opt_t::erase(q): opt empty."};
      }
      if (q != begin()) {
        throw std::runtime_error{"opt_t::erase(q): q != begin()."};
      }
      clear();
      return const_cast<iterator>(std::next(q));
    }

    /// Throws: `std::length_error` if `std::distance(q1, q2) > 1 || empty()`
    /// Throws: `std::runtime_error` if `q1 != begin()`
    iterator erase(const_iterator const& q1, const_iterator const& q2) {
      if (q1 == q2) {
        return const_cast<iterator>(q2);
      }
      if (std::next(q1) != q2) {
        throw std::length_error{"opt_t::erase(q1, q2): range [q1, q2) greater than 1."};
      }
      return erase(q1);
    }

    void clear() {
      opt = boost::none;
    }

    // VS2013 is confused with the 'iterator' assign overload.
    // TODO: Remove this when VS2013 is not supported anymore.

    /// Throws: `std::length_error` if `n > 1`
#if KA_COMPILER_VS2013_OR_BELOW
    void assign(size_type n, value_type const& u) {
#else
    template<typename U>
    void assign(size_type n, U&& u) {
#endif
      assign(&u, &u + n); // ok: only 0 or 1 is accepted.
    }

    /// Precondition: bounded_range(i, j)
    /// Throws: `std::length_error` if `std::distance(i, j) > 1`
    ///
    /// InputIterator<T> I
    template<typename I, typename = EnableIfInputIterator<I>>
    void assign(I i, I const& j) {
      if (i == j) {
        clear();
        return;
      }
      bool must_restore = true;
      auto _ = scoped(exchange(opt, src(i)), [&](boost::optional<T> const& old) {
        if (must_restore) {
          opt = old;
        }
      });
      ++i;
      if (i != j) {
        throw std::length_error{"opt_t::assign(i, j): range greater than 1."};
      }
      must_restore = false;
    }

    /// Throws: `std::length_error` if `l.size() > 1`
    void assign(std::initializer_list<T> l) {
      assign(l.begin(), l.end());
    }

    /// Precondition: !empty()
    reference front() {
      return src(begin());
    }

    /// Precondition: !empty()
    const_reference front() const {
      return src(begin());
    }

    /// Precondition: !empty()
    reference back() {
      return front();
    }

    /// Precondition: !empty()
    const_reference back() const {
      return front();
    }

    /// Throws: `std::length_error` if `!empty()`
    template<typename... Args>
    void emplace_front(Args&&... args) {
      emplace(begin(), fwd<Args>(args)...);
    }

    /// Throws: `std::length_error` if `!empty()`
    template<typename... Args>
    void emplace_back(Args&&... args) {
      emplace_front(fwd<Args>(args)...);
    }

    /// Throws: `std::length_error` if `!empty()`
    template<typename U>
    void push_front(U&& u) {
      insert(begin(), fwd<U>(u));
    }

    /// Throws: `std::length_error` if `!empty()`
    template<typename U>
    void push_back(U&& u) {
      push_front(fwd<U>(u));
    }

    /// Throws: `std::length_error` if `empty()`
    void pop_front() {
      erase(begin());
    }

    /// Throws: `std::length_error` if `empty()`
    void pop_back() {
      pop_front();
    }

    /// Precondition: n < size()
    reference operator[](size_type n) {
      return src(begin() + n);
    }

    /// Precondition: n < size()
    const_reference operator[](size_type n) const {
      return const_cast<opt_t&>(*this)[n];
    }

    /// Throws: `std::out_of_range` if `n >= size()`
    reference at(size_type n) {
      if (n >= size()) {
        throw std::out_of_range{"opt_t::at: n out of range."};
      }
      return operator[](n);
    }

    /// Throws: `std::out_of_range` if `n >= size()`
    const_reference at(size_type n) const {
      return const_cast<opt_t&>(*this).at(n);
    }
  // Functor:
    /// Function<U (T)> F
    template<typename F>
    auto fmap(F&& f) const -> opt_t<CodomainFor<F, T>> {
      using U = CodomainFor<F, T>;
      if (empty()) {
        return opt_t<U>{};
      } else {
        return opt_t<U>{}.call_set(fwd<F>(f), **this);
      }
    }

    constexpr
    auto flatten() const& noexcept -> T {
      return detail::flatten_impl(*this);
    }

    auto flatten() && noexcept -> T {
      return detail::flatten_impl(std::move(*this));
    }
  };

  /// Constructs an optional set with the given parameter.
  ///
  /// The returned optional is therefore not empty.
  ///
  /// Example: Constructing optionals from values
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /// auto o0 = opt(1);   // `o0` has type `opt_t<int>` and is not empty.
  /// auto o1 = opt('a'); // `o1` has type `opt_t<char>` and is not empty.
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ///
  /// See `opt()` for constructing a `void` optional that is set.
  template<typename T>
  opt_t<Decay<T>> opt(T&& t) {
    return opt_t<Decay<T>>{}.set(fwd<T>(t));
  }

  /// This `void` specialization strives to make `void` handling easier.
  ///
  /// It cannot circumvent all the problems with `void` though. Therefore,
  /// it does not make irrelevant the alternative of using a 'unit type' as a
  /// replacement to `void`.
  ///
  /// Also note that this specialization does _not_ model the standard concept
  /// `Container`. The main reason is it's impossible to iterator over `void`
  /// "values".
  template<>
  class opt_t<void> {
    bool empty_ = true;
  public:
  // Regular:
    opt_t() = default;
    KA_GENERATE_FRIEND_REGULAR_OPS_1(opt_t, empty_)

  // ...
    opt_t& set() KA_NOEXCEPT(true) {
      empty_ = false;
      return *this;
    }

    /// Procedure<void (Args...)> Proc
    template<typename Proc, typename... Args>
    opt_t& call_set(Proc&& p, Args&&... args) {
      fwd<Proc>(p)(fwd<Args>(args)...);
      return set();
    }

    void operator*() const {
      BOOST_ASSERT(!empty_); // Same behavior as `boost::optional`.
    }

    void const* get_ptr() const KA_NOEXCEPT(true) {
      return empty_ ? nullptr : this;
    }

    void* get_ptr() KA_NOEXCEPT(true) {
      return empty_ ? nullptr : this;
    }

  // "ProtoContainer":
    // (`void` makes impossible to model `Container`, in particular there is no
    // iteration and no dereferencement)
    using value_type = void;
    using size_type = std::size_t;

    // Default constructor, copy constructor, assignment and destruction defined
    // above.

    // Equality and difference defined above.

    void swap(opt_t& x) KA_NOEXCEPT(true) {
      std::swap(empty_, x.empty_);
    }

    friend
    void swap(opt_t& x, opt_t& y) KA_NOEXCEPT(true) {
      x.swap(y);
    }

    KA_CONSTEXPR
    size_type size() const KA_NOEXCEPT(true) {
      return empty() ? 0 : 1;
    }

    KA_CONSTEXPR
    size_type max_size() const KA_NOEXCEPT(true) {
      return 1;
    }

    KA_CONSTEXPR
    bool empty() const KA_NOEXCEPT_EXPR(true) {
      return empty_;
    }
  // Functor:
    /// Procedure<_ ()> F
    template<typename F>
    opt_t<CodomainFor<F>> fmap(F&& f) const {
      return fmap_dispatch(Equal<void, CodomainFor<F>>{}, fwd<F>(f));
    }
  private:
    template<typename F>
    opt_t<void> fmap_dispatch(true_t /* VoidCodomain */, F&& f) const {
      if (!empty()) {
        fwd<F>(f)();
      }
      return *this;
    }

    template<typename F>
    opt_t<CodomainFor<F>> fmap_dispatch(false_t /* VoidCodomain */, F&& f) const {
      opt_t<CodomainFor<F>> o;
      if (!empty()) {
        o.call_set(fwd<F>(f));
      }
      return o;
    }
  };

  /// Constructs a `void` optional that is set.
  ///
  /// The optional is set because this function is the counterpart the version
  /// taking an argument (that effectively returns a set optional).
  ///
  /// Example: Constructing optionals (`void` and non-`void`)
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /// auto o0 = opt();     // `o0` has type `opt_t<void>` and is not empty.
  /// auto o1 = opt(true); // `o1` has type `opt_t<bool>` and is not empty.
  ///
  /// opt_t<void> o2;      // `o2` is empty.
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  inline opt_t<void> opt() {
    return opt_t<void>{}.set();
  }

  namespace detail {
  // model EmptyMutable boost::optional<T>:
    template<typename T> KA_CONSTEXPR
    bool empty(boost::optional<T> const& t) {
      return !static_cast<bool>(t);
    }
  } // namespace detail

  namespace fmap_ns {
  // model FunctorApp opt:
    /// meaning(fmap(f, ka_opts...)) =
    ///     all_are_set
    ///       ? opt(f(src(ka_opts)...)) // set (void case handled)
    ///       : opt_t<U>()              // empty
    ///   where
    ///     all_are_set = !ka_opts.empty() && ...
    ///     U = typeof(f(ka_opts...))
    ///
    /// Function<U (T...)> F
    template<typename F, typename T, typename... O>
    auto fmap(F&& f, opt_t<T> const& x, O&&... o)
        -> opt_t<CodomainFor<F, T, typename Decay<O>::value_type...>> {
      // The pattern
      //  ```
      //  type res;
      //  if (condition) res = value;
      //  return res;
      //  ```
      //  sadly tends to generate more efficient code on current compilers
      //  (gcc9, clang9), even with optimizations activated, than
      //  ```
      //  return condition
      //    ? type(value)
      //    : type();
      //  ```
      //  .
      using U = CodomainFor<F, T, typename Decay<O>::value_type...>;
      opt_t<U> res;

      // TODO: Use fold expression when available.
      std::array<bool, 1 + sizeof...(O)> empties = {x.empty(), o.empty()...};
      if (std::none_of(empties.begin(), empties.end(), id_transfo_t{})) {
        res.call_set(fwd<F>(f), src(x), src(fwd<O>(o))...);
      }
      return res;
    }

  // model FunctorApp boost::optional:
    /// meaning(fmap(f, boost_opts...)) = meaning(fmap(f, as_ka_opt(boost_opts)...))
    ///   where
    ///     meaning(as_ka_opt(boost_opt)) = meaning(boost_opt)
    ///
    /// Function<U (T...)> F
    template<typename F, typename T, typename... O>
    auto fmap(F&& f, boost::optional<T> const& x, O&&... o)
        -> boost::optional<CodomainFor<F, T, typename Decay<O>::value_type...>> {
      using U = CodomainFor<F, T, typename Decay<O>::value_type...>;
      boost::optional<U> res;

      // TODO: Use fold expression when available.
      std::array<bool, 1 + sizeof...(O)> empties = {!x, (!o)...};
      if (std::none_of(empties.begin(), empties.end(), id_transfo_t{})) {
        res = boost::optional<U>(fwd<F>(f)(x.value(), fwd<O>(o).value()...));
      }
      return res;
    }
  } // namespace fmap_ns

  namespace detail {
    // Overloads are defined here and available for `flatten_fn_t`.

    /// Flattens a `boost::optional<boost::optional<T>>` into a `boost::optional<T>`.
    ///
    /// Returns the internal optional value if it exists, empty otherwise.template<typename T>
    template<typename T> constexpr
    auto flatten(boost::optional<boost::optional<T>> const& o) noexcept
      -> boost::optional<T> {
      return o ? *o : boost::optional<T>{};
    }

    /// Rvalue-ref overload of `flatten` of `boost::optional`.
    template<typename T>
    auto flatten(boost::optional<boost::optional<T>>&& o) noexcept -> boost::optional<T> {
      return o ? std::move(*o) : boost::optional<T>{};
    }
  } // namespace detail
} // namespace ka

#endif // KA_OPT_HPP

max_stars_repo_name: arntanguy/libqi

max_issues_repo_name: arntanguy/libqi

max_forks_repo_name: arntanguy/libqi


text:
#define BOOST_FILESYSTEM_VERSION 3

#include <iostream>
#include <fstream>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/filesystem.hpp>
#include "huffman_tree.hpp"
#include "constants.hpp"

long COUNTS_SIZE;

std::vector<uint64_t> count(std::ifstream &file_in, std::ofstream &file_out){

    file_in.clear();
    file_in.seekg(0);

    file_out.clear();
    file_out.seekp(0);

    std::vector<uint64_t> counts;
    counts.reserve(BYTE_SIZE);
    for (int i = 0; i < BYTE_SIZE; ++i) {
        counts.emplace_back(0);
    }

    char c;
    while (file_in.get(c)) {
        counts[static_cast<unsigned char>(c)]++;
    }

    file_in.clear();
    unsigned long bytecount_ending = file_in.tellg() & 0xFF;

    c = static_cast<char>(bytecount_ending);
    file_out.put(c);

    file_in.clear();
    file_in.seekg(0);

    unsigned int VAL_SIZE = 0; // largest nonzero sub-byte in counts.

    uint64_t val = *std::max_element(counts.begin(), counts.end()); // biggest value in counts

    for(unsigned int j = 0; j < 8; j++) {
        if ((val & (0xFF << (8 * j))) != 0) VAL_SIZE = j + 1; // find largest non-zero byte
    }
    file_out.put(static_cast<char>(VAL_SIZE));

    for(uint64_t i : counts){
        for(uint64_t j = 0; j < VAL_SIZE; j++){
            file_out.put(static_cast<char>((i & (0xFF << 8*j) ) >> 8*j));
        }
    }

    COUNTS_SIZE = 2 + VAL_SIZE*BYTE_SIZE; // 1 for ending + 1 for size + 256 frequencies * VAL_SIZE bytes per frequency

    return counts;
}

void huffman_encode(const huffman_tree &huffman, std::ifstream &file_in, std::ofstream &file_out){
    char buffer_read[BLOCK_SIZE];
    char buffer_write[BLOCK_SIZE];
    int write_index = 0;

    char buffer_bool = 0;
    char bit_index = 0;

    file_out.clear();
    file_out.seekp(COUNTS_SIZE);

    do{
        file_in.read(buffer_read, BLOCK_SIZE);
        if (verbose) std::cout << "read " << file_in.gcount() << " bytes" << std::endl;
        for(int i = 0; i < file_in.gcount(); i++){
            auto c  = static_cast<unsigned char>(buffer_read[i]);
            auto decisions = huffman.paths[c];
            for (bool d : decisions){
                //std::cout << d << std::endl;
                buffer_bool |= d << bit_index++;

                if (bit_index == 8){
                    buffer_write[write_index++] = buffer_bool;
                    buffer_bool = bit_index = 0;

                    if (write_index == BLOCK_SIZE){
                        file_out.write(buffer_write, BLOCK_SIZE);
                        if (verbose) std::cout << "wrote " << BLOCK_SIZE << " bytes" << std::endl;
                        write_index = 0;
                    }
                }
            }
        }
    } while (file_in.gcount() > 0);

    buffer_write[write_index++] = buffer_bool;
    file_out.write(buffer_write, write_index);

    if (verbose) std::cout << "wrote " << write_index+1 << " bytes" << std::endl; // +1 because put
}

int main(int argc, char *argv[]) {
    auto filename_in = test_in / boost::filesystem::path("compress.cpp");
    if(argc > 1) filename_in = argv[1];

    auto file_part = filename_in.stem();
    auto extension = filename_in.extension();

    auto filename_out = test_huff;
    if(argc > 2) filename_out = argv[2];
    if (boost::filesystem::is_directory(filename_out)){
        filename_out /= file_part;
        filename_out += extension;
        filename_out += dot;
        filename_out += huff;
    }

    std::ifstream file_in;
    std::ofstream file_out;

    file_in.open(filename_in.string()  , std::ios::in  | std::ios::binary);
    file_out.open(filename_out.string(), std::ios::out | std::ios::binary);

    std::vector<uint64_t> counts = count(file_in, file_out);

    auto huff = huffman_tree(counts);

    huffman_encode(huff, file_in, file_out);

    file_in.close();
    file_out.close();
    return EXIT_SUCCESS;
}

max_stars_repo_name: odderikf/algdat

max_issues_repo_name: odderikf/algdat

max_forks_repo_name: odderikf/algdat


text:
#include <iostream>
#include <memory>

#include <boost/program_options/variables_map.hpp>

#include "Application.h"
#include "ArgumentsParser.h"
#include "Option.h"
#include "AllowedURI.h"
#include "Download.h"
#include "Format.h"
#include "CreateProject.h"

int main(int argc, char* argv[]) {
	using namespace RunFragment;
	namespace po = boost::program_options;

	po::variables_map vm;
	try {
		vm = ArgumentsParser::argsToVm(argc, argv, Option::parsingOptions);
	}
	catch(std::exception& e) {
		std::cerr << "Error: " << e.what() << std::endl;
		std::cerr << "Try '--" << Option::help << "'" << std::endl;

		return EXIT_FAILURE;
	}

	if(vm.count(Option::help)) {
		std::cout << "Usage:" << std::endl;
		std::cout << "  " << argv[0] << "[options] <Image_shader.glsl>" << std::endl;
		std::cout << "  " << argv[0] << "[options] --" << Option::image << "=<Image_shader.glsl>" << std::endl;
		std::cout << "  " << argv[0] << "[options] --" << Option::config << "=<config_file.ini>" << std::endl;
		std::cout << "  " << argv[0] << "[options] --" << Option::download << "=<url>" << std::endl;
		std::cout << "  " << argv[0] << "[options] --" << Option::create << "=<path>" << std::endl;
		std::cout << Option::helpOptions << std::endl;

		return EXIT_SUCCESS;
	}

	if(vm.count(Option::download)) {
		auto uri = std::unique_ptr<AllowedURI> {vm[Option::download].as<AllowedURI*>()};

		Download::fromURI(uri.get());

		return EXIT_SUCCESS;
	}

	if(vm.count(Option::create)) {
		const auto format = vm.count(Option::format) ? vm[Option::format].as<Format>() : defaultFormat;
		const auto path =   vm[Option::create].as<fs::path>();

		try {
			switch(format) {
			case Format::ShaderToy: {
				CreateProject::shadertoy(path);
				break;
			}
			case Format::GLSLSandbox: {
				CreateProject::glslsandbox(path);
				break;
			}
			}

			return EXIT_SUCCESS;
		}
		catch(std::exception& e) {
			std::cerr << "Error: " << e.what() << std::endl;

			return EXIT_FAILURE;
		}
	}

	try {
		Application application {ArgumentsParser::vmToAppConfig(vm)};
		application.run();
	}
	catch(std::exception& e) {
		std::cerr << "Error: " << e.what() << std::endl;

		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}


text:
// Copyright (C) 2004-2006 The Trustees of Indiana University.

// Use, modification and distribution is 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)

//  Authors: Nick Edmonds
//           Douglas Gregor
//           Andrew Lumsdaine
#ifndef BOOST_GRAPH_PARALLEL_CC_HPP
#define BOOST_GRAPH_PARALLEL_CC_HPP

#ifndef BOOST_GRAPH_USE_MPI
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
#endif

#include <boost/property_map/property_map.hpp>
#include <boost/property_map/parallel/caching_property_map.hpp>
#include <boost/graph/parallel/algorithm.hpp>
#include <boost/pending/indirect_cmp.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/overloading.hpp>
#include <boost/graph/distributed/concepts.hpp>
#include <boost/graph/parallel/properties.hpp>
#include <boost/graph/distributed/local_subgraph.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/graph/named_function_params.hpp>
#include <boost/graph/parallel/process_group.hpp>
#include <boost/optional.hpp>
#include <algorithm>
#include <vector>
#include <list>
#include <boost/graph/parallel/container_traits.hpp>
#include <boost/graph/iteration_macros.hpp>

#define PBGL_IN_PLACE_MERGE /* In place merge instead of sorting */
//#define PBGL_SORT_ASSERT    /* Assert sorted for in place merge */

/* Explicit sychronization in pointer doubling step? */
#define PBGL_EXPLICIT_SYNCH
//#define PBGL_CONSTRUCT_METAGRAPH
#ifdef PBGL_CONSTRUCT_METAGRAPH
#  define MAX_VERTICES_IN_METAGRAPH 10000
#endif

namespace boost { namespace graph { namespace distributed {
  namespace cc_detail {
    enum connected_components_message {
      edges_msg, req_parents_msg, parents_msg, root_adj_msg
    };

    template <typename Vertex>
    struct metaVertex {
      metaVertex() {}
      metaVertex(const Vertex& v) : name(v) {}

      template<typename Archiver>
      void serialize(Archiver& ar, const unsigned int /*version*/)
      {
        ar & name;
      }

      Vertex name;
    };

#ifdef PBGL_CONSTRUCT_METAGRAPH
    // Build meta-graph on result of local connected components
    template <typename Graph, typename ParentMap, typename RootIterator,
              typename AdjacencyMap>
    void
    build_local_metagraph(const Graph& g, ParentMap p, RootIterator r,
                          RootIterator r_end, AdjacencyMap& adj)
    {
      // TODO: Static assert that AdjacencyMap::value_type is std::vector<vertex_descriptor>

      typedef typename boost::graph::parallel::process_group_type<Graph>::type
        process_group_type;
      typedef typename process_group_type::process_id_type process_id_type;

      typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;

      BOOST_STATIC_ASSERT((is_same<typename AdjacencyMap::mapped_type,
                                     std::vector<vertex_descriptor> >::value));

      using boost::graph::parallel::process_group;

      process_group_type pg = process_group(g);
      process_id_type id = process_id(pg);

      if (id != 0) {

        // Send component roots and their associated edges to P0
        for ( ; r != r_end; ++r ) {
          std::vector<vertex_descriptor> adjs(1, *r); // Root
          adjs.reserve(adjs.size() + adj[*r].size());
          for (typename std::vector<vertex_descriptor>::iterator iter = adj[*r].begin();
               iter != adj[*r].end(); ++iter)
            adjs.push_back(get(p, *iter)); // Adjacencies

          send(pg, 0, root_adj_msg, adjs);
        }
      }

      synchronize(pg);

      if (id == 0) {
        typedef metaVertex<vertex_descriptor> VertexProperties;

        typedef boost::adjacency_list<vecS, vecS, undirectedS,
          VertexProperties> metaGraph;
        typedef typename graph_traits<metaGraph>::vertex_descriptor
          meta_vertex_descriptor;

        std::map<vertex_descriptor, meta_vertex_descriptor> vertex_map;
        std::vector<std::pair<vertex_descriptor, vertex_descriptor> > edges;

        // Receive remote roots and edges
        while (optional<std::pair<process_id_type, int> > m = probe(pg)) {
          assert(m->second == root_adj_msg);

          std::vector<vertex_descriptor> adjs;
          receive(pg, m->first, m->second, adjs);

          vertex_map[adjs[0]] = graph_traits<metaGraph>::null_vertex();
          for (typename std::vector<vertex_descriptor>::iterator iter
                 = ++adjs.begin(); iter != adjs.end(); ++iter)
            edges.push_back(std::make_pair(adjs[0], *iter));
        }

        // Add local roots and edges
        for ( ; r != r_end; ++r ) {
          vertex_map[*r] = graph_traits<metaGraph>::null_vertex();
          edges.reserve(edges.size() + adj[*r].size());
          for (typename std::vector<vertex_descriptor>::iterator iter = adj[*r].begin();
               iter != adj[*r].end(); ++iter)
            edges.push_back(std::make_pair(*r, get(p, *iter)));
        }

        // Build local meta-graph
        metaGraph mg;

        // Add vertices with property to map back to distributed graph vertex
        for (typename std::map<vertex_descriptor, meta_vertex_descriptor>::iterator
               iter = vertex_map.begin(); iter != vertex_map.end(); ++iter)
          vertex_map[iter->first]
            = add_vertex(metaVertex<vertex_descriptor>(iter->first), mg);

        // Build meta-vertex map
        typename property_map<metaGraph, vertex_descriptor VertexProperties::*>::type
          metaVertexMap = get(&VertexProperties::name, mg);

        typename std::vector<std::pair<vertex_descriptor, vertex_descriptor> >
          ::iterator edge_iter = edges.begin();
        for ( ; edge_iter != edges.end(); ++edge_iter)
          add_edge(vertex_map[edge_iter->first], vertex_map[edge_iter->second], mg);

        edges.clear();

        // Call connected_components on it
        typedef typename property_map<metaGraph, vertex_index_t>::type
          meta_index_map_type;
        meta_index_map_type meta_index = get(vertex_index, mg);

        std::vector<std::size_t> mg_component_vec(num_vertices(mg));
        typedef iterator_property_map<std::vector<std::size_t>::iterator,
                                      meta_index_map_type>
        meta_components_map_type;
        meta_components_map_type mg_component(mg_component_vec.begin(),
                                              meta_index);
        std::size_t num_comp = connected_components(mg, mg_component);

        // Update Parent pointers
        std::vector<meta_vertex_descriptor> roots(num_comp, graph_traits<metaGraph>::null_vertex());

        BGL_FORALL_VERTICES_T(v, mg, metaGraph) {
          size_t component = get(mg_component, v);
          if (roots[component] == graph_traits<metaGraph>::null_vertex() ||
              get(meta_index, v) < get(meta_index, roots[component]))
            roots[component] = v;
        }

        // Set all the local parent pointers
        BGL_FORALL_VERTICES_T(v, mg, metaGraph) {
          // Problem in value being put (3rd parameter)
          put(p, get(metaVertexMap, v), get(metaVertexMap, roots[get(mg_component, v)]));
        }
      }

      synchronize(p);
    }
#endif

    /* Function object used to remove internal vertices and vertices >
       the current vertex from the adjacent vertex lists at each
       root */
    template <typename Vertex, typename ParentMap>
    class cull_adjacency_list
    {
    public:
      cull_adjacency_list(const Vertex v, const ParentMap p) : v(v), p(p) {}
      bool operator() (const Vertex x) { return (get(p, x) == v || x == v); }

    private:
      const Vertex    v;
      const ParentMap p;
    };

    /* Comparison operator used to choose targets for hooking s.t. vertices
       that are hooked to are evenly distributed across processors */
    template <typename OwnerMap, typename LocalMap>
    class hashed_vertex_compare
    {
    public:
      hashed_vertex_compare (const OwnerMap& o, const LocalMap& l)
        : owner(o), local(l) { }

      template <typename Vertex>
      bool operator() (const Vertex x, const Vertex y)
      {
        if (get(local, x) < get(local, y))
          return true;
        else if (get(local, x) == get(local, y))
          return (get(owner, x) < get(owner, y));
        return false;
      }

    private:
      OwnerMap   owner;
      LocalMap   local;
    };

#ifdef PBGL_EXPLICIT_SYNCH
    template <typename Graph, typename ParentMap, typename VertexList>
    void
    request_parent_map_entries(const Graph& g, ParentMap p,
                               std::vector<VertexList>& parent_requests)
    {
      typedef typename boost::graph::parallel::process_group_type<Graph>
        ::type process_group_type;
      typedef typename process_group_type::process_id_type process_id_type;

      typedef typename graph_traits<Graph>::vertex_descriptor
        vertex_descriptor;

      process_group_type pg = process_group(g);

      /*
        This should probably be send_oob_with_reply, especially when Dave
        finishes prefetch-batching
      */

      // Send root requests
      for (process_id_type i = 0; i < num_processes(pg); ++i) {
        if (!parent_requests[i].empty()) {
          std::vector<vertex_descriptor> reqs(parent_requests[i].begin(),
                                              parent_requests[i].end());
          send(pg, i, req_parents_msg, reqs);
        }
      }

      synchronize(pg);

      // Receive root requests and reply to them
      while (optional<std::pair<process_id_type, int> > m = probe(pg)) {
        std::vector<vertex_descriptor> requests;
        receive(pg, m->first, m->second, requests);
        for (std::size_t i = 0; i < requests.size(); ++i)
          requests[i] = get(p, requests[i]);
        send(pg, m->first, parents_msg, requests);
      }

      synchronize(pg);

      // Receive requested parents
      std::vector<vertex_descriptor> responses;
      for (process_id_type i = 0; i < num_processes(pg); ++i) {
        if (!parent_requests[i].empty()) {
          receive(pg, i, parents_msg, responses);
          std::size_t parent_idx = 0;
          for (typename VertexList::iterator v = parent_requests[i].begin();
               v != parent_requests[i].end(); ++v, ++parent_idx)
            put(p, *v, responses[parent_idx]);
        }
      }
    }
#endif

    template<typename DistributedGraph, typename ParentMap>
    void
    parallel_connected_components(DistributedGraph& g, ParentMap p)
    {
      using boost::connected_components;

      typedef typename graph_traits<DistributedGraph>::adjacency_iterator
        adjacency_iterator;
      typedef typename graph_traits<DistributedGraph>::out_edge_iterator
        out_edge_iterator;
      typedef typename graph_traits<DistributedGraph>::edge_iterator
        edge_iterator;
      typedef typename graph_traits<DistributedGraph>::vertex_descriptor
        vertex_descriptor;
      typedef typename graph_traits<DistributedGraph>::edge_descriptor
        edge_descriptor;

      typedef typename boost::graph::parallel::process_group_type<DistributedGraph>
        ::type process_group_type;
      typedef typename process_group_type::process_id_type process_id_type;

      using boost::graph::parallel::process_group;

      process_group_type pg = process_group(g);
      process_id_type id = process_id(pg);

      // TODO (NGE): Should old_roots, roots, and completed_roots be std::list
      adjacency_iterator av1, av2;
      std::vector<vertex_descriptor> old_roots;
      typename std::vector<vertex_descriptor>::iterator liter;
      typename std::vector<vertex_descriptor>::iterator aliter;
      typename std::map<vertex_descriptor,
                        std::vector<vertex_descriptor> > adj;

      typedef typename property_map<DistributedGraph, vertex_owner_t>::const_type
        OwnerMap;
      OwnerMap owner = get(vertex_owner, g);
      typedef typename property_map<DistributedGraph, vertex_local_t>::const_type
        LocalMap;
      LocalMap local = get(vertex_local, g);

      // We need to hold on to all of the parent pointers
      p.set_max_ghost_cells(0);

      //
      // STAGE 1 : Compute local components
      //
      local_subgraph<const DistributedGraph> ls(g);
      typedef typename property_map<local_subgraph<const DistributedGraph>,
                                    vertex_index_t>::type local_index_map_type;
      local_index_map_type local_index = get(vertex_index, ls);

      // Compute local connected components
      std::vector<std::size_t> ls_components_vec(num_vertices(ls));
      typedef iterator_property_map<std::vector<std::size_t>::iterator,
                                    local_index_map_type>
        ls_components_map_type;
      ls_components_map_type ls_component(ls_components_vec.begin(),
                                          local_index);
      std::size_t num_comp = connected_components(ls, ls_component);

      std::vector<vertex_descriptor>
        roots(num_comp, graph_traits<DistributedGraph>::null_vertex());

      BGL_FORALL_VERTICES_T(v, g, DistributedGraph) {
        size_t component = get(ls_component, v);
        if (roots[component] == graph_traits<DistributedGraph>::null_vertex() ||
            get(local_index, v) < get(local_index, roots[component]))
          roots[component] = v;
      }

      // Set all the local parent pointers
      BGL_FORALL_VERTICES_T(v, g, DistributedGraph) {
        put(p, v, roots[get(ls_component, v)]);
      }

      if (num_processes(pg) == 1) return;

      // Build adjacency list for all roots
      BGL_FORALL_VERTICES_T(v, g, DistributedGraph) {
        std::vector<vertex_descriptor>& my_adj = adj[get(p, v)];
        for (boost::tie(av1, av2) = adjacent_vertices(v, g);
             av1 != av2; ++av1) {
          if (get(owner, *av1) != id) my_adj.push_back(*av1);
        }
      }

      // For all vertices adjacent to a local vertex get p(v)
      for ( liter = roots.begin(); liter != roots.end(); ++liter ) {
        std::vector<vertex_descriptor>& my_adj = adj[*liter];
        for ( aliter = my_adj.begin(); aliter != my_adj.end(); ++aliter )
          request(p, *aliter);
      }
      synchronize(p);

      // Update adjacency list at root to make sure all adjacent
      // vertices are roots of remote components
      for ( liter = roots.begin(); liter != roots.end(); ++liter )
        {
          std::vector<vertex_descriptor>& my_adj = adj[*liter];
          for ( aliter = my_adj.begin(); aliter != my_adj.end(); ++aliter )
            *aliter = get(p, *aliter);

          my_adj.erase
            (remove_if(my_adj.begin(), my_adj.end(),
                       cull_adjacency_list<vertex_descriptor,
                                           ParentMap>(*liter, p) ),
             my_adj.end());
          // This sort needs to be here to make sure the initial
          // adjacency list is sorted
          sort(my_adj.begin(), my_adj.end(), std::less<vertex_descriptor>());
          my_adj.erase(unique(my_adj.begin(), my_adj.end()), my_adj.end());
        }

      // Get p(v) for the new adjacent roots
      p.clear();
      for ( liter = roots.begin(); liter != roots.end(); ++liter ) {
        std::vector<vertex_descriptor>& my_adj = adj[*liter];
        for ( aliter = my_adj.begin(); aliter != my_adj.end(); ++aliter )
          request(p, *aliter);
      }
#ifdef PBGL_EXPLICIT_SYNCH
      synchronize(p);
#endif

      // Lastly, remove roots with no adjacent vertices, this is
      // unnecessary but will speed up sparse graphs
      for ( liter = roots.begin(); liter != roots.end(); /*in loop*/)
        {
          if ( adj[*liter].empty() )
            liter = roots.erase(liter);
          else
            ++liter;
        }

#ifdef PBGL_CONSTRUCT_METAGRAPH
      /* TODO: If the number of roots is sufficiently small, we can
               use a 'problem folding' approach like we do in MST
               to gather all the roots and their adjacencies on one proc
               and solve for the connected components of the meta-graph */
      using boost::parallel::all_reduce;
      std::size_t num_roots = all_reduce(pg, roots.size(), std::plus<std::size_t>());
      if (num_roots < MAX_VERTICES_IN_METAGRAPH) {
        build_local_metagraph(g, p, roots.begin(), roots.end(), adj);

        // For each vertex in g, p(v) = p(p(v)), assign parent of leaf
        // vertices from first step to final parent
        BGL_FORALL_VERTICES_T(v, g, DistributedGraph) {
          put(p, v, get(p, get(p, v)));
        }

        synchronize(p);

        return;
      }
#endif

      //
      // Parallel Phase
      //

      std::vector<vertex_descriptor> completed_roots;
      hashed_vertex_compare<OwnerMap, LocalMap> v_compare(owner, local);
      bool any_hooked;
      vertex_descriptor new_root;

      std::size_t steps = 0;

      do {
        ++steps;

        // Pull in new parents for hooking phase
        synchronize(p);

        //
        // Hooking
        //
        bool hooked = false;
        completed_roots.clear();
        for ( liter = roots.begin(); liter != roots.end(); )
          {
            new_root = graph_traits<DistributedGraph>::null_vertex();
            std::vector<vertex_descriptor>& my_adj = adj[*liter];
            for ( aliter = my_adj.begin(); aliter != my_adj.end(); ++aliter )
              // try to hook to better adjacent vertex
              if ( v_compare( get(p, *aliter), *liter ) )
                new_root = get(p, *aliter);

            if ( new_root != graph_traits<DistributedGraph>::null_vertex() )
              {
                hooked = true;
                put(p, *liter, new_root);
                old_roots.push_back(*liter);
                completed_roots.push_back(*liter);
                liter = roots.erase(liter);
              }
            else
              ++liter;
          }

        //
        // Pointer jumping, perform until new roots determined
        //

        // TODO: Implement cycle reduction rules to reduce this from
        // O(n) to O(log n) [n = cycle length]
        bool all_done;
        std::size_t parent_root_count;

        std::size_t double_steps = 0;

        do {
          ++double_steps;
#ifndef PBGL_EXPLICIT_SYNCH
          // Get p(p(v)) for all old roots, and p(v) for all current roots
          for ( liter = old_roots.begin(); liter != old_roots.end(); ++liter )
            request(p, get(p, *liter));

          synchronize(p);
#else
          // Build root requests
          typedef std::set<vertex_descriptor> VertexSet;
          std::vector<VertexSet> parent_requests(num_processes(pg));
          for ( liter = old_roots.begin(); liter != old_roots.end(); ++liter )
            {
              vertex_descriptor p1 = *liter;
              if (get(owner, p1) != id) parent_requests[get(owner, p1)].insert(p1);
              vertex_descriptor p2 = get(p, p1);
              if (get(owner, p2) != id) parent_requests[get(owner, p2)].insert(p2);
            }

          request_parent_map_entries(g, p, parent_requests);
#endif
          // Perform a pointer jumping step on all old roots
          for ( liter = old_roots.begin(); liter != old_roots.end(); ++liter )
              put(p, *liter, get(p, get(p, *liter)));

          // make sure the parent of all old roots is itself a root
          parent_root_count = 0;
          for ( liter = old_roots.begin(); liter != old_roots.end(); ++liter )
            if ( get(p, *liter) == get(p, get(p, *liter)) )
              parent_root_count++;

          bool done = parent_root_count == old_roots.size();

          all_reduce(pg, &done, &done+1, &all_done,
                     std::logical_and<bool>());
        } while ( !all_done );
#ifdef PARALLEL_BGL_DEBUG
        if (id == 0) std::cerr << double_steps << " doubling steps.\n";
#endif
        //
        // Add adjacent vertices of just completed roots to adjacent
        // vertex list at new parent
        //
        typename std::vector<vertex_descriptor> outgoing_edges;
        for ( liter = completed_roots.begin(); liter != completed_roots.end();
              ++liter )
          {
            vertex_descriptor new_parent = get(p, *liter);

            if ( get(owner, new_parent) == id )
              {
                std::vector<vertex_descriptor>& my_adj = adj[new_parent];
                my_adj.reserve(my_adj.size() + adj[*liter].size());
                my_adj.insert( my_adj.end(),
                               adj[*liter].begin(), adj[*liter].end() );
#ifdef PBGL_IN_PLACE_MERGE
#ifdef PBGL_SORT_ASSERT
                assert(__gnu_cxx::is_sorted(my_adj.begin(),
                                            my_adj.end() - adj[*liter].size(),
                                            std::less<vertex_descriptor>()));
                assert(__gnu_cxx::is_sorted(my_adj.end() - adj[*liter].size(),
                                            my_adj.end(),
                                            std::less<vertex_descriptor>()));
#endif
                std::inplace_merge(my_adj.begin(),
                                   my_adj.end() - adj[*liter].size(),
                                   my_adj.end(),
                                   std::less<vertex_descriptor>());
#endif

              }
            else if ( adj[*liter].begin() != adj[*liter].end() )
              {
                outgoing_edges.clear();
                outgoing_edges.reserve(adj[*liter].size() + 1);
                // First element is the destination of the adjacency list
                outgoing_edges.push_back(new_parent);
                outgoing_edges.insert(outgoing_edges.end(),
                                      adj[*liter].begin(), adj[*liter].end() );
                send(pg, get(owner, new_parent), edges_msg, outgoing_edges);
                adj[*liter].clear();
              }
          }
        synchronize(pg);

        // Receive edges sent by remote nodes and add them to the
        // indicated vertex's adjacency list
        while (optional<std::pair<process_id_type, int> > m
               = probe(pg))
          {
            std::vector<vertex_descriptor> incoming_edges;
            receive(pg, m->first, edges_msg, incoming_edges);
            typename std::vector<vertex_descriptor>::iterator aviter
              = incoming_edges.begin();
            ++aviter;

            std::vector<vertex_descriptor>& my_adj = adj[incoming_edges[0]];

            my_adj.reserve(my_adj.size() + incoming_edges.size() - 1);
            my_adj.insert( my_adj.end(), aviter, incoming_edges.end() );

#ifdef PBGL_IN_PLACE_MERGE
            std::size_t num_incoming_edges = incoming_edges.size();
#ifdef PBGL_SORT_ASSERT
            assert(__gnu_cxx::is_sorted(my_adj.begin(),
                                        my_adj.end() - (num_incoming_edges-1),
                                        std::less<vertex_descriptor>()));
            assert(__gnu_cxx::is_sorted(my_adj.end() - (num_incoming_edges-1),
                                        my_adj.end(),
                                        std::less<vertex_descriptor>()));
#endif
            std::inplace_merge(my_adj.begin(),
                               my_adj.end() - (num_incoming_edges - 1),
                               my_adj.end(),
                               std::less<vertex_descriptor>());
#endif

          }

        // Remove any adjacent vertices that are in the same component
        // as a root from that root's list
        for ( liter = roots.begin(); liter != roots.end(); ++liter )
          {
            // We can probably get away without sorting and removing
            // duplicates Though sorting *may* cause root
            // determination to occur faster by choosing the root with
            // the most potential to hook to at each step
            std::vector<vertex_descriptor>& my_adj = adj[*liter];
            my_adj.erase
              (remove_if(my_adj.begin(), my_adj.end(),
                         cull_adjacency_list<vertex_descriptor,
                                             ParentMap>(*liter, p) ),
               my_adj.end());
#ifndef PBGL_IN_PLACE_MERGE
            sort(my_adj.begin(), my_adj.end(),
                 std::less<vertex_descriptor>() );
#endif
            my_adj.erase(unique(my_adj.begin(), my_adj.end()), my_adj.end());
          }

        // Reduce result of empty root list test
        all_reduce(pg, &hooked, &hooked+1, &any_hooked,
                   std::logical_or<bool>());
      } while ( any_hooked );
#ifdef PARALLEL_BGL_DEBUG
      if (id == 0) std::cerr << steps << " iterations.\n";
#endif
      //
      // Finalize
      //

      // For each vertex in g, p(v) = p(p(v)), assign parent of leaf
      // vertices from first step to final parent
      BGL_FORALL_VERTICES_T(v, g, DistributedGraph) {
        put(p, v, get(p, get(p, v)));
      }

      synchronize(p);
    }

  } // end namespace cc_detail

  template<typename Graph, typename ParentMap, typename ComponentMap>
  typename property_traits<ComponentMap>::value_type
  number_components_from_parents(const Graph& g, ParentMap p, ComponentMap c)
  {
    typedef typename graph_traits<Graph>::vertex_descriptor
      vertex_descriptor;
    typedef typename boost::graph::parallel::process_group_type<Graph>::type
      process_group_type;
    typedef typename property_traits<ComponentMap>::value_type
      ComponentMapType;

    process_group_type pg = process_group(g);

    /* Build list of roots */
    std::vector<vertex_descriptor> my_roots, all_roots;

    BGL_FORALL_VERTICES_T(v, g, Graph) {
      if( find( my_roots.begin(), my_roots.end(), get(p, v) )
          == my_roots.end() )
        my_roots.push_back( get(p, v) );
    }

    all_gather(pg, my_roots.begin(), my_roots.end(), all_roots);

    /* Number components */
    std::map<vertex_descriptor, ComponentMapType> comp_numbers;
    ComponentMapType c_num = 0;

    // Compute component numbers
    for (std::size_t i = 0; i < all_roots.size(); i++ )
      if ( comp_numbers.count(all_roots[i]) == 0 )
        comp_numbers[all_roots[i]] = c_num++;

    // Broadcast component numbers
    BGL_FORALL_VERTICES_T(v, g, Graph) {
      put( c, v, comp_numbers[get(p, v)] );
    }

    // Broadcast number of components
    if (process_id(pg) == 0) {
      typedef typename process_group_type::process_size_type
        process_size_type;
      for (process_size_type dest = 1, n = num_processes(pg);
           dest != n; ++dest)
        send(pg, dest, 0, c_num);
    }
    synchronize(pg);

    if (process_id(pg) != 0) receive(pg, 0, 0, c_num);

    synchronize(c);

    return c_num;
  }

  template<typename Graph, typename ParentMap>
  int
  number_components_from_parents(const Graph& g, ParentMap p,
                                 dummy_property_map)
  {
    using boost::parallel::all_reduce;

    // Count local roots.
    int num_roots = 0;
    BGL_FORALL_VERTICES_T(v, g, Graph)
      if (get(p, v) == v) ++num_roots;
    return all_reduce(g.process_group(), num_roots, std::plus<int>());
  }

  template<typename Graph, typename ComponentMap, typename ParentMap>
  typename property_traits<ComponentMap>::value_type
  connected_components
    (const Graph& g, ComponentMap c, ParentMap p
     BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, distributed_graph_tag))
  {
    cc_detail::parallel_connected_components(g, p);
    return number_components_from_parents(g, p, c);
  }

  /* Construct ParentMap by default */
  template<typename Graph, typename ComponentMap>
  typename property_traits<ComponentMap>::value_type
  connected_components
    ( const Graph& g, ComponentMap c
      BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, distributed_graph_tag) )
  {
    typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;

    std::vector<vertex_descriptor> x(num_vertices(g));

    return connected_components
             (g, c,
              make_iterator_property_map(x.begin(), get(vertex_index, g)));
  }
} // end namespace distributed

using distributed::connected_components;
} // end namespace graph

using graph::distributed::connected_components;
} // end namespace boost

#endif // BOOST_GRAPH_PARALLEL_CC_HPP

max_stars_repo_name: RaptDept/slimtune

max_issues_repo_name: RaptDept/slimtune

max_forks_repo_name: RaptDept/slimtune


text:
#pragma once

#include <cstdio>
#include <type_traits>
#include <iterator>
#include <stack>
#include <stdexcept>
#include <boost/format.hpp>
#include "io/input_stream.hpp"
#include "io/output_stream.hpp"
#include "io/file.hpp"
#include "log/log.hpp"
#include "json_tokenizer.hpp"
#include "utility/constructor_tag.hpp"
#include "utility/service_registry.hpp"

namespace gorc {

    class json_input_stream {
        template <typename EmFmtFnT>
        friend auto json_deserialize_heterogeneous(json_input_stream &f, EmFmtFnT efn)
            -> decltype(efn(f, std::string()));
        template <typename EmFmtFn>
        friend void json_deserialize_members(json_input_stream &f, EmFmtFn efn);
        template <typename EmFmtFn>
        friend void json_deserialize_array(json_input_stream &f, EmFmtFn efn);
        template <typename ValueT, typename OutItT>
        friend void json_deserialize_array(json_input_stream &f, OutItT const &rng);
        template <typename OutItT, typename EmFmtFn>
        friend void json_deserialize_array(json_input_stream &f, OutItT const &rng, EmFmtFn efn);
        friend void json_deserialize_null(json_input_stream &f);
        template <typename T>
        friend typename std::enable_if<std::is_same<std::string, T>::value, T>::type
            json_deserialize(json_input_stream &f);
        template <typename T>
        friend typename std::enable_if<std::is_fundamental<T>::value, T>::type
            json_deserialize(json_input_stream &f);

    private:
        json_tokenizer tok;

        void advance_token();
        void assert_token(std::string const &);

        inline bool at_end()
        {
            return tok.get_type() == token_type::end_of_file;
        }

        int64_t read_integer();
        double read_double();

        template <typename T>
        typename std::enable_if<std::is_same<T, bool>::value, T>::type read_value()
        {
            if(tok.get_type() == token_type::identifier && tok.get_value() == "true") {
                advance_token();
                return true;
            }
            else if(tok.get_type() == token_type::identifier && tok.get_value() == "false") {
                advance_token();
                return false;
            }
            else {
                diagnostic_context dc(get_diagnostic_context());
                LOG_FATAL(format("'%s' is not a boolean literal") % tok.get_value());
            }
        }

        template <typename T>
        typename std::enable_if<std::is_integral<T>::value &&
                                !std::is_same<T, bool>::value, T>::type read_value()
        {
            int64_t value = read_integer();
            advance_token();
            return static_cast<T>(value);
        }

        template <typename T>
        typename std::enable_if<std::is_floating_point<T>::value, T>::type read_value()
        {
            double value = read_double();
            advance_token();
            return static_cast<T>(value);
        }

    public:
        service_registry const &services;

        explicit json_input_stream(input_stream &f);
        json_input_stream(input_stream &f, service_registry const &services);
        virtual ~json_input_stream();

        diagnostic_context_location get_diagnostic_context() const;
    };

    template <typename T>
    typename std::enable_if<std::is_fundamental<T>::value, T>::type
        json_deserialize(json_input_stream &f)
    {
        return f.read_value<T>();
    }

    template <typename T>
    typename std::enable_if<std::is_same<std::string, T>::value, T>::type
        json_deserialize(json_input_stream &f)
    {
        std::string rv = f.tok.get_value();
        f.advance_token();
        return rv;
    }

    template <typename T>
    typename std::enable_if<!std::is_fundamental<T>::value &&
                            !std::is_same<std::string, T>::value>::type
        json_deserialize(json_input_stream &f, T &obj)
    {
        obj.json_deserialize(f);
    }

    template <typename T>
    typename std::enable_if<!std::is_fundamental<T>::value &&
                            !std::is_same<std::string, T>::value, T>::type
        json_deserialize(json_input_stream &f)
    {
        T obj(deserialization_constructor, f);
        return obj;
    }

    inline void json_deserialize_null(json_input_stream &f)
    {
        f.assert_token("null");
    }

    template <typename EmFmtFn>
    void json_deserialize_array(json_input_stream &f, EmFmtFn efn)
    {
        f.assert_token("[");

        while(!f.at_end()) {
            if(f.tok.get_value() == "]") {
                f.advance_token();
                return;
            }
            else if(f.tok.get_value() == ",") {
                f.advance_token();
                continue;
            }
            else {
                diagnostic_context ec(f.get_diagnostic_context());
                efn(f);
            }
        }

        diagnostic_context dc(f.get_diagnostic_context());
        LOG_FATAL("unexpected end of file inside array");
    }

    template <typename OutItT, typename EmFmtFn>
    void json_deserialize_array(json_input_stream &f, OutItT const &rng, EmFmtFn efn)
    {
        auto out_it = rng;

        f.assert_token("[");

        while(!f.at_end()) {
            if(f.tok.get_value() == "]") {
                f.advance_token();
                return;
            }
            else if(f.tok.get_value() == ",") {
                f.advance_token();
                continue;
            }
            else {
                diagnostic_context ec(f.get_diagnostic_context());
                *out_it = efn(f);
                ++out_it;
            }
        }

        diagnostic_context dc(f.get_diagnostic_context());
        LOG_FATAL("unexpected end of file inside array");
    }

    template <typename ValueT, typename OutItT>
    void json_deserialize_array(json_input_stream &f, OutItT const &rng)
    {
        auto out_it = rng;

        f.assert_token("[");

        while(!f.at_end()) {
            if(f.tok.get_value() == "]") {
                f.advance_token();
                return;
            }
            else if(f.tok.get_value() == ",") {
                f.advance_token();
                continue;
            }
            else {
                *out_it = json_deserialize<ValueT>(f);
                ++out_it;
            }
        }

        diagnostic_context dc(f.get_diagnostic_context());
        LOG_FATAL("unexpected end of file inside array");
    }

    template <typename ValueT, typename OutItT>
    void json_deserialize_array(json_input_stream &f, OutItT const &begin, OutItT const &end)
    {
        auto it = begin;
        json_deserialize_array(f, [&](json_input_stream &f) {
                if(it == end) {
                    LOG_FATAL("array contains too many elements");
                }

                *it = json_deserialize<ValueT>(f);
                ++it;
            });

        if(it != end) {
            diagnostic_context dc(f.get_diagnostic_context());
            LOG_FATAL("array contains too few elements");
        }
    }

    template <typename EmFmtFn>
    void json_deserialize_members(json_input_stream &f, EmFmtFn efn)
    {
        f.assert_token("{");

        std::string name_buf;

        while(!f.at_end()) {
            if(f.tok.get_value() == "}") {
                f.advance_token();
                return;
            }
            else if(f.tok.get_value() == ",") {
                f.advance_token();
                continue;
            }
            else {
                // Current token is a member name.
                if(f.tok.get_type() != token_type::string &&
                   f.tok.get_type() != token_type::identifier) {
                    diagnostic_context dc(f.get_diagnostic_context());
                    LOG_FATAL(format("expected key, found '%s'") % f.tok.get_value());
                }
                name_buf = f.tok.get_value();
                f.advance_token();
                f.assert_token(":");

                diagnostic_context ec(f.get_diagnostic_context());
                efn(f, name_buf);
            }
        }

        diagnostic_context dc(f.get_diagnostic_context());
        LOG_FATAL("unexpected end of file inside object");
    }

    template <typename EmFmtFn>
    auto json_deserialize_heterogeneous(json_input_stream &f, EmFmtFn efn)
        -> decltype(efn(f, std::string()))
    {
        if(f.tok.get_type() != token_type::string &&
           f.tok.get_type() != token_type::identifier) {
            diagnostic_context dc(f.get_diagnostic_context());
            LOG_FATAL(format("expected type, found '%s'") % f.tok.get_value());
        }

        std::string type_buf = f.tok.get_value();
        f.advance_token();

        diagnostic_context ec(f.get_diagnostic_context());
        return efn(f, type_buf);
    }

    template <typename OutItT, typename EmFmtFn>
    void json_deserialize_heterogeneous_array(json_input_stream &f, OutItT const &rng, EmFmtFn efn)
    {
        json_deserialize_array(f, rng, [&](json_input_stream &f) {
                return json_deserialize_heterogeneous(f, efn);
            });
    }

    template <typename EmFmtFn>
    void json_deserialize_heterogeneous_array(json_input_stream &f, EmFmtFn efn)
    {
        json_deserialize_array(f, [&](json_input_stream &f) {
                json_deserialize_heterogeneous(f, efn);
            });
    }

}

max_stars_repo_name: jdmclark/gorc

max_issues_repo_name: annnoo/gorc

max_forks_repo_name: annnoo/gorc


text:
//
//  VSCCollisionReceiver.cpp
//  EnveloppeEditor
//
//  Created by Jonathan Thorpe on 4/21/12.
//  Copyright (c) 2012 JBAT. All rights reserved.
//

#include "VSCIMCollisionMapping.h"

#include "VSCOBScene.h"
#include "VSCOBElement.h"
#include "VSCOBCollision.h"

#include <Ogre/Ogre.h>
#include <boost/assert.hpp>

VSC::Float VSC::IM::CollisionMapping::mappedValue(VSC::OB::Element::SPtr element, OB::Collision::SPtr collision)
{
    Float internalValue = this->internalMappedValue(element, collision);

    Float outputValue = (internalValue * mScaleFactor) + mOffset;

    if (mTrace)
    {
        std::cout << "CollisionMapping::mappedValue: " << outputValue << " (internal value: " << internalValue << ", ";
        std::cout << "scale factor: " << mScaleFactor << ", offset " << mOffset << ")" << std::endl;
    }

    return outputValue;
}

VSC::Float VSC::IM::CollisionVelocityMapping::internalMappedValue(OB::Element::SPtr element, OB::Collision::SPtr collision)
{
    BOOST_ASSERT(collision);

    if (collision)
    {
        const Ogre::Vector3& relativeVelocity = collision->getRelativeCollisionVelocity();
        return (Float) relativeVelocity.length();
    }

    return 0;
}

VSC::Float VSC::IM::CollisionDistanceMapping::internalMappedValue(OB::Element::SPtr element, OB::Collision::SPtr collision)
{
    return 0;
}


text:
#include <boost/program_options.hpp>
#include <iostream>

#include "sampler.hpp"
#include "tiling.hpp"

namespace boostPO = boost::program_options;

int main(int argc, char** argv)
{
	/* ARG PARSER *****************************************************/
	std::string fn_rules;
	std::string fn_bary;
	std::string fn_dev;
	std::string fn_out;
	std::string fn_image;
	unsigned int nbSample;
	unsigned short int seed;
	double lvl_min;
	double lvl_max;
	double rank_min;
	double rank_max;

	boostPO::variables_map vm;
	boostPO::options_description desc("Allowed options");
	desc.add_options()
		("help,h",
		 "produce help message")
		("rule,r",
		 boostPO::value<std::string>(&fn_rules)->required(),
		 "REQUIRED | Subdivision rule filename")
		("bary,b",
		 boostPO::value<std::string>(&fn_bary)->required(),
		 "REQUIRED | Barycenter offset filename (for each rule id)")
		("dev,d",
		 boostPO::value<std::string>(&fn_dev),
		 "Offset LUT filename (for each structural indices)")
		("out,o",
		 boostPO::value<std::string>(&fn_out),
		 "Output filename")
		("nbSample,n",
		 boostPO::value<unsigned int>(&nbSample)->default_value(1024),
		 "Number of sample de generate")
		("image,i",
		 boostPO::value<std::string>(&fn_image),
		 "Image for adaptive sampling")
		("lvlmin,l",
		 boostPO::value<double>(&lvl_min)->default_value(0),
		 "Level min")
		("lvlmax,L",
		 boostPO::value<double>(&lvl_max)->default_value(4),
		 "Level max")
		("rankmin,k",
		 boostPO::value<double>(&rank_min)->default_value(0),
		 "Rank min")
		("rankmax,K",
		 boostPO::value<double>(&rank_max)->default_value(29),
		 "Rank max")
		("seed,s",
		 boostPO::value<unsigned short int>(&seed)->default_value(0),
		 "Initial tile to use for sampling ([1-408], 0 = random)")
		;

	try
	{
		boostPO::store(
				boostPO::command_line_parser(argc, argv).
				options(desc).run(), vm);
		boostPO::notify(vm);
	}
	catch(boost::program_options::error& e)
	{
		std::cerr << e.what() << std::endl;
		std::cout << desc << "\n";
		exit(EXIT_FAILURE);
	}

	if(vm.count("help"))
	{
		std::cout << desc << "\n";
		exit(EXIT_SUCCESS);
	}

	/* PROG ***********************************************************/
	Sampler sampler(fn_rules, fn_bary, fn_dev);

	if( seed == 0 )
	{
		srand48(time(NULL));
		seed = std::ceil(drand48()*408);
	}
	if( vm.count("seed") ) seed = (seed-1)%408;

	if(fn_image.empty())
	{
		if( vm.count("out") )
		{
			WriterFileRaw write(fn_out);
			sampler.generateUniform(nbSample, 0, write, seed);
		}
		else
		{
			WriterEmpty write;
			sampler.generateUniform(nbSample, 0, write, seed);
		}
	}
	else
	{
		Image img(fn_image);
		double white_density = computeDensity(lvl_min, rank_min, 0.21, sampler.tiling().subdivFactor());
		double black_density = computeDensity(lvl_max, rank_max, 0.21, sampler.tiling().subdivFactor());

		if( vm.count("out") )
		{
			WriterFileRaw write(fn_out);
			sampler.generateAdaptive(&(img.dFunc), white_density, black_density, 0, write, seed);
		}
		else
		{
			WriterEmpty write;
			sampler.generateAdaptive(&(img.dFunc), white_density, black_density, 0, write, seed);
		}
	}
}

max_stars_repo_name: polyhex-sampling/sampler

max_issues_repo_name: polyhex-sampling/sampler

max_forks_repo_name: polyhex-sampling/sampler