text:
/*
 * Copyright  ：SIAT 异构智能计算体系结构与系统研究中心
 * Author      : Heldon 764165887@qq.com
 * Date       ：19-03-06
 * Description：launch a task in docker container
 */
//C++11 denpendencies
#include <iostream>
#include <string>

//google dependencies
#include <gflags/gflags.h>

//boost dependencies
#include <boost/lexical_cast.hpp>

//mesos dependencies
#include <common/scheduler.hpp>

//stout dependencies
#include <stout/exit.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>

//proto dependencies
#include <mesos.pb.h>
#include <configuration_glog.hpp>

using namespace mesos;

using boost::lexical_cast;  //to transform data type

using std::cout;
using std::cerr;
using std::endl;
using std::flush;
using std::string;
using std::vector;

//docker launch flags
DEFINE_double(cpu, 1, "Cpus per task");
DEFINE_double(mem, 32, "Memory(MB) per task");
DEFINE_string(docker_image, "","The docker image name");
DEFINE_string(master, "", "The master node pid");
DEFINE_string(command, " ", "The docker container entry command");

/**
 * Function name  : ValidateStr
 * Author         : Heldon
 * Date           : 2018-12-13
 * Description    : Determines whether the input parameter is valid
 * Return         : True or False*/
static bool ValidateStr(const char *flagname, const string &value) {
    if (!value.empty()) {
        return true;
    }
    printf("Invalid value for --%s: To run this program, you must set a meaningful value for it "
           "%s\n", flagname, value.c_str());;
    return false;
}
static const bool docker_image_Str = gflags::RegisterFlagValidator(&FLAGS_docker_image, &ValidateStr);
static const bool master_Str = gflags::RegisterFlagValidator(&FLAGS_docker_image, &ValidateStr);

class DockerNoExecutorScheduler : public Scheduler
{
public:
  DockerNoExecutorScheduler()
    : tasksLaunched(0), tasksFinished(0), totalTasks(1) {}

  virtual ~DockerNoExecutorScheduler() {}

  virtual void registered(SchedulerDriver*,
                          const FrameworkID&,
                          const MasterInfo&)
  {
    cout << "Registered!" << endl;
  }

  virtual void reregistered(SchedulerDriver*, const MasterInfo& masterInfo) {}

  virtual void disconnected(SchedulerDriver* driver) {}

  virtual void resourceOffers(SchedulerDriver* driver,
                              const vector<Offer>& offers)
  {
    cout << "." << flush;
    for (size_t i = 0; i < offers.size(); i++){
      LOG(INFO) << "Heldon offers_size : " << offers.size();
      const Offer& offer = offers[i];

      double cpus = 0;
      double mem = 0;

      for (int i = 0; i < offer.resources_size(); i++) {
        const Resource& resource = offer.resources(i);
        if (resource.name() == "cpus" &&
            resource.type() == Value::SCALAR) {
          cpus = resource.scalar().value();
        } else if (resource.name() == "mem" &&
                   resource.type() == Value::SCALAR) {
          mem = resource.scalar().value();
        }
      }

      // Launch tasks.
      vector<TaskInfo> tasks;
      while (tasksLaunched < totalTasks && cpus >= FLAGS_cpu && mem >= FLAGS_mem) {
        int taskId = tasksLaunched++;

        cout << "Starting task " << taskId << " on "
             << offer.hostname() << endl;

        TaskInfo task;
        task.set_name("Task " + lexical_cast<string>(taskId));
        task.mutable_task_id()->set_value(lexical_cast<string>(taskId));
        task.mutable_slave_id()->MergeFrom(offer.slave_id());
        task.mutable_command()->set_value(FLAGS_command);
        //task.mutable_command()->set_shell(false);

        // Use Docker to run the task.
        ContainerInfo containerInfo;
        containerInfo.set_type(ContainerInfo::DOCKER);

        ContainerInfo::DockerInfo dockerInfo;
        //dockerInfo.set_image("alpine");
        dockerInfo.set_image(FLAGS_docker_image);

        containerInfo.mutable_docker()->CopyFrom(dockerInfo);
        task.mutable_container()->CopyFrom(containerInfo);

        Resource* resource;

        resource = task.add_resources();
        resource->set_name("cpus");
        resource->set_type(Value::SCALAR);
        resource->mutable_scalar()->set_value(FLAGS_cpu);  //--cpu-shares = max(1 * 1024, 2)
                                                           //--cpu-quota = max(1 * 100ms, 1ms)
        resource = task.add_resources();
        resource->set_name("mem");
        resource->set_type(Value::SCALAR);
        resource->mutable_scalar()->set_value(FLAGS_mem);  //--memory = max(32MB , 32MB)

        tasks.push_back(task);

        cpus -= FLAGS_cpu;
        mem -= FLAGS_mem;
      }

      driver->launchTasks(offer.id(), tasks);
    }
  }

  virtual void offerRescinded(SchedulerDriver* driver,
                              const OfferID& offerId) {}

  virtual void statusUpdate(SchedulerDriver* driver, const TaskStatus& status)
  {
    int taskId = lexical_cast<int>(status.task_id().value());

    cout << "Task " << taskId << " is in state " << status.state() << endl;

    if (status.state() == TASK_FINISHED)
      tasksFinished++;

    if (tasksFinished == totalTasks)
      driver->stop();
  }

  virtual void frameworkMessage(SchedulerDriver* driver,
                                const ExecutorID& executorId,
                                const SlaveID& slaveId,
                                const string& data) {}

  virtual void slaveLost(SchedulerDriver* driver, const SlaveID& slaveId) {}

  virtual void executorLost(SchedulerDriver* driver,
                            const ExecutorID& executorId,
                            const SlaveID& slaveId,
                            int status) {}

  virtual void error(SchedulerDriver* driver, const string& message) {}

private:
  int tasksLaunched;
  int tasksFinished;
  int totalTasks;
};

int main(int argc, char** argv)
{
  google::SetUsageMessage("usage : Option[name] \n"
                          "--master          The master node pid. example:172.20.110.59:6060\n"
                          "--docker_image    The image name on DockerHub. example:heldon/hello_docker\n"
                          "--cpus            Cpus per task.(default:1)\n"
                          "--mem             Memory(MB) per task.(default:32)\n"
                          "--command         The docker container entry command");
  google::SetVersionString("Chameleon v1.0");
  google::ParseCommandLineFlags(&argc, &argv, true);
  google::CommandLineFlagInfo info;

  //--master and --docker_image must exist
  if(!master_Str){
      cerr<< "Wrong argument"<<endl;
      return -1;
  } else if(!docker_image_Str){
      cerr<< "Wrong argument"<<endl;
      return -1;
  }

  //construct scheduler
  DockerNoExecutorScheduler scheduler;

  FrameworkInfo framework;
  framework.set_user(""); // Have Mesos fill in the current user.
  framework.set_name("Docker Launch (C++)");
  framework.set_checkpoint(true);

  MesosSchedulerDriver* driver;
  driver = new MesosSchedulerDriver(&scheduler, framework, FLAGS_master);

  int status = driver->run() == DRIVER_STOPPED ? 0 : 1;
  LOG(INFO)<<"Heldon framework name : " << framework.name();

  // Ensure that the driver process terminates.
  driver->stop();

  delete driver;
  return status;
}

max_stars_repo_name: HICAS-ChameLeon/Chameleon

max_issues_repo_name: HICAS-ChameLeon/Chameleon

max_forks_repo_name: HICAS-ChameLeon/Chameleon


text:
//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef BOOST_SIMD_IEEE_FUNCTIONS_NEXTAFTER_HPP_INCLUDED
#define BOOST_SIMD_IEEE_FUNCTIONS_NEXTAFTER_HPP_INCLUDED
#include <boost/simd/include/functor.hpp>
#include <boost/dispatch/include/functor.hpp>

namespace boost { namespace simd { namespace tag
  {
   /*!
     @brief nextafter generic tag

     Represents the nextafter function in generic contexts.

     @par Models:
        Hierarchy
   **/
    struct nextafter_ : ext::elementwise_<nextafter_>
    {
      /// @brief Parent hierarchy
      typedef ext::elementwise_<nextafter_> parent;
      template<class... Args>
      static BOOST_FORCEINLINE BOOST_AUTO_DECLTYPE dispatch(Args&&... args)
      BOOST_AUTO_DECLTYPE_BODY( dispatching_nextafter_( ext::adl_helper(), static_cast<Args&&>(args)... ) )
    };
  }
  namespace ext
  {
   template<class Site, class... Ts>
   BOOST_FORCEINLINE generic_dispatcher<tag::nextafter_, Site> dispatching_nextafter_(adl_helper, boost::dispatch::meta::unknown_<Site>, boost::dispatch::meta::unknown_<Ts>...)
   {
     return generic_dispatcher<tag::nextafter_, Site>();
   }
   template<class... Args>
   struct impl_nextafter_;
  }
  /*!
    Returns the next element in the a1 direction.
    \par
    rg if a1 is greater than a0 this is next(a0)
    rg if a1 is equal to a0 this is a0
    rg if a1 is less than a0 this is prev(a0)

    @par Semantic:

    @code
    T r = nextafter(x, y);
    @endcode

    is similar to:

    @code
    if (y >  x)  r = next(a0);
    else if (y == x)  r = a0;
    else if (y <  x)  r = prev(a0);
    @endcode

    @param a0

    @param a1

    @return a value of same type as the inputs
  **/
  BOOST_DISPATCH_FUNCTION_IMPLEMENTATION(tag::nextafter_, nextafter, 2)
} }

#endif

ext: hpp


text:
//          Copyright Carl Philipp Reh 2009 - 2016.
// 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 FCPPT_RANGE_HASH_IMPL_HPP_INCLUDED
#define FCPPT_RANGE_HASH_IMPL_HPP_INCLUDED

#include <fcppt/range_hash_decl.hpp>
#include <fcppt/config/external_begin.hpp>
#include <boost/functional/hash/hash.hpp>
#include <cstddef>
#include <iterator>
#include <fcppt/config/external_end.hpp>

template<
	typename Type
>
std::size_t
fcppt::range_hash<
	Type
>::operator()(
	Type const &_value
) const
{
	using std::begin;
	using std::end;

	return
		boost::hash_range(
			begin(
				_value
			),
			end(
				_value
			)
		);
}

#endif

max_stars_repo_name: vinzenz/fcppt

max_issues_repo_name: vinzenz/fcppt

max_forks_repo_name: vinzenz/fcppt


text:
#include "Sender.h"
#include "../Util/UuidHash.h"
#include <boost/uuid/random_generator.hpp>
#include <algorithm>

gsl::Event::Sender::Sender() {
}

gsl::Event::Sender::~Sender() {
}

gsl::Event::Connection gsl::Event::Sender::RegisterEvent(const s3d::String & Name, const Function::EventType & Event) {
  std::size_t hash = Util::UuidHash()(boost::uuids::random_generator()());
  this->event_[Name].emplace_back(Event, hash);
  auto searchreg = [this](const s3d::String& EventName, std::size_t Hash) {
    auto it = this->event_.find(EventName);
    if (it != this->event_.end()) {
      auto find = std::find_if(it->second.cbegin(), it->second.cend(), [&Hash](const Function& f) {return f == Hash; });
      if (find != it->second.end()) {
        return true;
      }
    }
    return false;
  };
  auto unreg = [this](const s3d::String& EventName, std::size_t Hash) {
    auto it = this->event_.find(EventName);
    if (it != this->event_.end()) {
      auto find = std::find_if(it->second.begin(), it->second.end(), [&Hash](const Function& f) {return f == Hash; });
      if (find != it->second.end()) {
        find->Disable();
      }
    }
  };
  return Connection(Name, hash, searchreg, unreg);
}

void gsl::Event::Sender::UnregisterEvent(const s3d::String & Name, const std::type_info & TypeInfo) {
  auto it = this->event_.find(Name);
  if (it != this->event_.end()) {
    auto find = std::find_if(it->second.begin(), it->second.end(), [&TypeInfo](const Function& f) {return f == TypeInfo; });
    if (find != it->second.end()) {
      find->Disable();
    }
  }
}

