text:
// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/assert.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/ext/std/ratio.hpp>
#include <boost/hana/not_equal.hpp>

#include <ratio>
namespace hana = boost::hana;

BOOST_HANA_CONSTANT_CHECK(hana::equal(std::ratio<3, 4>{}, std::ratio<15, 20>{}));
BOOST_HANA_CONSTANT_CHECK(hana::not_equal(std::ratio<3, 4>{}, std::ratio<3, 5>{}));

int main() { }

ext: cpp


text:
#include "StdAfx.h"

#pragma warning(disable : 4146)
#pragma warning(disable : 4278)

#include <boost/algorithm/string.hpp>
#include <boost/bind.hpp>
#include <boost/algorithm/string/replace.hpp>

#include "CheckUpdatesDlg.h"
#include "LoginDlg.h"
#include "Notifier.h"

#include "../data/ServiceData.h"
#include "../data/NotificationsData.h"
#include "../data/ChangesTypes.h"
#include "../data/ToolbarSettings.h"

#include "../common/CommonConstants.h"
#include "../common/ResourceMessages.h"
#include "../common/URLUtils.h"

#include "../util/BitsUtils.h"
#include "../util/BrowserUtils.h"
#include "../util/COMWrappers.h"
#include "../util/HttpUtils.h"
#include "../util/ModuleUtils.h"
#include "../util/ScopeGuard.h"
#include "../util/StringUtils.h"
#include "../util/ShellUtils.h"

// Note: the functions below are exported and used by
// communication service to display UI based on some events

namespace facebook{

CComModule _Module;

__declspec(dllexport)
void showLoginDialog(const String& loginUrl, ULONG parentWindow, String& cookies) {

  CWnd *parent = CWnd::FromHandle((HWND)parentWindow);
  // initialize COM for this thread
  CoInitialize(0);
  ScopeGuard coUninitializeGuard(
    boost::bind(CoUninitializeWrapper()));
  if (::IsWindow((HWND)parentWindow)) {
    LoginDlg login(loginUrl, parent);
    login.DoModal();
    cookies = login.getCookies();
  }
}

__declspec(dllexport)
void showSelfNotification(const DataChangeEvents& changeID,
                          const ServiceData& sourceData) {
  if (ToolbarSettings::getInstance().isPopupEnabled()) {
    Notifier::showSelfNotification(changeID, sourceData);
  }
}

__declspec(dllexport)
void showFriendsChangePopup(const DataChangeEvents& changeID,
                            const FriendsIDs& friendsIds,
                            const ServiceData& sourceData) {
  if (ToolbarSettings::getInstance().isPopupEnabled()) {
    Notifier::showFriendsChangePopup(changeID, friendsIds, sourceData);
  }
}

__declspec(dllexport)
void showAlbumsChangePopup(const DataChangeEvents& changeID,
                           const AlbumsIDs& albumsIds,
                           const ServiceData& sourceData) {
  if (ToolbarSettings::getInstance().isPopupEnabled()) {
    Notifier::showAlbumsChangePopup(changeID, albumsIds, sourceData);
  }
}

/**
 * gets the url to the new version
 *
 * @return url to the new version
 */
String getUpdateUrl() {
  using boost::replace_all;
  String updateUrl;
  try {
    String facebookUpdatesUrl = kFacebookUpdatesUrl;
    //get the prefix for debug mode from registry if any
    String updateUrlPrefix = ToolbarSettings::getInstance().readStringValue(TO_UPDATEURLPREFIX);
    if (!updateUrlPrefix.empty()) {
      replace_all(facebookUpdatesUrl, _T("http://www"), updateUrlPrefix);
    }
    String version = getModuleVersion(NULL);
    HttpUtils::doGetRequest(facebookUpdatesUrl + version, updateUrl);
  }
  catch(...) {
  }

  if (updateUrl.empty() ||
    !isCorrectUrl(updateUrl)) {
    // no service available or old version
      updateUrl = String();
  }
  return updateUrl;
}

__declspec(dllexport)
void showNewVersionAvailablePopup() {
  if (!ToolbarSettings::getInstance().readValue(TO_CHECKUPDATES, true)) {
    // check for updates is disabled
    return;
  }
  CoInitialize(0);
  ScopeGuard coUninitializeGuard(
    boost::bind(CoUninitializeWrapper()));
  String updateUrl = getUpdateUrl();
  String updateFile = getApplicationDataDir() + _T("update.exe"); // temporary name
  if (updateUrl.empty()) {
    // if no new versions available but there are old updates - delete them
    if (PathFileExists(updateFile.c_str())) {
      DeleteFile(updateFile.c_str());
    }
    // no new version available.
    return;
  }
  int updatesCount =
    ToolbarSettings::getInstance().readIntValue(TO_UPDATESCOUNTER, 0);
  int updatesTimeout =
    ToolbarSettings::getInstance().readIntValue(TO_UPDATESTIMEOUT, kUpdatesTimeoutDefault);
  //if someone set 0
  if (updatesTimeout == 0) {
    updatesTimeout = kUpdatesTimeoutDefault;
  }

  BitsUtils bits;
  //check wherer we'are already in progress of download
  BitsUtils::BitsDownloadStatus bitsStatus =
    bits.checkDownloadStatus(kFacebookUpdateJobName);
  BOOL userResult;

  switch (bitsStatus) {
     case BitsUtils::DOWNLOAD_COMPLETED:
      // show form to install;
      userResult = CheckUpdatesDlg().DoModal();
      if (userResult == TRUE) {
        if (bits.completeDownload(kFacebookUpdateJobName)) {
          // terminate all Internet Explorer processes
          terminateAllProcesses(kIeProcessName);
          // reset the updates tries
          ToolbarSettings::getInstance().writeValue(
            TO_UPDATESCOUNTER, 0);
          // run the installation file
          execute(updateFile, String());
        } else {
          // if bits completion failed - open in UI
          bits.cancelDownload(kFacebookUpdateJobName);
          BrowserUtils::openUrlNewWindow(updateUrl);
        }
      }
      break;
    case BitsUtils::DOWNLOAD_IN_PROGRESS:
      // check for timeout
      if (bits.isDownloadExpired(kFacebookUpdateJobName, updatesTimeout)) {
          if (updatesCount < kMaxUpdatesTries) {
            ToolbarSettings::getInstance().writeValue(
              TO_UPDATESCOUNTER, ++updatesCount);
            // create new download
          }
          // it won't create download, but open new window
      } else {
        // do nothing - wait for completion
        break;
      }
    case BitsUtils::NO_DOWNLOAD:
      if (updatesCount < kMaxUpdatesTries) {
        // start the updates process
        bool bitsResult = bits.createDownload(kFacebookUpdateJobName,
                                              updateUrl,
                                              updateFile);
        if (!bitsResult) {
          ToolbarSettings::getInstance().writeValue(
            TO_UPDATESCOUNTER, ++updatesCount);
        }
        break;
      }
      // if not created task then cancel download and open in browser
    case BitsUtils::DOWNLOAD_FAILED:
      // cancel download
      bits.cancelDownload(kFacebookUpdateJobName);
      if (updatesCount < kMaxUpdatesTries) {
        break;
      }
      // open the link with url
      userResult = CheckUpdatesDlg().DoModal();
      if (userResult == TRUE) {
        //if yes then redirect to the url with new version
        BrowserUtils::openUrlNewWindow(updateUrl);
        // maybe following downloads will be sucessfull
        ToolbarSettings::getInstance().writeValue(
            TO_UPDATESCOUNTER, 0);
      }
      break;
  }
}

} // !namespace facebook

max_stars_repo_name: facebookarchive/ie-toolbar

max_issues_repo_name: facebookarchive/ie-toolbar

max_forks_repo_name: facebookarchive/ie-toolbar


text:
#include <iostream>
#include <map>
#include <boost/program_options.hpp>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp> // boost::is_any_of
#include "try.h"
#include "PSSPANNdata.h"
#include "ANNCore.h"
//#include "try.h"
using namespace std;
namespace opt = boost::program_options;

