text:
//#include <boost/regex.hpp>

#include <pcre.h>
#include <vector>
#include <fstream>
#include <gtest/gtest.h>
#include "../include/regxstring.h"

using namespace std;

static pcre *pcre_compile_DZ(const string &regx)
{
    const char *error;
    int erroffset;
    pcre *re = pcre_compile(
        regx.c_str(),
        0,
        &error,
        &erroffset,
        0);
    if (!re)
        cerr << "error at offset " << erroffset << ": " << error << "\n\n";
    return re;
}

static bool pcre_exec_DZ(const string &str, pcre *re)
{
    const int size = 120;
    vector<int> ovector(size);
    pcre_extra extra;
    extra.flags = PCRE_EXTRA_MATCH_LIMIT;
    extra.match_limit = 200000000;
    int rc = pcre_exec(
        re,              /* the compiled pattern */
        &extra,          /* no extra data - we didn't study the pattern */
        str.c_str(),     /* the subject string */
        (int)str.size(), /* the length of the subject */
        0,               /* start at offset 0 in the subject */
        0,               /* default options */
        &ovector[0],     /* output vector for substring information */
        size);           /* number of elements in the output vector */
    if (rc < 0)
    {
        switch (rc)
        {
        case PCRE_ERROR_NOMATCH:
            break;
            // Handle other special cases if you like
        default:
            cerr << "Matching error " << rc << " :\n";
            break;
        }
        return false;
    }
    return true;
}

static string Trim(string str){
    size_t i = 0,e = str.length();
    for(;i < e && isspace(str[i]);++i);
    size_t j = e;
    for(;j > i && isspace(str[j - 1]);--j);
    return (i < j ? str.substr(i,j - i) : "");
}

static string pre_handle(const string & str)
{
    string ret = Trim(str);
    if(!ret.empty()){
        if(ret[0] != '^')
            ret.insert(ret.begin(),'^');
        if(ret[ret.size() - 1] != '$')
            ret.push_back('$');
    }
    return ret;
}

namespace {
    TEST(CRegxStringTest, parseRegex_can_generate_string_from_regex) {
        const int TOTAL_NUMBER_OR_RAND_STRINGS = 10;
        ifstream testInput;
        CRegxString regxstr;
        string regx;

        testInput.open("resource/test_input.txt");
        EXPECT_TRUE(testInput.is_open());

        while (getline(testInput, regx))
        {
            regx = pre_handle(regx);
            pcre *re = pcre_compile_DZ(regx);
            EXPECT_TRUE(re);

            regxstr.ParseRegx(regx.c_str());

            for (int i = 0; i < TOTAL_NUMBER_OR_RAND_STRINGS; ++i) {
                regxstr.RandString();
                const string &str = regxstr.LastString();
                EXPECT_TRUE(pcre_exec_DZ(str, re));
            }

            pcre_free(re);
        }

        testInput.close();
        EXPECT_FALSE(testInput.is_open());
    }
}

max_stars_repo_name: tonylulciuc/regxstring

max_issues_repo_name: tonylulciuc/regxstring

max_forks_repo_name: tonylulciuc/regxstring


text:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#include "common.hh"
#include <arpa/inet.h>
#include <boost/chrono.hpp>
#include <boost/optional.hpp>
#include <cassert>
#include <cstring>
#include <dmtr/annot.h>
#include <dmtr/latency.h>
#include <dmtr/libos.h>
#include <dmtr/wait.h>
#include <iostream>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dmtr/libos/mem.h>
#include <netinet/in.h>
#include <signal.h>
#include <unistd.h>
#include <unordered_map>

static bool exit_signal = false;

int lqd = 0;
int fqd = 0;
dmtr_latency_t *latency = NULL;

void sig_handler(int signo)
{
    fprintf(stderr, "Received signal %d\n", signo);
    exit_signal = true;
}

void pin_thread(pthread_t thread, u_int16_t cpu) {
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(cpu, &cpuset);

    int rtn = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
    if (rtn != 0) {
        fprintf(stderr, "could not pin thread: %s\n", strerror(errno));
    }
}

int worker_iteration(int in_queue, int out_queue, dmtr_qtoken_t &token, boost::chrono::steady_clock::time_point &t) {

    DMTR_OK(dmtr_pop(&token, in_queue));
    dmtr_qresult_t wait_out;
    volatile int status;
    t = boost::chrono::steady_clock::now();
    while ( (status = dmtr_wait(&wait_out, token)) == EAGAIN && !exit_signal) {
    t = boost::chrono::steady_clock::now();
    }
    if (status != 0) {
        exit_signal = true;
        fprintf(stderr, "dmtr_wait returned %d\n", status);
        return status;
    } else {
        DMTR_OK(dmtr_push(&token, out_queue, &wait_out.qr_value.sga));
        DMTR_OK(dmtr_wait(&wait_out, token));
        return 0;
    }
}

int worker_loop(uint16_t cpu_id, int in_queue, int out_queue) {
    pin_thread(pthread_self(), cpu_id);

    dmtr_qtoken_t token;
    while (!exit_signal) {
        boost::chrono::steady_clock::time_point t0;
        DMTR_OK(worker_iteration(in_queue, out_queue, token, t0));
    }
    return 0;
}

int main_worker_loop(uint16_t cpu_id, int client_queue, int in_queue, int out_queue) {
    pin_thread(pthread_self(), cpu_id);
    DMTR_OK(dmtr_new_latency(&latency, "main"));

    dmtr_qtoken_t token;
    while (!exit_signal) {
        boost::chrono::steady_clock::time_point t0;
        DMTR_OK(worker_iteration(client_queue, out_queue, token, t0));
        boost::chrono::steady_clock::time_point t1;
        DMTR_OK(worker_iteration(in_queue, client_queue, token, t1));
        t1 = boost::chrono::steady_clock::now();
        dmtr_record_latency(latency, (t1 - t0).count());
    }
    return 0;
}

struct worker_args {
    int cpu_id;
    int in_qd;
    int out_qd;
    int client_qd;
};

void* worker_entry(void *vargs) {
    struct worker_args *args = (struct worker_args *)vargs;
    worker_loop(args->cpu_id, args->in_qd,  args->out_qd);
    return NULL;
}

void *main_worker_entry(void *vargs) {
    struct worker_args *args = (struct worker_args *)vargs;
    main_worker_loop(args->cpu_id, args->client_qd, args->in_qd, args->out_qd);
    printf("Dumping\n");
    dmtr_dump_latency(stderr, latency);
    printf("Dumped\n");
    return NULL;
}

int main_work(int lqd, int n_threads) {
    int memory_qds[n_threads];
    for (int i=0; i < n_threads; i++) {
        DMTR_OK(dmtr_queue(&memory_qds[i]));
    }

    dmtr_qtoken_t token;
    DMTR_OK(dmtr_accept(&token, lqd));

    dmtr_qresult_t wait_out;
    int status;
    while ( (status = dmtr_wait(&wait_out, token)) == EAGAIN && !exit_signal) {}
    if (status != 0) {
        DMTR_OK(status /*dmtr_wait*/);
        return -1;
    } else {
        printf("Accepted connection!\n");
        int client_qd = wait_out.qr_value.ares.qd;

        pthread_t pthreads[n_threads];
        struct worker_args thread_args[n_threads];

        for (int i=0; i < n_threads; i++) {
            struct worker_args *args = &thread_args[i];
            args->cpu_id = 3 + i;
            args->client_qd = client_qd;
            args->in_qd = (i == 0) ? memory_qds[n_threads - 1] : memory_qds[i-1];
            args->out_qd = memory_qds[i];

            main_worker_entry(args);

            //if (pthread_create(&pthreads[i], NULL, (i == 0) ? main_worker_entry : worker_entry, args)) {
            //    perror("pthread_create");
            //    exit_signal = true;
            //}
        }

        //for (int i=0; i < n_threads; i++) {
        //    pthread_join(pthreads[i], NULL);
        //}
    }
    return 0;
}

int main(int argc, char *argv[])
{
    std::string ip;
    std::string log_out;
    uint16_t port;
    uint16_t n_threads;

    options_description desc{"Threaded echo server"};
    desc.add_options()
        ("help", "produce help message")
        ("ip", value<std::string>(&ip), "server ip address")
        ("port", value<uint16_t>(&port)->default_value(12345), "server port")
        ("threads", value<uint16_t>(&n_threads), "number of threads");
        //("out,O", value<std::string>(&log_out), "log directory");

    variables_map vm;
    try {
        parsed_options parsed =
            command_line_parser(argc, argv).options(desc).allow_unregistered().run();
        store(parsed, vm);
        if (vm.count("help")) {
            std::cout << desc << std::endl;
            exit(0);
        }
        notify(vm);
    } catch (const error &e) {
        std::cerr << e.what() << std::endl;
        std::cerr << desc << std::endl;
        exit(0);
    }
    parse_args(argc, argv, true);

    struct sockaddr_in saddr = {};
    saddr.sin_family = AF_INET;

    const char *s = ip.c_str();
    std::cerr << "Listening on `" << s << ":" << port << "`..." << std::endl;
    if (inet_pton(AF_INET, s, &saddr.sin_addr) != 1) {
        std::cerr << "Unable to parse IP address." << std::endl;
        return -1;
    }

    saddr.sin_port = htons(port);

    DMTR_OK(dmtr_init(argc, argv));

    int lqd;
    DMTR_OK(dmtr_socket(&lqd, AF_INET, SOCK_STREAM, 0));
    DMTR_OK(dmtr_bind(lqd, reinterpret_cast<struct sockaddr *>(&saddr), sizeof(saddr)));
    DMTR_OK(dmtr_listen(lqd, 3));

    if (signal(SIGINT, sig_handler) == SIG_ERR)
        std::cout << "\ncan't catch SIGINT\n";

    return main_work(lqd, n_threads);
}

ext: cc

max_stars_repo_name: isaac-ped/demikernel

max_issues_repo_name: isaac-ped/demikernel

max_forks_repo_name: isaac-ped/demikernel


text:
/*
 * Picard Serial Multiplexer - main project file
 *
 * Copyright (c) 2010, Dust Networks Inc.
 */

#include <assert.h>
#include <stdint.h>

#include <iostream>
#include <list>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

#include <boost/thread.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
#include <boost/date_time/posix_time/posix_time.hpp>

#include "BoostLog.h"

#include "BoostClient.h"
#include "PicardBoost.h"
#include "BoostClientManager.h"
#include "BoostClientListener.h"

#include "Version.h"
#include "SerialMuxOptions.h"
#include "serial_mux.h"

#ifdef WIN32
// nt_service class from http://www.codeproject.com/KB/system/nt_service.aspx
#include "NTService/nt_service.h"
#endif

using namespace DustSerialMux;

#ifdef USE_PICARD_CLR
SerialPort^ connectSerial(String^ port /* serial port */ )
{
   // Create a new SerialPort object with default settings.
   SerialPort^ sp = gcnew SerialPort();

   // Allow the user to set the appropriate properties.
   sp->PortName = port;
   sp->BaudRate = DEFAULT_BAUD_RATE;
   //sp->Parity
   //sp->DataBits
   //sp->StopBits
   sp->Handshake = Handshake::None;

   // Set the read/write timeouts
   sp->ReadTimeout = 500;
   sp->WriteTimeout = 500;

   sp->Open();

   sp->DtrEnable = 1; // set CTS
   sp->RtsEnable = 0; // unset RTS (until we're ready to send)
   return sp;
}
#endif

boost::asio::io_service io_service;

CBasePicardIO*        gPicardIO = NULL;
CBoostClientListener* gListener = NULL;
CBoostClientManager*  gClientMgr = NULL;

