text:
// Copyright (c) 2010, Adam Petersen <adam@adampetersen.se>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY Adam Petersen ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Adam Petersen OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "tinch_pp/node.h"
#include "tinch_pp/mailbox.h"
#include "tinch_pp/erlang_types.h"
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/assign/list_of.hpp>
#include <iostream>
#include <stdexcept>

using namespace tinch_pp;
using namespace tinch_pp::erl;
using namespace boost;
using namespace boost::assign;

// USAGE:
// ======
// 1. Start an Erlang node with the cookie abcdef.
// 2. Start the Erlang program reflect_msg:
//          (testnode@127.0.0.1)4> reflect_msg:start_link().
// 3. Start this program. The program will send different messages
// to reflect_msg, which echoes the messages back.
//
// DESCRIPTION:
// ============
// This testcase sends different types of data to an echo-process.
// The reply is first matched on erl::any, which is expected to
// always succeed. Then, a submatch is performed on the value
// assigned by the any-match.
namespace {

void match_any_atom(mailbox_ptr mbox);

void match_any_binary(mailbox_ptr mbox);

void match_any_bitstring(mailbox_ptr mbox);

void match_any_negative_int(mailbox_ptr mbox);

void match_any_small_int(mailbox_ptr mbox);

void match_any_medium_int(mailbox_ptr mbox);

void match_any_nested_tuples(mailbox_ptr mbox);

void match_any_list(mailbox_ptr mbox);

void match_any_small_list(mailbox_ptr mbox);

void match_any_empty_tuple(mailbox_ptr mbox);

void match_any_string(mailbox_ptr mbox);

void match_any_float(mailbox_ptr mbox);

void match_any_binary(mailbox_ptr mbox);

typedef boost::function<void (mailbox_ptr)> sender_fn_type;

}

int main()
{
  node_ptr my_node = node::create("net_adm_test_node@127.0.0.1", "abcdef");

  mailbox_ptr mbox = my_node->create_mailbox();

  const sender_fn_type senders[] = {bind(match_any_atom, ::_1),
                                    bind(match_any_binary, ::_1),
                                    bind(match_any_bitstring, ::_1),
                                    bind(match_any_negative_int, ::_1),
                                    bind(match_any_small_int, ::_1),
                                    bind(match_any_medium_int, ::_1),
                                    bind(match_any_nested_tuples, ::_1),
                                    bind(match_any_empty_tuple, ::_1),
                                    bind(match_any_list, ::_1),
                                    bind(match_any_small_list, ::_1),
                                    bind(match_any_string, ::_1),
                                    bind(match_any_float, ::_1),
                                    bind(match_any_binary, ::_1)};
  const size_t number_of_senders = sizeof senders / sizeof senders[0];

  for(size_t i = 0; i < number_of_senders; ++i)
    senders[i](mbox);
}

namespace {

const std::string remote_node_name("testnode@127.0.0.1");
const std::string to_name("reflect_msg");

matchable_ptr receive_any(mailbox_ptr mbox)
{
  const matchable_ptr reply = mbox->receive();

  matchable_ptr any_result;

  if(!reply->match(erl::any(&any_result)))
    throw std::runtime_error("Failed to match on 'any' - must succeed => internal error!");

  return any_result;
}

// All messages have the following format: {echo, self(), Msg}

void match_any_atom(mailbox_ptr mbox)
{
  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()), atom("hello")));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(atom("hello")))
    std::cout << "Matched any atom(hello)" << std::endl;
  else
    std::cerr << "match_any_atom: No match - unexpected message!" << std::endl;
}

void match_any_binary(mailbox_ptr mbox)
{
  const msg_seq byte_stream = list_of(1)(2)(3)(42);
  const binary_value_type data(byte_stream);

  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()), binary(data)));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(binary(data)))
    std::cout << "Matched any binary <<1,2,3,42>>" << std::endl;
  else
    std::cerr << "match_any_binary: No match - unexpected message!" << std::endl;
}

void match_any_bitstring(mailbox_ptr mbox)
{
  const msg_seq byte_stream = list_of(1)(2)(3)(32);
  const int padding_bits    = 5;
  const binary_value_type data(byte_stream, padding_bits);

  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()), binary(data)));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(binary(data)))
    std::cout << "Matched any binary bitstring <<1,2,3,32:5>>" << std::endl;
  else
    std::cerr << "match_any_bintstring: No match - unexpected message!" << std::endl;
}

void match_any_negative_int(mailbox_ptr mbox)
{
  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()), int_(-1)));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(int_(-1)))
    std::cout << "Matched any int_(-1)" << std::endl;
  else
    std::cerr << "match_any_negative_int: No match - unexpected message!" << std::endl;
}

void match_any_small_int(mailbox_ptr mbox)
{
  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()), int_(2)));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(int_(2)))
    std::cout << "Matched any int_(2)" << std::endl;
  else
    std::cerr << "match_any_small_int: No match - unexpected message!" << std::endl;
}

// NOTE: Erlang supports big ints too, but I haven't implemented them yet.
void match_any_medium_int(mailbox_ptr mbox)
{
  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()), int_(10000)));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(int_(10000)))
    std::cout << "Matched any int_(10000)" << std::endl;
  else
    std::cerr << "match_any_medium_int: No match - unexpected message!" << std::endl;
}

void match_any_nested_tuples(mailbox_ptr mbox)
{
  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()),
                                                     make_e_tuple(atom("next"),
                                                     make_e_tuple(atom("nested"), int_(42)))));
  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(make_e_tuple(atom("next"), make_e_tuple(atom("nested"), int_(42)))))
    std::cout << "Matched any {next, {nested, 42}}" << std::endl;
  else
    std::cerr << "match_any_nested_tuples: No match - unexpected message!" << std::endl;
}

void match_any_empty_tuple(mailbox_ptr mbox)
{
  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()), make_e_tuple()));
  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(make_e_tuple()))
    std::cout << "Matched any empty tuple {}" << std::endl;
  else
    std::cerr << "match_any_empty_tuple: No match - unexpected message!" << std::endl;
}

void match_any_string(mailbox_ptr mbox)
{
  const std::string value_to_match = "my string";

  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()),
                                                     make_e_tuple(atom("next"), e_string(value_to_match))));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(make_e_tuple(atom("next"), e_string(value_to_match))))
    std::cout << "Matched any string {start, " << value_to_match << "}" << std::endl;
  else
    std::cerr << "match_any_string: No match - unexpected message!" << std::endl;
}

void match_any_float(mailbox_ptr mbox)
{
  const double value = 1234567.98765;
  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()),
                                                     make_e_tuple(atom("next"), float_(value))));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(make_e_tuple(atom("next"), float_(value))))
    std::cout << "Matched float {start, " << value << "}" << std::endl;
  else
    std::cerr << "match_any_float: No match - unexpected message!" << std::endl;
}

void match_any_list(mailbox_ptr mbox)
{
  const std::list<erl::object_ptr> send_numbers = list_of(make_int(1))(make_int(2))(make_int(1000));

  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()),
                                                     make_e_tuple(atom("numbers"), make_list(send_numbers))));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(make_e_tuple(atom("numbers"), make_list(send_numbers))))
    std::cout << "Matched any {numbers, List} with List size = " << send_numbers.size() << std::endl;
  else
    std::cerr << "match_any_list: No match - unexpected message!" << std::endl;
}

void match_any_small_list(mailbox_ptr mbox)
{
  const std::list<int_> send_numbers = list_of(int_(1))(int_(2))(int_(3));

  mbox->send(to_name, remote_node_name, make_e_tuple(atom("echo"), pid(mbox->self()),
                                                     make_e_tuple(atom("small_list"), make_list(send_numbers))));

  const matchable_ptr reply = receive_any(mbox);

  if(reply->match(make_e_tuple(atom("small_list"), make_list(send_numbers))))
    std::cout << "Matched any {small_list, List} with List size = " << send_numbers.size() << std::endl;
  else
    std::cerr << "match_any_small_list: No match - unexpected message!" << std::endl;
}

}


text:
// Copyright @2012 JDSU Xtreme

#define XTREME_REFDATA_INTERNAL_RDHELPER_PROTOCOL_H_IMPL_ 1
#include "xtreme/refdata/internal/rdhelper_protocol.h"

#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/assign/list_of.hpp>

#include <ctime>

namespace xtreme {
  namespace refdata {
    const std::string RDHelper_Protocol_v1p0::s_DefColsHeader =
        "PROTONUM,SRCPORT,DSTPORT,PORT,TRANSPORTPROTO,APPNPROTO";
    // 's_NullDummyRecLine' MUST be in-SYNC with above def-col-header
    const std::string RDHelper_Protocol_v1p0::s_NullDummyRecLine = "0,0,0,0,,";

    typedef boost::bimap<PROTOCOL_REC::PROTOCOL_COLTYPE, std::string> EnumMap_PROTOCOL_COLTYPE_T;
    const EnumMap_PROTOCOL_COLTYPE_T EnumMap_PROTOCOL_COLTYPE =
        boost::assign::list_of<EnumMap_PROTOCOL_COLTYPE_T::relation>
        (PROTOCOL_REC::PROTOCOL_COL_CUSTOM_IGNORE, "CUSTOM")
        (PROTOCOL_REC::PROTOCOL_COL_PROTONUM, "PROTONUM")
        (PROTOCOL_REC::PROTOCOL_COL_SRCPORT, "SRCPORT")
        (PROTOCOL_REC::PROTOCOL_COL_DSTPORT, "DSTPORT")
        (PROTOCOL_REC::PROTOCOL_COL_PORT, "PORT")
        (PROTOCOL_REC::PROTOCOL_COL_TRANSPORTPROTO, "TRANSPORTPROTO")
        (PROTOCOL_REC::PROTOCOL_COL_APPNPROTO, "APPNPROTO");

    RDHelper * getRDHelper_Protocol(const uint32_t fmtMajor,
        const uint32_t fmtMinor) {
      RDHelper * pHelper = nullptr;

      switch (fmtMajor) {
      case 1:
        switch (fmtMinor) {
        case 0:
          pHelper = new RDHelper_Protocol_v1p0();
          break;
        default:
          break;
        }
        break;

      default:
        break;
      }

      return pHelper;
    }

    RDHelper_Protocol_v1p0::RDHelper_Protocol_v1p0() :
            RDHelper(PROTOCOL_T, 1, 0,
                RDHelper_Protocol_v1p0::s_DefColsHeader,
                RDHelper_Protocol_v1p0::s_NullDummyRecLine) {
    }

