text:
/**
 *  @file
 *  @copyright defined in fsc/LICENSE.txt
 */
//
#include <stdlib.h>
#include <fscio/kafka_plugin/kafka_producer.hpp>
#include <fscio/kafka_plugin/kafka_plugin.hpp>
#include <fscio/kafka_plugin/kafka_types.hpp>

#include <fscio/chain/fscio_contract.hpp>
#include <fscio/chain/config.hpp>
#include <fscio/chain/exceptions.hpp>
#include <fscio/chain/transaction.hpp>
#include <fscio/chain/types.hpp>

#include <fc/io/json.hpp>
#include <fc/utf8.hpp>
#include <fc/variant.hpp>

#include <boost/chrono.hpp>
#include <boost/signals2/connection.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>

#include <queue>

namespace fc { class variant; }

namespace fscio {

    using chain::account_name;
    using chain::action_name;
    using chain::block_id_type;
    using chain::permission_name;
    using chain::transaction;
    using chain::signed_transaction;
    using chain::signed_block;
    using chain::transaction_id_type;
    using chain::packed_transaction;
    using chain::permission_level;
    using fscio::kafka_block_accept_st;

static appbase::abstract_plugin& _kafka_plugin = app().register_plugin<kafka_plugin>();
using kafka_producer_ptr = std::shared_ptr<class kafka_producer>;

    class kafka_plugin_impl {
    public:
        kafka_plugin_impl();

        ~kafka_plugin_impl();

        fc::optional<boost::signals2::scoped_connection> accepted_block_connection;
        fc::optional<boost::signals2::scoped_connection> irreversible_block_connection;
        fc::optional<boost::signals2::scoped_connection> accepted_transaction_connection;
        fc::optional<boost::signals2::scoped_connection> applied_transaction_connection;
        chain_plugin *chain_plug;
        struct action_info {
            account_name account;
            action_name name;
            vector <permission_level> authorization;
            string data_json;
        };

        struct trasaction_info_st {
            uint64_t block_number;
            fc::time_point block_time;
            chain::transaction_trace_ptr trace;
            vector<action_info> action_vec;

        };

        void consume_blocks();

        void accepted_block(const chain::block_state_ptr &);

        void applied_irreversible_block(const chain::block_state_ptr &);

        void accepted_transaction(const chain::transaction_metadata_ptr &);

        void applied_transaction(const chain::transaction_trace_ptr &);

        void process_accepted_transaction(const chain::transaction_metadata_ptr &);

        void _process_accepted_transaction(const chain::transaction_metadata_ptr &);

        void process_applied_transaction(const trasaction_info_st &);

        void _process_applied_transaction(const trasaction_info_st &);

        void process_accepted_block(const chain::block_state_ptr &);

        void _process_accepted_block(const chain::block_state_ptr &);

        void process_irreversible_block(const chain::block_state_ptr &);

        void _process_irreversible_block(const chain::block_state_ptr &);

        void init();

        bool configured{false};

        void filter_traction_trace(const chain::transaction_trace_ptr trace,action_name act_name);
        void _process_trace(vector<chain::action_trace>::iterator  action_trace_ptr,action_name act_name);

        uint32_t start_block_num = 0;
        bool start_block_reached = false;
        bool is_producer = false;

        size_t queue_size = 10000;
        std::deque<chain::transaction_metadata_ptr> transaction_metadata_queue;
        std::deque<chain::transaction_metadata_ptr> transaction_metadata_process_queue;
        std::deque<trasaction_info_st> transaction_trace_queue;
        std::deque<trasaction_info_st> transaction_trace_process_queue;
        std::deque<chain::block_state_ptr> block_state_queue;
        std::deque<chain::block_state_ptr> block_state_process_queue;
        std::deque<chain::block_state_ptr> irreversible_block_state_queue;
        std::deque<chain::block_state_ptr> irreversible_block_state_process_queue;
        boost::mutex mtx;
        boost::condition_variable condition;
        boost::thread consume_thread;
        boost::atomic<bool> done{false};
        boost::atomic<bool> startup{true};
        fc::optional<chain::chain_id_type> chain_id;
        fc::microseconds abi_serializer_max_time;

        static const account_name newaccount;
        static const account_name setabi;

        static const std::string block_states_col;
        static const std::string blocks_col;
        static const std::string trans_col;
        static const std::string trans_traces_col;
        static const std::string actions_col;
        static const std::string accounts_col;
        kafka_producer_ptr producer;
    };

    const account_name kafka_plugin_impl::newaccount = "newaccount";
    const account_name kafka_plugin_impl::setabi = "setabi";

    const std::string kafka_plugin_impl::block_states_col = "block_states";
    const std::string kafka_plugin_impl::blocks_col = "blocks";
    const std::string kafka_plugin_impl::trans_col = "transactions";
    const std::string kafka_plugin_impl::trans_traces_col = "transaction_traces";
    const std::string kafka_plugin_impl::actions_col = "actions";
    const std::string kafka_plugin_impl::accounts_col = "accounts";

    namespace {

        template<typename Queue, typename Entry>
        void queue(boost::mutex &mtx, boost::condition_variable &condition, Queue &queue, const Entry &e,
                   size_t queue_size) {
            int sleep_time = 100;
            size_t last_queue_size = 0;
            boost::mutex::scoped_lock lock(mtx);
            if (queue.size() > queue_size) {
                lock.unlock();
                condition.notify_one();
                if (last_queue_size < queue.size()) {
                    sleep_time += 100;
                } else {
                    sleep_time -= 100;
                    if (sleep_time < 0) sleep_time = 100;
                }
                last_queue_size = queue.size();
                boost::this_thread::sleep_for(boost::chrono::milliseconds(sleep_time));
                lock.lock();
            }
            queue.emplace_back(e);
            lock.unlock();
            condition.notify_one();
        }

    }

    void kafka_plugin_impl::accepted_transaction(const chain::transaction_metadata_ptr &t) {
        try {
            queue(mtx, condition, transaction_metadata_queue, t, queue_size);
        } catch (fc::exception &e) {
            elog("FC Exception while accepted_transaction ${e}", ("e", e.to_string()));
        } catch (std::exception &e) {
            elog("STD Exception while accepted_transaction ${e}", ("e", e.what()));
        } catch (...) {
            elog("Unknown exception while accepted_transaction");
        }
    }

    void kafka_plugin_impl::applied_transaction(const chain::transaction_trace_ptr &t) {
        try {
            if(!is_producer && !t->producer_block_id.valid()){
                return;
            }
            auto &chain = chain_plug->chain();
            trasaction_info_st transactioninfo = trasaction_info_st{
                    .block_number = chain.pending_block_state()->block_num,
                    .block_time = chain.pending_block_time(),
                    .trace =chain::transaction_trace_ptr(t)
            };
            trasaction_info_st &info_t = transactioninfo;

            queue(mtx, condition, transaction_trace_queue, info_t, queue_size);
        } catch (fc::exception &e) {
            elog("FC Exception while applied_transaction ${e}", ("e", e.to_string()));
        } catch (std::exception &e) {
            elog("STD Exception while applied_transaction ${e}", ("e", e.what()));
        } catch (...) {
            elog("Unknown exception while applied_transaction");
        }
    }

    void kafka_plugin_impl::applied_irreversible_block(const chain::block_state_ptr &bs) {
        try {
            queue(mtx, condition, irreversible_block_state_queue, bs, queue_size);
        } catch (fc::exception &e) {
            elog("FC Exception while applied_irreversible_block ${e}", ("e", e.to_string()));
        } catch (std::exception &e) {
            elog("STD Exception while applied_irreversible_block ${e}", ("e", e.what()));
        } catch (...) {
            elog("Unknown exception while applied_irreversible_block");
        }
    }

    void kafka_plugin_impl::accepted_block(const chain::block_state_ptr &bs) {
        try {
            queue(mtx, condition, block_state_queue, bs, queue_size);
        } catch (fc::exception &e) {
            elog("FC Exception while accepted_block ${e}", ("e", e.to_string()));
        } catch (std::exception &e) {
            elog("STD Exception while accepted_block ${e}", ("e", e.what()));
        } catch (...) {
            elog("Unknown exception while accepted_block");
        }
    }