void gsl::Event::Sender::SendEvent(const s3d::String & Name) {
  this->SendEvent(Name, {});
}

void gsl::Event::Sender::SendEvent(const s3d::String & Name, const Function::ArgumentType & Argument) {
  auto it = this->event_.find(Name);
  if (it != this->event_.end()) {
    bool flag = false;
    for (auto&& func : it->second) {
      if (func) {
        func(Argument);
      }
      else {
        flag = true;
      }
    }
    if (flag) {
      it->second.erase(std::remove_if(it->second.begin(), it->second.end(), [](Function& func) {return !func; }), it->second.end());
    }
  }
}

ext: cpp

max_stars_repo_name: HunterKonoha/ESCCore

max_issues_repo_name: HunterKonoha/ESCCore

max_forks_repo_name: HunterKonoha/ESCCore


text: #include <boost/asio/ip/host_name.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <iostream>
#include <vector>
#include <tuple>
#include <set>
#include <limits>
#include <algorithm>

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Triangulation_face_base_2.h>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/bipartite.hpp>
#include <boost/graph/connected_components.hpp>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef int Info;
typedef CGAL::Triangulation_vertex_base_with_info_2<Info,K> Vb;
typedef CGAL::Triangulation_face_base_2<K> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> Tds;
typedef CGAL::Delaunay_triangulation_2<K,Tds> DT;
typedef Tds::Vertex_handle Vh;
typedef std::pair<K::Point_2,Info> IPoint;

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS> graph;
typedef boost::graph_traits<graph>::vertex_descriptor vertex_desc;
typedef boost::graph_traits<graph>::edge_iterator edge_it;

typedef std::vector <boost::default_color_type> partition_t;
typedef typename boost::property_map <graph, boost::vertex_index_t>::type index_map_t;
typedef boost::iterator_property_map <partition_t::iterator, index_map_t> partition_map_t;

using namespace std;

// Use the Delaunay Triangulation to find and add all vertices,
// that are closer than r
void addAllInRange(Vh u, DT& dt, graph& G, K::FT& r2) {
    set<Vh> visited;

    vector<Vh> q;
    q.push_back(u);
    visited.insert(u);

    while (!q.empty()) {

        auto v = q[q.size() - 1];
        q.pop_back();

        if (u != v) {
            boost::add_edge(u->info(), v->info(), G);
        }

        auto neighbor = v->incident_vertices();
        do {
            if (!dt.is_infinite(neighbor) && visited.find(neighbor) == visited.end() && CGAL::squared_distance(u->point(), neighbor->point()) <= r2) {
                visited.insert(neighbor);
                q.push_back(neighbor);
            }
        } while(++neighbor != v->incident_vertices());
    }
}

void solve()
{
    int n, m;
    K::FT r;
    cin >> n >> m >> r;

    auto r2 = r * r;

    vector<IPoint> pts(n);
    long x, y;
    for (int i = 0; i < n; ++i)
    {
        cin >> x >> y;
        pts[i] = {K::Point_2(x, y), i};
    }

    DT dt;
    dt.insert(pts.begin(), pts.end());

    // Construct graph of potentially conflicting stations
    graph G(n);
    for (auto u = dt.finite_vertices_begin(); u != dt.finite_vertices_end(); ++u) {
        addAllInRange(u, dt, G, r2);
    }

    // Use BGL check for interference (no interference iff bipartit)
    auto is_bipartite = boost::is_bipartite(G);

    // Connected components:
    std::vector<int> component_map(n);
    boost::connected_components(G, boost::make_iterator_property_map(component_map.begin(), boost::get(boost::vertex_index, G)));

    int x1, x2, y1, y2;
    for (int j = 0; j < m; ++j)
    {
        cin >> x1 >> y1 >> x2 >> y2;

        if (!is_bipartite) {
            cout << "n";
            continue;
        }

        auto p1 = K::Point_2(x1, y1);
        auto p2 = K::Point_2(x2, y2);

        if (CGAL::squared_distance(p1, p2) <= r2) {
            cout << "y";
            continue;
        }

        auto v1 = dt.nearest_vertex(p1);
        auto v2 = dt.nearest_vertex(p2);

        if (CGAL::squared_distance(p1, v1->point()) > r2 || CGAL::squared_distance(p2, v2->point()) > r2 ) {
            cout << "n";
            continue;
        }

        if (component_map[v1->info()] == component_map[v2->info()]) {
            cout << "y";
        }
        else {
            cout << "n";
        }
    }
    cout << endl;

}

int main()
{
    ios_base::sync_with_stdio(false);
    int t;
    cin >> t;
    for (int i = 0; i < t; ++i)
    {
        solve();
    }
    return 0;
}

max_stars_repo_name: dsparber/algolab

max_issues_repo_name: dsparber/algolab

max_forks_repo_name: dsparber/algolab


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

#include "bcos-framework/interfaces/storage/Table.h"
#include "Hash.h"
#include "bcos-framework/interfaces/storage/StorageInterface.h"
#include "bcos-table/src/StateStorage.h"
#include <bcos-crypto/interfaces/crypto/CommonType.h>
#include <bcos-utilities/ThreadPool.h>
#include <bcos-utilities/testutils/TestPromptFixture.h>
#include <boost/test/tools/old/interface.hpp>
#include <boost/test/unit_test.hpp>
#include <iostream>
#include <optional>
#include <string>

using namespace std;
using namespace bcos;
using namespace bcos::storage;
using namespace bcos::crypto;

namespace std
{
inline ostream& operator<<(ostream& os, const tuple<string, crypto::HashType>& item)
{
    os << get<0>(item) << " " << get<1>(item);
    return os;
}

inline ostream& operator<<(ostream& os, const std::optional<Table>& table)
{
    os << table.has_value();
    return os;
}

inline ostream& operator<<(ostream& os, const std::unique_ptr<Error>& error)
{
    os << error->what();
    return os;
}
}  // namespace std

namespace bcos
{
namespace test
{
struct TableFixture
{
    TableFixture()
    {
        hashImpl = make_shared<Header256Hash>();
        memoryStorage = make_shared<StateStorage>(nullptr);
        tableFactory = make_shared<StateStorage>(memoryStorage);
    }

    ~TableFixture() {}
    std::shared_ptr<crypto::Hash> hashImpl = nullptr;
    std::shared_ptr<StorageInterface> memoryStorage = nullptr;
    protocol::BlockNumber m_blockNumber = 0;
    std::shared_ptr<StateStorage> tableFactory = nullptr;
};
BOOST_FIXTURE_TEST_SUITE(TableTest, TableFixture)

BOOST_AUTO_TEST_CASE(constructor)
{
    auto threadPool = ThreadPool("a", 1);
    auto table = std::make_shared<Table>(nullptr, nullptr);
    auto tableFactory = std::make_shared<StateStorage>(memoryStorage);
}

BOOST_AUTO_TEST_CASE(tableInfo)
{
    std::vector<std::string> fields = {"value9", "value8", "value7", "value6"};
    TableInfo tableInfo("test-table", fields);

    BOOST_CHECK_EQUAL_COLLECTIONS(
        fields.begin(), fields.end(), tableInfo.fields().begin(), tableInfo.fields().end());

    BOOST_CHECK_EQUAL(tableInfo.fieldIndex("value9"), 0);
    BOOST_CHECK_EQUAL(tableInfo.fieldIndex("value8"), 1);
    BOOST_CHECK_EQUAL(tableInfo.fieldIndex("value7"), 2);
    BOOST_CHECK_EQUAL(tableInfo.fieldIndex("value6"), 3);
}

BOOST_AUTO_TEST_CASE(dump_hash)
{
    std::string tableName("t_test");
    std::string keyField("key");
    std::string valueField("value");

    std::promise<std::optional<Table>> createPromise;
    tableFactory->asyncCreateTable(
        tableName, valueField, [&](auto&& error, std::optional<Table>&& table) {
            BOOST_CHECK(!error);
            createPromise.set_value(table);
        });

    BOOST_CHECK(createPromise.get_future().get());

    std::promise<std::optional<Table>> tablePromise;
    tableFactory->asyncOpenTable("t_test", [&](auto&& error, auto&& table) {
        BOOST_CHECK(!error);
        tablePromise.set_value(std::move(table));
    });
    auto table = tablePromise.get_future().get();
    BOOST_TEST(table);

    // BOOST_TEST(table->dirty() == false);
    auto entry = std::make_optional(table->newEntry());
    // entry->setField("key", "name");
    entry->setField(0, "Lili");
    table->setRow("name", *entry);
    auto tableinfo = table->tableInfo();
    BOOST_CHECK_EQUAL(tableinfo->name(), tableName);

    // BOOST_CHECK_EQUAL_COLLECTIONS(
    //     valueField.begin(), valueField.end(), tableinfo->fields.begin(),
    //     tableinfo->fields.end());

    // auto hash = tableFactory->hash(hashImpl);
    // BOOST_CHECK_EQUAL(hash.size, 32);

    // BOOST_CHECK_EQUAL(tableFactory.ex)

    // auto data = table->dump(m_blockNumber);
    // auto hash = table->hash();
    // BOOST_TEST(data->size() == 1);
    entry = table->newEntry();
    // entry->setField("key", "name2");
    entry->setField(0, "WW");
    BOOST_CHECK_NO_THROW(table->setRow("name2", *entry));

    // data = table->dump(m_blockNumber);
    // BOOST_TEST(data->size() == 2);
    // hash = table->hash();
    // BOOST_TEST(table->dirty() == true);
}

BOOST_AUTO_TEST_CASE(setRow)
{
    std::string tableName("t_test");
    std::string keyField("key");
    std::string valueField("value1,value2");

    std::promise<std::optional<Table>> createPromise;
    tableFactory->asyncCreateTable(
        tableName, valueField, [&](auto&& error, std::optional<Table>&& table) {
            BOOST_CHECK(!error);
            createPromise.set_value(std::move(table));
        });
    BOOST_CHECK(createPromise.get_future().get());

    std::promise<std::optional<Table>> tablePromise;
    tableFactory->asyncOpenTable("t_test", [&](auto&& error, auto&& table) {
        BOOST_CHECK(!error);
        tablePromise.set_value(std::move(table));
    });
    auto table = tablePromise.get_future().get();
    BOOST_TEST(table);

    // check fields order of t_test
    BOOST_TEST(table->tableInfo()->fields().size() == 2);
    BOOST_TEST(table->tableInfo()->fields()[0] == "value1");
    BOOST_TEST(table->tableInfo()->fields()[1] == "value2");
    // BOOST_TEST(table->tableInfo()->key == keyField);
    auto entry = std::make_optional(table->newEntry());
    // entry->setField("key", "name");
    // BOOST_CHECK_THROW(entry->setField(0, "Lili"), bcos::Error);
    BOOST_CHECK_NO_THROW(table->setRow("name", *entry));

    // check fields order of SYS_TABLE
    std::promise<std::optional<Table>> sysTablePromise;
    tableFactory->asyncOpenTable(StorageInterface::SYS_TABLES, [&](auto&& error, auto&& table) {
        BOOST_CHECK(!error);
        BOOST_TEST(table);
        sysTablePromise.set_value(std::move(table));
    });
    auto sysTable = sysTablePromise.get_future().get();
    BOOST_CHECK(sysTable);

    BOOST_TEST(sysTable->tableInfo()->fields().size() == 1);
    BOOST_TEST(sysTable->tableInfo()->fields()[0] == StateStorage::SYS_TABLE_VALUE_FIELDS);
    // BOOST_TEST(sysTable->tableInfo()->key == StateStorage::SYS_TABLE_KEY);
}

BOOST_AUTO_TEST_CASE(removeFromCache)
{
    std::string tableName("t_test");
    std::string keyField("key");
    std::string valueField("value1,value2");

    auto ret = tableFactory->createTable(tableName, valueField);
    BOOST_TEST(ret);
    auto table = tableFactory->openTable("t_test");
    BOOST_TEST(table);
    // check fields order of t_test
    BOOST_TEST(table->tableInfo()->fields().size() == 2);
    BOOST_TEST(table->tableInfo()->fields()[0] == "value1");
    BOOST_TEST(table->tableInfo()->fields()[1] == "value2");
    // BOOST_TEST(table->tableInfo()->key == keyField);
    auto entry = std::make_optional(table->newEntry());
    // entry->setField("key", "name");
    entry->setField(0, "hello world!");
    // BOOST_CHECK_THROW(entry->setField(0, "Lili"), bcos::Error);
    BOOST_CHECK_NO_THROW(table->setRow("name", *entry));

    auto deleteEntry = std::make_optional(table->newEntry());
    deleteEntry->setStatus(Entry::DELETED);
    BOOST_CHECK_NO_THROW(table->setRow("name", *deleteEntry));

    auto hashs = tableFactory->hash(hashImpl);

    auto tableFactory2 = std::make_shared<StateStorage>(nullptr);
    BOOST_CHECK(tableFactory2->createTable(tableName, valueField));
    auto table2 = tableFactory2->openTable(tableName);
    BOOST_TEST(table2);

    auto deleteEntry2 = std::make_optional(table2->newEntry());
    deleteEntry2->setStatus(Entry::DELETED);
    BOOST_CHECK_NO_THROW(table2->setRow("name", *deleteEntry2));
    auto hashs2 = tableFactory2->hash(hashImpl);

    BOOST_CHECK_EQUAL_COLLECTIONS(hashs.begin(), hashs.end(), hashs2.begin(), hashs2.end());
}

BOOST_AUTO_TEST_SUITE_END()
}  // namespace test
}  // namespace bcos