int main(int argc,char* argv[])
{
    //parameters
    opt::options_description desc("ALL options");
    desc.add_options()
        ("settings,s", opt::value<std::string>(), "the .pssp setting file")
        ("trainfile,t", opt::value<std::string>(), "the training file for training")
        ("validatefile,v", opt::value<std::string>(), "the validate file for training")
        ("weightfile,w", opt::value<std::string>(), "the weight file")
        ("weightbiasfile,b", opt::value<std::string>(), "the weight bias file")
        ("testfile,e", opt::value<std::string>(), "the test file for testing")
        ("predictfile,p", opt::value<std::string>(), "the predict file for prediction")
        ("outputprefix,o", opt::value<std::string>(), "the prefix for output")
        ("help,h", "this help")
        ;
    opt::variables_map vm;
    opt::store(opt::parse_command_line(argc,argv,desc),vm);
    opt::notify(vm);
    if(vm.count("help")){
        std::cout<<desc<<"\n";
        return 1;
    }
    //read options
    ifstream settings_file;
    try{
        settings_file.open(vm["settings"].as<std::string>());
    }
    catch(...){
        cout<<"Need the .pssp setting file\n";
        return 0;
    }
    //read file to map
    std::map<std::string,std::string> settings;
    std::string line;
    std::vector<std::string> vec_store;
    while(getline(settings_file,line)){
        if(line[0]=='#') continue;
        boost::split(vec_store, line,boost::is_any_of("\t"));
        settings[vec_store[0]]=vec_store[1];
        vec_store.clear();
    }

    cout << "PSSPANNcc" << endl;
    //Some common process
    int* topology;
    vec_store.clear();
    boost::split(vec_store, settings["HiddenLayerNode"],boost::is_any_of(","));
    int HiddenLayerNumber=stoi(settings["HiddenLayerNumber"]);
    topology=(int*)malloc(sizeof(int)*(2+HiddenLayerNumber));
    int weight_length=0;int weight_bias_length=0;

    for(int i=1;i<HiddenLayerNumber+1;i++) topology[i]=stoi(vec_store[i-1]);
    topology[0]=stoi(settings["InputLayerNode"]);
    topology[HiddenLayerNumber+1]=2;
    bool biasNode=false;
    if(settings["biasNode"]=="true") biasNode=true;
    float* weight;float* weight_bias;bool* result_store;
    if(settings["WeightAvailable"]=="true"){
        for(int i=1;i<HiddenLayerNumber+2;i++){
            weight_length+=topology[i]*topology[i-1];
        }
        try{
            try_cpp::read_file_in_float(weight,vm["weightfile"].as<std::string>(),weight_length);
        }
        catch(...){
            cout<<"Error in load weight file\n";
            return 0;
        }
    }
    if(settings["WeightbiasAvailable"]=="true"){
        for(int i=1;i<HiddenLayerNumber+2;i++){
            weight_bias_length+=topology[i];
        }
        try{
            try_cpp::read_file_in_float(weight_bias,vm["weightbiasfile"].as<std::string>(),weight_bias_length);
        }
        catch(...){
            cout<<"Error in load weight bias file\n";
            return 0;
        }
    }
    float threshold=0.3;
    if(settings.find("threshold")!=settings.end()){threshold = stof(settings["threshold"]);}
    bool has_ss=true;
    if(settings["SecondarayStructureInData"]=="false") has_ss=false;
    if(vm.find("outputprefix")==vm.end()){
        cout<<"Error! Need outputprefix\n";
        return 0;
    }
    //try_cpp::test_ANNCore_Prediction("../data/50_ss.txt");
    if(settings.find("Training")!=settings.end()){
        //training
        if(has_ss==false){
            cout<<"Error! For test, SecondarayStructureInData should be true\n";
            return 0;
        }
        PSSPANNdata* training;
        PSSPANNdata* validate;

        if(vm.find("trainfile")==vm.end()){
            cout<<"Error! Need correct trainfile input\n";
            return 0;
        }
        try{
            training = new PSSPANNdata(vm["trainfile"].as<std::string>());
        }
        catch(...){
            cout<<"Error! Need correct trainfile input\n";
            return 0;
        }
        bool Validation=false;

        if(settings["Validation"]=="true"){
            Validation=true;
            if(vm.find("validatefile")==vm.end()){
                cout<<"Error! Need correct validatefile input\n";
                return 0;
            }
            try{
                validate = new PSSPANNdata(vm["validatefile"].as<std::string>());
            }
            catch(...){
                cout<<"Error! Need correct validatefile input\n";
                return 0;
            }

        }
        threshold=ANN_Training_bool<PSSPANNdata>(training,topology,2+HiddenLayerNumber,
                                       PSSP_threshold_calculator,
                                       PSSP_from_output_to_result,
                                       weight,weight_bias,result_store,
                                       threshold,stoi(settings["MaxIteration"]),
                                       false,
                                       Validation,validate,
                                       stof(settings["Error"]),biasNode,20,
                                       weight_length,weight_bias_length
                                       );

    cout<<"threshold"<<threshold<<endl;
    weight_length=0;weight_bias_length=0;
    for(int i=1;i<HiddenLayerNumber+2;i++){
        weight_length+=topology[i]*topology[i-1];
    }
    for(int i=1;i<HiddenLayerNumber+2;i++){
        weight_bias_length+=topology[i];
    }
    try_cpp::print_array_file<float*>(weight,weight_length,vm["outputprefix"].as<std::string>() + "_weight.txt");
    try_cpp::print_array_file<float*>(weight_bias,weight_bias_length,vm["outputprefix"].as<std::string>() + "_weight_bias.txt");
    delete training;
    if(Validation) delete validate;
    }
    else if(settings.find("Prediction")!=settings.end()){
        //prediction
        if(vm.find("predictfile")==vm.end()){
            cout<<"Error! Need correct predictfile input\n";
            return 0;
        }
        PSSPANNdata prediction(vm["predictfile"].as<std::string>(),has_ss);
        ANN_Training_bool<PSSPANNdata>(&prediction,topology,2+HiddenLayerNumber,
                                       PSSP_threshold_calculator,
                                       PSSP_from_output_to_result,
                                       weight,weight_bias,result_store,
                                       threshold,1,
                                       true,
                                       false,NULL,
                                       0.1,biasNode,0,
                                       weight_length,weight_bias_length
                                       );
        print_ss(&prediction,result_store,prediction.data_size()*2,vm["outputprefix"].as<std::string>() + "_prediction.txt");
    }
    else if(settings.find("Test")!=settings.end()){
        //test
        if(vm.find("testfile")==vm.end()){
            cout<<"Error! Need correct testfile input\n";
            return 0;
        }
        PSSPANNdata test(vm["testfile"].as<std::string>());
        if(has_ss==false){
            cout<<"Error! For test, SecondarayStructureInData should be true\n";
            return 0;
        }
        ANN_Training_bool<PSSPANNdata>(&test,topology,2+HiddenLayerNumber,
                                       PSSP_threshold_calculator,
                                       PSSP_from_output_to_result,
                                       weight,weight_bias,result_store,
                                       threshold,1,
                                       true,
                                       false,NULL,
                                       0.1,biasNode,0,
                                       weight_length,weight_bias_length
                                       );
        cout<<"Q3:"<<test.Q3(result_store)<<endl;
        float* CC;
        CC=test.CC(result_store);
        printf("CC_H:%.6f\n",CC[0]);printf("CC_E:%.6f\n",CC[1]);printf("CC_C:%.6f\n",CC[2]);
        print_ss(&test,result_store,test.data_size()*2,vm["outputprefix"].as<std::string>() + "_test.txt");
        free(CC);free(weight);free(weight_bias);free(result_store);
    }
    else{
        cout<<"Wrong setting file\n";
    }
    return 0;
}

max_stars_repo_name: LuezhenYuan/BioinformaticsTools

max_issues_repo_name: LuezhenYuan/BioinformaticsTools

max_forks_repo_name: LuezhenYuan/BioinformaticsTools


text:
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)

Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_FIRST_SCALAR_HPP
#define BOOST_CORE_FIRST_SCALAR_HPP

#include <boost/config.hpp>
#include <cstddef>

namespace boost {
namespace detail {

template <class T> struct make_scalar { typedef T type; };

template <class T, std::size_t N> struct make_scalar<T[N]> {
  typedef typename make_scalar<T>::type type;
};

} // namespace detail

template <class T> BOOST_CONSTEXPR inline T *first_scalar(T *p) BOOST_NOEXCEPT {
  return p;
}

template <class T, std::size_t N>
BOOST_CONSTEXPR inline typename detail::make_scalar<T>::type *
first_scalar(T (*p)[N]) BOOST_NOEXCEPT {
  return boost::first_scalar(&(*p)[0]);
}

} // namespace boost

#endif

ext: hpp

max_stars_repo_name: henrywarhurst/matrix

max_issues_repo_name: henrywarhurst/matrix

max_forks_repo_name: henrywarhurst/matrix


text:
//
// Copyright Jason Rice 2017
// 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 NBDL_SQL_DB_DETAIL_STRING_SUM_HPP
#define NBDL_SQL_DB_DETAIL_STRING_SUM_HPP

#include <mpdef/list.hpp>

#include <boost/hana/plus.hpp>
#include <boost/hana/string.hpp>
#include <boost/hana/sum.hpp>

namespace nbdl::sql_db::detail
{
  namespace hana = boost::hana;

  constexpr auto string_sum = [](auto ...xs)
  {
    return hana::sum<hana::string_tag>(mpdef::make_list(xs...));
  };

  template <typename Delimeter = hana::string<' '>>
  constexpr auto string_sum_join = [](auto x1, auto ...xs)
  {
    return string_sum(x1, hana::plus(Delimeter{}, xs)...);
  };

  using identifier_quote_string = hana::string<'"'>; // SQL implementation specific (ANSI)

  template <typename Identifier>
  using identifier_quote = decltype(
    hana::plus(identifier_quote_string{},
    hana::plus(Identifier{},
      identifier_quote_string{}
    ))
  );
}

#endif

max_stars_repo_name: ricejasonf/nbdl

max_issues_repo_name: ricejasonf/nbdl

max_forks_repo_name: ricejasonf/nbdl


text:
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// test_class_info_save.cpp: test implementation level trait

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// test implementation level "object_class_info"
// should pass compilation and execution

#include <fstream>
#include <string>

#include <boost/preprocessor/stringize.hpp>

#include <serialization/level.hpp>
#include <serialization/version.hpp>
#include <serialization/tracking.hpp>
#include <serialization/nvp.hpp>

#include <I3Test.h>

// first case : serialize WITHOUT class information
class A
{
    friend class icecube::serialization::access;
    template<class Archive>
    void serialize(Archive & /*ar*/, const unsigned int file_version){
        // classes that don't save class info always have a version number of 0
        ENSURE(file_version == 0);
        static_assert(0 == ::icecube::serialization::version<A>::value,
                      "classes that don't save class info always have a version number of 0");
        ++count;
    }
public:
    unsigned int count;
    A() : count(0) {}
};

I3_CLASS_IMPLEMENTATION(A, ::icecube::serialization::object_serializable)
I3_CLASS_TRACKING(A, ::icecube::serialization::track_never)

// second case : serialize WITH class information
// note: GCC compile fails if this is after the class declaration
class B;
I3_CLASS_VERSION(B, 2)

class B
{
    friend class icecube::serialization::access;
    template<class Archive>
    void serialize(Archive & /*ar*/, const unsigned int file_version){
        // verify at execution that correct version number is passed on save
        ENSURE(
            static_cast<const int>(file_version)
            == ::icecube::serialization::version<B>::value
        );
        ++count;
    }
public:
    unsigned int count;
    B() : count(0) {}
};

I3_CLASS_IMPLEMENTATION(B, ::icecube::serialization::object_class_info)
I3_CLASS_TRACKING(B, icecube::serialization::track_always)

#include <iostream>

template <typename TS /*test settings*/>
void out(const char *testfile, const A & a, const B & b)
{
    typename TS::test_ostream os(testfile, TS::TEST_STREAM_FLAGS);
    typename TS::test_oarchive oa(os, TS::TEST_ARCHIVE_FLAGS);
    // write object twice to check tracking
    oa << I3_SERIALIZATION_NVP(a);
    oa << I3_SERIALIZATION_NVP(a);
    ENSURE(a.count == 2);  // no tracking => redundant saves
    oa << I3_SERIALIZATION_NVP(b);
    oa << I3_SERIALIZATION_NVP(b);
    ENSURE(b.count == 1);  // tracking => no redundant saves
}