    void kafka_plugin_impl::consume_blocks() {
        try {

            while (true) {
                boost::mutex::scoped_lock lock(mtx);
                while (transaction_metadata_queue.empty() &&
                       transaction_trace_queue.empty() &&
                       block_state_queue.empty() &&
                       irreversible_block_state_queue.empty() &&
                       !done) {
                    condition.wait(lock);
                }
                // capture for processing
                size_t transaction_metadata_size = transaction_metadata_queue.size();
                if (transaction_metadata_size > 0) {
                    transaction_metadata_process_queue = move(transaction_metadata_queue);
                    transaction_metadata_queue.clear();
                }
                size_t transaction_trace_size = transaction_trace_queue.size();
                if (transaction_trace_size > 0) {
                    transaction_trace_process_queue = move(transaction_trace_queue);
                    transaction_trace_queue.clear();
                }

                size_t block_state_size = block_state_queue.size();
                if (block_state_size > 0) {
                    block_state_process_queue = move(block_state_queue);
                    block_state_queue.clear();
                }
                size_t irreversible_block_size = irreversible_block_state_queue.size();
                if (irreversible_block_size > 0) {
                    irreversible_block_state_process_queue = move(irreversible_block_state_queue);
                    irreversible_block_state_queue.clear();
                }

                lock.unlock();

                // warn if queue size greater than 75%
                if (transaction_metadata_size > (queue_size * 0.75) ||
                    transaction_trace_size > (queue_size * 0.75) ||
                    block_state_size > (queue_size * 0.75) ||
                    irreversible_block_size > (queue_size * 0.75)) {
//            wlog("queue size: ${q}", ("q", transaction_metadata_size + transaction_trace_size ));
                } else if (done) {
                    ilog("draining queue, size: ${q}", ("q", transaction_metadata_size + transaction_trace_size));
                }

                // process transactions
                while (!transaction_metadata_process_queue.empty()) {
                    const auto &t = transaction_metadata_process_queue.front();
                    process_accepted_transaction(t);
                    transaction_metadata_process_queue.pop_front();
                }

                while (!transaction_trace_process_queue.empty()) {
                    const auto &t = transaction_trace_process_queue.front();
                    process_applied_transaction(t);
                    transaction_trace_process_queue.pop_front();
                }

                // process blocks
                while (!block_state_process_queue.empty()) {
                    const auto &bs = block_state_process_queue.front();
                    process_accepted_block(bs);
                    block_state_process_queue.pop_front();
                }

                // process irreversible blocks
                while (!irreversible_block_state_process_queue.empty()) {
                    const auto &bs = irreversible_block_state_process_queue.front();
                    process_irreversible_block(bs);
                    irreversible_block_state_process_queue.pop_front();
                }

                if (transaction_metadata_size == 0 &&
                    transaction_trace_size == 0 &&
                    block_state_size == 0 &&
                    irreversible_block_size == 0 &&
                    done) {
                    break;
                }
            }
            ilog("kafka_plugin consume thread shutdown gracefully");
        } catch (fc::exception &e) {
            elog("FC Exception while consuming block ${e}", ("e", e.to_string()));
        } catch (std::exception &e) {
            elog("STD Exception while consuming block ${e}", ("e", e.what()));
        } catch (...) {
            elog("Unknown exception while consuming block");
        }
    }

    void kafka_plugin_impl::process_accepted_transaction(const chain::transaction_metadata_ptr &t) {
        try {
            // always call since we need to capture setabi on accounts even if not storing transactions
            _process_accepted_transaction(t);
        } catch (fc::exception &e) {
            elog("FC Exception while processing accepted transaction metadata: ${e}", ("e", e.to_detail_string()));
        } catch (std::exception &e) {
            elog("STD Exception while processing accepted tranasction metadata: ${e}", ("e", e.what()));
        } catch (...) {
            elog("Unknown exception while processing accepted transaction metadata");
        }
    }

    void kafka_plugin_impl::process_applied_transaction(const trasaction_info_st &t) {
        try {
            if (start_block_reached) {
                _process_applied_transaction(t);
            }
        } catch (fc::exception &e) {
            elog("FC Exception while processing applied transaction trace: ${e}", ("e", e.to_detail_string()));
        } catch (std::exception &e) {
            elog("STD Exception while processing applied transaction trace: ${e}", ("e", e.what()));
        } catch (...) {
            elog("Unknown exception while processing applied transaction trace");
        }
    }

    void kafka_plugin_impl::process_irreversible_block(const chain::block_state_ptr &bs) {
        try {
            if (start_block_reached) {
                _process_irreversible_block(bs);
            }
        } catch (fc::exception &e) {
            elog("FC Exception while processing irreversible block: ${e}", ("e", e.to_detail_string()));
        } catch (std::exception &e) {
            elog("STD Exception while processing irreversible block: ${e}", ("e", e.what()));
        } catch (...) {
            elog("Unknown exception while processing irreversible block");
        }
    }

    void kafka_plugin_impl::process_accepted_block(const chain::block_state_ptr &bs) {
        try {
            if (!start_block_reached) {
                if (bs->block_num >= start_block_num) {
                    start_block_reached = true;
                }
            }
            if (start_block_reached) {
                _process_accepted_block(bs);
            }
        } catch (fc::exception &e) {
            elog("FC Exception while processing accepted block trace ${e}", ("e", e.to_string()));
        } catch (std::exception &e) {
            elog("STD Exception while processing accepted block trace ${e}", ("e", e.what()));
        } catch (...) {
            elog("Unknown exception while processing accepted block trace");
        }
    }

    void kafka_plugin_impl::_process_accepted_transaction(const chain::transaction_metadata_ptr &t) {

        const signed_transaction& trx = t->packed_trx->get_signed_transaction();

        string trx_json = fc::json::to_string( trx );
        //ilog("trx_json: ${e}",("e",trx_json));
        producer->kafka_sendmsg(KAFKA_TRX_ACCEPT,(char*)trx_json.c_str());

    }

    void kafka_plugin_impl::_process_applied_transaction(const trasaction_info_st &t) {

       uint64_t time = (t.block_time.time_since_epoch().count()/1000);

       string transaction_metadata_json =
               "{\"block_number\":" + std::to_string(t.block_number) + ",\"block_time\":" + std::to_string(time) +
               ",\"trace\":" + fc::json::to_string(t.trace).c_str() +"}";
       producer->kafka_sendmsg(KAFKA_TRX_APPLIED,(char*)transaction_metadata_json.c_str());
       //elog("transaction_metadata_json = ${e}",("e",transaction_metadata_json));

       if(producer->kafka_get_topic(KAFKA_TRX_TRANSFER) != NULL){
           filter_traction_trace(t.trace,N(transfer));
           if(t.trace->action_traces.size() > 0){
               string transfer_json =
                       "{\"block_number\":" + std::to_string(t.block_number) + ",\"block_time\":" + std::to_string(time) +
                       ",\"trace\":" + fc::json::to_string(t.trace).c_str() +"}";
               producer->kafka_sendmsg(KAFKA_TRX_TRANSFER,(char*)transfer_json.c_str());
               //elog("transfer_json = ${e}",("e",transfer_json));
           }
       }
   }

    void kafka_plugin_impl::_process_accepted_block( const chain::block_state_ptr& bs ) {
        const auto& header = bs->header;

        kafka_block_accept_st block_accept;

        block_accept.current_block_num = bs->block_num;
        block_accept.current_block_id = bs->id;
        block_accept.current_block_header = header;

        auto &chain = chain_plug->chain();
        block_accept.irreversible_block_num = chain.last_irreversible_block_num();
        block_accept.irreversible_block_id = chain.last_irreversible_block_id();

        auto block_json = fc::json::to_string( block_accept );
        //ilog("json: ${e}",("e",block_json));
        producer->kafka_sendmsg(KAFKA_BLOCK_ACCEPT,(char*)block_json.c_str());

    }

    void kafka_plugin_impl::_process_irreversible_block(const chain::block_state_ptr& bs)
    {

    }

    void kafka_plugin_impl::_process_trace(vector<chain::action_trace>::iterator  action_trace_ptr,action_name act_name){

        auto inline_trace_ptr = action_trace_ptr->inline_traces.begin();
        for(;inline_trace_ptr!=action_trace_ptr->inline_traces.end();inline_trace_ptr++){
            //elog("inline action:");
            _process_trace(inline_trace_ptr,act_name);
        }

        if(action_trace_ptr->act.name == act_name){

        //elog("act_name=${e}",("e",act_name));
        chain_apis::read_only::abi_bin_to_json_params params = {
            .code = action_trace_ptr->act.account,
            .action = action_trace_ptr->act.name,
            .binargs = action_trace_ptr->act.data
        };

        auto readonly = chain_plug->get_read_only_api();
        auto Result = readonly.abi_bin_to_json(params);

        string data_str = fc::json::to_string(Result.args);
        action_info action_info1 = {
            .account = action_trace_ptr->act.account,
            .name = action_trace_ptr->act.name,
            .authorization = action_trace_ptr->act.authorization,
            .data_json = data_str
        };

        action_trace_ptr->act.data.resize(data_str.size());
        action_trace_ptr->act.data.assign(data_str.begin(),data_str.end());
        //elog("act.data=${e}",("e",action_trace_ptr->act.data));
        }
    }

    void kafka_plugin_impl::filter_traction_trace(const chain::transaction_trace_ptr trace,action_name act_name){

        vector<chain::action_trace>::iterator action_trace_ptr = trace->action_traces.begin();

        for(;action_trace_ptr != trace->action_traces.end();){
            if(action_trace_ptr->act.name == act_name){
                _process_trace(action_trace_ptr,act_name);
                action_trace_ptr++;
                continue;
            }else{
                trace->action_traces.erase(action_trace_ptr);
            }
        }
    }

    kafka_plugin_impl::kafka_plugin_impl()
    :producer(new kafka_producer)
    {
    }

    kafka_plugin_impl::~kafka_plugin_impl() {
       if (!startup) {
          try {
             ilog( "kafka_db_plugin shutdown in process please be patient this can take a few minutes" );
             done = true;
             condition.notify_one();

             consume_thread.join();
             producer->kafka_destroy();
          } catch( std::exception& e ) {
             elog( "Exception on kafka_plugin shutdown of consume thread: ${e}", ("e", e.what()));
          }
       }
    }

    void kafka_plugin_impl::init() {

        ilog("starting kafka plugin thread");
        consume_thread = boost::thread([this] { consume_blocks(); });
        startup = false;
    }

////////////
// kafka_plugin
////////////

    kafka_plugin::kafka_plugin()
            : my(new kafka_plugin_impl) {
    }

    kafka_plugin::~kafka_plugin() {
    }