    iptr_RDRecord_t RDHelper_Protocol_v1p0::read(
        const std::string& csvRecLine) {
      // std::cout << "RDHelper_Protocol_v1p0::operator<<(" << csvRecLine << ")" << std::endl;
      bool validRec = false;
      std::vector < std::string > retTokens;
      getTokens(csvRecLine, retTokens);

      // Each CSV record MUST be as per the column-header definition
      if (retTokens.size() != m_ColumsByID.size())
        throw InvalidRecErr(
            "INCORRECT Reference Data Format [" + csvRecLine + "]");

      // Gather/Prepare PROTOCOL_REC fields from input csvRecLine
      // TODO(Shilpa): Should case-insensitive strings field(s) be transformed and stored as uppercase?
      nPROTONUM_t _protoNum = 0;
      nPORT_t _srcPort = 0;
      nPORT_t _dstPort = 0;
      nPORT_t _port = 0;
      nPORT_t _srcPortUL = 0;
      nPORT_t _dstPortUL = 0;
      nPORT_t _portUL = 0;
      TRANSPORTPROTO_t _transportProto;
      APPNPROTO_t _appnProto;
      uint32_t tmpProtoNum;

      PROTOCOL_REC::AvailCols_t _unknownCols;

      for (unsigned int ind = 0; ind < m_ColumsByID.size(); ind++) {
        PROTOCOL_REC::PROTOCOL_COLTYPE aColType = m_ColumsByID[ind];
        std::string aColVal = retTokens[ind];
        bool isUnknown = false;

        switch (aColType) {
        case PROTOCOL_REC::PROTOCOL_COL_CUSTOM_IGNORE:
          // TODO(Shilpa): Should we store ignored fields in record from here ?
          break;

        case PROTOCOL_REC::PROTOCOL_COL_PROTONUM:
          tmpProtoNum = boost::lexical_cast<uint32_t>(aColVal);
          _protoNum = (nPROTONUM_t) tmpProtoNum;
          break;

        case PROTOCOL_REC::PROTOCOL_COL_SRCPORT:
          if (validatePortAndUpdateRec(aColVal, _srcPort, _srcPortUL) == false)
            throw InvalidRecErr(
                "INCORRECT Reference Data Format [" + csvRecLine + "]");
          //  _srcPort = boost::lexical_cast<nPORT_t>(aColVal);

          break;

        case PROTOCOL_REC::PROTOCOL_COL_DSTPORT:
          if (validatePortAndUpdateRec(aColVal, _dstPort, _dstPortUL) == false)
            throw InvalidRecErr(
                "INCORRECT Reference Data Format [" + csvRecLine + "]");
          // _dstPort = boost::lexical_cast<nPORT_t>(aColVal);
          break;

        case PROTOCOL_REC::PROTOCOL_COL_PORT:
          if (validatePortAndUpdateRec(aColVal, _port, _portUL) == false)
            throw InvalidRecErr(
                "INCORRECT Reference Data Format [" + csvRecLine + "]");
          // _port = boost::lexical_cast<nPORT_t>(aColVal);
          break;

        case PROTOCOL_REC::PROTOCOL_COL_TRANSPORTPROTO:
          {
          isUnknown = READ_REFDATA_STRING(_transportProto, aColVal);
        }
          break;

        case PROTOCOL_REC::PROTOCOL_COL_APPNPROTO:
          {
          isUnknown = READ_REFDATA_STRING(_appnProto, aColVal);
        }
          break;

        default:
          break;
        }
        if (((size_t) aColType) < _unknownCols.size())
          _unknownCols.set(aColType, isUnknown);
      }

      // One of the port field values should be non zero
      if ((_srcPort != 0 && _dstPort == 0 && _port == 0) ||
          (_dstPort != 0 && _srcPort == 0 && _port == 0) ||
          (_port != 0 && _srcPort == 0 && _dstPort == 0) ||
          (_port == 0 && _srcPort == 0 && _dstPort == 0)) {
        validRec = true;
      }

      if (validRec == false)
        throw InvalidRecErr(
            "INCORRECT PORT VALUES in Record. Only one port value should be non-zero value ["
                + csvRecLine + "]");

      PROTOCOL_REC * pRec = new xtreme::refdata::PROTOCOL_REC(
          _protoNum,
          _srcPort,
          _dstPort,
          _port,
          _srcPortUL,
          _dstPortUL,
          _portUL,
          _transportProto,
          _appnProto);
      pRec->m_unknownCols = _unknownCols;
      iptr_RDRecord_t iptrRec(pRec);

      return iptrRec;
    }

    void RDHelper_Protocol_v1p0::getCSVDataStream(iptr_RDRecord_t _ipRec,
        std::stringstream& _csvDataSStream,
        bool useColumnsHeader) {
      // TODO(Shilpa):
      // Use the m_ColumsByID to generate CSV in user given format (if useColumnsHeader == true)
      // Else use 's_DefColsHeader'
      PROTOCOL_REC * pProtocolRec = refdata_downcast<PROTOCOL_REC, RDRecord>(
          _ipRec.get());

      if (nullptr == pProtocolRec)
        return;

      if (m_ColumsByID.size() <= 0)
        return;

      // outputCol(m_ColumsByID[0], _csvDataSStream, pProtocolRec);
      _csvDataSStream << outputCol(m_ColumsByID[0], pProtocolRec);
      for (unsigned int ind = 1; ind < m_ColumsByID.size(); ind++) {
        _csvDataSStream << RDHelper::CSV_SEPARATOR;
        // outputCol(m_ColumsByID[ind], _csvDataSStream, pProtocolRec);
        // _csvDataSStream << outputCol(m_ColumsByID[ind], pProtocolRec);
        WRITE_REFDATA_QUOTED_STRING(outputCol(m_ColumsByID[ind], pProtocolRec),
            _csvDataSStream);
      }

      _csvDataSStream << std::endl;   // One record per CSV-line
      return;
    }

    // void RDHelper_Protocol_v1p0::outputCol(PROTOCOL_REC::PROTOCOL_COLTYPE aColType,
    //    std::stringstream& _csvDataSStream,
    //    PROTOCOL_REC * pProtocolRec) {
    // }

    // 'aColType' value should be a valid enum value from ... PROTOCOL_REC::PROTOCOL_COLTYPE
    std::string RDHelper_Protocol_v1p0::outputCol(int32_t aColType,
        RDRecord * pRDRec) {
      PROTOCOL_REC * pProtocolRec = refdata_downcast<PROTOCOL_REC, RDRecord>(
          pRDRec);
      if (nullptr == pProtocolRec)
        return "";

      // During output ... transform non-string (like BCDs etc. to string)
      std::string _retStr("");

      switch (aColType) {
      case PROTOCOL_REC::PROTOCOL_COL_CUSTOM_IGNORE:
        // TODO(Shilpa): Should we store ignored fields in record and also output them here ?
        break;

      case PROTOCOL_REC::PROTOCOL_COL_PROTONUM:
        _retStr = boost::lexical_cast<std::string>
                  ((uint16_t) (pProtocolRec->m_protoNum));
        break;

      case PROTOCOL_REC::PROTOCOL_COL_SRCPORT:
        _retStr = boost::lexical_cast<std::string>(pProtocolRec->m_srcPort);
        if (pProtocolRec->m_srcPortUL > 0) {
          _retStr.append("-");
          _retStr.append(
              boost::lexical_cast<std::string>(pProtocolRec->m_srcPortUL));
        }
        break;

      case PROTOCOL_REC::PROTOCOL_COL_DSTPORT:
        _retStr = boost::lexical_cast<std::string>(pProtocolRec->m_dstPort);
        if (pProtocolRec->m_dstPortUL > 0) {
          _retStr.append("-");
          _retStr.append(
              boost::lexical_cast<std::string>(pProtocolRec->m_dstPortUL));
        }
        break;

      case PROTOCOL_REC::PROTOCOL_COL_PORT:
        _retStr = boost::lexical_cast<std::string>(pProtocolRec->m_port);
        if (pProtocolRec->m_portUL > 0) {
          _retStr.append("-");
          _retStr.append(
              boost::lexical_cast<std::string>(pProtocolRec->m_portUL));
        }
        break;

      case PROTOCOL_REC::PROTOCOL_COL_TRANSPORTPROTO:
        {
        WRITE_REFDATA_STRING(_retStr, pProtocolRec->m_transportProto,
            pProtocolRec->m_unknownCols.test(aColType));
      }
        break;

      case PROTOCOL_REC::PROTOCOL_COL_APPNPROTO:
        {
        WRITE_REFDATA_STRING(_retStr, pProtocolRec->m_appnProto,
            pProtocolRec->m_unknownCols.test(aColType));
      }
        break;

      default:
        break;
      }
      return _retStr;
    }

    bool RDHelper_Protocol_v1p0::validateColumnDefinition() {
      // TODO(Shilpa): Implement if user supplied column definition (in CSV) is to be supported...
      return true;
    }

    bool RDHelper_Protocol_v1p0::chkBuildColsList() {
      try {
        m_ColumsByID.clear();
        m_ColumsByID.resize(m_cols.size());
        for (unsigned int ind = 0; ind < m_cols.size(); ind++) {
          m_ColumsByID[ind] = EnumMap_PROTOCOL_COLTYPE.right.at(m_cols[ind]);  // might throw 'out_of_range'
        }
        return validateColumnDefinition();
      } catch(...) {
        return false;  // Unacceptable Column-Header ... contains UNKNOWN/UNDEFINED column(s)
      }
    }
    bool RDHelper_Protocol_v1p0::validatePortAndUpdateRec(
        std::string& portNumStr, nPORT_t& portNumLL, nPORT_t& portNumUL) {
      if (portNumStr.empty()) {
        portNumLL = 0;
        portNumUL = 0;
        return true;
      }
      static boost::regex regexp_portRange(
          "\\s*(?<LWR>\\d+)((-(?<UPR>\\d+)){0,1})\\s*");
      boost::cmatch matches;

      if (boost::regex_match(portNumStr.c_str(), matches, regexp_portRange)) {
        std::string uprLmtStr(matches["UPR"].first, matches["UPR"].second);
        std::string lwrLmtStr(matches["LWR"].first, matches["LWR"].second);

        if (!lwrLmtStr.empty()) {
          portNumLL = boost::lexical_cast<uint16_t>(lwrLmtStr);
          if (!uprLmtStr.empty()) {
            portNumUL = boost::lexical_cast<uint16_t>(uprLmtStr);
            if (portNumLL > portNumUL)
              return false;
          }
          if (portNumLL > MAX_PORT_NUM || portNumUL > MAX_PORT_NUM)
            return false;
        } else {
          return false;
        }
      } else {
        return false;
      }

      return true;
    }
  }
}  // end of namespace xtreme

ext: cc


text:
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2006, 2007 Ferdinando Ametrano
 Copyright (C) 2006 Katiuscia Manzoni
 Copyright (C) 2005 Eric Ehlers
 Copyright (C) 2005 Plamen Neykov

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/license.shtml>.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

#if defined(HAVE_CONFIG_H)
    #include <qlo/config.hpp>
#endif

#include <qlo/indexes/ibor/libor.hpp>

#include <ql/indexes/ibor/eurlibor.hpp>
#include <ql/indexes/ibor/usdlibor.hpp>
#include <ql/indexes/ibor/gbplibor.hpp>
#include <ql/indexes/ibor/sonia.hpp>
#include <ql/indexes/ibor/chflibor.hpp>
#include <ql/indexes/ibor/jpylibor.hpp>

#include <ql/utilities/dataparsers.hpp>

#include <boost/algorithm/string/case_conv.hpp>
using boost::algorithm::to_upper_copy;
using ObjectHandler::ValueObject;
using boost::shared_ptr;

namespace QuantLibAddin {