// signal to handle waiting for main loop completion from service/daemon stop() operation
boost::mutex gMuxLoopMutex;
boost::condition_variable gMuxLoopComplete;

void resetConnection()
{
   // stop the listener
   CBoostLog::log(LOG_ALWAYS, "picard connection reset");

   if (gPicardIO) {
      // close Picard read loop
      CBoostLog::log("stopping Picard read loop");
      gPicardIO->reset();
      gPicardIO->stop();
   }
   if (gClientMgr) {
      // close client connections
      CBoostLog::log("closing client connections");
      gClientMgr->closeClients();
   }
   if (gListener) {
      // stop the listener
      CBoostLog::log("stopping listener");
      gListener->stop();
   }

   io_service.stop();
}

bool muxRunning = true;
SerialMuxOptions opts;

// listen thread is to assure we get the protocol version from
// hello response before async listen get started
void listen_thread()
{
    uint8_t version;
    std::ostringstream msg;

    CBoostLog::log("listen_thread: waiting for Hello Response");
    bool picardReady = gPicardIO->waitForHello();
    version = gPicardIO->getVersion();
    msg << "listen_thread: got version " << std::dec << (int) version;
    CBoostLog::log(msg.str());
    gListener->set_protocolVersion(version);
    gListener->asyncListen();
}

// main loop for Serial Mux
void serial_mux_loop()
{
   // allow an external stop command
   while (muxRunning) {
      io_service.reset();

      // connect to Picard
#ifdef USE_PICARD_CLR
      SerialPort^ sp = nullptr;
      UdpClient^ picardSim = nullptr;

      try {
         if (opts.useSerial) {
            String^ serialDevice = gcnew String(opts.serialPort.c_str());
            sp = connectSerial(serialDevice);
            std::ostringstream msg;
            msg << "Connected to serial port " << opts.serialPort;
            CBoostLog::log(LOG_ALWAYS, msg.str());
            gPicardIO = new CPicardCLR_Serial(sp, opts.rtsDelay, opts.useFlowControl, opts.readTimeout);
         } else {
            picardSim = gcnew UdpClient();
            picardSim->Connect("127.0.0.1", opts.emulatorPort);
            gPicardIO = new CPicardCLR_UDP(picardSim, opts.readTimeout);
         }
      }
      catch (Exception^) {
         CBoostLog::log("error: can not open a connection to Picard, retrying");
         boost::this_thread::sleep(boost::posix_time::seconds(1));
         continue;
      }
#else
      try {
         if (opts.useSerial) {
            gPicardIO = new CPicardBoost_Serial(io_service, opts.serialPort,
                                                opts.rtsDelay, opts.useFlowControl, opts.readTimeout);
            std::ostringstream msg;
            msg << "Connected to serial port " << opts.serialPort;
            CBoostLog::log(LOG_ALWAYS, msg.str());
         }
         else {
            gPicardIO = new CPicardBoost_UDP(io_service, opts.emulatorPort, opts.readTimeout);
         }
      }
      catch (const std::exception& ex) {
         std::ostringstream msg;
         msg << "error: can not open a connection to Picard, retrying" << ex.what();
         CBoostLog::log(msg.str());
         boost::this_thread::sleep(boost::posix_time::seconds(1));
         continue;
      }
#endif

      // create the client manager
      gClientMgr = new CBoostClientManager(opts.picardRetries, opts.picardTimeout);
      gPicardIO->registerCallback(gClientMgr);

      // start output
      gPicardIO->start();
      boost::thread picardThread(&CBasePicardIO::threadMain, gPicardIO);
#ifdef WIN32
      SetThreadPriority(picardThread.native_handle(), THREAD_PRIORITY_HIGHEST);
#endif

      // start command processing thread
      boost::thread clientThread(&CBoostClientManager::commandLoop,
                                 gClientMgr, gPicardIO);

      // start listening
      gListener = new CBoostClientListener(io_service, opts.listenerPort, !opts.acceptAnyhost,
                                           *gClientMgr, opts.authToken, 0);
      boost::thread listenThread(listen_thread);

      boost::asio::io_service::work work(io_service);

      io_service.run();

      CBoostLog::log("stopping components");

      io_service.reset();

      // close command processing thread
      gPicardIO->registerCallback(NULL); // disable callbacks from Picard output
      gClientMgr->stop();
      clientThread.join();
      listenThread.join();

      // shutdown output
      gPicardIO->stop();
      picardThread.join();

      CBoostLog::log("deleting components");

      delete gClientMgr;
      gClientMgr = NULL;

      delete gListener;
      gListener = NULL;

      delete gPicardIO;
      gPicardIO = NULL;

#ifdef USE_PICARD_CLR
      // close connection to Picard
      CBoostLog::log("closing Picard connection");
      if (opts.useSerial) {
         sp->Close();
      } else {
         picardSim->Close();
      }
#endif
   }

   gMuxLoopComplete.notify_one();
}

#ifdef WIN32
// start the mux main loop when run as service
void WINAPI serial_mux_start(DWORD argc_, char_* argv_[])
{
   // start the mux main loop
   serial_mux_loop();
}
#endif

// stop the mux main loop when run as daemon/service
void serial_mux_stop()
{
   try {
      muxRunning = false;
      resetConnection();
   }
   catch (std::exception& ex) {
      CBoostLog::log("serial_mux_stop: exception");
      CBoostLog::log(ex.what());
   }

   // wait for the mux loop to complete before returning
   boost::unique_lock<boost::mutex> guard(gMuxLoopMutex);
   gMuxLoopComplete.wait(guard);
}

int main(int argc, char* argv[])
{
   // parse command line
   int result = 0;
   try {
      result = parseConfiguration(opts, argc, argv, std::cout);
   }
   catch (const std::exception& ex) {
      std::cerr << "error: " << ex.what() << std::endl;
      return 1;
   }
   // handle special options like --help and --version where we should exit immediately
   if (result != 0) {
      return 0;
   }

   // use the log as a lock file to indicate another serial mux is running here
   try {
      CBoostLog::getInstance().openLog(opts.logFile, opts.numLogBackups, opts.maxLogSize, opts.logLevel);
      // Print the header
      CBoostLog::log(LOG_ALWAYS, "*** Starting Serial API Multiplexer ***");
   }
   catch (const std::exception&) {
      cerr << "error: can not open log file, another Serial Mux must be running" << endl;
      return 1;
   }

   cout << getVersionString() << endl;
   CBoostLog::log(LOG_ALWAYS, getVersionString());

   if (opts.runAsDaemon) {
#ifdef WIN32
      win::nt_service& nts = win::nt_service::instance(opts.serviceName.c_str());

      // register the service main loop
      nts.register_service_main( serial_mux_start );
      // configure the service to accept stop controls
      nts.register_control_handler( SERVICE_CONTROL_STOP, serial_mux_stop );
      // configure the service to accept shutdown controls
      nts.register_control_handler( SERVICE_CONTROL_SHUTDOWN, serial_mux_stop );

      nts.start();
#else
      cerr << "Running as daemon not implemented" << endl;
      result = 1;
#endif
   } else {
      // go directly to the main loop
      serial_mux_loop();
   }

   CBoostLog::log(LOG_ALWAYS, "serial_mux shutting down");

   return result;
}

ext: cpp

max_stars_repo_name: dustcloud/serialmux

max_issues_repo_name: dustcloud/serialmux

max_forks_repo_name: dustcloud/serialmux


text: #include <boost/fusion/include/adapter.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


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


text:
/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include <tbb/mutex.h>
#include "base/util.h"
#include <boost/date_time/posix_time/posix_time.hpp>
#include "db/db_entry.h"
#include "db/db_table_partition.h"

using namespace std;

void DBEntryBase::SetState(DBTableBase *tbl_base, ListenerId listener,
                           DBState *state) {
    DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
    tbb::mutex::scoped_lock lock(tpart->dbstate_mutex());
    pair<StateMap::iterator, bool> res = state_.insert(
        make_pair(listener, state));
    if (!res.second) {
        res.first->second = state;
    } else {
        assert(!IsDeleted());
    }
}

DBState *DBEntryBase::GetState(DBTableBase *tbl_base, ListenerId listener) {
    DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
    tbb::mutex::scoped_lock lock(tpart->dbstate_mutex());
    StateMap::iterator loc = state_.find(listener);
    if (loc != state_.end()) {
        return loc->second;
    }
    return NULL;
}

const DBState *DBEntryBase::GetState(const DBTableBase *tbl_base,
                                     ListenerId listener) const {
    DBTableBase *table = const_cast<DBTableBase *>(tbl_base);
    DBTablePartBase *tpart = table->GetTablePartition(this);
    tbb::mutex::scoped_lock lock(tpart->dbstate_mutex());
    StateMap::const_iterator loc = state_.find(listener);
    if (loc != state_.end()) {
        return loc->second;
    }
    return NULL;
}

//
// Concurrency: called from arbitrary task.
//
// Evaluate concurrency issues with DBTablePartBase::RunNotify when making
// changes to this method.  We expect that either this method or RunNotify
// is responsible for removing the DBEntryBase when they run concurrently,
// assuming the DBEntryBase is eligible for removal.  The dbstate_mutex in
// in DBTablePartBase is used for synchronization.
//
// Remove DBState on this DBEntryBase for the given listener and enqueue
// for removal if appropriate.
// Note that the entry cannot be removed from DBTablePartBase here since
// this method may be called from an arbitrary Task.
//
void DBEntryBase::ClearState(DBTableBase *tbl_base, ListenerId listener) {
    DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
    tbb::mutex::scoped_lock lock(tpart->dbstate_mutex());
    state_.erase(listener);
    if (state_.empty() && IsDeleted() && !is_onlist()) {
        assert(!IsOnRemoveQ());
        tbl_base->EnqueueRemove(this);
    }
}

bool DBEntryBase::is_state_empty(DBTablePartBase *tpart) {
    tbb::mutex::scoped_lock lock(tpart->dbstate_mutex());
    return state_.empty();
}

void DBEntryBase::set_last_change_at_to_now() {
    last_change_at_ = UTCTimestampUsec();
}

void DBEntryBase::set_last_change_at(uint64_t time) {
    last_change_at_ = time;
}

void DBEntryBase::set_table_partition(DBTablePartBase *tpart) {
    tpart_ = tpart;
}

DBTablePartBase *DBEntryBase::get_table_partition() const {
    return tpart_;
}

DBTableBase *DBEntryBase::get_table() const {
    return (tpart_ ? tpart_->parent() : NULL);
}

const std::string DBEntryBase::last_change_at_str() const {
    return duration_usecs_to_string(UTCTimestampUsec() - last_change_at_);
}

max_stars_repo_name: Juniper/contrail-dev-controller

max_issues_repo_name: Juniper/contrail-dev-controller

max_forks_repo_name: Juniper/contrail-dev-controller


text:
///
/// @file   t_QueryParser.cpp
/// @author Dohyun Yun
/// @date   2010-06-23
///

#include "test_def.h"

#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
#include <query-manager/QueryParser.h>
#include <common/SFLogger.h>

using namespace std;
using namespace sf1r;
using namespace boost::unit_test;
namespace bfs = boost::filesystem;
using izenelib::ir::idmanager::IDManager;

namespace
{
const string TEST_DIR_STR = "t_QueryParser_dir";
}

struct QueryParserTestFixture
{
    std::vector<AnalysisInfo> analysisInfoList;
    boost::shared_ptr<LAManager> laManager;
    boost::shared_ptr<IDManager> idManager;