TEST_GROUP(class_info_save)

#define TEST_SET(name)\
TEST(name ## _test_class_info_save){ \
    A a; \
    B b; \
    std::string filename = I3Test::testfile(BOOST_PP_STRINGIZE(name) "_class_info_load_" BOOST_PP_STRINGIZE(I3_ARCHIVE_TEST)); \
    out<test_settings>(filename.c_str(), a, b); \
}
//do _not_ remove files, as they are needed by test_class_info_load

#define I3_ARCHIVE_TEST binary_archive.hpp
#include "select_archive.hpp"
TEST_SET(binary_archive)

#undef I3_ARCHIVE_TEST
#define I3_ARCHIVE_TEST text_archive.hpp
#include "select_archive.hpp"
TEST_SET(text_archive)

#undef I3_ARCHIVE_TEST
#define I3_ARCHIVE_TEST xml_archive.hpp
#include "select_archive.hpp"
TEST_SET(xml_archive)

#undef I3_ARCHIVE_TEST
#define I3_ARCHIVE_TEST portable_binary_archive.hpp
#include "select_archive.hpp"
TEST_SET(portable_binary_archive)

// EOF


text:
///////////////////////////////////////////////////////////////////////////////
// BSD 3-Clause License
//
// Copyright (C) 2020-2021, LAAS-CNRS, University of Edinburgh
// Copyright note valid unless otherwise stated in individual files.
// All rights reserved.
///////////////////////////////////////////////////////////////////////////////

#ifndef CROCODDYL_CORE_MATHBASE_HPP_
#define CROCODDYL_CORE_MATHBASE_HPP_

#include <Eigen/Core>
#include <Eigen/Geometry>

namespace crocoddyl {

template <typename _Scalar>
struct MathBaseTpl {
 public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  typedef _Scalar Scalar;
  typedef Eigen::Matrix<Scalar, 2, 1> Vector2s;
  typedef Eigen::Matrix<Scalar, 3, 1> Vector3s;
  typedef Eigen::Matrix<Scalar, 4, 1> Vector4s;
  typedef Eigen::Matrix<Scalar, 6, 1> Vector6s;
  typedef Eigen::Matrix<Scalar, 2, 2> Matrix2s;
  typedef Eigen::Matrix<Scalar, 3, 3> Matrix3s;
  typedef Eigen::Matrix<Scalar, 4, 6> Matrix46s;
  typedef Eigen::Matrix<Scalar, 6, 6> Matrix6s;
  typedef Eigen::Matrix<Scalar, 1, 2> RowVector2s;

  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 3> MatrixX3s;
  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 6> MatrixX6s;
  typedef Eigen::Matrix<Scalar, 3, Eigen::Dynamic> Matrix3xs;
  typedef Eigen::Matrix<Scalar, 6, Eigen::Dynamic> Matrix6xs;

  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1> VectorXs;
  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixXs;
  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatrixXsRowMajor;
  typedef Eigen::Array<Scalar, Eigen::Dynamic, 1> ArrayXs;
  typedef Eigen::Quaternion<Scalar> Quaternions;
  typedef Eigen::DiagonalMatrix<Scalar, Eigen::Dynamic> DiagonalMatrixXs;
};

}  // namespace crocoddyl

#endif

max_stars_repo_name: spykspeigel/crocoddyl

max_issues_repo_name: spykspeigel/crocoddyl

max_forks_repo_name: spykspeigel/crocoddyl


text:
//
// Created by jestjest on 11/19/17.
//

#include <boost/bind.hpp>
#include <cereal/archives/binary.hpp>
#include <messages/queryMessage.hpp>
#include <messages/responseMessage.hpp>
#include <messages/findQuery.hpp>
#include <messages/storeQuery.hpp>
#include <queue>
#include <messages/findValueResponse.hpp>
#include <messages/findNodeResponse.hpp>
#include "protocol.hpp"
#include "network.hpp"

namespace kdml {

    using boost::asio::ip::udp;
    namespace asio = boost::asio;
    namespace mp = boost::multiprecision;

    Protocol::Protocol(const NodeInfo& node)
            : owner(node),
              routingTable(node.id),
              ioService{},
              ioLock(new asio::io_service::work(ioService)) {

        network = new net::Network(node, ioService, this);
        network->startReceive();
        ioThread = std::thread([this]() { ioService.run(); });
    }

    void Protocol::async_get(mp::uint256_t key, kdml::GetCallback callback) {
        node_lookup(key, callback, true, false);
    }

    void Protocol::async_store(mp::uint256_t key, NodeInfo value) {
        node_lookup(key, NULL, false, true);
    }

    // TODO queue user commands while bootstrapping).
    void Protocol::bootstrap(const NodeInfo& peer) {
        Nodes endpoints = resolveEndpoint(peer);
        probePeers(std::move(endpoints));
    }

    void Protocol::join() {
        ioService.stop();
        if (ioThread.joinable()) {
            ioThread.join();
        }
    }

    void Protocol::handleReceive(const boost::system::error_code& error,
                                 std::size_t /*bytes_transferred*/) {

        if (error == asio::error::operation_aborted) {
            return;
        }

        asio::streambuf sb;
        boost::system::error_code recvError = network->populateBuf(sb);

        if (!recvError) {
            NodeInfo sender(network->getRemotePeer());
            std::shared_ptr<kdml::net::Message> message;
            {
                std::istream istream(&sb);
                cereal::BinaryInputArchive iarchive(istream);
                iarchive(message);
            }

            std::cout << "Parsed message: " << *message << std::endl;
            handleMessage(message, sender);
        }
        network->startReceive();
    }

    void Protocol::probePeers(Nodes endpoints) {
        if (endpoints.empty()) {
            throw std::string("Failed to find peers");
        } else {
            NodeInfo ep = endpoints.back();
            endpoints.pop_back();

            SimpleCallback onPong = [=](bool failure) {
                if (failure) {
                    probePeers(endpoints);
                } else {
                    auto bucket = routingTable.insertNode(ep);
                    node_lookup(owner.id, [bucket](Nodes found) {
                        // TODO: refresh buckets after bucket
                    }, false, false);
                }
            };

            network->send_ping(ep, onPong);
        }
    }

    Nodes Protocol::resolveEndpoint(const NodeInfo& endpoint) {
        udp::resolver resolver(ioService);
        udp::resolver::query query(udp::v4(), endpoint.getIpAddr(),
                                   std::to_string(endpoint.port));
        Nodes eps;
        auto resolvedEndpoints = resolver.resolve(query);
        decltype(resolvedEndpoints) end;

        while (resolvedEndpoints != end) {
            auto ep = (*resolvedEndpoints).endpoint();
            eps.emplace_back(NodeInfo{ep.address().to_string(), ep.port()});
            resolvedEndpoints++;
        }
        return eps;
    }

    void Protocol::handleMessage(std::shared_ptr<net::Message> msg,
                                 NodeInfo sender) {

        switch (msg->getMessageType()) {
            case net::MessageType::ERROR: {
                std::cerr << "Received error message: " << *msg << std::endl;
                break;
            }
            case net::MessageType::QUERY: {
                routingTable.insertNode(sender);
                handleQuery(std::dynamic_pointer_cast<net::QueryMessage>(msg), std::move(sender));
                break;
            }
            case net::MessageType::RESPONSE: {
                routingTable.insertNode(sender);
                handleResponse(std::dynamic_pointer_cast<net::ResponseMessage>(msg));
                break;
            }
        }
    }

    void Protocol::find_value_callback(Nodes nodes, bool found, GetCallback callback) {
        if(found) {
            std::cout << "Found nodes: first one: " << (*nodes.begin()).getIpAddr() << std::endl;
            callback(nodes);
        } else {
            std::cout << "Did not find a knowledgeable node." << std::endl;
            callback({});
        }
    }

    void Protocol::store_callback(mp::uint256_t key, Nodes nodes) {
        for(NodeInfo node : nodes) {
            network->send_store(key, node);
        }
    }

    /*
     * Pick a closest nodes to key from bucket, send asynchronous FIND_NODE rpcs to each.
     */
    void Protocol::node_lookup(mp::uint256_t key, GetCallback callback, bool findValue, bool store) {

        std::vector<NodeInfo> a_closest_nodes = routingTable.getAClosestNodes(ALPHA, key);
        RequestState request_state;
        request_state.key = key;
        request_state.findValue = findValue;
        request_state.store = store;
        request_state.callback = callback;
        for(NodeInfo node : a_closest_nodes) {
            NodeInfoWrapper node_wrapper(key, node);
            request_state.k_closest_nodes.insert(node_wrapper);
            request_state.responses_waiting++;
            if (request_state.findValue) {
                network->send_find_value(key, node);
            } else {
                network->send_find_node(key, node);
            }
        }
        lookups[key] = request_state;
    }

    //TODO: Nodes that fail to respond should be removed from consideration unless they respond