    Libor::Libor(const shared_ptr<ValueObject>& properties,
                 const QuantLib::Currency& currency,
                 const std::string& p,
                 const QuantLib::Handle<QuantLib::YieldTermStructure>& h,
                 bool permanent) : IborIndex(properties, permanent)
    {
        switch (currency.numericCode()) {
          case 978: // EUR
            if (to_upper_copy(p)=="ON")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorEURLibor(0, h));
            else if (to_upper_copy(p)=="1D")
                QL_FAIL("1D is ambigous: please specify ON, TN, or SN");
            else if (to_upper_copy(p)=="TN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorEURLibor(1, h));
            else if (to_upper_copy(p)=="SN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorEURLibor(2, h));
            else if (to_upper_copy(p)=="SW")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::EURLibor(1*QuantLib::Weeks, h));
            else {
                QuantLib::Period pp = QuantLib::PeriodParser::parse(p);
                pp.normalize();
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::EURLibor(pp, h));
            }
            break;
          case 840: // USD
            if (to_upper_copy(p)=="ON")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorUSDLibor(0, h));
            else if (to_upper_copy(p)=="1D")
                QL_FAIL("1D is ambigous: please specify ON, TN, or SN");
            else if (to_upper_copy(p)=="TN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorUSDLibor(1, h));
            else if (to_upper_copy(p)=="SN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorUSDLibor(2, h));
            else if (to_upper_copy(p)=="SW")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::USDLibor(1*QuantLib::Weeks, h));
            else {
                QuantLib::Period pp = QuantLib::PeriodParser::parse(p);
                pp.normalize();
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::USDLibor(pp, h));
            }
            break;
          case 826: // GBP
            if (to_upper_copy(p)=="ON")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorGBPLibor(0, h));
            else if (to_upper_copy(p)=="1D")
                QL_FAIL("1D is ambigous: please specify ON, TN, or SN");
            else if (to_upper_copy(p)=="TN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorGBPLibor(1, h));
            else if (to_upper_copy(p)=="SN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorGBPLibor(2, h));
            else if (to_upper_copy(p)=="SW")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::GBPLibor(1*QuantLib::Weeks, h));
            else {
                QuantLib::Period pp = QuantLib::PeriodParser::parse(p);
                pp.normalize();
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::GBPLibor(pp, h));
            }
            break;
          case 756: // CHF
            if (to_upper_copy(p)=="ON")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorCHFLibor(0, h));
            else if (to_upper_copy(p)=="1D")
                QL_FAIL("1D is ambigous: please specify ON, TN, or SN");
            else if (to_upper_copy(p)=="TN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorCHFLibor(1, h));
            else if (to_upper_copy(p)=="SN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorCHFLibor(2, h));
            else if (to_upper_copy(p)=="SW")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::CHFLibor(1*QuantLib::Weeks, h));
            else {
                QuantLib::Period pp = QuantLib::PeriodParser::parse(p);
                pp.normalize();
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::CHFLibor(pp, h));
            }
            break;
          case 392: // JPY
            if (to_upper_copy(p)=="ON")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorJPYLibor(0, h));
            else if (to_upper_copy(p)=="1D")
                QL_FAIL("1D is ambigous: please specify ON, TN, or SN");
            else if (to_upper_copy(p)=="TN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorJPYLibor(1, h));
            else if (to_upper_copy(p)=="SN")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::DailyTenorJPYLibor(2, h));
            else if (to_upper_copy(p)=="SW")
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::JPYLibor(1*QuantLib::Weeks, h));
            else {
                QuantLib::Period pp = QuantLib::PeriodParser::parse(p);
                pp.normalize();
                libraryObject_ = shared_ptr<QuantLib::IborIndex>(new
                    QuantLib::JPYLibor(pp, h));
            }
            break;
          default:
              QL_FAIL("Unhandled currency " << currency);
        }
    }

    Sonia::Sonia(const shared_ptr<ValueObject>& properties,
                 const QuantLib::Handle<QuantLib::YieldTermStructure>& h,
                 bool permanent)
    : OvernightIndex(properties, permanent)
    {
        libraryObject_ = shared_ptr<QuantLib::Sonia>(new
            QuantLib::Sonia(h));
    }

}

ext: cpp


text:
/**
 * Copyright (c) 2017-present, Facebook, Inc. and its affiliates.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 */
#include "logdevice/common/buffered_writer/BufferedWriterOptionsUtil.h"
#include <boost/program_options.hpp>
#include "logdevice/common/commandline_util_chrono.h"

using namespace boost::program_options;

namespace facebook { namespace logdevice {

void describeBufferedWriterOptions(options_description& po,
                                   BufferedWriter::Options* opts,
                                   std::string prefix) {
  static_assert(sizeof(BufferedWriter::Options) == 7 * 8,
                "If you added fields to BufferedWriter::Options, you may want "
                "to add them here as well.");

  po.add_options()(
      (prefix + "time-trigger").c_str(),
      chrono_value(&opts->time_trigger),
      "Flush buffered writes for a log when the oldest has been buffered this "
      "long (negative for no trigger).");
  po.add_options()(
      (prefix + "size-trigger").c_str(),
      value<std::string>()
          ->default_value(std::to_string(opts->size_trigger))
          ->notifier([prefix, opts](const std::string& val) {
            if (val == "-1") {
              opts->size_trigger = -1;
              return;
            }
            uint64_t x;
            if (parse_scaled_int(val.c_str(), &x) != 0) {
              throw boost::program_options::error("Invalid " + prefix +
                                                  "size-trigger: " + val);
            }
            opts->size_trigger = x;
          }),
      "Flush buffered writes for a log as soon there are this many payload "
      "bytes buffered (negative for no trigger).");
  po.add_options()(
      (prefix + "mode").c_str(),
      value<std::string>()
          ->default_value(BufferedWriter::LogOptions::modeToString(opts->mode))
          ->notifier([prefix, opts](const std::string& val) {
            if (BufferedWriter::LogOptions::parseMode(
                    val.c_str(), &opts->mode) != 0) {
              throw boost::program_options::error("Invalid " + prefix +
                                                  "mode: " + val);
            }
          }),
      "'independent' to write each buffered append independently. "
      "'one_at_a_time' to write sequentially, avoiding reordering.");
  po.add_options()(
      (prefix + "retry-count").c_str(),
      value<int>(&opts->retry_count)->default_value(opts->retry_count),
      "Max number of times to retry. 0 for no retrying, negative for "
      "unlimited.");
  po.add_options()(
      (prefix + "retry-initial-delay").c_str(),
      chrono_value(&opts->retry_initial_delay),
      "Initial delay before retrying (negative for a default 2x the append "
      "timeout).  Subsequent retries are made after successively larger delays"
      "(exponential backoff with a factor of 2) up to retry-max-delay.");
  po.add_options()((prefix + "retry-max-delay").c_str(),
                   chrono_value(&opts->retry_max_delay),
                   "Max delay when retrying (negative for no limit).");
  po.add_options()(
      (prefix + "compression").c_str(),
      value<std::string>()
          ->default_value(compressionToString(opts->compression))
          ->notifier([prefix, opts](const std::string& val) {
            if (BufferedWriter::LogOptions::parseCompression(
                    val.c_str(), &opts->compression) != 0) {
              throw boost::program_options::error("Invalid " + prefix +
                                                  "compression: " + val);
            }
          }),
      "Algorithm to use for client-side compression in Buffered writer. 'none' "
      "for no compression. Supported values: 'zstd', 'lz4', 'lz4_hc'.");
  po.add_options()((prefix + "memory-limit-mb").c_str(),
                   value<int32_t>(&opts->memory_limit_mb)
                       ->default_value(opts->memory_limit_mb),
                   "Approximate memory budget for buffered and inflight "
                   "writes, in megabytes.");
}

std::string BufferedWriter::LogOptions::modeToString(Mode mode) {
  switch (mode) {
    case Mode::INDEPENDENT:
      return "independent";
    case Mode::ONE_AT_A_TIME:
      return "one_at_a_time";
  }
  ld_check(false);
  return "(internal error)";
}

int BufferedWriter::LogOptions::parseMode(const char* str, Mode* out_mode) {
  Mode mode;
  if (!strcmp(str, "independent")) {
    mode = Mode::INDEPENDENT;
  } else if (!strcmp(str, "one_at_a_time")) {
    mode = Mode::ONE_AT_A_TIME;
  } else {
    return -1;
  }
  if (out_mode) {
    *out_mode = mode;
  }
  return 0;
}

std::string BufferedWriter::LogOptions::compressionToString(Compression c) {
  return facebook::logdevice::compressionToString(c);
}

int BufferedWriter::LogOptions::parseCompression(const char* str,
                                                 Compression* out_c) {
  return facebook::logdevice::parseCompression(str, out_c);
}

}} // namespace facebook::logdevice

max_stars_repo_name: SimonKinds/LogDevice