    QueryParserTestFixture()
        : laManager(new LAManager)
    {
        LAManagerConfig config;
        initConfig( analysisInfoList, config );

        bfs::create_directories(TEST_DIR_STR);
        idManager.reset(new IDManager(TEST_DIR_STR + "/idm_qmt"));
        LAPool::getInstance()->initLangAnalyzer();
        LAPool::getInstance()->init(config);
        QueryParser::initOnlyOnce();

        // Build restrict term dictionary
        std::string restrictDicPath(TEST_DIR_STR + "/restrict.txt");
        ofstream fpout(restrictDicPath.c_str());
        BOOST_CHECK( fpout.is_open() );
        fpout << "news" << endl;
        fpout << "korean news" << endl;
        fpout.close();
        QueryUtility::buildRestrictTermDictionary(restrictDicPath, idManager);

    } // end - initOnlyOnce

    ~QueryParserTestFixture()
    {
        idManager->close();
        bfs::remove_all(TEST_DIR_STR);
    }
};

void keywordTreeCheck(const QueryTreePtr& queryTree, const std::string& queryStr)
{
    izenelib::util::UString queryUStr(queryStr, izenelib::util::UString::UTF_8);
    BOOST_CHECK_EQUAL( QueryTree::KEYWORD , queryTree->type_ );
    BOOST_CHECK_EQUAL( queryStr , queryTree->keyword_ );
    BOOST_CHECK_NE( 0U , queryTree->keywordId_ );
    BOOST_CHECK( queryUStr == queryTree->keywordUString_ );
    BOOST_CHECK_EQUAL( 0U , queryTree->children_.size() );
} // end - keywordTreeCheck

BOOST_FIXTURE_TEST_SUITE(QueryParser_test, QueryParserTestFixture)

BOOST_AUTO_TEST_CASE(QueryParser_testcases)
{
//BOOST_AUTO_TEST_CASE(normalizeQuery_test)
{

#define USTRING(str) UString(str, UString::UTF_8)

    using izenelib::util::UString;
    std::vector<UString> queryStringList, normResultList;

    queryStringList.push_back(USTRING("   test"));
    queryStringList.push_back(USTRING("(  hello  |   world  )"));
    queryStringList.push_back(USTRING("{  test  case } ^ 12(month case)"));
    queryStringList.push_back(USTRING("(bracket close)(open space)"));
    normResultList.push_back(USTRING("test"));
    normResultList.push_back(USTRING("(hello|world)"));
    normResultList.push_back(USTRING("{test case}^12&(month&case)"));
    normResultList.push_back(USTRING("(bracket&close)&(open&space)"));

    UString out;
    QueryParser queryParser(laManager, idManager);

    for(size_t i = 0; i < queryStringList.size(); i++)
    {
        queryParser.normalizeQuery( queryStringList[i], out, true );
        BOOST_CHECK_EQUAL( out , normResultList[i] );
    }

    UString queryString = USTRING("{  test  \"case  \"  * no?unigram } ^ 12(month \" case\" *no?unigram");
    UString normResults[2] = {USTRING("{test \"case \" * no?unigram}^12&(month&\" case\"&*no?unigram)"), USTRING("{test \"case \" * no?unigram}^12&(month&case&no&unigram)")};

    queryParser.normalizeQuery( queryString, out, true );
    BOOST_CHECK_EQUAL( out , normResults[0] );

    queryParser.normalizeQuery( queryString, out, false );
    BOOST_CHECK_EQUAL( out , normResults[1] );
}

//BOOST_AUTO_TEST_CASE(parseQuery_basic_test)
{
    std::string queryStr;
    izenelib::util::UString queryUStr;
    QueryTreePtr queryTree;
    QueryParser queryParser(laManager, idManager);

    { // KEYWORD type
        queryStr = " 본케나오게하지마라. ";
        std::string compStr = "본케나오게하지마라.";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, false, true) );
        keywordTreeCheck(queryTree, compStr);
    }
    { // WILDCARD type 1
        queryStr = "본케나오게*하지마라?";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, false, true) );
        BOOST_CHECK_EQUAL( QueryTree::TRIE_WILDCARD, queryTree->type_ );
        BOOST_CHECK_EQUAL( queryStr , queryTree->keyword_ );
        BOOST_CHECK_NE( 0U , queryTree->keywordId_ );
        BOOST_CHECK( queryUStr == queryTree->keywordUString_ );
        BOOST_CHECK_EQUAL( 0U , queryTree->children_.size() );
    }
    { // WILDCARD type 2
        queryStr = "본케나오게*하지마라?";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, true, true) );
        BOOST_CHECK_EQUAL( QueryTree::UNIGRAM_WILDCARD, queryTree->type_ );
        BOOST_CHECK_EQUAL( queryStr , queryTree->keyword_ );
        BOOST_CHECK( queryUStr == queryTree->keywordUString_ );
        BOOST_CHECK_NE( 0U , queryTree->keywordId_ );
        BOOST_CHECK_EQUAL( 11U , queryTree->children_.size() );
        std::list<QueryTreePtr>::const_iterator iter = queryTree->children_.begin();

        BOOST_CHECK_EQUAL( QueryTree::KEYWORD, (*iter)->type_ );
        BOOST_CHECK_EQUAL( "본" , (*iter)->keyword_ );
        BOOST_CHECK( izenelib::util::UString("본", izenelib::util::UString::UTF_8) ==(*iter)->keywordUString_ );
        BOOST_CHECK_NE( 0U, (*iter)->keywordId_ );

        iter++;iter++;iter++;iter++;iter++;
        BOOST_CHECK_EQUAL( QueryTree::ASTERISK, (*iter)->type_ );

        iter++;iter++;
        BOOST_CHECK_EQUAL( QueryTree::KEYWORD, (*iter)->type_ );
        BOOST_CHECK_EQUAL( "지" , (*iter)->keyword_ );
        BOOST_CHECK( izenelib::util::UString("지", izenelib::util::UString::UTF_8) == (*iter)->keywordUString_ );
        BOOST_CHECK_NE( 0U, (*iter)->keywordId_ );

        iter++;iter++;iter++;
        BOOST_CHECK_EQUAL( QueryTree::QUESTION_MARK, (*iter)->type_ );
    }
    { // AND type
        queryStr = "본케나오게 하지마라";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, true, true) );
        BOOST_CHECK_EQUAL( QueryTree::AND, queryTree->type_ );
        BOOST_CHECK_EQUAL( "", queryTree->keyword_ );
        BOOST_CHECK_EQUAL( 0U , queryTree->keywordId_ );
        BOOST_CHECK_EQUAL( 2U , queryTree->children_.size() );

        std::list<QueryTreePtr>::const_iterator iter = queryTree->children_.begin();
        QueryTreePtr child = *iter;
        keywordTreeCheck(child, "본케나오게");

        child = *(++iter);
        keywordTreeCheck(child, "하지마라");
    }
    { // AND type with chinese character
//      queryStr = "가나北京 天安门abc 123";
//      queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
//      BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, true, true) );
//      BOOST_CHECK_EQUAL( "", queryTree->keyword_ );
//      BOOST_CHECK_EQUAL( 0U , queryTree->keywordId_ );
//      BOOST_CHECK_EQUAL( 2U , queryTree->children_.size() );

//      std::list<QueryTreePtr>::const_iterator iter = queryTree->children_.begin();
//      QueryTreePtr child = *iter;
//      keywordTreeCheck(child, "가나北京天安门abc");

//      child = *(++iter);
//      keywordTreeCheck(child, "123");
    }
    { // OR type
        queryStr = "본케나오게|하지마라";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, true, true) );
        BOOST_CHECK_EQUAL( QueryTree::OR, queryTree->type_ );
        BOOST_CHECK_EQUAL( "", queryTree->keyword_ );
        BOOST_CHECK_EQUAL( 0U , queryTree->keywordId_ );
        BOOST_CHECK_EQUAL( 2U , queryTree->children_.size() );

        std::list<QueryTreePtr>::const_iterator iter = queryTree->children_.begin();
        QueryTreePtr child = *iter;
        keywordTreeCheck(child, "본케나오게");

        child = *(++iter);
        keywordTreeCheck(child, "하지마라");
    }
    { // NOT type
        queryStr = "!빙신";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, true, true) );
        BOOST_CHECK_EQUAL( QueryTree::NOT, queryTree->type_ );
        BOOST_CHECK_EQUAL( "", queryTree->keyword_ );
        BOOST_CHECK_EQUAL( 0U , queryTree->keywordId_ );
        BOOST_CHECK_EQUAL( 1U , queryTree->children_.size() );

        QueryTreePtr child = *(queryTree->children_.begin());
        keywordTreeCheck(child, "빙신");
    }
    { // EXACT type
        queryStr = "\"본케나오게 .하지마라\"";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, true, true) );
        BOOST_CHECK_EQUAL( QueryTree::EXACT, queryTree->type_ );
        BOOST_CHECK_EQUAL( "본케나오게 .하지마라", queryTree->keyword_ );
        BOOST_CHECK_NE( 0U , queryTree->keywordId_ );
        BOOST_CHECK_EQUAL( 10U , queryTree->children_.size() );

        QTIter iter = queryTree->children_.begin();
        keywordTreeCheck(*iter++, "본");
        keywordTreeCheck(*iter++, "케");
        keywordTreeCheck(*iter++, "나");
        keywordTreeCheck(*iter++, "오");
        keywordTreeCheck(*iter++, "게");
        keywordTreeCheck(*iter++, "<PH>");
        keywordTreeCheck(*iter++, "하");
        keywordTreeCheck(*iter++, "지");
        keywordTreeCheck(*iter++, "마");
        keywordTreeCheck(*iter++, "라");
    }
    { // ORDER type
        queryStr = "[본케나오게 하지마라]";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, true, true) );
        BOOST_CHECK_EQUAL( QueryTree::ORDER, queryTree->type_ );
        BOOST_CHECK_EQUAL( "본케나오게 하지마라" , queryTree->keyword_ );
        BOOST_CHECK_NE( 0U , queryTree->keywordId_ );
        BOOST_CHECK_EQUAL( 2U , queryTree->children_.size() );

        std::list<QueryTreePtr>::const_iterator iter = queryTree->children_.begin();
        QueryTreePtr child = *iter;
        keywordTreeCheck(child, "본케나오게");

        child = *(++iter);
        keywordTreeCheck(child, "하지마라");
    }
    { // NEARBY type
        queryStr = "{본케나오게 하지마라}^1982";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, true, true) );
        BOOST_CHECK_EQUAL( QueryTree::NEARBY, queryTree->type_ );
        BOOST_CHECK_EQUAL( "본케나오게 하지마라" , queryTree->keyword_ );
        BOOST_CHECK_NE( 0U , queryTree->keywordId_ );
        BOOST_CHECK_EQUAL( 2U , queryTree->children_.size() );

        std::list<QueryTreePtr>::const_iterator iter = queryTree->children_.begin();
        QueryTreePtr child = *iter;
        keywordTreeCheck(child, "본케나오게");

        child = *(++iter);
        keywordTreeCheck(child, "하지마라");

        BOOST_CHECK_EQUAL( 1982 , queryTree->distance_ );
    }
    { // NEARBY type 2
        queryStr = "{본케나오게 하지마라}";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, true, true) );
        BOOST_CHECK_EQUAL( QueryTree::NEARBY, queryTree->type_ );
        BOOST_CHECK_EQUAL( "본케나오게 하지마라" , queryTree->keyword_ );
        BOOST_CHECK_NE( 0U , queryTree->keywordId_ );
        BOOST_CHECK_EQUAL( 2U , queryTree->children_.size() );

        std::list<QueryTreePtr>::const_iterator iter = queryTree->children_.begin();
        QueryTreePtr child = *iter;
        keywordTreeCheck(child, "본케나오게");

        child = *(++iter);
        keywordTreeCheck(child, "하지마라");

        BOOST_CHECK_EQUAL( 20 , queryTree->distance_ ); // defaut value
    }
    {
        queryStr = "news";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( !queryParser.parseQuery(queryUStr, queryTree, true, true) );

        queryStr = "korean news";
        queryUStr.assign(queryStr, izenelib::util::UString::UTF_8);
        BOOST_CHECK( !queryParser.parseQuery(queryUStr, queryTree, true, true) );
    } // end - Restrict Term Test
}