    void Protocol::node_lookup_callback(mp::uint256_t sender, RequestState& request_state, Nodes k_nodes,
                                        mp::uint256_t key, bool found) {

        request_state.responses_waiting--;
        request_state.responded_nodes.insert(sender);

        if (found) {
            assert(request_state.findValue);
            // If found, k_nodes will be the list of values associated with key
            find_value_callback(k_nodes, found, request_state.callback);
            lookups.erase(lookups.find(key), lookups.end());
            return;
        }

        for(NodeInfo node : k_nodes) {
            NodeInfoWrapper node_wrapper(key, node);
            request_state.k_closest_nodes.insert(node_wrapper);
        }

        // Query alpha more nodes
        // Terminates when has queried and heard responses from k closest nodes
        int responded = 0;
        bool k_responded = true;
        for (auto it=request_state.k_closest_nodes.begin(); it!=request_state.k_closest_nodes.end(); ++it) {
            if (request_state.responses_waiting >= ALPHA) break;
            if (k_responded && responded >= kdml::K) break;

            NodeInfoWrapper node_wrapper = *it;

            // Keep track if k closest nodes have responded
            auto responded_it = request_state.responded_nodes.find(node_wrapper.node.id);
            if (responded_it != request_state.responded_nodes.end()) {
                responded++;
            } else {
                k_responded = false;
            }

            // Do not query if node has already been queried
            auto queried_it = request_state.queried_nodes.find(node_wrapper.node.id);
            if (queried_it != request_state.queried_nodes.end()) {
                continue;
            }

            request_state.responses_waiting++;
            request_state.queried_nodes.insert(node_wrapper.node.id);
            if (request_state.findValue) {
                network->send_find_value(key, node_wrapper.node);
            } else {
                network->send_find_node(key, node_wrapper.node);
            }
        }

        if (request_state.responses_waiting == 0) {
            Nodes k_closest_nodes_list;
            for (auto it=request_state.k_closest_nodes.begin(); it!=request_state.k_closest_nodes.end()
                    && k_closest_nodes_list.size() < kdml::K; ++it) {
                NodeInfoWrapper node_wrapper = *it;
                k_closest_nodes_list.push_back(node_wrapper.node);
            }
            if (request_state.findValue) {
                find_value_callback(k_closest_nodes_list, found, request_state.callback);
            } else if (request_state.store){
                store_callback(key, k_closest_nodes_list);
            } else {
                std::cout << "Completed lookup for bootstrapping" << std::endl;
            }

            lookups.erase (lookups.find(key), lookups.end());
        }
    }

    void Protocol::handleQuery(std::shared_ptr<net::QueryMessage> msg,
                               NodeInfo sender) {

        switch (msg->getQueryType()) {
            case net::QueryType::PING: {
                network->send_ping_response(sender, msg->getTid());
                break;
            }
            case net::QueryType::FIND_NODE: {
                auto query = std::dynamic_pointer_cast<net::FindQuery>(msg);
                auto nodes = routingTable.getKClosestNodes(query->getTarget());
                network->send_find_node_response(sender, nodes, msg->getTid());
                break;
            }
            case net::QueryType::FIND_VALUE: {
                auto query = std::dynamic_pointer_cast<net::FindQuery>(msg);
                auto value = storage.find(query->getTarget());
                bool found = (value != storage.end());
                Nodes result;
                if (found) {
                    result = value->second;
                } else {
                    result = routingTable.getKClosestNodes(query->getTarget());
                }
                network->send_find_value_response(sender, found, result,
                                                  msg->getTid());
                break;
            }
            case net::QueryType::STORE: {
                auto query = std::dynamic_pointer_cast<net::StoreQuery>(msg);
                bool success = false;

                try {
                    storage[query->getKey()].emplace_back(query->getVal());
                    success = true;
                } catch (...) {}

                network->send_store_response(sender, success, msg->getTid());
                break;
            }
        }
    }

    void Protocol::handleResponse(std::shared_ptr<net::ResponseMessage> msg) {
        uint32_t tid = msg->getTid();

        if (!network->containsRequest(tid)) {
            std::cerr << "Received alien message" << *msg << std::endl;
            return;
        }

        Request outstanding = network->getRequest(tid);
        if (msg->getQueryType() == net::QueryType::PING) {
            network->removeRequest(tid);
            outstanding.onDone(msg, false);
        } else {
            auto it = lookups.find(outstanding.key);
            if (it != lookups.end()) {
                RequestState& request_state = it->second;
                if (outstanding.findValue) {
                    auto value_res = std::dynamic_pointer_cast<net::FindValueResponse>(msg);
                    node_lookup_callback(msg->id, request_state, value_res->data, outstanding.key, value_res->found);
                } else {
                    auto find_res = std::dynamic_pointer_cast<net::FindNodeResponse>(msg);
                    node_lookup_callback(msg->id, request_state, find_res->nodes, outstanding.key, false);
                }
            } else {
                std::cout << "Got response for nonexistent nodes lookup" << std::endl;
            }
        }
    }

}

max_stars_repo_name: jakerachleff/simple-kademlia

max_issues_repo_name: jakerachleff/simple-kademlia

max_forks_repo_name: jakerachleff/simple-kademlia


text:
// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
/*

    This is an example illustrating the use of the gui api from the dlib C++ Library.

    This is a pretty simple example.  It makes a window with a user
    defined widget (a draggable colored box) and a button.  You can drag the
    box around or click the button which increments a counter.
*/

#include <dlib/gui_widgets.h>
#include <sstream>
#include <string>

#include "snake-pop.h"
#include "snake-ai.h"

extern int generation;
extern int highscore;
extern bool auto_capture_highest;
extern bool snake_warp;
double last_avg_score = 0.0;
extern std::string train_out_filename;
extern ofstream train_file;
extern bool end_it_all;
extern std::mutex train_out_mutex;
int    max_gens = 0;

using namespace std;
using namespace dlib;

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

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

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

    if( argc < 5 )
    {
        printf("%s [width] [height] [population] [threads]\n ", argv[0] );
        exit(0);
    }

    ::initscr();
    ::cbreak();
    ::noecho();
    ::curs_set(0);
    ::clear();

    int wx = atoi( argv[1] );
    int wy = atoi( argv[2] );
    int population = atoi( argv[3] );
    int threads = atoi( argv[4] );
    std::string file, training_file;

    if( argc > 5 )
    {
        if( atoi( argv[5] ) == 1 )
        {
            if( argc > 7 )
            {
               training_file = argv[7];
            }

            ::refresh();
            ::endwin();

            Snake snake( ::time(NULL) );
            snake.init( wx, wy );

            snake.train( training_file );

/*
            ::initscr();
            ::cbreak();
            ::noecho();
            ::curs_set(0);
            ::clear();

            while(1)
            {
               snake.show();
            }
*/

            exit(0);

        }
        else
            file = argv[5];
    }

    if( argc > 6 )
    {
        ::max_gens = atoi( argv[6] );

        if( ::max_gens == 0 )
        {
            train_out_filename = argv[6];
            train_file.open( train_out_filename );
        }
        else
        {
            ::auto_capture_highest = true;
            ::snake_warp = true;
        }
    }

    Population pop( wx, wy, population, threads, file );

    pop.initializeSnakes( wx, wy );

    pop.update();

    pop.show();

    if( train_out_filename.length() > 0 )
    {
        end_it_all = true;
        train_out_mutex.lock();
        train_file.close();
        train_out_mutex.unlock();
        dlib::sleep( 500 );
        ::refresh();
        ::endwin();

        exit(0);
    }

    if( file.empty() )
        file = "nameless_snake.net";

    int localHighScore = pop.bestScore();

    while( true )
    {
        if( pop.done() )
        {
            pop.calculateFitness();
            ::last_avg_score = pop.avg_score();
            pop.naturalSelection();
            if( auto_capture_highest )
            {
               if( pop.bestScore() > localHighScore )
               {
                  std::stringstream num;
                  num << "." << pop.bestScore();
                  serialize( file + num.str()  ) << pop.bestSnake->get_net();
               }
            }
            //highscore = pop.bestSnake->score();
            pop.show();
        }
        else
        {
            //pop.update();
            pop.handle_snakes();
            //pop.show();
        }

        localHighScore = pop.bestScore();

        dlib::sleep( 10 );

        if( ::max_gens > 0 && ::generation > ::max_gens )
            break;
    }
        ::sleep(1);

    ::refresh();
    ::endwin();

    return 0;
}

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

// Normally, if you built this application on MS Windows in Visual Studio you
// would see a black console window pop up when you ran it.  The following
// #pragma directives tell Visual Studio to not include a console window along
// with your application.  However, if you prefer to have the console pop up as
// well then simply remove these #pragma statements.
#ifdef _MSC_VER
#   pragma comment( linker, "/entry:mainCRTStartup" )
#   pragma comment( linker, "/SUBSYSTEM:WINDOWS" )
#endif

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

max_stars_repo_name: busysteve/SnakeAI-cpp-dlib

max_issues_repo_name: busysteve/SnakeAI-cpp-dlib

max_forks_repo_name: busysteve/SnakeAI-cpp-dlib


text:
#pragma once
#include <vector>
#include <functional>
#include <ext/utility.hpp> //for ext::first_el для batch_lru_cache

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/member.hpp>

#include <boost/call_traits.hpp>
#include <boost/swap.hpp>
#include <boost/assert.hpp>

namespace ext
{
	/// lru кеш
	/// реализация подсмотрена здесь http://timday.bitbucket.org/lru.html,
	/// но есть небольшие изменения
	/// кеш разделен на 3 случая: manual_lru_cache, где пользователь сам заполняет кеш
	///                          lru_cache оригинальный кеш, получающий по одной записи за раз
	///                          batch_lru_cache кеш получающий пачку записей за раз
	///
	/// для получения данных используется не std::function, а функтор
	/// специальные функторы function_acquire/batch_function_acquire позволяют не писать новый функтор,
	/// а просто передать некое выражение в std::function<bool (Key, Val)>/std::function<bool (Key, vector<pair<Key, Val>> & )>

	/// кеш с ручной подгрузкой данных
	template <
		class Key,
		class Value,
		class Hash = boost::hash<Key>,
		class KeyEqual = std::equal_to<>
	>
	class manual_lru_cache
	{
	public:
		typedef typename boost::call_traits<Key>::param_type key_param;
		typedef typename boost::call_traits<Value>::param_type value_param;

		typedef Key key_type;
		typedef Value mapped_type;
		typedef Hash hasher;
		typedef KeyEqual key_equal;

	private:
		struct entry
		{
			key_type key;
			mapped_type value;

			entry(key_type && key, mapped_type && value)
				: key(std::move(key)), value(std::move(value)) {}
		};

		typedef boost::multi_index_container <
			entry,
			boost::multi_index::indexed_by<
				boost::multi_index::hashed_unique<
					boost::multi_index::member<entry, key_type, &entry::key>,
					hasher,
					key_equal
				>,
				boost::multi_index::sequenced<>
			>
		> cache_container;

		static const std::size_t ByCode = 0;
		static const std::size_t ByPos = 1;

		typedef typename cache_container::template nth_index<ByCode>::type  code_view;
		typedef typename cache_container::template nth_index<ByPos>::type   pos_view;