max_stars_repo_name: contropist/FISCO-BCOS

max_issues_repo_name: contropist/FISCO-BCOS

max_forks_repo_name: contropist/FISCO-BCOS


text:
/**
 * @project zapdos
 * @file src/utils/CfgFileOptions.cc
 * @author  S Roychowdhury < sroycode at gmail dot com >
 * @version 1.0.0
 *
 * @section LICENSE
 *
 * Copyright (c) 2018-2020 S Roychowdhury
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @section DESCRIPTION
 *
 *  CfgFileOptions.cc : Config File Reader impl
 *
 */
#include <fstream>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/algorithm/string.hpp>

#include <utils/CfgFileOptions.hpp>

#define ZPDS_CFGFILE_COLON ':'
#define ZPDS_CFGFILE_SEMICOLON ';'
#define ZPDS_CFGFILE_SQB_OPEN '['
#define ZPDS_CFGFILE_SQB_CLOSE ']'
#define ZPDS_CFGFILE_HASH '#'
#define ZPDS_CFGFILE_EQUALTO '='
#define ZPDS_CFGFILE_MIDLINE_TRIM " \t\r\n"
#define ZPDS_CFGFILE_ENDLINE_TRIM " \t\r\n;"
#define ZPDS_CFGFILE_BLANK_STR ""
#define ZPDS_CFGFILE_DELIM_STR ":"

zpds::utils::CfgFileOptions::~CfgFileOptions() {}

/**
 * Check : Check if Value Exists
 *
 */
bool zpds::utils::CfgFileOptions::Check(const std::string& Section, const std::string& Name)
{
	try {
		std::string s = Find<std::string>(Section,Name);
		return true;
	}
	catch (zpds::ConfigException& e) {
		return false;
	}
	return false; // never reaches
}

/**
 * Show: Show all entries
 *
 */
void zpds::utils::CfgFileOptions::Show()
{
	for (auto const& it : SectionMap) {
		std::cerr << it.first << " = " << it.second << std::endl;
	}
}

/**
 * Update: Update or Add an entry
 *
 */
void zpds::utils::CfgFileOptions::Update(const std::string& Section, const std::string& Name, const std::string& Value)
{
	SectionMap.insert(ssMapT::value_type(MakeKey(Section,Name),Value));
}

/**
 * MakeKey: Merge Section and Name
 *
 */
std::string zpds::utils::CfgFileOptions::MakeKey(const std::string& Section, const std::string& Name)
{
	return Section + ZPDS_CFGFILE_DELIM_STR + Name;
}

/**
 * Constructor : the used constructor
 *
 */
zpds::utils::CfgFileOptions::CfgFileOptions(const std::string& InputFile)
{
	std::ifstream file(InputFile.c_str());
	if(!file.is_open())
		throw zpds::ConfigException("Cannot Open Configfile");
	std::string line, inSection;
	while(std::getline(file,line)) {
		boost::algorithm::trim(line);
		if(! line.length()) continue;
		if(line[0] == ZPDS_CFGFILE_HASH) continue;
		if(line[0] == ZPDS_CFGFILE_SEMICOLON) continue;
		if(line[0] == ZPDS_CFGFILE_SQB_OPEN) {
			if(!line.find(ZPDS_CFGFILE_SQB_CLOSE))
				throw zpds::ConfigException("Configfile Syntax Error " + line);

			/** section name */
			inSection=line.substr(1,line.find(ZPDS_CFGFILE_SQB_CLOSE)-1);
			boost::algorithm::trim(inSection);
			std::string inHerits = ZPDS_CFGFILE_BLANK_STR;
			ssMapT::const_iterator it = InheritMap.find(inSection);
			if(it!=InheritMap.end())
				throw zpds::ConfigException("Duplicate Section : " + inSection);

			/** inherits name if exists */
			if(line.length() > line.find_last_of(ZPDS_CFGFILE_COLON)) {
				inHerits = line.substr(line.find_last_of(ZPDS_CFGFILE_COLON)+1);
				boost::algorithm::trim(inHerits);
				it = InheritMap.find(inHerits);
				if(it==InheritMap.end())
					throw zpds::ConfigException("Invalid Inherit : " +  inSection);
			}
			InheritMap.insert(ssMapT::value_type(inSection,inHerits));
			continue;
		}
		size_t EqPos = line.find(ZPDS_CFGFILE_EQUALTO); /** position */
		if(EqPos==std::string::npos)
			throw zpds::ConfigException("Invalid Line : " +  line);
		std::string myname = line.substr(0,EqPos);
		boost::algorithm::trim(myname);
		std::string myval = line.substr(EqPos+1);
		boost::algorithm::trim(myval);
		Update(inSection,myname,myval);
	}
	file.close();
}

ext: cc

max_stars_repo_name: sroycode/zapdos

max_issues_repo_name: vnaad/zapdos

max_forks_repo_name: vnaad/zapdos


text:
/*
 *          Copyright Andrey Semashev 2007 - 2015.
 * 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)
 */
#define BOOST_LOG_DYN_LINK 1

#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/support/date_time.hpp>

namespace logging = boost::log;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace keywords = boost::log::keywords;

#if 1

//[ example_tutorial_formatters_stream
void init()
{
    logging::add_file_log
    (
        keywords::file_name = "sample_%N.log",
        // This makes the sink to write log records that look like this:
        // 1: <normal> A normal severity message
        // 2: <error> An error severity message
        keywords::format =
        (
            expr::stream
                << expr::attr< unsigned int >("LineID")
                << ": <" << logging::trivial::severity
                << "> " << expr::smessage
        )
    );
}
//]

#else

//[ example_tutorial_formatters_stream_date_time
void init()
{
    logging::add_file_log
    (
        keywords::file_name = "sample_%N.log",
        // This makes the sink to write log records that look like this:
        // YYYY-MM-DD HH:MI:SS: <normal> A normal severity message
        // YYYY-MM-DD HH:MI:SS: <error> An error severity message
        keywords::format =
        (
            expr::stream
                << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
                << ": <" << logging::trivial::severity
                << "> " << expr::smessage
        )
    );
}
//]

#endif

int main(int, char*[])
{
    init();
    logging::add_common_attributes();

    using namespace logging::trivial;
    src::severity_logger< severity_level > lg;

    BOOST_LOG_SEV(lg, trace) << "A trace severity message";
    BOOST_LOG_SEV(lg, debug) << "A debug severity message";
    BOOST_LOG_SEV(lg, info) << "An informational severity message";
    BOOST_LOG_SEV(lg, warning) << "A warning severity message";
    BOOST_LOG_SEV(lg, error) << "An error severity message";
    BOOST_LOG_SEV(lg, fatal) << "A fatal severity message";

    return 0;
}

max_stars_repo_name: antarikshnarain/ArtemisLeapFrog

max_issues_repo_name: antarikshnarain/ArtemisLeapFrog

max_forks_repo_name: antarikshnarain/ArtemisLeapFrog


text:
#define BOOST_TEST_MODULE SolutionTest

#include "solution.hpp"

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

BOOST_AUTO_TEST_SUITE(SolutionSuite)

BOOST_AUTO_TEST_CASE(PlainTest1)
{
    vector<vector<char>> board{
        {'5','3','.','.','7','.','.','.','.'},
        {'6','.','.','1','9','5','.','.','.'},
        {'.','9','8','.','.','.','.','6','.'},
        {'8','.','.','.','6','.','.','.','3'},
        {'4','.','.','8','.','3','.','.','1'},
        {'7','.','.','.','2','.','.','.','6'},
        {'.','6','.','.','.','.','2','8','.'},
        {'.','.','.','4','1','9','.','.','5'},
        {'.','.','.','.','8','.','.','7','9'}
    };
    bool result = Solution().isValidSudoku(board);

    bool expected = true;
    BOOST_CHECK_EQUAL(result, expected);
}