text:
/*
* File:   config.hpp
* Author: Paul Kirth
*
* Created on June 18, 2013, 7:30 PM

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/

#if !defined(BOOST_AFIO_HEADERS_ONLY) && !defined(BOOST_ALL_DYN_LINK)
#define BOOST_AFIO_HEADERS_ONLY 1
#endif

// Fix up mingw weirdness
#if !defined(WIN32) && defined(_WIN32)
# define WIN32 1
#endif
// Boost ASIO needs this
#if !defined(_WIN32_WINNT) && defined(WIN32)
# define _WIN32_WINNT 0x0501
#endif
#if defined(WIN32) && _WIN32_WINNT<0x0501
# error _WIN32_WINNT must at least be set to Windows XP for Boost ASIO to compile
#endif
// Get Mingw to assume we are on at least Windows 2000
#if __MSVCRT_VERSION__ < 0x601
# undef __MSVCRT_VERSION__
# define __MSVCRT_VERSION__ 0x601
#endif
// Pull in detection of __MINGW64_VERSION_MAJOR
#ifdef __MINGW32__
# include <_mingw.h>
#endif

#include "../bindlib/include/import.h"

#ifndef __cpp_exceptions
# error Boost.AFIO needs C++ exceptions to be turned on
#endif
#ifndef __cpp_alias_templates
# error Boost.AFIO needs template alias support in the compiler
#endif
#ifndef __cpp_variadic_templates
# error Boost.AFIO needs variadic template support in the compiler
#endif
#ifndef __cpp_noexcept
# error Boost.AFIO needs noexcept support in the compiler
#endif
#ifndef __cpp_constexpr
# error Boost.AFIO needs constexpr (C++ 11) support in the compiler
#endif
#ifndef __cpp_thread_local
# error Boost.AFIO needs thread_local support in the compiler
#endif

#if defined(BOOST_AFIO_LATEST_VERSION) && BOOST_AFIO_LATEST_VERSION < 2
# error You need to include the latest version of Boost.AFIO before any earlier versions within the same translation unit
#endif
#ifndef BOOST_AFIO_LATEST_VERSION
# define BOOST_AFIO_LATEST_VERSION 2
#endif

#undef BOOST_AFIO_V2_STL11_IMPL
#undef BOOST_AFIO_V2_FILESYSTEM_IMPL
#undef BOOST_AFIO_V2_ASIO_IMPL
#undef BOOST_AFIO_V2
#undef BOOST_AFIO_V2_NAMESPACE
#undef BOOST_AFIO_V2_NAMESPACE_BEGIN
#undef BOOST_AFIO_V2_NAMESPACE_END

// Default to the C++ 11 STL for atomic, chrono, mutex and thread except on Mingw32
#if (defined(BOOST_AFIO_USE_BOOST_THREAD) && BOOST_AFIO_USE_BOOST_THREAD) || (defined(__MINGW32__) && !defined(__MINGW64__) && !defined(__MINGW64_VERSION_MAJOR))
# if defined(BOOST_OUTCOME_USE_BOOST_THREAD) && BOOST_OUTCOME_USE_BOOST_THREAD != 1
#  error You must configure Boost.Monad and Boost.AFIO to both use Boost.Thread together or both not at all.
# endif
# define BOOST_OUTCOME_USE_BOOST_THREAD 1
# define BOOST_AFIO_V2_STL11_IMPL boost
# ifndef BOOST_THREAD_VERSION
#  define BOOST_THREAD_VERSION 3
# endif
# if BOOST_THREAD_VERSION < 3
#  error Boost.AFIO requires that Boost.Thread be configured to v3 or later
# endif
#else
# if defined(BOOST_OUTCOME_USE_BOOST_THREAD) && BOOST_OUTCOME_USE_BOOST_THREAD != 0
#  error You must configure Boost.Monad and Boost.AFIO to both use Boost.Thread together or both not at all.
# endif
# define BOOST_OUTCOME_USE_BOOST_THREAD 0
# define BOOST_AFIO_V2_STL11_IMPL std
# ifndef BOOST_AFIO_USE_BOOST_THREAD
#  define BOOST_AFIO_USE_BOOST_THREAD 0
# endif
#endif
// Default to the C++ 11 STL if on MSVC (Dinkumware ships a copy), else Boost
#ifndef BOOST_AFIO_USE_BOOST_FILESYSTEM
# if _MSC_VER >= 1900  // >= VS 14
#  define BOOST_AFIO_USE_BOOST_FILESYSTEM 0
# endif
#endif
#ifndef BOOST_AFIO_USE_BOOST_FILESYSTEM
# define BOOST_AFIO_USE_BOOST_FILESYSTEM 1
#endif
#if BOOST_AFIO_USE_BOOST_FILESYSTEM
# define BOOST_AFIO_V2_FILESYSTEM_IMPL boost
# define BOOST_AFIO_USE_LEGACY_FILESYSTEM_SEMANTICS 1
#else
# define BOOST_AFIO_V2_FILESYSTEM_IMPL std
#endif
#ifdef ASIO_STANDALONE
# if defined(BOOST_OUTCOME_USE_BOOST_ERROR_CODE) && BOOST_OUTCOME_USE_BOOST_ERROR_CODE != 0
#  error You must configure Boost.Monad to use the STL error_code if using standalone ASIO
# endif
# define BOOST_OUTCOME_USE_BOOST_ERROR_CODE 0
# define BOOST_AFIO_V2_ASIO_IMPL asio
# undef BOOST_AFIO_USE_BOOST_ASIO
# define BOOST_AFIO_USE_BOOST_ASIO 0
#else
# if defined(BOOST_OUTCOME_USE_BOOST_ERROR_CODE) && BOOST_OUTCOME_USE_BOOST_ERROR_CODE != 1
#  error You must configure Boost.Monad to use the Boost error code if using Boost.ASIO
# endif
# define BOOST_OUTCOME_USE_BOOST_ERROR_CODE 1
# define BOOST_AFIO_V2_ASIO_IMPL boost
# undef BOOST_AFIO_USE_BOOST_ASIO
# define BOOST_AFIO_USE_BOOST_ASIO 1
// Pull in Boost now before Monad does to avoid warnings caused by APIBind emulating Boost
# include "boost/thread/future.hpp"
#endif
#if BOOST_AFIO_LATEST_VERSION == 2
# define BOOST_AFIO_V2 (boost), (afio), (BOOST_BINDLIB_NAMESPACE_VERSION(v2, BOOST_AFIO_V2_STL11_IMPL, BOOST_AFIO_V2_FILESYSTEM_IMPL, BOOST_AFIO_V2_ASIO_IMPL), inline)
#else
# define BOOST_AFIO_V2 (boost), (afio), (BOOST_BINDLIB_NAMESPACE_VERSION(v2, BOOST_AFIO_V2_STL11_IMPL, BOOST_AFIO_V2_FILESYSTEM_IMPL, BOOST_AFIO_V2_ASIO_IMPL))
#endif
#define BOOST_AFIO_V2_NAMESPACE       BOOST_BINDLIB_NAMESPACE      (BOOST_AFIO_V2)
#define BOOST_AFIO_V2_NAMESPACE_BEGIN BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2)
#define BOOST_AFIO_V2_NAMESPACE_END   BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2)

// From automated matrix generator
#undef BOOST_AFIO_NEED_DEFINE
#undef BOOST_AFIO_NEED_DEFINE_DESCRIPTION
#if !BOOST_AFIO_USE_BOOST_THREAD && !BOOST_AFIO_USE_BOOST_FILESYSTEM && !BOOST_AFIO_USE_BOOST_ASIO
# ifndef BOOST_AFIO_NEED_DEFINE_000
#  define BOOST_AFIO_NEED_DEFINE_DESCRIPTION "BOOST_AFIO_USE_BOOST_THREAD=0 BOOST_AFIO_USE_BOOST_FILESYSTEM=0 BOOST_AFIO_USE_BOOST_ASIO=0"
#  define BOOST_AFIO_NEED_DEFINE_000
#  define BOOST_AFIO_NEED_DEFINE 1
# endif
#elif BOOST_AFIO_USE_BOOST_THREAD && !BOOST_AFIO_USE_BOOST_FILESYSTEM && !BOOST_AFIO_USE_BOOST_ASIO
# ifndef BOOST_AFIO_NEED_DEFINE_100
#  define BOOST_AFIO_NEED_DEFINE_DESCRIPTION "BOOST_AFIO_USE_BOOST_THREAD=1 BOOST_AFIO_USE_BOOST_FILESYSTEM=0 BOOST_AFIO_USE_BOOST_ASIO=0"
#  define BOOST_AFIO_NEED_DEFINE_100
#  define BOOST_AFIO_NEED_DEFINE 1
# endif
#elif !BOOST_AFIO_USE_BOOST_THREAD && BOOST_AFIO_USE_BOOST_FILESYSTEM && !BOOST_AFIO_USE_BOOST_ASIO
# ifndef BOOST_AFIO_NEED_DEFINE_010
#  define BOOST_AFIO_NEED_DEFINE_DESCRIPTION "BOOST_AFIO_USE_BOOST_THREAD=0 BOOST_AFIO_USE_BOOST_FILESYSTEM=1 BOOST_AFIO_USE_BOOST_ASIO=0"
#  define BOOST_AFIO_NEED_DEFINE_010
#  define BOOST_AFIO_NEED_DEFINE 1
# endif
#elif BOOST_AFIO_USE_BOOST_THREAD && BOOST_AFIO_USE_BOOST_FILESYSTEM && !BOOST_AFIO_USE_BOOST_ASIO
# ifndef BOOST_AFIO_NEED_DEFINE_110
#  define BOOST_AFIO_NEED_DEFINE_DESCRIPTION "BOOST_AFIO_USE_BOOST_THREAD=1 BOOST_AFIO_USE_BOOST_FILESYSTEM=1 BOOST_AFIO_USE_BOOST_ASIO=0"
#  define BOOST_AFIO_NEED_DEFINE_110
#  define BOOST_AFIO_NEED_DEFINE 1
# endif
#elif !BOOST_AFIO_USE_BOOST_THREAD && !BOOST_AFIO_USE_BOOST_FILESYSTEM && BOOST_AFIO_USE_BOOST_ASIO
# ifndef BOOST_AFIO_NEED_DEFINE_001
#  define BOOST_AFIO_NEED_DEFINE_DESCRIPTION "BOOST_AFIO_USE_BOOST_THREAD=0 BOOST_AFIO_USE_BOOST_FILESYSTEM=0 BOOST_AFIO_USE_BOOST_ASIO=1"
#  define BOOST_AFIO_NEED_DEFINE_001
#  define BOOST_AFIO_NEED_DEFINE 1
# endif
#elif BOOST_AFIO_USE_BOOST_THREAD && !BOOST_AFIO_USE_BOOST_FILESYSTEM && BOOST_AFIO_USE_BOOST_ASIO
# ifndef BOOST_AFIO_NEED_DEFINE_101
#  define BOOST_AFIO_NEED_DEFINE_DESCRIPTION "BOOST_AFIO_USE_BOOST_THREAD=1 BOOST_AFIO_USE_BOOST_FILESYSTEM=0 BOOST_AFIO_USE_BOOST_ASIO=1"
#  define BOOST_AFIO_NEED_DEFINE_101
#  define BOOST_AFIO_NEED_DEFINE 1
# endif
#elif !BOOST_AFIO_USE_BOOST_THREAD && BOOST_AFIO_USE_BOOST_FILESYSTEM && BOOST_AFIO_USE_BOOST_ASIO
# ifndef BOOST_AFIO_NEED_DEFINE_011
#  define BOOST_AFIO_NEED_DEFINE_DESCRIPTION "BOOST_AFIO_USE_BOOST_THREAD=0 BOOST_AFIO_USE_BOOST_FILESYSTEM=1 BOOST_AFIO_USE_BOOST_ASIO=1"
#  define BOOST_AFIO_NEED_DEFINE_011
#  define BOOST_AFIO_NEED_DEFINE 1
# endif
#elif BOOST_AFIO_USE_BOOST_THREAD && BOOST_AFIO_USE_BOOST_FILESYSTEM && BOOST_AFIO_USE_BOOST_ASIO
# ifndef BOOST_AFIO_NEED_DEFINE_111
#  define BOOST_AFIO_NEED_DEFINE_DESCRIPTION "BOOST_AFIO_USE_BOOST_THREAD=1 BOOST_AFIO_USE_BOOST_FILESYSTEM=1 BOOST_AFIO_USE_BOOST_ASIO=1"
#  define BOOST_AFIO_NEED_DEFINE_111
#  define BOOST_AFIO_NEED_DEFINE 1
# endif
#endif

#ifdef BOOST_AFIO_NEED_DEFINE
#undef BOOST_AFIO_AFIO_H

#define BOOST_STL11_ATOMIC_MAP_NAMESPACE_BEGIN        BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL11_ATOMIC_MAP_NAMESPACE_END          BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL11_ATOMIC_MAP_NO_ATOMIC_CHAR32_T // missing VS14
#define BOOST_STL11_ATOMIC_MAP_NO_ATOMIC_CHAR16_T // missing VS14
#define BOOST_STL11_CHRONO_MAP_NAMESPACE_BEGIN        BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl11, inline), (chrono))
#define BOOST_STL11_CHRONO_MAP_NAMESPACE_END          BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl11, inline), (chrono))
#define BOOST_STL11_CONDITION_VARIABLE_MAP_NAMESPACE_BEGIN BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL11_CONDITION_VARIABLE_MAP_NAMESPACE_END   BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL1z_FILESYSTEM_MAP_NAMESPACE_BEGIN    BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl1z, inline), (filesystem))
#define BOOST_STL1z_FILESYSTEM_MAP_NAMESPACE_END      BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl1z, inline), (filesystem))
// Match Dinkumware's TR2 implementation
#define BOOST_STL1z_FILESYSTEM_MAP_NO_SYMLINK_OPTION
#define BOOST_STL1z_FILESYSTEM_MAP_NO_COPY_OPTION
#define BOOST_STL1z_FILESYSTEM_MAP_NO_CHANGE_EXTENSION
#define BOOST_STL1z_FILESYSTEM_MAP_NO_WRECURSIVE_DIRECTORY_ITERATOR
#define BOOST_STL1z_FILESYSTEM_MAP_NO_EXTENSION
#define BOOST_STL1z_FILESYSTEM_MAP_NO_TYPE_PRESENT
#define BOOST_STL1z_FILESYSTEM_MAP_NO_PORTABLE_FILE_NAME
#define BOOST_STL1z_FILESYSTEM_MAP_NO_PORTABLE_DIRECTORY_NAME
#define BOOST_STL1z_FILESYSTEM_MAP_NO_PORTABLE_POSIX_NAME
#define BOOST_STL1z_FILESYSTEM_MAP_NO_LEXICOGRAPHICAL_COMPARE
#define BOOST_STL1z_FILESYSTEM_MAP_NO_WINDOWS_NAME
#define BOOST_STL1z_FILESYSTEM_MAP_NO_PORTABLE_NAME
#define BOOST_STL1z_FILESYSTEM_MAP_NO_BASENAME
#define BOOST_STL1z_FILESYSTEM_MAP_NO_COMPLETE
#define BOOST_STL1z_FILESYSTEM_MAP_NO_IS_REGULAR
#define BOOST_STL1z_FILESYSTEM_MAP_NO_INITIAL_PATH
#define BOOST_STL1z_FILESYSTEM_MAP_NO_PERMISSIONS_PRESENT
#define BOOST_STL1z_FILESYSTEM_MAP_NO_CODECVT_ERROR_CATEGORY
#define BOOST_STL1z_FILESYSTEM_MAP_NO_WPATH
#define BOOST_STL1z_FILESYSTEM_MAP_NO_SYMBOLIC_LINK_EXISTS
#define BOOST_STL1z_FILESYSTEM_MAP_NO_COPY_DIRECTORY
#define BOOST_STL1z_FILESYSTEM_MAP_NO_NATIVE
#define BOOST_STL1z_FILESYSTEM_MAP_NO_UNIQUE_PATH
#define BOOST_STL11_FUTURE_MAP_NAMESPACE_BEGIN        BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL11_FUTURE_MAP_NAMESPACE_END          BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL11_FUTURE_MAP_NO_FUTURE
#define BOOST_STL11_MUTEX_MAP_NAMESPACE_BEGIN         BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL11_MUTEX_MAP_NAMESPACE_END           BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL1z_NETWORKING_MAP_NAMESPACE_BEGIN    BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl1z, inline), (asio))
#define BOOST_STL1z_NETWORKING_MAP_NAMESPACE_END      BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl1z, inline), (asio))
#define BOOST_STL1z_NETWORKING_MAP_NO_V4_MAPPED_T
#define BOOST_STL1z_NETWORKING_MAP_NO_EXECUTOR_ARG_T
#define BOOST_STL1z_NETWORKING_MAP_NO_WRAP
#define BOOST_STL1z_NETWORKING_MAP_NO_MAKE_WORK
#define BOOST_STL1z_NETWORKING_MAP_NO_ASYNC_COMPLETION
#define BOOST_STL1z_NETWORKING_MAP_NO_EXECUTOR_WORK
#define BOOST_STL1z_NETWORKING_MAP_NO_EXECUTION_CONTEXT
#define BOOST_STL1z_NETWORKING_MAP_NO_POST
#define BOOST_STL1z_NETWORKING_MAP_NO_EXECUTOR
#define BOOST_STL1z_NETWORKING_MAP_NO_USES_EXECUTOR
#define BOOST_STL1z_NETWORKING_MAP_NO_BAD_ADDRESS_CAST
#define BOOST_STL1z_NETWORKING_MAP_NO_BAD_EXECUTOR
#define BOOST_STL1z_NETWORKING_MAP_NO_GET_ASSOCIATED_EXECUTOR
#define BOOST_STL1z_NETWORKING_MAP_NO_ASSOCIATED_EXECUTOR
#define BOOST_STL1z_NETWORKING_MAP_NO_GET_ASSOCIATED_ALLOCATOR
#define BOOST_STL1z_NETWORKING_MAP_NO_ASSOCIATED_ALLOCATOR
#define BOOST_STL1z_NETWORKING_MAP_NO_IS_EXECUTOR
#define BOOST_STL1z_NETWORKING_MAP_NO_MAKE_ADDRESS_V4
#define BOOST_STL1z_NETWORKING_MAP_NO_MAKE_ADDRESS_V6
#define BOOST_STL1z_NETWORKING_MAP_NO_MAKE_ADDRESS
#define BOOST_STL1z_NETWORKING_MAP_NO_ADDRESS_CAST
#define BOOST_STL1z_NETWORKING_MAP_NO_DEFER
#define BOOST_STL1z_NETWORKING_MAP_NO_DISPATCH
#define BOOST_STL1z_NETWORKING_MAP_NO_THREAD_POOL
#define BOOST_STL1z_NETWORKING_MAP_NO_IS_MUTABLE_BUFFER_SEQUENCE
#define BOOST_STL1z_NETWORKING_MAP_NO_IS_CONST_BUFFER_SEQUENCE
#define BOOST_STL1z_NETWORKING_MAP_NO_EXECUTOR_WRAPPER
#define BOOST_STL1z_NETWORKING_MAP_NO_SYSTEM_EXECUTOR
#define BOOST_STL1z_NETWORKING_MAP_NO_HANDLER_TYPE
#define BOOST_STL1z_NETWORKING_MAP_NO_STRAND
#define BOOST_STL1z_NETWORKING_MAP_NO_READ_SIZE_HELPER
#define BOOST_STL11_RATIO_MAP_NAMESPACE_BEGIN         BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL11_RATIO_MAP_NAMESPACE_END           BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL11_THREAD_MAP_NAMESPACE_BEGIN        BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl11, inline))
#define BOOST_STL11_THREAD_MAP_NAMESPACE_END          BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl11, inline))
#include BOOST_BINDLIB_INCLUDE_STL11(../bindlib, BOOST_AFIO_V2_STL11_IMPL, atomic)
#include BOOST_BINDLIB_INCLUDE_STL11(../bindlib, BOOST_AFIO_V2_STL11_IMPL, chrono)
#include BOOST_BINDLIB_INCLUDE_STL11(../bindlib, BOOST_AFIO_V2_STL11_IMPL, condition_variable)
#include BOOST_BINDLIB_INCLUDE_STL1z(../bindlib, BOOST_AFIO_V2_FILESYSTEM_IMPL, filesystem)
#include BOOST_BINDLIB_INCLUDE_STL11(../bindlib, BOOST_AFIO_V2_STL11_IMPL, future)
#include BOOST_BINDLIB_INCLUDE_STL11(../bindlib, BOOST_AFIO_V2_STL11_IMPL, mutex)
#include BOOST_BINDLIB_INCLUDE_STL1z(../bindlib, BOOST_AFIO_V2_ASIO_IMPL, networking)
#include BOOST_BINDLIB_INCLUDE_STL11(../bindlib, BOOST_AFIO_V2_STL11_IMPL, ratio)
#include BOOST_BINDLIB_INCLUDE_STL11(../bindlib, BOOST_AFIO_V2_STL11_IMPL, thread)

#define BOOST_STL1z_NETWORKING_MAP_NAMESPACE_BEGIN    BOOST_BINDLIB_NAMESPACE_BEGIN(BOOST_AFIO_V2, (stl1z, inline), (asio))
#define BOOST_STL1z_NETWORKING_MAP_NAMESPACE_END      BOOST_BINDLIB_NAMESPACE_END  (BOOST_AFIO_V2, (stl1z, inline), (asio))
BOOST_STL1z_NETWORKING_MAP_NAMESPACE_BEGIN
// Need to bind in asio::windows
#ifdef WIN32
# if !BOOST_AFIO_USE_BOOST_ASIO
namespace error = ::asio::error;
namespace windows = ::asio::windows;
# else
namespace error = ::boost::asio::error;
namespace windows = ::boost::asio::windows;
# endif
#endif
BOOST_STL1z_NETWORKING_MAP_NAMESPACE_END
#undef BOOST_STL1z_NETWORKING_MAP_NAMESPACE_BEGIN
#undef BOOST_STL1z_NETWORKING_MAP_NAMESPACE_END

#ifndef DOXYGEN_SHOULD_SKIP_THIS
// Map an error category
BOOST_AFIO_V2_NAMESPACE_BEGIN
using std::to_string;

#if BOOST_AFIO_USE_BOOST_THREAD
//using boost::make_exception_ptr;
template<class T> inline boost::exception_ptr make_exception_ptr(T e)
{
  try
  {
    throw e;
  }
  catch(...)
  {
    return boost::current_exception();
  }
}
template<class _Res> using stl_future = ::boost::future<_Res>;
#else
using std::make_exception_ptr;
template<class _Res> using stl_future = ::std::future<_Res>;
#endif

#if !BOOST_AFIO_USE_BOOST_ASIO
typedef asio::error_code error_code;
using std::generic_category;
using std::system_category;
using std::system_error;
#else
typedef boost::system::error_code error_code;
using boost::system::generic_category;
using boost::system::system_category;
using boost::system::system_error;
#endif
#if defined(_MSC_VER) && 0
// Stupid MSVC doesn't resolve namespace binds correctly ...
#if !BOOST_AFIO_USE_BOOST_ASIO
namespace asio {
  namespace asio = ::asio;
  namespace detail { namespace asio = ::asio; }
  //namespace windows { namespace asio = ::asio; }
}
namespace asio_handler_cont_helpers { namespace asio = ::asio; }
namespace asio_handler_alloc_helpers { namespace asio = ::asio; }
namespace asio_handler_invoke_helpers { namespace asio = ::asio; }

#else
namespace boost { namespace asio {
  namespace asio = ::boost::asio;
  namespace detail { namespace asio = ::boost::asio; }
  namespace windows { namespace asio = ::boost::asio; }
} }
#endif
#endif
BOOST_AFIO_V2_NAMESPACE_END
#endif

#include "../outcome/include/boost/outcome.hpp"
BOOST_AFIO_V2_NAMESPACE_BEGIN
  using BOOST_OUTCOME_V1_NAMESPACE::is_lockable_locked;
  using spins_to_sleep = BOOST_OUTCOME_V1_NAMESPACE::spins_to_sleep;
  template<size_t _0> using spins_to_yield = BOOST_OUTCOME_V1_NAMESPACE::spins_to_yield<_0>;
  template<size_t _0, bool _1=true> using spins_to_loop = BOOST_OUTCOME_V1_NAMESPACE::spins_to_loop<_0, _1>;
  using null_spin_policy = BOOST_OUTCOME_V1_NAMESPACE::null_spin_policy;
  template<class T> using spinlockbase = BOOST_OUTCOME_V1_NAMESPACE::spinlockbase<T>;
  template<class T> using lockable_ptr = BOOST_OUTCOME_V1_NAMESPACE::lockable_ptr<T>;
  template<typename T, template<class> class spinpolicy2=spins_to_loop<125>::policy, template<class> class spinpolicy3=spins_to_yield<250>::policy, template<class> class spinpolicy4=spins_to_sleep::policy> using spinlock = BOOST_OUTCOME_V1_NAMESPACE::spinlock<T, spinpolicy2, spinpolicy3, spinpolicy4>;
  template<typename R> using outcome = BOOST_OUTCOME_V1_NAMESPACE::outcome<R>;
  template<typename R> using result = BOOST_OUTCOME_V1_NAMESPACE::result<R>;
  template<typename R> using option = BOOST_OUTCOME_V1_NAMESPACE::option<R>;
  template<typename R> using lightweight_promise = BOOST_OUTCOME_V1_NAMESPACE::lightweight_futures::promise<R>;
  template<typename R> using lightweight_future = BOOST_OUTCOME_V1_NAMESPACE::lightweight_futures::future<R>;
  template<typename R> using is_lightweight_future = BOOST_OUTCOME_V1_NAMESPACE::lightweight_futures::is_future<R>;
  using BOOST_OUTCOME_V1_NAMESPACE::empty;
  using BOOST_OUTCOME_V1_NAMESPACE::make_option;
  using BOOST_OUTCOME_V1_NAMESPACE::make_outcome;
  using BOOST_OUTCOME_V1_NAMESPACE::make_result;
  using BOOST_OUTCOME_V1_NAMESPACE::make_errored_outcome;
  using BOOST_OUTCOME_V1_NAMESPACE::make_errored_result;
  using BOOST_OUTCOME_V1_NAMESPACE::monad_errc;
  using BOOST_OUTCOME_V1_NAMESPACE::monad_category;
BOOST_AFIO_V2_NAMESPACE_END

///////////////////////////////////////////////////////////////////////////////
//  Set up dll import/export options
#if (defined(BOOST_AFIO_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && \
    !defined(BOOST_AFIO_STATIC_LINK)

# if defined(BOOST_AFIO_SOURCE)
#  undef BOOST_AFIO_HEADERS_ONLY
#  define BOOST_AFIO_DECL BOOST_SYMBOL_EXPORT
#  define BOOST_AFIO_BUILD_DLL
# else
#  define BOOST_AFIO_DECL
# endif
#else
# define BOOST_AFIO_DECL
#endif // building a shared library

///////////////////////////////////////////////////////////////////////////////
//  Auto library naming
#if !defined(BOOST_AFIO_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \
    !defined(BOOST_AFIO_NO_LIB) && !AFIO_STANDALONE && !BOOST_AFIO_HEADERS_ONLY

#define BOOST_LIB_NAME boost_afio

// tell the auto-link code to select a dll when required:
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_AFIO_DYN_LINK)
#define BOOST_DYN_LINK
#endif

#include <boost/config/auto_link.hpp>

#endif  // auto-linking disabled

//#define BOOST_THREAD_VERSION 4
//#define BOOST_THREAD_PROVIDES_VARIADIC_THREAD
//#define BOOST_THREAD_DONT_PROVIDE_FUTURE
//#define BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
#if BOOST_AFIO_HEADERS_ONLY == 1
# define BOOST_AFIO_HEADERS_ONLY_FUNC_SPEC inline
# define BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC inline
# define BOOST_AFIO_HEADERS_ONLY_VIRTUAL_SPEC inline virtual
// GCC gets upset if inline virtual functions aren't defined
# ifdef BOOST_GCC
#  define BOOST_AFIO_HEADERS_ONLY_VIRTUAL_UNDEFINED_SPEC { BOOST_AFIO_THROW_FATAL(std::runtime_error("Attempt to call pure virtual member function")); abort(); }
# else
#  define BOOST_AFIO_HEADERS_ONLY_VIRTUAL_UNDEFINED_SPEC =0;
# endif
#else
# define BOOST_AFIO_HEADERS_ONLY_FUNC_SPEC extern BOOST_AFIO_DECL
# define BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC
# define BOOST_AFIO_HEADERS_ONLY_VIRTUAL_SPEC virtual
# define BOOST_AFIO_HEADERS_ONLY_VIRTUAL_UNDEFINED_SPEC =0;
#endif

#if defined(__has_feature)
# if __has_feature(thread_sanitizer)
#  define BOOST_AFIO_DISABLE_THREAD_SANITIZE __attribute__((no_sanitize_thread))
# endif
#endif
#ifndef BOOST_AFIO_DISABLE_THREAD_SANITIZE
# define BOOST_AFIO_DISABLE_THREAD_SANITIZE
#endif

#ifndef BOOST_AFIO_LAMBDA_MOVE_CAPTURE
# ifdef __cpp_init_captures
#  define BOOST_AFIO_LAMBDA_MOVE_CAPTURE(var) var=std::move(var)
# else
#  define BOOST_AFIO_LAMBDA_MOVE_CAPTURE(var) var
# endif
#endif

#ifndef BOOST_AFIO_THREAD_LOCAL
# ifdef __cpp_thread_local
#  define BOOST_AFIO_THREAD_LOCAL thread_local
# elif defined(_MSC_VER)
#  define BOOST_AFIO_THREAD_LOCAL __declspec(thread)
# elif defined(__GNUC__)
#  define BOOST_AFIO_THREAD_LOCAL __thread
# else
#  error Unknown compiler, cannot set BOOST_AFIO_THREAD_LOCAL
# endif
#endif

#ifndef BOOST_AFIO_LOG_FATAL_EXIT
#define BOOST_AFIO_LOG_FATAL_EXIT(expr) std::cerr << expr
#endif

#endif  // BOOST_AFIO_NEED_DEFINE

ext: hpp

max_stars_repo_name: grassofsky/llfio

max_issues_repo_name: grassofsky/llfio

max_forks_repo_name: grassofsky/llfio


text:
/*

Copyright (c) 2003-2012, Arvid Norberg, Daniel Wallin
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#include <string>

#include "libtorrent/config.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/io_service.hpp"
#include "libtorrent/socket_io.hpp"
#include "libtorrent/time.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/escape_string.hpp"
#include "libtorrent/extensions.hpp"
#include <boost/bind.hpp>

namespace libtorrent {

	alert::alert() : m_timestamp(time_now()) {}
	alert::~alert() {}
	ptime alert::timestamp() const { return m_timestamp; }

	std::string torrent_alert::message() const
	{
		if (!handle.is_valid()) return " - ";
		torrent_status st = handle.status(torrent_handle::query_name);
		if (st.name.empty())
		{
			char msg[41];
			to_hex((char const*)&st.info_hash[0], 20, msg);
			return msg;
		}
		return st.name;
	}

	std::string peer_alert::message() const
	{
		error_code ec;
		return torrent_alert::message() + " peer (" + ip.address().to_string(ec)
			+ ", " + identify_client(pid) + ")";
	}

	std::string tracker_alert::message() const
	{
		return torrent_alert::message() + " (" + url + ")";
	}

	std::string read_piece_alert::message() const
	{
		char msg[200];
		if (ec)
		{
			snprintf(msg, sizeof(msg), "%s: read_piece %u failed: %s"
				, torrent_alert::message().c_str() , piece, ec.message().c_str());
		}
		else
		{
			snprintf(msg, sizeof(msg), "%s: read_piece %u successful"
				, torrent_alert::message().c_str() , piece);
		}
		return msg;
	}

	std::string file_completed_alert::message() const
	{
		char msg[200 + TORRENT_MAX_PATH];
		snprintf(msg, sizeof(msg), "%s: file %d finished downloading"
			, torrent_alert::message().c_str(), index);
		return msg;
	}

	std::string file_renamed_alert::message() const
	{
		char msg[200 + TORRENT_MAX_PATH * 2];
		snprintf(msg, sizeof(msg), "%s: file %d renamed to %s", torrent_alert::message().c_str()
			, index, name.c_str());
		return msg;
	}

	std::string file_rename_failed_alert::message() const
	{
		char ret[200 + TORRENT_MAX_PATH * 2];
		snprintf(ret, sizeof(ret), "%s: failed to rename file %d: %s"
			, torrent_alert::message().c_str(), index, convert_from_native(error.message()).c_str());
		return ret;
	}

	std::string performance_alert::message() const
	{
		static char const* warning_str[] =
		{
			"max outstanding disk writes reached",
			"max outstanding piece requests reached",
			"upload limit too low (download rate will suffer)",
			"download limit too low (upload rate will suffer)",
			"send buffer watermark too low (upload rate will suffer)",
			"too many optimistic unchoke slots",
			"using bittyrant unchoker with no upload rate limit set",
			"the disk queue limit is too high compared to the cache size. The disk queue eats into the cache size",
			"too few ports allowed for outgoing connections",
			"too few file descriptors are allowed for this process. connection limit lowered"
		};

		return torrent_alert::message() + ": performance warning: "
			+ warning_str[warning_code];
	}

	std::string state_changed_alert::message() const
	{
		static char const* state_str[] =
			{"checking (q)", "checking", "dl metadata"
			, "downloading", "finished", "seeding", "allocating"
			, "checking (r)"};

		return torrent_alert::message() + ": state changed to: "
			+ state_str[state];
	}

	std::string tracker_error_alert::message() const
	{
		char ret[400];
		snprintf(ret, sizeof(ret), "%s (%d) %s (%d)"
			, tracker_alert::message().c_str(), status_code
			, msg.c_str(), times_in_row);
		return ret;
	}

	std::string tracker_warning_alert::message() const
	{
		return tracker_alert::message() + " warning: " + msg;
	}

	std::string scrape_reply_alert::message() const
	{
		char ret[400];
		snprintf(ret, sizeof(ret), "%s scrape reply: %u %u"
			, tracker_alert::message().c_str(), incomplete, complete);
		return ret;
	}

	std::string scrape_failed_alert::message() const
	{
		return tracker_alert::message() + " scrape failed: " + msg;
	}

	std::string tracker_reply_alert::message() const
	{
		char ret[400];
		snprintf(ret, sizeof(ret), "%s received peers: %u"
			, tracker_alert::message().c_str(), num_peers);
		return ret;
	}

	std::string dht_reply_alert::message() const
	{
		char ret[400];
		snprintf(ret, sizeof(ret), "%s received DHT peers: %u"
			, tracker_alert::message().c_str(), num_peers);
		return ret;
	}

	std::string tracker_announce_alert::message() const
	{
		const static char* event_str[] = {"none", "completed", "started", "stopped", "paused"};
		TORRENT_ASSERT_VAL(event < int(sizeof(event_str)/sizeof(event_str[0])), event);
		return tracker_alert::message() + " sending announce (" + event_str[event] + ")";
	}

	std::string hash_failed_alert::message() const
	{
		char ret[400];
		snprintf(ret, sizeof(ret), "%s hash for piece %u failed"
			, torrent_alert::message().c_str(), piece_index);
		return ret;
	}

	std::string peer_ban_alert::message() const
	{
		return peer_alert::message() + " banned peer";
	}

	std::string peer_unsnubbed_alert::message() const
	{
		return peer_alert::message() + " peer unsnubbed";
	}

	std::string peer_snubbed_alert::message() const
	{
		return peer_alert::message() + " peer snubbed";
	}

	std::string invalid_request_alert::message() const
	{
		char ret[200];
		snprintf(ret, sizeof(ret), "%s peer sent an invalid piece request (piece: %u start: %u len: %u)"
			, peer_alert::message().c_str(), request.piece, request.start, request.length);
		return ret;
	}

	std::string piece_finished_alert::message() const
	{
		char ret[200];
		snprintf(ret, sizeof(ret), "%s piece: %u finished downloading"
			, torrent_alert::message().c_str(), piece_index);
		return ret;
	}

	std::string request_dropped_alert::message() const
	{
		char ret[200];
		snprintf(ret, sizeof(ret), "%s peer dropped block ( piece: %u block: %u)"
			, torrent_alert::message().c_str(), piece_index, block_index);
		return ret;
	}

	std::string block_timeout_alert::message() const
	{
		char ret[200];
		snprintf(ret, sizeof(ret), "%s peer timed out request ( piece: %u block: %u)"
			, torrent_alert::message().c_str(), piece_index, block_index);
		return ret;
	}

	std::string block_finished_alert::message() const
	{
		char ret[200];
		snprintf(ret, sizeof(ret), "%s block finished downloading (piece: %u block: %u)"
			, torrent_alert::message().c_str(), piece_index, block_index);
		return ret;
	}

	std::string block_downloading_alert::message() const
	{
		char ret[200];
		snprintf(ret, sizeof(ret), "%s requested block (piece: %u block: %u) %s"
			, torrent_alert::message().c_str(), piece_index, block_index, peer_speedmsg);
		return ret;
	}

	std::string unwanted_block_alert::message() const
	{
		char ret[200];
		snprintf(ret, sizeof(ret), "%s received block not in download queue (piece: %u block: %u)"
			, torrent_alert::message().c_str(), piece_index, block_index);
		return ret;
	}

	std::string listen_failed_alert::message() const
	{
		char const* op_str[] =
		{
			"parse_addr",
			"open",
			"bind",
			"listen",
			"get_peer_name",
			"accept"
		};
		char ret[250];
		snprintf(ret, sizeof(ret), "listening on %s failed: [%s] %s"
			, print_endpoint(endpoint).c_str()
			, op_str[operation]
			, convert_from_native(error.message()).c_str());
		return ret;
	}

	std::string listen_succeeded_alert::message() const
	{
		char ret[200];
		snprintf(ret, sizeof(ret), "successfully listening on %s", print_endpoint(endpoint).c_str());
		return ret;
	}

	std::string portmap_error_alert::message() const
	{
		static char const* type_str[] = {"NAT-PMP", "UPnP"};
		return std::string("could not map port using ") + type_str[map_type]
			+ ": " + convert_from_native(error.message());
	}

	std::string portmap_alert::message() const
	{
		static char const* type_str[] = {"NAT-PMP", "UPnP"};
		char ret[200];
		snprintf(ret, sizeof(ret), "successfully mapped port using %s. external port: %u"
			, type_str[map_type], external_port);
		return ret;
	}

	std::string portmap_log_alert::message() const
	{
		static char const* type_str[] = {"NAT-PMP", "UPnP"};
		char ret[600];
		snprintf(ret, sizeof(ret), "%s: %s", type_str[map_type], msg.c_str());
		return ret;
	}

	std::string dht_announce_alert::message() const
	{
		error_code ec;
		char ih_hex[41];
		to_hex((const char*)&info_hash[0], 20, ih_hex);
		char msg[200];
		snprintf(msg, sizeof(msg), "incoming dht announce: %s:%u (%s)"
			, ip.to_string(ec).c_str(), port, ih_hex);
		return msg;
	}

	std::string dht_get_peers_alert::message() const
	{
		char ih_hex[41];
		to_hex((const char*)&info_hash[0], 20, ih_hex);
		char msg[200];
		snprintf(msg, sizeof(msg), "incoming dht get_peers: %s", ih_hex);
		return msg;
	}

	std::string dht_reply_data_alert::message() const
	{
		char msg[200];
		snprintf(msg, sizeof(msg), "reply to dht getData received %lu entries", m_lst.size());
		return msg;
	}

	std::string  dht_reply_data_done_alert::message() const
	{
		char msg[200];
		snprintf(msg, sizeof(msg), "reply of getData done");
		return msg;
	}

	std::string dht_get_data_alert::message() const
	{
		char msg[200];
		snprintf(msg, sizeof(msg), "request of getData received (m_possiblyNeighbor=%d)", m_possiblyNeighbor);
		return msg;
	}

	stats_alert::stats_alert(torrent_handle const& h, int in
		, stat const& s)
		: torrent_alert(h)
		, interval(in)
	{
		for (int i = 0; i < num_channels; ++i)
			transferred[i] = s[i].counter();
	}

	std::string stats_alert::message() const
	{
		char msg[200];
		snprintf(msg, sizeof(msg), "%s: [%d] %d %d %d %d %d %d %d %d %d %d"
			, torrent_alert::message().c_str()
			, interval
			, transferred[0]
			, transferred[1]
			, transferred[2]
			, transferred[3]
			, transferred[4]
			, transferred[5]
			, transferred[6]
			, transferred[7]
			, transferred[8]
			, transferred[9]);
		return msg;
	}

	cache_flushed_alert::cache_flushed_alert(torrent_handle const& h): torrent_alert(h) {}

	std::string anonymous_mode_alert::message() const
	{
		char msg[200];
		char const* msgs[] = {
			"tracker is not anonymous, set a proxy"
		};
		snprintf(msg, sizeof(msg), "%s: %s: %s"
			, torrent_alert::message().c_str()
			, msgs[kind], str.c_str());
		return msg;
	}

	std::string lsd_peer_alert::message() const
	{
		char msg[200];
		snprintf(msg, sizeof(msg), "%s: received peer from local service discovery"
			, peer_alert::message().c_str());
		return msg;
	}

	std::string trackerid_alert::message() const
	{
		return "trackerid received: " + trackerid;
	}

	std::string dht_bootstrap_alert::message() const
	{
		return "DHT bootstrap complete";
	}

	std::string rss_alert::message() const
	{
		char msg[600];
		char const* state_msg[] = {"updating", "updated", "error"};
		snprintf(msg, sizeof(msg), "RSS feed %s: %s (%s)"
			, url.c_str(), state_msg[state], convert_from_native(error.message()).c_str());
		return msg;
	}

	std::string torrent_error_alert::message() const
	{
		char msg[200];
		snprintf(msg, sizeof(msg), " ERROR: %s", convert_from_native(error.message()).c_str());
		return torrent_alert::message() + msg;
	}

	std::string torrent_added_alert::message() const
	{
		return torrent_alert::message() + " added";
	}

	std::string torrent_removed_alert::message() const
	{
		return torrent_alert::message() + " removed";
	}

	std::string torrent_need_cert_alert::message() const
	{
		return torrent_alert::message() + " needs SSL certificate";
	}

	std::string incoming_connection_alert::message() const
	{
		char msg[600];
		char const* type_str[] = {
			"null",
			"TCP",
			"Socks5/TCP",
			"HTTP",
			"uTP",
			"i2p",
			"SSL/TCP",
			"SSL/Socks5",
			"HTTPS",
			"SSL/uTP"
			};
		error_code ec;
		snprintf(msg, sizeof(msg), "incoming connection from %s (%s)"
			, print_endpoint(ip).c_str(), type_str[socket_type]);
		return msg;
	}

	std::string add_torrent_alert::message() const
	{
		char msg[600];
		if (error)
		{
			snprintf(msg, sizeof(msg), "failed to add torrent: %s"
				, convert_from_native(error.message()).c_str());
		}
		else
		{
			snprintf(msg, sizeof(msg), "added torrent: %s"
				, !params.url.empty() ? params.url.c_str()
				: params.ti ? params.ti->name().c_str()
				: !params.name.empty() ? params.name.c_str()
				: !params.uuid.empty() ? params.uuid.c_str()
				: "");
		}
		return msg;
	}

	std::string state_update_alert::message() const
	{
		char msg[600];
		snprintf(msg, sizeof(msg), "state updates for %d torrents", int(status.size()));
		return msg;
	}

	std::string torrent_update_alert::message() const
	{
		char msg[200];
		snprintf(msg, sizeof(msg), " torrent changed info-hash from: %s to %s"
			, to_hex(old_ih.to_string()).c_str()
			, to_hex(new_ih.to_string()).c_str());
		return torrent_alert::message() + msg;
	}

	std::string rss_item_alert::message() const
	{
		char msg[500];
		snprintf(msg, sizeof(msg), "feed [%s] has new RSS item %s"
			, handle.get_feed_status().title.c_str()
			, item.title.empty() ? item.url.c_str() : item.title.c_str());
		return msg;
	}

} // namespace libtorrent

max_stars_repo_name: majestrate/twister-core

max_issues_repo_name: majestrate/twister-core

max_forks_repo_name: twisterarmy/twister-core


text:
// Copyright Takatoshi Kondo 2020
//
// 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)

#if !defined(MQTT_CONFIG_HPP)
#define MQTT_CONFIG_HPP

#if !defined(MQTT_STD_VARIANT)

// Use boost variant

// user intentionally defined BOOST_MPL_LIMIT_LIST_SIZE but size is too small
// NOTE: if BOOST_MPL_LIMIT_LIST_SIZE is not defined, the value is evaluate as 0.
#if defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) && BOOST_MPL_LIMIT_LIST_SIZE < 40

#error BOOST_MPL_LIMIT_LIST_SIZE need to greator or equal to 40

#else  // defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) && BOOST_MPL_LIMIT_LIST_SIZE < 40

// user doesn't define BOOST_MPL_LIMIT_LIST_SIZE intentionally
// but the defult value could be defined

#undef BOOST_MPL_LIMIT_LIST_SIZE
#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
#define BOOST_MPL_LIMIT_LIST_SIZE 40

#endif // defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) && BOOST_MPL_LIMIT_LIST_SIZE < 40

#endif // !defined(MQTT_STD_VARIANT)

// Check whether to use standard executors only
#if defined(MQTT_NO_TS_EXECUTORS)

// Determine Boost Asio version
#include <boost/asio/version.hpp>

// Make sure standard executors are supported by Boost Asio
#if BOOST_ASIO_VERSION < 101800
#error Boost Asio version 1.18.0 required for no TS-style executors
#endif // BOOST_ASIO_VERSION < 101800

#else // defined(MQTT_NO_TS_EXECUTORS)

// Force no TS executors if Boost Asio accepts these only
#if defined(BOOST_ASIO_NO_TS_EXECUTORS)
#define MQTT_NO_TS_EXECUTORS
#endif // defined(BOOST_ASIO_NO_TS_EXECUTORS)

#endif // defined(MQTT_NO_TS_EXECUTORS)

#define BOOST_UUID_FORCE_AUTO_LINK

#endif // MQTT_CONFIG_HPP


text:
//=======================================================================
// Copyright (c)
//
// 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)
//=======================================================================
/**
 * @file steiner_strategy.hpp
 * @brief
 * @author Maciej Andrejczuk
 * @version 1.0
 * @date 2013-08-01
 */