//BOOST_AUTO_TEST_CASE(parseQuery_extreme_test1)
{
    QueryParser queryParser(laManager, idManager);

    // Insert Large amount of query.
    string queryStr("회사명.대표.자본금(단위 백만원).업종.주소 順<>특7호*상명푸드(이상기.100.식품류) 방이동 51의4효성올림픽카운티1011호*새롬후디스(현성규.50.인삼제품) 서초동 1628의29*씨앤제이브라더스(안승길.50.식품류) 가락동 119의12 201호*엠디피생활건강(정인숙.500.건강식품) 문래동 3가55의7에이스테크노타워402호*해인바다(신상우.50.농수축임산물) 방이동 196의19<>유통*가나우드코리아(강상규.50.수출입) 영등포동 2가207*가백무역(최명자.50.의류) 신천동 11의9잠실한신코아오피스텔*건훈전자(황상하.300.전자부품) 서초동 1671의5대림서초리시온상가510호*경남아이앤티(이경남.300.통신기기) 역삼동 725의25포커스빌딩 2층*경한철강(김종민.50.철강) 문래동 3가54의43*그레비컴(노경선.50.신용카드조회기) 하계동 288현대2차(아) 상가지하1층전관*글로벌콘티넨탈코리아(박상호.100.재활용품자재) 역촌동 43의64*까사아이엔티(이한우.50.원단수출입) 포이동 240일영빌딩 2층*나노윈(최병영.50.정밀측정시스템) 가락동 171의11예울빌딩 3층*네트서브웨이(오정석.20.전산소모품) 역삼동 707의38테헤란오피스빌딩 1203호*다인인터컴(백광조.30.통신장비) 여의도동 11의11한서오피스텔512*다인티앤지(이광석.50.섬유) 염창동 264의26 2층*대솔아이티(최성민.50.컴퓨터주변기기) 정릉동 921의8*동 일엠디(강권.50.공산품) 양재동 23이비지니스타워504*두리농산(김광태.100.농산물) 동 작동 105*디엘가스산업(권석범.50.가스기기류) 공항동 1351*디티유어패럴(김미정.50.의류) 신당동 193의3 713호*라이프써핑(이종철.50.전자상거래) 서교동 395의166서교빌딩 602호*레몬통상(임종말.50.농수축산물) 가락동 98의7거북이빌딩 201호*레이스조이(천?牙?50.전자상거래) 양재동 20의12 112호*머리나라(.770.무역) 석촌동 2의9금보빌딩 ");
    izenelib::util::UString queryUStr(queryStr, izenelib::util::UString::UTF_8);
    QueryTreePtr queryTree;
    BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, false, true) );
}

//BOOST_AUTO_TEST_CASE(getAnalyzedQueryTree_basic_test)
{
    /*
    QueryParser queryParser(laManager, idManager);

    {
        izenelib::util::UString queryUStr("(reds|iphone4) (!빨간 자동차)", izenelib::util::UString::UTF_8);
        QueryTreePtr queryTree;

        AnalysisInfo analysisInfo;
        analysisInfo.analyzerId_ = "la_korall";

        BOOST_CHECK(queryParser.getAnalyzedQueryTree(true, analysisInfo, queryUStr, queryTree, false));

        // ROOT -> child : DFS check
        BOOST_CHECK_EQUAL(queryTree->type_ , QueryTree::AND);

        QTIter c, gc, ggc; // child, grand child, grand grand child

        c = queryTree->children_.begin();
        BOOST_CHECK_EQUAL((*c)->type_ , QueryTree::OR);

        gc = (*c)->children_.begin();
        keywordTreeCheck ((*gc) , "red"); gc++;
        BOOST_CHECK_EQUAL((*gc)->type_ , QueryTree::AND);
        ggc = (*gc)->children_.begin();
        keywordTreeCheck (*ggc, "iphon"); ggc++;
        keywordTreeCheck (*ggc , "4");

        c++;
        BOOST_CHECK_EQUAL((*c)->type_ , QueryTree::NOT);
        gc = (*c)->children_.begin();
        keywordTreeCheck (*gc , "빨간");

        c++;
        keywordTreeCheck (*c , "자동차");
    }
    { // Use Operator | as a character in special token option
        string queryStr("abc|123\\|def");

        AnalysisInfo analysisInfo;
        analysisInfo.analyzerId_ = "la_token";
        analysisInfo.tokenizerNameList_.insert("tok_allow_ex");

        izenelib::util::UString queryUStr(queryStr, izenelib::util::UString::UTF_8);
        QueryTreePtr queryTree;
        BOOST_CHECK(queryParser.getAnalyzedQueryTree(true, analysisInfo, queryUStr, queryTree, false));

        // Check Query Tree
        BOOST_CHECK_EQUAL( queryTree->type_ , QueryTree::OR );
        BOOST_CHECK_EQUAL( queryTree->children_.size() , 2 );
        QTIter childIter = queryTree->children_.begin();
        keywordTreeCheck(*childIter++, "abc");
        keywordTreeCheck(*childIter, "123|def");
    }
    */
}

//BOOST_AUTO_TEST_CASE(getAnalyzedQueryTree_phrase_test)
{
    QueryParser queryParser(laManager, idManager);

    { // Order Type
        izenelib::util::UString queryUStr("[대한민국 명바기]", izenelib::util::UString::UTF_8);
        QueryTreePtr queryTree;
        QTIter childIter;

        AnalysisInfo analysisInfo;
        analysisInfo.analyzerId_ = "la_korall";

        // Check without analysis
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, false, true) );
        BOOST_CHECK_EQUAL(queryTree->type_ , QueryTree::ORDER);
        BOOST_CHECK_EQUAL(queryTree->keyword_ , "대한민국 명바기");
        BOOST_CHECK_EQUAL(queryTree->children_.size() , 2U );
        childIter = queryTree->children_.begin();
        keywordTreeCheck(*childIter++, "대한민국");
        keywordTreeCheck(*childIter, "명바기");

        // Check with language analysis
        BOOST_CHECK(queryParser.getAnalyzedQueryTree(true, analysisInfo, queryUStr, queryTree, false, true));
        BOOST_CHECK_EQUAL(queryTree->type_ , QueryTree::ORDER);
        BOOST_CHECK_EQUAL(queryTree->keyword_ , "대한민국 명바기");
        BOOST_CHECK_EQUAL(queryTree->children_.size() , 3U );
        childIter = queryTree->children_.begin();
        keywordTreeCheck(*childIter++, "대한");
        keywordTreeCheck(*childIter++, "민국");
        keywordTreeCheck(*childIter++, "명바");
    }
    { // Nearby Type
        izenelib::util::UString queryUStr("{대한민국 명바기}^777", izenelib::util::UString::UTF_8);
        QueryTreePtr queryTree;
        QTIter childIter;

        AnalysisInfo analysisInfo;
        analysisInfo.analyzerId_ = "la_korall";

        // Check without analysis
        BOOST_CHECK( queryParser.parseQuery(queryUStr, queryTree, false, true) );
        BOOST_CHECK_EQUAL(queryTree->type_ , QueryTree::NEARBY);
        BOOST_CHECK_EQUAL(queryTree->keyword_ , "대한민국 명바기");
        BOOST_CHECK_EQUAL(queryTree->distance_ , 777 );
        BOOST_CHECK_EQUAL(queryTree->children_.size() , 2U );
        childIter = queryTree->children_.begin();
        keywordTreeCheck(*childIter++, "대한민국");
        keywordTreeCheck(*childIter, "명바기");

        // Check with language analysis
        BOOST_CHECK(queryParser.getAnalyzedQueryTree(true, analysisInfo, queryUStr, queryTree, false, true));
        BOOST_CHECK_EQUAL(queryTree->type_ , QueryTree::NEARBY);
        BOOST_CHECK_EQUAL(queryTree->keyword_ , "대한민국 명바기");
        BOOST_CHECK_EQUAL(queryTree->distance_ , 777 );
        BOOST_CHECK_EQUAL(queryTree->children_.size() , 3U );
        childIter = queryTree->children_.begin();
        keywordTreeCheck(*childIter++, "대한");
        keywordTreeCheck(*childIter++, "민국");
        keywordTreeCheck(*childIter++, "명바");
    }
}

}

BOOST_AUTO_TEST_SUITE_END()


text:
#include <memory>
#include <cstddef>
#include <stdexcept>
#include <string>
#include <random>
#include <iostream>
#include <iomanip>
#include <thread>

#include <dlfcn.h>

#include <pcg_random.hpp>

#include <common/defines.h>

#include <Common/Stopwatch.h>

#include <emmintrin.h>
#include <immintrin.h>

#include <boost/program_options.hpp>

template <typename F, typename MemcpyImpl>
void NO_INLINE loop(uint8_t * dst, uint8_t * src, size_t size, F && chunk_size_distribution, MemcpyImpl && impl)
{
    while (size)
    {
        size_t bytes_to_copy = std::min<size_t>(size, chunk_size_distribution());

        impl(dst, src, bytes_to_copy);

        dst += bytes_to_copy;
        src += bytes_to_copy;
        size -= bytes_to_copy;

        /// Execute at least one SSE instruction as a penalty after running AVX code.
        __asm__ volatile ("pxor %%xmm7, %%xmm7" ::: "xmm7");
    }
}

using RNG = pcg32_fast;

template <size_t N>
size_t generatorUniform(RNG & rng) { return rng() % N; };

template <typename F, typename MemcpyImpl>
uint64_t test(uint8_t * dst, uint8_t * src, size_t size, size_t iterations, size_t num_threads, F && generator, MemcpyImpl && impl, const char * name)
{
    Stopwatch watch;

    std::vector<std::thread> threads;
    threads.reserve(num_threads);

    for (size_t thread_num = 0; thread_num < num_threads; ++thread_num)
    {
        size_t begin = size * thread_num / num_threads;
        size_t end = size * (thread_num + 1) / num_threads;

        threads.emplace_back([begin, end, iterations, &src, &dst, &generator, &impl]
        {
            for (size_t iteration = 0; iteration < iterations; ++iteration)
            {
                loop(
                    iteration % 2 ? &src[begin] : &dst[begin],
                    iteration % 2 ? &dst[begin] : &src[begin],
                    end - begin,
                    [rng = RNG(), &generator]() mutable { return generator(rng); },
                    std::forward<MemcpyImpl>(impl));
            }
        });
    }

    for (auto & thread : threads)
        thread.join();

    uint64_t elapsed_ns = watch.elapsed();

    /// Validation
    for (size_t i = 0; i < size; ++i)
        if (dst[i] != uint8_t(i))
            throw std::logic_error("Incorrect result");

    std::cout << name;
    return elapsed_ns;
}

using memcpy_type = void * (*)(const void * __restrict, void * __restrict, size_t);

static void * memcpy_erms(void * dst, const void * src, size_t size)
{
    asm volatile (
        "rep movsb"
        : "=D"(dst), "=S"(src), "=c"(size)
        : "0"(dst), "1"(src), "2"(size)
        : "memory");
    return dst;
}