	private:
		cache_container m_cache;
		std::size_t m_cache_maxsize;

		void touch(typename code_view::iterator it)
		{
			auto & pv = m_cache.template get<ByPos>();
			auto posIt = m_cache.template project<ByPos>(it);
			// перемещаем элемент по it в конец списка
			pv.relocate(pv.end(), posIt);
		}

	public:
		/// скидывает наиболее давно используемый элемент
		void drop_last()
		{
			auto & pv = m_cache.template get<ByPos>();
			pv.pop_front();
		}

		mapped_type & insert(key_type key, mapped_type data)
		{
			bool inserted;
			typename code_view::iterator pos;
			std::tie(pos, inserted) = m_cache.emplace(std::move(key), std::move(data));

			if (!inserted) {
				// const_cast is safe because our index is only by key
				auto & val = const_cast<mapped_type &>(pos->value);
				boost::swap(val, data);
				touch(pos);
				return val;
			}
			else {
				BOOST_ASSERT_MSG(m_cache_maxsize > 0, "lru_cache can't work with CacheMaxSize == 0");
				if (m_cache_maxsize < m_cache.size())
					drop_last();

				// const_cast is safe because our index is only by key
				return const_cast<mapped_type &>(pos->value);
			}
		}

		/// получает данные по ключу, если таких данных нет, то throws std::out_of_range
		mapped_type & at(key_param key)
		{
			auto * val = find_ptr(key);
			if (val)
				return *val;
			else
				throw std::out_of_range("lru_cache out of range");
		}
		/// получает данные по ключу, если таких данных нет, то returns nullptr
		mapped_type * find_ptr(key_param key)
		{
			auto it = m_cache.find(key);
			if (it == m_cache.end())
				return nullptr;
			else
			{
				touch(it);
				// const_cast is safe because our index is only by key
				return &const_cast<mapped_type &>(it->value);
			}
		}

		/// сбрасывает кеш
		void clear()                 { m_cache.clear(); }
		std::size_t size() const     { return m_cache.size(); }
		std::size_t maxsize() const  { return m_cache_maxsize; }

		/// скидывает элменты так что бы размер кеша не превышал size
		void drop_to(std::size_t size)
		{
			auto & pv = m_cache.template get<ByPos>();
			for (auto cursz = m_cache.size(); cursz > size; --cursz)
				pv.pop_front();
		}

		void set_maxsize(std::size_t size)
		{
			if (size == 0)
				throw std::invalid_argument("lru_cache: CacheMaxSize == 0 is invalid");

			drop_to(size);
			m_cache_maxsize = size;
		}

		explicit manual_lru_cache(std::size_t size)
			: m_cache_maxsize(size) {}

		manual_lru_cache(const manual_lru_cache &) = delete;
		manual_lru_cache & operator =(const manual_lru_cache &) = delete;

		manual_lru_cache(manual_lru_cache && r) = default;
		manual_lru_cache & operator =(manual_lru_cache && r) = default;

		void swap(manual_lru_cache & other) noexcept
		{
			boost::swap(m_cache, other.m_cache);
			boost::swap(m_cache_maxsize, other.m_cache_maxsize);
		}
	};

	template <class Key, class Value, class Hash, class KeyEqual>
	inline void swap(manual_lru_cache<Key, Value, Hash, KeyEqual> & c1,
	                 manual_lru_cache<Key, Value, Hash, KeyEqual> & c2) noexcept
	{
		c1.swap(c2);
	}

	/// lru_cache умеющий получать записи автоматически с помощью функтора Acquire
	/// выражение:
	/// Value v = Acquire(key) должно быть валидным
	template <
		class Key,
		class Value,
		class Hash = boost::hash<Key>,
		class KeyEqual = std::equal_to<>,
		class Acquire = std::function<Value(const Key &)>
	>
	class lru_cache : private manual_lru_cache<Key, Value, Hash, KeyEqual>
	{
		typedef manual_lru_cache<Key, Value, Hash, KeyEqual> base_type;

	public:
		using typename base_type::key_type;
		using typename base_type::mapped_type;
		using typename base_type::hasher;
		using typename base_type::key_equal;
		using typename base_type::key_param;

	private:
		Acquire m_Acquire;

		mapped_type * acquire(key_param key)
		{
			Value val = m_Acquire(key);
			return &base_type::insert(std::move(key), std::move(val));
		}

	public:
		using base_type::clear;
		using base_type::size;
		using base_type::maxsize;
		using base_type::drop_last;
		using base_type::drop_to;
		using base_type::set_maxsize;

		/// получает данные по ключу
		mapped_type & at(key_param key)
		{
			auto * val = base_type::find_ptr(key);
			if (!val) val = acquire(key);
			return *val;
		}

		explicit lru_cache(std::size_t size, Acquire ac)
			: base_type(size), m_Acquire(std::move(ac)) {}

		lru_cache(const lru_cache &) = delete;
		lru_cache & operator =(const lru_cache &) = delete;

		lru_cache(lru_cache && r) = default;
		lru_cache & operator =(lru_cache && r) = default;

		void swap(lru_cache & other) noexcept
		{
			base_type::swap(other);
			boost::swap(m_Acquire, other.m_Acquire);
		}
	};

	template <class Key, class Value, class Hash, class KeyEqual, class Acquire>
	inline void swap(lru_cache<Key, Value, Hash, KeyEqual, Acquire> & c1,
	                 lru_cache<Key, Value, Hash, KeyEqual, Acquire> & c2) noexcept
	{
		c1.swap(c2);
	}

	/// lru_cache умеющий получать записи автоматически с помощью функтора Acquire
	///
	/// выражение:
	/// auto data = Acquire(key, size(), maxsize());
	/// должно быть валидным
	/// возвращаемое значение - stl compatible range of tuple like objects,
	/// where get<0>(val) - returns key, get<1>(val) - returns value
	template <
		class Key,
		class Value,
		class Hash,
		class KeyEqual,
		class Acquire
	>
	class batch_lru_cache : private manual_lru_cache<Key, Value>
	{
		typedef manual_lru_cache<Key, Value, Hash, KeyEqual> base_type;

	public:
		using typename base_type::key_type;
		using typename base_type::mapped_type;
		using typename base_type::hasher;
		using typename base_type::key_equal;
		using typename base_type::key_param;

	private:
		Acquire m_Acquire;

		template <class DataContainer>
		void merge(DataContainer && data)
		{
			first_el first;
			second_el second;
			for (auto && val : data)
			{
				typedef typename std::decay<decltype(first(val))>::type KeyType;
				typedef typename std::decay<decltype(second(val))>::type ValueType;

				static_assert(std::is_convertible<KeyType, key_type>::value, "Key mismatch");
				static_assert(std::is_convertible<ValueType, mapped_type>::value, "Value mismatch");

				base_type::insert(std::move(first(val)), std::move(second(val)));
			}
		}

		Value * acquire(key_param key)
		{
			auto data = m_Acquire(key, size(), maxsize());
			merge(std::move(data));
			return base_type::find_ptr(key);
		}

	public:
		using base_type::clear;
		using base_type::size;
		using base_type::maxsize;
		using base_type::drop_last;
		using base_type::drop_to;
		using base_type::set_maxsize;

		/// получает данные по ключу
		mapped_type & at(key_param key)
		{
			auto * val = find_ptr(key);
			if (!val) val = acquire(key);
			return *val;
		}

		explicit batch_lru_cache(std::size_t maxSize, Acquire ac)
			: base_type(maxSize), m_Acquire(std::move(ac)) {}

		batch_lru_cache(const batch_lru_cache &) = delete;
		batch_lru_cache & operator =(const batch_lru_cache &) = delete;

		batch_lru_cache(batch_lru_cache && r) = default;
		batch_lru_cache & operator =(batch_lru_cache && r) = default;

		void swap(batch_lru_cache & other) noexcept
		{
			base_type::swap(other);
			boost::swap(m_Acquire, other.m_Acquire);
		}
	};

	template <class Key, class Value, class Hash, class KeyEqual, class Acquire>
	inline void swap(batch_lru_cache<Key, Value, Hash, KeyEqual, Acquire> & c1,
	                 batch_lru_cache<Key, Value, Hash, KeyEqual, Acquire> & c2) noexcept
	{
		c1.swap(c2);
	}
}

max_stars_repo_name: dmlys/ExtLibrary

max_issues_repo_name: dmlys/extlib

max_forks_repo_name: dmlys/extlib


text:
#include <internal/facts/linux/operating_system_resolver.hpp>
#include <internal/facts/linux/release_file.hpp>
#include <internal/util/regex.hpp>
#include <facter/facts/os.hpp>
#include <facter/facts/scalar_value.hpp>
#include <facter/facts/map_value.hpp>
#include <facter/facts/collection.hpp>
#include <facter/execution/execution.hpp>
#include <facter/util/file.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <map>
#include <vector>
#include <tuple>

using namespace std;
using namespace facter::util;
using namespace facter::execution;
using namespace boost::filesystem;
namespace bs = boost::system;

namespace facter { namespace facts { namespace linux {

    operating_system_resolver::data operating_system_resolver::collect_data(collection& facts)
    {
        // Default to the base implementation
        data result = posix::operating_system_resolver::collect_data(facts);

        // Populate distro info
        execution::each_line("lsb_release", {"-a"}, [&](string& line) {
            string* variable = nullptr;
            size_t offset = 0;
            if (boost::starts_with(line, "LSB Version:")) {
                variable = &result.specification_version;
                offset = 12;
            } else if (boost::starts_with(line, "Distributor ID:")) {
                variable = &result.distro.id;
                offset = 15;
            } else if (boost::starts_with(line, "Description:")) {
                variable = &result.distro.description;
                offset = 12;
            } else if (boost::starts_with(line, "Codename:")) {
                variable = &result.distro.codename;
                offset = 9;
            } else if (boost::starts_with(line, "Release:")) {
                variable = &result.distro.release;
                offset = 8;
            }
            if (!variable) {
                return true;
            }
            *variable = line.substr(offset);
            boost::trim(*variable);
            return true;
        });

        auto name = get_name(result.distro.id);
        if (!name.empty()) {
            result.name = move(name);
        }

        auto release = get_release(result.name, result.distro.release);
        if (!release.empty()) {
            result.release = move(release);
        }

        // Convert the architecture value depending on distro
        // For certain distros, use "amd64" for "x86_64"
        // For certain distros, use "x86" for "i386"
        if (result.architecture == "x86_64" && (
             result.name == os::debian ||
             result.name == os::gentoo ||
             result.name == os::kfreebsd ||
             result.name == os::ubuntu)) {
            result.architecture = "amd64";
        } else if (re_search(result.architecture, boost::regex("i[3456]86|pentium"))) {
            // For 32-bit, use "x86" for Gentoo and "i386" for everyone else
            if (result.name == os::gentoo) {
                result.architecture = "x86";
            } else {
                result.architecture = "i386";
            }
        }

        result.selinux = collect_selinux_data();

        return result;
    }