#ifndef PAAL_STEINER_STRATEGY_HPP
#define PAAL_STEINER_STRATEGY_HPP

#include "paal/data_structures/bimap.hpp"
#include "paal/data_structures/subset_iterator.hpp"
#include "paal/iterative_rounding/steiner_tree/steiner_components.hpp"
#include "paal/utils/assign_updates.hpp"

#include <boost/graph/connected_components.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/range/as_array.hpp>
#include <boost/range/algorithm_ext/erase.hpp>
#include <boost/range/algorithm/sort.hpp>
#include <boost/range/algorithm/unique.hpp>
#include <boost/random/discrete_distribution.hpp>

#include <random>
#include <unordered_set>
#include <vector>

namespace paal {
namespace ir {

/**
 * Generates all the components possible.
 * It iterates over all subsets of terminals with no more than K elements.
 */
class steiner_tree_all_generator {
private:
    template<typename Metric>
    using MTraits = typename data_structures::metric_traits<Metric>;

public:
    /// Constructor.
    steiner_tree_all_generator(int K = 4) : m_component_max_size(K) {}

    /// Generates all possible components.
    template<typename Metric, typename Terminals>
    void gen_components(const Metric& cost_map, const Terminals& terminals,
            const Terminals& steiner_vertices,
            steiner_components<
                typename MTraits<Metric>::VertexType,
                typename MTraits<Metric>::DistanceType>& components) {

        using Vertex = typename MTraits<Metric>::VertexType;
        using Dist = typename MTraits<Metric>::DistanceType;
        std::vector<Vertex> current_terminals;
        gen_all_components<Vertex, Dist>(components, 0, terminals.size(),
            current_terminals, cost_map, terminals, steiner_vertices);
    }
private:
    template<typename Vertex, typename Dist, typename Metric, typename Terminals>
    void gen_all_components(steiner_components<Vertex, Dist>& components,
            int first_avail, int last, std::vector<Vertex>& curr,
            const Metric& cost_map, const Terminals& terminals,
            const Terminals& steiner_vertices) {

        if (curr.size() > 1) {
            steiner_component<Vertex, Dist> c(cost_map, curr, steiner_vertices);
            components.add(std::move(c));
        }
        if ((int) curr.size() >= m_component_max_size)
            return;
        for (int i = first_avail; i < last; ++i) {
            curr.push_back(terminals[i]);
            gen_all_components(components, i + 1, last, curr, cost_map,
                terminals, steiner_vertices);
            curr.pop_back();
        }
    }