static void * memcpy_trivial(void * __restrict dst_, const void * __restrict src_, size_t size)
{
    char * __restrict dst = reinterpret_cast<char * __restrict>(dst_);
    const char * __restrict src = reinterpret_cast<const char * __restrict>(src_);
    void * ret = dst;

    while (size > 0)
    {
        *dst = *src;
        ++dst;
        ++src;
        --size;
    }

    return ret;
}

extern "C" void * memcpy_jart(void * dst, const void * src, size_t size);
extern "C" void MemCpy(void * dst, const void * src, size_t size);

void * memcpy_fast_sse(void * dst, const void * src, size_t size);
void * memcpy_fast_avx(void * dst, const void * src, size_t size);
void * memcpy_tiny(void * dst, const void * src, size_t size);

static void * memcpySSE2(void * __restrict destination, const void * __restrict source, size_t size)
{
    unsigned char *dst = reinterpret_cast<unsigned char *>(destination);
    const unsigned char *src = reinterpret_cast<const unsigned char *>(source);
    size_t padding;

    // small memory copy
    if (size <= 16)
        return memcpy_tiny(dst, src, size);

    // align destination to 16 bytes boundary
    padding = (16 - (reinterpret_cast<size_t>(dst) & 15)) & 15;

    if (padding > 0)
    {
        __m128i head = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
        _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), head);
        dst += padding;
        src += padding;
        size -= padding;
    }

    // medium size copy
    __m128i c0;

    for (; size >= 16; size -= 16)
    {
        c0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
        src += 16;
        _mm_store_si128((reinterpret_cast<__m128i*>(dst)), c0);
        dst += 16;
    }

    memcpy_tiny(dst, src, size);
    return destination;
}

static void * memcpySSE2Unrolled2(void * __restrict destination, const void * __restrict source, size_t size)
{
    unsigned char *dst = reinterpret_cast<unsigned char *>(destination);
    const unsigned char *src = reinterpret_cast<const unsigned char *>(source);
    size_t padding;

    // small memory copy
    if (size <= 32)
        return memcpy_tiny(dst, src, size);

    // align destination to 16 bytes boundary
    padding = (16 - (reinterpret_cast<size_t>(dst) & 15)) & 15;

    if (padding > 0)
    {
        __m128i head = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
        _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), head);
        dst += padding;
        src += padding;
        size -= padding;
    }

    // medium size copy
    __m128i c0, c1;

    for (; size >= 32; size -= 32)
    {
        c0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 0);
        c1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 1);
        src += 32;
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 0), c0);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 1), c1);
        dst += 32;
    }

    memcpy_tiny(dst, src, size);
    return destination;
}

static void * memcpySSE2Unrolled4(void * __restrict destination, const void * __restrict source, size_t size)
{
    unsigned char *dst = reinterpret_cast<unsigned char *>(destination);
    const unsigned char *src = reinterpret_cast<const unsigned char *>(source);
    size_t padding;

    // small memory copy
    if (size <= 64)
        return memcpy_tiny(dst, src, size);

    // align destination to 16 bytes boundary
    padding = (16 - (reinterpret_cast<size_t>(dst) & 15)) & 15;

    if (padding > 0)
    {
        __m128i head = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
        _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), head);
        dst += padding;
        src += padding;
        size -= padding;
    }

    // medium size copy
    __m128i c0, c1, c2, c3;

    for (; size >= 64; size -= 64)
    {
        c0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 0);
        c1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 1);
        c2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 2);
        c3 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 3);
        src += 64;
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 0), c0);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 1), c1);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 2), c2);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 3), c3);
        dst += 64;
    }

    memcpy_tiny(dst, src, size);
    return destination;
}

static void * memcpySSE2Unrolled8(void * __restrict destination, const void * __restrict source, size_t size)
{
    unsigned char *dst = reinterpret_cast<unsigned char *>(destination);
    const unsigned char *src = reinterpret_cast<const unsigned char *>(source);
    size_t padding;

    // small memory copy
    if (size <= 128)
        return memcpy_tiny(dst, src, size);

    // align destination to 16 bytes boundary
    padding = (16 - (reinterpret_cast<size_t>(dst) & 15)) & 15;

    if (padding > 0)
    {
        __m128i head = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
        _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), head);
        dst += padding;
        src += padding;
        size -= padding;
    }

    // medium size copy
    __m128i c0, c1, c2, c3, c4, c5, c6, c7;

    for (; size >= 128; size -= 128)
    {
        c0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 0);
        c1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 1);
        c2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 2);
        c3 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 3);
        c4 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 4);
        c5 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 5);
        c6 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 6);
        c7 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 7);
        src += 128;
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 0), c0);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 1), c1);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 2), c2);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 3), c3);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 4), c4);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 5), c5);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 6), c6);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 7), c7);
        dst += 128;
    }

    memcpy_tiny(dst, src, size);
    return destination;
}

//static __attribute__((__always_inline__, __target__("sse2")))
__attribute__((__always_inline__))
void memcpy_my_medium_sse(uint8_t * __restrict & dst, const uint8_t * __restrict & src, size_t & size)
{
    /// Align destination to 16 bytes boundary.
    size_t padding = (16 - (reinterpret_cast<size_t>(dst) & 15)) & 15;

    if (padding > 0)
    {
        __m128i head = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
        _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), head);
        dst += padding;
        src += padding;
        size -= padding;
    }

    /// Aligned unrolled copy.
    __m128i c0, c1, c2, c3, c4, c5, c6, c7;

    while (size >= 128)
    {
        c0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 0);
        c1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 1);
        c2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 2);
        c3 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 3);
        c4 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 4);
        c5 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 5);
        c6 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 6);
        c7 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 7);
        src += 128;
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 0), c0);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 1), c1);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 2), c2);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 3), c3);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 4), c4);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 5), c5);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 6), c6);
        _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 7), c7);
        dst += 128;

        size -= 128;
    }
}

__attribute__((__target__("avx")))
void memcpy_my_medium_avx(uint8_t * __restrict & __restrict dst, const uint8_t * __restrict & __restrict src, size_t & __restrict size)
{
    size_t padding = (32 - (reinterpret_cast<size_t>(dst) & 31)) & 31;

    if (padding > 0)
    {
        __m256i head = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src));
        _mm256_storeu_si256(reinterpret_cast<__m256i*>(dst), head);
        dst += padding;
        src += padding;
        size -= padding;
    }

    __m256i c0, c1, c2, c3, c4, c5, c6, c7;

    while (size >= 256)
    {
        c0 = _mm256_loadu_si256((reinterpret_cast<const __m256i*>(src)) + 0);
        c1 = _mm256_loadu_si256((reinterpret_cast<const __m256i*>(src)) + 1);
        c2 = _mm256_loadu_si256((reinterpret_cast<const __m256i*>(src)) + 2);
        c3 = _mm256_loadu_si256((reinterpret_cast<const __m256i*>(src)) + 3);
        c4 = _mm256_loadu_si256((reinterpret_cast<const __m256i*>(src)) + 4);
        c5 = _mm256_loadu_si256((reinterpret_cast<const __m256i*>(src)) + 5);
        c6 = _mm256_loadu_si256((reinterpret_cast<const __m256i*>(src)) + 6);
        c7 = _mm256_loadu_si256((reinterpret_cast<const __m256i*>(src)) + 7);
        src += 256;
        _mm256_store_si256(((reinterpret_cast<__m256i*>(dst)) + 0), c0);
        _mm256_store_si256(((reinterpret_cast<__m256i*>(dst)) + 1), c1);
        _mm256_store_si256(((reinterpret_cast<__m256i*>(dst)) + 2), c2);
        _mm256_store_si256(((reinterpret_cast<__m256i*>(dst)) + 3), c3);
        _mm256_store_si256(((reinterpret_cast<__m256i*>(dst)) + 4), c4);
        _mm256_store_si256(((reinterpret_cast<__m256i*>(dst)) + 5), c5);
        _mm256_store_si256(((reinterpret_cast<__m256i*>(dst)) + 6), c6);
        _mm256_store_si256(((reinterpret_cast<__m256i*>(dst)) + 7), c7);
        dst += 256;

        size -= 256;
    }
}

bool have_avx = true;

static uint8_t * memcpy_my(uint8_t * __restrict dst, const uint8_t * __restrict src, size_t size)
{
    uint8_t * ret = dst;

tail:
    if (size <= 16)
    {
        if (size >= 8)
        {
            __builtin_memcpy(dst + size - 8, src + size - 8, 8);
            __builtin_memcpy(dst, src, 8);
        }
        else if (size >= 4)
        {
            __builtin_memcpy(dst + size - 4, src + size - 4, 4);
            __builtin_memcpy(dst, src, 4);
        }
        else if (size >= 2)
        {
            __builtin_memcpy(dst + size - 2, src + size - 2, 2);
            __builtin_memcpy(dst, src, 2);
        }
        else if (size >= 1)
        {
            *dst = *src;
        }
    }
    else if (have_avx)
    {
        if (size <= 32)
        {
            __builtin_memcpy(dst, src, 8);
            __builtin_memcpy(dst + 8, src + 8, 8);

            dst += 16;
            src += 16;
            size -= 16;

            goto tail;
        }

        if (size <= 256)
        {
            __asm__(
                "vmovups    -0x20(%[s],%[size],1), %%ymm0\n"
                "vmovups    %%ymm0, -0x20(%[d],%[size],1)\n"
                : [d]"+r"(dst), [s]"+r"(src)
                : [size]"r"(size)
                : "ymm0", "memory");

            while (size > 32)
            {
                __asm__(
                    "vmovups    (%[s]), %%ymm0\n"
                    "vmovups    %%ymm0, (%[d])\n"
                    : [d]"+r"(dst), [s]"+r"(src)
                    :
                    : "ymm0", "memory");

                dst += 32;
                src += 32;
                size -= 32;
            }
        }
        else
        {
            size_t padding = (32 - (reinterpret_cast<size_t>(dst) & 31)) & 31;

            if (padding > 0)
            {
                __asm__(
                    "vmovups    (%[s]), %%ymm0\n"
                    "vmovups    %%ymm0, (%[d])\n"
                    : [d]"+r"(dst), [s]"+r"(src)
                    :
                    : "ymm0", "memory");

                dst += padding;
                src += padding;
                size -= padding;
            }

            while (size >= 256)
            {
                __asm__(
                    "vmovups    (%[s]), %%ymm0\n"
                    "vmovups    0x20(%[s]), %%ymm1\n"
                    "vmovups    0x40(%[s]), %%ymm2\n"
                    "vmovups    0x60(%[s]), %%ymm3\n"
                    "vmovups    0x80(%[s]), %%ymm4\n"
                    "vmovups    0xa0(%[s]), %%ymm5\n"
                    "vmovups    0xc0(%[s]), %%ymm6\n"
                    "vmovups    0xe0(%[s]), %%ymm7\n"
                    "add        $0x100,%[s]\n"
                    "vmovaps    %%ymm0, (%[d])\n"
                    "vmovaps    %%ymm1, 0x20(%[d])\n"
                    "vmovaps    %%ymm2, 0x40(%[d])\n"
                    "vmovaps    %%ymm3, 0x60(%[d])\n"
                    "vmovaps    %%ymm4, 0x80(%[d])\n"
                    "vmovaps    %%ymm5, 0xa0(%[d])\n"
                    "vmovaps    %%ymm6, 0xc0(%[d])\n"
                    "vmovaps    %%ymm7, 0xe0(%[d])\n"
                    "add        $0x100, %[d]\n"
                    : [d]"+r"(dst), [s]"+r"(src)
                    :
                    : "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "memory");

                size -= 256;
            }

            goto tail;
        }
    }
    else
    {
        if (size <= 128)
        {
            _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + size - 16), _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + size - 16)));

            while (size > 16)
            {
                _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), _mm_loadu_si128(reinterpret_cast<const __m128i *>(src)));
                dst += 16;
                src += 16;
                size -= 16;
            }
        }
        else
        {
            /// Align destination to 16 bytes boundary.
            size_t padding = (16 - (reinterpret_cast<size_t>(dst) & 15)) & 15;

            if (padding > 0)
            {
                __m128i head = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
                _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), head);
                dst += padding;
                src += padding;
                size -= padding;
            }

            /// Aligned unrolled copy.
            __m128i c0, c1, c2, c3, c4, c5, c6, c7;

            while (size >= 128)
            {
                c0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 0);
                c1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 1);
                c2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 2);
                c3 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 3);
                c4 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 4);
                c5 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 5);
                c6 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 6);
                c7 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src) + 7);
                src += 128;
                _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 0), c0);
                _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 1), c1);
                _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 2), c2);
                _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 3), c3);
                _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 4), c4);
                _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 5), c5);
                _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 6), c6);
                _mm_store_si128((reinterpret_cast<__m128i*>(dst) + 7), c7);
                dst += 128;

                size -= 128;
            }

            goto tail;
        }
    }

    return ret;
}