    void kafka_plugin::set_program_options(options_description &cli, options_description &cfg) {
        cfg.add_options()
                ("kafka-trx_accept_topic", bpo::value<std::string>()->default_value("fscio.trx-accept"),
                 "The topic for accepted transaction.")
                ("kafka-trx_applied_topic", bpo::value<std::string>()->default_value("fscio.trx-applied"),
                 "The topic for appiled transaction.")
                ("kafka-trx_transfer_topic", bpo::value<std::string>()->default_value("fscio.trx-transfer"),
                 "The topic for transfer transaction.")
                ("kafka-block_accepted_topic", bpo::value<std::string>()->default_value("fscio.block-accept"),
                 "The topic for accepted block.")
                ("kafka-uri,k", bpo::value<std::string>(),
                 "the kafka brokers uri, as 192.168.31.225:9092")
                ("kafka-queue-size", bpo::value<uint32_t>()->default_value(256),
                 "The target queue size between nodfsc and kafka plugin thread.")
                ("kafka-block-start", bpo::value<uint32_t>()->default_value(256),
                 "If specified then only abi data pushed to kafka until specified block is reached.")
                 ;
    }

    void kafka_plugin::plugin_initialize(const variables_map &options) {
        char *accept_trx_topic = NULL;
        char *applied_trx_topic = NULL;
        char *transfer_trx_topic = NULL;
        char *accept_block_topic = NULL;
        char *brokers_str = NULL;

        try {
            if (options.count("kafka-uri")) {
                ilog("initializing kafka_plugin");
                brokers_str = (char *) (options.at("kafka-uri").as<std::string>().c_str());
                ilog("brokers_str:${j}", ("j", brokers_str));
                if (options.count("kafka-trx_accept_topic") != 0) {
                    accept_trx_topic = (char *) (options.at("kafka-trx_accept_topic").as<std::string>().c_str());
                }
                ilog("kafka-trx_accept_topic:${j}", ("j", accept_trx_topic));
                if (options.count("kafka-trx_applied_topic") != 0) {
                    applied_trx_topic = (char *) (options.at("kafka-trx_applied_topic").as<std::string>().c_str());
                }
                ilog("kafka-trx_applied_topic:${j}", ("j", applied_trx_topic));
                if (options.count("kafka-trx_transfer_topic") != 0) {
                    transfer_trx_topic = (char *) (options.at("kafka-trx_transfer_topic").as<std::string>().c_str());
                }
                ilog("kafka-trx_transfer_topic:${j}", ("j", transfer_trx_topic));
                if (options.count("kafka-block_accepted_topic") != 0) {
                    accept_block_topic = (char *) (options.at("kafka-block_accepted_topic").as<std::string>().c_str());
                }
                ilog("kafka-block_accepted_topic:${j}", ("j", accept_block_topic));

                if(0!=my->producer->kafka_init(brokers_str,accept_trx_topic,applied_trx_topic,transfer_trx_topic, accept_block_topic)){
                    elog("kafka_plugin initialized fail");
                }else{
                    ilog("kafka_plugin initialized ok");
                }
            }

            if (options.count("kafka-uri")) {
                my->configured = true;

                if( options.count( "kafka-queue-size" )) {
                    my->queue_size = options.at( "kafka-queue-size" ).as<uint32_t>();
                }
                if( options.count( "kafka-block-start" )) {
                    my->start_block_num = options.at( "kafka-block-start" ).as<uint32_t>();
                }
                if( my->start_block_num == 0 ) {
                    my->start_block_reached = true;
                }

                // hook up to signals on controller
                //chain_plugin* chain_plug = app().find_plugiin<chain_plugin>();
                my->chain_plug = app().find_plugin<chain_plugin>();
                FSC_ASSERT(my->chain_plug, chain::missing_chain_plugin_exception, "");
                auto &chain = my->chain_plug->chain();
                my->chain_id.emplace(chain.get_chain_id());

                my->accepted_block_connection.emplace( chain.accepted_block.connect( [&]( const chain::block_state_ptr& bs ) {
                    my->accepted_block(bs);
                }));

                my->irreversible_block_connection.emplace(
                    chain.irreversible_block.connect([&](const chain::block_state_ptr &bs) {
                    my->applied_irreversible_block(bs);
                }));

                my->accepted_transaction_connection.emplace(
                    chain.accepted_transaction.connect([&](const chain::transaction_metadata_ptr &t) {
                    my->accepted_transaction(t);
                }));
                my->applied_transaction_connection.emplace(
                    chain.applied_transaction.connect([&](const chain::transaction_trace_ptr &t) {
                    my->applied_transaction(t);
                }));
                my->init();
            } else {
                wlog( "fscio::kafka_plugin configured, but no --kafka-uri specified." );
                wlog( "kafka_plugin disabled." );
            }

            if( options.count( "producer-name") ) {
                wlog( "kafka plugin not recommended on producer node" );
                my->is_producer = true;
            }
        }

        FC_LOG_AND_RETHROW()
    }

    void kafka_plugin::plugin_startup() {
    }

    void kafka_plugin::plugin_shutdown() {

        my->accepted_block_connection.reset();
        my->irreversible_block_connection.reset();
        my->accepted_transaction_connection.reset();
        my->applied_transaction_connection.reset();
        my.reset();

    }

} // namespace fscio

max_stars_repo_name: FutureSharesCloud/FutureSharesCloud

max_issues_repo_name: FutureSharesCloud/FutureSharesCloud

max_forks_repo_name: FutureSharesCloud/FutureSharesCloud


text:
#include "waitdialog.hpp"

#include <boost/lexical_cast.hpp>

#include <components/widgets/box.hpp>

#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/statemanager.hpp"

#include "../mwworld/class.hpp"
#include "../mwworld/cellstore.hpp"

#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp"

#include "../mwstate/charactermanager.hpp"

namespace MWGui
{

    WaitDialogProgressBar::WaitDialogProgressBar()
        : WindowBase("openmw_wait_dialog_progressbar.layout")
    {
        getWidget(mProgressBar, "ProgressBar");
        getWidget(mProgressText, "ProgressText");
    }

    void WaitDialogProgressBar::open()
    {
        center();
    }

    void WaitDialogProgressBar::setProgress (int cur, int total)
    {
        mProgressBar->setProgressRange (total);
        mProgressBar->setProgressPosition (cur);
        mProgressText->setCaption(boost::lexical_cast<std::string>(cur) + "/" + boost::lexical_cast<std::string>(total));
    }

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