    string operating_system_resolver::get_name(string const& distro_id)
    {
        // Start by checking for Cumulus Linux or CoreOS
        string value = check_os_release_linux();
        if (!value.empty()) {
            return value;
        }

        // Check for Debian next
        value = check_debian_linux(distro_id);
        if (!value.empty()) {
            return value;
        }

        // Check for Oracle Enterprise Linux next
        value = check_oracle_linux();
        if (!value.empty()) {
            return value;
        }

        // Check for RedHat next
        value = check_redhat_linux();
        if (!value.empty()) {
            return value;
        }

        // Check for SuSE next
        value = check_suse_linux();
        if (!value.empty()) {
            return value;
        }

        // Check for some other Linux last
        return check_other_linux();
    }

    string operating_system_resolver::get_release(string const& name, string const& distro_release)
    {
        // Map of release files that contain a "release X.X.X" on the first line
        static map<string, string> const release_files = {
                { string(os::centos),                   string(release_file::redhat) },
                { string(os::redhat),                   string(release_file::redhat) },
                { string(os::scientific),               string(release_file::redhat) },
                { string(os::scientific_cern),          string(release_file::redhat) },
                { string(os::ascendos),                 string(release_file::redhat) },
                { string(os::cloud_linux),              string(release_file::redhat) },
                { string(os::psbm),                     string(release_file::redhat) },
                { string(os::xen_server),               string(release_file::redhat) },
                { string(os::fedora),                   string(release_file::fedora) },
                { string(os::meego),                    string(release_file::meego) },
                { string(os::oracle_linux),             string(release_file::oracle_linux) },
                { string(os::oracle_enterprise_linux),  string(release_file::oracle_enterprise_linux) },
                { string(os::oracle_vm_linux),          string(release_file::oracle_vm_linux) },
        };

        string value;
        auto it = release_files.find(name);
        if (it != release_files.end()) {
            string contents;
            if (file::each_line(it->second, [&](string& line) {
                // We only need the first line
                contents = move(line);
                return false;
            })) {
                if (boost::ends_with(contents, "(Rawhide)")) {
                    value = "Rawhide";
                } else {
                    re_search(contents, boost::regex("release (\\d[\\d.]*)"), &value);
                }
            }
        }

        // Debian uses the entire contents of the release file as the version
        if (value.empty() && name == os::debian) {
            value = file::read(release_file::debian);
            boost::trim_right(value);
        }

        // Alpine uses the entire contents of the release file as the version
        if (value.empty() && name == os::alpine) {
            value = file::read(release_file::alpine);
            boost::trim_right(value);
        }

        // Check for SuSE related distros, read the release file
        if (value.empty() && (
                name == os::suse ||
                name == os::suse_enterprise_server ||
                name == os::suse_enterprise_desktop ||
                name == os::open_suse)) {
            string contents = file::read(release_file::suse);
            string major;
            string minor;
            if (re_search(contents, boost::regex("(?m)^VERSION\\s*=\\s*(\\d+)\\.?(\\d+)?"), &major, &minor)) {
                // Check that we have a minor version; if not, use the patch level
                if (minor.empty()) {
                    if (!re_search(contents, boost::regex("(?m)^PATCHLEVEL\\s*=\\s*(\\d+)"), &minor)) {
                        minor = "0";
                    }
                }
                value = major + "." + minor;
            } else {
                value = "unknown";
            }
        }

        // Read version files of particular operating systems
        if (value.empty()) {
            const char* file = nullptr;
            boost::regex pattern;
            if (name == os::ubuntu) {
                file = release_file::lsb;
                pattern = "(?m)^DISTRIB_RELEASE=(\\d+\\.\\d+)(?:\\.\\d+)*";
            } else if (name == os::slackware) {
                file = release_file::slackware;
                pattern = "Slackware ([0-9.]+)";
            } else if (name == os::mageia) {
                file = release_file::mageia;
                pattern = "Mageia release ([0-9.]+)";
            } else if (name == os::cumulus || name == os::coreos) {
                file = release_file::os;
                pattern = "(?m)^VERSION_ID\\s*=\\s*(\\d+\\.\\d+\\.\\d+)";
            } else if (name == os::linux_mint) {
                file = release_file::linux_mint_info;
                pattern = "(?m)^RELEASE=(\\d+)";
            } else if (name == os::openwrt) {
                file = release_file::openwrt_version;
                pattern = "(?m)^(\\d+\\.\\d+.*)";
            }
            if (file) {
                string contents = file::read(file);
                re_search(contents, pattern, &value);
            }
        }

        // For VMware ESX, execute the vmware tool
        if (value.empty() && name == os::vmware_esx) {
            auto result = execute("vmware", { "-v" });
            if (result.first) {
                re_search(result.second, boost::regex("VMware ESX .*?(\\d.*)"), &value);
            }
        }

        // For Amazon, use the distro release
        if (value.empty() && name == os::amazon) {
            return distro_release;
        }

        return value;
    }

    tuple<string, string> operating_system_resolver::parse_release(string const& name, string const& release) const
    {
        if (name != os::ubuntu) {
            return resolvers::operating_system_resolver::parse_release(name, release);
        }

        string major, minor;
        re_search(release, boost::regex("(\\d+\\.\\d*)\\.?(\\d*)"), &major, &minor);
        return make_tuple(move(major), move(minor));
    }

    string operating_system_resolver::check_os_release_linux()
    {
        // Check for NAME in /etc/os-release
        // Both cfacter and ruby facter should use the same field.
        bs::error_code ec;
        if (is_regular_file(release_file::os, ec)) {
            string contents = file::read(release_file::os);
            boost::trim(contents);

            string release;
            if (re_search(contents, boost::regex("(?m)^NAME=[\"']?(.+?)[\"']?$"), &release)) {
                if (release == "Cumulus Linux") {
                    return os::cumulus;
                } else if (release == "CoreOS") {
                    return os::coreos;
                }
            }
        }
        return {};
    }

    string operating_system_resolver::check_debian_linux(string const& distro_id)
    {
        // Check for Debian variants
        bs::error_code ec;
        if (is_regular_file(release_file::debian, ec)) {
            if (distro_id == os::ubuntu || distro_id == os::linux_mint) {
                return distro_id;
            }
            return os::debian;
        }
        return {};
    }

    string operating_system_resolver::check_oracle_linux()
    {
        bs::error_code ec;
        if (is_regular_file(release_file::oracle_enterprise_linux, ec)) {
            if (is_regular_file(release_file::oracle_vm_linux, ec)) {
                return os::oracle_vm_linux;
            }
            return os::oracle_enterprise_linux;
        }
        return {};
    }

    string operating_system_resolver::check_redhat_linux()
    {
        bs::error_code ec;
        if (is_regular_file(release_file::redhat, ec)) {
            static vector<tuple<boost::regex, string>> const regexs {
                make_tuple(boost::regex("(?i)centos"),                        string(os::centos)),
                make_tuple(boost::regex("(?i)scientific linux CERN"),         string(os::scientific_cern)),
                make_tuple(boost::regex("(?i)scientific linux release"),      string(os::scientific)),
                make_tuple(boost::regex("(?im)^cloudlinux"),                  string(os::cloud_linux)),
                make_tuple(boost::regex("(?i)Ascendos"),                      string(os::ascendos)),
                make_tuple(boost::regex("(?im)^XenServer"),                   string(os::xen_server)),
                make_tuple(boost::regex("XCP"),                               string(os::zen_cloud_platform)),
                make_tuple(boost::regex("(?im)^Parallels Server Bare Metal"), string(os::psbm)),
                make_tuple(boost::regex("(?m)^Fedora release"),               string(os::fedora)),
            };

            string contents = file::read(release_file::redhat);
            boost::trim(contents);
            for (auto const& regex : regexs) {
                if (re_search(contents, get<0>(regex))) {
                    return get<1>(regex);
                }
            }
            return os::redhat;
        }
        return {};
    }

    string operating_system_resolver::check_suse_linux()
    {
        bs::error_code ec;
        if (is_regular_file(release_file::suse, ec)) {
            static vector<tuple<boost::regex, string>> const regexs {
                make_tuple(boost::regex("(?im)^SUSE LINUX Enterprise Server"),  string(os::suse_enterprise_server)),
                make_tuple(boost::regex("(?im)^SUSE LINUX Enterprise Desktop"), string(os::suse_enterprise_desktop)),
                make_tuple(boost::regex("(?im)^openSUSE"),                      string(os::open_suse)),
            };

            string contents = file::read(release_file::suse);
            boost::trim(contents);
            for (auto const& regex : regexs) {
                if (re_search(contents, get<0>(regex))) {
                    return get<1>(regex);
                }
            }
            return os::suse;
        }
        return {};
    }