    int m_component_max_size;
};

namespace detail {

template<typename Vertex>
struct vertex_filter {
    bool operator()(Vertex v) const { return vertices.find(v) == vertices.end(); }
    std::unordered_set<Vertex> vertices;
};

}// detail

/**
 * Generates all the components possible based on the underlying graph.
 * It iterates over all subsets of terminals with no more than K elements.
 */
template<typename Graph, typename Vertex, typename Terminals>
class steiner_tree_graph_all_generator {
private:
    template<typename Metric>
    using MTraits = typename data_structures::metric_traits<Metric>;

public:
    /// Constructor.
    steiner_tree_graph_all_generator(const Graph& graph,
        const Terminals& terminals, int K = 4) : m_component_max_size(K),
            m_index(terminals),
            m_terminals_graph(m_index.size()) {
        initialize_terminals_graph(graph, terminals);
    }

    /// Generates all possible components.
    template<typename Metric>
    void gen_components(const Metric& cost_map, const Terminals& terminals,
            const Terminals& steiner_vertices,
            steiner_components<
                typename MTraits<Metric>::VertexType,
                typename MTraits<Metric>::DistanceType>& components) {

        using Dist = typename MTraits<Metric>::DistanceType;
        merge_vertices<Dist>(cost_map);
        std::vector<Vertex> current_terminals;
        gen_all_components<Dist>(components, 0, terminals.size(),
            current_terminals, cost_map, terminals, steiner_vertices);
    }

private:
    using AuxGraph = boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>;
    using VertexIndex = data_structures::bimap<Vertex>;