    WaitDialog::WaitDialog()
        : WindowBase("openmw_wait_dialog.layout")
        , mProgressBar()
        , mWaiting(false)
        , mSleeping(false)
        , mHours(1)
        , mRemainingTime(0.05)
        , mCurHour(0)
        , mManualHours(1)
        , mInterruptAt(-1)
    {
        getWidget(mDateTimeText, "DateTimeText");
        getWidget(mRestText, "RestText");
        getWidget(mHourText, "HourText");
        getWidget(mUntilHealedButton, "UntilHealedButton");
        getWidget(mWaitButton, "WaitButton");
        getWidget(mCancelButton, "CancelButton");
        getWidget(mHourSlider, "HourSlider");

        mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onCancelButtonClicked);
        mUntilHealedButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onUntilHealedButtonClicked);
        mWaitButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onWaitButtonClicked);
        mHourSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &WaitDialog::onHourSliderChangedPosition);

        mProgressBar.setVisible (false);
    }

    void WaitDialog::exit()
    {
        if(!mProgressBar.isVisible()) //Only exit if not currently waiting
            MWBase::Environment::get().getWindowManager()->popGuiMode();
    }

    void WaitDialog::open()
    {
        if (!MWBase::Environment::get().getWindowManager ()->getRestEnabled ())
        {
            MWBase::Environment::get().getWindowManager()->popGuiMode ();
        }

        int canRest = MWBase::Environment::get().getWorld ()->canRest ();

        if (canRest == 2)
        {
            // resting underwater or mid-air not allowed
            MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage1}");
            MWBase::Environment::get().getWindowManager()->popGuiMode ();
        }

        setCanRest(canRest == 0);

        onHourSliderChangedPosition(mHourSlider, 0);
        mHourSlider->setScrollPosition (0);

        std::string month = MWBase::Environment::get().getWorld ()->getMonthName();
        int hour = MWBase::Environment::get().getWorld ()->getTimeStamp ().getHour ();
        bool pm = hour >= 12;
        if (hour >= 13) hour -= 12;
        if (hour == 0) hour = 12;

        std::string dateTimeText =
                boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getDay ()) + " "
                + month + " (#{sDay} " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getTimeStamp ().getDay())
                + ") " + boost::lexical_cast<std::string>(hour) + " " + (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}");

        mDateTimeText->setCaptionWithReplacing (dateTimeText);
    }

    void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender)
    {
        int autoHours = MWBase::Environment::get().getMechanicsManager()->getHoursToRest();

        startWaiting(autoHours);
    }

    void WaitDialog::onWaitButtonClicked(MyGUI::Widget* sender)
    {
        startWaiting(mManualHours);
    }

    void WaitDialog::startWaiting(int hoursToWait)
    {
        if(Settings::Manager::getBool("autosave","Saves") && mSleeping) //autosaves when enabled and sleeping
            MWBase::Environment::get().getStateManager()->quickSave("Autosave");

        MWBase::World* world = MWBase::Environment::get().getWorld();
        MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.2);
        setVisible(false);
        mProgressBar.setVisible (true);

        mWaiting = true;
        mCurHour = 0;
        mHours = hoursToWait;

        // FIXME: move this somewhere else?
        mInterruptAt = -1;
        MWWorld::Ptr player = world->getPlayerPtr();
        if (mSleeping && player.getCell()->isExterior())
        {
            std::string regionstr = player.getCell()->getCell()->mRegion;
            if (!regionstr.empty())
            {
                const ESM::Region *region = world->getStore().get<ESM::Region>().find (regionstr);
                if (!region->mSleepList.empty())
                {
                    float fSleepRandMod = world->getStore().get<ESM::GameSetting>().find("fSleepRandMod")->getFloat();
                    int x = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * hoursToWait; // [0, hoursRested]
                    float y = fSleepRandMod * hoursToWait;
                    if (x > y)
                    {
                        float fSleepRestMod = world->getStore().get<ESM::GameSetting>().find("fSleepRestMod")->getFloat();
                        mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait);
                        mInterruptCreatureList = region->mSleepList;
                    }
                }
            }
        }

        mRemainingTime = 0.05;
        mProgressBar.setProgress (0, mHours);
    }

    void WaitDialog::onCancelButtonClicked(MyGUI::Widget* sender)
    {
        exit();
    }

    void WaitDialog::onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position)
    {
        mHourText->setCaptionWithReplacing (boost::lexical_cast<std::string>(position+1) + " #{sRestMenu2}");
        mManualHours = position+1;
    }

    void WaitDialog::setCanRest (bool canRest)
    {
        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
        MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
        bool full = (stats.getHealth().getCurrent() >= stats.getHealth().getModified())
                && (stats.getMagicka().getCurrent() >= stats.getMagicka().getModified());
        MWMechanics::NpcStats& npcstats = player.getClass().getNpcStats(player);
        bool werewolf = npcstats.isWerewolf();

        mUntilHealedButton->setVisible(canRest && !full);
        mWaitButton->setCaptionWithReplacing (canRest ? "#{sRest}" : "#{sWait}");
        mRestText->setCaptionWithReplacing (canRest ? "#{sRestMenu3}"
                                                    : (werewolf ? "#{sWerewolfRestMessage}"
                                                                : "#{sRestIllegal}"));

        mSleeping = canRest;

        Gui::Box* box = dynamic_cast<Gui::Box*>(mMainWidget);
        if (box == NULL)
            throw std::runtime_error("main widget must be a box");
        box->notifyChildrenSizeChanged();
        center();
    }

    void WaitDialog::onFrame(float dt)
    {
        if (!mWaiting)
            return;

        if (mCurHour == mInterruptAt)
        {
            MWBase::Environment::get().getWindowManager()->messageBox("#{sSleepInterrupt}");
            MWBase::Environment::get().getWorld()->spawnRandomCreature(mInterruptCreatureList);
            stopWaiting();
        }

        mRemainingTime -= dt;

        while (mRemainingTime < 0)
        {
            mRemainingTime += 0.05;
            ++mCurHour;
            mProgressBar.setProgress (mCurHour, mHours);

            if (mCurHour <= mHours)
            {
                MWBase::Environment::get().getWorld ()->advanceTime (1);
                MWBase::Environment::get().getMechanicsManager ()->rest (mSleeping);
            }
        }

        if (mCurHour > mHours)
        {
            stopWaiting();

            MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
            const MWMechanics::NpcStats &pcstats = player.getClass().getNpcStats(player);

            // trigger levelup if possible
            const MWWorld::Store<ESM::GameSetting> &gmst =
                MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
            if (mSleeping && pcstats.getLevelProgress () >= gmst.find("iLevelUpTotal")->getInt())
            {
                MWBase::Environment::get().getWindowManager()->pushGuiMode (GM_Levelup);
            }
        }
    }

    void WaitDialog::stopWaiting ()
    {
        MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.2);
        mProgressBar.setVisible (false);
        MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Rest);
        MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_RestBed);
        mWaiting = false;
    }

    void WaitDialog::wakeUp ()
    {
        mSleeping = false;
        mWaiting = false;
        stopWaiting();
    }

}

ext: cpp

max_stars_repo_name: Bodillium/openmw

max_issues_repo_name: Bodillium/openmw

max_forks_repo_name: Bodillium/openmw


text: #include <boost/ptr_container/nullable.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <boost/filesystem.hpp>
#include <fstream>
#include <memory>
#include "tasks/internal/exists_task.h"

namespace fs = boost::filesystem;

class exists_task_test : public ::testing::Test
{
protected:
	fs::path root;
	fs::path target;
	std::shared_ptr<exists_task> task;
	std::shared_ptr<task_metadata> task_meta;

	virtual void SetUp()
	{
		root = fs::temp_directory_path() / fs::unique_path();
		fs::create_directory(root);
		fs::create_directory(root / "subdir");

		create_file(root / "file_a");
		create_file(root / "subdir" / "file_b");

		task_meta = std::make_shared<task_metadata>();
		task_meta->cmd_args = {"failure message", root.string()};
		task = std::make_shared<exists_task>(1, task_meta);
	}

	virtual void TearDown()
	{
		fs::remove_all(root);
		fs::remove(root);
	}

	void create_file(const fs::path &path)
	{
		std::ofstream f(path.string());
		f << "test file";
		f.close();
	}
};

TEST_F(exists_task_test, root_exists)
{
	auto results = task->run();
	ASSERT_EQ(task_status::OK, results->status) << "Failed with: " + results->error_message;
}

TEST_F(exists_task_test, file_subdir_exists)
{
	task_meta->cmd_args = {"failure message", (root / "subdir").string(), (root / "file_a").string()};

	auto results = task->run();
	ASSERT_EQ(task_status::OK, results->status) << "Failed with: " + results->error_message;
}

TEST_F(exists_task_test, file_not_exists)
{
	task_meta->cmd_args = {"failure message", (root / "not_a_file").string()};

	auto results = task->run();
	ASSERT_EQ(task_status::FAILED, results->status);
	ASSERT_TRUE(results->error_message.find("cannot be found") != std::string::npos);
	ASSERT_EQ("failure message", results->output_stderr);
}

max_stars_repo_name: rqu/worker

max_issues_repo_name: rqu/worker

max_forks_repo_name: rqu/worker


text:
#ifndef ENGINE_RESPONSE_OBJECTS_HPP_
#define ENGINE_RESPONSE_OBJECTS_HPP_

#include "extractor/travel_mode.hpp"
#include "guidance/turn_instruction.hpp"
#include "engine/guidance/leg_geometry.hpp"
#include "engine/guidance/route.hpp"
#include "engine/guidance/route_leg.hpp"
#include "engine/guidance/route_step.hpp"
#include "engine/guidance/step_maneuver.hpp"
#include "engine/polyline_compressor.hpp"
#include "util/coordinate.hpp"
#include "util/json_container.hpp"

#include <boost/optional.hpp>

#include <algorithm>
#include <iterator>
#include <string>
#include <vector>

namespace osrm
{
namespace engine
{

struct Hint;

namespace api
{
namespace json
{
namespace detail
{

// Check whether to include a modifier in the result of the API
inline bool isValidModifier(const guidance::StepManeuver maneuver)
{
    return (maneuver.waypoint_type == guidance::WaypointType::None ||
            maneuver.instruction.direction_modifier != osrm::guidance::DirectionModifier::UTurn);
}

inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection)
{
    return intersection.lanes.lanes_in_turn > 0;
}

util::json::Array coordinateToLonLat(const util::Coordinate &coordinate);

/**
 * Ensures that a bearing value is a whole number, and clamped to the range 0-359
 */
inline double roundAndClampBearing(double bearing) { return std::fmod(std::round(bearing), 360); }

} // namespace detail

template <unsigned POLYLINE_PRECISION, typename ForwardIter>
util::json::String makePolyline(ForwardIter begin, ForwardIter end)
{
    return {encodePolyline<POLYLINE_PRECISION>(begin, end)};
}

template <typename ForwardIter>
util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
{
    auto num_coordinates = std::distance(begin, end);
    BOOST_ASSERT(num_coordinates != 0);
    util::json::Object geojson;
    geojson.values["type"] = "LineString";
    util::json::Array coordinates;
    if (num_coordinates > 1)
    {
        coordinates.values.reserve(num_coordinates);
        auto into = std::back_inserter(coordinates.values);
        std::transform(begin, end, into, &detail::coordinateToLonLat);
    }
    else if (num_coordinates > 0)
    {
        // For a single location we create a [location, location] LineString
        // instead of a single Point making the GeoJSON output consistent.
        coordinates.values.reserve(2);
        auto location = detail::coordinateToLonLat(*begin);
        coordinates.values.push_back(location);
        coordinates.values.push_back(location);
    }
    geojson.values["coordinates"] = std::move(coordinates);

    return geojson;
}

util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver);

util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geometry);

util::json::Object makeRoute(const guidance::Route &route,
                             util::json::Array legs,
                             boost::optional<util::json::Value> geometry,
                             const char *weight_name);

// Creates a Waypoint without Hint, see the Hint overload below
util::json::Object
makeWaypoint(const util::Coordinate &location, const double &distance, std::string name);

// Creates a Waypoint with Hint, see the overload above when Hint is not needed
util::json::Object makeWaypoint(const util::Coordinate &location,
                                const double &distance,
                                std::string name,
                                const Hint &hint);

util::json::Object makeRouteLeg(guidance::RouteLeg leg, util::json::Array steps);

util::json::Array makeRouteLegs(std::vector<guidance::RouteLeg> legs,
                                std::vector<util::json::Value> step_geometries,
                                std::vector<util::json::Object> annotations);
}
}
} // namespace engine
} // namespace osrm