    string operating_system_resolver::check_other_linux()
    {
        static vector<tuple<string, string>> const files {
            make_tuple(string(release_file::openwrt),        string(os::openwrt)),
            make_tuple(string(release_file::gentoo),         string(os::gentoo)),
            make_tuple(string(release_file::mandriva),       string(os::mandriva)),
            make_tuple(string(release_file::mandrake),       string(os::mandrake)),
            make_tuple(string(release_file::meego),          string(os::meego)),
            make_tuple(string(release_file::archlinux),      string(os::archlinux)),
            make_tuple(string(release_file::oracle_linux),   string(os::oracle_linux)),
            make_tuple(string(release_file::vmware_esx),     string(os::vmware_esx)),
            make_tuple(string(release_file::slackware),      string(os::slackware)),
            make_tuple(string(release_file::alpine),         string(os::alpine)),
            make_tuple(string(release_file::mageia),         string(os::mageia)),
            make_tuple(string(release_file::amazon),         string(os::amazon)),
        };

        for (auto const& file : files) {
            bs::error_code ec;
            if (is_regular_file(get<0>(file), ec)) {
                return get<1>(file);
            }
        }
        return {};
    }

    operating_system_resolver::selinux_data operating_system_resolver::collect_selinux_data()
    {
        selinux_data result;
        result.supported = true;

        string mountpoint = get_selinux_mountpoint();
        result.enabled = !mountpoint.empty();
        if (!result.enabled) {
            return result;
        }

        // Get the policy version
        result.policy_version = file::read(mountpoint + "/policyvers");

        // Check for enforcement
        string enforce = file::read(mountpoint + "/enforce");
        if (!enforce.empty()) {
            if (enforce == "1") {
                result.enforced = true;
                result.current_mode = "enforcing";
            } else {
                result.current_mode = "permissive";
            }
        }

        // Parse the SELinux config for mode and policy
        static boost::regex mode_regex("(?m)^SELINUX=(\\w+)$");
        static boost::regex policy_regex("(?m)^SELINUXTYPE=(\\w+)$");
        file::each_line("/etc/selinux/config", [&](string& line) {
            if (re_search(line, mode_regex, &result.config_mode)) {
                return true;
            }
            if (re_search(line, policy_regex, &result.config_policy)) {
                return true;
            }
            return true;
        });
        return result;
    }

    string operating_system_resolver::get_selinux_mountpoint()
    {
        static boost::regex regexp("\\S+ (\\S+) selinuxfs");
        string mountpoint;
        file::each_line("/proc/self/mounts", [&](string& line) {
            if (re_search(line, regexp, &mountpoint)) {
                return false;
            }
            return true;
        });
        return mountpoint;
    }

}}}  // namespace facter::facts::linux

ext: cc

max_stars_repo_name: MikaelSmith/cfacter

max_issues_repo_name: MikaelSmith/cfacter

max_forks_repo_name: MikaelSmith/cfacter


text:
// SerialForWindowsTerminal.cpp : 定义应用程序的入口点。
//

#include "framework.h"
#include "SerialForWindowsTerminal.h"
#include <vector>
#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/windows/stream_handle.hpp>

#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInstance;
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    SettingFunc(HWND, UINT, WPARAM, LPARAM);

using PortsArray = std::vector<std::pair<std::wstring, int>>;
static PortsArray GetAllPorts(void)
{
    PortsArray ports;
    HKEY hRegKey;
    int nCount = 0;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Hardware\\DeviceMap\\SerialComm", 0, KEY_READ, &hRegKey) == ERROR_SUCCESS)
    {
        while (true)
        {
            TCHAR szName[MAX_PATH] = { 0 };
            TCHAR szPort[MAX_PATH] = { 0 };
            DWORD nValueSize = MAX_PATH - 1;
            DWORD nDataSize = MAX_PATH - 1;
            DWORD nType;

            if (::RegEnumValue(hRegKey, nCount, szName, &nValueSize, NULL, &nType, (LPBYTE)szPort, &nDataSize) == ERROR_NO_MORE_ITEMS)
            {
                break;
            }
            std::wstring name(szName);
            auto idx = name.find_last_of('\\');
            if (idx != name.npos)
            {
                name = name.substr(idx + 1);
            }
            name += L" (";
            name += szPort;
            name += L")";
            ports.push_back(std::make_pair(name, (int)std::wcstoul(szPort + 3, nullptr, 10)));
            nCount++;
        }
        ::RegCloseKey(hRegKey);
    }
    return ports;
}

static void UpdatePortControl(HWND hDlg)
{
    auto allPorts = GetAllPorts();
    auto hWndPort = GetDlgItem(hDlg, IDC_COMBO_PORT);
    ComboBox_ResetContent(hWndPort);
    for (auto port : allPorts)
    {
        auto index = ComboBox_AddString(hWndPort, port.first.c_str());
        ComboBox_SetItemData(hWndPort, index, port.second);
    }
}

static void CenterParentWindow(HWND hWnd)
{
    RECT rcDlg;
    ::GetWindowRect(hWnd, &rcDlg);
    RECT rcParent;
    HWND hWndParent = GetParent(hWnd);
    GetClientRect(hWndParent, &rcParent);
    POINT ptParentInScreen;
    ptParentInScreen.x = rcParent.left;
    ptParentInScreen.y = rcParent.top;
    ::ClientToScreen(hWndParent, (LPPOINT)&ptParentInScreen);
    SetWindowPos(
        hWnd,
        NULL,
        ptParentInScreen.x + (rcParent.right - rcParent.left - (rcDlg.right - rcDlg.left)) / 2,
        ptParentInScreen.y + (rcParent.bottom - rcParent.top - (rcDlg.bottom - rcDlg.top)) / 2,
        0,
        0,
        SWP_NOZORDER | SWP_NOSIZE);
}

typedef struct
{
    DWORD Serial;
    DWORD BaudRate;
    DWORD WordLength;
    DWORD StopBit;
    DWORD Parity;
    DWORD FlowControl;
}SERIAL_CONFIG;

static SERIAL_CONFIG ReadSerialConfig()
{
    HKEY hKey;
    SERIAL_CONFIG cfg;
    cfg.Serial = 0;
    cfg.BaudRate = 9600;
    cfg.WordLength = 8;
    cfg.StopBit = ONESTOPBIT;
    cfg.Parity = NOPARITY;
    cfg.FlowControl = 0;
    if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\SerialForWindowsTerminal", 0, KEY_READ, &hKey))
    {
        DWORD dwSize = sizeof(DWORD);
        DWORD dwType = REG_DWORD;

        ::RegQueryValueEx(hKey, L"Serial", 0, &dwType, (LPBYTE)&cfg.Serial, &dwSize);
        ::RegQueryValueEx(hKey, L"BaudRate", 0, &dwType, (LPBYTE)&cfg.BaudRate, &dwSize);
        ::RegQueryValueEx(hKey, L"WordLength", 0, &dwType, (LPBYTE)&cfg.WordLength, &dwSize);
        ::RegQueryValueEx(hKey, L"StopBit", 0, &dwType, (LPBYTE)&cfg.StopBit, &dwSize);
        ::RegQueryValueEx(hKey, L"Parity", 0, &dwType, (LPBYTE)&cfg.Parity, &dwSize);
        ::RegQueryValueEx(hKey, L"FlowControl", 0, &dwType, (LPBYTE)&cfg.FlowControl, &dwSize);
        ::RegCloseKey(hKey);
    }
    return cfg;
}

static void WriteSerialConfig(const SERIAL_CONFIG& cfg)
{
    HKEY hKey;
    if (ERROR_SUCCESS == ::RegCreateKey(HKEY_CURRENT_USER, L"SOFTWARE\\SerialForWindowsTerminal", &hKey))
    {
        DWORD dwSize = sizeof(DWORD);
        DWORD dwType = REG_DWORD;

        ::RegSetValueEx(hKey, L"Serial", 0, dwType, (CONST LPBYTE) & cfg.Serial, dwSize);
        ::RegSetValueEx(hKey, L"BaudRate", 0, dwType, (CONST LPBYTE) & cfg.BaudRate, dwSize);
        ::RegSetValueEx(hKey, L"WordLength", 0, dwType, (CONST LPBYTE) & cfg.WordLength, dwSize);
        ::RegSetValueEx(hKey, L"StopBit", 0, dwType, (CONST LPBYTE) & cfg.StopBit, dwSize);
        ::RegSetValueEx(hKey, L"Parity", 0, dwType, (CONST LPBYTE) & cfg.Parity, dwSize);
        ::RegSetValueEx(hKey, L"FlowControl", 0, dwType, (CONST LPBYTE) & cfg.FlowControl, dwSize);
        ::RegCloseKey(hKey);
    }
}

static boost::system::error_code InitializeSerialPort(boost::asio::serial_port& serialPort,const SERIAL_CONFIG& cfg, boost::system::error_code& ec)
{
    serialPort.set_option(boost::asio::serial_port::baud_rate(cfg.BaudRate), ec);
    if (ec)
        return ec;
    serialPort.set_option(boost::asio::serial_port::character_size(cfg.WordLength), ec);
    if (ec)
        return ec;
    switch (cfg.StopBit)
    {
    case 0:
        serialPort.set_option(boost::asio::serial_port::stop_bits(boost::asio::serial_port::stop_bits::one), ec);
        break;
    case 1:
        serialPort.set_option(boost::asio::serial_port::stop_bits(boost::asio::serial_port::stop_bits::onepointfive), ec);
        break;
    case 2:
        serialPort.set_option(boost::asio::serial_port::stop_bits(boost::asio::serial_port::stop_bits::two), ec);
        break;
    default:
        serialPort.set_option(boost::asio::serial_port::stop_bits(boost::asio::serial_port::stop_bits::one), ec);
        break;
    }
    if (ec)
        return ec;

    switch (cfg.Parity)
    {
    case 0:
        serialPort.set_option(boost::asio::serial_port::parity(boost::asio::serial_port::parity::none), ec);
        break;
    case 1:
        serialPort.set_option(boost::asio::serial_port::parity(boost::asio::serial_port::parity::odd), ec);
        break;
    case 2:
        serialPort.set_option(boost::asio::serial_port::parity(boost::asio::serial_port::parity::even), ec);
        break;
    default:
        serialPort.set_option(boost::asio::serial_port::parity(boost::asio::serial_port::parity::none), ec);
        break;
    }
    if (ec)
        return ec;

    switch (cfg.FlowControl)
    {
    case 0:
        serialPort.set_option(boost::asio::serial_port::flow_control(boost::asio::serial_port::flow_control::none), ec);
        break;
    case 1:
        serialPort.set_option(boost::asio::serial_port::flow_control(boost::asio::serial_port::flow_control::software), ec);
        break;
    case 2:
        serialPort.set_option(boost::asio::serial_port::flow_control(boost::asio::serial_port::flow_control::hardware), ec);
        break;
    default:
        serialPort.set_option(boost::asio::serial_port::flow_control(boost::asio::serial_port::flow_control::none), ec);
        break;
    }

    return ec;
}