BOOST_AUTO_TEST_CASE(PlainTest2)
{
    vector<vector<char>> board{
        {'8','3','.','.','7','.','.','.','.'},
        {'6','.','.','1','9','5','.','.','.'},
        {'.','9','8','.','.','.','.','6','.'},
        {'8','.','.','.','6','.','.','.','3'},
        {'4','.','.','8','.','3','.','.','1'},
        {'7','.','.','.','2','.','.','.','6'},
        {'.','6','.','.','.','.','2','8','.'},
        {'.','.','.','4','1','9','.','.','5'},
        {'.','.','.','.','8','.','.','7','9'}
    };
    bool result = Solution().isValidSudoku(board);

    bool expected = false;
    BOOST_CHECK_EQUAL(result, expected);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: johnhany/leetcode

max_issues_repo_name: johnhany/leetcode

max_forks_repo_name: johnhany/leetcode


text:
#pragma once

#include <cmath>

#include <Eigen/SparseLU>

#include "OpenABF/Exceptions.hpp"
#include "OpenABF/HalfEdgeMesh.hpp"
#include "OpenABF/Math.hpp"

namespace OpenABF
{

namespace traits
{
/** @brief ABF and ABFPlusPlus vertex traits */
template <typename T>
struct ABFVertexTraits : public DefaultVertexTraits<T> {
    /** Lagrange Multiplier: Planarity constraint */
    T lambda_plan{0};
    /** Lagrange Multiplier: Reconstruction constraint */
    T lambda_len{1};
};

/** @brief ABF and ABFPlusPlus edge traits */
template <typename T>
struct ABFEdgeTraits : public DefaultEdgeTraits<T> {
    /** 3D angle */
    T beta{0};
    /** Optimal (i.e. target) angle */
    T phi{0};
    /** Angle weight */
    T weight{0};
    /** Sin of alpha, because it's used a lot */
    T alpha_sin{0};
    /** Cos of alpha, because it's used a lot */
    T alpha_cos{0};
};

/** @brief ABF and ABFPlusPlus face traits */
template <typename T>
struct ABFFaceTraits : public DefaultFaceTraits<T> {
    /** Lagrange Multiplier: Triangle validity constraint */
    T lambda_tri{0};
};
}  // namespace traits

namespace detail
{

/** @brief %ABF and ABF++ implementation details */
namespace ABF
{

/** @brief A HalfEdgeMesh with the %ABF traits */
template <typename T>
using Mesh = HalfEdgeMesh<
    T,
    3,
    traits::ABFVertexTraits<T>,
    traits::ABFEdgeTraits<T>,
    traits::ABFFaceTraits<T>>;

/** @brief Initialize the %ABF angles and weights from the edge alpha values */
template <typename T, class MeshPtr>
void InitializeAnglesAndWeights(MeshPtr& m)
{
    // Initialize and bound angle properties
    static constexpr auto MinAngle = PI<T> / T(180);
    static constexpr auto MaxAngle = PI<T> - MinAngle;
    for (auto& e : m->edges()) {
        e->alpha = e->beta = e->phi =
            std::min(std::max(e->alpha, MinAngle), MaxAngle);
        e->alpha_sin = std::sin(e->alpha);
        e->alpha_cos = std::cos(e->alpha);
        e->weight = T(1) / (e->phi * e->phi);
    }

    // Update weights for interior vertices
    for (auto& v : m->vertices_interior()) {
        auto wheel = v->wheel();
        auto angle_sum = std::accumulate(
            wheel.begin(), wheel.end(), T(0),
            [](auto a, auto b) { return a + b->beta; });
        for (auto& e : wheel) {
            e->phi *= 2 * PI<T> / angle_sum;
            e->weight = T(1) / (e->phi * e->phi);
        }
    }
}

/** @brief Compute ∇CTri w.r.t LambdaTri == CTri */
template <
    typename T,
    class FacePtr,
    std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
auto TriGrad(const FacePtr& f) -> T
{
    T g = -PI<T>;
    for (const auto& e : *f) {
        g += e->alpha;
    }
    return g;
}

/** @brief Compute ∇CPlan w.r.t LambdaPlan == CPlan */
template <
    typename T,
    class VertPtr,
    std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
auto PlanGrad(const VertPtr& v) -> T
{
    auto edges = v->wheel();
    T g = -2 * PI<T>;
    for (const auto& e : v->wheel()) {
        g += e->alpha;
    }
    return g;
}

/** @brief Compute ∇CLen w.r.t LambdaLen == CLen */
template <
    typename T,
    class VertPtr,
    std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
auto LenGrad(const VertPtr& vertex) -> T
{
    T p1{1};
    T p2{1};
    for (const auto& e : vertex->wheel()) {
        p1 *= e->next->alpha_sin;
        p2 *= e->next->next->alpha_sin;
    }
    return p1 - p2;
}

/** @brief Compute ∇CLen w.r.t edge->alpha */
template <
    typename T,
    class VertPtr,
    class EdgePtr,
    std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
auto LenGrad(const VertPtr& vertex, const EdgePtr& edge) -> T
{
    T p1{1};
    T p2{1};
    for (const auto& a : vertex->wheel()) {
        auto b = a->next;
        if (b == edge) {
            p1 *= b->alpha_cos;
            p2 = T(0);
        } else {
            p1 *= b->alpha_sin;
        }

        auto c = a->next->next;
        if (c == edge) {
            p1 = T(0);
            p2 *= c->alpha_cos;
        } else {
            p2 *= c->alpha_sin;
        }
    }
    return p1 - p2;
}

/** @brief Compute ∇F w.r.t an edge's alpha */
template <
    typename T,
    class EdgePtr,
    std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
auto AlphaGrad(const EdgePtr& edge) -> T
{
    // δE/δα
    auto g = (edge->alpha - edge->phi) * edge->weight;
    // δCTri/δα
    g += edge->face->lambda_tri;
    for (const auto& e : *edge->face) {
        // Skip boundary vertices
        if (e->vertex->is_boundary()) {
            continue;
        }
        if (e == edge) {
            // δCPlan/δα
            g += e->vertex->lambda_plan;
        } else {
            // δCLen/δα
            auto d = LenGrad<T>(e->vertex, edge);
            d *= e->vertex->lambda_len;
            g += d;
        }
    }
    return g;
}

/** @brief Compute ∇F w.r.t all parameters */
template <
    typename T,
    class MeshPtr,
    std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
auto Gradient(const MeshPtr& mesh) -> T
{
    T g{0};
    for (const auto& f : mesh->faces()) {
        // AlphaGrad for all edges
        for (const auto& e : *f) {
            auto gAlpha = AlphaGrad<T>(e);
            g += gAlpha * gAlpha;
        }
        // TriGrad for all faces
        auto gTri = TriGrad<T>(f);
        g += gTri * gTri;
    }

    // PlanGrad and LenGrad for all interior vertices
    for (const auto& v : mesh->vertices_interior()) {
        auto gPlan = PlanGrad<T>(v);
        g += gPlan * gPlan;

        auto gLen = LenGrad<T>(v);
        g += gLen * gLen;
    }
    return g;
}
}  // namespace ABF
}  // namespace detail

/**
 * @brief Compute parameterized interior angles using Angle-based flattening
 *
 * Iteratively computes a new set of interior angles which minimize the total
 * angular error of the parameterized mesh. This follows the standard
 * angled-based flattening formulation, which directly solves for the objective
 * functions and constraints. ABFPlusPlus is generally preferred as it
 * dramatically simplifies the size of the solved problem without introducing
 * more error.
 *
 * This class **does not** compute a parameterized mesh. Rather, it calculates
 * the optimal interior angles for such a mesh. To convert this information
 * into a full parameterization, pass the processed HalfEdgeMesh to
 * AngleBasedLSCM.
 *
 * Implements "Parameterization of faceted surfaces for meshing using
 * angle-based flattening" by Sheffer and de Sturler (2001)
 * \cite sheffer2001abf.
 *
 * @tparam T Floating-point type
 * @tparam MeshType HalfEdgeMesh type which implements the ABF traits
 * @tparam Solver A solver implementing the
 * [Eigen Sparse solver
 * concept](https://eigen.tuxfamily.org/dox-devel/group__TopicSparseSystems.html)
 * and templated on Eigen::SparseMatrix<T>
 */
template <
    typename T,
    class MeshType = detail::ABF::Mesh<T>,
    class Solver =
        Eigen::SparseLU<Eigen::SparseMatrix<T>, Eigen::COLAMDOrdering<int>>,
    std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
class ABF
{
public:
    /** @brief Mesh type alias */
    using Mesh = MeshType;

    /** @brief Set the maximum number of iterations */
    void setMaxIterations(std::size_t it) { maxIters_ = it; }

    /**
     * @brief Get the mesh gradient
     *
     * **Note:** Result is only valid after running compute().
     */
    auto gradient() const -> T { return grad_; }

    /**
     * @brief Get the number of iterations of the last computation
     *
     * **Note:** Result is only valid after running compute().
     */
    auto iterations() const -> std::size_t { return iters_; }

    /** @copydoc ABF::Compute */
    void compute(typename Mesh::Pointer& mesh)
    {
        Compute(mesh, iters_, grad_, maxIters_);
    }

    /**
     * @brief Compute parameterized interior angles
     *
     * @throws SolverException If matrix cannot be decomposed or if solver fails
     * to find a solution.
     * @throws MeshException If mesh gradient cannot be calculated.
     */
    static void Compute(
        typename Mesh::Pointer& mesh,
        std::size_t& iters,
        T& gradient,
        std::size_t maxIters = 10)
    {
        using namespace detail::ABF;

        // Initialize angles and weights
        InitializeAnglesAndWeights<T>(mesh);

        // while ||∇F(x)|| > ε
        gradient = Gradient<T>(mesh);
        if (std::isnan(gradient) or std::isinf(gradient)) {
            throw MeshException("Mesh gradient cannot be computed");
        }
        auto gradDelta = INF<T>;
        iters = 0;
        while (gradient > 0.001 and gradDelta > 0.001 and iters < maxIters) {
            if (std::isnan(gradient) or std::isinf(gradient)) {
                throw MeshException("Mesh gradient cannot be computed");
            }
            // Typedefs
            using Triplet = Eigen::Triplet<T>;
            using SparseMatrix = Eigen::SparseMatrix<T>;
            using DenseVector = Eigen::Matrix<T, Eigen::Dynamic, 1>;

            // Helpful parameters
            auto vCnt = mesh->num_vertices();
            auto vIntCnt = mesh->num_vertices_interior();
            auto edgeCnt = mesh->num_edges();
            auto faceCnt = mesh->num_faces();

            //// RHS ////
            // b1 = -alpha gradient
            std::vector<Triplet> triplets;
            std::size_t idx{0};
            for (const auto& e : mesh->edges()) {
                triplets.emplace_back(idx, 0, -AlphaGrad<T>(e));
                ++idx;
            }

            // b2 = -lambda gradient
            // lambda tri
            for (const auto& f : mesh->faces()) {
                triplets.emplace_back(idx, 0, -TriGrad<T>(f));
                ++idx;
            }
            // lambda plan and lambda len
            for (const auto& v : mesh->vertices_interior()) {
                triplets.emplace_back(idx, 0, -PlanGrad<T>(v));
                triplets.emplace_back(vIntCnt + idx, 0, -LenGrad<T>(v));
                ++idx;
            }
            SparseMatrix b(edgeCnt + faceCnt + 2 * vIntCnt, 1);
            b.reserve(triplets.size());
            b.setFromTriplets(triplets.begin(), triplets.end());

            // vertex idx -> interior vertex idx permutation
            std::map<std::size_t, std::size_t> vIdx2vIntIdx;
            std::size_t newIdx{0};
            for (const auto& v : mesh->vertices_interior()) {
                vIdx2vIntIdx[v->idx] = newIdx++;
            }

            ///// LHS /////
            // Lambda = diag(2/w)
            // v.weight == 1/w, so Lambda is diag(2*weight)
            // We only need Lambda Inverse, so this is 1 / 2*weight
            triplets.clear();
            idx = 0;
            for (const auto& e : mesh->edges()) {
                triplets.emplace_back(idx, idx, 2 * e->weight);
                ++idx;
            }

            // J
            // Jacobian of the CTri constraints
            for (idx = 0; idx < faceCnt; idx++) {
                auto row = idx + edgeCnt;
                auto col = 3 * idx;
                triplets.emplace_back(row, col, 1);
                triplets.emplace_back(row, col + 1, 1);
                triplets.emplace_back(row, col + 2, 1);

                // Jt
                triplets.emplace_back(col, row, 1);
                triplets.emplace_back(col + 1, row, 1);
                triplets.emplace_back(col + 2, row, 1);
            }
            for (const auto& v : mesh->vertices_interior()) {
                auto row = idx + edgeCnt;
                for (const auto& e0 : v->wheel()) {
                    // Jacobian of the CPlan constraint
                    triplets.emplace_back(row, e0->idx, 1);
                    triplets.emplace_back(e0->idx, row, 1);

                    // Jacobian of the CLen constraint
                    auto e1 = e0->next;
                    auto e2 = e1->next;
                    auto d1 = LenGrad<T>(v, e1);
                    auto d2 = LenGrad<T>(v, e2);
                    triplets.emplace_back(vIntCnt + row, e1->idx, d1);
                    triplets.emplace_back(vIntCnt + row, e2->idx, d2);
                    triplets.emplace_back(e1->idx, vIntCnt + row, d1);
                    triplets.emplace_back(e2->idx, vIntCnt + row, d2);
                }
                ++idx;
            }
            auto Asize = edgeCnt + faceCnt + 2 * vIntCnt;
            SparseMatrix A(Asize, Asize);
            A.reserve(triplets.size());
            A.setFromTriplets(triplets.begin(), triplets.end());

            A.makeCompressed();
            Solver solver;
            solver.compute(A);
            if (solver.info() != Eigen::ComputationInfo::Success) {
                throw SolverException(solver.lastErrorMessage());
            }
            DenseVector delta = solver.solve(b);
            if (solver.info() != Eigen::ComputationInfo::Success) {
                throw SolverException(solver.lastErrorMessage());
            }

            // alpha += delta_alpha
            // Update sin and cos
            idx = 0;
            for (auto& e : mesh->edges()) {
                e->alpha += delta(idx++, 0);
                e->alpha = std::min(std::max(e->alpha, T(0)), PI<T>);
                e->alpha_sin = std::sin(e->alpha);
                e->alpha_cos = std::cos(e->alpha);
            }

            // lambda += delta_lambda
            for (auto& f : mesh->faces()) {
                f->lambda_tri += delta(idx++, 0);
            }
            for (auto& v : mesh->vertices_interior()) {
                auto intIdx = vIdx2vIntIdx.at(v->idx);
                v->lambda_plan += delta(idx + intIdx, 0);
                v->lambda_len += delta(idx + vIntCnt + intIdx, 0);
                idx++;
            }

            // Recalculate gradient for next iteration
            auto newGrad = detail::ABF::Gradient<T>(mesh);
            gradDelta = std::abs(newGrad - gradient);
            gradient = newGrad;
            iters++;
        }
    }

    /** @copydoc ABF::Compute */
    static void Compute(typename Mesh::Pointer& mesh)
    {
        std::size_t iters{0};
        T grad{0};
        Compute(mesh, iters, grad);
    }

protected:
    /** Gradient */
    T grad_{0};
    /** Number of executed iterations */
    std::size_t iters_{0};
    /** Max iterations */
    std::size_t maxIters_{10};
};

}  // namespace OpenABF

max_stars_repo_name: educelab/OpenABF

max_issues_repo_name: educelab/OpenABF

max_forks_repo_name: educelab/OpenABF


text:
#pragma once
#define _CRT_SECURE_NO_WARNINGS

//数据结构
#include <map>
#include <string>
#include <vector>
#include "mycq.hpp"

//系统
#include <Windows.h>
#include <direct.h>
#include <time.h>
#include <fstream>
#include <thread>

//#include <regex>
#include <boost/regex.hpp>
//#include <boost/timer.hpp>

#include "MyJson.h"
#include "moderation.hpp"

using namespace std;

string appDir;
MyJson conf;

/*私聊指令*/
class Private {
    enum PrivateIndex {
        NONE,

        SEND_GROUP_GETID,
        SEND_GROUP_END,
        SEND_QQ,

        ADD_KEYWORD,
        ADD_KEYWORD_WHITE,
        ADD_KEYWORD_RE,

        DEL_KEYWORD,
        DEL_KEYWORD_WHITE,
        DEL_KEYWORD_RE,

        ADD_QQLIST,
        ADD_GROUPLIST_SEND,

        DEL_QQLIST,
        DEL_GROUPLIST_SEND,

        ADD_GROUPLIST,
        DEL_GROUPLIST

    };

public:
    Private(long long fromQQ = 0) : m_fromQQ(fromQQ), m_index(NONE), m_ReplyGroup(0), m_ReplyQQ(0) {
    }

    void init(int64_t fromQQ) {
        m_fromQQ = fromQQ;
    }

    //发送给所有主人
    void sendAdminMsg(string& SendMsg) {
        for (long long root : conf.admin) {
            mycq::send_private_message_async(root, SendMsg, conf.async);
        }
    }

    //私聊消息处理
    void funthing(const char* msg) {
        auto iter = find(conf.admin.begin(), conf.admin.end(), m_fromQQ);

        if (iter == conf.admin.end()) {
            //不是主人时将消息转发给主人
            MsgRelayFun(msg);
        } else {
            //为主人时进入指令函数
            instruct(msg);
        }
    }

    //消息转发
    void MsgRelayFun(const char* msg) {
        if (conf.relayPrivateMsg) {
            std::ostringstream SendMsg;

            //获取QQ资料
            auto QQInf = mycq::get_stranger_info(m_fromQQ, true);

            //构造消息
            SendMsg << "来自" << QQInf.nickname << "(" + std::to_string(m_fromQQ) << ")的私聊消息:" << endl << endl;
            SendMsg << msg << endl << endl;
            SendMsg << "(回复请发送 回复" << std::to_string(m_fromQQ) << ")";

            //发送给主人
            sendAdminMsg(SendMsg.str());
        }
    }

    //指令对话
    void funcute(const char* msg) {
        switch (m_index) {
        case SEND_GROUP_GETID: //回复群
        {
            m_ReplyGroup = atoll(msg);
            mycq::send_private_message(m_fromQQ, "请发送回复内容");
            m_index = SEND_GROUP_END;
            break;
        }
        case SEND_GROUP_END: //回复群
        {
            ostringstream sendMsg;
            int res;
            res = mycq::send_group_message(m_ReplyGroup, msg);

            // auto groupInf = mycq::get_group_list_map();
            auto groupInf = mycq::get_group_info(m_ReplyGroup);
            if (res == 0)
                sendMsg << "发送给QQ群 " << groupInf.group_name << "(" << m_ReplyGroup << ") "
                        << "成功";
            else
                sendMsg << "发送给QQ群 " << groupInf.group_name << "(" << m_ReplyGroup << ") "
                        << "失败" << endl
                        << "错误代码：" << res;
            mycq::send_private_message(m_fromQQ, sendMsg.str());
            m_ReplyGroup = 0;
            m_index = NONE;
            break;
        }
        case ADD_KEYWORD: //添加关键词
        {
            //支持批量添加 解析每行数据
            unordered_set<string> temp_array;
            temp_array = MyUtils::line_get_str(msg);

            for (auto temp_keyword : temp_array) {
                WKEYWORD temp_add(temp_keyword);
                conf.alone[0].keyWord.insert(temp_add);
            }

            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            mycq::send_private_message(m_fromQQ, "添加 默认关键词 成功");

            m_index = NONE;
            break;
        }
        case DEL_KEYWORD: //删除关键词
        {
            bool del_bool = false;

            auto it = conf.alone[0].keyWord.begin();

            while (it != conf.alone[0].keyWord.end()) {
                if (it->keyWord == msg) {
                    auto del = it;

                    it = conf.alone[0].keyWord.erase(del);
                    del_bool = true;
                } else {
                    it++;
                }
            }

            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            if (del_bool)
                mycq::send_private_message(m_fromQQ, "删除 默认关键词 成功");
            else
                mycq::send_private_message(m_fromQQ, "删除 默认关键词 失败");

            m_index = NONE;
            break;
        }
        case ADD_QQLIST: //添加名单
        {
            //支持批量添加 解析每行数据
            unordered_set<long long> temp_array;
            temp_array = MyUtils::line_get_ll(msg);

            for (auto temp_longlong : temp_array) {
                conf.alone[0].QQList.insert(temp_longlong);
            }

            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            mycq::send_private_message(m_fromQQ, "添加默认 名单 成功");

            m_index = NONE;
            break;
        }
        case DEL_QQLIST: //删除名单
        {
            bool del_bool = false;

            long long del_QQId = 0;
            del_QQId = atoll(msg);

            if (del_QQId == 0) {
                mycq::send_private_message(m_fromQQ, "格式有误");
                m_index = NONE;
                break;
            }

            auto it = conf.alone[0].QQList.begin();

            while (it != conf.alone[0].QQList.end()) {
                if (*it == del_QQId) {
                    auto del = it;

                    it = conf.alone[0].QQList.erase(del);
                    del_bool = true;
                } else {
                    it++;
                }
            }

            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            if (del_bool)
                mycq::send_private_message(m_fromQQ, "删除默认 名单 成功");
            else
                mycq::send_private_message(m_fromQQ, "删除默认 名单 失败");

            m_index = NONE;
            break;
        }
        case ADD_GROUPLIST: //添加监控群
        {
            //支持批量添加 解析每行数据
            unordered_set<long long> temp_array;
            temp_array = MyUtils::line_get_ll(msg);

            for (auto temp_longlong : temp_array) {
                conf.alone[0].groupList.insert(temp_longlong);
            }

            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            mycq::send_private_message(m_fromQQ, "添加 默认监控群 成功");
            m_index = NONE;
            break;
        }
        case DEL_GROUPLIST: //删除监控群
        {
            bool del_bool = false;

            long long del_GourpId = 0;
            del_GourpId = atoll(msg);

            if (del_GourpId == 0) {
                mycq::send_private_message(m_fromQQ, "格式有误");
                m_index = NONE;
                break;
            }

            auto it = conf.alone[0].groupList.begin();

            while (it != conf.alone[0].groupList.end()) {
                if (*it == del_GourpId) {
                    auto del = it;

                    it = conf.alone[0].groupList.erase(del);
                    del_bool = true;
                } else {
                    it++;
                }
            }

            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            if (del_bool)
                mycq::send_private_message(m_fromQQ, "删除 默认监控群 成功");
            else
                mycq::send_private_message(m_fromQQ, "删除 默认监控群 失败");
            m_index = NONE;
            break;
        }
        case SEND_QQ: //回复QQ
        {
            ostringstream sendMsg;
            int res;
            res = mycq::send_private_message(m_ReplyQQ, msg);

            auto QQInf = mycq::get_stranger_info(m_ReplyQQ);
            if (res == 0)
                sendMsg << "发送给QQ " << QQInf.nickname << "(" << m_ReplyQQ << ")"
                        << " 成功";
            else
                sendMsg << "发送给QQ " << QQInf.nickname << "(" << m_ReplyQQ << ")"
                        << " 失败" << endl
                        << "错误代码：" << res;
            mycq::send_private_message(m_fromQQ, sendMsg.str());
            m_ReplyQQ = 0;
            m_index = NONE;
            break;
        } //回复QQ

        case ADD_KEYWORD_WHITE: //添加白名单关键词
        {
            //支持批量添加 解析每行数据
            unordered_set<string> temp_array;
            temp_array = MyUtils::line_get_str(msg);

            for (auto temp_keyword : temp_array) {
                WKEYWORD temp_add(temp_keyword);
                conf.alone[0].keyWordWhite.insert(temp_add);
            }

            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            mycq::send_private_message(m_fromQQ, "添加默认 白名单关键词 成功");

            m_index = NONE;
            break;
        }
        case DEL_KEYWORD_WHITE: //删除白名单关键词
        {
            bool del_bool = false;

            auto it = conf.alone[0].keyWordWhite.begin();

            while (it != conf.alone[0].keyWordWhite.end()) {
                if (it->keyWord == msg) {
                    auto del = it;

                    it = conf.alone[0].keyWordWhite.erase(del);
                    del_bool = true;
                } else {
                    it++;
                }
            }
            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            if (del_bool)
                mycq::send_private_message(m_fromQQ, "删除默认 白名单关键词 成功");
            else
                mycq::send_private_message(m_fromQQ, "删除默认 白名单关键词 失败");

            m_index = NONE;
            break;
        }

        case ADD_KEYWORD_RE: //添加正则表达式关键词
        {
            //支持批量添加 解析每行数据
            unordered_set<string> temp_array;
            temp_array = MyUtils::line_get_str(msg);

            for (auto temp_keyword : temp_array) {
                WKEYWORD temp_add(temp_keyword);
                conf.alone[0].keyWordRegex.insert(temp_add);
            }
            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            mycq::send_private_message(m_fromQQ, "添加默认 正则表达式关键词 成功");

            m_index = NONE;
            break;
        }
        case DEL_KEYWORD_RE: //删除正则表达式关键词
        {
            bool del_bool = false;

            auto it = conf.alone[0].keyWordRegex.begin();

            while (it != conf.alone[0].keyWordRegex.end()) {
                if (it->keyWord == msg) {
                    auto del = it;

                    it = conf.alone[0].keyWordRegex.erase(del);
                    del_bool = true;
                } else {
                    it++;
                }
            }
            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            if (del_bool)
                mycq::send_private_message(m_fromQQ, "删除默认 正则表达式关键词 成功");
            else
                mycq::send_private_message(m_fromQQ, "删除默认 正则表达式关键词 失败");

            m_index = NONE;
            break;
        }

        case ADD_GROUPLIST_SEND: //添加转发到群号码
        {
            //支持批量添加 解析每行数据
            unordered_set<long long> temp_array;
            temp_array = MyUtils::line_get_ll(msg);

            for (auto temp_longlong : temp_array) {
                conf.alone[0].relayGroupList.insert(temp_longlong);
            }

            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            mycq::send_private_message(m_fromQQ, "添加默认 转发群 成功");

            m_index = NONE;
            break;
        }
        case DEL_GROUPLIST_SEND: //删除转发到群号码
        {
            bool del_bool = false;

            long long del_QQId = 0;
            del_QQId = atoll(msg);

            if (del_QQId == 0) {
                mycq::send_private_message(m_fromQQ, "格式有误");
                m_index = NONE;
                break;
            }

            auto it = conf.alone[0].relayGroupList.begin();

            while (it != conf.alone[0].relayGroupList.end()) {
                if (*it == del_QQId) {
                    auto del = it;

                    it = conf.alone[0].relayGroupList.erase(del);
                    del_bool = true;
                } else {
                    it++;
                }
            }

            //重新构造json 并写入文件
            conf.all2json();
            conf.json2file();

            if (del_bool)
                mycq::send_private_message(m_fromQQ, "删除默认 转发群 成功");
            else
                mycq::send_private_message(m_fromQQ, "删除默认 转发群 失败");

            m_index = NONE;
            break;
        }
        }
    }

    //指令检测
    void instruct(const char* msg) {
        string& prefix = conf.prefix;

        //检测是否有为处理完的指令对话
        if (m_index != NONE) {
            funcute(msg);
            return;
        }

        //功能菜单
        if (!std::string(prefix + "功能").compare(msg) || !std::string(prefix + "菜单").compare(msg)
            || !strcmp(msg, "关键词触发器菜单")) {
            std::string menu =
                "******设置类*******\n"
                "查看/添加/删除关键词\n" //[CQ:emoji,id=9999]
                "查看/添加/删除白名单关键词\n"
                "查看/添加/删除正则表达式关键词\n"
                "查看/添加/删除监控群\n" //[CQ:emoji,id=127984]
                "查看/添加/删除转发群\n"
                "查看/添加/删除监控名单\n" //[CQ:emoji,id=128203]
                "查看/添加/删除白名单\n"
                "\n"

                "******开关类*****\n"
                "开启/关闭强力检测\n"
                "开启/关闭提醒主人\n"
                "开启/关闭撤回消息\n"
                "开启/关闭群内提醒\n"
                "开启/关闭私聊提醒\n"
                "开启/关闭华为云接口\n"
                "\n"

                "******回复类******\n"
                "回复群+QQ群号\n" //[CQ:emoji,id=127380]
                "回复+QQ号\n"
                //"退出群+QQ群号\n"
                "\n"

                "只能修改默认设置，无法对单独设置进行修改\n"
                "请发送功能名称（不包括表情）\n"
                "如: 查看关键词";

            mycq::send_private_message(m_fromQQ, menu);
            m_index = NONE;
        }

        //开关类
        else if (!std::string(prefix + "开启强力检测").compare(msg)) {
            conf.alone[0].streng = true;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已开启 强力检测关键词");

            return;
        } else if (!std::string(prefix + "关闭强力检测").compare(msg)) {
            conf.alone[0].streng = false;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已关闭 强力检测关键词");

            m_index = NONE;
        } else if (!std::string(prefix + "开启提醒主人").compare(msg)) {
            conf.alone[0].keyWordSendAdmin = true;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已开启 触发关键词提醒主人");

            return;
        } else if (!std::string(prefix + "关闭提醒主人").compare(msg)) {
            conf.alone[0].keyWordSendAdmin = false;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已关闭 触发关键词提醒主人");

            return;
        } else if (!std::string(prefix + "开启群内提醒").compare(msg)) {
            conf.alone[0].keyWordGroupWarn = true;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已开启 触发关键词后发送群消息提醒");

            return;
        } else if (!std::string(prefix + "关闭群内提醒").compare(msg)) {
            conf.alone[0].keyWordGroupWarn = false;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已关闭 触发关键词后发送群消息提醒");

            return;
        } else if (!std::string(prefix + "开启私聊提醒").compare(msg)) {
            conf.alone[0].keyWordPrivateWarn = true;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已开启 触发关键词后发送私聊提醒");

            return;
        } else if (!std::string(prefix + "关闭私聊提醒").compare(msg)) {
            conf.alone[0].keyWordPrivateWarn = false;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已关闭 触发关键词后发送私聊提醒");

            m_index = NONE;
        } else if (!std::string(prefix + "开启撤回消息").compare(msg)
                   || !std::string(prefix + "开启消息撤回").compare(msg)) {
            conf.alone[0].deleteMsg = true;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已开启 撤回触发关键词消息（需Pro）");

            return;
        } else if (!std::string(prefix + "关闭撤回消息").compare(msg)
                   || !std::string(prefix + "关闭消息撤回").compare(msg)) {
            conf.alone[0].deleteMsg = false;
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已关闭 撤回触发关键词消息（需Pro）");

            return;
        } else if (!std::string(prefix + "开启华为云接口").compare(msg)) {
            conf.alone[0].huaweiApiSwitch = true;

            if (conf.alone[0].huaweiDomainName.empty() || conf.alone[0].huaweiPassWord.empty()
                || conf.alone[0].huaweiProjectName.empty() || conf.alone[0].huaweiUserName.empty()) {
                mycq::send_private_message(m_fromQQ, "开启华为云接口失败，原因:未在界面添加华为云的必要设置");
                return;
            }
            conf.initModeration();
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已开启 华为云接口");

            return;
        } else if (!std::string(prefix + "关闭华为云接口").compare(msg)) {
            conf.alone[0].huaweiApiSwitch = false;
            conf.initModeration();
            conf.alone2json();
            conf.json2file();
            mycq::send_private_message(m_fromQQ, "已关闭 华为云接口");

            return;
        }

        //回复类
        else if (!std::string(prefix + "回复群").compare(msg)) {
            mycq::send_private_message(m_fromQQ, "请发送要回复的QQ群号");
            m_index = SEND_GROUP_GETID;
        } else if (std::string(msg).find(prefix + "回复群") != string::npos) {
            m_ReplyGroup = atoll(msg + std::string(prefix + "回复群").length());

            if (m_ReplyGroup == 0) {
                mycq::send_private_message(m_fromQQ, "格式有误，请按照格式重新发送");
                return;
            }
            mycq::send_private_message(m_fromQQ, "请发送回复内容");
            m_index = SEND_GROUP_END;
        } else if (std::string(msg).find(prefix + "回复") != string::npos) {
            m_ReplyQQ = atoll(msg + std::string(prefix + "回复").length());
            if (m_ReplyQQ != 0) {
                mycq::send_private_message(m_fromQQ, "请发送要回复的消息");
                m_index = SEND_QQ;
            } else {
                mycq::send_private_message(m_fromQQ, "格式有误，请发送 回复+QQ号");
                m_index = NONE;
            }

        }

        //默认关键词
        else if (!std::string(prefix + "查看关键词").compare(msg)) {
            string SendMsg = "全局默认 关键词\n";

            for (auto KeyWord : conf.alone[0].keyWord) SendMsg += KeyWord.keyWord + "\n";

            mycq::send_private_message(m_fromQQ, SendMsg);
            m_index = NONE;
        } else if (!std::string(prefix + "添加关键词").compare(msg)) {
            mycq::send_private_message(m_fromQQ, "请发送添加的关键词(可批量添加，每行一个)");
            m_index = ADD_KEYWORD;
        } else if (!std::string(prefix + "删除关键词").compare(msg)) {
            std::string SendMsg = "全局默认 关键词：\n";

            for (auto WKeyWord : conf.alone[0].keyWord) {
                SendMsg += WKeyWord.keyWord + "\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);

            mycq::send_private_message(m_fromQQ, "请发送准备删除的关键词");
            m_index = DEL_KEYWORD;
        }

        //白名单关键词
        else if (!std::string(prefix + "查看白名单关键词").compare(msg)) {
            string SendMsg = "全局默认 白名单关键词：\n";

            for (auto KeyWord : conf.alone[0].keyWordWhite) SendMsg += KeyWord.keyWord + "\n";

            mycq::send_private_message(m_fromQQ, SendMsg);
            m_index = NONE;
        } else if (!std::string(prefix + "添加白名单关键词").compare(msg)) {
            mycq::send_private_message(m_fromQQ, "请发送添加的 白名单关键词 (可批量添加，每行一个)");
            m_index = ADD_KEYWORD_WHITE;
        } else if (!std::string(prefix + "删除白名单关键词").compare(msg)) {
            std::string SendMsg = "全局默认 白名单关键词：\n";

            for (auto WKeyWord : conf.alone[0].keyWordWhite) {
                SendMsg += WKeyWord.keyWord + "\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);

            mycq::send_private_message(m_fromQQ, "请发送准备删除的 白名单关键词");
            m_index = DEL_KEYWORD_WHITE;
        }

        //正则表达式关键词
        else if (!std::string(prefix + "查看正则表达式关键词").compare(msg)) {
            string SendMsg = "全局默认 正则表达式关键词：\n";

            for (auto KeyWord : conf.alone[0].keyWordRegex) SendMsg += KeyWord.keyWord + "\n";

            mycq::send_private_message(m_fromQQ, SendMsg);
            m_index = NONE;
        } else if (!std::string(prefix + "添加正则表达式关键词").compare(msg)) {
            mycq::send_private_message(m_fromQQ, "请发送添加的 正则表达式关键词 (可批量添加，每行一个)");
            m_index = ADD_KEYWORD_RE;
        } else if (!std::string(prefix + "删除正则表达式关键词").compare(msg)) {
            std::string SendMsg = "全局默认 正则表达式关键词：\n";

            for (auto WKeyWord : conf.alone[0].keyWordRegex) {
                SendMsg += WKeyWord.keyWord + "\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);

            mycq::send_private_message(m_fromQQ, "请发送准备删除的 正则表达式关键词");
            m_index = DEL_KEYWORD_RE;
        }

        //设置转发群
        else if (!std::string(prefix + "查看转发群").compare(msg)) {
            std::string SendMsg = "全局默认 转发群：\n";
            auto temp_GourpList = mycq::get_group_list_map();

            //列出监控群名单
            for (auto id : conf.alone[0].relayGroupList) {
                SendMsg += temp_GourpList[id].group_name + "(" + to_string(id) + ")\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);

            m_index = NONE;
            m_index = NONE;
        } else if (!std::string(prefix + "添加转发群").compare(msg)) {
            mycq::send_private_message(m_fromQQ, "请发送添加的 群号码 (可批量添加，每行一个)");
            m_index = ADD_GROUPLIST_SEND;
        } else if (!std::string(prefix + "删除转发群").compare(msg)) {
            std::string SendMsg = "全局默认 转发群：\n";
            auto temp_GourpList = mycq::get_group_list_map();

            //列出监控群名单
            for (auto id : conf.alone[0].relayGroupList) {
                SendMsg += temp_GourpList[id].group_name + "(" + to_string(id) + ")\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);
            mycq::send_private_message(m_fromQQ, "请发送要删除 群号码");
            m_index = DEL_GROUPLIST_SEND;
        }

        //设置监控群
        else if (!std::string(prefix + "添加监控群").compare(msg)) {
            mycq::send_private_message(m_fromQQ, "请发送添加的群号码(可批量添加，每行一个)");
            m_index = ADD_GROUPLIST;
        } else if (!std::string(prefix + "删除监控群").compare(msg)) {
            std::string SendMsg = "全局默认 监控群：\n";
            auto temp_GourpList = mycq::get_group_list_map();

            //列出监控群名单
            for (auto id : conf.alone[0].groupList) {
                SendMsg += temp_GourpList[id].group_name + "(" + to_string(id) + ")\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);
            mycq::send_private_message(m_fromQQ, "请发送要删除群号码");
            m_index = DEL_GROUPLIST;
        } else if (!std::string(prefix + "查看监控群").compare(msg)) {
            std::string SendMsg = "全局默认 监控群：\n";
            auto temp_GourpList = mycq::get_group_list_map();

            //列出监控群名单
            for (auto id : conf.alone[0].groupList) {
                SendMsg += temp_GourpList[id].group_name + "(" + to_string(id) + ")\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);

            m_index = NONE;
        }

        //设置监控名单
        else if (!std::string(prefix + "添加监控名单").compare(msg)) {
            if (conf.alone[0].QQListType == 0) {
                mycq::send_private_message(m_fromQQ,
                                           "当前特殊名单模式为白名单，与您的指令不符，请在先界面中设置为监控名单模式");
                return;
            }

            mycq::send_private_message(m_fromQQ, "请发送添加的监控名单QQ(可批量添加，每行一个)");
            m_index = ADD_QQLIST;
        } else if (!std::string(prefix + "删除监控名单").compare(msg)) {
            if (conf.alone[0].QQListType == 0) {
                mycq::send_private_message(m_fromQQ,
                                           "当前特殊名单模式为白名单，与您的指令不符，请在先界面中设置为监控名单模式");
                return;
            }
            std::string SendMsg = "全局默认 监控名单：\n";

            for (auto id : conf.alone[0].QQList) {
                auto QQinf = mycq::get_stranger_info(id);
                SendMsg += QQinf.nickname + "(" + to_string(id) + ")\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);
            mycq::send_private_message(m_fromQQ, "请发送要删除白名单号码");
            m_index = DEL_QQLIST;
        } else if (!std::string(prefix + "查看监控名单").compare(msg)) {
            if (conf.alone[0].QQListType == 0) {
                mycq::send_private_message(m_fromQQ,
                                           "当前特殊名单模式为白名单，与您的指令不符，请在先界面中设置为监控名单模式");
                return;
            }
            std::string SendMsg = "全局默认 监控名单：\n";

            for (auto temp : conf.alone[0].QQList) {
                auto QQinf = mycq::get_stranger_info(temp);
                SendMsg += QQinf.nickname + "(" + to_string(temp) + ")\n";
            }
            mycq::send_private_message(m_fromQQ, SendMsg);

            m_index = NONE;
        }
        //设置白名单
        else if (!std::string(prefix + "添加白名单").compare(msg)) {
            if (conf.alone[0].QQListType == 1) {
                mycq::send_private_message(m_fromQQ,
                                           "当前特殊名单模式为监控名单，与您的指令不符，请在先界面中设置为白名单模式");
                return;
            }

            mycq::send_private_message(m_fromQQ, "请发送添加的白名单(可批量添加，每行一个)");
            m_index = ADD_QQLIST;
        } else if (!std::string(prefix + "删除白名单").compare(msg)) {
            if (conf.alone[0].QQListType == 1) {
                mycq::send_private_message(m_fromQQ,
                                           "当前特殊名单模式为监控名单，与您的指令不符，请在先界面中设置为白名单模式");
                return;
            }
            std::string SendMsg = "全局默认 白名单：\n";

            for (auto id : conf.alone[0].QQList) {
                auto QQinf = mycq::get_stranger_info(id);
                SendMsg += QQinf.nickname + "(" + to_string(id) + ")\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);
            mycq::send_private_message(m_fromQQ, "请发送要删除白名单号码");
            m_index = DEL_QQLIST;
        } else if (!std::string(prefix + "查看白名单").compare(msg)) {
            if (conf.alone[0].QQListType == 1) {
                mycq::send_private_message(m_fromQQ,
                                           "当前特殊名单模式为监控名单，与您的指令不符，请在先界面中设置为白名单模式");
                return;
            }
            std::string SendMsg = "全局默认 白名单：\n";

            for (auto temp : conf.alone[0].QQList) {
                auto QQinf = mycq::get_stranger_info(temp);
                SendMsg += QQinf.nickname + "(" + to_string(temp) + ")\n";
            }

            mycq::send_private_message(m_fromQQ, SendMsg);

            m_index = NONE;
        }
    }

private:
    PrivateIndex m_index; //指令位置

    int64_t m_ReplyGroup; //需要回复的群号码
    int64_t m_ReplyQQ; //需要回复的QQ号码
    int64_t m_fromQQ; //消息来自的QQ号码
};

/*关键词触发*/

class GroupKeyWord {
public:
    //处理
    void dealFun(int conf_index) {
        int& dealType = conf.alone[conf_index].dealType;

        //撤回
        if (conf.alone[conf_index].deleteMsg) mycq::delete_message(m_msgId);

        if (dealType == 1) {
            if (evet.is_anonymous())
                mycq::set_group_anonymous_ban(m_fromGroup, m_fromAnonymous, conf.alone[conf_index].banTimeLen * 60);
            else
                mycq::set_group_ban(m_fromGroup, m_fromQQ, conf.alone[conf_index].banTimeLen * 60);

            std::string TimeStr;

            int TimeDay = 0;
            int TimeHour = 0;
            int TimeMin = 0;

            TimeDay = conf.alone[conf_index].banTimeLen / 1440;
            TimeHour = (conf.alone[conf_index].banTimeLen - TimeDay * 1440) / 60;
            TimeMin = conf.alone[conf_index].banTimeLen % 60;

            if (TimeDay) {
                TimeStr = std::to_string(TimeDay) + "天";
            }

            if (TimeHour) {
                TimeStr += std::to_string(TimeHour) + "小时";
            }

            if (TimeMin) {
                TimeStr += std::to_string(TimeMin) + "分钟";
            }

            dealTypeStr = "禁言";
            dealTypeStr += TimeStr;

        } else if (dealType == 2) {
            mycq::set_group_kick(m_fromGroup, m_fromQQ, false);

            dealTypeStr = "踢出";

        } else if (dealType == 3) {
            mycq::set_group_kick(m_fromGroup, m_fromQQ, true);

            dealTypeStr = "踢出并拉黑";

        } else {
            dealTypeStr = "未做处理";
        }
    }

    //发送给所有主人
    void sendAdminMsg(string& SendMsg) {
        for (long long root : conf.admin) {
            mycq::send_private_message_async(root, SendMsg, conf.async);
        }
    }

    //构造提醒主人消息
    string keyWordSendAdminFun(int conf_index) {
        ostringstream msg;

        auto QQInf = mycq::get_group_member_info(m_fromGroup, m_fromQQ, true);
        // auto groupList = mycq::get_group_list_map();
        auto groupInf = mycq::get_group_info(m_fromGroup);

        string name;
        string card;
        string QQid_str;

        if (evet.is_anonymous()) {
            name = "匿名（" + evet.anonymous.name + "）";
            card = name;
            QQid_str = to_string(m_fromQQ) + "（匿名）";
        } else {
            name = QQInf.nickname;
            card = QQInf.card;
            QQid_str = to_string(m_fromQQ);
        }

        msg << "群号码：" << m_fromGroup << endl;
        msg << "群名称：" << groupInf.group_name << endl;
        msg << "QQ号码：" << QQid_str << endl;
        msg << "QQ名称：" << name << "\n";
        msg << "QQ群名片：" << card << "\n";
        msg << "由于内容：" << endl << endl << m_msg << endl << endl;

        if (!keyWordRegex.empty()) {
            msg << "正则表达式：" << keyWordRegex << endl;
        }

        msg << "触发了关键词：" << keyWord << endl;
        msg << "处理方式：" << dealTypeStr << endl;
        msg << "本次处理总耗时：" << timerElapsed() << "秒" << endl;
        msg << "(回复请发送：回复群" << m_fromGroup << ")";

        return msg.str();
    }

    //触发关键词操作
    void KeyWrodEvent(int conf_index) {
        //处理
        dealFun(conf_index);

        //转发到群
        auto relayGroupList([conf_index, this] {
            if (!conf.alone[conf_index].relayGroupList.empty()) {
                string relayGroupMsg(conf.alone[conf_index].relayGroupWord);
                //转发到群变量
                variableRelayGroup(relayGroupMsg, conf_index);
                //发送
                for (long long GroupId : conf.alone[conf_index].relayGroupList) {
                    mycq::send_group_message_async(GroupId, relayGroupMsg, conf.async);
                }
            }
        });

        //群内警告（回复群内容消息）
        auto keyWordGroupWarn([conf_index, this] {
            if (conf.alone[conf_index].keyWordGroupWarn) //群内回复是否开启
            {
                string sendMsg(conf.alone[conf_index].keyWordGroupWarnWord);
                if (conf.alone[conf_index].keyWordGroupWarnWord.empty()) //自定义内容为空时使用默认提示
                {
                    sendMsg = "{at} 触发关键词，处理方式:{处理方式}";
                }
                variableKeyWordWarn(sendMsg, conf_index); //变量
                mycq::send_group_message_async(m_fromGroup, sendMsg, conf.async);
            }
        });

        //触发后回复私聊消息
        auto keyWordPrivateWarn([conf_index, this] {
            if (conf.alone[conf_index].keyWordPrivateWarn) {
                if (!conf.alone[conf_index].keyWordPrivateWarnWord.empty()) {
                    string sendMsg(conf.alone[conf_index].keyWordPrivateWarnWord);
                    //解析变量
                    variableKeyWordWarn(sendMsg, conf_index);
                    mycq::send_private_message_async(m_fromQQ, sendMsg, conf.async);
                }
            }
        });

        //提醒主人
        auto keyWordSendAdmin([conf_index, this] {
            if (conf.alone[conf_index].keyWordSendAdmin) //触发后提醒主人是否开启
            {
                string sendMsg = keyWordSendAdminFun(conf_index);
                sendAdminMsg(sendMsg);
            }
        });

        if (conf.async) {
            thread th_relayGroupList(relayGroupList);
            thread th_keyWordGroupWarn(keyWordGroupWarn);
            thread th_keyWordPrivateWarn(keyWordPrivateWarn);
            th_relayGroupList.join();
            th_keyWordGroupWarn.join();
            th_keyWordPrivateWarn.join();

            keyWordSendAdmin();
        } else {
            relayGroupList();
            keyWordGroupWarn();
            keyWordPrivateWarn();
            keyWordSendAdmin();
        }
    }

    //删除cq码
    std::wstring DelCQ(std::wstring msg) {
        if (msg.find(L"[CQ:") != wstring::npos) {
            boost::wregex e1(L"\\[CQ:.*\\]");
            msg = boost::regex_replace(msg, e1, L"");
        }

        return msg;
    }

    //删除cq码
    std::string DelCQ(std::string msg) {
        if (msg.find("[CQ:") != string::npos) {
            boost::regex e1("\\[CQ:.*\\]");
            msg = boost::regex_replace(msg, e1, "");
        }

        return msg;
    }

    //基本变量
    void variableBasic(std::string& str, int conf_index) {
        //触发的关键词
        MyUtils::replace_all_distinct(str, "{msg}", m_msg);

        //触发的关键词
        MyUtils::replace_all_distinct(str, "{关键词}", keyWord);

        //触发的QQ号码
        MyUtils::replace_all_distinct(str, "{QQ号码}", to_string(m_fromQQ));

        //触发的群号码
        MyUtils::replace_all_distinct(str, "{群号码}", to_string(m_fromGroup));

        //处理方式
        MyUtils::replace_all_distinct(str, "{处理方式}", dealTypeStr);

        //消息内容

        //系统时间
        if (str.find("{日期}") != str.npos || str.find("{时间}") != str.npos || str.find("{星期}") != str.npos) {
            //获取当前时间
            SYSTEMTIME sys;
            GetLocalTime(&sys);

            char date[20];
            char time[20];
            char Week[20];
            char weekStr[8][4] = {"天", "一", "二", "三", "四", "五", "六"};

            sprintf(date, u8"%4d年%02d月%02d日", sys.wYear, sys.wMonth, sys.wDay);
            sprintf(time, u8"%02d:%02d:%02d", sys.wHour, sys.wMinute, sys.wSecond);
            sprintf(Week, u8"星期%s", weekStr[sys.wDayOfWeek]);

            //日期
            MyUtils::replace_all_distinct(str, "{日期}", date);

            //时间
            MyUtils::replace_all_distinct(str, "{时间}", time);

            //星期
            MyUtils::replace_all_distinct(str, "{星期}", Week);
        }

        // QQ资料
        if (str.find("{QQ名称}") != str.npos || str.find("{QQ名片}") != str.npos) {
            auto QQInf = mycq::get_group_member_info(m_fromGroup, m_fromQQ, true);

            string name;
            string card;
            if (evet.is_anonymous()) {
                name = "匿名（" + evet.anonymous.name + "）";
                card = name;
            } else {
                name = QQInf.nickname;
                card = QQInf.card;
            }

            //触发的QQ名称
            MyUtils::replace_all_distinct(str, "{QQ名称}", name);
            //触发的QQ名片
            MyUtils::replace_all_distinct(str, "{QQ名片}", card);
        }

        //群资料
        if (str.find("{群名称}") != str.npos) {
            auto groupInf = mycq::get_group_info(m_fromGroup);

            //触发的群名称
            MyUtils::replace_all_distinct(str, "{群名称}", groupInf.group_name);
        }
    }

    //转发到群格式
    void variableRelayGroup(std::string& str, int conf_index) {
        //默认内容为msg
        if (str.empty()) {
            str = "{msg}";
        }

        //消息内容
        if (str.find("{msg}") != string::npos) {
            string temp_msg(m_msg);
            int frontLine = 0;
            int afterLine = temp_msg.size();

            int i = 0;

            //调整消息内容--删除前行数
            if (conf.alone[conf_index].relayGroupMsg_trimFront) {
                for (auto it = temp_msg.begin(); it != temp_msg.end(); it++) {
                    frontLine++;
                    if (*it == '\n') {
                        i++;
                        if (i == conf.alone[conf_index].relayGroupMsg_trimFront) break;
                    }
                }
            }

            //调整消息内容--删除后行数
            if (conf.alone[conf_index].relayGroupMsg_trimBack) {
                i = 0;
                for (auto it = temp_msg.rbegin(); it != temp_msg.rend(); it++) {
                    afterLine--;
                    if (*it == '\n') {
                        i++;
                        if (i == conf.alone[conf_index].relayGroupMsg_trimBack) break;
                    }
                }
            }

            temp_msg[afterLine] = 0;
            temp_msg = temp_msg.c_str() + frontLine;

            //检测消息修剪后内容为空
            if (temp_msg.empty()) {
                ostringstream sendMsg;
                sendMsg << "转发到群错误" << endl;
                sendMsg << "原因：消息修剪后内容为空" << endl;
                sendMsg << "消息内容：" << endl << endl;
                sendMsg << m_msg << endl << endl;
                sendMsg << "删除前面行数：" << conf.alone[conf_index].relayGroupMsg_trimFront << "行" << endl;
                sendMsg << "删除后面行数：" << conf.alone[conf_index].relayGroupMsg_trimBack << "行" << endl;
                sendMsg << "请查看转发到群中消息修剪是否有误";

                sendAdminMsg(sendMsg.str());
                str = "";

                return;
            }

            MyUtils::replace_all_distinct(str, "{msg}", temp_msg);
        }

        variableBasic(str, conf_index);
    }

    //自定义触发关键词提醒 变量
    void variableKeyWordWarn(std::string& str, int conf_index) {
        //艾特
        MyUtils::replace_all_distinct(str, "{at}", "[CQ:at,qq=" + std::to_string(m_fromQQ) + "]");

        variableBasic(str, conf_index);
    }

    //白名单关键词检测
    bool KeyWordWhiteFun(int conf_index) {
        if (conf.alone[conf_index].keyWordWhite.empty()) return false;

        wstring wmsg;
        if (conf.alone[conf_index].deleteCQCode) {
            wmsg = m_wmsg_delCQ;
        } else {
            wmsg = m_wmsg;
        }

        //查找关键词 如果存在某一个 则返回true
        for (WKEYWORD KeyWord_one : conf.alone[conf_index].keyWordWhite) {
            if (wmsg.find(KeyWord_one.wkeyWrod) != std::wstring::npos) {
                return true;
            }
        }

        return false;
    }

    //关键词对比  KeyWord关键词容器 Streng强力检测 KeyWordWarn返回触发的关键词
    bool KeyWordFun(int conf_index) {
        //判断关键词是否为空
        if (conf.alone[conf_index].keyWord.empty()) {
            return false;
        }

        wstring wmsg;
        if (conf.alone[conf_index].deleteCQCode) {
            wmsg = m_wmsg_delCQ;
        } else {
            wmsg = m_wmsg;
        }

        //普通关键词检测
        for (auto KeyWord_one : conf.alone[conf_index].keyWord) {
            if (wmsg.find(KeyWord_one.wkeyWrod) != std::wstring::npos) {
                //记录触发的关键词
                keyWord = KeyWord_one.keyWord;

                return true;
            }
        }

        //强力检测
        if (conf.alone[conf_index].streng) {
            for (auto KeyWord_one : conf.alone[conf_index].keyWord) {
                //记录关键词字数与匹配数
                int temp_num = KeyWord_one.wkeyWrod.size(), temp_num_find = 0;

                //判断消息和关键词是否为空
                if (KeyWord_one.wkeyWrod.empty() || m_wmsg.empty()) {
                    return false;
                }

                //开始强力检测   逐个字对比
                for (auto keyc : KeyWord_one.wkeyWrod) {
                    for (auto msgc : wmsg) {
                        if (keyc == msgc) {
                            temp_num_find++;
                            break;
                        }
                    }
                }

                //触发强力检测后
                if (temp_num_find >= temp_num) {
                    //记录触发的关键词
                    keyWord = KeyWord_one.keyWord;

                    return true;
                }
            }
        }

        //云端关键词检测
        for (auto& api : conf.alone[conf_index].moderationApi) {
            string inf;
            string delcq_msg = DelCQ(m_msg);
            int res = api->text(delcq_msg, inf);
            if (res == 1) {
                cq::logging::info(u8"关键词触发器-云端检测", inf);
                keyWord = "云端检测（";
                keyWord += inf;
                keyWord += "）";

                return true;
            } else if (res == -1) {
                cq::logging::error(u8"关键词触发器-云端检测错误", inf);
            }
        }

        return false;
    }

    //正则表达式关键词检测
    bool KeyKordRegexFun(int conf_index) {
        wstring wmsg;
        if (conf.alone[conf_index].deleteCQCode) {
            wmsg = m_wmsg_delCQ;
        } else {
            wmsg = m_wmsg;
        }

        for (WKEYWORD aloneRegex : conf.alone[conf_index].keyWordRegex) {
            try {
                boost::wregex re(aloneRegex.wkeyWrod);
                boost::wsmatch RE;

                bool rec = boost::regex_search(wmsg, RE, re);

                if (rec) {
                    keyWord = MyUtils::wstring2string(RE.str());
                    keyWordRegex = aloneRegex.keyWord;
                    return true;
                }

            } catch (exception& e) {
                ostringstream sendMsg;
                sendMsg << "正则表达式崩溃" << endl;
                sendMsg << "表达式:";
                sendMsg << aloneRegex.keyWord << endl;
                sendMsg << "崩溃消息:" << endl << endl;
                sendMsg << m_msg << endl << endl;
                sendMsg << "返回的错误消息:" << endl;
                sendMsg << e.what();

                sendAdminMsg(sendMsg.str());
            }
        }
        return false;
    }

    //内容处理功能  触发true  未触发false
    bool indexFun(int conf_index) {
        //查找是否为默认监控群
        auto list_bool =
            find(conf.alone[conf_index].groupList.begin(), conf.alone[conf_index].groupList.end(), m_fromGroup);

        //如果找到看 为默认监控群
        if (list_bool == conf.alone[conf_index].groupList.end()) return false;

        //如果为检测白名单模式
        if (conf.alone[conf_index].QQListType == 0) {
            //检测是否为白名单 如果为白名单将退出函数
            if (find(conf.alone[conf_index].QQList.begin(), conf.alone[conf_index].QQList.end(), m_fromQQ)
                != conf.alone[conf_index].QQList.end()) {
                return false;
            }
        }
        //如果为检测监控名单模式
        else if (conf.alone[conf_index].QQListType == 1) {
            //如果在监控名单没找到此号码 则退出函数
            if (find(conf.alone[conf_index].QQList.begin(), conf.alone[conf_index].QQList.end(), m_fromQQ)
                == conf.alone[conf_index].QQList.end()) {
                return false;
            }
        }

        //如果关键词为白名单 将退出函数
        if (KeyWordWhiteFun(conf_index)) {
            return false;
        }

        //如果触发了关键词
        if (KeyWordFun(conf_index)) {
            KeyWrodEvent(conf_index);
            return true;
        }

        //如果触发了正则表达式关键词
        if (KeyKordRegexFun(conf_index)) {
            KeyWrodEvent(conf_index);
            return true;
        }

        return false;
    }

    //内容处理
    void MsgFun() {
        // m_time.restart();
        m_startTime = clock(); //开始检测的时间
        for (auto temp : conf.alone) {
            //全局设置最后检测
            if (temp.first == 0) continue;

            if (temp.second.use) {
                bool ret = indexFun(temp.first);

                if (ret) return;
            }
        }

        indexFun(0);
    }

    //获取耗时
    double timerElapsed() {
        return static_cast<double>(clock() - m_startTime) / CLOCKS_PER_SEC;
    }

    GroupKeyWord(cq::GroupMessageEvent evet) : evet(evet) {
        m_fromQQ = evet.user_id;
        m_fromGroup = evet.group_id;
        m_fromAnonymous = evet.anonymous;
        m_msg = evet.message;
        m_msgId = evet.message_id;

        //将消息的宽字符串格式存放到对象中
        m_wmsg = MyUtils::string2wstring(evet.message);

        m_wmsg_delCQ = DelCQ(m_wmsg);
    }

private:
    int64_t m_fromQQ; //来自的QQ号码
    int64_t m_fromGroup; //来自的群号

    cq::Anonymous m_fromAnonymous; //来源的匿名信息
    string m_msg; //消息内容
    int64_t m_msgId; //消息id
    clock_t m_startTime; //计算程序流失的时间
    // timer m_time; //计算程序流失的时间

    wstring m_wmsg; //宽字节消息内容
    wstring m_wmsg_delCQ; //删除CQ码
    cq::GroupMessageEvent evet;

    //触发后内容
    string dealTypeStr; //处理方式
    string keyWord; //普通关键词
    string keyWordRegex; //正则表达式关键词
};

max_stars_repo_name: zhaoguoqingit/KeyWord

max_issues_repo_name: constStar/coolq-keyword

max_forks_repo_name: constStar/coolq-keyword


text:
/*
** EPITECH PROJECT, 2019
** CPP_babel_2019
** File description:
** Server
*/

/// \file UdpNetwork.hpp
/// \author Mattéo V.
/// \brief Header file for UdpNetwork class

#ifndef UdpNetwork_HPP_
    #define UdpNetwork_HPP_

#include <iostream>
#include <array>
#include <functional>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <optional>

#include "macro.hpp"
#include "Rfc.hpp"

using boost::asio::ip::udp;

/// \namespace Server
/// \brief Used for the all server classes
namespace Server
{
    /// \class UdpNetwork
    /// \brief UdpNetwork class, receive all udp connection
    class UdpNetwork    {

        public:
            /// \param io : io_context used by every I/O object of boost
            /// \param callBack : callBack function
            /// \brief Constructor
            /// Initialize socket and wait for a new connection
            UdpNetwork(boost::asio::io_context &io, std::function<void(Server::UdpNetwork *)>callBack);

            /// \brief Destructor
            /// Do nothing special
            ~UdpNetwork();

            /// \brief return port of socket
            int port() const { return _socket.local_endpoint().port(); };
            /// \brief return port of the sender socket
            int remotePort() const { return _endpoint.port(); };
            /// \brief return ip of the sender socket
            std::string remoteIp() const { return _endpoint.address().to_string(); };
            // std::optional<std::string> remoteIp() const { return _remoteIp ? _remoteIp : {}; };

            /// \brief get the buffer content
            std::array<char, BUFFER_SIZE> buffer() const { return _buf; };

            /// \brief write packet to client
            /// \param ip : ip of the destination
            /// \param data : any other data to be send
            /// \param size : size of total data
            void write(const std::string &ip, const void *data, const std::size_t size);

        private:
            /// \brief Wait for connection and setup a callback for received message
            /// called again by handleRead to accept new packet
            void startAccept();

            /// \brief handle any received packet
            /// \param size : size of the packet received
            void handleRead(const std::size_t);

            /// \brief callback for any sent packet
            /// \param size : size of the packet sent
            void handleWrite(const std::size_t);

            std::string _remoteIp;

            /*! Socket used to receive data from udp */
            udp::socket _socket;
            /*! Connection endpoint */
            udp::endpoint _endpoint;
            /*! Buffer containing data got from remote client */
            std::array<char, BUFFER_SIZE> _buf;
            /*! callBack function */
            std::function<void(Server::UdpNetwork *)> _callBack;
    };
}

#endif /* !UdpNetwork_HPP_ */

max_stars_repo_name: ltabis/epitech-projects

max_issues_repo_name: ltabis/epitech-projects

max_forks_repo_name: ltabis/epitech-projects