#endif // ENGINE_GUIDANCE_API_RESPONSE_GENERATOR_HPP_

max_stars_repo_name: asaveljevs/osrm-backend

max_issues_repo_name: zhangdida/osrm-backend

max_forks_repo_name: zhangdida/osrm-backend


text:
//  thread_pool.hpp  --------------------------------------------------------------//

//  Copyright 2013 Andrey Semashev

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

#ifndef BOOST_DETAIL_WINAPI_THREAD_POOL_HPP
#define BOOST_DETAIL_WINAPI_THREAD_POOL_HPP

#include <boost/detail/winapi/basic_types.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN2K

namespace boost
{
namespace detail
{
namespace winapi
{
#if defined( BOOST_USE_WINDOWS_H )

typedef ::WAITORTIMERCALLBACKFUNC WAITORTIMERCALLBACKFUNC_;
typedef ::WAITORTIMERCALLBACK WAITORTIMERCALLBACK_;

using ::RegisterWaitForSingleObject;
using ::UnregisterWait;
using ::UnregisterWaitEx;

const ULONG_ wt_execute_default = WT_EXECUTEDEFAULT;
const ULONG_ wt_execute_in_io_thread = WT_EXECUTEINIOTHREAD;
const ULONG_ wt_execute_in_ui_thread = WT_EXECUTEINUITHREAD;
const ULONG_ wt_execute_in_wait_thread = WT_EXECUTEINWAITTHREAD;
const ULONG_ wt_execute_only_once = WT_EXECUTEONLYONCE;
const ULONG_ wt_execute_in_timer_thread = WT_EXECUTEINTIMERTHREAD;
const ULONG_ wt_execute_long_function = WT_EXECUTELONGFUNCTION;
const ULONG_ wt_execute_in_persistent_io_thread = WT_EXECUTEINPERSISTENTIOTHREAD;
const ULONG_ wt_execute_in_persistent_thread = WT_EXECUTEINPERSISTENTTHREAD;
const ULONG_ wt_transfer_impersonation = WT_TRANSFER_IMPERSONATION;

inline ULONG_ wt_set_max_threadpool_threads(ULONG_ flags, ULONG_ limit)
{
    return WT_SET_MAX_THREADPOOL_THREADS(flags, limit);
}

#else

extern "C" {

typedef void (NTAPI* WAITORTIMERCALLBACKFUNC_) (PVOID_, BOOLEAN_);
typedef WAITORTIMERCALLBACKFUNC_ WAITORTIMERCALLBACK_;

__declspec(dllimport) BOOL_ WINAPI RegisterWaitForSingleObject
(
    HANDLE_* phNewWaitObject,
    HANDLE_ hObject,
    WAITORTIMERCALLBACK_ Callback,
    PVOID_ Context,
    ULONG_ dwMilliseconds,
    ULONG_ dwFlags
);

__declspec(dllimport) BOOL_ WINAPI UnregisterWait(HANDLE_ WaitHandle);
__declspec(dllimport) BOOL_ WINAPI UnregisterWaitEx(HANDLE_ WaitHandle, HANDLE_ CompletionEvent);

} // extern "C"

const ULONG_ wt_execute_default = 0x00000000;
const ULONG_ wt_execute_in_io_thread = 0x00000001;
const ULONG_ wt_execute_in_ui_thread = 0x00000002;
const ULONG_ wt_execute_in_wait_thread = 0x00000004;
const ULONG_ wt_execute_only_once = 0x00000008;
const ULONG_ wt_execute_in_timer_thread = 0x00000020;
const ULONG_ wt_execute_long_function = 0x00000010;
const ULONG_ wt_execute_in_persistent_io_thread = 0x00000040;
const ULONG_ wt_execute_in_persistent_thread = 0x00000080;
const ULONG_ wt_transfer_impersonation = 0x00000100;

inline ULONG_ wt_set_max_threadpool_threads(ULONG_ flags, ULONG_ limit)
{
    return flags | (limit << 16);
}

#endif
}
}
}

#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN2K

#endif // BOOST_DETAIL_WINAPI_THREAD_POOL_HPP


text:
/*!
@file
Defines `boost::hana::Functor`.

@copyright Louis Dionne 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
 */

#ifndef BOOST_HANA_FUNCTOR_HPP
#define BOOST_HANA_FUNCTOR_HPP

#include <boost/hana/fwd/functor.hpp>

#include <boost/hana/bool.hpp>
#include <boost/hana/core/datatype.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/models.hpp>
#include <boost/hana/core/when.hpp>
#include <boost/hana/detail/std/forward.hpp>
#include <boost/hana/functional/always.hpp>
#include <boost/hana/functional/partial.hpp>
#include <boost/hana/logical.hpp>

namespace boost { namespace hana {
    //////////////////////////////////////////////////////////////////////////
    // transform
    //////////////////////////////////////////////////////////////////////////
    template <typename Fun, typename>
    struct transform_impl : transform_impl<Fun, when<true>> { };

    template <typename Fun, bool condition>
    struct transform_impl<Fun, when<condition>> : default_ {
        template <typename Xs, typename F>
        static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
            return hana::adjust_if(detail::std::forward<Xs>(xs),
                                   hana::always(true_),
                                   detail::std::forward<F>(f));
        }
    };

    //////////////////////////////////////////////////////////////////////////
    // adjust_if
    //////////////////////////////////////////////////////////////////////////
    template <typename Fun, typename>
    struct adjust_if_impl : adjust_if_impl<Fun, when<true>> { };

    namespace functor_detail {
        struct go {
            template <typename F, typename X>
            static constexpr decltype(auto) helper(decltype(true_), F&& f, X&& x)
            { return detail::std::forward<F>(f)(detail::std::forward<X>(x)); }

            template <typename F, typename X>
            static constexpr X helper(decltype(false_), F&&, X&& x)
            { return detail::std::forward<X>(x); }

            template <typename F, typename X>
            static constexpr decltype(auto) helper(bool cond, F&& f, X&& x) {
                return cond ? detail::std::forward<F>(f)(detail::std::forward<X>(x))
                            : detail::std::forward<X>(x);
            }

            template <typename Pred, typename F, typename X>
            constexpr decltype(auto) operator()(Pred&& pred, F&& f, X&& x) const {
                auto cond = hana::if_(detail::std::forward<Pred>(pred)(x),
                    true_, false_
                );
                return go::helper(cond, detail::std::forward<F>(f),
                                        detail::std::forward<X>(x));
            }
        };
    }

    template <typename Fun, bool condition>
    struct adjust_if_impl<Fun, when<condition>> : default_ {
        template <typename Xs, typename Pred, typename F>
        static constexpr auto apply(Xs&& xs, Pred&& pred, F&& f) {
            return hana::transform(detail::std::forward<Xs>(xs),
                hana::partial(functor_detail::go{},
                        detail::std::forward<Pred>(pred),
                        detail::std::forward<F>(f)));
        }
    };

    //////////////////////////////////////////////////////////////////////////
    // adjust
    //////////////////////////////////////////////////////////////////////////
    template <typename Fun, typename>
    struct adjust_impl : adjust_impl<Fun, when<true>> { };

    template <typename Fun, bool condition>
    struct adjust_impl<Fun, when<condition>> : default_ {
        template <typename Xs, typename Value, typename F>
        static constexpr auto apply(Xs&& xs, Value&& value, F&& f) {
            return hana::adjust_if(
                detail::std::forward<Xs>(xs),
                hana::equal.to(detail::std::forward<Value>(value)),
                detail::std::forward<F>(f)
            );
        }
    };

    //////////////////////////////////////////////////////////////////////////
    // replace_if
    //////////////////////////////////////////////////////////////////////////
    template <typename Fun, typename>
    struct replace_if_impl : replace_if_impl<Fun, when<true>> { };

    template <typename Fun, bool condition>
    struct replace_if_impl<Fun, when<condition>> : default_ {
        template <typename Xs, typename Pred, typename Value>
        static constexpr decltype(auto) apply(Xs&& xs, Pred&& pred, Value&& v) {
            return hana::adjust_if(detail::std::forward<Xs>(xs),
                detail::std::forward<Pred>(pred),
                hana::always(detail::std::forward<Value>(v))
            );
        }
    };

    //////////////////////////////////////////////////////////////////////////
    // replace
    //////////////////////////////////////////////////////////////////////////
    template <typename Fun, typename>
    struct replace_impl : replace_impl<Fun, when<true>> { };

    template <typename Fun, bool condition>
    struct replace_impl<Fun, when<condition>> : default_ {
        template <typename Xs, typename OldVal, typename NewVal>
        static constexpr decltype(auto)
        apply(Xs&& xs, OldVal&& oldval, NewVal&& newval) {
            return hana::replace_if(
                detail::std::forward<Xs>(xs),
                hana::equal.to(detail::std::forward<OldVal>(oldval)),
                detail::std::forward<NewVal>(newval)
            );
        }
    };

    //////////////////////////////////////////////////////////////////////////
    // fill
    //////////////////////////////////////////////////////////////////////////
    template <typename Fun, typename>
    struct fill_impl : fill_impl<Fun, when<true>> { };