template <class TStream1, class TStream2>
static void DoStreamToStream(TStream1& stream1, TStream2& stream2, std::vector<uint8_t>& buffer)
{
    stream1.async_read_some(
        boost::asio::buffer(buffer.data(), buffer.size()),
        [&stream1, &stream2, &buffer](const boost::system::error_code& ec, std::size_t bytes_transferred)
        {
            if (ec)
            {
                std::cerr << "\033[31m" << "error : " << ec.message() << "\033[0m" << std::endl;
            }
            else
            {
                boost::asio::async_write(
                    stream2,
                    boost::asio::const_buffer(buffer.data(), bytes_transferred),
                    [&stream1, &stream2, &buffer](const boost::system::error_code& ec, std::size_t bytes_transferred)
                    {
                        if (ec)
                        {
                            std::cerr << "\033[31m" << "error : " << ec.message() << "\033[0m" << std::endl;
                        }
                        else
                        {
                            DoStreamToStream(stream1, stream2, buffer);
                        }
                    }
                );
            }
        }
    );
}

static boost::system::error_code DoWork(boost::asio::io_service& ioctx, boost::asio::serial_port& serialPort)
{
    boost::system::error_code ec;
    boost::asio::windows::stream_handle stdinput(ioctx);
    boost::asio::windows::stream_handle stdoutput(ioctx);
    const auto kBufferSize = 1024;
    std::vector<uint8_t> serialPortRecvBuffer;
    std::vector<uint8_t> serialPortSendBuffer;
    serialPortRecvBuffer.resize(kBufferSize);
    serialPortSendBuffer.resize(kBufferSize);

    auto conin = CreateFile(L"CONIN$", FILE_GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
    auto conout = CreateFile(L"CONOUT$", FILE_GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

    if (stdinput.assign(conin, ec))
        return ec;

    if (stdoutput.assign(conout, ec))
        return ec;

    DoStreamToStream(serialPort, stdoutput, serialPortRecvBuffer);
    DoStreamToStream(stdinput, serialPort, serialPortSendBuffer);
    ioctx.run(ec);
    return ec;
}

int wmain(int argc, const WCHAR* args[])
{
    boost::system::error_code ec;
    boost::asio::io_service ioctx;
    boost::asio::serial_port serialPort(ioctx);
    hInstance = GetModuleHandle(nullptr);

    DWORD consoleMode = 0;
    auto conin = GetStdHandle(STD_INPUT_HANDLE);
    auto conout = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleMode(conin, &consoleMode);
    consoleMode |= ENABLE_MOUSE_INPUT;
    consoleMode &= ~ENABLE_ECHO_INPUT;
    consoleMode &= ~ENABLE_PROCESSED_INPUT;
    consoleMode &= ~ENABLE_LINE_INPUT;
    consoleMode |= ENABLE_QUICK_EDIT_MODE;
    consoleMode |= ENABLE_WINDOW_INPUT;
    consoleMode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
    SetConsoleMode(conin, consoleMode);

    GetConsoleMode(conout, &consoleMode);
    SetConsoleMode(conout, consoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT);

    while (true)
    {
        auto hWndParent = ::GetForegroundWindow();
        if (hWndParent == nullptr)
            hWndParent = GetConsoleWindow();
        if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_SETTING_DIALOG), hWndParent, SettingFunc, 1) == IDOK)
        {
            auto cfg = ReadSerialConfig();
            auto portName = std::string("COM") + std::to_string(cfg.Serial);
            if (serialPort.open(portName, ec))
            {
                std::cerr << "\033[31m" << "can not open " << portName << "\033[0m" <<std::endl;
                std::cerr << "\033[31m" << "error : " << ec.message() << "\033[0m" << std::endl;
                continue;
            }
            if (InitializeSerialPort(serialPort, cfg, ec))
            {
                std::cerr << "\033[31m" << "can not initialize " << portName << "\033[0m" << std::endl;
                std::cerr << "\033[31m" << "error : " << ec.message() << "\033[0m" << std::endl;
                continue;
            }
            break;
        }
        else
        {
            return ERROR_CANCELLED;
        }
    }
    ec = DoWork(ioctx, serialPort);
    if (ec)
    {
        std::cerr << "\033[31m" << "error : " << ec.message() << "\033[0m" << std::endl;
        return ec.value();
    }
    return ERROR_SUCCESS;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        CenterParentWindow(hDlg);
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

INT_PTR CALLBACK SettingFunc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
    {
        CenterParentWindow(hDlg);
        auto cfg = ReadSerialConfig();
        auto hWndPort = GetDlgItem(hDlg, IDC_COMBO_PORT);
        UpdatePortControl(hDlg);
        auto portCount = ComboBox_GetCount(hWndPort);
        if (cfg.Serial != 0)
        {
            for (int i = 0; i < portCount; ++i)
            {
                auto com = (int)ComboBox_GetItemData(hWndPort, i);
                if (com == cfg.Serial)
                {
                    ComboBox_SetCurSel(hWndPort, i);
                    break;
                }
            }
        }
        else
        {
            ComboBox_SetCurSel(hWndPort, 0);
        }

        auto hWndBaudRate = GetDlgItem(hDlg, IDC_COMBO_SPEED);
        ComboBox_AddString(hWndBaudRate, L"50");
        ComboBox_AddString(hWndBaudRate, L"75");
        ComboBox_AddString(hWndBaudRate, L"100");
        ComboBox_AddString(hWndBaudRate, L"105");
        ComboBox_AddString(hWndBaudRate, L"300");
        ComboBox_AddString(hWndBaudRate, L"600");
        ComboBox_AddString(hWndBaudRate, L"1200");
        ComboBox_AddString(hWndBaudRate, L"2400");
        ComboBox_AddString(hWndBaudRate, L"4800");
        ComboBox_AddString(hWndBaudRate, L"9600");
        ComboBox_AddString(hWndBaudRate, L"19200");
        ComboBox_AddString(hWndBaudRate, L"38400");
        ComboBox_AddString(hWndBaudRate, L"57600");
        ComboBox_AddString(hWndBaudRate, L"115200");
        ComboBox_AddString(hWndBaudRate, L"128000");
        ComboBox_AddString(hWndBaudRate, L"256000");
        ComboBox_SetText(hWndBaudRate, std::to_wstring(cfg.BaudRate).c_str());

        auto hWndWordLength = GetDlgItem(hDlg, IDC_COMBO_WORD);
        ComboBox_AddString(hWndWordLength, L"4");
        ComboBox_AddString(hWndWordLength, L"5");
        ComboBox_AddString(hWndWordLength, L"6");
        ComboBox_AddString(hWndWordLength, L"7");
        ComboBox_AddString(hWndWordLength, L"8");
        ComboBox_AddString(hWndWordLength, L"9");
        ComboBox_AddString(hWndWordLength, L"10");
        ComboBox_SetCurSel(hWndWordLength, (int)(cfg.WordLength - 4));

        auto hWndStopBit = GetDlgItem(hDlg, IDC_COMBO_STOP);
        ComboBox_AddString(hWndStopBit, L"1");
        ComboBox_AddString(hWndStopBit, L"1.5");
        ComboBox_AddString(hWndStopBit, L"2");
        ComboBox_SetCurSel(hWndStopBit, (int)(cfg.StopBit));

        auto hWndParity = GetDlgItem(hDlg, IDC_COMBO_PARITY);
        ComboBox_AddString(hWndParity, L"无");
        ComboBox_AddString(hWndParity, L"奇");
        ComboBox_AddString(hWndParity, L"偶");
        ComboBox_SetCurSel(hWndParity, (int)(cfg.Parity));

        auto hWndFlowControl = GetDlgItem(hDlg, IDC_COMBO_FLOW_CONTROL);
        ComboBox_AddString(hWndFlowControl, L"无");
        ComboBox_AddString(hWndFlowControl, L"软件(Xon/Xoff)");
        ComboBox_AddString(hWndFlowControl, L"硬件");
        ComboBox_SetCurSel(hWndFlowControl, (int)(cfg.FlowControl));

        return (INT_PTR)TRUE;
    }
    case WM_DEVICECHANGE:
        UpdatePortControl(hDlg);
        return (INT_PTR)TRUE;
    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            if (LOWORD(wParam) == IDOK)
            {
                SERIAL_CONFIG cfg = {0};
                auto hWndPort = GetDlgItem(hDlg, IDC_COMBO_PORT);
                auto hWndBaudRate = GetDlgItem(hDlg, IDC_COMBO_SPEED);
                auto hWndWordLength = GetDlgItem(hDlg, IDC_COMBO_WORD);
                auto hWndStopBit = GetDlgItem(hDlg, IDC_COMBO_STOP);
                auto hWndParity = GetDlgItem(hDlg, IDC_COMBO_PARITY);
                auto hWndFlowControl = GetDlgItem(hDlg, IDC_COMBO_FLOW_CONTROL);

                WCHAR txtBuffer[32] = {0};
                auto curSel = ComboBox_GetCurSel(hWndPort);
                if (curSel >= 0)
                {
                    cfg.Serial = (DWORD)ComboBox_GetItemData(hWndPort, curSel);
                }
                else
                {
                    ComboBox_GetText(hWndPort, txtBuffer, 32);
                    cfg.Serial = std::wcstoul(txtBuffer + 3, nullptr, 10);
                }
                ComboBox_GetText(hWndBaudRate, txtBuffer, 32);
                cfg.BaudRate = std::wcstoul(txtBuffer, nullptr, 10);
                cfg.WordLength = ComboBox_GetCurSel(hWndWordLength) + 4;
                cfg.StopBit = ComboBox_GetCurSel(hWndStopBit);
                cfg.Parity = ComboBox_GetCurSel(hWndParity);
                cfg.FlowControl = ComboBox_GetCurSel(hWndFlowControl);
                WriteSerialConfig(cfg);
            }
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}