    int m_component_max_size;
    VertexIndex m_index;
    AuxGraph m_terminals_graph;

    void initialize_terminals_graph(const Graph& graph, const Terminals& terminals) {
        detail::vertex_filter<Vertex> filter;
        filter.vertices.insert(terminals.begin(), terminals.end());
        auto index = get(boost::vertex_index, graph);
        std::vector<int> components(num_vertices(graph));
        for (auto u : terminals) {
            for (auto v : terminals) {
                if (u == v) continue;
                filter.vertices.erase(u);
                filter.vertices.erase(v);
                boost::filtered_graph<Graph, boost::keep_all, decltype(filter)>
                    fg(graph, boost::keep_all{}, filter);
                boost::connected_components(fg, &components[0]);
                if (components[index[u]] == components[index[v]]) {
                    add_edge(get_idx(u), get_idx(v), m_terminals_graph);
                }
                filter.vertices.insert(u);
                filter.vertices.insert(v);
            }
        }
    }

    template<typename Dist, typename Metric>
    void merge_vertices(const Metric& cost_map) {
        auto range = vertices(m_terminals_graph);
        for (auto v_pair : data_structures::make_subsets_iterator_range<2>(
                range.first, range.second)) {
            auto i = std::get<0>(v_pair);
            auto j = std::get<1>(v_pair);
            if (cost_map(get_val(i), get_val(j)) == Dist{}) {
                merge_vertices(i, j);
                merge_vertices(j, i);
            }
        }
    }