    template <typename Fun, bool condition>
    struct fill_impl<Fun, when<condition>> : default_ {
        template <typename Xs, typename Value>
        static constexpr decltype(auto) apply(Xs&& xs, Value&& v) {
            return hana::transform(detail::std::forward<Xs>(xs),
                                   hana::always(detail::std::forward<Value>(v))
            );
        }
    };

    //////////////////////////////////////////////////////////////////////////
    // models
    //////////////////////////////////////////////////////////////////////////
    template <typename F>
    struct models_impl<Functor, F>
        : _integral_constant<bool,
            !is_default<transform_impl<F>>{} ||
            !is_default<adjust_if_impl<F>>{}
        >
    { };
}} // end namespace boost::hana

#endif // !BOOST_HANA_FUNCTOR_HPP

max_stars_repo_name: josephwinston/hana

max_issues_repo_name: josephwinston/hana

max_forks_repo_name: josephwinston/hana


text:
///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2008-2012  Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
//  See accompanying file COPYING.TXT file for licensing details.
//
///////////////////////////////////////////////////////////////////////////////
#define CPPCMS_SOURCE
#include <cppcms/cppcms_error.h>
#include <cppcms/config.h>
#include <iostream>
#include <string.h>

#include <booster/system_error.h>

using namespace std;

namespace cppcms {

cppcms_error::cppcms_error(int err,std::string const &error) :
	booster::runtime_error(error+":" + strerror(err))
{
}

std::string cppcms_error::strerror(int err)
{
	return booster::system::error_code(err,booster::system::system_category).message();
}

}

max_stars_repo_name: gatehouse/cppcms

max_issues_repo_name: gatehouse/cppcms

max_forks_repo_name: gatehouse/cppcms


text:
///////////////////////////////////////////////////////////////////////////////
// subset_traits.hpp                                                         //
//                                                                           //
//  Copyright 2010 Erwann Rogard. Distributed under the Boost                //
//  Software License, Version 1.0. (See accompanying file                    //
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)         //
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_FUSION_DETAIL_CONTAINER_MAP_SUBSET_TRAITS_HPP_ER_2010
#define BOOST_FUSION_DETAIL_CONTAINER_MAP_SUBSET_TRAITS_HPP_ER_2010
#include <boost/mpl/bool.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/vector/vector10.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/include/filter_view.hpp>
#include <boost/fusion/include/pair.hpp>
#include <boost/fusion/include/at_key.hpp>
#include <boost/fusion/container/map/detail/unpack_map.hpp>

namespace boost {
namespace fusion{
namespace detail{

    template<typename T,typename Keys>
    struct map_subset_traits{

        template<typename U>
        struct key_of{ typedef typename U::first_type type; };

        template<typename Key>
        struct contains : boost::mpl::contains<Keys,Key>{};

        // TODO check that it contains Keys
        //typedef typename boost::fusion::detail::extract_keys<
        //    T
        //>::type keys_superset;

        struct filter{
            template<typename U>
            struct apply : contains<typename key_of<U>::type>{};
        };

        typedef boost::fusion::filter_view<T,filter> view;
        typedef boost::fusion::filter_view<
            typename boost::add_const<T>::type,
            filter
        > view_const;

        template<typename Key>
        struct pair_of{
            typedef typename boost::fusion::result_of::at_key<T,Key>::type at_;
            typedef typename boost::remove_reference<at_>::type data_;
            typedef boost::fusion::pair<Key,data_> type;
        };

        typedef typename boost::mpl::fold<
            Keys,
            boost::mpl::vector0<>,
            boost::mpl::push_back<
                boost::mpl::_1,
                pair_of<boost::mpl::_2>
            >
        >::type pairs;

        typedef typename boost::fusion::detail::unpack_map<
            pairs
        >::type map;
    };

}// detail
}// fusion
}// boost

#endif


text:
/// @file track_collection.hpp A mutable collection of tracks with implicit sharing

#ifndef BIGGLES_TRACK_COLLECTION_HPP__
#define BIGGLES_TRACK_COLLECTION_HPP__

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

#include "detail/pair_collection.hpp"
#include "detail/track_pair_data.hpp"
#include "detail/transfer_possibility.hpp"
#include "detail/cross_over_possibility.hpp"
#include "track.hpp"

namespace biggles
{

/// @brief WIP: A collection of tracks.
///
/// Tracks are implicitly shared between collections.
///
/// FIXME: Is this a bottleneck for multi-threading?

class track_collection
{
public:
    /// @brief The internal container for the track collection.
    typedef std::set<shared_const_track_ptr> track_const_ptr_set;

    /// @brief Locate a track by its handle, throwing an exception if it isn't present.
    ///
    /// @param t A handle to the track.
    ///
    /// @return a const reference to the track associated with handle \p t.
    ///
    /// @throw std::runtime_error if \p t is not in the collection.
    const track& find(shared_const_track_ptr t) const;

    /// \brief checks if a track is in the collection
    bool contains(shared_const_track_ptr t) const { return tracks_.find(t) != tracks_.end(); }

    /// @brief Insert a new track into the collection.
    ///
    /// The track \p t is copied into the collection.
    ///
    /// @param t A reference to the track to copy into the collection.
    ///
    /// @return A handle for the newly inserted track and a flag indicating if the track was inserted.
    shared_const_track_ptr insert(const track& t);

    /// @brief Insert a new track into the collection from a \c boost::shared_ptr<>.
    ///
    /// This is a zero-copy version of insert() which inserts the track and increments the internal reference count of
    /// \p t_p.
    ///
    /// @param t_p A pointer to the track to insert.
    ///
    /// @return A handle to the newly inserted track.
    ///
    /// @throw std::runtime_error if the track pointed to by \p t_p is already in the collection.
    shared_const_track_ptr insert(const shared_const_track_ptr& t_p);

    /// @brief Remove a track from the collection, checking if the track is present.
    ///
    /// This is like remove() except that an exception is thrown if \p is not in the collection.
    ///
    /// @param track The handle of the track to remove.
    ///
    /// @throw std::runtime_error if \p track is not in the collection.
    void remove(const shared_const_track_ptr& track);

    /// @brief Replace a track in the collection with a new one.
    ///
    /// This is semantically identical to passing \p old_track to remove() and then passing \p new_track to insert()
    /// except that there may be a more efficient specialisation for particular types.
    ///
    /// @tparam Track Any type capable of being passed as the first argument to insert().
    /// @param old_track A handle to the track to be replaced.
    /// @param new_track A new track to take the place of \p old_track.
    ///
    /// @return A handle to the track which replaced \p old_track.
    template<typename Track>
    shared_const_track_ptr replace(const shared_const_track_ptr& old_track, Track new_track);

    /// @brief Replace a track in the collection with a new one, checking the old track is present.
    ///
    /// This is semantically identical to passing \p old_track to check_remove() and then passing \p new_track to
    /// insert() except that there may be a more efficient specialisation for particular types.
    ///
    /// @tparam Track Any type capable of being passed as the first argument to insert().
    /// @param old_track A handle to the track to be replaced.
    /// @param new_track A new track to take the place of \p old_track.
    ///
    /// @return A handle to the track which replaced \p old_track.
    ///
    /// @throw std::runtime_error if \p old_track is not in the collection.
    template<typename Track>
    shared_const_track_ptr check_replace(const shared_const_track_ptr& old_track, Track new_track);

    /// @brief Merge two tracks into one.
    ///
    /// @param track_1
    /// @param track_2
    /// @param dynamic_drag
    ///
    /// @return A handle to the new track formed from merging \p track_1 and \p track_2.
    shared_const_track_ptr merge(const shared_const_track_ptr& track_1, const shared_const_track_ptr& track_2, float dynamic_drag);

    /// @brief FIXME: UNIMPLEMENTED
    ///
    /// @param track
    /// @param at
    ///
    /// @return
    boost::tuple<shared_const_track_ptr, shared_const_track_ptr> split(shared_const_track_ptr track, size_t at);

    /// @brief Remove a track from the collection but return the shared pointer to it.
    ///
    /// This is like remove() but also returns a shared pointer to the removed track.
    ///
    /// @param track
    ///
    /// @throw std::runtime_error if \p track is not in the collection.
    shared_const_track_ptr pull_out(const shared_const_track_ptr& track);

    /// @name Iterating over tracks
    ///
    /// These member functions are provided to ease interaction with STL algorithms such as \p std::copy.
    ///
    /// @note There is no non-const iterator type because all mutation of the track set should be done by a member
    /// function. These iterators are provided for convenience only and should not be used to mutate the collection.
    /// @{

    /// @brief An const iterator type for iterating over all tracks.
    typedef track_const_ptr_set::const_iterator const_iterator;

    /// @brief An const iterator type for iterating over all tracks.
    typedef track_const_ptr_set::const_iterator iterator;

    /// @brief Query if there are no tracks in the collection.
    bool empty() const { return tracks_.empty(); }

    /// @brief Query the number of tracks in the collection.
    size_t size() const { return tracks_.size(); }

    /// @brief Return an iterator pointing to the first track.
    const_iterator begin() const { return tracks_.begin(); }

    /// @brief Return an iterator pointing just beyond the last track.
    const_iterator end() const { return tracks_.end(); }

    /// @}

    track_collection() { }

    /// @brief Copy constructor.
    ///
    /// @param c
    track_collection(const track_collection& c)
        : tracks_(c.tracks_)
    { }

protected:
    /// @brief The internal collection of track pointers.
    track_const_ptr_set tracks_;