extern "C" void * __memcpy_erms(void * __restrict destination, const void * __restrict source, size_t size);
extern "C" void * __memcpy_sse2_unaligned(void * __restrict destination, const void * __restrict source, size_t size);
extern "C" void * __memcpy_ssse3(void * __restrict destination, const void * __restrict source, size_t size);
extern "C" void * __memcpy_ssse3_back(void * __restrict destination, const void * __restrict source, size_t size);
extern "C" void * __memcpy_avx_unaligned(void * __restrict destination, const void * __restrict source, size_t size);
extern "C" void * __memcpy_avx_unaligned_erms(void * __restrict destination, const void * __restrict source, size_t size);
extern "C" void * __memcpy_avx512_unaligned(void * __restrict destination, const void * __restrict source, size_t size);
extern "C" void * __memcpy_avx512_unaligned_erms(void * __restrict destination, const void * __restrict source, size_t size);
extern "C" void * __memcpy_avx512_no_vzeroupper(void * __restrict destination, const void * __restrict source, size_t size);

#define VARIANT(N, NAME) \
    if (memcpy_variant == N) \
        return test(dst, src, size, iterations, num_threads, std::forward<F>(generator), NAME, #NAME);

template <typename F>
uint64_t dispatchMemcpyVariants(size_t memcpy_variant, uint8_t * dst, uint8_t * src, size_t size, size_t iterations, size_t num_threads, F && generator)
{
    memcpy_type memcpy_libc_old = reinterpret_cast<memcpy_type>(dlsym(RTLD_NEXT, "memcpy"));

    VARIANT(1, memcpy)
    VARIANT(2, memcpy_trivial)
    VARIANT(3, memcpy_libc_old)
    VARIANT(4, memcpy_erms)
    VARIANT(5, MemCpy)
    VARIANT(6, memcpySSE2)
    VARIANT(7, memcpySSE2Unrolled2)
    VARIANT(8, memcpySSE2Unrolled4)
    VARIANT(9, memcpySSE2Unrolled8)
    VARIANT(10, memcpy_fast_sse)
    VARIANT(11, memcpy_fast_avx)
    VARIANT(12, memcpy_my)

    VARIANT(21, __memcpy_erms)
    VARIANT(22, __memcpy_sse2_unaligned)
    VARIANT(23, __memcpy_ssse3)
    VARIANT(24, __memcpy_ssse3_back)
    VARIANT(25, __memcpy_avx_unaligned)
    VARIANT(26, __memcpy_avx_unaligned_erms)
    VARIANT(27, __memcpy_avx512_unaligned)
    VARIANT(28, __memcpy_avx512_unaligned_erms)
    VARIANT(29, __memcpy_avx512_no_vzeroupper)

    return 0;
}

uint64_t dispatchVariants(
    size_t memcpy_variant, size_t generator_variant, uint8_t * dst, uint8_t * src, size_t size, size_t iterations, size_t num_threads)
{
    if (generator_variant == 1)
        return dispatchMemcpyVariants(memcpy_variant, dst, src, size, iterations, num_threads, generatorUniform<16>);
    if (generator_variant == 2)
        return dispatchMemcpyVariants(memcpy_variant, dst, src, size, iterations, num_threads, generatorUniform<256>);
    if (generator_variant == 3)
        return dispatchMemcpyVariants(memcpy_variant, dst, src, size, iterations, num_threads, generatorUniform<4096>);
    if (generator_variant == 4)
        return dispatchMemcpyVariants(memcpy_variant, dst, src, size, iterations, num_threads, generatorUniform<65536>);
    if (generator_variant == 5)
        return dispatchMemcpyVariants(memcpy_variant, dst, src, size, iterations, num_threads, generatorUniform<1048576>);

    return 0;
}

int main(int argc, char ** argv)
{
    boost::program_options::options_description desc("Allowed options");
    desc.add_options()("help,h", "produce help message")
        ("size", boost::program_options::value<size_t>()->default_value(1000000), "Bytes to copy on every iteration")
        ("iterations", boost::program_options::value<size_t>(), "Number of iterations")
        ("threads", boost::program_options::value<size_t>()->default_value(1), "Number of copying threads")
        ("distribution", boost::program_options::value<size_t>()->default_value(4), "Distribution of chunk sizes to perform copy")
        ("variant", boost::program_options::value<size_t>(), "Variant of memcpy implementation")
        ("tsv", "Print result in tab-separated format")
        ;

    boost::program_options::variables_map options;
    boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), options);

    if (options.count("help") || !options.count("variant"))
    {
        std::cout << R"(Usage:

for size in 4096 16384 50000 65536 100000 1000000 10000000 100000000; do
    for threads in 1 2 4 $(($(nproc) / 2)) $(nproc); do
        for distribution in 1 2 3 4 5; do
            for variant in {1..12} {21..29}; do
                for i in {1..10}; do
                    ./memcpy-bench --tsv --size $size --variant $variant --threads $threads --distribution $distribution;
                done;
            done;
        done;
    done;
done | tee result.tsv

clickhouse-local --structure '
    name String,
    size UInt64,
    iterations UInt64,
    threads UInt16,
    generator UInt8,
    memcpy UInt8,
    elapsed UInt64
' --query "
    SELECT
        size, name,
        avg(1000 * elapsed / size / iterations) AS s,
        count() AS c
    FROM table
    GROUP BY size, name
    ORDER BY size ASC, s DESC
" --output-format PrettyCompact < result.tsv

)" << std::endl;
        std::cout << desc << std::endl;
        return 1;
    }

    size_t size = options["size"].as<size_t>();
    size_t num_threads = options["threads"].as<size_t>();
    size_t memcpy_variant = options["variant"].as<size_t>();
    size_t generator_variant = options["distribution"].as<size_t>();

    size_t iterations;
    if (options.count("iterations"))
    {
        iterations = options["iterations"].as<size_t>();
    }
    else
    {
        iterations = 10000000000ULL / size;

        if (generator_variant == 1)
            iterations /= 10;
    }

    std::unique_ptr<uint8_t[]> src(new uint8_t[size]);
    std::unique_ptr<uint8_t[]> dst(new uint8_t[size]);

    /// Fill src with some pattern for validation.
    for (size_t i = 0; i < size; ++i)
        src[i] = i;

    /// Fill dst to avoid page faults.
    memset(dst.get(), 0, size);

    uint64_t elapsed_ns = dispatchVariants(memcpy_variant, generator_variant, dst.get(), src.get(), size, iterations, num_threads);

    std::cout << std::fixed << std::setprecision(3);

    if (options.count("tsv"))
    {
        std::cout
            << '\t' << size
            << '\t' << iterations
            << '\t' << num_threads
            << '\t' << generator_variant
            << '\t' << memcpy_variant
            << '\t' << elapsed_ns
            << '\n';
    }
    else
    {
        std::cout << ": processed in " << (elapsed_ns / 1e9) << " sec, " << (size * iterations * 1.0 / elapsed_ns) << " GB/sec\n";
    }

    return 0;
}

max_stars_repo_name: evryfs/ClickHouse

max_issues_repo_name: evryfs/ClickHouse

max_forks_repo_name: evryfs/ClickHouse


text:
// ----------------------------------------------------------------------------
// -                        Open3D: www.open3d.org                            -
// ----------------------------------------------------------------------------
// The MIT License (MIT)
//
// Copyright (c) 2018-2021 www.open3d.org
//
// 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.
// ----------------------------------------------------------------------------

#include "open3d/t/geometry/TriangleMesh.h"

#include <Eigen/Core>
#include <string>
#include <unordered_map>

#include "open3d/core/EigenConverter.h"
#include "open3d/core/ShapeUtil.h"
#include "open3d/core/Tensor.h"
#include "open3d/core/TensorCheck.h"
#include "open3d/t/geometry/kernel/PointCloud.h"
#include "open3d/t/geometry/kernel/Transform.h"