    void merge_vertices(Vertex trg, Vertex src) {
        for (auto v : boost::as_array(adjacent_vertices(src,
                m_terminals_graph))) {
            if (trg != static_cast<Vertex>(v)) {
                add_edge(trg, v, m_terminals_graph);
            }
        }
    }

    auto get_idx(Vertex v) const -> decltype(m_index.get_idx(v)) {
        return m_index.get_idx(v);
    }

    auto get_val(int idx) const -> decltype(m_index.get_val(idx)) {
        return m_index.get_val(idx);
    }

    bool is_graph_component(const std::vector<Vertex>& comp) const {
        for (auto term_pair : data_structures::make_subsets_iterator_range<2>(
                comp.begin(), comp.end())) {
            if (!edge(
                    get_idx(std::get<0>(term_pair)),
                    get_idx(std::get<1>(term_pair)),
                    m_terminals_graph).second) {
                return false;
            }
        }
        return true;
    }

    template<typename Dist, typename Metric>
    void gen_all_components(steiner_components<Vertex, Dist>& components,
            int first_avail, int last, std::vector<Vertex>& curr,
            const Metric& cost_map, const Terminals& terminals,
            const Terminals& steiner_vertices) {

        // TODO implement a subset_iterator with K passed as a parameter
        // not as a template parameter (also in the gen_all_components method
        // in steiner_tree_all_generator)
        if (curr.size() > 1) {
            if (!is_graph_component(curr))
                return;
            steiner_component<Vertex, Dist> c(cost_map, curr, steiner_vertices);
            components.add(std::move(c));
        }
        if ((int) curr.size() >= m_component_max_size)
            return;
        for (int i = first_avail; i < last; ++i) {
            curr.push_back(terminals[i]);
            gen_all_components(components, i + 1, last, curr, cost_map,
                terminals, steiner_vertices);
            curr.pop_back();
        }
    }
};

/**
 * Makes a graph_all_generator object.
 */
template<typename Vertex, typename Graph, typename Terminals>
steiner_tree_graph_all_generator<Graph, Vertex, Terminals>
make_steiner_tree_graph_all_generator(const Graph& graph,
        const Terminals& terminals, int K = 4) {
    return steiner_tree_graph_all_generator<Graph, Vertex, Terminals>(
        graph, terminals, K);
}

/**
 * Generates specified number of components by selecting random elements.
 */
class steiner_tree_random_generator {
public:
    /// Constructor.
    steiner_tree_random_generator(int N = 100, int K = 3) :
            m_iterations(N), m_component_max_size(K) {
    }

    /// Generates a specified number of components by selecting random elements.
    template<typename Metric, typename Terminals>
    void gen_components(const Metric& cost_map, const Terminals & terminals,
            const Terminals& steiner_vertices,
            steiner_components<
                typename data_structures::metric_traits<Metric>::VertexType,
                typename data_structures::metric_traits<Metric>::DistanceType>& components) {

        using Vertex = typename data_structures::metric_traits<Metric>::VertexType;
        using Dist = typename data_structures::metric_traits<Metric>::DistanceType;
        if (terminals.size() < 2) {
            return;
        }
        for (int i = 0; i < m_iterations; ++i) {
            std::set<Vertex> curr;
            while ((int)curr.size() < m_component_max_size) {
                if (curr.size() > 1) {
                    int c =
                        (int)rand() %
                        m_component_max_size; // TODO: Is this fair probability?
                    if (c == 0) {
                        break;
                    }
                }
                int r = (int)rand() % terminals.size();
                curr.insert(terminals[r]);
            }
            std::vector<Vertex> elements(curr.begin(), curr.end());
            steiner_component<Vertex, Dist> c(cost_map, elements, steiner_vertices);
            components.add(std::move(c));
        }
        // TODO some terminals may not be in any component
    }

  private:
    int m_iterations;
    int m_component_max_size;
};

/**
 * Generates specified number of components by randomly selecting elements
 * with probability dependent on distance from vertices already selected.
 */
class steiner_tree_smart_generator {
    std::default_random_engine m_rng;
public:
    /// Constructor.
    steiner_tree_smart_generator(int N = 100, int K = 3, std::default_random_engine rng = std::default_random_engine{}) :
            m_iterations(N), m_component_max_size(K) {
    }

    /// Generates components.
    template<typename Metric, typename Terminals>
    void gen_components(const Metric& cost_map, const Terminals& terminals,
            const Terminals& steiner_vertices,
            steiner_components<
                    typename data_structures::metric_traits<Metric>::VertexType,
                    typename data_structures::metric_traits<Metric>::DistanceType>& components) {

        using Vertex = typename data_structures::metric_traits<Metric>::VertexType;
        using Dist = typename data_structures::metric_traits<Metric>::DistanceType;
        std::vector<Vertex> elements;
        std::vector<double> prob;
        for (Vertex start : terminals) {
            for (int i = 0; i < m_iterations; ++i) {
                elements.clear();
                elements.push_back(start);
                int limit = 2 + rand() % (m_component_max_size - 1);
                while ((int)elements.size() < limit) {
                    prob.resize(terminals.size());
                    for (int k = 0; k < (int)prob.size(); ++k) {
                        for (auto e : elements) {
                            if (e == terminals[k]) {
                                prob[k] = 0;
                                break;
                            }
                            int cost = cost_map(e, terminals[k]);
                            assert(cost > 0);
                            assign_max(prob[k], 1. / cost);
                        }
                    }
                    auto selected = boost::random::discrete_distribution<std::size_t>(prob)(m_rng);
                    if (selected == prob.size()) break;
                    elements.push_back(terminals[selected]);
                }
                boost::erase(elements, boost::unique<boost::return_found_end>(boost::sort(elements)));

                steiner_component<Vertex, Dist> c(cost_map, elements, steiner_vertices);
                components.add(std::move(c));
            }
        }
    }

  private:
    int m_iterations;
    int m_component_max_size;
};

} // ir
} // paal

#endif // PAAL_STEINER_STRATEGY_HPP

max_stars_repo_name: Kommeren/AA

max_issues_repo_name: Kommeren/AA

max_forks_repo_name: Kommeren/AA


text: #include <boost/property_map/shared_array_property_map.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include "difference_of_squares.h"
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(squares_of_sums)
{
    BOOST_REQUIRE_EQUAL(225, squares::square_of_sums(5));
    BOOST_REQUIRE_EQUAL(3025, squares::square_of_sums(10));
    BOOST_REQUIRE_EQUAL(25502500, squares::square_of_sums(100));
}

BOOST_AUTO_TEST_CASE(sum_of_squares)
{
    BOOST_REQUIRE_EQUAL(55, squares::sum_of_squares(5));
    BOOST_REQUIRE_EQUAL(385, squares::sum_of_squares(10));
    BOOST_REQUIRE_EQUAL(338350, squares::sum_of_squares(100));
}

BOOST_AUTO_TEST_CASE(up_to_5)
{
    BOOST_REQUIRE_EQUAL(225, squares::square_of_sums(5));
    BOOST_REQUIRE_EQUAL(55, squares::sum_of_squares(5));
    BOOST_REQUIRE_EQUAL(170, squares::difference(5));
}

BOOST_AUTO_TEST_CASE(up_to_10)
{
    BOOST_REQUIRE_EQUAL(3025, squares::square_of_sums(10));
    BOOST_REQUIRE_EQUAL(385, squares::sum_of_squares(10));
    BOOST_REQUIRE_EQUAL(2640, squares::difference(10));
}

BOOST_AUTO_TEST_CASE(up_to_100)
{
    BOOST_REQUIRE_EQUAL(25502500, squares::square_of_sums(100));
    BOOST_REQUIRE_EQUAL(338350, squares::sum_of_squares(100));
    BOOST_REQUIRE_EQUAL(25164150, squares::difference(100));
}
#if defined(EXERCISM_RUN_ALL_TESTS)
#endif