    /// @brief Remove a track from the collection.
    ///
    /// @param track The handle of the track to remove.
    ///
    /// @return The number of tracks removed. This is 1 if \p track was removed and 0 if \p track could not be found
    /// within the collection.
    ///
    /// @sa remove()
    size_t unsafe_remove(const shared_const_track_ptr& track);

    /// @brief Locate a track by its handle.
    ///
    /// This function may be significantly faster than check_find() since it doesn't need to assert that the track is in
    /// the collection.
    ///
    /// @note This member function is unsafe in that no checks are made that \p t is in the collection.
    ///
    /// @sa find()
    ///
    /// @param t A handle to the track to find.
    ///
    /// @return a const reference to the track associated with handle \p t.
    ///
    /// @throw std::runtime_error if \p t is not in the collection.
    const track& unsafe_find(shared_const_track_ptr t) const { return *t; }

private:

    // To make a track collection non-assignable.
    const track_collection& operator = (const track_collection&);
};

template <class OBS_CONTAINER>
void ingest_observations(OBS_CONTAINER& container, const observation_collection& oc) {
    container.insert(container.end(), oc.begin(), oc.end());
}

template <class OBS_CONTAINER>
void ingest_observations(OBS_CONTAINER& container, const track_collection& tc) {
    BOOST_FOREACH(const shared_const_track_ptr& track_p, tc) {
        ingest_observations(container, track_p->observations());
    }
}

}

#define WITHIN_BIGGLES_TRACK_COLLECTION_HPP__
#include "track_collection.tcc"
#undef WITHIN_BIGGLES_TRACK_COLLECTION_HPP__

#endif // BIGGLES_TRACK_COLLECTION_HPP__

max_stars_repo_name: fbi-octopus/biggles

max_issues_repo_name: fbi-octopus/biggles

max_forks_repo_name: fbi-octopus/biggles


text:
#ifndef BOOST_CONTRACT_DETAIL_INLINED_OLD_HPP_
#define BOOST_CONTRACT_DETAIL_INLINED_OLD_HPP_

// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html

// IMPORTANT: Do NOT use config macros BOOST_CONTRACT_... in this file so lib
// .cpp does not need recompiling if config changes (recompile only user code).

#include <boost/contract/old.hpp>
#include <boost/contract/detail/declspec.hpp>

namespace boost { namespace contract {

BOOST_CONTRACT_DETAIL_DECLINLINE
old_value null_old() { return old_value(); }

BOOST_CONTRACT_DETAIL_DECLINLINE
old_pointer make_old(old_value const& old) {
    return old_pointer(0, old);
}

BOOST_CONTRACT_DETAIL_DECLINLINE
old_pointer make_old(virtual_* v, old_value const& old) {
    return old_pointer(v, old);
}

} } // namespacd

#endif // #include guard


text:
//
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//

#ifndef BOOST_BEAST_HTTP_FIELDS_HPP
#define BOOST_BEAST_HTTP_FIELDS_HPP

#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/string_param.hpp>
#include <boost/beast/core/string.hpp>
#include <boost/beast/core/detail/allocator.hpp>
#include <boost/beast/core/detail/empty_base_optimization.hpp>
#include <boost/beast/http/field.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/optional.hpp>
#include <algorithm>
#include <cctype>
#include <cstring>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>