namespace open3d {
namespace t {
namespace geometry {

TriangleMesh::TriangleMesh(const core::Device &device)
    : Geometry(Geometry::GeometryType::TriangleMesh, 3),
      device_(device),
      vertex_attr_(TensorMap("positions")),
      triangle_attr_(TensorMap("indices")) {}

TriangleMesh::TriangleMesh(const core::Tensor &vertex_positions,
                           const core::Tensor &triangle_indices)
    : TriangleMesh([&]() {
          if (vertex_positions.GetDevice() != triangle_indices.GetDevice()) {
              utility::LogError(
                      "vertex_positions' device {} does not match "
                      "triangle_indices' device {}.",
                      vertex_positions.GetDevice().ToString(),
                      triangle_indices.GetDevice().ToString());
          }
          return vertex_positions.GetDevice();
      }()) {
    SetVertexPositions(vertex_positions);
    SetTriangleIndices(triangle_indices);
}

std::string TriangleMesh::ToString() const {
    if (vertex_attr_.size() == 0 || triangle_attr_.size() == 0)
        return fmt::format("TriangleMesh on {} [{} vertices and {} triangles].",
                           GetDevice().ToString(), vertex_attr_.size(),
                           triangle_attr_.size());

    auto str = fmt::format(
            "TriangleMesh on {} [{} vertices ({}) and {} triangles ({})].",
            GetDevice().ToString(), GetVertexPositions().GetLength(),
            GetVertexPositions().GetDtype().ToString(),
            GetTriangleIndices().GetLength(),
            GetTriangleIndices().GetDtype().ToString());

    std::string vertices_attr_str = "\nVertex Attributes:";
    if (vertex_attr_.size() == 1) {
        vertices_attr_str += " None.";
    } else {
        for (const auto &kv : vertex_attr_) {
            if (kv.first != "positions") {
                vertices_attr_str +=
                        fmt::format(" {} (dtype = {}, shape = {}),", kv.first,
                                    kv.second.GetDtype().ToString(),
                                    kv.second.GetShape().ToString());
            }
        }
        vertices_attr_str[vertices_attr_str.size() - 1] = '.';
    }

    std::string triangles_attr_str = "\nTriangle Attributes:";
    if (triangle_attr_.size() == 1) {
        triangles_attr_str += " None.";
    } else {
        for (const auto &kv : triangle_attr_) {
            if (kv.first != "indices") {
                triangles_attr_str +=
                        fmt::format(" {} (dtype = {}, shape = {}),", kv.first,
                                    kv.second.GetDtype().ToString(),
                                    kv.second.GetShape().ToString());
            }
        }
        triangles_attr_str[triangles_attr_str.size() - 1] = '.';
    }

    return str + vertices_attr_str + triangles_attr_str;
}

TriangleMesh &TriangleMesh::Transform(const core::Tensor &transformation) {
    core::AssertTensorShape(transformation, {4, 4});

    kernel::transform::TransformPoints(transformation, GetVertexPositions());
    if (HasVertexNormals()) {
        kernel::transform::TransformNormals(transformation, GetVertexNormals());
    }
    if (HasTriangleNormals()) {
        kernel::transform::TransformNormals(transformation,
                                            GetTriangleNormals());
    }

    return *this;
}

TriangleMesh &TriangleMesh::Translate(const core::Tensor &translation,
                                      bool relative) {
    core::AssertTensorShape(translation, {3});

    core::Tensor transform =
            translation.To(GetDevice(), GetVertexPositions().GetDtype());

    if (!relative) {
        transform -= GetCenter();
    }
    GetVertexPositions() += transform;
    return *this;
}

TriangleMesh &TriangleMesh::Scale(double scale, const core::Tensor &center) {
    core::AssertTensorShape(center, {3});
    core::AssertTensorDevice(center, device_);

    const core::Tensor center_d =
            center.To(GetDevice(), GetVertexPositions().GetDtype());

    GetVertexPositions().Sub_(center_d).Mul_(scale).Add_(center_d);
    return *this;
}

TriangleMesh &TriangleMesh::Rotate(const core::Tensor &R,
                                   const core::Tensor &center) {
    core::AssertTensorShape(R, {3, 3});
    core::AssertTensorShape(center, {3});

    kernel::transform::RotatePoints(R, GetVertexPositions(), center);
    if (HasVertexNormals()) {
        kernel::transform::RotateNormals(R, GetVertexNormals());
    }
    if (HasTriangleNormals()) {
        kernel::transform::RotateNormals(R, GetTriangleNormals());
    }
    return *this;
}

geometry::TriangleMesh TriangleMesh::FromLegacy(
        const open3d::geometry::TriangleMesh &mesh_legacy,
        core::Dtype float_dtype,
        core::Dtype int_dtype,
        const core::Device &device) {
    if (float_dtype != core::Float32 && float_dtype != core::Float64) {
        utility::LogError("float_dtype must be Float32 or Float64, but got {}.",
                          float_dtype.ToString());
    }
    if (int_dtype != core::Int32 && int_dtype != core::Int64) {
        utility::LogError("int_dtype must be Int32 or Int64, but got {}.",
                          int_dtype.ToString());
    }

    TriangleMesh mesh(device);
    if (mesh_legacy.HasVertices()) {
        mesh.SetVertexPositions(
                core::eigen_converter::EigenVector3dVectorToTensor(
                        mesh_legacy.vertices_, float_dtype, device));
    } else {
        utility::LogWarning("Creating from empty legacy TriangleMesh.");
    }
    if (mesh_legacy.HasVertexColors()) {
        mesh.SetVertexColors(core::eigen_converter::EigenVector3dVectorToTensor(
                mesh_legacy.vertex_colors_, float_dtype, device));
    }
    if (mesh_legacy.HasVertexNormals()) {
        mesh.SetVertexNormals(
                core::eigen_converter::EigenVector3dVectorToTensor(
                        mesh_legacy.vertex_normals_, float_dtype, device));
    }
    if (mesh_legacy.HasTriangles()) {
        mesh.SetTriangleIndices(
                core::eigen_converter::EigenVector3iVectorToTensor(
                        mesh_legacy.triangles_, int_dtype, device));
    }
    if (mesh_legacy.HasTriangleNormals()) {
        mesh.SetTriangleNormals(
                core::eigen_converter::EigenVector3dVectorToTensor(
                        mesh_legacy.triangle_normals_, float_dtype, device));
    }
    if (mesh_legacy.HasTriangleUvs()) {
        mesh.SetTriangleAttr(
                "texture_uvs",
                core::eigen_converter::EigenVector2dVectorToTensor(
                        mesh_legacy.triangle_uvs_, float_dtype, device)
                        .Reshape({-1, 3, 2}));
    }
    return mesh;
}

open3d::geometry::TriangleMesh TriangleMesh::ToLegacy() const {
    open3d::geometry::TriangleMesh mesh_legacy;
    if (HasVertexPositions()) {
        mesh_legacy.vertices_ =
                core::eigen_converter::TensorToEigenVector3dVector(
                        GetVertexPositions());
    }
    if (HasVertexColors()) {
        mesh_legacy.vertex_colors_ =
                core::eigen_converter::TensorToEigenVector3dVector(
                        GetVertexColors());
    }
    if (HasVertexNormals()) {
        mesh_legacy.vertex_normals_ =
                core::eigen_converter::TensorToEigenVector3dVector(
                        GetVertexNormals());
    }
    if (HasTriangleIndices()) {
        mesh_legacy.triangles_ =
                core::eigen_converter::TensorToEigenVector3iVector(
                        GetTriangleIndices());
    }
    if (HasTriangleNormals()) {
        mesh_legacy.triangle_normals_ =
                core::eigen_converter::TensorToEigenVector3dVector(
                        GetTriangleNormals());
    }
    if (HasTriangleAttr("texture_uvs")) {
        mesh_legacy.triangle_uvs_ =
                core::eigen_converter::TensorToEigenVector2dVector(
                        GetTriangleAttr("texture_uvs").Reshape({-1, 2}));
    }
    if (HasVertexAttr("texture_uvs")) {
        utility::LogWarning("{}",
                            "texture_uvs as a vertex attribute is not "
                            "supported by legacy TriangleMesh. Ignored.");
    }

    return mesh_legacy;
}

TriangleMesh TriangleMesh::To(const core::Device &device, bool copy) const {
    if (!copy && GetDevice() == device) {
        return *this;
    }
    TriangleMesh mesh(device);
    for (const auto &kv : triangle_attr_) {
        mesh.SetTriangleAttr(kv.first, kv.second.To(device, /*copy=*/true));
    }
    for (const auto &kv : vertex_attr_) {
        mesh.SetVertexAttr(kv.first, kv.second.To(device, /*copy=*/true));
    }
    return mesh;
}

}  // namespace geometry
}  // namespace t
}  // namespace open3d


text:
/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *
 *************************************************************/

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */

#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <tools/solar.h>
#include <rtl/ustring.hxx>
#include <tools/stream.hxx>
#include <IDocumentExternalData.hxx>

namespace ww8
{
    typedef boost::shared_array<sal_uInt8> DataArray_t;

class WW8Struct : public ::sw::ExternalData
    {
        DataArray_t mp_data;
        sal_uInt32 mn_offset;
        sal_uInt32 mn_size;

    public:
        WW8Struct(SvStream& rSt, sal_uInt32 nPos, sal_uInt32 nSize);
        WW8Struct(WW8Struct * pStruct, sal_uInt32 nPos, sal_uInt32 nSize);
        virtual ~WW8Struct();

        sal_uInt8 getU8(sal_uInt32 nOffset);

        sal_uInt16 getU16(sal_uInt32 nOffset)
        { return getU8(nOffset) + (getU8(nOffset + 1) << 8); }

        sal_uInt32 getU32(sal_uInt32 nOffset)
        { return  getU16(nOffset) + (getU16(nOffset + 1) << 16); }

        ::rtl::OUString getUString(sal_uInt32 nOffset, sal_uInt32 nCount);

        ::rtl::OUString getString(sal_uInt32 nOffset, sal_uInt32 nCount);
    };

typedef ::std::vector<rtl::OUString> StringVector_t;
    template <class T>
    class WW8Sttb : public WW8Struct
    {
        typedef ::boost::shared_ptr< void > ExtraPointer_t;
        typedef ::std::vector< ExtraPointer_t > ExtrasVector_t;
        bool bDoubleByteCharacters;
        StringVector_t m_Strings;
        ExtrasVector_t m_Extras;

    public:
        WW8Sttb(SvStream& rSt, sal_Int32 nPos, sal_uInt32 nSize);
        virtual ~WW8Sttb();

        sal_uInt32 getCount() const;
        ::rtl::OUString getEntry(sal_uInt32 nEntry) const
        {
            return m_Strings[nEntry];
        }

        StringVector_t & getStrings()
        {
            return m_Strings;
        }

        const T * getExtra(sal_uInt32 nEntry) const
        {
            return dynamic_cast<const T *> (m_Extras[nEntry].get());
        }
    };

    template <class T>
    WW8Sttb<T>::WW8Sttb(SvStream& rSt, sal_Int32 nPos, sal_uInt32 nSize)
    : WW8Struct(rSt, nPos, nSize), bDoubleByteCharacters(false)
    {
        sal_uInt32 nOffset = 0;

        if (getU16(nOffset) == 0xffff)
        {
            bDoubleByteCharacters = true;
            nOffset += 2;
        }

        sal_uInt16 nCount = getU16(nOffset);
        sal_uInt16 ncbExtra = getU16(nOffset + 2);

        nOffset += 4;
        for (sal_uInt16 i = 0; i < nCount; i++)
        {
            if (bDoubleByteCharacters)
            {
                sal_uInt16 nStrLen = getU16(nOffset);

                m_Strings.push_back(getUString(nOffset +2, nStrLen));

                nOffset += 2 + 2 * nStrLen;
            }
            else
            {
                sal_uInt8 nStrLen = getU8(nOffset);

                m_Strings.push_back(getUString(nOffset, nStrLen));

                nOffset += 1 + nStrLen;
            }

            if (ncbExtra > 0)
            {
                ExtraPointer_t pExtra(new T(this, nOffset, ncbExtra));
                m_Extras.push_back(pExtra);

                nOffset += ncbExtra;
            }
        }
    }

    template <class T>
    WW8Sttb<T>::~WW8Sttb()
    {
    }
}

ext: hxx

max_stars_repo_name: Grosskopf/openoffice

max_issues_repo_name: Grosskopf/openoffice

max_forks_repo_name: Grosskopf/openoffice


text:
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <fstream>
#include <vector>
#include <iostream>

#define BOOST_FILESYSTEM_NO_DEPRECATED
#define BOOST_NO_CXX11_SCOPED_ENUMS
#include <boost/filesystem.hpp>

#include "fileman/http_manager.h"

using namespace testing;
using namespace std;
namespace fs = boost::filesystem;

static fileman_config get_recodex_config()
{
	fileman_config conf;
	conf.remote_url = "https://recodex.mff.cuni.cz:8082";
	conf.username = "re";
	conf.password = "codex";
	return conf;
}

TEST(HttpManager, DISABLED_GetExistingFile)
{
	auto tmp = fs::temp_directory_path();
	fileman_config config = get_recodex_config();
	http_manager m({config});
	EXPECT_NO_THROW(m.get_file(config.remote_url + "/fm_test/test1.txt", (tmp / "test1.txt").string()));
	EXPECT_TRUE(fs::is_regular_file((tmp / "test1.txt").string()));
	fs::remove(tmp / "test1.txt");
}

TEST(HttpManager, DISABLED_GetExistingFileRedirect)
{
	auto tmp = fs::temp_directory_path();
	fileman_config config = get_recodex_config();
	http_manager m({config});
	EXPECT_NO_THROW(m.get_file(config.remote_url + "/fm_test/test2.txt", (tmp / "test2.txt").string()));
	EXPECT_TRUE(fs::is_regular_file((tmp / "test2.txt").string()));
	fs::remove(tmp / "test2.txt");
}