namespace boost {
namespace beast {
namespace http {

/** A container for storing HTTP header fields.

    This container is designed to store the field value pairs that make
    up the fields and trailers in an HTTP message. Objects of this type
    are iterable, with each element holding the field name and field
    value.

    Field names are stored as-is, but comparisons are case-insensitive.
    The container behaves as a `std::multiset`; there will be a separate
    value for each occurrence of the same field name. When the container
    is iterated the fields are presented in the order of insertion, with
    fields having the same name following each other consecutively.

    Meets the requirements of @b Fields

    @tparam Allocator The allocator to use. This must meet the
    requirements of @b Allocator.
*/
template<class Allocator>
class basic_fields
#if ! BOOST_BEAST_DOXYGEN
    : private beast::detail::empty_base_optimization<Allocator>
#endif
{
    // Fancy pointers are not supported
    static_assert(std::is_pointer<typename
        std::allocator_traits<Allocator>::pointer>::value,
        "Allocator must use regular pointers");

    friend class fields_test; // for `header`

    static std::size_t constexpr max_static_buffer = 4096;

    using off_t = std::uint16_t;

public:
    /// The type of allocator used.
    using allocator_type = Allocator;

    /// The type of element used to represent a field
    class value_type
    {
        friend class basic_fields;

        boost::asio::const_buffer
        buffer() const;

        value_type(field name,
            string_view sname, string_view value);

        boost::intrusive::list_member_hook<
            boost::intrusive::link_mode<
                boost::intrusive::normal_link>>
                    list_hook_;
        boost::intrusive::set_member_hook<
            boost::intrusive::link_mode<
                boost::intrusive::normal_link>>
                    set_hook_;
        off_t off_;
        off_t len_;
        field f_;

    public:
        /// Constructor (deleted)
        value_type(value_type const&) = delete;

        /// Assignment (deleted)
        value_type& operator=(value_type const&) = delete;

        /// Returns the field enum, which can be @ref field::unknown
        field
        name() const;

        /// Returns the field name as a string
        string_view const
        name_string() const;

        /// Returns the value of the field
        string_view const
        value() const;
    };

    /** A strictly less predicate for comparing keys, using a case-insensitive comparison.

        The case-comparison operation is defined only for low-ASCII characters.
    */
    struct key_compare : beast::iless
    {
        /// Returns `true` if lhs is less than rhs using a strict ordering
        template<class String>
        bool
        operator()(
            String const& lhs,
            value_type const& rhs) const noexcept
        {
            if(lhs.size() < rhs.name_string().size())
                return true;
            if(lhs.size() > rhs.name_string().size())
                return false;
            return iless::operator()(lhs, rhs.name_string());
        }

        /// Returns `true` if lhs is less than rhs using a strict ordering
        template<class String>
        bool
        operator()(
            value_type const& lhs,
            String const& rhs) const noexcept
        {
            if(lhs.name_string().size() < rhs.size())
                return true;
            if(lhs.name_string().size() > rhs.size())
                return false;
            return iless::operator()(lhs.name_string(), rhs);
        }

        /// Returns `true` if lhs is less than rhs using a strict ordering
        bool
        operator()(
            value_type const& lhs,
            value_type const& rhs) const noexcept
        {
            if(lhs.name_string().size() < rhs.name_string().size())
                return true;
            if(lhs.name_string().size() > rhs.name_string().size())
                return false;
            return iless::operator()(lhs.name_string(), rhs.name_string());
        }
    };

    /// The algorithm used to serialize the header
#if BOOST_BEAST_DOXYGEN
    using writer = implementation_defined;
#else
    class writer;
#endif

private:
    using list_t = typename boost::intrusive::make_list<
        value_type, boost::intrusive::member_hook<
            value_type, boost::intrusive::list_member_hook<
                boost::intrusive::link_mode<
                    boost::intrusive::normal_link>>,
                        &value_type::list_hook_>,
                            boost::intrusive::constant_time_size<
                                false>>::type;

    using set_t = typename boost::intrusive::make_multiset<
        value_type, boost::intrusive::member_hook<value_type,
            boost::intrusive::set_member_hook<
                boost::intrusive::link_mode<
                    boost::intrusive::normal_link>>,
                        &value_type::set_hook_>,
                            boost::intrusive::constant_time_size<true>,
                                boost::intrusive::compare<key_compare>>::type;

    using align_type = typename
        boost::type_with_alignment<alignof(value_type)>::type;

    using rebind_type = typename
        beast::detail::allocator_traits<Allocator>::
            template rebind_alloc<align_type>;

    using alloc_traits =
        beast::detail::allocator_traits<rebind_type>;

    using size_type = typename
        beast::detail::allocator_traits<Allocator>::size_type;

public:
    /// Destructor
    ~basic_fields();

    /// Constructor.
    basic_fields() = default;

    /** Constructor.

        @param alloc The allocator to use.
    */
    explicit
    basic_fields(Allocator const& alloc) noexcept;

    /** Move constructor.

        The state of the moved-from object is
        as if constructed using the same allocator.
    */
    basic_fields(basic_fields&&) noexcept;

    /** Move constructor.

        The state of the moved-from object is
        as if constructed using the same allocator.

        @param alloc The allocator to use.
    */
    basic_fields(basic_fields&&, Allocator const& alloc);

    /// Copy constructor.
    basic_fields(basic_fields const&);

    /** Copy constructor.

        @param alloc The allocator to use.
    */
    basic_fields(basic_fields const&, Allocator const& alloc);

    /// Copy constructor.
    template<class OtherAlloc>
    basic_fields(basic_fields<OtherAlloc> const&);

    /** Copy constructor.

        @param alloc The allocator to use.
    */
    template<class OtherAlloc>
    basic_fields(basic_fields<OtherAlloc> const&,
        Allocator const& alloc);

    /** Move assignment.

        The state of the moved-from object is
        as if constructed using the same allocator.
    */
    basic_fields& operator=(basic_fields&&) noexcept(
        alloc_traits::propagate_on_container_move_assignment::value);

    /// Copy assignment.
    basic_fields& operator=(basic_fields const&);

    /// Copy assignment.
    template<class OtherAlloc>
    basic_fields& operator=(basic_fields<OtherAlloc> const&);

public:
    /// A constant iterator to the field sequence.
#if BOOST_BEAST_DOXYGEN
    using const_iterator = implementation_defined;
#else
    using const_iterator = typename list_t::const_iterator;
#endif

    /// A constant iterator to the field sequence.
    using iterator = const_iterator;

    /// Return a copy of the allocator associated with the container.
    allocator_type
    get_allocator() const
    {
        return this->member();
    }

    //--------------------------------------------------------------------------
    //
    // Element access
    //
    //--------------------------------------------------------------------------

    /** Returns the value for a field, or throws an exception.

        If more than one field with the specified name exists, the
        first field defined by insertion order is returned.

        @param name The name of the field.

        @return The field value.

        @throws std::out_of_range if the field is not found.
    */
    string_view const
    at(field name) const;

    /** Returns the value for a field, or throws an exception.

        If more than one field with the specified name exists, the
        first field defined by insertion order is returned.

        @param name The name of the field.

        @return The field value.

        @throws std::out_of_range if the field is not found.
    */
    string_view const
    at(string_view name) const;

    /** Returns the value for a field, or `""` if it does not exist.

        If more than one field with the specified name exists, the
        first field defined by insertion order is returned.

        @param name The name of the field.
    */
    string_view const
    operator[](field name) const;

    /** Returns the value for a case-insensitive matching header, or `""` if it does not exist.

        If more than one field with the specified name exists, the
        first field defined by insertion order is returned.

        @param name The name of the field.
    */
    string_view const
    operator[](string_view name) const;

    //--------------------------------------------------------------------------
    //
    // Iterators
    //
    //--------------------------------------------------------------------------

    /// Return a const iterator to the beginning of the field sequence.
    const_iterator
    begin() const
    {
        return list_.cbegin();
    }

    /// Return a const iterator to the end of the field sequence.
    const_iterator
    end() const
    {
        return list_.cend();
    }

    /// Return a const iterator to the beginning of the field sequence.
    const_iterator
    cbegin() const
    {
        return list_.cbegin();
    }

    /// Return a const iterator to the end of the field sequence.
    const_iterator
    cend() const
    {
        return list_.cend();
    }

    //--------------------------------------------------------------------------
    //
    // Capacity
    //
    //--------------------------------------------------------------------------

private:
    // VFALCO Since the header and message derive from Fields,
    //        what does the expression m.empty() mean? Its confusing.
    bool
    empty() const
    {
        return list_.empty();
    }
public:

    //--------------------------------------------------------------------------
    //
    // Modifiers
    //
    //--------------------------------------------------------------------------

    /** Remove all fields from the container

        All references, pointers, or iterators referring to contained
        elements are invalidated. All past-the-end iterators are also
        invalidated.

        @par Postconditions:
        @code
            std::distance(this->begin(), this->end()) == 0
        @endcode
    */
    void
    clear();

    /** Insert a field.

        If one or more fields with the same name already exist,
        the new field will be inserted after the last field with
        the matching name, in serialization order.

        @param name The field name.

        @param value The value of the field, as a @ref string_param
    */
    void
    insert(field name, string_param const& value);

    /** Insert a field.

        If one or more fields with the same name already exist,
        the new field will be inserted after the last field with
        the matching name, in serialization order.

        @param name The field name.

        @param value The value of the field, as a @ref string_param
    */
    void
    insert(string_view name, string_param const& value);

    /** Insert a field.

        If one or more fields with the same name already exist,
        the new field will be inserted after the last field with
        the matching name, in serialization order.

        @param name The field name.

        @param name_string The literal text corresponding to the
        field name. If `name != field::unknown`, then this value
        must be equal to `to_string(name)` using a case-insensitive
        comparison, otherwise the behavior is undefined.

        @param value The value of the field, as a @ref string_param
    */
    void
    insert(field name, string_view name_string,
        string_param const& value);

    /** Set a field value, removing any other instances of that field.

        First removes any values with matching field names, then
        inserts the new field value.

        @param name The field name.

        @param value The value of the field, as a @ref string_param

        @return The field value.
    */
    void
    set(field name, string_param const& value);

    /** Set a field value, removing any other instances of that field.

        First removes any values with matching field names, then
        inserts the new field value.

        @param name The field name.

        @param value The value of the field, as a @ref string_param
    */
    void
    set(string_view name, string_param const& value);

    /** Remove a field.

        References and iterators to the erased elements are
        invalidated. Other references and iterators are not
        affected.

        @param pos An iterator to the element to remove.

        @return An iterator following the last removed element.
        If the iterator refers to the last element, the end()
        iterator is returned.
    */
    const_iterator
    erase(const_iterator pos);

    /** Remove all fields with the specified name.

        All fields with the same field name are erased from the
        container.
        References and iterators to the erased elements are
        invalidated. Other references and iterators are not
        affected.

        @param name The field name.

        @return The number of fields removed.
    */
    std::size_t
    erase(field name);

    /** Remove all fields with the specified name.

        All fields with the same field name are erased from the
        container.
        References and iterators to the erased elements are
        invalidated. Other references and iterators are not
        affected.

        @param name The field name.

        @return The number of fields removed.
    */
    std::size_t
    erase(string_view name);

    /** Return a buffer sequence representing the trailers.

        This function returns a buffer sequence holding the
        serialized representation of the trailer fields promised
        in the Accept field. Before calling this function the
        Accept field must contain the exact trailer fields
        desired. Each field must also exist.
    */

    /// Swap this container with another
    void
    swap(basic_fields& other);

    /// Swap two field containers
    template<class Alloc>
    friend
    void
    swap(basic_fields<Alloc>& lhs, basic_fields<Alloc>& rhs);

    //--------------------------------------------------------------------------
    //
    // Lookup
    //
    //--------------------------------------------------------------------------

    /** Return the number of fields with the specified name.

        @param name The field name.
    */
    std::size_t
    count(field name) const;

    /** Return the number of fields with the specified name.

        @param name The field name.
    */
    std::size_t
    count(string_view name) const;

    /** Returns an iterator to the case-insensitive matching field.

        If more than one field with the specified name exists, the
        first field defined by insertion order is returned.

        @param name The field name.

        @return An iterator to the matching field, or `end()` if
        no match was found.
    */
    const_iterator
    find(field name) const;

    /** Returns an iterator to the case-insensitive matching field name.

        If more than one field with the specified name exists, the
        first field defined by insertion order is returned.

        @param name The field name.

        @return An iterator to the matching field, or `end()` if
        no match was found.
    */
    const_iterator
    find(string_view name) const;

    /** Returns a range of iterators to the fields with the specified name.

        @param name The field name.

        @return A range of iterators to fields with the same name,
        otherwise an empty range.
    */
    std::pair<const_iterator, const_iterator>
    equal_range(field name) const;

    /** Returns a range of iterators to the fields with the specified name.

        @param name The field name.

        @return A range of iterators to fields with the same name,
        otherwise an empty range.
    */
    std::pair<const_iterator, const_iterator>
    equal_range(string_view name) const;

    //--------------------------------------------------------------------------
    //
    // Observers
    //
    //--------------------------------------------------------------------------

    /// Returns a copy of the key comparison function
    key_compare
    key_comp() const
    {
        return key_compare{};
    }

protected:
    /** Returns the request-method string.

        @note Only called for requests.
    */
    string_view
    get_method_impl() const;

    /** Returns the request-target string.

        @note Only called for requests.
    */
    string_view
    get_target_impl() const;

    /** Returns the response reason-phrase string.

        @note Only called for responses.
    */
    string_view
    get_reason_impl() const;

    /** Returns the chunked Transfer-Encoding setting
    */
    bool
    get_chunked_impl() const;

    /** Returns the keep-alive setting
    */
    bool
    get_keep_alive_impl(unsigned version) const;

    /** Returns `true` if the Content-Length field is present.
    */
    bool
    has_content_length_impl() const;

    /** Set or clear the method string.

        @note Only called for requests.
    */
    void
    set_method_impl(string_view s);

    /** Set or clear the target string.

        @note Only called for requests.
    */
    void
    set_target_impl(string_view s);

    /** Set or clear the reason string.

        @note Only called for responses.
    */
    void
    set_reason_impl(string_view s);

    /** Adjusts the chunked Transfer-Encoding value
    */
    void
    set_chunked_impl(bool value);

    /** Sets or clears the Content-Length field
    */
    void
    set_content_length_impl(
        boost::optional<std::uint64_t> const& value);

    /** Adjusts the Connection field
    */
    void
    set_keep_alive_impl(
        unsigned version, bool keep_alive);

private:
    template<class OtherAlloc>
    friend class basic_fields;

    value_type&
    new_element(field name,
        string_view sname, string_view value);

    void
    delete_element(value_type& e);

    void
    set_element(value_type& e);

    void
    realloc_string(string_view& dest, string_view s);

    void
    realloc_target(
        string_view& dest, string_view s);

    template<class OtherAlloc>
    void
    copy_all(basic_fields<OtherAlloc> const&);

    void
    clear_all();

    void
    delete_list();

    void
    move_assign(basic_fields&, std::true_type);

    void
    move_assign(basic_fields&, std::false_type);

    void
    copy_assign(basic_fields const&, std::true_type);

    void
    copy_assign(basic_fields const&, std::false_type);

    void
    swap(basic_fields& other, std::true_type);

    void
    swap(basic_fields& other, std::false_type);

    set_t set_;
    list_t list_;
    string_view method_;
    string_view target_or_reason_;
};

/// A typical HTTP header fields container
using fields = basic_fields<std::allocator<char>>;

} // http
} // beast
} // boost

#include <boost/beast/http/impl/fields.ipp>

#endif