TEST(HttpManager, GetExistingHttp)
{
	auto tmp = fs::temp_directory_path();
	fileman_config config;
	config.remote_url = "http://curl.haxx.se";
	config.username = "";
	config.password = "";
	http_manager m({config});
	EXPECT_NO_THROW(m.get_file("http://curl.haxx.se/rfc/rfc7234.txt", (tmp / "rfc7234.txt").string()));
	EXPECT_TRUE(fs::is_regular_file((tmp / "rfc7234.txt").string()));
	fs::remove(tmp / "rfc7234.txt");
}

TEST(HttpManager, GetNonexistingFile)
{
	auto tmp = fs::temp_directory_path();
	fileman_config config = get_recodex_config();
	http_manager m({config});
	EXPECT_THROW(
		m.get_file(config.remote_url + "/fm_test_nonexist/test3.txt", (tmp / "test3.txt").string()), fm_exception);
	EXPECT_FALSE(fs::is_regular_file((tmp / "test3.txt").string()));
	//*
	try {
		fs::remove(tmp / "test3.txt");
	} catch (...) {
	}
	//*/
}

TEST(HttpManager, WrongAuthentication)
{
	auto tmp = fs::temp_directory_path();
	fileman_config config = get_recodex_config();
	config.username = "codex";
	config.password = "re";
	http_manager m({config});
	EXPECT_THROW(m.get_file(config.remote_url + "/fm_test/test1.txt", (tmp / "test1.txt").string()), fm_exception);
	EXPECT_FALSE(fs::is_regular_file((tmp / "test1.txt").string()));
	fs::remove(tmp / "test1.txt");
}

TEST(HttpManager, NonexistingServer)
{
	auto tmp = fs::temp_directory_path();
	fileman_config config;
	config.remote_url = "http://abcd.example.com";
	config.username = "a";
	config.password = "a";
	http_manager m({config});
	EXPECT_THROW(m.get_file("http://abcd.example.com/test1.txt", (tmp / "test1.txt").string()), fm_exception);
	EXPECT_FALSE(fs::is_regular_file((tmp / "test1.txt").string()));
	fs::remove(tmp / "test1.txt");
}

// Not testing now ...
/*TEST(HttpManager, ValidInvalidURLs)
{
	EXPECT_NO_THROW(http_manager m("https://ps.stdin.cz:8443/", "", ""));
	EXPECT_NO_THROW(http_manager m("http://ps.stdin.cz/", "", ""));

	EXPECT_THROW(http_manager m("htt://a.b/", "", ""), fm_exception);
	EXPECT_THROW(http_manager m("http://a.b", "", ""), fm_exception);
	EXPECT_THROW(http_manager m("htt://a/", "", ""), fm_exception);
	EXPECT_THROW(http_manager m("htt://a.b/", "", ""), fm_exception);
}*/

std::vector<std::string> codes{
	"400", // Bad Request
	"401", // Unauthorized
	"402", // Payment Required
	"403", // Forbidden
	"404", // Not Found
	"405", // Method Not Allowed
	"406", // Not Acceptable
	"407", // Proxy Authentication Required
	"408", // Request Timeout
	"409", // Conflict
	"410", // Gone
	"411", // Length Required
	"412", // Precondition Required
	"413", // Request Entry Too Large
	"414", // Request-URI Too Long
	"415", // Unsupported Media Type
	"416", // Requested Range Not Satisfiable
	"417", // Expectation Failed
	"418", // I'm a teapot
	"422", // Unprocessable Entity
	"428", // Precondition Required
	"429", // Too Many Requests
	"431", // Request Header Fields Too Large
	"500", // Internal Server Error
	"501", // Not Implemented
	"502", // Bad Gateway
	"503", // Service Unavailable
	"504", // Gateway Timeout
	"505", // HTTP Version Not Supported
	"511", // Network Authentication Required
	"520", // Web server is returning an unknown error
	"522", // Connection timed out
	"524" // A timeout occurred
};
TEST(HttpManager, DISABLED_AllWrongErrorCodes)
{
	auto tmp = fs::temp_directory_path();
	fileman_config config;
	config.remote_url = "http://httpstat.us";
	config.username = "";
	config.password = "";
	http_manager m({config});
	for (auto &i : codes) {
		// std::cout << i << std::endl;
		EXPECT_THROW(m.get_file(std::string("http://httpstat.us/") + i, (tmp / "test.txt").string()), fm_exception);
		EXPECT_FALSE(fs::is_regular_file(tmp / i));
	}
}

TEST(HttpManager, DISABLED_SimplePutFile)
{
	auto tmp = fs::temp_directory_path();
	{
		ofstream o((tmp / "a.txt").string());
		o << "testing string" << endl;
	}

	fileman_config config1 = get_recodex_config();

	http_manager m1({config1});
	EXPECT_NO_THROW(m1.put_file((tmp / "a.txt").string(), config1.remote_url + "/fm_test/a.txt"));

	// Invalid credentials
	fileman_config config2 = get_recodex_config();
	config2.username = "codex";
	config2.password = "re";
	http_manager m2({config2});
	EXPECT_THROW(m2.put_file((tmp / "a.txt").string(), config2.remote_url + "/fm_test/a.txt"), fm_exception);

	fs::remove(tmp / "a.txt");
}

TEST(HttpManager, PutFileWrongURL)
{
	auto tmp = fs::temp_directory_path();
	{
		ofstream o((tmp / "b.txt").string());
		o << "testing string" << endl;
	}

	fileman_config config = get_recodex_config();
	http_manager m({config});
	EXPECT_THROW(m.put_file((tmp / "b.txt").string(), config.remote_url + "/fm_test_nonexist/b.txt"), fm_exception);

	EXPECT_THROW(m.put_file((tmp / "b.txt").string(), "http://ps.stdin.cz/b.txt"), fm_exception);

	fs::remove(tmp / "b.txt");
}

TEST(HttpManager, PutWrongFile)
{
	auto tmp = fs::temp_directory_path();
	fileman_config config = get_recodex_config();
	http_manager m({config});
	EXPECT_THROW(m.put_file((tmp / "abc5xyz.txt").string(), config.remote_url + "/fm_test/abc5xyz.txt"), fm_exception);
}

max_stars_repo_name: rqu/worker

max_issues_repo_name: rqu/worker

max_forks_repo_name: rqu/worker


text:
#ifndef GRID_H
#define GRID_H

#include <Eigen/Dense>

#include "collisionObject.hpp"
#include "materialPoints.hpp"
#include "snowModel.hpp"

using namespace Eigen;

namespace SnowSimulator {

// Forward declarations

class MaterialPoint;
class MaterialPoints;

class GridCell;
class GridNode;
class Grid;

/**
 * A simple class that binds a collection of particles to a particular
 * GridNode.
 */
class GridCell {
public:
  GridCell();
  // GridCell(GridNode *gridNode);
  void addMaterialPoint(MaterialPoint *materialPoint);
  void clear();

  std::vector<MaterialPoint *> &particles() { return m_materialPoints; }

  GridNode *m_node; // Pointer to the immediately adjacent GridNode
  std::vector<MaterialPoint *> m_materialPoints;
};

class GridNode {
public:
  GridNode(Vector3i idx, Grid *grid);
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  Vector3f position() const;
  double mass() { return m_mass; }

  float basisFunction(Vector3f particlePos) const;
  Vector3f gradBasisFunction(Vector3f particlePos) const;

  void zeroForce();
  void addForce(Vector3f force);

  Vector3f &velocity() { return m_velocity; };
  Vector3f &nextVelocity() { return m_nextVelocity; };
  Vector3f &force() { return m_force; };

  std::vector<GridNode *> m_neighbors;
  std::vector<GridCell *> m_neighborCells;

  // Physical properties

  Vector3f m_velocity;
  Vector3f m_nextVelocity;
  Vector3f m_velocityStar;

  double m_mass;
  Vector3f m_force;

private:
  float cubicBSpline(float x) const;
  float gradCubicBSpline(float x) const;

  Vector3i m_idx;
  Grid *m_grid;
};

class Grid {
public:
  Grid(Vector3f origin, Vector3i dimensions, float spacing);
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  std::vector<GridNode *> getAllNodes();

  // Template functions

  template <typename Lambda>
  void forEachNeighbor(MaterialPoint *particle, Lambda &&f) {
    Array3i particleIdx =
        (particle->m_position.array() / m_spacing).floor().cast<int>();
    Array3i min = (particleIdx - 2).max(0);
    Array3i max = (particleIdx + 3).min(m_dim.array() - 1);

    for (int x = min.x(); x < max.x(); x++) {
      for (int y = min.y(); y < max.y(); y++) {
        for (int z = min.z(); z < max.z(); z++) {
          int neighborIdx = vectorToIdx(Vector3i(x, y, z));
          f(m_gridNodes[neighborIdx]);
        }
      }
    }
  }

  inline Vector3i idxToVector(int idx) {
    return Vector3i(idx % m_dim.x(), (idx / m_dim.x()) % m_dim.y(),
                    idx / (m_dim.x() * m_dim.y()));
  }

  inline int vectorToIdx(const Vector3i &idx) {
    return idx.x() + m_dim.x() * (idx.y() + m_dim.y() * idx.z());
  }

  int getParticleIdx(MaterialPoint *mp) {
    Vector3i idx = (mp->position().array() / m_spacing).cast<int>();
    return vectorToIdx(idx);
  }

  // Accessor methods

  Vector3f &origin() { return m_origin; }
  Vector3i &dim() { return m_dim; }
  Vector3f extent() { return m_dim.cast<float>() * m_spacing; }

  float spacing() { return m_spacing; }

  std::vector<GridNode *> &nodes() { return m_gridNodes; }
  std::vector<GridCell *> &cells() { return m_gridCells; }

  // Grid sizing and location

  Vector3f m_origin;
  Vector3i m_dim;
  float m_spacing; // h in the paper

  // Grid data

  std::vector<GridNode *> m_gridNodes;
  std::vector<GridCell *> m_gridCells;
};

} // namespace SnowSimulator

#endif // GRID_H

max_stars_repo_name: kvchen/snowsim

max_issues_repo_name: kvchen/snowsim

max_forks_repo_name: kvchen/snowsim


text:
//==================================================================================================
/*!
  @file

  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_BITWISE_OR_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_BITWISE_OR_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

 /*!
    @ingroup group-bitwise
    Function object implementing bitwise_or capabilities

    return the bitwise or of the two parameters

    The operands must share the same bit size.

    The result type is the one of the first operand.

    Infix notation can be used with operator '|',
    but this will not work in scalar mode if any
    operand is floating point because of C++ limitations.

    @par semantic:
    For any given value @c x, of type @c T0, @c y of type @c T1
    of same memory size:

    @code
    T0 r = bitwise_or(x, y);
    @endcode

    The code is equivalent to:

    @code
    T1 r = x | y;
    @endcode

    @see  bitwise_and, bitwise_or, bitwise_xor, bitwise_notand,
    bitwise_notor, bitwise_ornot, complement

  **/
  T0 bitwise_or(T0 const &x, T1 const& y);
} }
#endif

#include <boost/simd/function/scalar/bitwise_or.hpp>
#include <boost/simd/arch/common/scalar/function/bitwise_or.hpp>
#include <boost/simd/function/simd/bitwise_or.hpp>

#endif

max_stars_repo_name: xmar/pythran

max_issues_repo_name: xmar/pythran

max_forks_repo_name: xmar/pythran